Core: Remove thema and kindsys dependencies (#84499)

* Move some thema code inside grafana

* Use new codegen instead of thema for core kinds

* Replace TS generator

* Use new generator for go types

* Remove thema from oapi generator

* Remove thema from generators

* Don't use kindsys/thema for core kinds

* Remove kindsys/thema from plugins

* Remove last thema related

* Remove most of cuectx and move utils_ts into codegen. It also deletes wire dependency

* Merge plugins generators

* Delete thema dependency 🎉

* Fix CODEOWNERS

* Fix package name

* Fix TS output names

* More path fixes

* Fix mod codeowners

* Use original plugin's name

* Remove kindsys dependency 🎉

* Modify oapi schema and create an apply function to fix elasticsearch errors

* cue.mod was deleted by mistake

* Fix TS panels

* sort imports

* Fixing elasticsearch output

* Downgrade oapi-codegen library

* Update output ts files

* More fixes

* Restore old elasticsearch generated file and skip its generation. Remove core imports into plugins

* More lint fixes

* Add codeowners

* restore embed.go file

* Fix embed.go
pull/83368/head
Selene 1 year ago committed by GitHub
parent 856e410480
commit 473898e47c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      .github/CODEOWNERS
  2. 2
      embed.go
  3. 48
      go.mod
  4. 155
      go.sum
  5. 7
      kinds/constraint.cue
  6. 155
      kinds/gen.go
  7. 25
      pkg/codegen/generators.go
  8. 282
      pkg/codegen/generators/decorators.go
  9. 193
      pkg/codegen/generators/go_generator.go
  10. 199
      pkg/codegen/generators/openapi_generator.go
  11. 56
      pkg/codegen/generators/ts_generator.go
  12. 130
      pkg/codegen/generators/utils.go
  13. 16
      pkg/codegen/jenny_core_registry.go
  14. 20
      pkg/codegen/jenny_eachmajor.go
  15. 29
      pkg/codegen/jenny_go_spec.go
  16. 22
      pkg/codegen/jenny_k8_resources.go
  17. 23
      pkg/codegen/jenny_ts_types.go
  18. 56
      pkg/codegen/jenny_tsveneerindex.go
  19. 15
      pkg/codegen/util_go.go
  20. 6
      pkg/codegen/util_ts.go
  21. 73
      pkg/cuectx/ctx.go
  22. 239
      pkg/cuectx/load.go
  23. 18
      pkg/plugins/codegen/jenny_plugin_registry.go
  24. 19
      pkg/plugins/codegen/jenny_plugingotypes.go
  25. 47
      pkg/plugins/codegen/jenny_plugintstypes.go
  26. 30
      pkg/plugins/pfs/corelist/corelist.go
  27. 87
      pkg/plugins/pfs/corelist/corelist_load_gen.go
  28. 20
      pkg/plugins/pfs/decl.go
  29. 40
      pkg/plugins/pfs/decl_parser.go
  30. 157
      pkg/plugins/pfs/pfs.go
  31. 297
      pkg/plugins/pfs/pfs_test.go
  32. 31
      pkg/plugins/pfs/plugin.go
  33. 31
      pkg/plugins/pfs/plugin_test.go
  34. 3
      pkg/server/wire.go
  35. 85
      pkg/tsdb/azuremonitor/kinds/dataquery/types_dataquery_gen.go
  36. 2
      pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource.go
  37. 25
      pkg/tsdb/cloud-monitoring/kinds/dataquery/types_dataquery_gen.go
  38. 14
      pkg/tsdb/cloudwatch/annotation_query.go
  39. 8
      pkg/tsdb/cloudwatch/cloudwatch.go
  40. 50
      pkg/tsdb/cloudwatch/kinds/dataquery/types_dataquery_gen.go
  41. 8
      pkg/tsdb/cloudwatch/log_actions.go
  42. 7
      pkg/tsdb/cloudwatch/log_sync_query.go
  43. 9
      pkg/tsdb/cloudwatch/models/cloudwatch_query.go
  44. 12
      pkg/tsdb/cloudwatch/models/cloudwatch_query_test.go
  45. 9
      pkg/tsdb/cloudwatch/utils/utils.go
  46. 13
      pkg/tsdb/grafana-pyroscope-datasource/kinds/dataquery/types_dataquery_gen.go
  47. 20
      pkg/tsdb/grafana-pyroscope-datasource/query.go
  48. 38
      pkg/tsdb/grafana-testdata-datasource/kinds/dataquery/types_dataquery_gen.go
  49. 3
      pkg/tsdb/loki/healthcheck.go
  50. 9
      pkg/tsdb/loki/kinds/dataquery/types_dataquery_gen.go
  51. 11
      pkg/tsdb/loki/parse_query.go
  52. 8
      pkg/tsdb/loki/streaming.go
  53. 11
      pkg/tsdb/parca/kinds/dataquery/types_dataquery_gen.go
  54. 8
      pkg/tsdb/parca/query.go
  55. 9
      pkg/tsdb/tempo/kinds/dataquery/types_dataquery_gen.go
  56. 74
      public/app/plugins/gen.go

@ -624,10 +624,10 @@ playwright.config.ts @grafana/plugins-platform-frontend
# Kind system and code generation # Kind system and code generation
embed.go @grafana/grafana-as-code embed.go @grafana/grafana-as-code
/pkg/kinds/ @grafana/grafana-as-code /pkg/kinds/ @grafana/grafana-as-code
/pkg/cuectx/ @grafana/grafana-as-code
/pkg/registry/ @grafana/grafana-as-code /pkg/registry/ @grafana/grafana-as-code
/pkg/registry/apis/ @grafana/grafana-app-platform-squad /pkg/registry/apis/ @grafana/grafana-app-platform-squad
/pkg/codegen/ @grafana/grafana-as-code /pkg/codegen/ @grafana/grafana-as-code
/pkg/codegen/generators @grafana/grafana-as-code
/pkg/kinds/*/*_gen.go @grafana/grafana-as-code /pkg/kinds/*/*_gen.go @grafana/grafana-as-code
/pkg/registry/schemas/ @grafana/grafana-as-code /pkg/registry/schemas/ @grafana/grafana-as-code
/public/app/plugins/*gen.go @grafana/grafana-as-code /public/app/plugins/*gen.go @grafana/grafana-as-code

@ -6,5 +6,5 @@ import (
// CueSchemaFS embeds all schema-related CUE files in the Grafana project. // CueSchemaFS embeds all schema-related CUE files in the Grafana project.
// //
//go:embed cue.mod/module.cue kinds/*.cue kinds/*/*.cue packages/grafana-schema/src/common/*.cue public/app/plugins/*/*/*.cue public/app/plugins/*/*/plugin.json //go:embed cue.mod/module.cue
var CueSchemaFS embed.FS var CueSchemaFS embed.FS

@ -15,9 +15,6 @@ replace cuelang.org/go => github.com/grafana/cue v0.0.0-20230926092038-971951014
// import that instead of v0.X even though v0.X is newer. // import that instead of v0.X even though v0.X is newer.
replace github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.49.0 replace github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.49.0
// The v0.120.0 is needed for now to be compatible with grafana/thema.
replace github.com/getkin/kin-openapi => github.com/getkin/kin-openapi v0.120.0
require ( require (
cloud.google.com/go/storage v1.36.0 // @grafana/backend-platform cloud.google.com/go/storage v1.36.0 // @grafana/backend-platform
cuelang.org/go v0.6.0-0.dev // @grafana/grafana-as-code cuelang.org/go v0.6.0-0.dev // @grafana/grafana-as-code
@ -90,7 +87,6 @@ require (
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
github.com/urfave/cli/v2 v2.25.0 // @grafana/backend-platform github.com/urfave/cli/v2 v2.25.0 // @grafana/backend-platform
github.com/vectordotdev/go-datemath v0.1.1-0.20220323213446-f3954d0b18ae // @grafana/backend-platform github.com/vectordotdev/go-datemath v0.1.1-0.20220323213446-f3954d0b18ae // @grafana/backend-platform
github.com/yalue/merged_fs v1.2.2 // @grafana/grafana-as-code
github.com/yudai/gojsondiff v1.0.0 // @grafana/backend-platform github.com/yudai/gojsondiff v1.0.0 // @grafana/backend-platform
go.opentelemetry.io/collector/pdata v1.0.1 // @grafana/backend-platform go.opentelemetry.io/collector/pdata v1.0.1 // @grafana/backend-platform
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 // @grafana/grafana-operator-experience-squad go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 // @grafana/grafana-operator-experience-squad
@ -103,7 +99,7 @@ require (
golang.org/x/oauth2 v0.16.0 // @grafana/grafana-authnz-team golang.org/x/oauth2 v0.16.0 // @grafana/grafana-authnz-team
golang.org/x/sync v0.6.0 // @grafana/alerting-squad-backend golang.org/x/sync v0.6.0 // @grafana/alerting-squad-backend
golang.org/x/time v0.5.0 // @grafana/backend-platform golang.org/x/time v0.5.0 // @grafana/backend-platform
golang.org/x/tools v0.17.0 // indirect; @grafana/grafana-as-code golang.org/x/tools v0.17.0 // @grafana/grafana-as-code
gonum.org/v1/gonum v0.12.0 // @grafana/observability-metrics gonum.org/v1/gonum v0.12.0 // @grafana/observability-metrics
google.golang.org/api v0.155.0 // @grafana/backend-platform google.golang.org/api v0.155.0 // @grafana/backend-platform
google.golang.org/grpc v1.62.1 // @grafana/plugins-platform-backend google.golang.org/grpc v1.62.1 // @grafana/plugins-platform-backend
@ -113,7 +109,7 @@ require (
gopkg.in/mail.v2 v2.3.1 // @grafana/backend-platform gopkg.in/mail.v2 v2.3.1 // @grafana/backend-platform
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-squad-backend gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-squad-backend
xorm.io/builder v0.3.6 // @grafana/backend-platform xorm.io/builder v0.3.6 // indirect; @grafana/backend-platform
xorm.io/core v0.7.3 // @grafana/backend-platform xorm.io/core v0.7.3 // @grafana/backend-platform
xorm.io/xorm v0.8.2 // @grafana/alerting-squad-backend xorm.io/xorm v0.8.2 // @grafana/alerting-squad-backend
) )
@ -135,7 +131,7 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cheekybits/genny v1.0.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect
github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect
github.com/deepmap/oapi-codegen v1.12.4 // indirect github.com/deepmap/oapi-codegen v1.13.0 // @grafana/grafana-as-code
github.com/dennwc/varint v1.0.0 // indirect github.com/dennwc/varint v1.0.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/docker/go-units v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect
@ -160,12 +156,12 @@ require (
github.com/google/btree v1.1.2 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/flatbuffers v23.5.26+incompatible // indirect github.com/google/flatbuffers v23.5.26+incompatible // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // @grafana/backend-platform github.com/googleapis/gax-go/v2 v2.12.0 // @grafana/backend-platform
github.com/gorilla/mux v1.8.0 // @grafana/backend-platform github.com/gorilla/mux v1.8.1 // @grafana/backend-platform
github.com/grafana/grafana-google-sdk-go v0.1.0 // @grafana/partner-datasources github.com/grafana/grafana-google-sdk-go v0.1.0 // @grafana/partner-datasources
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect
github.com/hashicorp/go-multierror v1.1.1 // @grafana/alerting-squad github.com/hashicorp/go-multierror v1.1.1 // indirect; @grafana/alerting-squad
github.com/hashicorp/go-sockaddr v1.0.6 // indirect github.com/hashicorp/go-sockaddr v1.0.6 // indirect
github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect
@ -177,7 +173,7 @@ require (
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
github.com/mattetti/filebuffer v1.0.1 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/miekg/dns v1.1.57 // indirect github.com/miekg/dns v1.1.57 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@ -224,7 +220,6 @@ require (
github.com/bufbuild/connect-go v1.10.0 // @grafana/observability-traces-and-profiling github.com/bufbuild/connect-go v1.10.0 // @grafana/observability-traces-and-profiling
github.com/dlmiddlecote/sqlstats v1.0.2 // @grafana/backend-platform github.com/dlmiddlecote/sqlstats v1.0.2 // @grafana/backend-platform
github.com/drone/drone-cli v1.6.1 // @grafana/grafana-release-guild github.com/drone/drone-cli v1.6.1 // @grafana/grafana-release-guild
github.com/getkin/kin-openapi v0.120.0 // @grafana/grafana-operator-experience-squad
github.com/golang-migrate/migrate/v4 v4.7.0 // @grafana/backend-platform github.com/golang-migrate/migrate/v4 v4.7.0 // @grafana/backend-platform
github.com/google/go-github v17.0.0+incompatible // @grafana/grafana-release-guild github.com/google/go-github v17.0.0+incompatible // @grafana/grafana-release-guild
github.com/google/go-github/v45 v45.2.0 // @grafana/grafana-release-guild github.com/google/go-github/v45 v45.2.0 // @grafana/grafana-release-guild
@ -250,11 +245,9 @@ require (
github.com/go-jose/go-jose/v3 v3.0.3 // @grafana/grafana-authnz-team github.com/go-jose/go-jose/v3 v3.0.3 // @grafana/grafana-authnz-team
github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics
github.com/grafana/dataplane/sdata v0.0.7 // @grafana/observability-metrics github.com/grafana/dataplane/sdata v0.0.7 // @grafana/observability-metrics
github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482 // @grafana/grafana-as-code
github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b // @grafana/observability-traces-and-profiling github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b // @grafana/observability-traces-and-profiling
github.com/grafana/thema v0.0.0-20230712153715-375c1b45f3ed // @grafana/grafana-as-code
github.com/microsoft/go-mssqldb v1.6.1-0.20240214161942-b65008136246 // @grafana/grafana-bi-squad github.com/microsoft/go-mssqldb v1.6.1-0.20240214161942-b65008136246 // @grafana/grafana-bi-squad
github.com/redis/go-redis/v9 v9.0.2 // @grafana/alerting-squad-backend github.com/redis/go-redis/v9 v9.1.0 // @grafana/alerting-squad-backend
go.opentelemetry.io/contrib/samplers/jaegerremote v0.18.0 // @grafana/backend-platform go.opentelemetry.io/contrib/samplers/jaegerremote v0.18.0 // @grafana/backend-platform
golang.org/x/mod v0.14.0 // @grafana/backend-platform golang.org/x/mod v0.14.0 // @grafana/backend-platform
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // @grafana/partner-datasources k8s.io/utils v0.0.0-20230726121419-3b25d923346b // @grafana/partner-datasources
@ -298,9 +291,6 @@ require (
github.com/bwmarrin/snowflake v0.3.0 // @grafan/grafana-app-platform-squad github.com/bwmarrin/snowflake v0.3.0 // @grafan/grafana-app-platform-squad
github.com/centrifugal/protocol v0.10.0 // indirect github.com/centrifugal/protocol v0.10.0 // indirect
github.com/cloudflare/circl v1.3.7 // indirect github.com/cloudflare/circl v1.3.7 // indirect
github.com/cockroachdb/errors v1.9.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect
github.com/cockroachdb/redact v1.1.3 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@ -315,7 +305,6 @@ require (
github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/getsentry/sentry-go v0.12.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/googleapis v1.4.1 // indirect
@ -328,13 +317,12 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db // indirect github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // @grafana/alerting-squad-backend github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect; @grafana/alerting-squad-backend
github.com/hashicorp/memberlist v0.5.0 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/invopop/yaml v0.2.0 // indirect github.com/invopop/yaml v0.2.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-ieproxy v0.0.3 // indirect github.com/mattn/go-ieproxy v0.0.3 // indirect
@ -350,7 +338,6 @@ require (
github.com/redis/rueidis v1.0.16 // indirect github.com/redis/rueidis v1.0.16 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.3.4 // indirect github.com/rivo/uniseg v0.3.4 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect github.com/segmentio/asm v1.2.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect
@ -427,7 +414,7 @@ require (
github.com/imdario/mergo v0.3.16 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/compress v1.17.4 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/labstack/echo/v4 v4.10.2 // indirect github.com/labstack/echo/v4 v4.11.1 // indirect
github.com/labstack/gommon v0.4.0 // indirect github.com/labstack/gommon v0.4.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mschoch/smat v0.2.0 // indirect github.com/mschoch/smat v0.2.0 // indirect
@ -440,7 +427,6 @@ require (
require ( require (
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gnostic-models v0.6.8 // indirect
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 // @grafana/backend-platform github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 // @grafana/backend-platform
@ -486,9 +472,19 @@ require (
require github.com/jackc/pgx/v5 v5.5.5 // @grafana/oss-big-tent require github.com/jackc/pgx/v5 v5.5.5 // @grafana/oss-big-tent
require github.com/getkin/kin-openapi v0.120.0 // @grafana/grafana-as-code
require ( require (
github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/invopop/jsonschema v0.12.0 // indirect github.com/invopop/jsonschema v0.12.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
@ -500,7 +496,13 @@ require (
github.com/jcmturner/goidentity/v6 v6.0.1 // indirect github.com/jcmturner/goidentity/v6 v6.0.1 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/yudai/pp v2.0.1+incompatible // indirect
golang.org/x/arch v0.3.0 // indirect
) )
// Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream // Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream

155
go.sum

@ -1181,7 +1181,6 @@ gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zum
git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=
github.com/99designs/basicauth-go v0.0.0-20160802081356-2a93ba0f464d/go.mod h1:3cARGAK9CfW3HoxCy1a0G4TKrdiKke8ftOMEOHyySYs= github.com/99designs/basicauth-go v0.0.0-20160802081356-2a93ba0f464d/go.mod h1:3cARGAK9CfW3HoxCy1a0G4TKrdiKke8ftOMEOHyySYs=
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY= github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI=
github.com/Azure/azure-amqp-common-go/v3 v3.2.2/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= github.com/Azure/azure-amqp-common-go/v3 v3.2.2/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI=
github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U=
@ -1278,8 +1277,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
github.com/Code-Hex/go-generics-cache v1.3.1 h1:i8rLwyhoyhaerr7JpjtYjJZUcCbWOdiYO3fZXLiEC4g= github.com/Code-Hex/go-generics-cache v1.3.1 h1:i8rLwyhoyhaerr7JpjtYjJZUcCbWOdiYO3fZXLiEC4g=
github.com/Code-Hex/go-generics-cache v1.3.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= github.com/Code-Hex/go-generics-cache v1.3.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
@ -1291,7 +1288,6 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
@ -1320,7 +1316,6 @@ github.com/RoaringBitmap/real-roaring-datasets v0.0.0-20190726190000-eb7c87156f7
github.com/RoaringBitmap/roaring v0.9.1/go.mod h1:h1B7iIUOmnAeb5ytYMvnHJwxMc6LUrwBnzXWRuqTQUc= github.com/RoaringBitmap/roaring v0.9.1/go.mod h1:h1B7iIUOmnAeb5ytYMvnHJwxMc6LUrwBnzXWRuqTQUc=
github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo= github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXlp4riwo=
github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
@ -1329,7 +1324,6 @@ github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3H
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
@ -1447,7 +1441,6 @@ github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE=
github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f h1:y06x6vGnFYfXUoVMbrcP1Uzpj4JG01eB5vRps9G8agM= github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f h1:y06x6vGnFYfXUoVMbrcP1Uzpj4JG01eB5vRps9G8agM=
github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f/go.mod h1:2stgcRjl6QmW+gU2h5E7BQXg4HU0gzxKWDuT5HviN9s= github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f/go.mod h1:2stgcRjl6QmW+gU2h5E7BQXg4HU0gzxKWDuT5HviN9s=
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
@ -1493,10 +1486,10 @@ github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0=
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/bsm/ginkgo/v2 v2.5.0 h1:aOAnND1T40wEdAtkGSkvSICWeQ8L3UASX7YVCqQx+eQ= github.com/bsm/ginkgo/v2 v2.9.5 h1:rtVBYPs3+TC5iLUVOis1B9tjLTup7Cj5IfzosKtvTJ0=
github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/ginkgo/v2 v2.9.5/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.20.0 h1:JhAwLmtRzXFTx2AkALSLa8ijZafntmhSoU63Ok18Uq8= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg= github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg=
github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8= github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
@ -1508,6 +1501,9 @@ github.com/buildkite/yaml v2.1.0+incompatible/go.mod h1:UoU8vbcwu1+vjZq01+KrpSeL
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds= github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds=
github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI= github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
@ -1530,6 +1526,9 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89 h1:aPflPkRFkVwbW6dmcVqfgwp1i+UWGFH6VgR1Jim5Ygc= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89 h1:aPflPkRFkVwbW6dmcVqfgwp1i+UWGFH6VgR1Jim5Ygc=
github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=
@ -1570,15 +1569,7 @@ github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b80
github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw=
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8=
github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk=
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74=
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@ -1621,16 +1612,14 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4= github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
github.com/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP7g5Q2s= github.com/deepmap/oapi-codegen v1.13.0 h1:cnFHelhsRQbYvanCUAbRSn/ZpkUb1HPRlQcu8YqSORQ=
github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas= github.com/deepmap/oapi-codegen v1.13.0/go.mod h1:Amy7tbubKY9qkZOXqymI3Z6xSbndmu+atMJheLdyg44=
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU=
github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY=
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
@ -1681,7 +1670,6 @@ github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 h1:1L0aalTpPz7YlMxETKpmQoWMBkeiuorElZIXoNmgiPE= github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 h1:1L0aalTpPz7YlMxETKpmQoWMBkeiuorElZIXoNmgiPE=
github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
@ -1719,11 +1707,9 @@ github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87K
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
@ -1732,7 +1718,6 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@ -1754,27 +1739,23 @@ github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyT
github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk=
github.com/fullstorydev/grpchan v1.1.1 h1:heQqIJlAv5Cnks9a70GRL2EJke6QQoUB25VGR6TZQas= github.com/fullstorydev/grpchan v1.1.1 h1:heQqIJlAv5Cnks9a70GRL2EJke6QQoUB25VGR6TZQas=
github.com/fullstorydev/grpchan v1.1.1/go.mod h1:f4HpiV8V6htfY/K44GWV1ESQzHBTq7DinhzqQ95lpgc= github.com/fullstorydev/grpchan v1.1.1/go.mod h1:f4HpiV8V6htfY/K44GWV1ESQzHBTq7DinhzqQ95lpgc=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gchaincl/sqlhooks v1.3.0 h1:yKPXxW9a5CjXaVf2HkQn6wn7TZARvbAOAelr3H8vK2Y= github.com/gchaincl/sqlhooks v1.3.0 h1:yKPXxW9a5CjXaVf2HkQn6wn7TZARvbAOAelr3H8vK2Y=
github.com/gchaincl/sqlhooks v1.3.0/go.mod h1:9BypXnereMT0+Ys8WGWHqzgkkOfHIhyeUCqXC24ra34= github.com/gchaincl/sqlhooks v1.3.0/go.mod h1:9BypXnereMT0+Ys8WGWHqzgkkOfHIhyeUCqXC24ra34=
github.com/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg= github.com/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg=
github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw= github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw=
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew=
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
@ -1817,7 +1798,6 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY=
github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo=
github.com/go-openapi/analysis v0.21.5/go.mod h1:25YcZosX9Lwz2wBsrFrrsL8bmjjXdlyP6zsr2AMy29M= github.com/go-openapi/analysis v0.21.5/go.mod h1:25YcZosX9Lwz2wBsrFrrsL8bmjjXdlyP6zsr2AMy29M=
@ -1881,10 +1861,18 @@ github.com/go-openapi/validate v0.23.0/go.mod h1:EeiAZ5bmpSIOJV1WLfyYF9qp/B1ZgSa
github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-resty/resty/v2 v2.9.1/go.mod h1:4/GYJVjh9nhkhGR6AUNW3XhpDYNUr+Uvy9gV/VGZIy4= github.com/go-resty/resty/v2 v2.9.1/go.mod h1:4/GYJVjh9nhkhGR6AUNW3XhpDYNUr+Uvy9gV/VGZIy4=
@ -1961,11 +1949,9 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg=
github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@ -2033,7 +2019,6 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219 h1:utua3L2IbQJmauC5IXdEA547bcoU5dozgQAfc8Onsg4= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219 h1:utua3L2IbQJmauC5IXdEA547bcoU5dozgQAfc8Onsg4=
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
@ -2163,9 +2148,11 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@ -2190,8 +2177,6 @@ github.com/grafana/gofpdf v0.0.0-20231002120153-857cc45be447 h1:jxJJ5z0GxqhWFbQU
github.com/grafana/gofpdf v0.0.0-20231002120153-857cc45be447/go.mod h1:IxsY6mns6Q5sAnWcrptrgUrSglTZJXH/kXr9nbpb/9I= github.com/grafana/gofpdf v0.0.0-20231002120153-857cc45be447/go.mod h1:IxsY6mns6Q5sAnWcrptrgUrSglTZJXH/kXr9nbpb/9I=
github.com/grafana/grafana-aws-sdk v0.25.0 h1:XNi3iA/C/KPArmVbQfbwKQROaIotd38nCRjNE6P1UP0= github.com/grafana/grafana-aws-sdk v0.25.0 h1:XNi3iA/C/KPArmVbQfbwKQROaIotd38nCRjNE6P1UP0=
github.com/grafana/grafana-aws-sdk v0.25.0/go.mod h1:3zghFF6edrxn0d6k6X9HpGZXDH+VfA+MwD2Pc/9X0ec= github.com/grafana/grafana-aws-sdk v0.25.0/go.mod h1:3zghFF6edrxn0d6k6X9HpGZXDH+VfA+MwD2Pc/9X0ec=
github.com/grafana/grafana-azure-sdk-go v1.13.1 h1:zYw5kNYf4zS4mG+yuB0Izn1Z4rsrPdLLivWF2JHUXPk=
github.com/grafana/grafana-azure-sdk-go v1.13.1/go.mod h1:SAlwLdEuox4vw8ZaeQwnepYXnhznnQQdstJbcw8LH68=
github.com/grafana/grafana-azure-sdk-go/v2 v2.0.1 h1:a/zb8uX7EvmS2YAFbYPyGEnZP8jMp7WppAm05Qtunok= github.com/grafana/grafana-azure-sdk-go/v2 v2.0.1 h1:a/zb8uX7EvmS2YAFbYPyGEnZP8jMp7WppAm05Qtunok=
github.com/grafana/grafana-azure-sdk-go/v2 v2.0.1/go.mod h1:nW7pr7POOGafhyOrq8V0ouXBcXTmpRCer3sDAfeSV+Y= github.com/grafana/grafana-azure-sdk-go/v2 v2.0.1/go.mod h1:nW7pr7POOGafhyOrq8V0ouXBcXTmpRCer3sDAfeSV+Y=
github.com/grafana/grafana-google-sdk-go v0.1.0 h1:LKGY8z2DSxKjYfr2flZsWgTRTZ6HGQbTqewE3JvRaNA= github.com/grafana/grafana-google-sdk-go v0.1.0 h1:LKGY8z2DSxKjYfr2flZsWgTRTZ6HGQbTqewE3JvRaNA=
@ -2209,8 +2194,6 @@ github.com/grafana/grafana/pkg/promlib v0.0.2 h1:yy7iwHlHH7Hl/n7ix9+RPIKg3CcKCAS
github.com/grafana/grafana/pkg/promlib v0.0.2/go.mod h1:3El4NlsfALz8QQCbEGHGFvJUG+538QLMuALRhZ3pcoo= github.com/grafana/grafana/pkg/promlib v0.0.2/go.mod h1:3El4NlsfALz8QQCbEGHGFvJUG+538QLMuALRhZ3pcoo=
github.com/grafana/grafana/pkg/util/xorm v0.0.1 h1:72QZjxWIWpSeOF8ob4aMV058kfgZyeetkAB8dmeti2o= github.com/grafana/grafana/pkg/util/xorm v0.0.1 h1:72QZjxWIWpSeOF8ob4aMV058kfgZyeetkAB8dmeti2o=
github.com/grafana/grafana/pkg/util/xorm v0.0.1/go.mod h1:eNfbB9f2jM8o9RfwqwjY8SYm5tvowJ8Ly+iE4P9rXII= github.com/grafana/grafana/pkg/util/xorm v0.0.1/go.mod h1:eNfbB9f2jM8o9RfwqwjY8SYm5tvowJ8Ly+iE4P9rXII=
github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482 h1:1YNoeIhii4UIIQpCPU+EXidnqf449d0C3ZntAEt4KSo=
github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482/go.mod h1:GNcfpy5+SY6RVbNGQW264gC0r336Dm+0zgQ5vt6+M8Y=
github.com/grafana/prometheus-alertmanager v0.25.1-0.20240208102907-e82436ce63e6 h1:CBm0rwLCPDyarg9/bHJ50rBLYmyMDoyCWpgRMITZhdA= github.com/grafana/prometheus-alertmanager v0.25.1-0.20240208102907-e82436ce63e6 h1:CBm0rwLCPDyarg9/bHJ50rBLYmyMDoyCWpgRMITZhdA=
github.com/grafana/prometheus-alertmanager v0.25.1-0.20240208102907-e82436ce63e6/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE= github.com/grafana/prometheus-alertmanager v0.25.1-0.20240208102907-e82436ce63e6/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE=
github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo=
@ -2226,8 +2209,6 @@ github.com/grafana/sqlds/v3 v3.2.0 h1:WXuYEaFfiCvgm8kK2ixx44/zAEjFzCylA2+RF3GBqZ
github.com/grafana/sqlds/v3 v3.2.0/go.mod h1:kH0WuHUR3j0Q7IEymbm2JiaPckUhRCbqjV9ajaBAnmM= github.com/grafana/sqlds/v3 v3.2.0/go.mod h1:kH0WuHUR3j0Q7IEymbm2JiaPckUhRCbqjV9ajaBAnmM=
github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b h1:mDlkqgTEJuK7vjPG44f3ZMtId5AAYLWHvBVbiGqIOOQ= github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b h1:mDlkqgTEJuK7vjPG44f3ZMtId5AAYLWHvBVbiGqIOOQ=
github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b/go.mod h1:UK7kTP5llPeRcGBOe5mm4QTNTd0k/mAqTVSOFdDH6AU= github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b/go.mod h1:UK7kTP5llPeRcGBOe5mm4QTNTd0k/mAqTVSOFdDH6AU=
github.com/grafana/thema v0.0.0-20230712153715-375c1b45f3ed h1:TMtHc+B0SSNw2in6Ro1dAiBYSPRp4NzKgndFDfupt18=
github.com/grafana/thema v0.0.0-20230712153715-375c1b45f3ed/go.mod h1:3zLJnssFRPCnebCBRlq53t5LgYv9P1mbj0XMozZMTww=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
@ -2340,7 +2321,6 @@ github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@ -2351,7 +2331,6 @@ github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@ -2368,11 +2347,6 @@ github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/ionos-cloud/sdk-go/v6 v6.1.10 h1:3815Q2Hw/wc4cJ8wD7bwfsmDsdfIEp80B7BQMj0YP2w= github.com/ionos-cloud/sdk-go/v6 v6.1.10 h1:3815Q2Hw/wc4cJ8wD7bwfsmDsdfIEp80B7BQMj0YP2w=
github.com/ionos-cloud/sdk-go/v6 v6.1.10/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= github.com/ionos-cloud/sdk-go/v6 v6.1.10/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk=
github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g=
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
@ -2477,15 +2451,9 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= 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/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8=
github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE=
github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro=
github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
@ -2494,8 +2462,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4=
github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
@ -2505,7 +2471,6 @@ github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHU
github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@ -2533,16 +2498,16 @@ github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLg
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ=
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353 h1:X/79QL0b4YJVO5+OsPH9rF2u428CIrGL/jLmPsoOQQ4= github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353 h1:X/79QL0b4YJVO5+OsPH9rF2u428CIrGL/jLmPsoOQQ4=
github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353/go.mod h1:N0SVk0uhy+E1PZ3C9ctsPRlvOPAFPkCNlcPBDkt0N3U= github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353/go.mod h1:N0SVk0uhy+E1PZ3C9ctsPRlvOPAFPkCNlcPBDkt0N3U=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
@ -2583,7 +2548,6 @@ github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PT
github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs= github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@ -2600,7 +2564,6 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
@ -2611,22 +2574,19 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI=
github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
github.com/microsoft/go-mssqldb v1.6.1-0.20240214161942-b65008136246 h1:KT4vTYcHqj5C5hMK5kSpyAk7MnFqfHVWLL4VqMq66S8= github.com/microsoft/go-mssqldb v1.6.1-0.20240214161942-b65008136246 h1:KT4vTYcHqj5C5hMK5kSpyAk7MnFqfHVWLL4VqMq66S8=
github.com/microsoft/go-mssqldb v1.6.1-0.20240214161942-b65008136246/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= github.com/microsoft/go-mssqldb v1.6.1-0.20240214161942-b65008136246/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
@ -2703,7 +2663,6 @@ github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto= github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto=
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY= github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
@ -2746,7 +2705,6 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
@ -2819,6 +2777,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
@ -2834,8 +2794,6 @@ github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuR
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
@ -2924,8 +2882,8 @@ github.com/prometheus/prometheus v0.49.0/go.mod h1:aDogiyqmv3aBIWDb5z5Sdcxuuf2BO
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b h1:zd/2RNzIRkoGGMjE+YIsZ85CnDIz672JK2F3Zl4vux4= github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b h1:zd/2RNzIRkoGGMjE+YIsZ85CnDIz672JK2F3Zl4vux4=
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b/go.mod h1:KjY0wibdYKc4DYkerHSbguaf3JeIPGhNJBp2BNiFH78= github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b/go.mod h1:KjY0wibdYKc4DYkerHSbguaf3JeIPGhNJBp2BNiFH78=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/redis/go-redis/v9 v9.0.2 h1:BA426Zqe/7r56kCcvxYLWe1mkaz71LKF77GwgFzSxfE= github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY=
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps= github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c=
github.com/redis/rueidis v1.0.16 h1:ieB3AqZe9GcuTWZL8PFu1Mfn+pfqjBZAJEZh7zOcwSI= github.com/redis/rueidis v1.0.16 h1:ieB3AqZe9GcuTWZL8PFu1Mfn+pfqjBZAJEZh7zOcwSI=
github.com/redis/rueidis v1.0.16/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo= github.com/redis/rueidis v1.0.16/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
@ -2944,7 +2902,6 @@ github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
@ -2971,7 +2928,6 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21 h1:yWfiTPwYxB0l5fGMhl/G+liULugVIHD9AU77iNLrURQ= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21 h1:yWfiTPwYxB0l5fGMhl/G+liULugVIHD9AU77iNLrURQ=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
github.com/scottlepp/go-duck v0.0.15 h1:qrSF3pXlXAA4a7uxAfLYajqXLkeBjv8iW1wPdSfkMj0= github.com/scottlepp/go-duck v0.0.15 h1:qrSF3pXlXAA4a7uxAfLYajqXLkeBjv8iW1wPdSfkMj0=
github.com/scottlepp/go-duck v0.0.15/go.mod h1:GL+hHuKdueJRrFCduwBc7A7TQk+Tetc5BPXPVtduihY= github.com/scottlepp/go-duck v0.0.15/go.mod h1:GL+hHuKdueJRrFCduwBc7A7TQk+Tetc5BPXPVtduihY=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
@ -2981,7 +2937,6 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/segmentio/encoding v0.3.6 h1:E6lVLyDPseWEulBmCmAKPanDd3jiyGDo5gMcugCRwZQ= github.com/segmentio/encoding v0.3.6 h1:E6lVLyDPseWEulBmCmAKPanDd3jiyGDo5gMcugCRwZQ=
github.com/segmentio/encoding v0.3.6/go.mod h1:n0JeuIqEQrQoPDGsjo8UNd1iA0U8d8+oHAA4E3G3OxM= github.com/segmentio/encoding v0.3.6/go.mod h1:n0JeuIqEQrQoPDGsjo8UNd1iA0U8d8+oHAA4E3G3OxM=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shoenig/test v0.6.6/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shoenig/test v0.6.6/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
@ -3079,19 +3034,19 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f h1:A+MmlgpvrHLeUP8dkBVn4Pnf5Bp5Yk2OALm7SEJLLE8= github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f h1:A+MmlgpvrHLeUP8dkBVn4Pnf5Bp5Yk2OALm7SEJLLE8=
github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f/go.mod h1:OBcG9bn7sHtXgarhUEb3OfCnNsgtGnkVf41ilSZ3K3E= github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f/go.mod h1:OBcG9bn7sHtXgarhUEb3OfCnNsgtGnkVf41ilSZ3K3E=
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 h1:aVGB3YnaS/JNfOW3tiHIlmNmTDg618va+eT0mVomgyI= github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 h1:aVGB3YnaS/JNfOW3tiHIlmNmTDg618va+eT0mVomgyI=
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8/go.mod h1:fVle4kNr08ydeohzYafr20oZzbAkhQT39gKK/pFQ5M4= github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8/go.mod h1:fVle4kNr08ydeohzYafr20oZzbAkhQT39gKK/pFQ5M4=
github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
@ -3104,15 +3059,11 @@ github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
github.com/urfave/cli/v2 v2.25.0 h1:ykdZKuQey2zq0yin/l7JOm9Mh+pg72ngYMeB0ABn6q8= github.com/urfave/cli/v2 v2.25.0 h1:ykdZKuQey2zq0yin/l7JOm9Mh+pg72ngYMeB0ABn6q8=
github.com/urfave/cli/v2 v2.25.0/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/urfave/cli/v2 v2.25.0/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vectordotdev/go-datemath v0.1.1-0.20220323213446-f3954d0b18ae h1:oyiy3uBj1F4O3AaFh7hUGBrJjAssJhKyAbwxtkslxqo= github.com/vectordotdev/go-datemath v0.1.1-0.20220323213446-f3954d0b18ae h1:oyiy3uBj1F4O3AaFh7hUGBrJjAssJhKyAbwxtkslxqo=
github.com/vectordotdev/go-datemath v0.1.1-0.20220323213446-f3954d0b18ae/go.mod h1:PnwzbSst7KD3vpBzzlntZU5gjVa455Uqa5QPiKSYJzQ= github.com/vectordotdev/go-datemath v0.1.1-0.20220323213446-f3954d0b18ae/go.mod h1:PnwzbSst7KD3vpBzzlntZU5gjVa455Uqa5QPiKSYJzQ=
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
@ -3145,9 +3096,6 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRT
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryBNl9eKOeqQ58Y/Qpo3Q9QNxKHX5uzzQ= github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryBNl9eKOeqQ58Y/Qpo3Q9QNxKHX5uzzQ=
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY= github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY=
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
github.com/yalue/merged_fs v1.2.2 h1:vXHTpJBluJryju7BBpytr3PDIkzsPMpiEknxVGPhN/I=
github.com/yalue/merged_fs v1.2.2/go.mod h1:WqqchfVYQyclV2tnR7wtRhBddzBvLVR83Cjw9BKQw0M=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
@ -3301,6 +3249,9 @@ go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
gocloud.dev v0.25.0 h1:Y7vDq8xj7SyM848KXf32Krda2e6jQ4CLh/mTeCSqXtk= gocloud.dev v0.25.0 h1:Y7vDq8xj7SyM848KXf32Krda2e6jQ4CLh/mTeCSqXtk=
gocloud.dev v0.25.0/go.mod h1:7HegHVCYZrMiU3IE1qtnzf/vRrDwLYnRNR3EhWX8x9Y= gocloud.dev v0.25.0/go.mod h1:7HegHVCYZrMiU3IE1qtnzf/vRrDwLYnRNR3EhWX8x9Y=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@ -3316,7 +3267,6 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -3326,7 +3276,6 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@ -3441,7 +3390,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -3452,7 +3400,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -3490,7 +3437,6 @@ golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@ -3622,7 +3568,6 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -3796,7 +3741,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/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.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -3809,14 +3753,12 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@ -4332,18 +4274,14 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo=
gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
@ -4361,7 +4299,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -1,7 +0,0 @@
package kind
import "github.com/grafana/kindsys"
// In each child directory, the set of .cue files with 'package kind'
// must be an instance of kindsys.Core - a declaration of a core kind.
kindsys.Core

@ -15,37 +15,49 @@ import (
"sort" "sort"
"strings" "strings"
"cuelang.org/go/cue/errors" "cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/load"
"github.com/grafana/codejen" "github.com/grafana/codejen"
"github.com/grafana/cuetsy" "github.com/grafana/cuetsy"
"github.com/grafana/kindsys"
"github.com/grafana/grafana/pkg/codegen" "github.com/grafana/grafana/pkg/codegen"
"github.com/grafana/grafana/pkg/cuectx"
) )
// CoreDefParentPath is the path, relative to the repository root, where
// each child directory is expected to contain .cue files defining one
// Core kind.
var CoreDefParentPath = "kinds"
// TSCoreKindParentPath is the path, relative to the repository root, to the directory that
// contains one directory per kind, full of generated TS kind output: types and default consts.
var TSCoreKindParentPath = filepath.Join("packages", "grafana-schema", "src", "raw")
func main() { func main() {
if len(os.Args) > 1 { if len(os.Args) > 1 {
fmt.Fprintf(os.Stderr, "plugin thema code generator does not currently accept any arguments\n, got %q", os.Args) fmt.Fprintf(os.Stderr, "code generator does not currently accept any arguments\n, got %q", os.Args)
os.Exit(1) os.Exit(1)
} }
// Core kinds composite code generator. Produces all generated code in // Core kinds composite code generator. Produces all generated code in
// grafana/grafana that derives from core kinds. // grafana/grafana that derives from core kinds.
coreKindsGen := codejen.JennyListWithNamer(func(def kindsys.Kind) string { coreKindsGen := codejen.JennyListWithNamer(func(def codegen.SchemaForGen) string {
return def.Props().Common().MachineName return def.Name
}) })
// All the jennies that comprise the core kinds generator pipeline // All the jennies that comprise the core kinds generator pipeline
coreKindsGen.Append( coreKindsGen.Append(
&codegen.GoSpecJenny{}, &codegen.GoSpecJenny{},
codegen.LatestMajorsOrXJenny(cuectx.TSCoreKindParentPath), &codegen.K8ResourcesJenny{},
&codegen.CoreRegistryJenny{},
codegen.LatestMajorsOrXJenny(TSCoreKindParentPath),
codegen.TSVeneerIndexJenny(filepath.Join("packages", "grafana-schema", "src")), codegen.TSVeneerIndexJenny(filepath.Join("packages", "grafana-schema", "src")),
) )
header := codegen.SlashHeaderMapper("kinds/gen.go") header := codegen.SlashHeaderMapper("kinds/gen.go")
coreKindsGen.AddPostprocessors(header) coreKindsGen.AddPostprocessors(header)
ctx := cuecontext.New()
cwd, err := os.Getwd() cwd, err := os.Getwd()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "could not get working directory: %s", err) fmt.Fprintf(os.Stderr, "could not get working directory: %s", err)
@ -53,29 +65,15 @@ func main() {
} }
groot := filepath.Dir(cwd) groot := filepath.Dir(cwd)
rt := cuectx.GrafanaThemaRuntime() f := os.DirFS(filepath.Join(groot, CoreDefParentPath))
var all []kindsys.Kind
f := os.DirFS(filepath.Join(groot, cuectx.CoreDefParentPath))
kinddirs := elsedie(fs.ReadDir(f, "."))("error reading core kind fs root directory") kinddirs := elsedie(fs.ReadDir(f, "."))("error reading core kind fs root directory")
for _, kinddir := range kinddirs { all, err := loadCueFiles(ctx, kinddirs)
if !kinddir.IsDir() {
continue
}
rel := filepath.Join(cuectx.CoreDefParentPath, kinddir.Name())
def, err := cuectx.LoadCoreKindDef(rel, rt.Context(), nil)
if err != nil { if err != nil {
die(fmt.Errorf("%s is not a valid kind: %s", rel, errors.Details(err, nil))) die(err)
}
if def.Properties.MachineName != kinddir.Name() {
die(fmt.Errorf("%s: kind's machine name (%s) must equal parent dir name (%s)", rel, def.Properties.Name, kinddir.Name()))
}
all = append(all, elsedie(kindsys.BindCore(rt, def))(rel))
} }
sort.Slice(all, func(i, j int) bool { sort.Slice(all, func(i, j int) bool {
return nameFor(all[i].Props()) < nameFor(all[j].Props()) return all[i].Name < all[j].Name
}) })
jfs, err := coreKindsGen.GenerateFS(all...) jfs, err := coreKindsGen.GenerateFS(all...)
@ -83,22 +81,12 @@ func main() {
die(fmt.Errorf("core kinddirs codegen failed: %w", err)) die(fmt.Errorf("core kinddirs codegen failed: %w", err))
} }
commfsys := elsedie(genCommon(filepath.Join(groot, "pkg", "kindsys")))("common schemas failed") commfsys := elsedie(genCommon(ctx, groot))("common schemas failed")
commfsys = elsedie(commfsys.Map(header))("failed gen header on common fsys") commfsys = elsedie(commfsys.Map(header))("failed gen header on common fsys")
if err = jfs.Merge(commfsys); err != nil { if err = jfs.Merge(commfsys); err != nil {
die(err) die(err)
} }
// Merging k8 resources
rawResources, err := genRawResources(kinddirs)
if err != nil {
die(err)
}
if err = jfs.Merge(rawResources); err != nil {
die(err)
}
if _, set := os.LookupEnv("CODEGEN_VERIFY"); set { if _, set := os.LookupEnv("CODEGEN_VERIFY"); set {
if err = jfs.Verify(context.Background(), groot); err != nil { if err = jfs.Verify(context.Background(), groot); err != nil {
die(fmt.Errorf("generated code is out of sync with inputs:\n%s\nrun `make gen-cue` to regenerate", err)) die(fmt.Errorf("generated code is out of sync with inputs:\n%s\nrun `make gen-cue` to regenerate", err))
@ -108,43 +96,28 @@ func main() {
} }
} }
func nameFor(m kindsys.SomeKindProperties) string {
switch x := m.(type) {
case kindsys.CoreProperties:
return x.Name
case kindsys.CustomProperties:
return x.Name
case kindsys.ComposableProperties:
return x.Name
default:
// unreachable so long as all the possibilities in KindProperties have switch branches
panic("unreachable")
}
}
type dummyCommonJenny struct{} type dummyCommonJenny struct{}
func genCommon(kp string) (*codejen.FS, error) { func genCommon(ctx *cue.Context, groot string) (*codejen.FS, error) {
fsys := codejen.NewFS() fsys := codejen.NewFS()
// kp := filepath.Join("pkg", "kindsys")
path := filepath.Join("packages", "grafana-schema", "src", "common") path := filepath.Join("packages", "grafana-schema", "src", "common")
// Grab all the common_* files from kindsys and load them in
dfsys := os.DirFS(kp)
matches := elsedie(fs.Glob(dfsys, "common_*.cue"))("could not glob kindsys cue files")
for _, fname := range matches {
fpath := filepath.Join(path, strings.TrimPrefix(fname, "common_"))
fpath = fpath[:len(fpath)-4] + "_gen.cue"
data := elsedie(fs.ReadFile(dfsys, fname))("error reading " + fname)
_ = fsys.Add(*codejen.NewFile(fpath, data, dummyCommonJenny{}))
}
fsys = elsedie(fsys.Map(packageMapper))("failed remapping fs") fsys = elsedie(fsys.Map(packageMapper))("failed remapping fs")
v, err := cuectx.BuildGrafanaInstance(nil, path, "", nil) commonFiles := make([]string, 0)
if err != nil { filepath.WalkDir(filepath.Join(groot, path), func(path string, d fs.DirEntry, err error) error {
return nil, err if d.IsDir() || filepath.Ext(d.Name()) != ".cue" {
return nil
}
commonFiles = append(commonFiles, path)
return nil
})
instance := load.Instances(commonFiles, &load.Config{})[0]
if instance.Err != nil {
return nil, instance.Err
} }
v := ctx.BuildInstance(instance)
b := elsedie(cuetsy.Generate(v, cuetsy.Config{ b := elsedie(cuetsy.Generate(v, cuetsy.Config{
Export: true, Export: true,
}))("failed to generate common schema TS") }))("failed to generate common schema TS")
@ -186,26 +159,8 @@ func die(err error) {
os.Exit(1) os.Exit(1)
} }
// Resource generation without using Thema func loadCueFiles(ctx *cue.Context, dirs []os.DirEntry) ([]codegen.SchemaForGen, error) {
func genRawResources(dirs []os.DirEntry) (*codejen.FS, error) { values := make([]codegen.SchemaForGen, 0)
jenny := codejen.JennyListWithNamer[[]codegen.CueSchema](func(_ []codegen.CueSchema) string {
return "RawResources"
})
jenny.Append(
&codegen.K8ResourcesJenny{},
&codegen.CoreRegistryJenny{},
)
header := codegen.SlashHeaderMapper("kinds/gen.go")
jenny.AddPostprocessors(header)
return jenny.GenerateFS(loadCueFiles(dirs))
}
func loadCueFiles(dirs []os.DirEntry) []codegen.CueSchema {
ctx := cuectx.GrafanaCUEContext()
values := make([]codegen.CueSchema, 0)
for _, dir := range dirs { for _, dir := range dirs {
if !dir.IsDir() { if !dir.IsDir() {
continue continue
@ -225,13 +180,33 @@ func loadCueFiles(dirs []os.DirEntry) []codegen.CueSchema {
os.Exit(1) os.Exit(1)
} }
sch := codegen.CueSchema{ v := ctx.CompileBytes(cueFile)
FilePath: "./" + filepath.Join(cuectx.CoreDefParentPath, entry), name, err := getSchemaName(v)
CueFile: ctx.CompileBytes(cueFile), if err != nil {
return nil, err
}
sch := codegen.SchemaForGen{
Name: name,
FilePath: "./" + filepath.Join(CoreDefParentPath, entry),
CueFile: v,
IsGroup: false,
OutputName: strings.ToLower(name),
} }
values = append(values, sch) values = append(values, sch)
} }
return values return values, nil
}
func getSchemaName(v cue.Value) (string, error) {
namePath := v.LookupPath(cue.ParsePath("name"))
name, err := namePath.String()
if err != nil {
return "", fmt.Errorf("file doesn't have name field set: %s", err)
}
name = strings.Replace(name, "-", "_", -1)
return name, nil
} }

@ -7,14 +7,12 @@ import (
"cuelang.org/go/cue" "cuelang.org/go/cue"
"github.com/grafana/codejen" "github.com/grafana/codejen"
"github.com/grafana/kindsys"
"github.com/grafana/thema"
) )
type OneToOne codejen.OneToOne[kindsys.Kind] type OneToOne codejen.OneToOne[SchemaForGen]
type OneToMany codejen.OneToMany[kindsys.Kind] type OneToMany codejen.OneToMany[SchemaForGen]
type ManyToOne codejen.ManyToOne[kindsys.Kind] type ManyToOne codejen.ManyToOne[SchemaForGen]
type ManyToMany codejen.ManyToMany[kindsys.Kind] type ManyToMany codejen.ManyToMany[SchemaForGen]
// SlashHeaderMapper produces a FileMapper that injects a comment header onto // SlashHeaderMapper produces a FileMapper that injects a comment header onto
// a [codejen.File] indicating the main generator that produced it (via the provided // a [codejen.File] indicating the main generator that produced it (via the provided
@ -47,21 +45,10 @@ func SlashHeaderMapper(maingen string) codejen.FileMapper {
} }
} }
// SchemaForGen is an intermediate values type for jennies that holds both a thema.Schema,
// and values relevant to generating the schema that should properly, eventually, be in
// thema itself.
//
// TODO this will be replaced by thema-native constructs
type SchemaForGen struct { type SchemaForGen struct {
// The PascalCase name of the schematized type.
Name string Name string
// The schema to be rendered for the type itself.
Schema thema.Schema
// Whether the schema is grouped. See https://github.com/grafana/thema/issues/62
IsGroup bool
}
type CueSchema struct {
CueFile cue.Value CueFile cue.Value
FilePath string FilePath string
IsGroup bool
OutputName string // Some TS output files are capitalised and others not.
} }

@ -0,0 +1,282 @@
package generators
import (
"fmt"
"regexp"
"strings"
"unicode"
"github.com/dave/dst"
"github.com/dave/dst/dstutil"
)
// depointerizer returns an AST manipulator that removes redundant
// pointer indirection from the defined types.
func depointerizer() dstutil.ApplyFunc {
return func(c *dstutil.Cursor) bool {
switch x := c.Node().(type) {
case *dst.Field:
if s, is := x.Type.(*dst.StarExpr); is {
switch deref := depoint(s).(type) {
case *dst.ArrayType, *dst.MapType:
x.Type = deref
}
}
}
return true
}
}
func depoint(e dst.Expr) dst.Expr {
if star, is := e.(*dst.StarExpr); is {
return star.X
}
return e
}
func setStar(e dst.Expr) string {
if _, is := e.(*dst.StarExpr); is {
return "*"
}
return ""
}
func fixTODOComments() dstutil.ApplyFunc {
return func(cursor *dstutil.Cursor) bool {
switch f := cursor.Node().(type) {
case *dst.File:
for _, d := range f.Decls {
if isTypeSpec(d) {
removeGoFieldComment(d.Decorations().Start.All())
}
fixTODOComment(d.Decorations().Start.All())
}
case *dst.Field:
if len(f.Names) > 0 {
removeGoFieldComment(f.Decorations().Start.All())
}
}
return true
}
}
func fixTODOComment(comments []string) {
todoRegex := regexp.MustCompile("(//) (.*) (TODO.*)")
if len(comments) > 0 {
comments[0] = todoRegex.ReplaceAllString(comments[0], "$1 $3")
}
}
func removeGoFieldComment(comments []string) {
todoRegex := regexp.MustCompile("(//) ([A-Z].*?) ([A-Z]?.*?) (.*)")
if len(comments) > 0 {
matches := todoRegex.FindAllStringSubmatch(comments[0], -1)
if len(matches) > 0 {
if strings.EqualFold(matches[0][3], matches[0][2]) {
comments[0] = fmt.Sprintf("%s %s %s", matches[0][1], matches[0][3], matches[0][4])
} else {
r := []rune(matches[0][3])
if !unicode.IsLower(r[0]) {
comments[0] = fmt.Sprintf("%s %s %s", matches[0][1], matches[0][3], matches[0][4])
}
}
}
}
}
func isTypeSpec(d dst.Decl) bool {
gd, ok := d.(*dst.GenDecl)
if !ok {
return false
}
_, is := gd.Specs[0].(*dst.TypeSpec)
return is
}
// It fixes the "generic" fields. It happens when a value in cue could be different structs.
// For Go it generates a struct with a json.RawMessage field inside and multiple functions to map it between the different possibilities.
func fixRawData() dstutil.ApplyFunc {
return func(c *dstutil.Cursor) bool {
f, is := c.Node().(*dst.File)
if !is {
return false
}
rawFields := make(map[string]bool)
existingRawFields := make(map[string]bool)
for _, decl := range f.Decls {
switch x := decl.(type) {
// Find the structs that only contains one json.RawMessage inside
case *dst.GenDecl:
for _, t := range x.Specs {
if ts, ok := t.(*dst.TypeSpec); ok {
if tp, ok := ts.Type.(*dst.StructType); ok && len(tp.Fields.List) == 1 {
if fn, ok := tp.Fields.List[0].Type.(*dst.SelectorExpr); ok {
if fmt.Sprintf("%s.%s", fn.X, fn.Sel.Name) == "json.RawMessage" {
rawFields[ts.Name.Name] = true
}
}
}
}
}
// Find the functions of the previous structs to verify that are the ones that we are looking for.
case *dst.FuncDecl:
for _, recv := range x.Recv.List {
fnType := depoint(recv.Type).(*dst.Ident).Name
if rawFields[fnType] {
existingRawFields[fnType] = true
}
}
}
}
dstutil.Apply(f, func(c *dstutil.Cursor) bool {
switch x := c.Node().(type) {
// Delete the functions
case *dst.FuncDecl:
c.Delete()
case *dst.GenDecl:
// Deletes all "generics" generated for these json.RawMessage structs
comments := x.Decorations().Start.All()
if len(comments) > 0 {
if strings.HasSuffix(comments[0], "defines model for .") {
c.Delete()
}
}
for _, spec := range x.Specs {
if tp, ok := spec.(*dst.TypeSpec); ok {
// Delete structs with only json.RawMessage
if existingRawFields[tp.Name.Name] && tp.Name.Name != "MetricAggregation2" {
c.Delete()
continue
}
// Set types that was using these structs as interface{}
if st, ok := tp.Type.(*dst.StructType); ok {
iterateStruct(st, withoutRawData(existingRawFields))
}
if mt, ok := tp.Type.(*dst.MapType); ok {
iterateMap(mt, withoutRawData(existingRawFields))
}
if at, ok := tp.Type.(*dst.ArrayType); ok {
iterateArray(at, withoutRawData(existingRawFields))
}
}
}
}
return true
}, nil)
return true
}
}
// Fixes type name containing underscores in the generated Go files
func fixUnderscoreInTypeName() dstutil.ApplyFunc {
return func(c *dstutil.Cursor) bool {
switch x := c.Node().(type) {
case *dst.GenDecl:
if specs, isType := x.Specs[0].(*dst.TypeSpec); isType {
if strings.Contains(specs.Name.Name, "_") {
oldName := specs.Name.Name
specs.Name.Name = strings.ReplaceAll(specs.Name.Name, "_", "")
x.Decs.Start[0] = strings.ReplaceAll(x.Decs.Start[0], oldName, specs.Name.Name)
}
if st, ok := specs.Type.(*dst.StructType); ok {
iterateStruct(st, withoutUnderscore)
}
if mt, ok := specs.Type.(*dst.MapType); ok {
iterateMap(mt, withoutUnderscore)
}
if at, ok := specs.Type.(*dst.ArrayType); ok {
iterateArray(at, withoutUnderscore)
}
}
case *dst.Field:
findFieldsWithUnderscores(x)
}
return true
}
}
func findFieldsWithUnderscores(x *dst.Field) {
switch t := x.Type.(type) {
case *dst.Ident:
withoutUnderscore(t)
case *dst.StarExpr:
if i, is := t.X.(*dst.Ident); is {
withoutUnderscore(i)
}
case *dst.ArrayType:
iterateArray(t, withoutUnderscore)
case *dst.MapType:
iterateMap(t, withoutUnderscore)
}
}
func withoutUnderscore(i *dst.Ident) {
if strings.Contains(i.Name, "_") {
i.Name = strings.ReplaceAll(i.Name, "_", "")
}
}
func withoutRawData(existingFields map[string]bool) func(ident *dst.Ident) {
return func(i *dst.Ident) {
if existingFields[i.Name] {
i.Name = setStar(i) + "any"
}
}
}
func iterateStruct(s *dst.StructType, fn func(i *dst.Ident)) {
for i, f := range s.Fields.List {
switch mx := depoint(f.Type).(type) {
case *dst.Ident:
fn(mx)
case *dst.ArrayType:
iterateArray(mx, fn)
case *dst.MapType:
iterateMap(mx, fn)
case *dst.StructType:
iterateStruct(mx, fn)
case *dst.InterfaceType:
s.Fields.List[i].Type = interfaceToAny(f.Type)
}
}
}
func iterateMap(s *dst.MapType, fn func(i *dst.Ident)) {
switch mx := s.Value.(type) {
case *dst.Ident:
fn(mx)
case *dst.ArrayType:
iterateArray(mx, fn)
case *dst.MapType:
iterateMap(mx, fn)
case *dst.InterfaceType:
s.Value = interfaceToAny(s.Value)
}
}
func iterateArray(a *dst.ArrayType, fn func(i *dst.Ident)) {
switch mx := a.Elt.(type) {
case *dst.Ident:
fn(mx)
case *dst.ArrayType:
iterateArray(mx, fn)
case *dst.StructType:
iterateStruct(mx, fn)
case *dst.InterfaceType:
a.Elt = interfaceToAny(a.Elt)
}
}
func interfaceToAny(i dst.Expr) dst.Expr {
star := ""
if _, is := i.(*dst.StarExpr); is {
star = "*"
}
return &dst.Ident{Name: star + "any"}
}

@ -0,0 +1,193 @@
package generators
import (
"bytes"
"fmt"
"go/parser"
"go/token"
"path/filepath"
"strings"
"cuelang.org/go/cue"
"cuelang.org/go/pkg/encoding/yaml"
"github.com/dave/dst/decorator"
"github.com/dave/dst/dstutil"
"github.com/deepmap/oapi-codegen/pkg/codegen"
"github.com/getkin/kin-openapi/openapi3"
"golang.org/x/tools/imports"
)
type GoConfig struct {
Config *OpenApiConfig
PackageName string
ApplyFuncs []dstutil.ApplyFunc
}
func GenerateTypesGo(v cue.Value, cfg *GoConfig) ([]byte, error) {
if cfg == nil {
return nil, fmt.Errorf("configuration cannot be nil")
}
applyFuncs := []dstutil.ApplyFunc{depointerizer(), fixRawData(), fixUnderscoreInTypeName(), fixTODOComments()}
applyFuncs = append(applyFuncs, cfg.ApplyFuncs...)
f, err := generateOpenAPI(v, cfg.Config)
if err != nil {
return nil, err
}
str, err := yaml.Marshal(v.Context().BuildFile(f))
if err != nil {
return nil, fmt.Errorf("cue-yaml marshaling failed: %w", err)
}
loader := openapi3.NewLoader()
oT, err := loader.LoadFromData([]byte(str))
if err != nil {
return nil, fmt.Errorf("loading generated openapi failed: %w", err)
}
schemaName, err := getSchemaName(v)
if err != nil {
return nil, err
}
if cfg.PackageName == "" {
cfg.PackageName = schemaName
}
// Hack to fix https://github.com/grafana/thema/pull/127 issue without importing
// to avoid to add the whole vendor in Grafana code
if cfg.PackageName == "dataquery" {
fixDataQuery(oT)
}
ccfg := codegen.Configuration{
PackageName: cfg.PackageName,
Compatibility: codegen.CompatibilityOptions{
AlwaysPrefixEnumValues: true,
},
Generate: codegen.GenerateOptions{
Models: true,
},
OutputOptions: codegen.OutputOptions{
SkipPrune: true,
UserTemplates: map[string]string{
"imports.tmpl": importstmpl,
},
},
}
gostr, err := codegen.Generate(oT, ccfg)
if err != nil {
return nil, fmt.Errorf("openapi generation failed: %w", err)
}
return postprocessGoFile(genGoFile{
path: fmt.Sprintf("%s_type_gen.go", schemaName),
appliers: applyFuncs,
in: []byte(gostr),
})
}
type genGoFile struct {
path string
appliers []dstutil.ApplyFunc
in []byte
}
func postprocessGoFile(cfg genGoFile) ([]byte, error) {
fname := sanitizeLabelString(filepath.Base(cfg.path))
buf := new(bytes.Buffer)
fset := token.NewFileSet()
gf, err := decorator.ParseFile(fset, fname, string(cfg.in), parser.ParseComments)
if err != nil {
return nil, fmt.Errorf("error parsing generated file: %w", err)
}
for _, af := range cfg.appliers {
dstutil.Apply(gf, af, nil)
}
err = decorator.Fprint(buf, gf)
if err != nil {
return nil, fmt.Errorf("error formatting generated file: %w", err)
}
byt, err := imports.Process(fname, buf.Bytes(), nil)
if err != nil {
return nil, fmt.Errorf("goimports processing of generated file failed: %w", err)
}
// Compare imports before and after; warn about performance if some were added
gfa, _ := parser.ParseFile(fset, fname, string(byt), parser.ParseComments)
imap := make(map[string]bool)
for _, im := range gf.Imports {
imap[im.Path.Value] = true
}
var added []string
for _, im := range gfa.Imports {
if !imap[im.Path.Value] {
added = append(added, im.Path.Value)
}
}
if len(added) != 0 {
// TODO improve the guidance in this error if/when we better abstract over imports to generate
return nil, fmt.Errorf("goimports added the following import statements to %s: \n\t%s\nRelying on goimports to find imports significantly slows down code generation. Either add these imports with an AST manipulation in cfg.ApplyFuncs, or set cfg.IgnoreDiscoveredImports to true", cfg.path, strings.Join(added, "\n\t"))
}
return byt, nil
}
// fixDataQuery extends the properties for the AllOf schemas when a DataQuery exists.
// deep/oapi-codegen library ignores the properties of the models and only ones have references.
// It doesn't apply this change https://github.com/grafana/thema/pull/154 since it modifies the
// vendor implementation, and we don't import it.
func fixDataQuery(spec *openapi3.T) *openapi3.T {
for _, sch := range spec.Components.Schemas {
if sch.Value != nil && len(sch.Value.AllOf) > 0 {
for _, allOf := range sch.Value.AllOf {
for n, p := range allOf.Value.Properties {
sch.Value.Properties[n] = p
}
}
sch.Value.AllOf = nil
}
}
return spec
}
// Almost all of the below imports are eliminated by dst transformers and calls
// to goimports - but if they're not present in the template, then the internal
// call to goimports that oapi-codegen makes will trigger a search for them,
// which can slow down codegen by orders of magnitude.
var importstmpl = `package {{ .PackageName }}
import (
"bytes"
"compress/gzip"
"context"
"encoding/base64"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"gopkg.in/yaml.v2"
"io"
"io/ioutil"
"os"
"net/http"
"net/url"
"path"
"strings"
"time"
"github.com/deepmap/oapi-codegen/pkg/runtime"
openapi_types "github.com/deepmap/oapi-codegen/pkg/types"
"github.com/getkin/kin-openapi/openapi3"
"github.com/go-chi/chi/v5"
"github.com/labstack/echo/v4"
"github.com/gin-gonic/gin"
"github.com/gorilla/mux"
)
`

@ -0,0 +1,199 @@
package generators
import (
"fmt"
"strings"
"cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
"cuelang.org/go/encoding/openapi"
)
type OpenApiConfig struct {
Config *openapi.Config
IsGroup bool
RootName string
SubPath cue.Path
}
func generateOpenAPI(v cue.Value, cfg *OpenApiConfig) (*ast.File, error) {
if cfg == nil {
return nil, fmt.Errorf("missing openapi configuration")
}
if cfg.Config == nil {
cfg.Config = &openapi.Config{}
}
name, err := getSchemaName(v)
if err != nil {
return nil, err
}
gen := &oapiGen{
cfg: cfg,
name: name,
val: v.LookupPath(cue.ParsePath("lineage.schemas[0].schema")),
subpath: cfg.SubPath,
bpath: v.LookupPath(cue.ParsePath("lineage.schemas[0]")).Path(),
}
declFunc := genSchema
if cfg.IsGroup {
declFunc = genGroup
}
decls, err := declFunc(gen)
if err != nil {
return nil, err
}
// TODO recursively sort output to improve stability of output
return &ast.File{
Decls: []ast.Decl{
ast.NewStruct(
"openapi", ast.NewString("3.0.0"),
"paths", ast.NewStruct(),
"components", ast.NewStruct(
"schemas", &ast.StructLit{Elts: decls},
),
),
},
}, nil
}
type oapiGen struct {
cfg *OpenApiConfig
val cue.Value
subpath cue.Path
// overall name for the generated oapi doc
name string
// original NameFunc
onf func(cue.Value, cue.Path) string
// full prefix path that leads up to the #SchemaDef, e.g. lin._sortedSchemas[0]
bpath cue.Path
}
func genGroup(gen *oapiGen) ([]ast.Decl, error) {
ctx := gen.val.Context()
iter, err := gen.val.Fields(cue.Definitions(true), cue.Optional(true))
if err != nil {
panic(fmt.Errorf("unreachable - should always be able to get iter for struct kinds: %w", err))
}
var decls []ast.Decl
for iter.Next() {
val, sel := iter.Value(), iter.Selector()
name := strings.Trim(sel.String(), "?#")
v := ctx.CompileString(fmt.Sprintf("#%s: _", name))
defpath := cue.MakePath(cue.Def(name))
defsch := v.FillPath(defpath, val)
cfgi := *gen.cfg.Config
cfgi.NameFunc = func(val cue.Value, path cue.Path) string {
return gen.nfSingle(val, path, defpath, name)
}
part, err := openapi.Generate(defsch, &cfgi)
if err != nil {
return nil, fmt.Errorf("failed generation for grouped field %s: %w", sel, err)
}
decls = append(decls, getSchemas(part)...)
}
return decls, nil
}
func genSchema(gen *oapiGen) ([]ast.Decl, error) {
hasSubpath := len(gen.cfg.SubPath.Selectors()) > 0
name := sanitizeLabelString(gen.name)
if gen.cfg.RootName != "" {
name = gen.cfg.RootName
} else if hasSubpath {
sel := gen.cfg.SubPath.Selectors()
name = sel[len(sel)-1].String()
}
val := gen.val
if hasSubpath {
for i, sel := range gen.cfg.SubPath.Selectors() {
if !gen.val.Allows(sel) {
return nil, fmt.Errorf("subpath %q not present in schema", cue.MakePath(gen.cfg.SubPath.Selectors()[:i+1]...))
}
}
val = val.LookupPath(gen.cfg.SubPath)
}
v := gen.val.Context().CompileString(fmt.Sprintf("#%s: _", name))
defpath := cue.MakePath(cue.Def(name))
defsch := v.FillPath(defpath, val)
gen.cfg.Config.NameFunc = func(val cue.Value, path cue.Path) string {
return gen.nfSingle(val, path, defpath, name)
}
f, err := openapi.Generate(defsch.Eval(), gen.cfg.Config)
if err != nil {
return nil, err
}
return getSchemas(f), nil
}
// For generating a single, our NameFunc must:
// - Eliminate any path prefixes on the element, both internal lineage and wrapping
// - Replace the name "_#schema" with the desired name
// - Call the user-provided NameFunc, if any
// - Remove CUE markers like #, !, ?
func (gen *oapiGen) nfSingle(val cue.Value, path, defpath cue.Path, name string) string {
tpath := trimPathPrefix(trimThemaPathPrefix(path, gen.bpath), defpath)
if path.String() == "" || tpath.String() == defpath.String() {
return name
}
if val == gen.val {
return ""
}
if gen.onf != nil {
return gen.onf(val, tpath)
}
return strings.Trim(tpath.String(), "?#")
}
func getSchemas(f *ast.File) []ast.Decl {
compos := orp(getFieldByLabel(f, "components"))
schemas := orp(getFieldByLabel(compos.Value, "schemas"))
return schemas.Value.(*ast.StructLit).Elts
}
func orp[T any](t T, err error) T {
if err != nil {
panic(err)
}
return t
}
func trimThemaPathPrefix(p, base cue.Path) cue.Path {
if !pathHasPrefix(p, base) {
return p
}
rest := p.Selectors()[len(base.Selectors()):]
if len(rest) == 0 {
return cue.Path{}
}
switch rest[0].String() {
case "schema", "_#schema", "_join", "joinSchema":
return cue.MakePath(rest[1:]...)
default:
return cue.MakePath(rest...)
}
}

@ -0,0 +1,56 @@
package generators
import (
"fmt"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"github.com/grafana/cuetsy"
"github.com/grafana/cuetsy/ts"
"github.com/grafana/cuetsy/ts/ast"
)
type TSConfig struct {
CuetsyConfig *cuetsy.Config
IsGroup bool
RootName string
}
// GenerateTypesTS generates native TypeScript types and defaults corresponding to
// the provided Schema.
func GenerateTypesTS(v cue.Value, cfg *TSConfig) (*ast.File, error) {
if cfg == nil {
return nil, fmt.Errorf("configuration cannot be empty")
}
if cfg.CuetsyConfig == nil {
cfg.CuetsyConfig = &cuetsy.Config{
Export: true,
}
}
// Thema #schema was a unification between the schema and cue.TopKind(_). For any reason, without this unification,
// cuetsy fails finding some enums ¯\_(ツ)_/¯.
oldSchema := cuecontext.New().CompileBytes([]byte("_"))
schdef := v.LookupPath(cue.ParsePath("lineage.schemas[0].schema")).Unify(oldSchema)
tf, err := cuetsy.GenerateAST(schdef, *cfg.CuetsyConfig)
if err != nil {
return nil, fmt.Errorf("generating TS for child elements of schema failed: %w", err)
}
file := &ts.File{
Nodes: tf.Nodes,
}
if !cfg.IsGroup {
top, err := cuetsy.GenerateSingleAST(cfg.RootName, schdef, cuetsy.TypeInterface)
if err != nil {
return nil, fmt.Errorf("generating TS for schema root failed: %w", err)
}
file.Nodes = append(file.Nodes, top.T)
if top.D != nil {
file.Nodes = append(file.Nodes, top.D)
}
}
return file, nil
}

@ -0,0 +1,130 @@
package generators
import (
"fmt"
"strconv"
"strings"
"cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/token"
)
// sanitizeLabelString strips characters from a string that are not allowed for
// use in a CUE label.
func sanitizeLabelString(s string) string {
return strings.Map(func(r rune) rune {
switch {
case r >= 'a' && r <= 'z':
fallthrough
case r >= 'A' && r <= 'Z':
fallthrough
case r >= '0' && r <= '9':
fallthrough
case r == '_':
return r
default:
return -1
}
}, s)
}
// trimPathPrefix strips the provided prefix from the provided path, if the
// prefix exists.
//
// If path and prefix are equivalent, and there is at least one additional
// selector in the provided path.
func trimPathPrefix(path, prefix cue.Path) cue.Path {
sels, psels := path.Selectors(), prefix.Selectors()
if len(sels) == 1 {
return path
}
var i int
for ; i < len(psels) && i < len(sels); i++ {
if !selEq(psels[i], sels[i]) {
break
}
}
return cue.MakePath(sels[i:]...)
}
// selEq indicates whether two selectors are equivalent. Selectors are equivalent if
// they are either exactly equal, or if they are equal ignoring path optionality.
func selEq(s1, s2 cue.Selector) bool {
return s1 == s2 || s1.Optional() == s2.Optional()
}
// getFieldByLabel returns the ast.Field with a given label from a struct-ish input.
func getFieldByLabel(n ast.Node, label string) (*ast.Field, error) {
var d []ast.Decl
switch x := n.(type) {
case *ast.File:
d = x.Decls
case *ast.StructLit:
d = x.Elts
default:
return nil, fmt.Errorf("not an *ast.File or *ast.StructLit")
}
for _, el := range d {
if isFieldWithLabel(el, label) {
return el.(*ast.Field), nil
}
}
return nil, fmt.Errorf("no field with label %q", label)
}
func isFieldWithLabel(n ast.Node, label string) bool {
if x, is := n.(*ast.Field); is {
if l, is := x.Label.(*ast.BasicLit); is {
return strEq(l, label)
}
if l, is := x.Label.(*ast.Ident); is {
return identStrEq(l, label)
}
}
return false
}
func strEq(lit *ast.BasicLit, str string) bool {
if lit.Kind != token.STRING {
return false
}
ls, _ := strconv.Unquote(lit.Value)
return str == ls || str == lit.Value
}
func identStrEq(id *ast.Ident, str string) bool {
if str == id.Name {
return true
}
ls, _ := strconv.Unquote(id.Name)
return str == ls
}
// pathHasPrefix tests whether the [cue.Path] p begins with prefix.
func pathHasPrefix(p, prefix cue.Path) bool {
ps, pres := p.Selectors(), prefix.Selectors()
if len(pres) > len(ps) {
return false
}
return pathsAreEq(ps[:len(pres)], pres)
}
func pathsAreEq(p1s, p2s []cue.Selector) bool {
if len(p1s) != len(p2s) {
return false
}
for i := 0; i < len(p2s); i++ {
if !selEq(p2s[i], p1s[i]) {
return false
}
}
return true
}
func getSchemaName(v cue.Value) (string, error) {
nameValue := v.LookupPath(cue.ParsePath("name"))
return nameValue.String()
}

@ -7,7 +7,6 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"cuelang.org/go/cue"
"github.com/grafana/codejen" "github.com/grafana/codejen"
) )
@ -21,10 +20,10 @@ func (jenny *CoreRegistryJenny) JennyName() string {
return "CoreRegistryJenny" return "CoreRegistryJenny"
} }
func (jenny *CoreRegistryJenny) Generate(cueFiles []CueSchema) (codejen.Files, error) { func (jenny *CoreRegistryJenny) Generate(cueFiles ...SchemaForGen) (codejen.Files, error) {
schemas := make([]Schema, len(cueFiles)) schemas := make([]Schema, len(cueFiles))
for i, v := range cueFiles { for i, v := range cueFiles {
name, err := getSchemaName(v.CueFile) name, err := getSchemaName(v.Name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -51,12 +50,7 @@ func (jenny *CoreRegistryJenny) Generate(cueFiles []CueSchema) (codejen.Files, e
return codejen.Files{*file}, nil return codejen.Files{*file}, nil
} }
func getSchemaName(v cue.Value) (string, error) { func getSchemaName(pkg string) (string, error) {
name, err := getPackageName(v) pkg = strings.Replace(pkg, "-", "_", -1)
if err != nil { return strings.ToLower(pkg), nil
return "", err
}
name = strings.Replace(name, "-", "_", -1)
return strings.ToLower(name), nil
} }

@ -7,7 +7,6 @@ import (
"github.com/grafana/codejen" "github.com/grafana/codejen"
"github.com/grafana/cuetsy/ts" "github.com/grafana/cuetsy/ts"
"github.com/grafana/cuetsy/ts/ast" "github.com/grafana/cuetsy/ts/ast"
"github.com/grafana/kindsys"
) )
// LatestMajorsOrXJenny returns a jenny that repeats the input for the latest in each major version. // LatestMajorsOrXJenny returns a jenny that repeats the input for the latest in each major version.
@ -27,28 +26,17 @@ func (j *lmox) JennyName() string {
return "LatestMajorsOrXJenny" return "LatestMajorsOrXJenny"
} }
func (j *lmox) Generate(kind kindsys.Kind) (codejen.Files, error) { func (j *lmox) Generate(sfg SchemaForGen) (codejen.Files, error) {
// TODO remove this once codejen catches nils https://github.com/grafana/codejen/issues/5 sfg.IsGroup = true
if kind == nil {
return nil, nil
}
comm := kind.Props().Common()
sfg := SchemaForGen{
Name: comm.Name,
IsGroup: true,
Schema: kind.Lineage().Latest(),
}
f, err := j.inner.Generate(sfg) f, err := j.inner.Generate(sfg)
if err != nil { if err != nil {
return nil, fmt.Errorf("%s jenny failed on %s schema for %s: %w", j.inner.JennyName(), sfg.Schema.Version(), kind.Props().Common().Name, err) return nil, fmt.Errorf("%s jenny failed for %s: %w", j.inner.JennyName(), sfg.Name, err)
} }
if f == nil || !f.Exists() { if f == nil || !f.Exists() {
return nil, nil return nil, nil
} }
f.RelativePath = filepath.Join(j.parentdir, comm.MachineName, "x", f.RelativePath) f.RelativePath = filepath.Join(j.parentdir, sfg.OutputName, "x", f.RelativePath)
f.From = append(f.From, j) f.From = append(f.From, j)
return codejen.Files{*f}, nil return codejen.Files{*f}, nil
} }

@ -2,13 +2,12 @@ package codegen
import ( import (
"fmt" "fmt"
"strings"
"cuelang.org/go/cue" "cuelang.org/go/cue"
"github.com/dave/dst/dstutil" "github.com/dave/dst/dstutil"
"github.com/grafana/codejen" "github.com/grafana/codejen"
"github.com/grafana/kindsys" "github.com/grafana/grafana/pkg/codegen/generators"
"github.com/grafana/thema/encoding/gocode"
"github.com/grafana/thema/encoding/openapi"
) )
type GoSpecJenny struct { type GoSpecJenny struct {
@ -19,19 +18,19 @@ func (jenny *GoSpecJenny) JennyName() string {
return "GoResourceTypes" return "GoResourceTypes"
} }
func (jenny *GoSpecJenny) Generate(kinds ...kindsys.Kind) (codejen.Files, error) { func (jenny *GoSpecJenny) Generate(sfg ...SchemaForGen) (codejen.Files, error) {
files := make(codejen.Files, len(kinds)) files := make(codejen.Files, len(sfg))
for i, v := range kinds { for i, v := range sfg {
name := v.Lineage().Name() packageName := strings.ToLower(v.Name)
b, err := gocode.GenerateTypesOpenAPI(v.Lineage().Latest(), b, err := generators.GenerateTypesGo(v.CueFile,
&gocode.TypeConfigOpenAPI{ &generators.GoConfig{
Config: &openapi.Config{ Config: &generators.OpenApiConfig{
Group: false, IsGroup: false,
RootName: "Spec", RootName: "Spec",
Subpath: cue.MakePath(cue.Str("spec")), SubPath: cue.MakePath(cue.Str("spec")),
}, },
PackageName: name, PackageName: packageName,
ApplyFuncs: append(jenny.ApplyFuncs, PrefixDropper(v.Props().Common().Name)), ApplyFuncs: append(jenny.ApplyFuncs, PrefixDropper(v.Name)),
}, },
) )
@ -39,7 +38,7 @@ func (jenny *GoSpecJenny) Generate(kinds ...kindsys.Kind) (codejen.Files, error)
return nil, err return nil, err
} }
files[i] = *codejen.NewFile(fmt.Sprintf("pkg/kinds/%s/%s_spec_gen.go", name, name), b, jenny) files[i] = *codejen.NewFile(fmt.Sprintf("pkg/kinds/%s/%s_spec_gen.go", packageName, packageName), b, jenny)
} }
return files, nil return files, nil

@ -18,25 +18,20 @@ func (jenny *K8ResourcesJenny) JennyName() string {
return "K8ResourcesJenny" return "K8ResourcesJenny"
} }
func (jenny *K8ResourcesJenny) Generate(cueFiles []CueSchema) (codejen.Files, error) { func (jenny *K8ResourcesJenny) Generate(cueFiles ...SchemaForGen) (codejen.Files, error) {
files := make(codejen.Files, 0) files := make(codejen.Files, 0)
for _, val := range cueFiles { for _, val := range cueFiles {
pkg, err := getPackageName(val.CueFile) resource, err := jenny.genResource(val.Name, val.CueFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
resource, err := jenny.genResource(pkg, val.CueFile) metadata, err := jenny.genMetadata(val.Name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
metadata, err := jenny.genMetadata(pkg) status, err := jenny.genStatus(val.Name)
if err != nil {
return nil, err
}
status, err := jenny.genStatus(pkg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -100,15 +95,6 @@ func (jenny *K8ResourcesJenny) genStatus(pkg string) (codejen.File, error) {
return *codejen.NewFile(fmt.Sprintf("pkg/kinds/%s/%s_status_gen.go", pkg, pkg), buf.Bytes(), jenny), nil return *codejen.NewFile(fmt.Sprintf("pkg/kinds/%s/%s_status_gen.go", pkg, pkg), buf.Bytes(), jenny), nil
} }
func getPackageName(val cue.Value) (string, error) {
name := val.LookupPath(cue.ParsePath("name"))
pkg, err := name.String()
if err != nil {
return "", fmt.Errorf("file doesn't have name field set: %s", err)
}
return pkg, nil
}
func getVersion(val cue.Value) (string, error) { func getVersion(val cue.Value) (string, error) {
val = val.LookupPath(cue.ParsePath("lineage.schemas[0].version")) val = val.LookupPath(cue.ParsePath("lineage.schemas[0].version"))
versionValues, err := val.List() versionValues, err := val.List()

@ -4,17 +4,12 @@ import (
"github.com/grafana/codejen" "github.com/grafana/codejen"
"github.com/grafana/cuetsy" "github.com/grafana/cuetsy"
"github.com/grafana/cuetsy/ts/ast" "github.com/grafana/cuetsy/ts/ast"
"github.com/grafana/grafana/pkg/cuectx" "github.com/grafana/grafana/pkg/codegen/generators"
"github.com/grafana/thema/encoding/typescript"
) )
type ApplyFunc func(sfg SchemaForGen, file *ast.File) type ApplyFunc func(sfg SchemaForGen, file *ast.File)
// TSTypesJenny is a [OneToOne] that produces TypeScript types and // TSTypesJenny is a [OneToOne] that produces TypeScript types and defaults.
// defaults for a Thema schema.
//
// Thema's generic TS jenny will be able to replace this one once
// https://github.com/grafana/thema/issues/89 is complete.
type TSTypesJenny struct { type TSTypesJenny struct {
ApplyFuncs []ApplyFunc ApplyFuncs []ApplyFunc
} }
@ -26,14 +21,13 @@ func (j TSTypesJenny) JennyName() string {
} }
func (j TSTypesJenny) Generate(sfg SchemaForGen) (*codejen.File, error) { func (j TSTypesJenny) Generate(sfg SchemaForGen) (*codejen.File, error) {
// TODO allow using name instead of machine name in thema generator f, err := generators.GenerateTypesTS(sfg.CueFile, &generators.TSConfig{
f, err := typescript.GenerateTypes(sfg.Schema, &typescript.TypeConfig{
CuetsyConfig: &cuetsy.Config{ CuetsyConfig: &cuetsy.Config{
Export: true, Export: true,
ImportMapper: cuectx.MapCUEImportToTS, ImportMapper: MapCUEImportToTS,
}, },
RootName: sfg.Name, RootName: sfg.Name,
Group: sfg.IsGroup, IsGroup: sfg.IsGroup,
}) })
for _, renameFunc := range j.ApplyFuncs { for _, renameFunc := range j.ApplyFuncs {
@ -44,5 +38,10 @@ func (j TSTypesJenny) Generate(sfg SchemaForGen) (*codejen.File, error) {
return nil, err return nil, err
} }
return codejen.NewFile(sfg.Schema.Lineage().Name()+"_types.gen.ts", []byte(f.String()), j), nil outputName := sfg.Name
if sfg.OutputName != "" {
outputName = sfg.OutputName
}
return codejen.NewFile(outputName+"_types.gen.ts", []byte(f.String()), j), nil
} }

@ -12,14 +12,9 @@ import (
"github.com/grafana/cuetsy" "github.com/grafana/cuetsy"
"github.com/grafana/cuetsy/ts" "github.com/grafana/cuetsy/ts"
"github.com/grafana/cuetsy/ts/ast" "github.com/grafana/cuetsy/ts/ast"
"github.com/grafana/grafana/pkg/cuectx" "github.com/grafana/grafana/pkg/codegen/generators"
"github.com/grafana/kindsys"
"github.com/grafana/thema"
"github.com/grafana/thema/encoding/typescript"
) )
var schPath = cue.MakePath(cue.Hid("_#schema", "github.com/grafana/thema"))
// TSVeneerIndexJenny generates an index.gen.ts file with references to all // TSVeneerIndexJenny generates an index.gen.ts file with references to all
// generated TS types. Elements with the attribute @grafana(TSVeneer="type") are // generated TS types. Elements with the attribute @grafana(TSVeneer="type") are
// exported from a handwritten file, rather than the raw generated types. // exported from a handwritten file, rather than the raw generated types.
@ -43,19 +38,18 @@ func (gen *genTSVeneerIndex) JennyName() string {
return "TSVeneerIndexJenny" return "TSVeneerIndexJenny"
} }
func (gen *genTSVeneerIndex) Generate(kinds ...kindsys.Kind) (*codejen.File, error) { func (gen *genTSVeneerIndex) Generate(sfg ...SchemaForGen) (*codejen.File, error) {
tsf := new(ast.File) tsf := new(ast.File)
for _, def := range kinds { for _, def := range sfg {
sch := def.Lineage().Latest() f, err := generators.GenerateTypesTS(def.CueFile, &generators.TSConfig{
f, err := typescript.GenerateTypes(sch, &typescript.TypeConfig{
CuetsyConfig: &cuetsy.Config{ CuetsyConfig: &cuetsy.Config{
ImportMapper: cuectx.MapCUEImportToTS, ImportMapper: MapCUEImportToTS,
}, },
RootName: def.Props().Common().Name, RootName: def.Name,
Group: def.Props().Common().LineageIsGroup, IsGroup: def.IsGroup,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("%s: %w", def.Props().Common().Name, err) return nil, fmt.Errorf("%s: %w", def.Name, err)
} }
// The obvious approach would be calling renameSpecNode() here, same as in the ts resource jenny, // The obvious approach would be calling renameSpecNode() here, same as in the ts resource jenny,
// to rename the "spec" field to the name of the kind. But that was causing extra // to rename the "spec" field to the name of the kind. But that was causing extra
@ -66,7 +60,7 @@ func (gen *genTSVeneerIndex) Generate(kinds ...kindsys.Kind) (*codejen.File, err
elems, err := gen.extractTSIndexVeneerElements(def, f) elems, err := gen.extractTSIndexVeneerElements(def, f)
if err != nil { if err != nil {
return nil, fmt.Errorf("%s: %w", def.Props().Common().Name, err) return nil, fmt.Errorf("%s: %w", def.Name, err)
} }
tsf.Nodes = append(tsf.Nodes, elems...) tsf.Nodes = append(tsf.Nodes, elems...)
} }
@ -74,12 +68,9 @@ func (gen *genTSVeneerIndex) Generate(kinds ...kindsys.Kind) (*codejen.File, err
return codejen.NewFile(filepath.Join(gen.dir, "index.gen.ts"), []byte(tsf.String()), gen), nil return codejen.NewFile(filepath.Join(gen.dir, "index.gen.ts"), []byte(tsf.String()), gen), nil
} }
func (gen *genTSVeneerIndex) extractTSIndexVeneerElements(def kindsys.Kind, tf *ast.File) ([]ast.Decl, error) { func (gen *genTSVeneerIndex) extractTSIndexVeneerElements(def SchemaForGen, tf *ast.File) ([]ast.Decl, error) {
lin := def.Lineage()
comm := def.Props().Common()
// Check the root, then walk the tree // Check the root, then walk the tree
rootv := lin.Latest().Underlying().LookupPath(schPath) rootv := def.CueFile.LookupPath(cue.ParsePath("lineage.schemas[0].schema"))
var raw, custom, rawD, customD ast.Idents var raw, custom, rawD, customD ast.Idents
@ -105,7 +96,7 @@ func (gen *genTSVeneerIndex) extractTSIndexVeneerElements(def kindsys.Kind, tf *
} }
// Search the generated TS AST for the type and default def nodes // Search the generated TS AST for the type and default def nodes
pair := findDeclNode(name, comm.Name, tf) pair := findDeclNode(name, def.Name, tf)
if pair.T == nil { if pair.T == nil {
// No generated type for this item, skip it // No generated type for this item, skip it
return false return false
@ -152,29 +143,32 @@ func (gen *genTSVeneerIndex) extractTSIndexVeneerElements(def kindsys.Kind, tf *
return nil, terr return nil, terr
} }
vpath := fmt.Sprintf("v%v", thema.Lineage.Latest(lin).Version()) vpath := "x"
if def.Props().Common().Maturity.Less(kindsys.MaturityStable) { machineName := strings.ToLower(def.Name)
vpath = "x"
}
ret := make([]ast.Decl, 0) ret := make([]ast.Decl, 0)
if len(raw) > 0 { if len(raw) > 0 {
ret = append(ret, ast.ExportSet{ ret = append(ret, ast.ExportSet{
CommentList: []ast.Comment{ts.CommentFromString(fmt.Sprintf("Raw generated types from %s kind.", comm.Name), 80, false)}, CommentList: []ast.Comment{ts.CommentFromString(fmt.Sprintf("Raw generated types from %s kind.", def.Name), 80, false)},
TypeOnly: true, TypeOnly: true,
Exports: raw, Exports: raw,
From: ast.Str{Value: fmt.Sprintf("./raw/%s/%s/%s_types.gen", comm.MachineName, vpath, comm.MachineName)}, From: ast.Str{Value: fmt.Sprintf("./raw/%s/%s/%s_types.gen", machineName, vpath, machineName)},
}) })
} }
if len(rawD) > 0 { if len(rawD) > 0 {
ret = append(ret, ast.ExportSet{ ret = append(ret, ast.ExportSet{
CommentList: []ast.Comment{ts.CommentFromString(fmt.Sprintf("Raw generated enums and default consts from %s kind.", lin.Name()), 80, false)}, CommentList: []ast.Comment{ts.CommentFromString(fmt.Sprintf("Raw generated enums and default consts from %s kind.", machineName), 80, false)},
TypeOnly: false, TypeOnly: false,
Exports: rawD, Exports: rawD,
From: ast.Str{Value: fmt.Sprintf("./raw/%s/%s/%s_types.gen", comm.MachineName, vpath, comm.MachineName)}, From: ast.Str{Value: fmt.Sprintf("./raw/%s/%s/%s_types.gen", machineName, vpath, machineName)},
}) })
} }
vtfile := fmt.Sprintf("./veneer/%s.types", lin.Name()) vtfile := fmt.Sprintf("./veneer/%s.types", machineName)
version, err := getVersion(def.CueFile)
if err != nil {
return nil, err
}
customstr := fmt.Sprintf(`// The following exported declarations correspond to types in the %s@%s kind's customstr := fmt.Sprintf(`// The following exported declarations correspond to types in the %s@%s kind's
// schema with attribute @grafana(TSVeneer="type"). // schema with attribute @grafana(TSVeneer="type").
// //
@ -184,7 +178,7 @@ func (gen *genTSVeneerIndex) extractTSIndexVeneerElements(def kindsys.Kind, tf *
// and exports all the symbols in the list. // and exports all the symbols in the list.
// //
// TODO generate code such that tsc enforces type compatibility between raw and veneer decls`, // TODO generate code such that tsc enforces type compatibility between raw and veneer decls`,
lin.Name(), thema.Lineage.Latest(lin).Version(), filepath.ToSlash(filepath.Join(gen.dir, vtfile))) machineName, strings.ReplaceAll(version, "-", "."), filepath.ToSlash(filepath.Join(gen.dir, vtfile)))
customComments := []ast.Comment{{Text: customstr}} customComments := []ast.Comment{{Text: customstr}}
if len(custom) > 0 { if len(custom) > 0 {

@ -27,21 +27,6 @@ func PrefixDropper(prefix string) dstutil.ApplyFunc {
}).applyfunc }).applyfunc
} }
// PrefixReplacer returns a dstutil.ApplyFunc that removes the provided prefix
// string when it appears as a leading sequence in type names, var names, and
// comments in a generated Go file.
//
// When an exact match for prefix is found, the provided replace string
// is substituted.
func PrefixReplacer(prefix, replace string) dstutil.ApplyFunc {
return (&prefixmod{
prefix: prefix,
replace: replace,
rxpsuff: regexp.MustCompile(fmt.Sprintf(`%s([a-zA-Z_]+)`, prefix)),
rxp: regexp.MustCompile(fmt.Sprintf(`%s([\s.,;-])`, prefix)),
}).applyfunc
}
func depoint(e dst.Expr) dst.Expr { func depoint(e dst.Expr) dst.Expr {
if star, is := e.(*dst.StarExpr); is { if star, is := e.(*dst.StarExpr); is {
return star.X return star.X

@ -1,4 +1,4 @@
package cuectx package codegen
import ( import (
"fmt" "fmt"
@ -13,8 +13,6 @@ import (
// indicates the import path should be dropped in the conversion to TS. Imports // indicates the import path should be dropped in the conversion to TS. Imports
// not present in the list are not allowed, and code generation will fail. // not present in the list are not allowed, and code generation will fail.
var importMap = map[string]string{ var importMap = map[string]string{
"github.com/grafana/thema": "",
"github.com/grafana/kindsys": "",
"github.com/grafana/grafana/pkg/plugins/pfs": "", "github.com/grafana/grafana/pkg/plugins/pfs": "",
"github.com/grafana/grafana/packages/grafana-schema/src/common": "@grafana/schema", "github.com/grafana/grafana/packages/grafana-schema/src/common": "@grafana/schema",
} }
@ -37,8 +35,6 @@ func init() {
// Grafana kind definitions. // Grafana kind definitions.
func PermittedCUEImports() []string { func PermittedCUEImports() []string {
return []string{ return []string{
"github.com/grafana/thema",
"github.com/grafana/kindsys",
"github.com/grafana/grafana/pkg/plugins/pfs", "github.com/grafana/grafana/pkg/plugins/pfs",
"github.com/grafana/grafana/packages/grafana-schema/src/common", "github.com/grafana/grafana/packages/grafana-schema/src/common",
} }

@ -1,73 +0,0 @@
// Package cuectx provides a single, central ["cuelang.org/go/cue".Context] and
// ["github.com/grafana/thema".Runtime] that can be used uniformly across
// Grafana, and related helper functions for loading Thema lineages.
package cuectx
import (
"path/filepath"
"sync"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"github.com/grafana/thema"
"github.com/grafana/thema/vmux"
)
// CoreDefParentPath is the path, relative to the repository root, where
// each child directory is expected to contain .cue files defining one
// Core kind.
var CoreDefParentPath = "kinds"
// GoCoreKindParentPath is the path, relative to the repository root, to the directory
// containing one directory per kind, full of generated Go kind output: types and bindings.
var GoCoreKindParentPath = filepath.Join("pkg", "kinds")
// TSCoreKindParentPath is the path, relative to the repository root, to the directory that
// contains one directory per kind, full of generated TS kind output: types and default consts.
var TSCoreKindParentPath = filepath.Join("packages", "grafana-schema", "src", "raw")
var (
ctx *cue.Context
rt *thema.Runtime
once sync.Once
)
func initContext() {
once.Do(func() {
ctx = cuecontext.New()
rt = thema.NewRuntime(ctx)
})
}
// GrafanaCUEContext returns Grafana's singleton instance of [cue.Context].
//
// All code within grafana/grafana that needs a *cue.Context should get it
// from this function, when one was not otherwise provided.
func GrafanaCUEContext() *cue.Context {
initContext()
return ctx
}
// GrafanaThemaRuntime returns Grafana's singleton instance of [thema.Runtime].
//
// All code within grafana/grafana that needs a *thema.Runtime should get it
// from this function, when one was not otherwise provided.
func GrafanaThemaRuntime() *thema.Runtime {
initContext()
return rt
}
// JSONtoCUE attempts to decode the given []byte into a cue.Value, relying on
// the central Grafana cue.Context provided in this package.
//
// The provided path argument determines the name given to the input bytes if
// later CUE operations (e.g. Thema validation) produce errors related to the
// returned cue.Value.
//
// This is a convenience function for one-off JSON decoding. It's wasteful to
// call it repeatedly. Most use cases should probably prefer making
// their own Thema/CUE decoders.
func JSONtoCUE(path string, b []byte) (cue.Value, error) {
return vmux.NewJSONCodec(path).Decode(GrafanaCUEContext(), b)
}

@ -1,239 +0,0 @@
package cuectx
import (
"fmt"
"io/fs"
"path/filepath"
"testing/fstest"
"cuelang.org/go/cue"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/cuecontext"
"github.com/grafana/kindsys"
"github.com/grafana/thema"
"github.com/grafana/thema/load"
"github.com/yalue/merged_fs"
"github.com/grafana/grafana"
)
// LoadGrafanaInstancesWithThema loads CUE files containing a lineage
// representing some Grafana core model schema. It is expected to be used when
// implementing a thema.LineageFactory.
//
// This function primarily juggles paths to make CUE's loader happy. Provide the
// path from the grafana root to the directory containing the lineage.cue. The
// lineage.cue file must be the sole contents of the provided fs.FS.
//
// More details on underlying behavior can be found in the docs for github.com/grafana/thema/load.InstanceWithThema.
//
// TODO this approach is complicated and confusing, refactor to something understandable
func LoadGrafanaInstancesWithThema(path string, cueFS fs.FS, rt *thema.Runtime, opts ...thema.BindOption) (thema.Lineage, error) {
prefix := filepath.FromSlash(path)
fs, err := prefixWithGrafanaCUE(prefix, cueFS)
if err != nil {
return nil, err
}
inst, err := load.InstanceWithThema(fs, prefix)
// Need to trick loading by creating the embedded file and
// making it look like a module in the root dir.
if err != nil {
return nil, err
}
val := rt.Context().BuildInstance(inst)
lin, err := thema.BindLineage(val, rt, opts...)
if err != nil {
return nil, err
}
return lin, nil
}
// prefixWithGrafanaCUE constructs an fs.FS that merges the provided fs.FS with
// the embedded FS containing Grafana's core CUE files, [grafana.CueSchemaFS].
// The provided prefix should be the relative path from the grafana repository
// root to the directory root of the provided inputfs.
//
// The returned fs.FS is suitable for passing to a CUE loader, such as [load.InstanceWithThema].
func prefixWithGrafanaCUE(prefix string, inputfs fs.FS) (fs.FS, error) {
m, err := prefixFS(prefix, inputfs)
if err != nil {
return nil, err
}
return merged_fs.NewMergedFS(m, grafana.CueSchemaFS), nil
}
// TODO such a waste, replace with stateless impl that just transforms paths on the fly
func prefixFS(prefix string, fsys fs.FS) (fs.FS, error) {
m := make(fstest.MapFS)
prefix = filepath.FromSlash(prefix)
err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
b, err := fs.ReadFile(fsys, filepath.ToSlash(path))
if err != nil {
return err
}
// fstest can recognize only forward slashes.
m[filepath.ToSlash(filepath.Join(prefix, path))] = &fstest.MapFile{Data: b}
return nil
})
return m, err
}
// LoadGrafanaInstance wraps [load.InstanceWithThema] to load a
// [*build.Instance] corresponding to a particular path within the
// github.com/grafana/grafana CUE module.
//
// This allows resolution of imports within the grafana or thema CUE modules to
// work correctly and consistently by relying on the embedded FS at
// [grafana.CueSchemaFS] and [thema.CueFS].
//
// relpath should be a relative path path within [grafana.CueSchemaFS] to be
// loaded. Optionally, the caller may provide an additional fs.FS via the
// overlay parameter, which will be merged with [grafana.CueSchemaFS] at
// relpath, and loaded.
//
// pkg, if non-empty, is set as the value of
// ["cuelang.org/go/cue/load".Config.Package]. If the CUE package to be loaded
// is the same as the parent directory name, it should be omitted.
//
// NOTE this function will be deprecated in favor of a more generic loader
func LoadGrafanaInstance(relpath string, pkg string, overlay fs.FS) (*build.Instance, error) {
// notes about how this crap needs to work
//
// Within grafana/grafana, need:
// - pass in an fs.FS that, in its root, contains the .cue files to load
// - has no cue.mod
// - gets prefixed with the appropriate path within grafana/grafana
// - and merged with all the other .cue files from grafana/grafana
// notes about how this crap needs to work
//
// Need a prefixing instance loader that:
// - can take multiple fs.FS, each one representing a CUE module (nesting?)
// - reconcile at most one of the provided fs with cwd
// - behavior must differ depending on whether cwd is in a cue module
// - behavior should(?) be controllable depending on
relpath = filepath.ToSlash(relpath)
var f fs.FS = grafana.CueSchemaFS
// merge the kindsys filesystem with ours for the kind categories
f = merged_fs.NewMergedFS(kindsys.CueSchemaFS, f)
var err error
if overlay != nil {
f, err = prefixWithGrafanaCUE(relpath, overlay)
if err != nil {
return nil, err
}
// merge the kindsys filesystem with ours for the kind categories
f = merged_fs.NewMergedFS(kindsys.CueSchemaFS, f)
}
if pkg != "" {
return load.InstanceWithThema(f, relpath, load.Package(pkg))
}
return load.InstanceWithThema(f, relpath)
}
// BuildGrafanaInstance wraps [LoadGrafanaInstance], additionally building
// the returned [*build.Instance] into a [cue.Value].
//
// An error is returned if:
// - The underlying call to [LoadGrafanaInstance] returns an error
// - The built [cue.Value] has an error ([cue.Value.Err] returns non-nil)
//
// NOTE this function will be deprecated in favor of a more generic builder
func BuildGrafanaInstance(ctx *cue.Context, relpath string, pkg string, overlay fs.FS) (cue.Value, error) {
bi, err := LoadGrafanaInstance(relpath, pkg, overlay)
if err != nil {
return cue.Value{}, err
}
if ctx == nil {
ctx = GrafanaCUEContext()
}
v := ctx.BuildInstance(bi)
if v.Err() != nil {
return v, fmt.Errorf("%s not a valid CUE instance: %w", relpath, v.Err())
}
return v, nil
}
// LoadInstanceWithGrafana loads a [*build.Instance] from .cue files
// in the provided modFS as ["cuelang.org/go/cue/load".Instances], but
// fulfilling any imports of CUE packages under:
//
// - github.com/grafana/grafana
// - github.com/grafana/thema
//
// This function is modeled after [load.InstanceWithThema]. It has the same
// signature and expectations for the modFS.
//
// Attempting to use this func to load files within the
// github.com/grafana/grafana CUE module will result in an error. Use
// [LoadGrafanaInstance] instead.
//
// NOTE This function will be deprecated in favor of a more generic loader
func LoadInstanceWithGrafana(fsys fs.FS, dir string, opts ...load.Option) (*build.Instance, error) {
if modf, err := fs.ReadFile(fsys, "cue.mod/module.cue"); err != nil {
// delegate error handling
return load.InstanceWithThema(fsys, dir, opts...)
} else if modname, err := cuecontext.New().CompileBytes(modf).LookupPath(cue.MakePath(cue.Str("module"))).String(); err != nil {
// delegate error handling
return load.InstanceWithThema(fsys, dir, opts...)
} else if modname == "github.com/grafana/grafana" {
return nil, fmt.Errorf("use cuectx.LoadGrafanaInstance to load .cue files within github.com/grafana/grafana CUE module")
}
// TODO wasteful, doing this every time - make that stateless prefixfs!
depFS, err := prefixFS("cue.mod/pkg/github.com/grafana/grafana", grafana.CueSchemaFS)
if err != nil {
panic(err)
}
// TODO wasteful, doing this every time - make that stateless prefixfs!
kindsysFS, err := prefixFS("cue.mod/pkg/github.com/grafana/kindsys", kindsys.CueSchemaFS)
if err != nil {
panic(err)
}
allTheFs := merged_fs.MergeMultiple(kindsysFS, depFS, fsys)
// FIXME remove grafana from cue.mod/pkg if it exists, otherwise external thing can inject files to be loaded
return load.InstanceWithThema(allTheFs, dir, opts...)
}
// LoadCoreKindDef loads and validates a core kind definition of the kind
// category indicated by the type parameter. On success, it returns a [Def]
// which contains the entire contents of the kind definition.
//
// defpath is the path to the directory containing the core kind definition,
// relative to the root of the caller's repository. For example, under
// dashboards are in "kinds/dashboard".
func LoadCoreKindDef(defpath string, ctx *cue.Context, overlay fs.FS) (kindsys.Def[kindsys.CoreProperties], error) {
vk, err := BuildGrafanaInstance(ctx, defpath, "kind", overlay)
if err != nil {
return kindsys.Def[kindsys.CoreProperties]{}, err
}
props, err := kindsys.ToKindProps[kindsys.CoreProperties](vk)
if err != nil {
return kindsys.Def[kindsys.CoreProperties]{}, err
}
return kindsys.Def[kindsys.CoreProperties]{
V: vk,
Properties: props,
}, nil
}

@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/grafana/codejen" "github.com/grafana/codejen"
"github.com/grafana/grafana/pkg/plugins/pfs"
) )
var registryPath = filepath.Join("pkg", "registry", "schemas") var registryPath = filepath.Join("pkg", "registry", "schemas")
@ -27,21 +28,22 @@ func (jenny *PluginRegistryJenny) JennyName() string {
return "PluginRegistryJenny" return "PluginRegistryJenny"
} }
func (jenny *PluginRegistryJenny) Generate(files []string) (*codejen.File, error) { func (jenny *PluginRegistryJenny) Generate(decls ...*pfs.PluginDecl) (*codejen.File, error) {
if len(files) == 0 { if len(decls) == 0 {
return nil, nil return nil, nil
} }
schemas := make([]Schema, len(files)) schemas := make([]Schema, len(decls))
for i, file := range files { for i, decl := range decls {
name, err := getSchemaName(file) variant := fmt.Sprintf("%s.cue", strings.ToLower(decl.SchemaInterface.Name))
name, err := getSchemaName(decl.PluginPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to find schema name: %s", err) return nil, fmt.Errorf("unable to find schema name: %s", err)
} }
schemas[i] = Schema{ schemas[i] = Schema{
Name: name, Name: name,
Filename: filepath.Base(file), Filename: variant,
FilePath: file, FilePath: "./" + filepath.Join("public", "app", "plugins", decl.PluginPath, variant),
} }
} }
@ -65,7 +67,7 @@ func getSchemaName(path string) (string, error) {
if len(parts) < 2 { if len(parts) < 2 {
return "", fmt.Errorf("path should contain more than 2 elements") return "", fmt.Errorf("path should contain more than 2 elements")
} }
folderName := parts[len(parts)-2] folderName := parts[len(parts)-1]
if renamed, ok := renamedPlugins[folderName]; ok { if renamed, ok := renamedPlugins[folderName]; ok {
folderName = renamed folderName = renamed
} }

@ -6,12 +6,9 @@ import (
"strings" "strings"
copenapi "cuelang.org/go/encoding/openapi" copenapi "cuelang.org/go/encoding/openapi"
"github.com/dave/dst/dstutil"
"github.com/grafana/codejen" "github.com/grafana/codejen"
corecodegen "github.com/grafana/grafana/pkg/codegen" "github.com/grafana/grafana/pkg/codegen/generators"
"github.com/grafana/grafana/pkg/plugins/pfs" "github.com/grafana/grafana/pkg/plugins/pfs"
"github.com/grafana/thema/encoding/gocode"
"github.com/grafana/thema/encoding/openapi"
) )
// TODO this is duplicative of other Go type jennies. Remove it in favor of a better-abstracted version in thema itself // TODO this is duplicative of other Go type jennies. Remove it in favor of a better-abstracted version in thema itself
@ -30,22 +27,22 @@ func (j *pgoJenny) JennyName() string {
} }
func (j *pgoJenny) Generate(decl *pfs.PluginDecl) (*codejen.File, error) { func (j *pgoJenny) Generate(decl *pfs.PluginDecl) (*codejen.File, error) {
b := decl.PluginMeta.Backend hasBackend := decl.PluginMeta.Backend
if b == nil || !*b || !decl.HasSchema() { // We skip elasticsearch since we have problems with the generated file.
// This is temporal until we migrate to the new system.
if hasBackend == nil || !*hasBackend || decl.PluginMeta.Id == "elasticsearch" {
return nil, nil return nil, nil
} }
slotname := strings.ToLower(decl.SchemaInterface.Name) slotname := strings.ToLower(decl.SchemaInterface.Name)
byt, err := gocode.GenerateTypesOpenAPI(decl.Lineage.Latest(), &gocode.TypeConfigOpenAPI{ byt, err := generators.GenerateTypesGo(decl.CueFile, &generators.GoConfig{
Config: &openapi.Config{ Config: &generators.OpenApiConfig{
Group: decl.SchemaInterface.IsGroup,
Config: &copenapi.Config{ Config: &copenapi.Config{
MaxCycleDepth: 10, MaxCycleDepth: 10,
}, },
SplitSchema: true, IsGroup: decl.SchemaInterface.IsGroup,
}, },
PackageName: slotname, PackageName: slotname,
ApplyFuncs: []dstutil.ApplyFunc{corecodegen.PrefixDropper(decl.Lineage.Name())},
}) })
if err != nil { if err != nil {
return nil, err return nil, err

@ -11,7 +11,6 @@ import (
tsast "github.com/grafana/cuetsy/ts/ast" tsast "github.com/grafana/cuetsy/ts/ast"
"github.com/grafana/grafana/pkg/build" "github.com/grafana/grafana/pkg/build"
"github.com/grafana/grafana/pkg/codegen" "github.com/grafana/grafana/pkg/codegen"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/grafana/grafana/pkg/plugins/pfs" "github.com/grafana/grafana/pkg/plugins/pfs"
) )
@ -34,15 +33,11 @@ func (j *ptsJenny) JennyName() string {
} }
func (j *ptsJenny) Generate(decl *pfs.PluginDecl) (codejen.Files, error) { func (j *ptsJenny) Generate(decl *pfs.PluginDecl) (codejen.Files, error) {
if !decl.HasSchema() {
return nil, nil
}
genFile := &tsast.File{} genFile := &tsast.File{}
versionedFile := &tsast.File{} versionedFile := &tsast.File{}
for _, im := range decl.Imports { for _, im := range decl.Imports {
if tsim, err := cuectx.ConvertImport(im); err != nil { if tsim, err := codegen.ConvertImport(im); err != nil {
return nil, err return nil, err
} else if tsim.From.Value != "" { } else if tsim.From.Value != "" {
genFile.Imports = append(genFile.Imports, tsim) genFile.Imports = append(genFile.Imports, tsim)
@ -94,18 +89,46 @@ func getPluginVersion(pluginVersion *string) string {
func adaptToPipeline(j codejen.OneToOne[codegen.SchemaForGen]) codejen.OneToOne[*pfs.PluginDecl] { func adaptToPipeline(j codejen.OneToOne[codegen.SchemaForGen]) codejen.OneToOne[*pfs.PluginDecl] {
return codejen.AdaptOneToOne(j, func(pd *pfs.PluginDecl) codegen.SchemaForGen { return codejen.AdaptOneToOne(j, func(pd *pfs.PluginDecl) codegen.SchemaForGen {
name := strings.ReplaceAll(pd.PluginMeta.Name, " ", "")
if pd.SchemaInterface.Name == "DataQuery" {
name = name + "DataQuery"
}
return codegen.SchemaForGen{ return codegen.SchemaForGen{
Name: name, Name: derivePascalName(pd.PluginMeta.Id, pd.PluginMeta.Name) + pd.SchemaInterface.Name,
Schema: pd.Lineage.Latest(), CueFile: pd.CueFile,
IsGroup: pd.SchemaInterface.IsGroup, IsGroup: pd.SchemaInterface.IsGroup,
} }
}) })
} }
func derivePascalName(id string, name string) string {
sani := func(s string) string {
ret := strings.Title(strings.Map(func(r rune) rune {
switch {
case r >= 'a' && r <= 'z':
return r
case r >= 'A' && r <= 'Z':
return r
default:
return -1
}
}, strings.Title(strings.Map(func(r rune) rune {
switch r {
case '-', '_':
return ' '
default:
return r
}
}, s))))
if len(ret) > 63 {
return ret[:63]
}
return ret
}
fromname := sani(name)
if len(fromname) != 0 {
return fromname
}
return sani(strings.Split(id, "-")[1])
}
func getGrafanaVersion() string { func getGrafanaVersion() string {
dir, err := os.Getwd() dir, err := os.Getwd()
if err != nil { if err != nil {

@ -1,30 +0,0 @@
package corelist
import (
"sync"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/grafana/grafana/pkg/plugins/pfs"
"github.com/grafana/thema"
)
var coreTrees []pfs.ParsedPlugin
var coreOnce sync.Once
// New returns a pfs.PluginList containing the plugin trees for all core plugins
// in the current version of Grafana.
//
// Go code within the grafana codebase should only ever call this with nil.
func New(rt *thema.Runtime) []pfs.ParsedPlugin {
var pl []pfs.ParsedPlugin
if rt == nil {
coreOnce.Do(func() {
coreTrees = corePlugins(cuectx.GrafanaThemaRuntime())
})
pl = make([]pfs.ParsedPlugin, len(coreTrees))
copy(pl, coreTrees)
} else {
return corePlugins(rt)
}
return pl
}

@ -1,87 +0,0 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
//
// Generated by:
// public/app/plugins/gen.go
// Using jennies:
// PluginTreeListJenny
//
// Run 'make gen-cue' from repository root to regenerate.
package corelist
import (
"fmt"
"io/fs"
"github.com/grafana/grafana"
"github.com/grafana/grafana/pkg/plugins/pfs"
"github.com/grafana/thema"
)
func parsePluginOrPanic(path string, pkgname string, rt *thema.Runtime) pfs.ParsedPlugin {
sub, err := fs.Sub(grafana.CueSchemaFS, path)
if err != nil {
panic("could not create fs sub to " + path)
}
pp, err := pfs.ParsePluginFS(sub, rt)
if err != nil {
panic(fmt.Sprintf("error parsing plugin metadata for %s: %s", pkgname, err))
}
return pp
}
func corePlugins(rt *thema.Runtime) []pfs.ParsedPlugin {
return []pfs.ParsedPlugin{
parsePluginOrPanic("public/app/plugins/datasource/alertmanager", "alertmanager", rt),
parsePluginOrPanic("public/app/plugins/datasource/azuremonitor", "grafana_azure_monitor_datasource", rt),
parsePluginOrPanic("public/app/plugins/datasource/cloud-monitoring", "stackdriver", rt),
parsePluginOrPanic("public/app/plugins/datasource/cloudwatch", "cloudwatch", rt),
parsePluginOrPanic("public/app/plugins/datasource/dashboard", "dashboard", rt),
parsePluginOrPanic("public/app/plugins/datasource/elasticsearch", "elasticsearch", rt),
parsePluginOrPanic("public/app/plugins/datasource/grafana", "grafana", rt),
parsePluginOrPanic("public/app/plugins/datasource/grafana-postgresql-datasource", "grafana_postgresql_datasource", rt),
parsePluginOrPanic("public/app/plugins/datasource/grafana-pyroscope-datasource", "grafana_pyroscope_datasource", rt),
parsePluginOrPanic("public/app/plugins/datasource/grafana-testdata-datasource", "grafana_testdata_datasource", rt),
parsePluginOrPanic("public/app/plugins/datasource/graphite", "graphite", rt),
parsePluginOrPanic("public/app/plugins/datasource/jaeger", "jaeger", rt),
parsePluginOrPanic("public/app/plugins/datasource/loki", "loki", rt),
parsePluginOrPanic("public/app/plugins/datasource/mssql", "mssql", rt),
parsePluginOrPanic("public/app/plugins/datasource/mysql", "mysql", rt),
parsePluginOrPanic("public/app/plugins/datasource/parca", "parca", rt),
parsePluginOrPanic("public/app/plugins/datasource/prometheus", "prometheus", rt),
parsePluginOrPanic("public/app/plugins/datasource/tempo", "tempo", rt),
parsePluginOrPanic("public/app/plugins/datasource/zipkin", "zipkin", rt),
parsePluginOrPanic("public/app/plugins/panel/alertlist", "alertlist", rt),
parsePluginOrPanic("public/app/plugins/panel/annolist", "annolist", rt),
parsePluginOrPanic("public/app/plugins/panel/barchart", "barchart", rt),
parsePluginOrPanic("public/app/plugins/panel/bargauge", "bargauge", rt),
parsePluginOrPanic("public/app/plugins/panel/candlestick", "candlestick", rt),
parsePluginOrPanic("public/app/plugins/panel/canvas", "canvas", rt),
parsePluginOrPanic("public/app/plugins/panel/dashlist", "dashlist", rt),
parsePluginOrPanic("public/app/plugins/panel/datagrid", "datagrid", rt),
parsePluginOrPanic("public/app/plugins/panel/debug", "debug", rt),
parsePluginOrPanic("public/app/plugins/panel/flamegraph", "flamegraph", rt),
parsePluginOrPanic("public/app/plugins/panel/gauge", "gauge", rt),
parsePluginOrPanic("public/app/plugins/panel/geomap", "geomap", rt),
parsePluginOrPanic("public/app/plugins/panel/gettingstarted", "gettingstarted", rt),
parsePluginOrPanic("public/app/plugins/panel/graph", "graph", rt),
parsePluginOrPanic("public/app/plugins/panel/heatmap", "heatmap", rt),
parsePluginOrPanic("public/app/plugins/panel/histogram", "histogram", rt),
parsePluginOrPanic("public/app/plugins/panel/live", "live", rt),
parsePluginOrPanic("public/app/plugins/panel/logs", "logs", rt),
parsePluginOrPanic("public/app/plugins/panel/news", "news", rt),
parsePluginOrPanic("public/app/plugins/panel/nodeGraph", "nodeGraph", rt),
parsePluginOrPanic("public/app/plugins/panel/piechart", "piechart", rt),
parsePluginOrPanic("public/app/plugins/panel/stat", "stat", rt),
parsePluginOrPanic("public/app/plugins/panel/state-timeline", "state_timeline", rt),
parsePluginOrPanic("public/app/plugins/panel/status-history", "status_history", rt),
parsePluginOrPanic("public/app/plugins/panel/table", "table", rt),
parsePluginOrPanic("public/app/plugins/panel/table-old", "table_old", rt),
parsePluginOrPanic("public/app/plugins/panel/text", "text", rt),
parsePluginOrPanic("public/app/plugins/panel/timeseries", "timeseries", rt),
parsePluginOrPanic("public/app/plugins/panel/traces", "traces", rt),
parsePluginOrPanic("public/app/plugins/panel/trend", "trend", rt),
parsePluginOrPanic("public/app/plugins/panel/welcome", "welcome", rt),
parsePluginOrPanic("public/app/plugins/panel/xychart", "xychart", rt),
}
}

@ -1,18 +1,16 @@
package pfs package pfs
import ( import (
"cuelang.org/go/cue"
"cuelang.org/go/cue/ast" "cuelang.org/go/cue/ast"
"github.com/grafana/kindsys"
"github.com/grafana/thema"
) )
type PluginDecl struct { type PluginDecl struct {
SchemaInterface *SchemaInterface SchemaInterface SchemaInterface
Lineage thema.Lineage CueFile cue.Value
Imports []*ast.ImportSpec Imports []*ast.ImportSpec
PluginPath string PluginPath string
PluginMeta Metadata PluginMeta Metadata
KindDecl kindsys.Def[kindsys.ComposableProperties]
} }
type SchemaInterface struct { type SchemaInterface struct {
@ -26,15 +24,3 @@ type Metadata struct {
Backend *bool Backend *bool
Version *string Version *string
} }
func EmptyPluginDecl(path string, meta Metadata) *PluginDecl {
return &PluginDecl{
PluginPath: path,
PluginMeta: meta,
Imports: make([]*ast.ImportSpec, 0),
}
}
func (decl *PluginDecl) HasSchema() bool {
return decl.Lineage != nil && decl.SchemaInterface != nil
}

@ -6,35 +6,22 @@ import (
"path/filepath" "path/filepath"
"sort" "sort"
"github.com/grafana/thema" "cuelang.org/go/cue/cuecontext"
) )
type declParser struct { type DeclParser struct {
rt *thema.Runtime
skip map[string]bool skip map[string]bool
} }
// Extracted from kindsys repository func NewDeclParser(skip map[string]bool) *DeclParser {
var schemaInterfaces = map[string]*SchemaInterface{ return &DeclParser{
"PanelCfg": {
Name: "PanelCfg",
IsGroup: true,
},
"DataQuery": {
Name: "DataQuery",
IsGroup: false,
},
}
func NewDeclParser(rt *thema.Runtime, skip map[string]bool) *declParser {
return &declParser{
rt: rt,
skip: skip, skip: skip,
} }
} }
// TODO convert this to be the new parser for Tree // TODO convert this to be the new parser for Tree
func (psr *declParser) Parse(root fs.FS) ([]*PluginDecl, error) { func (psr *DeclParser) Parse(root fs.FS) ([]*PluginDecl, error) {
ctx := cuecontext.New()
// TODO remove hardcoded tree structure assumption, work from root of provided fs // TODO remove hardcoded tree structure assumption, work from root of provided fs
plugins, err := fs.Glob(root, "**/**/plugin.json") plugins, err := fs.Glob(root, "**/**/plugin.json")
if err != nil { if err != nil {
@ -50,30 +37,23 @@ func (psr *declParser) Parse(root fs.FS) ([]*PluginDecl, error) {
} }
dir, _ := fs.Sub(root, path) dir, _ := fs.Sub(root, path)
pp, err := ParsePluginFS(dir, psr.rt) pp, err := ParsePluginFS(ctx, dir, path)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing plugin failed for %s: %s", dir, err) return nil, fmt.Errorf("parsing plugin failed for %s: %s", dir, err)
} }
if len(pp.ComposableKinds) == 0 { if !pp.CueFile.Exists() {
decls = append(decls, EmptyPluginDecl(path, pp.Properties))
continue continue
} }
for slotName, kind := range pp.ComposableKinds {
if err != nil {
return nil, fmt.Errorf("parsing plugin failed for %s: %s", dir, err)
}
decls = append(decls, &PluginDecl{ decls = append(decls, &PluginDecl{
SchemaInterface: schemaInterfaces[slotName], SchemaInterface: pp.Variant,
Lineage: kind.Lineage(), CueFile: pp.CueFile,
Imports: pp.CUEImports, Imports: pp.CUEImports,
PluginMeta: pp.Properties, PluginMeta: pp.Properties,
PluginPath: path, PluginPath: path,
KindDecl: kind.Def(),
}) })
} }
}
sort.Slice(decls, func(i, j int) bool { sort.Slice(decls, func(i, j int) bool {
return decls[i].PluginPath < decls[j].PluginPath return decls[i].PluginPath < decls[j].PluginPath

@ -4,29 +4,32 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/fs" "io/fs"
"sort"
"strings" "strings"
"testing/fstest"
"cuelang.org/go/cue" "cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/errors" "cuelang.org/go/cue/errors"
"cuelang.org/go/cue/token" "cuelang.org/go/cue/load"
"github.com/grafana/kindsys" "github.com/grafana/grafana/pkg/codegen"
"github.com/grafana/thema"
"github.com/grafana/thema/load"
"github.com/yalue/merged_fs"
"github.com/grafana/grafana/pkg/cuectx"
) )
// PackageName is the name of the CUE package that Grafana will load when // PackageName is the name of the CUE package that Grafana will load when
// looking for a Grafana plugin's kind declarations. // looking for a Grafana plugin's kind declarations.
const PackageName = "grafanaplugin" const PackageName = "grafanaplugin"
var schemaInterface = map[string]SchemaInterface{
"DataQuery": {
Name: "DataQuery",
IsGroup: false,
},
"PanelCfg": {
Name: "PanelCfg",
IsGroup: true,
},
}
// PermittedCUEImports returns the list of import paths that may be used in a // PermittedCUEImports returns the list of import paths that may be used in a
// plugin's grafanaplugin cue package. // plugin's grafanaplugin cue package.
var PermittedCUEImports = cuectx.PermittedCUEImports var PermittedCUEImports = codegen.PermittedCUEImports
func importAllowed(path string) bool { func importAllowed(path string) bool {
for _, p := range PermittedCUEImports() { for _, p := range PermittedCUEImports() {
@ -39,22 +42,12 @@ func importAllowed(path string) bool {
var allowedImportsStr string var allowedImportsStr string
var allsi []kindsys.SchemaInterface
func init() { func init() {
all := make([]string, 0, len(PermittedCUEImports())) all := make([]string, 0, len(PermittedCUEImports()))
for _, im := range PermittedCUEImports() { for _, im := range PermittedCUEImports() {
all = append(all, fmt.Sprintf("\t%s", im)) all = append(all, fmt.Sprintf("\t%s", im))
} }
allowedImportsStr = strings.Join(all, "\n") allowedImportsStr = strings.Join(all, "\n")
for _, s := range kindsys.SchemaInterfaces(nil) {
allsi = append(allsi, s)
}
sort.Slice(allsi, func(i, j int) bool {
return allsi[i].Name() < allsi[j].Name()
})
} }
// ParsePluginFS takes a virtual filesystem and checks that it contains a valid // ParsePluginFS takes a virtual filesystem and checks that it contains a valid
@ -69,17 +62,17 @@ func init() {
// This function parses exactly one plugin. It does not descend into // This function parses exactly one plugin. It does not descend into
// subdirectories to search for additional plugin.json or .cue files. // subdirectories to search for additional plugin.json or .cue files.
// //
// Calling this with a nil [thema.Runtime] (the singleton returned from
// [cuectx.GrafanaThemaRuntime] is used) will memoize certain CUE operations.
// Prefer passing nil unless a different thema.Runtime is specifically required.
//
// [GrafanaPlugin]: https://github.com/grafana/grafana/blob/main/pkg/plugins/pfs/grafanaplugin.cue // [GrafanaPlugin]: https://github.com/grafana/grafana/blob/main/pkg/plugins/pfs/grafanaplugin.cue
func ParsePluginFS(fsys fs.FS, rt *thema.Runtime) (ParsedPlugin, error) { func ParsePluginFS(ctx *cue.Context, fsys fs.FS, dir string) (ParsedPlugin, error) {
if fsys == nil { if fsys == nil {
return ParsedPlugin{}, ErrEmptyFS return ParsedPlugin{}, ErrEmptyFS
} }
if rt == nil {
rt = cuectx.GrafanaThemaRuntime() cuefiles, err := fs.Glob(fsys, "*.cue")
if err != nil {
return ParsedPlugin{}, fmt.Errorf("error globbing for cue files in fsys: %w", err)
} else if len(cuefiles) == 0 {
return ParsedPlugin{}, nil
} }
metadata, err := getPluginMetadata(fsys) metadata, err := getPluginMetadata(fsys)
@ -88,27 +81,19 @@ func ParsePluginFS(fsys fs.FS, rt *thema.Runtime) (ParsedPlugin, error) {
} }
pp := ParsedPlugin{ pp := ParsedPlugin{
ComposableKinds: make(map[string]kindsys.Composable),
Properties: metadata, Properties: metadata,
} }
if cuefiles, err := fs.Glob(fsys, "*.cue"); err != nil {
return ParsedPlugin{}, fmt.Errorf("error globbing for cue files in fsys: %w", err)
} else if len(cuefiles) == 0 {
return pp, nil
}
fsys, err = ensureCueMod(fsys, pp.Properties)
if err != nil { if err != nil {
return ParsedPlugin{}, fmt.Errorf("%s has invalid cue.mod: %w", pp.Properties.Id, err) return ParsedPlugin{}, err
} }
bi, err := cuectx.LoadInstanceWithGrafana(fsys, "", load.Package(PackageName)) bi := load.Instances(cuefiles, &load.Config{
if err != nil || bi.Err != nil { Package: PackageName,
if err == nil { Dir: dir,
err = bi.Err })[0]
} if bi.Err != nil {
return ParsedPlugin{}, errors.Wrap(errors.Newf(token.NoPos, "%s did not load", pp.Properties.Id), err) return ParsedPlugin{}, bi.Err
} }
for _, f := range bi.Files { for _, f := range bi.Files {
@ -132,105 +117,35 @@ func ParsePluginFS(fsys fs.FS, rt *thema.Runtime) (ParsedPlugin, error) {
panic("Refactor required - upstream CUE implementation changed, bi.Files is no longer populated") panic("Refactor required - upstream CUE implementation changed, bi.Files is no longer populated")
} }
gpi := rt.Context().BuildInstance(bi) gpi := ctx.BuildInstance(bi)
if gpi.Err() != nil { if gpi.Err() != nil {
return ParsedPlugin{}, errors.Wrap(errors.Promote(ErrInvalidGrafanaPluginInstance, pp.Properties.Id), gpi.Err()) return ParsedPlugin{}, errors.Wrap(errors.Promote(ErrInvalidGrafanaPluginInstance, pp.Properties.Id), gpi.Err())
} }
for _, si := range allsi { for name, si := range schemaInterface {
iv := gpi.LookupPath(cue.MakePath(cue.Str("composableKinds"), cue.Str(si.Name()))) iv := gpi.LookupPath(cue.MakePath(cue.Str("composableKinds"), cue.Str(name)))
if !iv.Exists() { if !iv.Exists() {
continue continue
} }
iv = iv.FillPath(cue.MakePath(cue.Str("schemaInterface")), si.Name()) iv = iv.FillPath(cue.MakePath(cue.Str("schemaInterface")), name)
iv = iv.FillPath(cue.MakePath(cue.Str("name")), derivePascalName(pp.Properties.Id, pp.Properties.Name)+si.Name()) iv = iv.FillPath(cue.MakePath(cue.Str("name")), derivePascalName(pp.Properties.Id, pp.Properties.Name)+name)
lineageNamePath := iv.LookupPath(cue.MakePath(cue.Str("lineage"), cue.Str("name"))) lineageNamePath := iv.LookupPath(cue.MakePath(cue.Str("lineage"), cue.Str("name")))
if !lineageNamePath.Exists() { if !lineageNamePath.Exists() {
iv = iv.FillPath(cue.MakePath(cue.Str("lineage"), cue.Str("name")), derivePascalName(pp.Properties.Id, pp.Properties.Name)+si.Name()) iv = iv.FillPath(cue.MakePath(cue.Str("lineage"), cue.Str("name")), derivePascalName(pp.Properties.Id, pp.Properties.Name)+name)
} }
validSchema := iv.LookupPath(cue.ParsePath("lineage.schemas[0].schema")) validSchema := iv.LookupPath(cue.ParsePath("lineage.schemas[0].schema"))
if !validSchema.Exists() { if !validSchema.Exists() {
return ParsedPlugin{}, errors.Wrap(errors.Promote(ErrInvalidGrafanaPluginInstance, pp.Properties.Id), validSchema.Err()) return ParsedPlugin{}, errors.Wrap(errors.Promote(ErrInvalidGrafanaPluginInstance, pp.Properties.Id), validSchema.Err())
} }
pp.Variant = si
props, err := kindsys.ToKindProps[kindsys.ComposableProperties](iv) pp.CueFile = iv
if err != nil {
return ParsedPlugin{}, err
}
compo, err := kindsys.BindComposable(rt, kindsys.Def[kindsys.ComposableProperties]{
Properties: props,
V: iv,
})
if err != nil {
return ParsedPlugin{}, err
}
pp.ComposableKinds[si.Name()] = compo
} }
return pp, nil return pp, nil
} }
// LoadComposableKindDef loads and validates a composable kind definition.
// On success, it returns a [Def] which contains the entire contents of the kind definition.
//
// defpath is the path to the directory containing the composable kind definition,
// relative to the root of the caller's repository.
//
// NOTE This function will be deprecated in favor of a more generic loader when kind
// providers will be implemented.
func LoadComposableKindDef(fsys fs.FS, rt *thema.Runtime, defpath string) (kindsys.Def[kindsys.ComposableProperties], error) {
pp := ParsedPlugin{
ComposableKinds: make(map[string]kindsys.Composable),
Properties: Metadata{
Id: defpath,
},
}
fsys, err := ensureCueMod(fsys, pp.Properties)
if err != nil {
return kindsys.Def[kindsys.ComposableProperties]{}, fmt.Errorf("%s has invalid cue.mod: %w", pp.Properties.Id, err)
}
bi, err := cuectx.LoadInstanceWithGrafana(fsys, "", load.Package(PackageName))
if err != nil {
return kindsys.Def[kindsys.ComposableProperties]{}, err
}
ctx := rt.Context()
v := ctx.BuildInstance(bi)
if v.Err() != nil {
return kindsys.Def[kindsys.ComposableProperties]{}, fmt.Errorf("%s not a valid CUE instance: %w", defpath, v.Err())
}
props, err := kindsys.ToKindProps[kindsys.ComposableProperties](v)
if err != nil {
return kindsys.Def[kindsys.ComposableProperties]{}, err
}
return kindsys.Def[kindsys.ComposableProperties]{
V: v,
Properties: props,
}, nil
}
func ensureCueMod(fsys fs.FS, metadata Metadata) (fs.FS, error) {
if modf, err := fs.ReadFile(fsys, "cue.mod/module.cue"); err != nil {
if !errors.Is(err, fs.ErrNotExist) {
return nil, err
}
return merged_fs.NewMergedFS(fsys, fstest.MapFS{
"cue.mod/module.cue": &fstest.MapFile{Data: []byte(fmt.Sprintf(`module: "grafana.com/grafana/plugins/%s"`, metadata.Id))},
}), nil
} else if _, err := cuecontext.New().CompileBytes(modf).LookupPath(cue.MakePath(cue.Str("module"))).String(); err != nil {
return nil, fmt.Errorf("error reading cue module name: %w", err)
}
return fsys, nil
}
func getPluginMetadata(fsys fs.FS) (Metadata, error) { func getPluginMetadata(fsys fs.FS) (Metadata, error) {
b, err := fs.ReadFile(fsys, "plugin.json") b, err := fs.ReadFile(fsys, "plugin.json")
if err != nil { if err != nil {

@ -1,297 +0,0 @@
package pfs
import (
"archive/zip"
"io/fs"
"os"
"path/filepath"
"sort"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/stretchr/testify/require"
)
func TestParsePluginTestdata(t *testing.T) {
type tt struct {
tfs fs.FS
// TODO could remove this by getting rid of inconsistent subdirs
subpath string
skip string
err error
// TODO could remove this by expecting that dirname == id
rootid string
}
tab := map[string]tt{
"app-with-child": {
rootid: "myorgid-simple-app",
subpath: "dist",
skip: "schema violation, weirdness in info.version field",
},
"duplicate-plugins": {
rootid: "test-app",
subpath: "nested",
skip: "schema violation, dependencies don't follow naming constraints",
},
"includes-symlinks": {
skip: "schema violation, dependencies don't follow naming constraints",
},
"installer": {
rootid: "test-datasource",
subpath: "plugin",
},
"invalid-plugin-json": {
rootid: "test-app",
err: ErrInvalidRootFile,
},
"invalid-v1-signature": {
rootid: "test-datasource",
subpath: "plugin",
},
"invalid-v2-extra-file": {
rootid: "test-datasource",
subpath: "plugin",
},
"invalid-v2-missing-file": {
rootid: "test-datasource",
subpath: "plugin",
},
"lacking-files": {
rootid: "test-datasource",
subpath: "plugin",
},
"nested-plugins": {
rootid: "test-datasource",
subpath: "parent",
},
"non-pvt-with-root-url": {
rootid: "test-datasource",
subpath: "plugin",
},
"renderer-added-file": {
rootid: "test-renderer",
subpath: "plugin",
},
"symbolic-plugin-dirs": {
skip: "io/fs-based scanner will not traverse symlinks; caller of ParsePluginFS() must do it",
},
"test-app": {
skip: "schema violation, dependencies don't follow naming constraints",
rootid: "test-app",
},
"test-app-with-includes": {
rootid: "test-app",
skip: "has a 'page'-type include which isn't a known part of spec",
},
"test-app-with-roles": {
rootid: "test-app",
},
"unsigned-datasource": {
rootid: "test-datasource",
subpath: "plugin",
},
"unsigned-panel": {
rootid: "test-panel",
subpath: "plugin",
},
"valid-v2-pvt-signature": {
rootid: "test-datasource",
subpath: "plugin",
},
"valid-v2-pvt-signature-root-url-uri": {
rootid: "test-datasource",
subpath: "plugin",
},
"valid-v2-signature": {
rootid: "test-datasource",
subpath: "plugin",
},
"plugin-with-dist": {
rootid: "test-datasource",
subpath: "plugin",
},
"no-rootfile": {
err: ErrNoRootFile,
},
"valid-model-panel": {},
"valid-model-datasource": {},
"missing-kind-datasource": {},
"panel-conflicting-joinschema": {
err: ErrInvalidLineage,
skip: "TODO implement BindOption in thema, SatisfiesJoinSchema, then use it here",
},
"panel-does-not-follow-slot-joinschema": {
err: ErrInvalidLineage,
skip: "TODO implement BindOption in thema, SatisfiesJoinSchema, then use it here",
},
"pluginRootWithDist": {
err: ErrNoRootFile,
skip: "This folder is used to test multiple plugins in the same folder",
},
"name-mismatch-panel": {
err: ErrInvalidGrafanaPluginInstance,
},
"disallowed-cue-import": {
err: ErrDisallowedCUEImport,
},
"cdn": {
rootid: "grafana-worldmap-panel",
subpath: "plugin",
},
"external-registration": {
rootid: "grafana-test-datasource",
},
}
staticRootPath, err := filepath.Abs(filepath.Join("..", "manager", "testdata"))
require.NoError(t, err)
dfs := os.DirFS(staticRootPath)
ents, err := fs.ReadDir(dfs, ".")
require.NoError(t, err)
// Ensure table test and dir list are ==
var dirs, tts []string
for k := range tab {
tts = append(tts, k)
}
for _, ent := range ents {
dirs = append(dirs, ent.Name())
}
sort.Strings(tts)
sort.Strings(dirs)
if !cmp.Equal(tts, dirs) {
t.Fatalf("table test map (-) and pkg/plugins/manager/testdata dirs (+) differ: %s", cmp.Diff(tts, dirs))
}
for _, ent := range ents {
tst := tab[ent.Name()]
tst.tfs, err = fs.Sub(dfs, filepath.Join(ent.Name(), tst.subpath))
require.NoError(t, err)
tab[ent.Name()] = tst
}
lib := cuectx.GrafanaThemaRuntime()
for name, otst := range tab {
tst := otst // otherwise var is shadowed within func by looping
t.Run(name, func(t *testing.T) {
if tst.skip != "" {
t.Skip(tst.skip)
}
pp, err := ParsePluginFS(tst.tfs, lib)
if tst.err == nil {
require.NoError(t, err, "unexpected error while parsing plugin tree")
} else {
require.Error(t, err)
t.Logf("%T %s", err, err)
require.ErrorIs(t, err, tst.err, "unexpected error type while parsing plugin tree")
return
}
if tst.rootid == "" {
tst.rootid = name
}
require.Equal(t, tst.rootid, pp.Properties.Id, "expected plugin id and actual plugin id differ")
})
}
}
func TestParseTreeZips(t *testing.T) {
type tt struct {
tfs fs.FS
// TODO could remove this by getting rid of inconsistent subdirs
subpath string
skip string
err error
// TODO could remove this by expecting that dirname == id
rootid string
}
tab := map[string]tt{
"grafana-simple-json-datasource-ec18fa4da8096a952608a7e4c7782b4260b41bcf.zip": {
skip: "binary plugin",
},
"plugin-with-absolute-member.zip": {
skip: "not actually a plugin, no plugin.json?",
},
"plugin-with-absolute-symlink-dir.zip": {
skip: "not actually a plugin, no plugin.json?",
},
"plugin-with-absolute-symlink.zip": {
skip: "not actually a plugin, no plugin.json?",
},
"plugin-with-parent-member.zip": {
skip: "not actually a plugin, no plugin.json?",
},
"plugin-with-symlink-dir.zip": {
skip: "not actually a plugin, no plugin.json?",
},
"plugin-with-symlink.zip": {
skip: "not actually a plugin, no plugin.json?",
},
"plugin-with-symlinks.zip": {
subpath: "test-app",
rootid: "test-app",
},
}
staticRootPath, err := filepath.Abs(filepath.Join("..", "storage", "testdata"))
require.NoError(t, err)
ents, err := os.ReadDir(staticRootPath)
require.NoError(t, err)
// Ensure table test and dir list are ==
var dirs, tts []string
for k := range tab {
tts = append(tts, k)
}
for _, ent := range ents {
dirs = append(dirs, ent.Name())
}
sort.Strings(tts)
sort.Strings(dirs)
if !cmp.Equal(tts, dirs) {
t.Fatalf("table test map (-) and pkg/plugins/installer/testdata dirs (+) differ: %s", cmp.Diff(tts, dirs))
}
for _, ent := range ents {
tst := tab[ent.Name()]
r, err := zip.OpenReader(filepath.Join(staticRootPath, ent.Name()))
require.NoError(t, err)
defer r.Close() //nolint:errcheck
if tst.subpath != "" {
tst.tfs, err = fs.Sub(r, tst.subpath)
require.NoError(t, err)
} else {
tst.tfs = r
}
tab[ent.Name()] = tst
}
lib := cuectx.GrafanaThemaRuntime()
for name, otst := range tab {
tst := otst // otherwise var is shadowed within func by looping
t.Run(name, func(t *testing.T) {
if tst.skip != "" {
t.Skip(tst.skip)
}
pp, err := ParsePluginFS(tst.tfs, lib)
if tst.err == nil {
require.NoError(t, err, "unexpected error while parsing plugin fs")
} else {
require.ErrorIs(t, err, tst.err, "unexpected error type while parsing plugin fs")
return
}
if tst.rootid == "" {
tst.rootid = name
}
require.Equal(t, tst.rootid, pp.Properties.Id, "expected plugin id and actual plugin id differ")
})
}
}

@ -1,8 +1,8 @@
package pfs package pfs
import ( import (
"cuelang.org/go/cue"
"cuelang.org/go/cue/ast" "cuelang.org/go/cue/ast"
"github.com/grafana/kindsys"
) )
// ParsedPlugin represents everything knowable about a single plugin from static // ParsedPlugin represents everything knowable about a single plugin from static
@ -13,35 +13,10 @@ import (
type ParsedPlugin struct { type ParsedPlugin struct {
// Properties contains the plugin's definition, as declared in plugin.json. // Properties contains the plugin's definition, as declared in plugin.json.
Properties Metadata Properties Metadata
CueFile cue.Value
// ComposableKinds is a map of all the composable kinds declared in this plugin. Variant SchemaInterface
// Keys are the name of the [kindsys.SchemaInterface] implemented by the value.
//
// Composable kind defs are only populated in this map by [ParsePluginFS] if
// they are implementations of a known schema interface, or are for
// an unknown schema interface.
ComposableKinds map[string]kindsys.Composable
// CustomKinds is a map of all the custom kinds declared in this plugin.
// Keys are the machineName of the custom kind.
// CustomKinds map[string]kindsys.Custom
// CUEImports lists the CUE import statements in the plugin's grafanaplugin CUE // CUEImports lists the CUE import statements in the plugin's grafanaplugin CUE
// package, if any. // package, if any.
CUEImports []*ast.ImportSpec CUEImports []*ast.ImportSpec
} }
// TODO is this static approach worth using, akin to core generated registries? instead of the ParsedPlugins.ComposableKinds map? in addition to it?
// ComposableKinds represents all the possible composable kinds that may be
// defined in a Grafana plugin.
//
// The value of each field, if non-nil, is a standard [kindsys.Def]
// representing a CUE definition of a composable kind that implements the
// schema interface corresponding to the field's name. (This invariant is
// only enforced in [ComposableKinds] returned from [ParsePluginFS].)
//
// type ComposableKinds struct {
// PanelCfg kindsys.Def[kindsys.ComposableProperties]
// Queries kindsys.Def[kindsys.ComposableProperties]
// DSCfg kindsys.Def[kindsys.ComposableProperties]
// }

@ -1,31 +0,0 @@
package pfs
import (
"sort"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/grafana/kindsys"
)
// This is a brick-dumb test that just ensures known schema interfaces are being
// loaded correctly from their declarations in .cue files.
//
// If this test fails, it's either because:
// - They're not being loaded correctly - there's a bug in kindsys or pfs somewhere, fix it
// - The set of schema interfaces has been modified - update the static list here
func TestSchemaInterfacesAreLoaded(t *testing.T) {
knownSI := []string{"PanelCfg", "DataQuery", "DataSourceCfg"}
all := kindsys.SchemaInterfaces(nil)
var loadedSI []string
for k := range all {
loadedSI = append(loadedSI, k)
}
sort.Strings(knownSI)
sort.Strings(loadedSI)
if diff := cmp.Diff(knownSI, loadedSI); diff != "" {
t.Fatalf("kindsys cue-declared schema interfaces differ from ComposableKinds go struct:\n%s", diff)
}
}

@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/api/avatar" "github.com/grafana/grafana/pkg/api/avatar"
"github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/httpclient"
@ -306,8 +305,6 @@ var wireBasicSet = wire.NewSet(
secretsStore.ProvideService, secretsStore.ProvideService,
avatar.ProvideAvatarCacheServer, avatar.ProvideAvatarCacheServer,
statscollector.ProvideService, statscollector.ProvideService,
cuectx.GrafanaCUEContext,
cuectx.GrafanaThemaRuntime,
csrf.ProvideCSRFFilter, csrf.ProvideCSRFFilter,
wire.Bind(new(csrf.Service), new(*csrf.CSRF)), wire.Bind(new(csrf.Service), new(*csrf.CSRF)),
ossaccesscontrol.ProvideTeamPermissions, ossaccesscontrol.ProvideTeamPermissions,

@ -98,9 +98,8 @@ const (
// AppInsightsGroupByQuery defines model for AppInsightsGroupByQuery. // AppInsightsGroupByQuery defines model for AppInsightsGroupByQuery.
type AppInsightsGroupByQuery struct { type AppInsightsGroupByQuery struct {
BaseGrafanaTemplateVariableQuery Kind *AppInsightsGroupByQueryKind `json:"kind,omitempty"`
Kind AppInsightsGroupByQueryKind `json:"kind"` MetricName *string `json:"metricName,omitempty"`
MetricName string `json:"metricName"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
} }
@ -109,8 +108,7 @@ type AppInsightsGroupByQueryKind string
// AppInsightsMetricNameQuery defines model for AppInsightsMetricNameQuery. // AppInsightsMetricNameQuery defines model for AppInsightsMetricNameQuery.
type AppInsightsMetricNameQuery struct { type AppInsightsMetricNameQuery struct {
BaseGrafanaTemplateVariableQuery Kind *AppInsightsMetricNameQueryKind `json:"kind,omitempty"`
Kind AppInsightsMetricNameQueryKind `json:"kind"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
} }
@ -221,11 +219,6 @@ type AzureMonitorDataQuery = map[string]any
// AzureMonitorQuery defines model for AzureMonitorQuery. // AzureMonitorQuery defines model for AzureMonitorQuery.
type AzureMonitorQuery struct { type AzureMonitorQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
// Azure Monitor Logs sub-query properties // Azure Monitor Logs sub-query properties
AzureLogAnalytics *AzureLogsQuery `json:"azureLogAnalytics,omitempty"` AzureLogAnalytics *AzureLogsQuery `json:"azureLogAnalytics,omitempty"`
AzureMonitor *AzureMetricQuery `json:"azureMonitor,omitempty"` AzureMonitor *AzureMetricQuery `json:"azureMonitor,omitempty"`
@ -233,9 +226,29 @@ type AzureMonitorQuery struct {
// Application Insights Traces sub-query properties // Application Insights Traces sub-query properties
AzureTraces *AzureTracesQuery `json:"azureTraces,omitempty"` AzureTraces *AzureTracesQuery `json:"azureTraces,omitempty"`
// For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema
// TODO this shouldn't be unknown but DataSourceRef | null
Datasource *any `json:"datasource,omitempty"`
GrafanaTemplateVariableFn *any `json:"grafanaTemplateVariableFn,omitempty"` GrafanaTemplateVariableFn *any `json:"grafanaTemplateVariableFn,omitempty"`
// Hide true if query is disabled (ie should not be returned to the dashboard)
// Note this does not always imply that the query should not be executed since
// the results from a hidden query may be used as the input to other queries (SSE etc)
Hide *bool `json:"hide,omitempty"`
Namespace *string `json:"namespace,omitempty"` Namespace *string `json:"namespace,omitempty"`
// Specify the query flavor
// TODO make this required and give it a default
QueryType *string `json:"queryType,omitempty"`
// A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId *string `json:"refId,omitempty"`
// Azure Monitor query type. // Azure Monitor query type.
// queryType: #AzureQueryType // queryType: #AzureQueryType
Region *string `json:"region,omitempty"` Region *string `json:"region,omitempty"`
@ -336,15 +349,14 @@ type DataQuery struct {
// GrafanaTemplateVariableQueryType defines model for GrafanaTemplateVariableQueryType. // GrafanaTemplateVariableQueryType defines model for GrafanaTemplateVariableQueryType.
type GrafanaTemplateVariableQueryType string type GrafanaTemplateVariableQueryType string
// MetricDefinitionsQuery defines model for MetricDefinitionsQuery. // @deprecated Use MetricNamespaceQuery instead
type MetricDefinitionsQuery struct { type MetricDefinitionsQuery struct {
BaseGrafanaTemplateVariableQuery Kind *MetricDefinitionsQueryKind `json:"kind,omitempty"`
Kind MetricDefinitionsQueryKind `json:"kind"`
MetricNamespace *string `json:"metricNamespace,omitempty"` MetricNamespace *string `json:"metricNamespace,omitempty"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
ResourceGroup string `json:"resourceGroup"` ResourceGroup *string `json:"resourceGroup,omitempty"`
ResourceName *string `json:"resourceName,omitempty"` ResourceName *string `json:"resourceName,omitempty"`
Subscription string `json:"subscription"` Subscription *string `json:"subscription,omitempty"`
} }
// MetricDefinitionsQueryKind defines model for MetricDefinitionsQuery.Kind. // MetricDefinitionsQueryKind defines model for MetricDefinitionsQuery.Kind.
@ -352,13 +364,12 @@ type MetricDefinitionsQueryKind string
// MetricNamesQuery defines model for MetricNamesQuery. // MetricNamesQuery defines model for MetricNamesQuery.
type MetricNamesQuery struct { type MetricNamesQuery struct {
BaseGrafanaTemplateVariableQuery Kind *MetricNamesQueryKind `json:"kind,omitempty"`
Kind MetricNamesQueryKind `json:"kind"` MetricNamespace *string `json:"metricNamespace,omitempty"`
MetricNamespace string `json:"metricNamespace"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
ResourceGroup string `json:"resourceGroup"` ResourceGroup *string `json:"resourceGroup,omitempty"`
ResourceName string `json:"resourceName"` ResourceName *string `json:"resourceName,omitempty"`
Subscription string `json:"subscription"` Subscription *string `json:"subscription,omitempty"`
} }
// MetricNamesQueryKind defines model for MetricNamesQuery.Kind. // MetricNamesQueryKind defines model for MetricNamesQuery.Kind.
@ -366,13 +377,12 @@ type MetricNamesQueryKind string
// MetricNamespaceQuery defines model for MetricNamespaceQuery. // MetricNamespaceQuery defines model for MetricNamespaceQuery.
type MetricNamespaceQuery struct { type MetricNamespaceQuery struct {
BaseGrafanaTemplateVariableQuery Kind *MetricNamespaceQueryKind `json:"kind,omitempty"`
Kind MetricNamespaceQueryKind `json:"kind"`
MetricNamespace *string `json:"metricNamespace,omitempty"` MetricNamespace *string `json:"metricNamespace,omitempty"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
ResourceGroup string `json:"resourceGroup"` ResourceGroup *string `json:"resourceGroup,omitempty"`
ResourceName *string `json:"resourceName,omitempty"` ResourceName *string `json:"resourceName,omitempty"`
Subscription string `json:"subscription"` Subscription *string `json:"subscription,omitempty"`
} }
// MetricNamespaceQueryKind defines model for MetricNamespaceQuery.Kind. // MetricNamespaceQueryKind defines model for MetricNamespaceQuery.Kind.
@ -380,10 +390,9 @@ type MetricNamespaceQueryKind string
// ResourceGroupsQuery defines model for ResourceGroupsQuery. // ResourceGroupsQuery defines model for ResourceGroupsQuery.
type ResourceGroupsQuery struct { type ResourceGroupsQuery struct {
BaseGrafanaTemplateVariableQuery Kind *ResourceGroupsQueryKind `json:"kind,omitempty"`
Kind ResourceGroupsQueryKind `json:"kind"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
Subscription string `json:"subscription"` Subscription *string `json:"subscription,omitempty"`
} }
// ResourceGroupsQueryKind defines model for ResourceGroupsQuery.Kind. // ResourceGroupsQueryKind defines model for ResourceGroupsQuery.Kind.
@ -391,12 +400,11 @@ type ResourceGroupsQueryKind string
// ResourceNamesQuery defines model for ResourceNamesQuery. // ResourceNamesQuery defines model for ResourceNamesQuery.
type ResourceNamesQuery struct { type ResourceNamesQuery struct {
BaseGrafanaTemplateVariableQuery Kind *ResourceNamesQueryKind `json:"kind,omitempty"`
Kind ResourceNamesQueryKind `json:"kind"` MetricNamespace *string `json:"metricNamespace,omitempty"`
MetricNamespace string `json:"metricNamespace"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
ResourceGroup string `json:"resourceGroup"` ResourceGroup *string `json:"resourceGroup,omitempty"`
Subscription string `json:"subscription"` Subscription *string `json:"subscription,omitempty"`
} }
// ResourceNamesQueryKind defines model for ResourceNamesQuery.Kind. // ResourceNamesQueryKind defines model for ResourceNamesQuery.Kind.
@ -407,8 +415,7 @@ type ResultFormat string
// SubscriptionsQuery defines model for SubscriptionsQuery. // SubscriptionsQuery defines model for SubscriptionsQuery.
type SubscriptionsQuery struct { type SubscriptionsQuery struct {
BaseGrafanaTemplateVariableQuery Kind *SubscriptionsQueryKind `json:"kind,omitempty"`
Kind SubscriptionsQueryKind `json:"kind"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
} }
@ -417,8 +424,7 @@ type SubscriptionsQueryKind string
// UnknownQuery defines model for UnknownQuery. // UnknownQuery defines model for UnknownQuery.
type UnknownQuery struct { type UnknownQuery struct {
BaseGrafanaTemplateVariableQuery Kind *UnknownQueryKind `json:"kind,omitempty"`
Kind UnknownQueryKind `json:"kind"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
} }
@ -427,10 +433,9 @@ type UnknownQueryKind string
// WorkspacesQuery defines model for WorkspacesQuery. // WorkspacesQuery defines model for WorkspacesQuery.
type WorkspacesQuery struct { type WorkspacesQuery struct {
BaseGrafanaTemplateVariableQuery Kind *WorkspacesQueryKind `json:"kind,omitempty"`
Kind WorkspacesQueryKind `json:"kind"`
RawQuery *string `json:"rawQuery,omitempty"` RawQuery *string `json:"rawQuery,omitempty"`
Subscription string `json:"subscription"` Subscription *string `json:"subscription,omitempty"`
} }
// WorkspacesQueryKind defines model for WorkspacesQuery.Kind. // WorkspacesQueryKind defines model for WorkspacesQuery.Kind.

@ -410,9 +410,7 @@ func addTraceDataLinksToFields(query *AzureLogAnalyticsQuery, azurePortalBaseUrl
logsQueryType := string(dataquery.AzureQueryTypeAzureLogAnalytics) logsQueryType := string(dataquery.AzureQueryTypeAzureLogAnalytics)
logsJSONModel := dataquery.AzureMonitorQuery{ logsJSONModel := dataquery.AzureMonitorQuery{
DataQuery: dataquery.DataQuery{
QueryType: &logsQueryType, QueryType: &logsQueryType,
},
AzureLogAnalytics: &dataquery.AzureLogsQuery{ AzureLogAnalytics: &dataquery.AzureLogsQuery{
Query: &query.TraceLogsExploreQuery, Query: &query.TraceLogsExploreQuery,
Resources: []string{queryJSONModel.AzureTraces.Resources[0]}, Resources: []string{queryJSONModel.AzureTraces.Resources[0]},

@ -89,20 +89,35 @@ type AlignmentTypes string
// CloudMonitoringQuery defines model for CloudMonitoringQuery. // CloudMonitoringQuery defines model for CloudMonitoringQuery.
type CloudMonitoringQuery struct { type CloudMonitoringQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
// Aliases can be set to modify the legend labels. e.g. {{metric.label.xxx}}. See docs for more detail. // Aliases can be set to modify the legend labels. e.g. {{metric.label.xxx}}. See docs for more detail.
AliasBy *string `json:"aliasBy,omitempty"` AliasBy *string `json:"aliasBy,omitempty"`
// For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema
// TODO this shouldn't be unknown but DataSourceRef | null
Datasource *any `json:"datasource,omitempty"`
// Hide true if query is disabled (ie should not be returned to the dashboard)
// Note this does not always imply that the query should not be executed since
// the results from a hidden query may be used as the input to other queries (SSE etc)
Hide *bool `json:"hide,omitempty"`
// Time interval in milliseconds. // Time interval in milliseconds.
IntervalMs *float32 `json:"intervalMs,omitempty"` IntervalMs *float32 `json:"intervalMs,omitempty"`
// PromQL sub-query properties. // PromQL sub-query properties.
PromQLQuery *PromQLQuery `json:"promQLQuery,omitempty"` PromQLQuery *PromQLQuery `json:"promQLQuery,omitempty"`
// Specify the query flavor
// TODO make this required and give it a default
QueryType *string `json:"queryType,omitempty"`
// A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId *string `json:"refId,omitempty"`
// SLO sub-query properties. // SLO sub-query properties.
SloQuery *SLOQuery `json:"sloQuery,omitempty"` SloQuery *SLOQuery `json:"sloQuery,omitempty"`

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils"
) )
type annotationEvent struct { type annotationEvent struct {
@ -50,7 +51,12 @@ func (e *cloudWatchExecutor) executeAnnotationQuery(ctx context.Context, pluginC
actionPrefix := model.ActionPrefix actionPrefix := model.ActionPrefix
alarmNamePrefix := model.AlarmNamePrefix alarmNamePrefix := model.AlarmNamePrefix
cli, err := e.getCWClient(ctx, pluginCtx, model.Region) region := ""
if model.Region != nil {
region = *model.Region
}
cli, err := e.getCWClient(ctx, pluginCtx, region)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -76,9 +82,9 @@ func (e *cloudWatchExecutor) executeAnnotationQuery(ctx context.Context, pluginC
if err != nil { if err != nil {
return nil, fmt.Errorf("%v: %w", "failed to call cloudwatch:DescribeAlarms", err) return nil, fmt.Errorf("%v: %w", "failed to call cloudwatch:DescribeAlarms", err)
} }
alarmNames = filterAlarms(resp, model.Namespace, metricName, dimensions, statistic, period) alarmNames = filterAlarms(resp, utils.Depointerizer(model.Namespace), metricName, dimensions, statistic, period)
} else { } else {
if model.Region == "" || model.Namespace == "" || metricName == "" || statistic == "" { if model.Region == nil || model.Namespace == nil || metricName == "" || statistic == "" {
return result, errors.New("invalid annotations query") return result, errors.New("invalid annotations query")
} }
@ -96,7 +102,7 @@ func (e *cloudWatchExecutor) executeAnnotationQuery(ctx context.Context, pluginC
} }
} }
params := &cloudwatch.DescribeAlarmsForMetricInput{ params := &cloudwatch.DescribeAlarmsForMetricInput{
Namespace: aws.String(model.Namespace), Namespace: aws.String(utils.Depointerizer(model.Namespace)),
MetricName: aws.String(metricName), MetricName: aws.String(metricName),
Dimensions: qd, Dimensions: qd,
Statistic: aws.String(statistic), Statistic: aws.String(statistic),

@ -210,8 +210,12 @@ func (e *cloudWatchExecutor) QueryData(ctx context.Context, req *backend.QueryDa
// Public dashboard queries execute like alert queries, i.e. they execute on the backend, therefore, we need to handle them synchronously. // Public dashboard queries execute like alert queries, i.e. they execute on the backend, therefore, we need to handle them synchronously.
// Since `model.Type` is set during execution on the frontend by the query runner and isn't saved with the query, we are checking here is // Since `model.Type` is set during execution on the frontend by the query runner and isn't saved with the query, we are checking here is
// missing the `model.Type` property and if it is a log query in order to determine if it is a public dashboard query. // missing the `model.Type` property and if it is a log query in order to determine if it is a public dashboard query.
fromPublicDashboard := (model.Type == "" && model.QueryMode == logsQueryMode) queryMode := ""
isSyncLogQuery := ((fromAlert || fromExpression) && model.QueryMode == logsQueryMode) || fromPublicDashboard if model.QueryMode != nil {
queryMode = string(*model.QueryMode)
}
fromPublicDashboard := model.Type == "" && queryMode == logsQueryMode
isSyncLogQuery := ((fromAlert || fromExpression) && queryMode == logsQueryMode) || fromPublicDashboard
if isSyncLogQuery { if isSyncLogQuery {
return executeSyncLogQuery(ctx, e, req) return executeSyncLogQuery(ctx, e, req)
} }

@ -105,14 +105,11 @@ const (
QueryEditorPropertyTypeString QueryEditorPropertyType = "string" QueryEditorPropertyTypeString QueryEditorPropertyType = "string"
) )
// CloudWatchAnnotationQuery defines model for CloudWatchAnnotationQuery. // Shape of a CloudWatch Annotation query
//
// TS type is CloudWatchDefaultQuery = Omit<CloudWatchLogsQuery, 'queryMode'> & CloudWatchMetricsQuery, declared in veneer
// #CloudWatchDefaultQuery: #CloudWatchLogsQuery & #CloudWatchMetricsQuery @cuetsy(kind="type")
type CloudWatchAnnotationQuery struct { type CloudWatchAnnotationQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
MetricStat
// The ID of the AWS account to query for the metric, specifying `all` will query all accounts that the monitoring account is permitted to query. // The ID of the AWS account to query for the metric, specifying `all` will query all accounts that the monitoring account is permitted to query.
AccountId *string `json:"accountId,omitempty"` AccountId *string `json:"accountId,omitempty"`
@ -149,14 +146,14 @@ type CloudWatchAnnotationQuery struct {
MetricName *string `json:"metricName,omitempty"` MetricName *string `json:"metricName,omitempty"`
// A namespace is a container for CloudWatch metrics. Metrics in different namespaces are isolated from each other, so that metrics from different applications are not mistakenly aggregated into the same statistics. For example, Amazon EC2 uses the AWS/EC2 namespace. // A namespace is a container for CloudWatch metrics. Metrics in different namespaces are isolated from each other, so that metrics from different applications are not mistakenly aggregated into the same statistics. For example, Amazon EC2 uses the AWS/EC2 namespace.
Namespace string `json:"namespace"` Namespace *string `json:"namespace,omitempty"`
// The length of time associated with a specific Amazon CloudWatch statistic. Can be specified by a number of seconds, 'auto', or as a duration string e.g. '15m' being 15 minutes // The length of time associated with a specific Amazon CloudWatch statistic. Can be specified by a number of seconds, 'auto', or as a duration string e.g. '15m' being 15 minutes
Period *string `json:"period,omitempty"` Period *string `json:"period,omitempty"`
// Enable matching on the prefix of the action name or alarm name, specify the prefixes with actionPrefix and/or alarmNamePrefix // Enable matching on the prefix of the action name or alarm name, specify the prefixes with actionPrefix and/or alarmNamePrefix
PrefixMatching *bool `json:"prefixMatching,omitempty"` PrefixMatching *bool `json:"prefixMatching,omitempty"`
QueryMode CloudWatchQueryMode `json:"queryMode"` QueryMode *CloudWatchQueryMode `json:"queryMode,omitempty"`
// Specify the query flavor // Specify the query flavor
// TODO make this required and give it a default // TODO make this required and give it a default
@ -165,10 +162,10 @@ type CloudWatchAnnotationQuery struct {
// A unique identifier for the query within the list of targets. // A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results. // In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful. // By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId string `json:"refId"` RefId *string `json:"refId,omitempty"`
// AWS region to query for the metric // AWS region to query for the metric
Region string `json:"region"` Region *string `json:"region,omitempty"`
// Metric data aggregations over specified periods of time. For detailed definitions of the statistics supported by CloudWatch, see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Statistics-definitions.html. // Metric data aggregations over specified periods of time. For detailed definitions of the statistics supported by CloudWatch, see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Statistics-definitions.html.
Statistic *string `json:"statistic,omitempty"` Statistic *string `json:"statistic,omitempty"`
@ -180,13 +177,8 @@ type CloudWatchAnnotationQuery struct {
// CloudWatchDataQuery defines model for CloudWatchDataQuery. // CloudWatchDataQuery defines model for CloudWatchDataQuery.
type CloudWatchDataQuery = map[string]any type CloudWatchDataQuery = map[string]any
// CloudWatchLogsQuery defines model for CloudWatchLogsQuery. // Shape of a CloudWatch Logs query
type CloudWatchLogsQuery struct { type CloudWatchLogsQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
// For mixed data sources the selected datasource is on the query level. // For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined. // For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema // TODO find a better way to do this ^ that's friendly to schema
@ -200,14 +192,14 @@ type CloudWatchLogsQuery struct {
// Note this does not always imply that the query should not be executed since // Note this does not always imply that the query should not be executed since
// the results from a hidden query may be used as the input to other queries (SSE etc) // the results from a hidden query may be used as the input to other queries (SSE etc)
Hide *bool `json:"hide,omitempty"` Hide *bool `json:"hide,omitempty"`
Id string `json:"id"` Id *string `json:"id,omitempty"`
// @deprecated use logGroups // @deprecated use logGroups
LogGroupNames []string `json:"logGroupNames,omitempty"` LogGroupNames []string `json:"logGroupNames,omitempty"`
// Log groups to query // Log groups to query
LogGroups []LogGroup `json:"logGroups,omitempty"` LogGroups []LogGroup `json:"logGroups,omitempty"`
QueryMode CloudWatchQueryMode `json:"queryMode"` QueryMode *CloudWatchQueryMode `json:"queryMode,omitempty"`
// Specify the query flavor // Specify the query flavor
// TODO make this required and give it a default // TODO make this required and give it a default
@ -216,23 +208,17 @@ type CloudWatchLogsQuery struct {
// A unique identifier for the query within the list of targets. // A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results. // In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful. // By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId string `json:"refId"` RefId *string `json:"refId,omitempty"`
// AWS region to query for the logs // AWS region to query for the logs
Region string `json:"region"` Region *string `json:"region,omitempty"`
// Fields to group the results by, this field is automatically populated whenever the query is updated // Fields to group the results by, this field is automatically populated whenever the query is updated
StatsGroups []string `json:"statsGroups,omitempty"` StatsGroups []string `json:"statsGroups,omitempty"`
} }
// CloudWatchMetricsQuery defines model for CloudWatchMetricsQuery. // Shape of a CloudWatch Metrics query
type CloudWatchMetricsQuery struct { type CloudWatchMetricsQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
MetricStat
// The ID of the AWS account to query for the metric, specifying `all` will query all accounts that the monitoring account is permitted to query. // The ID of the AWS account to query for the metric, specifying `all` will query all accounts that the monitoring account is permitted to query.
AccountId *string `json:"accountId,omitempty"` AccountId *string `json:"accountId,omitempty"`
@ -258,7 +244,7 @@ type CloudWatchMetricsQuery struct {
Hide *bool `json:"hide,omitempty"` Hide *bool `json:"hide,omitempty"`
// ID can be used to reference other queries in math expressions. The ID can include numbers, letters, and underscore, and must start with a lowercase letter. // ID can be used to reference other queries in math expressions. The ID can include numbers, letters, and underscore, and must start with a lowercase letter.
Id string `json:"id"` Id *string `json:"id,omitempty"`
// Change the time series legend names using dynamic labels. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/graph-dynamic-labels.html for more details. // Change the time series legend names using dynamic labels. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/graph-dynamic-labels.html for more details.
Label *string `json:"label,omitempty"` Label *string `json:"label,omitempty"`
@ -272,7 +258,7 @@ type CloudWatchMetricsQuery struct {
MetricQueryType *MetricQueryType `json:"metricQueryType,omitempty"` MetricQueryType *MetricQueryType `json:"metricQueryType,omitempty"`
// A namespace is a container for CloudWatch metrics. Metrics in different namespaces are isolated from each other, so that metrics from different applications are not mistakenly aggregated into the same statistics. For example, Amazon EC2 uses the AWS/EC2 namespace. // A namespace is a container for CloudWatch metrics. Metrics in different namespaces are isolated from each other, so that metrics from different applications are not mistakenly aggregated into the same statistics. For example, Amazon EC2 uses the AWS/EC2 namespace.
Namespace string `json:"namespace"` Namespace *string `json:"namespace,omitempty"`
// The length of time associated with a specific Amazon CloudWatch statistic. Can be specified by a number of seconds, 'auto', or as a duration string e.g. '15m' being 15 minutes // The length of time associated with a specific Amazon CloudWatch statistic. Can be specified by a number of seconds, 'auto', or as a duration string e.g. '15m' being 15 minutes
Period *string `json:"period,omitempty"` Period *string `json:"period,omitempty"`
@ -285,10 +271,10 @@ type CloudWatchMetricsQuery struct {
// A unique identifier for the query within the list of targets. // A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results. // In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful. // By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId string `json:"refId"` RefId *string `json:"refId,omitempty"`
// AWS region to query for the metric // AWS region to query for the metric
Region string `json:"region"` Region *string `json:"region,omitempty"`
Sql *SQLExpression `json:"sql,omitempty"` Sql *SQLExpression `json:"sql,omitempty"`
// When the metric query type is `metricQueryType` is set to `Query`, this field is used to specify the query string. // When the metric query type is `metricQueryType` is set to `Query`, this field is used to specify the query string.

@ -102,8 +102,8 @@ func (e *cloudWatchExecutor) executeLogAction(ctx context.Context, logsQuery mod
} }
region := instance.Settings.Region region := instance.Settings.Region
if logsQuery.Region != "" { if logsQuery.Region != nil {
region = logsQuery.Region region = *logsQuery.Region
} }
logsClient, err := e.getCWLogsClient(ctx, pluginCtx, region) logsClient, err := e.getCWLogsClient(ctx, pluginCtx, region)
@ -248,8 +248,8 @@ func (e *cloudWatchExecutor) handleStartQuery(ctx context.Context, logsClient cl
dataFrame.RefID = refID dataFrame.RefID = refID
region := "default" region := "default"
if logsQuery.Region != "" { if logsQuery.Region != nil {
region = logsQuery.Region region = *logsQuery.Region
} }
dataFrame.Meta = &data.FrameMeta{ dataFrame.Meta = &data.FrameMeta{

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils"
) )
const initialAlertPollPeriod = time.Second const initialAlertPollPeriod = time.Second
@ -36,9 +37,9 @@ var executeSyncLogQuery = func(ctx context.Context, e *cloudWatchExecutor, req *
logsQuery.QueryString = *logsQuery.Expression logsQuery.QueryString = *logsQuery.Expression
} }
region := logsQuery.Region region := utils.Depointerizer(logsQuery.Region)
if logsQuery.Region == "" || region == defaultRegion { if region == "" || region == defaultRegion {
logsQuery.Region = instance.Settings.Region logsQuery.Region = utils.Pointer(instance.Settings.Region)
} }
logsClient, err := e.getCWLogsClient(ctx, req.PluginContext, region) logsClient, err := e.getCWLogsClient(ctx, req.PluginContext, region)

@ -17,6 +17,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils"
) )
type ( type (
@ -239,9 +240,9 @@ func ParseMetricDataQueries(dataQueries []backend.DataQuery, startTime time.Time
cwQuery := &CloudWatchQuery{ cwQuery := &CloudWatchQuery{
logger: logger, logger: logger,
RefId: refId, RefId: refId,
Id: mdq.Id, Id: utils.Depointerizer(mdq.Id),
Region: mdq.Region, Region: utils.Depointerizer(mdq.Region),
Namespace: mdq.Namespace, Namespace: utils.Depointerizer(mdq.Namespace),
TimezoneUTCOffset: mdq.TimezoneUTCOffset, TimezoneUTCOffset: mdq.TimezoneUTCOffset,
} }
@ -314,7 +315,7 @@ func (q *CloudWatchQuery) validateAndSetDefaults(refId string, metricsDataQuery
q.AccountId = metricsDataQuery.AccountId q.AccountId = metricsDataQuery.AccountId
} }
if metricsDataQuery.Id == "" { if utils.Depointerizer(metricsDataQuery.Id) == "" {
// Why not just use refId if id is not specified in the frontend? When specifying an id in the editor, // Why not just use refId if id is not specified in the frontend? When specifying an id in the editor,
// and alphabetical must be used. The id must be unique, so if an id like for example a, b or c would be used, // and alphabetical must be used. The id must be unique, so if an id like for example a, b or c would be used,
// it would likely collide with some ref id. That's why the `query` prefix is used. // it would likely collide with some ref id. That's why the `query` prefix is used.

@ -7,8 +7,6 @@ import (
"testing" "testing"
"time" "time"
"github.com/grafana/kindsys"
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery" "github.com/grafana/grafana/pkg/tsdb/cloudwatch/kinds/dataquery"
@ -898,15 +896,15 @@ func Test_migrateAliasToDynamicLabel_single_query_preserves_old_alias_and_create
queryToMigrate := metricsDataQuery{ queryToMigrate := metricsDataQuery{
CloudWatchMetricsQuery: dataquery.CloudWatchMetricsQuery{ CloudWatchMetricsQuery: dataquery.CloudWatchMetricsQuery{
Region: "us-east-1", Region: utils.Pointer("us-east-1"),
Namespace: "ec2", Namespace: utils.Pointer("ec2"),
MetricName: kindsys.Ptr("CPUUtilization"), MetricName: utils.Pointer("CPUUtilization"),
Alias: kindsys.Ptr(tc.inputAlias), Alias: utils.Pointer(tc.inputAlias),
Dimensions: &dataquery.Dimensions{ Dimensions: &dataquery.Dimensions{
"InstanceId": []any{"test"}, "InstanceId": []any{"test"},
}, },
Statistic: &average, Statistic: &average,
Period: kindsys.Ptr("600"), Period: utils.Pointer("600"),
Hide: &false, Hide: &false,
}, },
} }

@ -4,6 +4,15 @@ import "github.com/go-stack/stack"
func Pointer[T any](arg T) *T { return &arg } func Pointer[T any](arg T) *T { return &arg }
func Depointerizer[T any](v *T) T {
var emptyValue T
if v != nil {
emptyValue = *v
}
return emptyValue
}
// Stack is copied from grafana/pkg/infra/log // Stack is copied from grafana/pkg/infra/log
// TODO: maybe this should live in grafana-plugin-sdk-go? // TODO: maybe this should live in grafana-plugin-sdk-go?
func Stack(skip int) string { func Stack(skip int) string {

@ -43,11 +43,6 @@ type DataQuery struct {
// GrafanaPyroscopeDataQuery defines model for GrafanaPyroscopeDataQuery. // GrafanaPyroscopeDataQuery defines model for GrafanaPyroscopeDataQuery.
type GrafanaPyroscopeDataQuery struct { type GrafanaPyroscopeDataQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
// For mixed data sources the selected datasource is on the query level. // For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined. // For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema // TODO find a better way to do this ^ that's friendly to schema
@ -55,7 +50,7 @@ type GrafanaPyroscopeDataQuery struct {
Datasource *any `json:"datasource,omitempty"` Datasource *any `json:"datasource,omitempty"`
// Allows to group the results. // Allows to group the results.
GroupBy []string `json:"groupBy"` GroupBy []string `json:"groupBy,omitempty"`
// Hide true if query is disabled (ie should not be returned to the dashboard) // Hide true if query is disabled (ie should not be returned to the dashboard)
// Note this does not always imply that the query should not be executed since // Note this does not always imply that the query should not be executed since
@ -63,13 +58,13 @@ type GrafanaPyroscopeDataQuery struct {
Hide *bool `json:"hide,omitempty"` Hide *bool `json:"hide,omitempty"`
// Specifies the query label selectors. // Specifies the query label selectors.
LabelSelector string `json:"labelSelector"` LabelSelector *string `json:"labelSelector,omitempty"`
// Sets the maximum number of nodes in the flamegraph. // Sets the maximum number of nodes in the flamegraph.
MaxNodes *int64 `json:"maxNodes,omitempty"` MaxNodes *int64 `json:"maxNodes,omitempty"`
// Specifies the type of profile to query. // Specifies the type of profile to query.
ProfileTypeId string `json:"profileTypeId"` ProfileTypeId *string `json:"profileTypeId,omitempty"`
// Specify the query flavor // Specify the query flavor
// TODO make this required and give it a default // TODO make this required and give it a default
@ -78,7 +73,7 @@ type GrafanaPyroscopeDataQuery struct {
// A unique identifier for the query within the list of targets. // A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results. // In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful. // By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId string `json:"refId"` RefId *string `json:"refId,omitempty"`
// Specifies the query span selectors. // Specifies the query span selectors.
SpanSelector []string `json:"spanSelector,omitempty"` SpanSelector []string `json:"spanSelector,omitempty"`

@ -52,6 +52,9 @@ func (d *PyroscopeDatasource) query(ctx context.Context, pCtx backend.PluginCont
return response return response
} }
profileTypeId := depointerizer(qm.ProfileTypeId)
labelSelector := depointerizer(qm.LabelSelector)
responseMutex := sync.Mutex{} responseMutex := sync.Mutex{}
g, gCtx := errgroup.WithContext(ctx) g, gCtx := errgroup.WithContext(ctx)
if query.QueryType == queryTypeMetrics || query.QueryType == queryTypeBoth { if query.QueryType == queryTypeMetrics || query.QueryType == queryTypeBoth {
@ -75,8 +78,8 @@ func (d *PyroscopeDatasource) query(ctx context.Context, pCtx backend.PluginCont
logger.Debug("Sending SelectSeriesRequest", "queryModel", qm, "function", logEntrypoint()) logger.Debug("Sending SelectSeriesRequest", "queryModel", qm, "function", logEntrypoint())
seriesResp, err := d.client.GetSeries( seriesResp, err := d.client.GetSeries(
gCtx, gCtx,
qm.ProfileTypeId, profileTypeId,
qm.LabelSelector, labelSelector,
query.TimeRange.From.UnixMilli(), query.TimeRange.From.UnixMilli(),
query.TimeRange.To.UnixMilli(), query.TimeRange.To.UnixMilli(),
qm.GroupBy, qm.GroupBy,
@ -101,7 +104,7 @@ func (d *PyroscopeDatasource) query(ctx context.Context, pCtx backend.PluginCont
var profileResp *ProfileResponse var profileResp *ProfileResponse
if len(qm.SpanSelector) > 0 { if len(qm.SpanSelector) > 0 {
logger.Debug("Calling GetSpanProfile", "queryModel", qm, "function", logEntrypoint()) logger.Debug("Calling GetSpanProfile", "queryModel", qm, "function", logEntrypoint())
prof, err := d.client.GetSpanProfile(gCtx, qm.ProfileTypeId, qm.LabelSelector, qm.SpanSelector, query.TimeRange.From.UnixMilli(), query.TimeRange.To.UnixMilli(), qm.MaxNodes) prof, err := d.client.GetSpanProfile(gCtx, profileTypeId, labelSelector, qm.SpanSelector, query.TimeRange.From.UnixMilli(), query.TimeRange.To.UnixMilli(), qm.MaxNodes)
if err != nil { if err != nil {
span.RecordError(err) span.RecordError(err)
span.SetStatus(codes.Error, err.Error()) span.SetStatus(codes.Error, err.Error())
@ -111,7 +114,7 @@ func (d *PyroscopeDatasource) query(ctx context.Context, pCtx backend.PluginCont
profileResp = prof profileResp = prof
} else { } else {
logger.Debug("Calling GetProfile", "queryModel", qm, "function", logEntrypoint()) logger.Debug("Calling GetProfile", "queryModel", qm, "function", logEntrypoint())
prof, err := d.client.GetProfile(gCtx, qm.ProfileTypeId, qm.LabelSelector, query.TimeRange.From.UnixMilli(), query.TimeRange.To.UnixMilli(), qm.MaxNodes) prof, err := d.client.GetProfile(gCtx, profileTypeId, labelSelector, query.TimeRange.From.UnixMilli(), query.TimeRange.To.UnixMilli(), qm.MaxNodes)
if err != nil { if err != nil {
span.RecordError(err) span.RecordError(err)
span.SetStatus(codes.Error, err.Error()) span.SetStatus(codes.Error, err.Error())
@ -450,3 +453,12 @@ func seriesToDataFrames(resp *SeriesResponse) []*data.Frame {
} }
return frames return frames
} }
func depointerizer[T any](v *T) T {
var emptyValue T
if v != nil {
emptyValue = *v
}
return emptyValue
}

@ -26,11 +26,11 @@ const (
StreamingQueryTypeTraces StreamingQueryType = "traces" StreamingQueryTypeTraces StreamingQueryType = "traces"
) )
// Defines values for ErrorType. // Defines values for TestDataDataQueryErrorType.
const ( const (
ErrorTypeFrontendException ErrorType = "frontend_exception" TestDataDataQueryErrorTypeFrontendException TestDataDataQueryErrorType = "frontend_exception"
ErrorTypeFrontendObservable ErrorType = "frontend_observable" TestDataDataQueryErrorTypeFrontendObservable TestDataDataQueryErrorType = "frontend_observable"
ErrorTypeServerPanic ErrorType = "server_panic" TestDataDataQueryErrorTypeServerPanic TestDataDataQueryErrorType = "server_panic"
) )
// Defines values for TestDataQueryType. // Defines values for TestDataQueryType.
@ -154,27 +154,43 @@ type StreamingQueryType string
// TestDataDataQuery defines model for TestDataDataQuery. // TestDataDataQuery defines model for TestDataDataQuery.
type TestDataDataQuery struct { type TestDataDataQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
Alias *string `json:"alias,omitempty"` Alias *string `json:"alias,omitempty"`
Channel *string `json:"channel,omitempty"` Channel *string `json:"channel,omitempty"`
CsvContent *string `json:"csvContent,omitempty"` CsvContent *string `json:"csvContent,omitempty"`
CsvFileName *string `json:"csvFileName,omitempty"` CsvFileName *string `json:"csvFileName,omitempty"`
CsvWave []CSVWave `json:"csvWave,omitempty"` CsvWave []CSVWave `json:"csvWave,omitempty"`
// For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema
// TODO this shouldn't be unknown but DataSourceRef | null
Datasource *any `json:"datasource,omitempty"`
// Drop percentage (the chance we will lose a point 0-100) // Drop percentage (the chance we will lose a point 0-100)
DropPercent *float64 `json:"dropPercent,omitempty"` DropPercent *float64 `json:"dropPercent,omitempty"`
ErrorType *ErrorType `json:"errorType,omitempty"` ErrorType *TestDataDataQueryErrorType `json:"errorType,omitempty"`
FlamegraphDiff *bool `json:"flamegraphDiff,omitempty"` FlamegraphDiff *bool `json:"flamegraphDiff,omitempty"`
// Hide true if query is disabled (ie should not be returned to the dashboard)
// Note this does not always imply that the query should not be executed since
// the results from a hidden query may be used as the input to other queries (SSE etc)
Hide *bool `json:"hide,omitempty"`
Labels *string `json:"labels,omitempty"` Labels *string `json:"labels,omitempty"`
LevelColumn *bool `json:"levelColumn,omitempty"` LevelColumn *bool `json:"levelColumn,omitempty"`
Lines *int64 `json:"lines,omitempty"` Lines *int64 `json:"lines,omitempty"`
Nodes *NodesQuery `json:"nodes,omitempty"` Nodes *NodesQuery `json:"nodes,omitempty"`
Points [][]any `json:"points,omitempty"` Points [][]any `json:"points,omitempty"`
PulseWave *PulseWaveQuery `json:"pulseWave,omitempty"` PulseWave *PulseWaveQuery `json:"pulseWave,omitempty"`
// Specify the query flavor
// TODO make this required and give it a default
QueryType *string `json:"queryType,omitempty"`
RawFrameContent *string `json:"rawFrameContent,omitempty"` RawFrameContent *string `json:"rawFrameContent,omitempty"`
// A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId *string `json:"refId,omitempty"`
ScenarioId *TestDataQueryType `json:"scenarioId,omitempty"` ScenarioId *TestDataQueryType `json:"scenarioId,omitempty"`
SeriesCount *int32 `json:"seriesCount,omitempty"` SeriesCount *int32 `json:"seriesCount,omitempty"`
Sim *SimulationQuery `json:"sim,omitempty"` Sim *SimulationQuery `json:"sim,omitempty"`
@ -184,8 +200,8 @@ type TestDataDataQuery struct {
Usa *USAQuery `json:"usa,omitempty"` Usa *USAQuery `json:"usa,omitempty"`
} }
// ErrorType defines model for TestDataDataQuery.ErrorType. // TestDataDataQueryErrorType defines model for TestDataDataQuery.ErrorType.
type ErrorType string type TestDataDataQueryErrorType string
// TestDataQueryType defines model for TestDataQueryType. // TestDataQueryType defines model for TestDataQueryType.
type TestDataQueryType string type TestDataQueryType string

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery" "github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery"
"github.com/grafana/grafana/pkg/util"
) )
const ( const (
@ -39,7 +40,7 @@ func healthcheck(ctx context.Context, req *backend.CheckHealthRequest, s *Servic
step := "1s" step := "1s"
qt := "instant" qt := "instant"
qm := dataquery.LokiDataQuery{ qm := dataquery.LokiDataQuery{
Expr: "vector(1)+vector(1)", Expr: util.Pointer("vector(1)+vector(1)"),
Step: &step, Step: &step,
QueryType: &qt, QueryType: &qt,
} }

@ -63,11 +63,6 @@ type DataQuery struct {
// LokiDataQuery defines model for LokiDataQuery. // LokiDataQuery defines model for LokiDataQuery.
type LokiDataQuery struct { type LokiDataQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
// For mixed data sources the selected datasource is on the query level. // For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined. // For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema // TODO find a better way to do this ^ that's friendly to schema
@ -76,7 +71,7 @@ type LokiDataQuery struct {
EditorMode *QueryEditorMode `json:"editorMode,omitempty"` EditorMode *QueryEditorMode `json:"editorMode,omitempty"`
// The LogQL query. // The LogQL query.
Expr string `json:"expr"` Expr *string `json:"expr,omitempty"`
// Hide true if query is disabled (ie should not be returned to the dashboard) // Hide true if query is disabled (ie should not be returned to the dashboard)
// Note this does not always imply that the query should not be executed since // Note this does not always imply that the query should not be executed since
@ -102,7 +97,7 @@ type LokiDataQuery struct {
// A unique identifier for the query within the list of targets. // A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results. // In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful. // By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId string `json:"refId"` RefId *string `json:"refId,omitempty"`
// @deprecated, now use step. // @deprecated, now use step.
Resolution *int64 `json:"resolution,omitempty"` Resolution *int64 `json:"resolution,omitempty"`

@ -149,7 +149,7 @@ func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) {
return nil, err return nil, err
} }
expr := interpolateVariables(model.Expr, interval, timeRange, queryType, step) expr := interpolateVariables(depointerizer(model.Expr), interval, timeRange, queryType, step)
direction, err := parseDirection(model.Direction) direction, err := parseDirection(model.Direction)
if err != nil { if err != nil {
@ -187,3 +187,12 @@ func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) {
return qs, nil return qs, nil
} }
func depointerizer[T any](v *T) T {
var emptyValue T
if v != nil {
emptyValue = *v
}
return emptyValue
}

@ -34,7 +34,7 @@ func (s *Service) SubscribeStream(ctx context.Context, req *backend.SubscribeStr
if err != nil { if err != nil {
return nil, err return nil, err
} }
if query.Expr == "" { if query.Expr != nil {
return &backend.SubscribeStreamResponse{ return &backend.SubscribeStreamResponse{
Status: backend.SubscribeStreamStatusNotFound, Status: backend.SubscribeStreamStatusNotFound,
}, fmt.Errorf("missing expr in channel (subscribe)") }, fmt.Errorf("missing expr in channel (subscribe)")
@ -69,7 +69,7 @@ func (s *Service) RunStream(ctx context.Context, req *backend.RunStreamRequest,
if err != nil { if err != nil {
return err return err
} }
if query.Expr == "" { if query.Expr != nil {
return fmt.Errorf("missing expr in cuannel") return fmt.Errorf("missing expr in cuannel")
} }
@ -80,7 +80,7 @@ func (s *Service) RunStream(ctx context.Context, req *backend.RunStreamRequest,
signal.Notify(interrupt, os.Interrupt) signal.Notify(interrupt, os.Interrupt)
params := url.Values{} params := url.Values{}
params.Add("query", query.Expr) params.Add("query", *query.Expr)
wsurl, _ := url.Parse(dsInfo.URL) wsurl, _ := url.Parse(dsInfo.URL)
@ -149,7 +149,7 @@ func (s *Service) RunStream(ctx context.Context, req *backend.RunStreamRequest,
} }
}() }()
ticker := time.NewTicker(time.Second * 60) //.Step) ticker := time.NewTicker(time.Second * 60) // .Step)
defer ticker.Stop() defer ticker.Stop()
for { for {

@ -43,11 +43,6 @@ type DataQuery struct {
// ParcaDataQuery defines model for ParcaDataQuery. // ParcaDataQuery defines model for ParcaDataQuery.
type ParcaDataQuery struct { type ParcaDataQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
// For mixed data sources the selected datasource is on the query level. // For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined. // For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema // TODO find a better way to do this ^ that's friendly to schema
@ -60,10 +55,10 @@ type ParcaDataQuery struct {
Hide *bool `json:"hide,omitempty"` Hide *bool `json:"hide,omitempty"`
// Specifies the query label selectors. // Specifies the query label selectors.
LabelSelector string `json:"labelSelector"` LabelSelector *string `json:"labelSelector,omitempty"`
// Specifies the type of profile to query. // Specifies the type of profile to query.
ProfileTypeId string `json:"profileTypeId"` ProfileTypeId *string `json:"profileTypeId,omitempty"`
// Specify the query flavor // Specify the query flavor
// TODO make this required and give it a default // TODO make this required and give it a default
@ -72,7 +67,7 @@ type ParcaDataQuery struct {
// A unique identifier for the query within the list of targets. // A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results. // In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful. // By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId string `json:"refId"` RefId *string `json:"refId,omitempty"`
} }
// ParcaQueryType defines model for ParcaQueryType. // ParcaQueryType defines model for ParcaQueryType.

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
"github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils"
"github.com/grafana/grafana/pkg/tsdb/parca/kinds/dataquery" "github.com/grafana/grafana/pkg/tsdb/parca/kinds/dataquery"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
@ -56,7 +57,8 @@ func (d *ParcaDatasource) query(ctx context.Context, pCtx backend.PluginContext,
span.SetStatus(codes.Error, response.Error.Error()) span.SetStatus(codes.Error, response.Error.Error())
return response return response
} }
response.Frames = append(response.Frames, seriesToDataFrame(seriesResp, qm.ProfileTypeId)...)
response.Frames = append(response.Frames, seriesToDataFrame(seriesResp, utils.Depointerizer(qm.ProfileTypeId))...)
} }
if query.QueryType == queryTypeProfile || query.QueryType == queryTypeBoth { if query.QueryType == queryTypeProfile || query.QueryType == queryTypeBoth {
@ -82,7 +84,7 @@ func makeProfileRequest(qm queryModel, query backend.DataQuery) *connect.Request
Mode: v1alpha1.QueryRequest_MODE_MERGE, Mode: v1alpha1.QueryRequest_MODE_MERGE,
Options: &v1alpha1.QueryRequest_Merge{ Options: &v1alpha1.QueryRequest_Merge{
Merge: &v1alpha1.MergeProfile{ Merge: &v1alpha1.MergeProfile{
Query: fmt.Sprintf("%s%s", qm.ProfileTypeId, qm.LabelSelector), Query: fmt.Sprintf("%s%s", utils.Depointerizer(qm.ProfileTypeId), utils.Depointerizer(qm.LabelSelector)),
Start: &timestamppb.Timestamp{ Start: &timestamppb.Timestamp{
Seconds: query.TimeRange.From.Unix(), Seconds: query.TimeRange.From.Unix(),
}, },
@ -101,7 +103,7 @@ func makeProfileRequest(qm queryModel, query backend.DataQuery) *connect.Request
func makeMetricRequest(qm queryModel, query backend.DataQuery) *connect.Request[v1alpha1.QueryRangeRequest] { func makeMetricRequest(qm queryModel, query backend.DataQuery) *connect.Request[v1alpha1.QueryRangeRequest] {
return &connect.Request[v1alpha1.QueryRangeRequest]{ return &connect.Request[v1alpha1.QueryRangeRequest]{
Msg: &v1alpha1.QueryRangeRequest{ Msg: &v1alpha1.QueryRangeRequest{
Query: fmt.Sprintf("%s%s", qm.ProfileTypeId, qm.LabelSelector), Query: fmt.Sprintf("%s%s", utils.Depointerizer(qm.ProfileTypeId), utils.Depointerizer(qm.LabelSelector)),
Start: &timestamppb.Timestamp{ Start: &timestamppb.Timestamp{
Seconds: query.TimeRange.From.Unix(), Seconds: query.TimeRange.From.Unix(),
}, },

@ -78,17 +78,12 @@ type TempoDataQuery = map[string]any
// TempoQuery defines model for TempoQuery. // TempoQuery defines model for TempoQuery.
type TempoQuery struct { type TempoQuery struct {
// DataQuery These are the common properties available to all queries in all datasources.
// Specific implementations will *extend* this interface, adding the required
// properties for the given context.
DataQuery
// For mixed data sources the selected datasource is on the query level. // For mixed data sources the selected datasource is on the query level.
// For non mixed scenarios this is undefined. // For non mixed scenarios this is undefined.
// TODO find a better way to do this ^ that's friendly to schema // TODO find a better way to do this ^ that's friendly to schema
// TODO this shouldn't be unknown but DataSourceRef | null // TODO this shouldn't be unknown but DataSourceRef | null
Datasource *any `json:"datasource,omitempty"` Datasource *any `json:"datasource,omitempty"`
Filters []TraceqlFilter `json:"filters"` Filters []TraceqlFilter `json:"filters,omitempty"`
// Filters that are used to query the metrics summary // Filters that are used to query the metrics summary
GroupBy []TraceqlFilter `json:"groupBy,omitempty"` GroupBy []TraceqlFilter `json:"groupBy,omitempty"`
@ -117,7 +112,7 @@ type TempoQuery struct {
// A unique identifier for the query within the list of targets. // A unique identifier for the query within the list of targets.
// In server side expressions, the refId is used as a variable name to identify results. // In server side expressions, the refId is used as a variable name to identify results.
// By default, the UI will assign A->Z; however setting meaningful names may be useful. // By default, the UI will assign A->Z; however setting meaningful names may be useful.
RefId string `json:"refId"` RefId *string `json:"refId,omitempty"`
// @deprecated Logfmt query to filter traces by their tags. Example: http.status_code=200 error=true // @deprecated Logfmt query to filter traces by their tags. Example: http.status_code=200 error=true
Search *string `json:"search,omitempty"` Search *string `json:"search,omitempty"`

@ -8,18 +8,15 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/grafana/codejen"
corecodegen "github.com/grafana/grafana/pkg/codegen"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/grafana/grafana/pkg/plugins/codegen"
"github.com/grafana/grafana/pkg/plugins/pfs"
"github.com/grafana/kindsys"
"github.com/grafana/thema"
"io/fs"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/grafana/codejen"
corecodegen "github.com/grafana/grafana/pkg/codegen"
"github.com/grafana/grafana/pkg/plugins/codegen"
"github.com/grafana/grafana/pkg/plugins/pfs"
) )
var skipPlugins = map[string]bool{ var skipPlugins = map[string]bool{
@ -40,25 +37,20 @@ func main() {
log.Fatal(fmt.Errorf("could not get working directory: %s", err)) log.Fatal(fmt.Errorf("could not get working directory: %s", err))
} }
groot := filepath.Clean(filepath.Join(cwd, "../../..")) groot := filepath.Clean(filepath.Join(cwd, "../../.."))
rt := cuectx.GrafanaThemaRuntime()
pluginKindGen := codejen.JennyListWithNamer(func(d *pfs.PluginDecl) string { pluginKindGen := codejen.JennyListWithNamer(func(d *pfs.PluginDecl) string {
return d.PluginMeta.Id return d.PluginMeta.Id
}) })
pluginKindGen.Append( pluginKindGen.Append(
&codegen.PluginRegistryJenny{},
codegen.PluginGoTypesJenny("pkg/tsdb"), codegen.PluginGoTypesJenny("pkg/tsdb"),
codegen.PluginTSTypesJenny("public/app/plugins"), codegen.PluginTSTypesJenny("public/app/plugins"),
) )
schifs := kindsys.SchemaInterfaces(rt.Context()) pluginKindGen.AddPostprocessors(corecodegen.SlashHeaderMapper("public/app/plugins/gen.go"), splitSchiffer())
schifnames := make([]string, 0, len(schifs))
for _, schif := range schifs {
schifnames = append(schifnames, strings.ToLower(schif.Name()))
}
pluginKindGen.AddPostprocessors(corecodegen.SlashHeaderMapper("public/app/plugins/gen.go"), splitSchiffer(schifnames))
declParser := pfs.NewDeclParser(rt, skipPlugins) declParser := pfs.NewDeclParser(skipPlugins)
decls, err := declParser.Parse(os.DirFS(cwd)) decls, err := declParser.Parse(os.DirFS(cwd))
if err != nil { if err != nil {
log.Fatalln(fmt.Errorf("parsing plugins in dir failed %s: %s", cwd, err)) log.Fatalln(fmt.Errorf("parsing plugins in dir failed %s: %s", cwd, err))
@ -69,15 +61,6 @@ func main() {
log.Fatalln(fmt.Errorf("error writing files to disk: %s", err)) log.Fatalln(fmt.Errorf("error writing files to disk: %s", err))
} }
rawResources, err := genRawResources()
if err != nil {
log.Fatalln(fmt.Errorf("error generating raw plugin resources: %s", err))
}
if err := jfs.Merge(rawResources); err != nil {
log.Fatalln(fmt.Errorf("Unable to merge raw resources: %s", err))
}
if _, set := os.LookupEnv("CODEGEN_VERIFY"); set { if _, set := os.LookupEnv("CODEGEN_VERIFY"); set {
if err = jfs.Verify(context.Background(), groot); err != nil { if err = jfs.Verify(context.Background(), groot); err != nil {
log.Fatal(fmt.Errorf("generated code is out of sync with inputs:\n%s\nrun `make gen-cue` to regenerate", err)) log.Fatal(fmt.Errorf("generated code is out of sync with inputs:\n%s\nrun `make gen-cue` to regenerate", err))
@ -87,20 +70,8 @@ func main() {
} }
} }
func kind2pd(rt *thema.Runtime, j codejen.OneToOne[kindsys.Kind]) codejen.OneToOne[*pfs.PluginDecl] { func splitSchiffer() codejen.FileMapper {
return codejen.AdaptOneToOne(j, func(pd *pfs.PluginDecl) kindsys.Kind { names := []string{"panelcfg", "dataquery"}
kd, err := kindsys.BindComposable(rt, pd.KindDecl)
if err != nil {
return nil
}
return kd
})
}
func splitSchiffer(names []string) codejen.FileMapper {
for i := range names {
names[i] = names[i] + "/"
}
return func(f codejen.File) (codejen.File, error) { return func(f codejen.File) (codejen.File, error) {
// TODO it's terrible that this has to exist, CODEJEN NEEDS TO BE BETTER // TODO it's terrible that this has to exist, CODEJEN NEEDS TO BE BETTER
path := filepath.ToSlash(f.RelativePath) path := filepath.ToSlash(f.RelativePath)
@ -113,28 +84,3 @@ func splitSchiffer(names []string) codejen.FileMapper {
return f, nil return f, nil
} }
} }
func genRawResources() (*codejen.FS, error) {
jennies := codejen.JennyListWithNamer(func(d []string) string {
return "PluginsRawResources"
})
jennies.Append(&codegen.PluginRegistryJenny{})
schemas := make([]string, 0)
filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error {
if d.IsDir() {
return nil
}
if !strings.HasSuffix(d.Name(), ".cue") {
return nil
}
schemas = append(schemas, "./"+filepath.Join("public", "app", "plugins", path))
return nil
})
jennies.AddPostprocessors(corecodegen.SlashHeaderMapper("public/app/plugins/gen.go"))
return jennies.GenerateFS(schemas)
}

Loading…
Cancel
Save