mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
merge main
This commit is contained in:
commit
d5f3038421
@ -5537,7 +5537,8 @@ exports[`better eslint`] = {
|
||||
"public/app/features/trails/MetricSelect/MetricSelectScene.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"]
|
||||
],
|
||||
"public/app/features/trails/MetricsHeader.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
|
||||
|
@ -129,14 +129,20 @@ max-func-lines = 60
|
||||
|
||||
[linters]
|
||||
disable-all = true
|
||||
# try to keep this list sorted, please
|
||||
enable = [
|
||||
"asciicheck",
|
||||
"bodyclose",
|
||||
"depguard",
|
||||
"dogsled",
|
||||
"errcheck",
|
||||
"errorlint",
|
||||
"exhaustive",
|
||||
"exportloopref",
|
||||
# "gochecknoinits",
|
||||
# "goconst",
|
||||
# "gocritic", # Temporarily disabled on 2022-09-09, running into weird bug "ruleguard: execution error: used Run() with an empty rule set; forgot to call Load() first?"
|
||||
"gocyclo",
|
||||
"goimports",
|
||||
"goprintffuncname",
|
||||
"gosec",
|
||||
@ -145,19 +151,14 @@ enable = [
|
||||
"ineffassign",
|
||||
"misspell",
|
||||
"nakedret",
|
||||
"exportloopref",
|
||||
"prealloc",
|
||||
"revive",
|
||||
"staticcheck",
|
||||
"stylecheck",
|
||||
"typecheck",
|
||||
"unconvert",
|
||||
"unused",
|
||||
"whitespace",
|
||||
"gocyclo",
|
||||
"exhaustive",
|
||||
"typecheck",
|
||||
"asciicheck",
|
||||
"errorlint",
|
||||
"revive",
|
||||
]
|
||||
|
||||
# Disabled linters (might want them later)
|
||||
|
@ -341,7 +341,7 @@
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"align": "auto",
|
||||
@ -436,7 +436,7 @@
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"align": "auto",
|
||||
@ -523,7 +523,7 @@
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"fillOpacity": 20,
|
||||
@ -608,7 +608,7 @@
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"fillOpacity": 20,
|
||||
@ -693,7 +693,7 @@
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"fillOpacity": 20,
|
||||
@ -778,7 +778,7 @@
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"fillOpacity": 80,
|
||||
@ -845,7 +845,7 @@
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"fillOpacity": 80,
|
||||
|
@ -46,17 +46,12 @@ refs:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/table/#sparkline
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/table/#sparkline
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/table/#sparkline
|
||||
calculation-types:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/query-transform-data/calculation-types/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types/
|
||||
heatmap-panel:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/heatmap/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/heatmap/
|
||||
configuration-file:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#configuration-file-location
|
||||
@ -64,9 +59,9 @@ refs:
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#configuration-file-location
|
||||
dashboard-variable:
|
||||
- pattern: /docs/grafana/
|
||||
destination: docs/grafana/<GRAFANA_VERSION>/dashboards/variables/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/dashboards/variables/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: docs/grafana/<GRAFANA_VERSION>/dashboards/variables/
|
||||
destination: /docs/grafana-cloud/visualizations/dashboards/variables/
|
||||
feature-toggle:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#feature_toggles
|
||||
@ -76,12 +71,12 @@ refs:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/table/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/table/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/table/
|
||||
time-series-panel:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/time-series/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/time-series/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/time-series/
|
||||
---
|
||||
|
||||
# Transform data
|
||||
@ -119,7 +114,7 @@ The following steps guide you in adding a transformation to data. This documenta
|
||||
1. Click the **Transform** tab.
|
||||
1. Click a transformation.
|
||||
A transformation row appears where you configure the transformation options. For more information about how to configure a transformation, refer to [Transformation functions](#transformation-functions).
|
||||
For information about available calculations, refer to [Calculation types](ref:calculation-types).
|
||||
For information about available calculations, refer to [Calculation types][].
|
||||
1. To apply another transformation, click **Add transformation**.
|
||||
This transformation acts on the result set returned by the previous transformation.
|
||||
{{< figure src="/static/img/docs/transformations/transformations-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="Transform tab in the panel editor" >}}
|
||||
@ -191,7 +186,7 @@ Use this transformation to add a new field calculated from two other fields. Eac
|
||||
- **Variance** - Calculates the moving variance.
|
||||
- **Row index** - Insert a field with the row index.
|
||||
- **Field name** - Select the names of fields you want to use in the calculation for the new field.
|
||||
- **Calculation** - If you select **Reduce row** mode, then the **Calculation** field appears. Click in the field to see a list of calculation choices you can use to create the new field. For information about available calculations, refer to [Calculation types](ref:calculation-types).
|
||||
- **Calculation** - If you select **Reduce row** mode, then the **Calculation** field appears. Click in the field to see a list of calculation choices you can use to create the new field. For information about available calculations, refer to [Calculation types][].
|
||||
- **Operation** - If you select **Binary operation** or **Unary operation** mode, then the **Operation** fields appear. These fields allow you to apply basic math operations on values in a single row from selected fields. You can also use numerical values for binary operations.
|
||||
- **As percentile** - If you select **Row index** mode, then the **As percentile** switch appears. This switch allows you to transform the row index as a percentage of the total number of rows.
|
||||
- **Alias** - (Optional) Enter the name of your new field. If you leave this blank, then the field will be named to match the calculation.
|
||||
@ -355,7 +350,7 @@ Consider the following dataset:
|
||||
| 1636678680000000000 | {"value": 5} |
|
||||
| 1636678620000000000 | {"value": 12} |
|
||||
|
||||
You could prepare the data to be used by a [Time series panel](ref:time-series-panel) with this configuration:
|
||||
You could prepare the data to be used by a [Time series panel][] with this configuration:
|
||||
|
||||
- Source: json_data
|
||||
- Format: JSON
|
||||
@ -536,7 +531,7 @@ Click and uncheck the field names to remove them from the result. Fields that ar
|
||||
|
||||
#### Use a dashboard variable
|
||||
|
||||
Enable 'From variable' to let you select a dashboard variable that's used to include fields. By setting up a [dashboard variable](ref:dashboard-variable) with multiple choices, the same fields can be displayed across multiple visualizations.
|
||||
Enable 'From variable' to let you select a dashboard variable that's used to include fields. By setting up a [dashboard variable][] with multiple choices, the same fields can be displayed across multiple visualizations.
|
||||
|
||||
{{< figure src="/static/img/docs/transformations/filter-name-table-before-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="A table visualization with time, value, Min, and Max columns" >}}
|
||||
|
||||
@ -595,7 +590,7 @@ This transformation lets you tailor the time representation in your visualizatio
|
||||
|
||||
### Group by
|
||||
|
||||
Use this transformation to group the data by a specified field (column) value and process calculations on each group. Click to see a list of calculation choices. For information about available calculations, refer to [Calculation types](ref:calculation-types).
|
||||
Use this transformation to group the data by a specified field (column) value and process calculations on each group. Click to see a list of calculation choices. For information about available calculations, refer to [Calculation types][].
|
||||
|
||||
Here's an example of original data.
|
||||
|
||||
@ -687,7 +682,7 @@ Once **Calculate** has been selected, another selection box will appear next to
|
||||
|
||||
{{< figure src="/static/img/docs/transformations/nested-table-select-stat.png" class="docs-image--no-shadow" max-width= "1100px" alt="A select box showing available statistic calculations once the calculate option for the field has been selected." >}}
|
||||
|
||||
For information about available calculations, refer to [Calculation types](ref:calculation-types).
|
||||
For information about available calculations, refer to [Calculation types][].
|
||||
|
||||
Here's an example of original data:
|
||||
|
||||
@ -1419,7 +1414,7 @@ This transformation allows you to manipulate and analyze geospatial data, enabli
|
||||
|
||||
### Time series to table transform
|
||||
|
||||
Use this transformation to convert time series results into a table, transforming a time series data frame into a **Trend** field which can then be used with the [sparkline cell type](ref:sparkline-cell-type). If there are multiple time series queries, each will result in a separate table data frame. These can be joined using join or merge transforms to produce a single table with multiple sparklines per row.
|
||||
Use this transformation to convert time series results into a table, transforming a time series data frame into a **Trend** field which can then be used with the [sparkline cell type][]. If there are multiple time series queries, each will result in a separate table data frame. These can be joined using join or merge transforms to produce a single table with multiple sparklines per row.
|
||||
|
||||
{{< figure src="/static/img/docs/transformations/table-sparklines.png" class="docs-image--no-shadow" max-width= "1100px" alt="A table panel showing multiple values and their corresponding sparklines." >}}
|
||||
|
||||
@ -1427,7 +1422,7 @@ For each generated **Trend** field value, a calculation function can be selected
|
||||
|
||||
{{< figure src="/static/img/docs/transformations/timeseries-table-select-stat.png" class="docs-image--no-shadow" max-width= "1100px" alt="A select box showing available statistics that can be calculated." >}}
|
||||
|
||||
> **Note:** This transformation is available in Grafana 9.5+ as an opt-in beta feature. Modify the Grafana [configuration file](ref:configuration-file) to use it.
|
||||
> **Note:** This transformation is available in Grafana 9.5+ as an opt-in beta feature. Modify the Grafana [configuration file][] to use it.
|
||||
|
||||
### Regression analysis
|
||||
|
||||
@ -1442,4 +1437,10 @@ There are two different models:
|
||||
|
||||
> **Note:** This transformation is currently in public preview. Grafana Labs offers limited support, and breaking changes might occur prior to the feature being made generally available. Enable the `regressionTransformation` feature toggle in Grafana to use this feature. Contact Grafana Support to enable this feature in Grafana Cloud.
|
||||
|
||||
[Data frames]: https://grafana.com/developers/plugin-tools/introduction/data-frames/
|
||||
[Table panel]: ref:table-panel
|
||||
[Calculation types]: ref:calculation-types
|
||||
[sparkline cell type]: ref:sparkline-cell-type
|
||||
[configuration file]: ref:configuration-file
|
||||
[Time series panel]: ref:time-series-panel
|
||||
[feature toggle]: ref:feature-toggle
|
||||
[dashboard variable]: ref:dashboard-variable
|
||||
|
23
go.mod
23
go.mod
@ -44,7 +44,7 @@ require (
|
||||
github.com/aws/aws-sdk-go v1.51.31 // @grafana/aws-datasources
|
||||
github.com/beevik/etree v1.2.0 // @grafana/grafana-backend-group
|
||||
github.com/benbjohnson/clock v1.3.5 // @grafana/alerting-backend
|
||||
github.com/blang/semver/v4 v4.0.0 // @grafana/grafana-release-guild
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect; @grafana/grafana-release-guild
|
||||
github.com/blugelabs/bluge v0.1.9 // @grafana/grafana-backend-group
|
||||
github.com/blugelabs/bluge_segment_api v0.2.0 // @grafana/grafana-backend-group
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // @grafana/grafana-backend-group
|
||||
@ -55,8 +55,6 @@ require (
|
||||
github.com/dave/dst v0.27.2 // @grafana/grafana-as-code
|
||||
github.com/deepmap/oapi-codegen/v2 v2.1.0 // @grafana/grafana-as-code
|
||||
github.com/dlmiddlecote/sqlstats v1.0.2 // @grafana/grafana-backend-group
|
||||
github.com/docker/docker v26.0.1+incompatible // @grafana/grafana-release-guild
|
||||
github.com/drone/drone-cli v1.6.1 // @grafana/grafana-release-guild
|
||||
github.com/fatih/color v1.16.0 // @grafana/grafana-backend-group
|
||||
github.com/fullstorydev/grpchan v1.1.1 // @grafana/grafana-backend-group
|
||||
github.com/gchaincl/sqlhooks v1.3.0 // @grafana/grafana-search-and-storage
|
||||
@ -79,8 +77,6 @@ require (
|
||||
github.com/golang/protobuf v1.5.4 // @grafana/grafana-backend-group
|
||||
github.com/golang/snappy v0.0.4 // @grafana/alerting-backend
|
||||
github.com/google/go-cmp v0.6.0 // @grafana/grafana-backend-group
|
||||
github.com/google/go-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/uuid v1.6.0 // @grafana/grafana-backend-group
|
||||
github.com/google/wire v0.5.0 // @grafana/grafana-backend-group
|
||||
github.com/googleapis/gax-go/v2 v2.12.3 // @grafana/grafana-backend-group
|
||||
@ -155,7 +151,7 @@ require (
|
||||
github.com/stretchr/testify v1.9.0 // @grafana/grafana-backend-group
|
||||
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf // @grafana/grafana-backend-group
|
||||
github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f // @grafana/grafana-backend-group
|
||||
github.com/urfave/cli v1.22.15 // @grafana/grafana-backend-group
|
||||
github.com/urfave/cli v1.22.15 // indirect; @grafana/grafana-backend-group
|
||||
github.com/urfave/cli/v2 v2.25.1 // @grafana/grafana-backend-group
|
||||
github.com/wk8/go-ordered-map v1.0.0 // @grafana/grafana-backend-group
|
||||
github.com/xlab/treeprint v1.2.0 // @grafana/observability-traces-and-profiling
|
||||
@ -176,7 +172,7 @@ require (
|
||||
gocloud.dev v0.25.0 // @grafana/grafana-app-platform-squad
|
||||
golang.org/x/crypto v0.24.0 // @grafana/grafana-backend-group
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // @grafana/alerting-backend
|
||||
golang.org/x/mod v0.18.0 // @grafana/grafana-backend-group
|
||||
golang.org/x/mod v0.18.0 // indirect; @grafana/grafana-backend-group
|
||||
golang.org/x/net v0.26.0 // @grafana/oss-big-tent @grafana/partner-datasources
|
||||
golang.org/x/oauth2 v0.20.0 // @grafana/identity-access-team
|
||||
golang.org/x/sync v0.7.0 // @grafana/alerting-backend
|
||||
@ -228,7 +224,6 @@ require (
|
||||
github.com/FZambia/eagle v0.1.0 // indirect
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/RoaringBitmap/roaring v0.9.4 // indirect
|
||||
github.com/agext/levenshtein v1.2.1 // indirect
|
||||
@ -252,10 +247,8 @@ require (
|
||||
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
||||
github.com/blevesearch/vellum v1.0.7 // indirect
|
||||
github.com/blugelabs/ice v1.0.0 // indirect
|
||||
github.com/bmatcuk/doublestar v1.1.1 // indirect
|
||||
github.com/bufbuild/protocompile v0.4.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/buildkite/yaml v2.1.0+incompatible // indirect
|
||||
github.com/caio/go-tdigest v3.1.0+incompatible // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/centrifugal/protocol v0.10.0 // indirect
|
||||
@ -272,12 +265,7 @@ require (
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/drone-runners/drone-runner-docker v1.8.2 // indirect
|
||||
github.com/drone/drone-go v1.7.1 // indirect
|
||||
github.com/drone/envsubst v1.0.3 // indirect
|
||||
github.com/drone/runner-go v1.12.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/edsrzf/mmap-go v1.1.0 // indirect
|
||||
github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 // indirect
|
||||
@ -287,7 +275,6 @@ require (
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect; @grafana/grafana-app-platform-squad
|
||||
@ -313,7 +300,6 @@ require (
|
||||
github.com/google/cel-go v0.17.7 // indirect
|
||||
github.com/google/flatbuffers v24.3.25+incompatible // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
@ -381,8 +367,6 @@ require (
|
||||
github.com/oapi-codegen/runtime v1.1.1 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20220512140940-7b36cea86235 // indirect
|
||||
github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
@ -430,7 +414,6 @@ require (
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
|
43
go.sum
43
go.sum
@ -1348,8 +1348,6 @@ filippo.io/age v1.1.1 h1:pIpO7l151hCnQ4BdyBujnGP2YlUo0uj6sAVNHGBvXHg=
|
||||
filippo.io/age v1.1.1/go.mod h1:l03SrzDUrBkdBx8+IILdnn2KZysqQdbEBUQ4p3sqEQE=
|
||||
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
|
||||
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/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e/go.mod h1:Xa6lInWHNQnuWoF0YPSsx+INFA9qk7/7pTjwb3PInkY=
|
||||
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-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U=
|
||||
@ -1405,7 +1403,6 @@ github.com/Azure/azure-storage-blob-go v0.15.0/go.mod h1:vbjsVbX0dlxnRc4FFMPsS9B
|
||||
github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg=
|
||||
github.com/Azure/go-amqp v0.16.4/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
@ -1661,7 +1658,6 @@ github.com/blugelabs/bluge_segment_api v0.2.0/go.mod h1:95XA+ZXfRj/IXADm7gZ+iTcW
|
||||
github.com/blugelabs/ice v0.2.0/go.mod h1:7foiDf4V83FIYYnGh2LOoRWsbNoCqAAMNgKn879Iyu0=
|
||||
github.com/blugelabs/ice v1.0.0 h1:um7wf9e6jbkTVCrOyQq3tKK43fBMOvLUYxbj3Qtc4eo=
|
||||
github.com/blugelabs/ice v1.0.0/go.mod h1:gNfFPk5zM+yxJROhthxhVQYjpBO9amuxWXJQ2Lo+IbQ=
|
||||
github.com/bmatcuk/doublestar v1.1.1 h1:YroD6BJCZBYx06yYFEWvUuKVWQn3vLLQAVmDmvTSaiQ=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
@ -1678,8 +1674,6 @@ github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZ
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/buildkite/yaml v2.1.0+incompatible h1:xirI+ql5GzfikVNDmt+yeiXpf/v1Gt03qXTtT5WXdr8=
|
||||
github.com/buildkite/yaml v2.1.0+incompatible/go.mod h1:UoU8vbcwu1+vjZq01+KrpSeLBgQQIjL/H7Y6KwikUrI=
|
||||
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/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
||||
@ -1759,7 +1753,6 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE
|
||||
github.com/containerd/cgroups/v3 v3.0.1/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw=
|
||||
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
|
||||
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/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
@ -1807,7 +1800,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
|
||||
github.com/deepmap/oapi-codegen/v2 v2.1.0 h1:I/NMVhJCtuvL9x+S2QzZKpSjGi33oDZwPRdemvOZWyQ=
|
||||
github.com/deepmap/oapi-codegen/v2 v2.1.0/go.mod h1:R1wL226vc5VmCNJUvMyYr3hJMm5reyv25j952zAVXZ8=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||
@ -1833,10 +1825,8 @@ github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
@ -1844,18 +1834,6 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/drone-runners/drone-runner-docker v1.8.2 h1:F7+39FSyzEUqLXYMvTdTGBhCS79ODDIhw3DQeF5GYT8=
|
||||
github.com/drone-runners/drone-runner-docker v1.8.2/go.mod h1:JR3pZeVZKKpkbTajiq0YtAx9WutkODdVKZGNR83kEwE=
|
||||
github.com/drone/drone-cli v1.6.1 h1:Beh0opEGR5XYezOyOmiqWzTMBGHkGDrh2tIG1cY/5GY=
|
||||
github.com/drone/drone-cli v1.6.1/go.mod h1://HC780Gua3Nhob/I2VPL3nTqmleEE/HIhGhTcJb2ds=
|
||||
github.com/drone/drone-go v1.7.1 h1:ZX+3Rs8YHUSUQ5mkuMLmm1zr1ttiiE2YGNxF3AnyDKw=
|
||||
github.com/drone/drone-go v1.7.1/go.mod h1:fxCf9jAnXDZV1yDr0ckTuWd1intvcQwfJmTRpTZ1mXg=
|
||||
github.com/drone/envsubst v1.0.2/go.mod h1:bkZbnc/2vh1M12Ecn7EYScpI4YGYU0etwLJICOWi8Z0=
|
||||
github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g=
|
||||
github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g=
|
||||
github.com/drone/runner-go v1.12.0 h1:zUjDj9ylsJ4n4Mvy4znddq/Z4EBzcUXzTltpzokKtgs=
|
||||
github.com/drone/runner-go v1.12.0/go.mod h1:vu4pPPYDoeN6vdYQAY01GGGsAIW4aLganJNaa8Fx8zE=
|
||||
github.com/drone/signal v1.0.0/go.mod h1:S8t92eFT0g4WUgEc/LxG+LCuiskpMNsG0ajAMGnyZpc=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
@ -1944,8 +1922,6 @@ github.com/gchaincl/sqlhooks v1.3.0/go.mod h1:9BypXnereMT0+Ys8WGWHqzgkkOfHIhyeUC
|
||||
github.com/getkin/kin-openapi v0.122.0 h1:WB9Jbl0Hp/T79/JF9xlSW5Kl9uYdk/AWD0yAd9HOM10=
|
||||
github.com/getkin/kin-openapi v0.122.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw=
|
||||
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/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
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=
|
||||
@ -2086,7 +2062,6 @@ github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q8
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=
|
||||
github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
|
||||
github.com/gogo/protobuf v0.0.0-20170307180453-100ba4e88506/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
@ -2193,10 +2168,7 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI=
|
||||
github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28=
|
||||
github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=
|
||||
github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
@ -2293,7 +2265,6 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51
|
||||
github.com/gorilla/mux v1.6.2/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.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
@ -2621,7 +2592,6 @@ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
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/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
@ -2804,8 +2774,6 @@ github.com/moby/moby v23.0.4+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHs
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -2820,7 +2788,6 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ
|
||||
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
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/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
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=
|
||||
@ -2835,7 +2802,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
|
||||
github.com/natessilva/dag v0.0.0-20180124060714-7194b8dcc5c4/go.mod h1:cojhOHk1gbMeklOyDP2oKKLftefXoJreOQGOrXk+Z38=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
github.com/nats-io/jwt v1.2.2/go.mod h1:/xX356yQA6LuXI9xWW7mZNpxgF2mBmGecH+Fj34sP5Q=
|
||||
@ -3084,7 +3050,6 @@ github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThC
|
||||
github.com/russellhaering/goxmldsig v1.4.0 h1:8UcDh/xGyQiyrW+Fq5t8f+l2DLB1+zlhYzkPUJ7Qhys=
|
||||
github.com/russellhaering/goxmldsig v1.4.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
@ -3244,9 +3209,6 @@ github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3k
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
@ -3395,8 +3357,6 @@ go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v8
|
||||
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
@ -3439,7 +3399,6 @@ golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaE
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/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=
|
||||
@ -3892,7 +3851,6 @@ golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXct
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
@ -4569,7 +4527,6 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
1
go.work
1
go.work
@ -4,6 +4,7 @@ use (
|
||||
.
|
||||
./pkg/apimachinery
|
||||
./pkg/apiserver
|
||||
./pkg/build
|
||||
./pkg/build/wire
|
||||
./pkg/promlib
|
||||
./pkg/storage/unified/resource
|
||||
|
707
go.work.sum
707
go.work.sum
File diff suppressed because it is too large
Load Diff
@ -28,7 +28,7 @@ export const VizTooltipContent = ({
|
||||
const scrollableStyle: CSSProperties = scrollable
|
||||
? {
|
||||
maxHeight: maxHeight,
|
||||
overflowY: 'scroll',
|
||||
overflowY: 'auto',
|
||||
}
|
||||
: {};
|
||||
|
||||
|
@ -47,7 +47,7 @@ export const VizTooltipRow = ({
|
||||
maxHeight: 55,
|
||||
whiteSpace: 'wrap',
|
||||
wordBreak: 'break-word',
|
||||
overflowY: 'scroll',
|
||||
overflowY: 'auto',
|
||||
}
|
||||
: {
|
||||
whiteSpace: 'wrap',
|
||||
|
@ -156,8 +156,8 @@ func publishPackages(cfg packaging.PublishConfig) error {
|
||||
pth = path.Join(pth, product)
|
||||
baseArchiveURL := fmt.Sprintf("https://dl.grafana.com/%s", pth)
|
||||
|
||||
var builds []buildRepr
|
||||
for _, ba := range packaging.ArtifactConfigs {
|
||||
builds := make([]buildRepr, len(packaging.ArtifactConfigs))
|
||||
for i, ba := range packaging.ArtifactConfigs {
|
||||
u := ba.GetURL(baseArchiveURL, cfg)
|
||||
|
||||
sha256, err := getSHA256(u)
|
||||
@ -165,12 +165,12 @@ func publishPackages(cfg packaging.PublishConfig) error {
|
||||
return err
|
||||
}
|
||||
|
||||
builds = append(builds, buildRepr{
|
||||
builds[i] = buildRepr{
|
||||
OS: ba.Os,
|
||||
URL: u,
|
||||
SHA256: string(sha256),
|
||||
Arch: ba.Arch,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
r := releaseRepr{
|
||||
|
@ -6,9 +6,8 @@ import (
|
||||
"log"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/fsutil"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/fs"
|
||||
)
|
||||
|
||||
// VerifyStorybook Action implements the sub-command "verify-storybook".
|
||||
@ -19,7 +18,7 @@ func VerifyStorybook(c *cli.Context) error {
|
||||
"packages/grafana-ui/dist/storybook/index.html",
|
||||
"packages/grafana-ui/dist/storybook/iframe.html"}
|
||||
for _, p := range paths {
|
||||
exists, err := fs.Exists(filepath.Join(grafanaDir, p))
|
||||
exists, err := fsutil.Exists(filepath.Join(grafanaDir, p))
|
||||
if err != nil {
|
||||
return cli.Exit(fmt.Sprintf("failed to verify Storybook build: %s", err), 1)
|
||||
}
|
||||
|
65
pkg/build/fsutil/copy_recursive.go
Normal file
65
pkg/build/fsutil/copy_recursive.go
Normal file
@ -0,0 +1,65 @@
|
||||
package fsutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// CopyRecursive copies files and directories recursively.
|
||||
func CopyRecursive(src, dst string) error {
|
||||
sfi, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !sfi.IsDir() {
|
||||
return CopyFile(src, dst)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(dst); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(dst, sfi.Mode()); err != nil {
|
||||
return fmt.Errorf("failed to create directory %q: %s", dst, err)
|
||||
}
|
||||
}
|
||||
|
||||
entries, err := os.ReadDir(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
srcPath := filepath.Join(src, entry.Name())
|
||||
dstPath := filepath.Join(dst, entry.Name())
|
||||
|
||||
srcFi, err := os.Stat(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch srcFi.Mode() & os.ModeType {
|
||||
case os.ModeDir:
|
||||
if err := CopyRecursive(srcPath, dstPath); err != nil {
|
||||
return err
|
||||
}
|
||||
case os.ModeSymlink:
|
||||
link, err := os.Readlink(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Symlink(link, dstPath); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
if err := CopyFile(srcPath, dstPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if srcFi.Mode()&os.ModeSymlink != 0 {
|
||||
if err := os.Chmod(dstPath, srcFi.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
120
pkg/build/go.mod
Normal file
120
pkg/build/go.mod
Normal file
@ -0,0 +1,120 @@
|
||||
module github.com/grafana/grafana/pkg/build
|
||||
|
||||
go 1.22.4
|
||||
|
||||
// Override docker/docker to avoid:
|
||||
// go: github.com/drone-runners/drone-runner-docker@v1.8.2 requires
|
||||
// github.com/docker/docker@v0.0.0-00010101000000-000000000000: invalid version: unknown revision 000000000000
|
||||
replace github.com/docker/docker => github.com/moby/moby v23.0.4+incompatible
|
||||
|
||||
// contains openapi encoder fixes. remove ASAP
|
||||
replace cuelang.org/go => github.com/grafana/cue v0.0.0-20230926092038-971951014e3f // @grafana/grafana-as-code
|
||||
|
||||
// Override Prometheus version because Prometheus v2.X is tagged as v0.X for Go modules purposes and Go assumes
|
||||
// that v1.Y is higher than v0.X, so when we resolve dependencies if any dependency imports v1.Y we'd
|
||||
// import that instead of v0.X even though v0.X is newer.
|
||||
replace github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.52.0
|
||||
|
||||
// Update when github.com/deepmap/oapi-codegen/v2 is updated to support later versions.
|
||||
replace github.com/getkin/kin-openapi => github.com/getkin/kin-openapi v0.122.0
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.38.0 // @grafana/grafana-backend-group
|
||||
github.com/Masterminds/semver/v3 v3.2.0 // @grafana/grafana-release-guild
|
||||
github.com/aws/aws-sdk-go v1.51.31 // @grafana/aws-datasources
|
||||
github.com/blang/semver/v4 v4.0.0 // @grafana/grafana-release-guild
|
||||
github.com/docker/docker v26.0.1+incompatible // @grafana/grafana-release-guild
|
||||
github.com/drone/drone-cli v1.6.1 // @grafana/grafana-release-guild
|
||||
github.com/gogo/protobuf v1.3.2 // indirect; @grafana/alerting-backend
|
||||
github.com/golang/protobuf v1.5.4 // indirect; @grafana/grafana-backend-group
|
||||
github.com/google/go-cmp v0.6.0 // @grafana/grafana-backend-group
|
||||
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/uuid v1.6.0 // indirect; @grafana/grafana-backend-group
|
||||
github.com/googleapis/gax-go/v2 v2.12.3 // indirect; @grafana/grafana-backend-group
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect; @grafana/grafana-backend-group
|
||||
github.com/stretchr/testify v1.9.0 // @grafana/grafana-backend-group
|
||||
github.com/urfave/cli v1.22.15 // @grafana/grafana-backend-group
|
||||
github.com/urfave/cli/v2 v2.25.1 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect; @grafana/plugins-platform-backend
|
||||
go.opentelemetry.io/otel v1.26.0 // indirect; @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 // indirect; @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/trace v1.26.0 // indirect; @grafana/grafana-backend-group
|
||||
golang.org/x/crypto v0.24.0 // indirect; @grafana/grafana-backend-group
|
||||
golang.org/x/mod v0.18.0 // @grafana/grafana-backend-group
|
||||
golang.org/x/net v0.26.0 // indirect; @grafana/oss-big-tent @grafana/partner-datasources
|
||||
golang.org/x/oauth2 v0.20.0 // @grafana/identity-access-team
|
||||
golang.org/x/sync v0.7.0 // indirect; @grafana/alerting-backend
|
||||
golang.org/x/text v0.16.0 // indirect; @grafana/grafana-backend-group
|
||||
golang.org/x/time v0.5.0 // indirect; @grafana/grafana-backend-group
|
||||
golang.org/x/tools v0.22.0 // indirect; @grafana/grafana-as-code
|
||||
google.golang.org/api v0.176.0 // @grafana/grafana-backend-group
|
||||
google.golang.org/grpc v1.64.0 // indirect; @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.34.1 // indirect; @grafana/plugins-platform-backend
|
||||
gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-backend
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.112.1 // indirect
|
||||
cloud.google.com/go/auth v0.2.2 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.6 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/bmatcuk/doublestar v1.1.1 // indirect
|
||||
github.com/buildkite/yaml v2.1.0+incompatible // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/drone-runners/drone-runner-docker v1.8.2 // indirect
|
||||
github.com/drone/drone-go v1.7.1 // indirect
|
||||
github.com/drone/envsubst v1.0.3 // indirect
|
||||
github.com/drone/runner-go v1.12.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect; @grafana/grafana-app-platform-squad
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20220512140940-7b36cea86235 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect; @grafana/grafana-backend-group
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gotest.tools/v3 v3.5.1 // indirect
|
||||
)
|
||||
|
||||
// Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream
|
||||
replace github.com/crewjam/saml => github.com/grafana/saml v0.4.15-0.20240523142256-cc370b98af7c
|
||||
|
||||
// replace github.com/google/cel-go => github.com/google/cel-go v0.16.1
|
||||
|
||||
// Use our fork of the upstream alertmanagers.
|
||||
// This is required in order to get notification delivery errors from the receivers API.
|
||||
replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20240422145632-c33c6b5b6e6b
|
||||
|
||||
exclude github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||
|
||||
// Use our fork xorm. go.work currently overrides this and points to the local ./pkg/util/xorm directory.
|
||||
replace xorm.io/xorm => github.com/grafana/grafana/pkg/util/xorm v0.0.1
|
342
pkg/build/go.sum
Normal file
342
pkg/build/go.sum
Normal file
@ -0,0 +1,342 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
|
||||
cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
|
||||
cloud.google.com/go/auth v0.2.2 h1:gmxNJs4YZYcw6YvKRtVBaF2fyUE6UrWPyzU8jHvYfmI=
|
||||
cloud.google.com/go/auth v0.2.2/go.mod h1:2bDNJWtWziDT3Pu1URxHHbkHE/BbOCuyUiKIGcNvafo=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.1 h1:VSPmMmUlT8CkIZ2PzD9AlLN+R3+D1clXMWHHa6vG/Ag=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.1/go.mod h1:tOdK/k+D2e4GEwfBRA48dKNQiDsqIXxLh7VU319eV0g=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
|
||||
cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
|
||||
cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg=
|
||||
cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=
|
||||
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/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/aws/aws-sdk-go v1.51.31 h1:4TM+sNc+Dzs7wY1sJ0+J8i60c6rkgnKP1pvPx8ghsSY=
|
||||
github.com/aws/aws-sdk-go v1.51.31/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/bmatcuk/doublestar v1.1.1 h1:YroD6BJCZBYx06yYFEWvUuKVWQn3vLLQAVmDmvTSaiQ=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/buildkite/yaml v2.1.0+incompatible h1:xirI+ql5GzfikVNDmt+yeiXpf/v1Gt03qXTtT5WXdr8=
|
||||
github.com/buildkite/yaml v2.1.0+incompatible/go.mod h1:UoU8vbcwu1+vjZq01+KrpSeLBgQQIjL/H7Y6KwikUrI=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/drone-runners/drone-runner-docker v1.8.2 h1:F7+39FSyzEUqLXYMvTdTGBhCS79ODDIhw3DQeF5GYT8=
|
||||
github.com/drone-runners/drone-runner-docker v1.8.2/go.mod h1:JR3pZeVZKKpkbTajiq0YtAx9WutkODdVKZGNR83kEwE=
|
||||
github.com/drone/drone-cli v1.6.1 h1:Beh0opEGR5XYezOyOmiqWzTMBGHkGDrh2tIG1cY/5GY=
|
||||
github.com/drone/drone-cli v1.6.1/go.mod h1://HC780Gua3Nhob/I2VPL3nTqmleEE/HIhGhTcJb2ds=
|
||||
github.com/drone/drone-go v1.7.1 h1:ZX+3Rs8YHUSUQ5mkuMLmm1zr1ttiiE2YGNxF3AnyDKw=
|
||||
github.com/drone/drone-go v1.7.1/go.mod h1:fxCf9jAnXDZV1yDr0ckTuWd1intvcQwfJmTRpTZ1mXg=
|
||||
github.com/drone/envsubst v1.0.2/go.mod h1:bkZbnc/2vh1M12Ecn7EYScpI4YGYU0etwLJICOWi8Z0=
|
||||
github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g=
|
||||
github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g=
|
||||
github.com/drone/runner-go v1.12.0 h1:zUjDj9ylsJ4n4Mvy4znddq/Z4EBzcUXzTltpzokKtgs=
|
||||
github.com/drone/runner-go v1.12.0/go.mod h1:vu4pPPYDoeN6vdYQAY01GGGsAIW4aLganJNaa8Fx8zE=
|
||||
github.com/drone/signal v1.0.0/go.mod h1:S8t92eFT0g4WUgEc/LxG+LCuiskpMNsG0ajAMGnyZpc=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
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/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/gogo/protobuf v0.0.0-20170307180453-100ba4e88506/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI=
|
||||
github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA=
|
||||
github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/moby/moby v23.0.4+incompatible h1:A/pe8vi9KIKhNbzR0G3wW4ACKDsMgXILBveMqiJNa8M=
|
||||
github.com/moby/moby v23.0.4+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/natessilva/dag v0.0.0-20180124060714-7194b8dcc5c4/go.mod h1:cojhOHk1gbMeklOyDP2oKKLftefXoJreOQGOrXk+Z38=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20220512140940-7b36cea86235 h1:DxS3bbeUSCpMQr3mTez5PIDrS+yBeBsoDsftOhqB1Fg=
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20220512140940-7b36cea86235/go.mod h1:K/JAU0m27RFhDRX4PcFdIKntROP6y5Ed6O91aZYDQfs=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM=
|
||||
github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0=
|
||||
github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw=
|
||||
github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
|
||||
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
|
||||
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
|
||||
go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
|
||||
go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs=
|
||||
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
|
||||
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-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-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
google.golang.org/api v0.176.0 h1:dHj1/yv5Dm/eQTXiP9hNCRT3xzJHWXeNdRq29XbMxoE=
|
||||
google.golang.org/api v0.176.0/go.mod h1:Rra+ltKu14pps/4xTycZfobMgLpbosoaaL7c+SEMrO8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
@ -8,7 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/config"
|
||||
"github.com/grafana/grafana/pkg/infra/fs"
|
||||
"github.com/grafana/grafana/pkg/build/fsutil"
|
||||
)
|
||||
|
||||
// writeRpmMacros writes ~/.rpmmacros.
|
||||
@ -31,7 +31,7 @@ func writeRpmMacros(homeDir, gpgPassPath string) error {
|
||||
// Import imports the GPG package signing key.
|
||||
// ~/.rpmmacros also gets written.
|
||||
func Import(cfg config.Config) error {
|
||||
exists, err := fs.Exists(cfg.GPGPrivateKey)
|
||||
exists, err := fsutil.Exists(cfg.GPGPrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -19,10 +19,10 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/config"
|
||||
"github.com/grafana/grafana/pkg/build/errutil"
|
||||
"github.com/grafana/grafana/pkg/build/fsutil"
|
||||
"github.com/grafana/grafana/pkg/build/grafana"
|
||||
"github.com/grafana/grafana/pkg/build/plugins"
|
||||
"github.com/grafana/grafana/pkg/build/syncutil"
|
||||
"github.com/grafana/grafana/pkg/infra/fs"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -99,7 +99,7 @@ func packageGrafana(
|
||||
p syncutil.WorkerPool,
|
||||
) error {
|
||||
distDir := filepath.Join(grafanaDir, "dist")
|
||||
exists, err := fs.Exists(distDir)
|
||||
exists, err := fsutil.Exists(distDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -317,28 +317,28 @@ func createPackage(srcDir string, options linuxPackageOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := fs.CopyFile(filepath.Join(options.wrapperFilePath, binary),
|
||||
if err := fsutil.CopyFile(filepath.Join(options.wrapperFilePath, binary),
|
||||
filepath.Join(packageRoot, "usr", "sbin", binary)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fs.CopyFile(filepath.Join(options.wrapperFilePath, cliBinary),
|
||||
if err := fsutil.CopyFile(filepath.Join(options.wrapperFilePath, cliBinary),
|
||||
filepath.Join(packageRoot, "usr", "sbin", cliBinary)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fs.CopyFile(filepath.Join(options.wrapperFilePath, serverBinary),
|
||||
if err := fsutil.CopyFile(filepath.Join(options.wrapperFilePath, serverBinary),
|
||||
filepath.Join(packageRoot, "usr", "sbin", serverBinary)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fs.CopyFile(options.initdScriptSrc, filepath.Join(packageRoot, options.initdScriptFilePath)); err != nil {
|
||||
if err := fsutil.CopyFile(options.initdScriptSrc, filepath.Join(packageRoot, options.initdScriptFilePath)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fs.CopyFile(options.defaultFileSrc, filepath.Join(packageRoot, options.etcDefaultFilePath)); err != nil {
|
||||
if err := fsutil.CopyFile(options.defaultFileSrc, filepath.Join(packageRoot, options.etcDefaultFilePath)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fs.CopyFile(options.systemdFileSrc, filepath.Join(packageRoot, options.systemdServiceFilePath)); err != nil {
|
||||
if err := fsutil.CopyFile(options.systemdFileSrc, filepath.Join(packageRoot, options.systemdServiceFilePath)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fs.CopyRecursive(srcDir, filepath.Join(packageRoot, options.homeDir)); err != nil {
|
||||
if err := fsutil.CopyRecursive(srcDir, filepath.Join(packageRoot, options.homeDir)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -416,7 +416,7 @@ func executeFPM(options linuxPackageOptions, packageRoot, srcDir string) error {
|
||||
}
|
||||
log.Printf("Creating %s package: %s...", options.packageType, cmdStr)
|
||||
const rvmPath = "/etc/profile.d/rvm.sh"
|
||||
exists, err := fs.Exists(rvmPath)
|
||||
exists, err := fsutil.Exists(rvmPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -439,7 +439,7 @@ func copyPubDir(grafanaDir, tmpDir string) error {
|
||||
srcPubDir := filepath.Join(grafanaDir, "public")
|
||||
tgtPubDir := filepath.Join(tmpDir, "public")
|
||||
log.Printf("Copying %q to %q...", srcPubDir, tgtPubDir)
|
||||
if err := fs.CopyRecursive(srcPubDir, tgtPubDir); err != nil {
|
||||
if err := fsutil.CopyRecursive(srcPubDir, tgtPubDir); err != nil {
|
||||
return fmt.Errorf("failed to copy %q to %q: %w", srcPubDir, tgtPubDir, err)
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ func copyBinaries(grafanaDir, tmpDir string, args grafana.BuildArgs, edition con
|
||||
srcPath := filepath.Join(binDir, file.Name())
|
||||
tgtPath := filepath.Join(tgtDir, file.Name())
|
||||
|
||||
if err := fs.CopyFile(srcPath, tgtPath); err != nil {
|
||||
if err := fsutil.CopyFile(srcPath, tgtPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -491,7 +491,7 @@ func copyConfFiles(grafanaDir, tmpDir string) error {
|
||||
}
|
||||
for _, info := range infos {
|
||||
fpath := filepath.Join(confDir, info.Name())
|
||||
if err := fs.CopyRecursive(fpath, filepath.Join(tmpDir, "conf", info.Name())); err != nil {
|
||||
if err := fsutil.CopyRecursive(fpath, filepath.Join(tmpDir, "conf", info.Name())); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -510,7 +510,7 @@ func copyPlugins(ctx context.Context, v config.Variant, grafanaDir, tmpDir strin
|
||||
}
|
||||
|
||||
tgtDir := filepath.Join(tmpDir, "plugins-bundled")
|
||||
exists, err := fs.Exists(tgtDir)
|
||||
exists, err := fsutil.Exists(tgtDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -550,7 +550,7 @@ func copyPlugins(ctx context.Context, v config.Variant, grafanaDir, tmpDir strin
|
||||
|
||||
wantExe = fmt.Sprintf("%s_%s", plugExe, sfx)
|
||||
log.Printf("The external plugin should contain an executable %q", wantExe)
|
||||
exists, err := fs.Exists(filepath.Join(srcDir, wantExe))
|
||||
exists, err := fsutil.Exists(filepath.Join(srcDir, wantExe))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -591,7 +591,7 @@ func copyPlugins(ctx context.Context, v config.Variant, grafanaDir, tmpDir strin
|
||||
}
|
||||
|
||||
log.Printf("Copying %q to %q", pth, dstPath)
|
||||
return fs.CopyFile(pth, dstPath)
|
||||
return fsutil.CopyFile(pth, dstPath)
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to copy external plugin %q to %q: %w", srcDir, dstDir, err)
|
||||
}
|
||||
@ -610,7 +610,7 @@ func copyInternalPlugins(pluginsDir, tmpDir string) error {
|
||||
tgtDir := filepath.Join(tmpDir, "plugins-bundled", "internal")
|
||||
srcDir := filepath.Join(pluginsDir, "dist")
|
||||
|
||||
exists, err := fs.Exists(tgtDir)
|
||||
exists, err := fsutil.Exists(tgtDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -635,7 +635,7 @@ func copyInternalPlugins(pluginsDir, tmpDir string) error {
|
||||
|
||||
dstPath := filepath.Join(tgtDir, fi.Name())
|
||||
log.Printf("Copying internal plugin %q to %q...", srcPath, dstPath)
|
||||
if err := fs.CopyRecursive(srcPath, dstPath); err != nil {
|
||||
if err := fsutil.CopyRecursive(srcPath, dstPath); err != nil {
|
||||
return fmt.Errorf("failed to copy %q to %q: %w", srcPath, dstPath, err)
|
||||
}
|
||||
}
|
||||
@ -696,7 +696,7 @@ func realPackageVariant(ctx context.Context, v config.Variant, edition config.Ed
|
||||
return fmt.Errorf("failed to create tools dir %q: %w", toolsDir, err)
|
||||
}
|
||||
|
||||
if err := fs.CopyFile("/usr/local/go/lib/time/zoneinfo.zip",
|
||||
if err := fsutil.CopyFile("/usr/local/go/lib/time/zoneinfo.zip",
|
||||
filepath.Join(tmpDir, "tools", "zoneinfo.zip")); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -860,7 +860,7 @@ type linuxPackageOptions struct {
|
||||
// createArchive makes a distribution archive.
|
||||
func createArchive(srcDir string, edition config.Edition, v config.Variant, version, grafanaDir string) error {
|
||||
distDir := filepath.Join(grafanaDir, "dist")
|
||||
exists, err := fs.Exists(distDir)
|
||||
exists, err := fsutil.Exists(distDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/build/config"
|
||||
"github.com/grafana/grafana/pkg/build/errutil"
|
||||
"github.com/grafana/grafana/pkg/build/fsutil"
|
||||
"github.com/grafana/grafana/pkg/build/syncutil"
|
||||
"github.com/grafana/grafana/pkg/infra/fs"
|
||||
)
|
||||
|
||||
type PluginSigningMode = int
|
||||
@ -45,7 +45,7 @@ func Build(ctx context.Context, grafanaDir string, p syncutil.WorkerPool, g *err
|
||||
}
|
||||
|
||||
dstPath := filepath.Join("plugins-bundled", "dist", fi.Name())
|
||||
if err := fs.CopyRecursive(filepath.Join(dpath, "dist"), dstPath); err != nil {
|
||||
if err := fsutil.CopyRecursive(filepath.Join(dpath, "dist"), dstPath); err != nil {
|
||||
return err
|
||||
}
|
||||
if !verMode.PluginSignature.Sign {
|
||||
|
@ -558,8 +558,9 @@ func (e *State) biSeriesSeries(labels data.Labels, op string, aSeries, bSeries S
|
||||
func (e *State) walkFunc(node *parse.FuncNode) (Results, error) {
|
||||
var res Results
|
||||
var err error
|
||||
var in []reflect.Value
|
||||
for _, a := range node.Args {
|
||||
|
||||
in := make([]reflect.Value, len(node.Args))
|
||||
for i, a := range node.Args {
|
||||
var v any
|
||||
switch t := a.(type) {
|
||||
case *parse.StringNode:
|
||||
@ -580,7 +581,8 @@ func (e *State) walkFunc(node *parse.FuncNode) (Results, error) {
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
in = append(in, reflect.ValueOf(v))
|
||||
|
||||
in[i] = reflect.ValueOf(v)
|
||||
}
|
||||
|
||||
f := reflect.ValueOf(node.F.F)
|
||||
|
@ -444,7 +444,7 @@ func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) error {
|
||||
defaultLevelName, _ := getLogLevelFromConfig("log", "info", cfg)
|
||||
defaultFilters := getFilters(util.SplitString(cfg.Section("log").Key("filters").String()))
|
||||
|
||||
var configLoggers []logWithFilters
|
||||
configLoggers := make([]logWithFilters, 0, len(modes))
|
||||
for _, mode := range modes {
|
||||
mode = strings.TrimSpace(mode)
|
||||
sec, err := cfg.GetSection("log." + mode)
|
||||
@ -505,6 +505,7 @@ func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) error {
|
||||
|
||||
handler.filters = modeFilters
|
||||
handler.maxLevel = leveloption
|
||||
|
||||
configLoggers = append(configLoggers, handler)
|
||||
}
|
||||
if len(configLoggers) > 0 {
|
||||
|
@ -71,7 +71,7 @@ func (m *service) Run(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var svcs []services.Service
|
||||
svcs := make([]services.Service, 0, len(m.serviceMap))
|
||||
for _, s := range m.serviceMap {
|
||||
svcs = append(svcs, s)
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/grafana/codejen"
|
||||
tsast "github.com/grafana/cuetsy/ts/ast"
|
||||
"github.com/grafana/grafana/pkg/build"
|
||||
"github.com/grafana/grafana/pkg/codegen"
|
||||
"github.com/grafana/grafana/pkg/plugins/pfs"
|
||||
)
|
||||
@ -135,7 +134,7 @@ func getGrafanaVersion() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
pkg, err := build.OpenPackageJSON(path.Join(dir, "../../../"))
|
||||
pkg, err := OpenPackageJSON(path.Join(dir, "../../../"))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
33
pkg/plugins/codegen/package_json.go
Normal file
33
pkg/plugins/codegen/package_json.go
Normal file
@ -0,0 +1,33 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type PackageJSON struct {
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
// Opens the package.json file in the provided directory and returns a struct that represents its contents
|
||||
func OpenPackageJSON(dir string) (PackageJSON, error) {
|
||||
f, err := os.Open(filepath.Clean(dir + "/package.json"))
|
||||
if err != nil {
|
||||
return PackageJSON{}, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
log.Println("error closing package.json", err)
|
||||
}
|
||||
}()
|
||||
|
||||
jsonObj := PackageJSON{}
|
||||
if err := json.NewDecoder(f).Decode(&jsonObj); err != nil {
|
||||
return PackageJSON{}, err
|
||||
}
|
||||
|
||||
return jsonObj, nil
|
||||
}
|
@ -93,6 +93,8 @@ func TestDefaultStaticDetectorsInspector(t *testing.T) {
|
||||
plugin *plugins.Plugin
|
||||
exp bool
|
||||
}
|
||||
|
||||
//nolint:prealloc // just a test, and it'd require too much refactoring to preallocate
|
||||
var tcs []tc
|
||||
|
||||
// Angular imports
|
||||
|
@ -381,11 +381,13 @@ func TestFSPathSeparatorFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
func fileList(manifest *PluginManifest) []string {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(manifest.Files))
|
||||
for k := range manifest.Files {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
|
@ -62,9 +62,10 @@ func DirAsLocalSources(pluginsPath string, class plugins.Class) ([]*LocalSource,
|
||||
}
|
||||
slices.Sort(pluginDirs)
|
||||
|
||||
var sources []*LocalSource
|
||||
for _, dir := range pluginDirs {
|
||||
sources = append(sources, NewLocalSource(class, []string{dir}))
|
||||
sources := make([]*LocalSource, len(pluginDirs))
|
||||
for i, dir := range pluginDirs {
|
||||
sources[i] = NewLocalSource(class, []string{dir})
|
||||
}
|
||||
|
||||
return sources, nil
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ func TestDirAsLocalSources(t *testing.T) {
|
||||
{
|
||||
name: "Directory with no subdirectories",
|
||||
pluginsPath: filepath.Join(testdataDir, "pluginRootWithDist", "datasource"),
|
||||
expected: nil,
|
||||
expected: []*LocalSource{},
|
||||
},
|
||||
{
|
||||
name: "Directory with a symlink to a directory",
|
||||
|
@ -38,22 +38,25 @@ func (s *Service) externalPluginSources() []plugins.PluginSource {
|
||||
return []plugins.PluginSource{}
|
||||
}
|
||||
|
||||
var srcs []plugins.PluginSource
|
||||
for _, src := range localSrcs {
|
||||
srcs = append(srcs, src)
|
||||
srcs := make([]plugins.PluginSource, len(localSrcs))
|
||||
for i, src := range localSrcs {
|
||||
srcs[i] = src
|
||||
}
|
||||
|
||||
return srcs
|
||||
}
|
||||
|
||||
func (s *Service) pluginSettingSources() []plugins.PluginSource {
|
||||
var sources []plugins.PluginSource
|
||||
sources := make([]plugins.PluginSource, 0, len(s.cfg.PluginSettings))
|
||||
for _, ps := range s.cfg.PluginSettings {
|
||||
path, exists := ps["path"]
|
||||
if !exists || path == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
sources = append(sources, NewLocalSource(plugins.ClassExternal, []string{path}))
|
||||
}
|
||||
|
||||
return sources
|
||||
}
|
||||
|
||||
|
@ -197,9 +197,8 @@ type versionArg struct {
|
||||
}
|
||||
|
||||
func createPluginVersions(versions ...versionArg) []Version {
|
||||
var vs []Version
|
||||
|
||||
for _, version := range versions {
|
||||
vs := make([]Version, len(versions))
|
||||
for i, version := range versions {
|
||||
ver := Version{
|
||||
Version: version.version,
|
||||
}
|
||||
@ -211,7 +210,8 @@ func createPluginVersions(versions ...versionArg) []Version {
|
||||
}
|
||||
}
|
||||
}
|
||||
vs = append(vs, ver)
|
||||
|
||||
vs[i] = ver
|
||||
}
|
||||
|
||||
return vs
|
||||
|
@ -326,7 +326,7 @@ func (e DatasourcePermissionsService) SetBuiltInRolePermission(ctx context.Conte
|
||||
// if an OSS/unlicensed instance is upgraded to Enterprise/licensed.
|
||||
// https://github.com/grafana/identity-access-team/issues/672
|
||||
func (e DatasourcePermissionsService) SetPermissions(ctx context.Context, orgID int64, resourceID string, commands ...accesscontrol.SetResourcePermissionCommand) ([]accesscontrol.ResourcePermission, error) {
|
||||
var dbCommands []resourcepermissions.SetResourcePermissionsCommand
|
||||
dbCommands := make([]resourcepermissions.SetResourcePermissionsCommand, 0, len(commands))
|
||||
for _, cmd := range commands {
|
||||
// Only set query permissions for built-in roles; do not set permissions for data sources with * as UID, as this would grant wildcard permissions
|
||||
if cmd.Permission != "Query" || cmd.BuiltinRole == "" || resourceID == "*" {
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/annotations"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/tag"
|
||||
@ -27,6 +28,7 @@ func ProvideService(
|
||||
cfg *setting.Cfg,
|
||||
features featuremgmt.FeatureToggles,
|
||||
tagService tag.Service,
|
||||
tracer tracing.Tracer,
|
||||
) *RepositoryImpl {
|
||||
l := log.New("annotations")
|
||||
l.Debug("Initializing annotations service")
|
||||
@ -35,7 +37,7 @@ func ProvideService(
|
||||
write := xormStore
|
||||
|
||||
var read readStore
|
||||
historianStore := loki.NewLokiHistorianStore(cfg.UnifiedAlerting.StateHistory, features, db, log.New("annotations.loki"))
|
||||
historianStore := loki.NewLokiHistorianStore(cfg.UnifiedAlerting.StateHistory, features, db, log.New("annotations.loki"), tracer)
|
||||
if historianStore != nil {
|
||||
l.Debug("Using composite read store")
|
||||
read = NewCompositeStore(log.New("annotations.composite"), xormStore, historianStore)
|
||||
|
@ -48,7 +48,7 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
|
||||
features := featuremgmt.WithFeatures()
|
||||
tagService := tagimpl.ProvideService(sql)
|
||||
|
||||
repo := ProvideService(sql, cfg, features, tagService)
|
||||
repo := ProvideService(sql, cfg, features, tagService, tracing.InitializeTracerForTest())
|
||||
|
||||
dashboard1 := testutil.CreateDashboard(t, sql, cfg, features, dashboards.SaveDashboardCommand{
|
||||
UserID: 1,
|
||||
@ -317,7 +317,7 @@ func TestIntegrationAnnotationListingWithInheritedRBAC(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
cfg.AnnotationMaximumTagsLength = 60
|
||||
|
||||
repo := ProvideService(sql, cfg, tc.features, tagimpl.ProvideService(sql))
|
||||
repo := ProvideService(sql, cfg, tc.features, tagimpl.ProvideService(sql), tracing.InitializeTracerForTest())
|
||||
|
||||
usr.Permissions = map[int64]map[string][]string{1: tc.permissions}
|
||||
testutil.SetupRBACPermission(t, sql, role, usr)
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
ngmetrics "github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
||||
@ -53,7 +54,7 @@ type LokiHistorianStore struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func NewLokiHistorianStore(cfg setting.UnifiedAlertingStateHistorySettings, ft featuremgmt.FeatureToggles, db db.DB, log log.Logger) *LokiHistorianStore {
|
||||
func NewLokiHistorianStore(cfg setting.UnifiedAlertingStateHistorySettings, ft featuremgmt.FeatureToggles, db db.DB, log log.Logger, tracer tracing.Tracer) *LokiHistorianStore {
|
||||
if !useStore(cfg, ft) {
|
||||
return nil
|
||||
}
|
||||
@ -64,7 +65,7 @@ func NewLokiHistorianStore(cfg setting.UnifiedAlertingStateHistorySettings, ft f
|
||||
}
|
||||
|
||||
return &LokiHistorianStore{
|
||||
client: historian.NewLokiClient(lokiCfg, historian.NewRequester(), ngmetrics.NewHistorianMetrics(prometheus.DefaultRegisterer, subsystem), log),
|
||||
client: historian.NewLokiClient(lokiCfg, historian.NewRequester(), ngmetrics.NewHistorianMetrics(prometheus.DefaultRegisterer, subsystem), log, tracer),
|
||||
db: db,
|
||||
log: log,
|
||||
}
|
||||
|
@ -420,21 +420,12 @@ func (s *Service) RunMigration(ctx context.Context, uid string) (*cloudmigration
|
||||
}
|
||||
|
||||
func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.MigrateDataRequest, error) {
|
||||
var migrationDataSlice []cloudmigration.MigrateDataRequestItem
|
||||
// Data sources
|
||||
dataSources, err := s.getDataSources(ctx)
|
||||
if err != nil {
|
||||
s.log.Error("Failed to get datasources", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
for _, ds := range dataSources {
|
||||
migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{
|
||||
Type: cloudmigration.DatasourceDataType,
|
||||
RefID: ds.UID,
|
||||
Name: ds.Name,
|
||||
Data: ds,
|
||||
})
|
||||
}
|
||||
|
||||
// Dashboards
|
||||
dashboards, err := s.getDashboards(ctx)
|
||||
@ -443,6 +434,26 @@ func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.Mig
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Folders
|
||||
folders, err := s.getFolders(ctx)
|
||||
if err != nil {
|
||||
s.log.Error("Failed to get folders", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
migrationDataSlice := make(
|
||||
[]cloudmigration.MigrateDataRequestItem, 0,
|
||||
len(dataSources)+len(dashboards)+len(folders),
|
||||
)
|
||||
for _, ds := range dataSources {
|
||||
migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{
|
||||
Type: cloudmigration.DatasourceDataType,
|
||||
RefID: ds.UID,
|
||||
Name: ds.Name,
|
||||
Data: ds,
|
||||
})
|
||||
}
|
||||
|
||||
for _, dashboard := range dashboards {
|
||||
dashboard.Data.Del("id")
|
||||
migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{
|
||||
@ -453,13 +464,6 @@ func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.Mig
|
||||
})
|
||||
}
|
||||
|
||||
// Folders
|
||||
folders, err := s.getFolders(ctx)
|
||||
if err != nil {
|
||||
s.log.Error("Failed to get folders", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, f := range folders {
|
||||
migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{
|
||||
Type: cloudmigration.FolderDataType,
|
||||
@ -468,6 +472,7 @@ func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.Mig
|
||||
Data: f,
|
||||
})
|
||||
}
|
||||
|
||||
migrationData := &cloudmigration.MigrateDataRequest{
|
||||
Items: migrationDataSlice,
|
||||
}
|
||||
@ -521,9 +526,9 @@ func (s *Service) getFolders(ctx context.Context) ([]folder.Folder, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []folder.Folder
|
||||
for _, folder := range folders {
|
||||
result = append(result, *folder)
|
||||
result := make([]folder.Folder, len(folders))
|
||||
for i, folder := range folders {
|
||||
result[i] = *folder
|
||||
}
|
||||
|
||||
return result, nil
|
||||
@ -535,10 +540,11 @@ func (s *Service) getDashboards(ctx context.Context) ([]dashboards.Dashboard, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []dashboards.Dashboard
|
||||
for _, dashboard := range dashs {
|
||||
result = append(result, *dashboard)
|
||||
result := make([]dashboards.Dashboard, len(dashs))
|
||||
for i, dashboard := range dashs {
|
||||
result[i] = *dashboard
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
@ -332,12 +332,14 @@ func setupRedisLiveEngine(g *GrafanaLive, node *centrifuge.Node) error {
|
||||
redisShardConfigs := []centrifuge.RedisShardConfig{
|
||||
{Address: redisAddress, Password: redisPassword},
|
||||
}
|
||||
var redisShards []*centrifuge.RedisShard
|
||||
|
||||
redisShards := make([]*centrifuge.RedisShard, 0, len(redisShardConfigs))
|
||||
for _, redisConf := range redisShardConfigs {
|
||||
redisShard, err := centrifuge.NewRedisShard(node, redisConf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error connecting to Live Redis: %v", err)
|
||||
}
|
||||
|
||||
redisShards = append(redisShards, redisShard)
|
||||
}
|
||||
|
||||
@ -348,6 +350,7 @@ func setupRedisLiveEngine(g *GrafanaLive, node *centrifuge.Node) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating Live Redis broker: %v", err)
|
||||
}
|
||||
|
||||
node.SetBroker(broker)
|
||||
|
||||
presenceManager, err := centrifuge.NewRedisPresenceManager(node, centrifuge.RedisPresenceManagerConfig{
|
||||
@ -357,7 +360,9 @@ func setupRedisLiveEngine(g *GrafanaLive, node *centrifuge.Node) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating Live Redis presence manager: %v", err)
|
||||
}
|
||||
|
||||
node.SetPresenceManager(presenceManager)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -116,17 +116,21 @@ func (s *Manager) handleDatasourceEvent(orgID int64, dsUID string, resubmit bool
|
||||
s.mu.RUnlock()
|
||||
return nil
|
||||
}
|
||||
var resubmitRequests []streamRequest
|
||||
var waitChannels []chan struct{}
|
||||
|
||||
resubmitRequests := make([]streamRequest, 0, len(dsStreams))
|
||||
waitChannels := make([]chan struct{}, 0, len(dsStreams))
|
||||
for channel := range dsStreams {
|
||||
streamCtx, ok := s.streams[channel]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
streamCtx.cancelFn()
|
||||
|
||||
waitChannels = append(waitChannels, streamCtx.CloseCh)
|
||||
resubmitRequests = append(resubmitRequests, streamCtx.streamRequest)
|
||||
}
|
||||
|
||||
s.mu.RUnlock()
|
||||
|
||||
// Wait for all streams to stop.
|
||||
|
@ -563,8 +563,8 @@ func toRuleGroup(log log.Logger, manager state.AlertInstanceManager, groupKey ng
|
||||
// Returns the whole JSON model as a string if it fails to extract a minimum of 1 query.
|
||||
func ruleToQuery(logger log.Logger, rule *ngmodels.AlertRule) string {
|
||||
var queryErr error
|
||||
var queries []string
|
||||
|
||||
queries := make([]string, 0, len(rule.Data))
|
||||
for _, q := range rule.Data {
|
||||
q, err := q.GetQuery()
|
||||
if err != nil {
|
||||
|
@ -46,156 +46,164 @@ func ContactPointToContactPointExport(cp definitions.ContactPoint) (notify.APIRe
|
||||
// This is needed to keep the API models clean and convert from database model
|
||||
j.RegisterExtension(&contactPointsExtension{})
|
||||
|
||||
var integration []*notify.GrafanaIntegrationConfig
|
||||
contactPointsLength := len(cp.Alertmanager) + len(cp.Dingding) + len(cp.Discord) + len(cp.Email) +
|
||||
len(cp.Googlechat) + len(cp.Kafka) + len(cp.Line) + len(cp.Opsgenie) +
|
||||
len(cp.Pagerduty) + len(cp.OnCall) + len(cp.Pushover) + len(cp.Sensugo) +
|
||||
len(cp.Sns) + len(cp.Slack) + len(cp.Teams) + len(cp.Telegram) +
|
||||
len(cp.Threema) + len(cp.Victorops) + len(cp.Webhook) + len(cp.Wecom) +
|
||||
len(cp.Webex)
|
||||
|
||||
integration := make([]*notify.GrafanaIntegrationConfig, 0, contactPointsLength)
|
||||
|
||||
var errs []error
|
||||
for _, i := range cp.Alertmanager {
|
||||
el, err := marshallIntegration(j, "prometheus-alertmanager", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Dingding {
|
||||
el, err := marshallIntegration(j, "dingding", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Discord {
|
||||
el, err := marshallIntegration(j, "discord", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Email {
|
||||
el, err := marshallIntegration(j, "email", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Googlechat {
|
||||
el, err := marshallIntegration(j, "googlechat", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Kafka {
|
||||
el, err := marshallIntegration(j, "kafka", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Line {
|
||||
el, err := marshallIntegration(j, "line", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Opsgenie {
|
||||
el, err := marshallIntegration(j, "opsgenie", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Pagerduty {
|
||||
el, err := marshallIntegration(j, "pagerduty", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.OnCall {
|
||||
el, err := marshallIntegration(j, "oncall", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Pushover {
|
||||
el, err := marshallIntegration(j, "pushover", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Sensugo {
|
||||
el, err := marshallIntegration(j, "sensugo", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Sns {
|
||||
el, err := marshallIntegration(j, "sns", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Slack {
|
||||
el, err := marshallIntegration(j, "slack", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Teams {
|
||||
el, err := marshallIntegration(j, "teams", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Telegram {
|
||||
el, err := marshallIntegration(j, "telegram", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Threema {
|
||||
el, err := marshallIntegration(j, "threema", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Victorops {
|
||||
el, err := marshallIntegration(j, "victorops", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Webhook {
|
||||
el, err := marshallIntegration(j, "webhook", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Wecom {
|
||||
el, err := marshallIntegration(j, "wecom", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
for _, i := range cp.Webex {
|
||||
el, err := marshallIntegration(j, "webex", i, i.DisableResolveMessage)
|
||||
integration = append(integration, el)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
integration = append(integration, el)
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return notify.APIReceiver{}, errors.Join(errs...)
|
||||
}
|
||||
|
@ -7,6 +7,11 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/dskit/instrument"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Requester executes an HTTP request.
|
||||
@ -14,7 +19,7 @@ type Requester interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// TimedClient instruments a request. It implements Requester.
|
||||
// TimedClient instruments a request with metrics. It implements Requester.
|
||||
type TimedClient struct {
|
||||
client Requester
|
||||
collector instrument.Collector
|
||||
@ -70,3 +75,51 @@ func TimeRequest(ctx context.Context, operation string, coll instrument.Collecto
|
||||
coll, toStatusCode, doRequest)
|
||||
return response, err
|
||||
}
|
||||
|
||||
// TracedClient instruments a request with tracing. It implements Requester.
|
||||
type TracedClient struct {
|
||||
client Requester
|
||||
tracer tracing.Tracer
|
||||
name string
|
||||
}
|
||||
|
||||
func NewTracedClient(client Requester, tracer tracing.Tracer, name string) *TracedClient {
|
||||
return &TracedClient{
|
||||
client: client,
|
||||
tracer: tracer,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// Do executes the request.
|
||||
func (c TracedClient) Do(r *http.Request) (*http.Response, error) {
|
||||
ctx, span := c.tracer.Start(r.Context(), c.name, trace.WithSpanKind(trace.SpanKindClient))
|
||||
defer span.End()
|
||||
|
||||
span.SetAttributes(semconv.HTTPURL(r.URL.String()))
|
||||
span.SetAttributes(semconv.HTTPMethod(r.Method))
|
||||
|
||||
c.tracer.Inject(ctx, r.Header, span)
|
||||
|
||||
r = r.WithContext(ctx)
|
||||
resp, err := c.client.Do(r)
|
||||
if err != nil {
|
||||
span.SetStatus(codes.Error, "request failed")
|
||||
span.RecordError(err)
|
||||
} else {
|
||||
if resp.ContentLength > 0 {
|
||||
span.SetAttributes(attribute.Int64("http.content_length", resp.ContentLength))
|
||||
}
|
||||
span.SetAttributes(semconv.HTTPStatusCode(resp.StatusCode))
|
||||
if resp.StatusCode >= 400 && resp.StatusCode < 600 {
|
||||
span.RecordError(fmt.Errorf("error with HTTP status code %d", resp.StatusCode))
|
||||
}
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// RoundTrip implements the RoundTripper interface.
|
||||
func (c TracedClient) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
return c.Do(r)
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ func (ng *AlertNG) init() error {
|
||||
PromoteConfig: true,
|
||||
SyncInterval: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.SyncInterval,
|
||||
}
|
||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m)
|
||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer)
|
||||
if err != nil {
|
||||
moaLogger.Error("Failed to create remote Alertmanager", "err", err)
|
||||
return nil, err
|
||||
@ -234,7 +234,7 @@ func (ng *AlertNG) init() error {
|
||||
TenantID: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.TenantID,
|
||||
URL: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.URL,
|
||||
}
|
||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m)
|
||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer)
|
||||
if err != nil {
|
||||
moaLogger.Error("Failed to create remote Alertmanager, falling back to using only the internal one", "err", err)
|
||||
return internalAM, nil
|
||||
@ -270,7 +270,7 @@ func (ng *AlertNG) init() error {
|
||||
URL: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.URL,
|
||||
SyncInterval: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.SyncInterval,
|
||||
}
|
||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m)
|
||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer)
|
||||
if err != nil {
|
||||
moaLogger.Error("Failed to create remote Alertmanager, falling back to using only the internal one", "err", err)
|
||||
return internalAM, nil
|
||||
@ -359,7 +359,7 @@ func (ng *AlertNG) init() error {
|
||||
// There are a set of feature toggles available that act as short-circuits for common configurations.
|
||||
// If any are set, override the config accordingly.
|
||||
ApplyStateHistoryFeatureToggles(&ng.Cfg.UnifiedAlerting.StateHistory, ng.FeatureToggles, ng.Log)
|
||||
history, err := configureHistorianBackend(initCtx, ng.Cfg.UnifiedAlerting.StateHistory, ng.annotationsRepo, ng.dashboardService, ng.store, ng.Metrics.GetHistorianMetrics(), ng.Log)
|
||||
history, err := configureHistorianBackend(initCtx, ng.Cfg.UnifiedAlerting.StateHistory, ng.annotationsRepo, ng.dashboardService, ng.store, ng.Metrics.GetHistorianMetrics(), ng.Log, ng.tracer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -523,7 +523,7 @@ type Historian interface {
|
||||
state.Historian
|
||||
}
|
||||
|
||||
func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingStateHistorySettings, ar annotations.Repository, ds dashboards.DashboardService, rs historian.RuleStore, met *metrics.Historian, l log.Logger) (Historian, error) {
|
||||
func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingStateHistorySettings, ar annotations.Repository, ds dashboards.DashboardService, rs historian.RuleStore, met *metrics.Historian, l log.Logger, tracer tracing.Tracer) (Historian, error) {
|
||||
if !cfg.Enabled {
|
||||
met.Info.WithLabelValues("noop").Set(0)
|
||||
return historian.NewNopHistorian(), nil
|
||||
@ -538,7 +538,7 @@ func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingS
|
||||
if backend == historian.BackendTypeMultiple {
|
||||
primaryCfg := cfg
|
||||
primaryCfg.Backend = cfg.MultiPrimary
|
||||
primary, err := configureHistorianBackend(ctx, primaryCfg, ar, ds, rs, met, l)
|
||||
primary, err := configureHistorianBackend(ctx, primaryCfg, ar, ds, rs, met, l, tracer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("multi-backend target \"%s\" was misconfigured: %w", cfg.MultiPrimary, err)
|
||||
}
|
||||
@ -547,7 +547,7 @@ func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingS
|
||||
for _, b := range cfg.MultiSecondaries {
|
||||
secCfg := cfg
|
||||
secCfg.Backend = b
|
||||
sec, err := configureHistorianBackend(ctx, secCfg, ar, ds, rs, met, l)
|
||||
sec, err := configureHistorianBackend(ctx, secCfg, ar, ds, rs, met, l, tracer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("multi-backend target \"%s\" was miconfigured: %w", b, err)
|
||||
}
|
||||
@ -569,7 +569,7 @@ func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingS
|
||||
}
|
||||
req := historian.NewRequester()
|
||||
lokiBackendLogger := log.New("ngalert.state.historian", "backend", "loki")
|
||||
backend := historian.NewRemoteLokiBackend(lokiBackendLogger, lcfg, req, met)
|
||||
backend := historian.NewRemoteLokiBackend(lokiBackendLogger, lcfg, req, met, tracer)
|
||||
|
||||
testConnCtx, cancelFunc := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancelFunc()
|
||||
@ -627,8 +627,8 @@ func ApplyStateHistoryFeatureToggles(cfg *setting.UnifiedAlertingStateHistorySet
|
||||
}
|
||||
}
|
||||
|
||||
func createRemoteAlertmanager(cfg remote.AlertmanagerConfig, kvstore kvstore.KVStore, decryptFn remote.DecryptFn, autogenFn remote.AutogenFn, m *metrics.RemoteAlertmanager) (*remote.Alertmanager, error) {
|
||||
return remote.NewAlertmanager(cfg, notifier.NewFileStore(cfg.OrgID, kvstore), decryptFn, autogenFn, m)
|
||||
func createRemoteAlertmanager(cfg remote.AlertmanagerConfig, kvstore kvstore.KVStore, decryptFn remote.DecryptFn, autogenFn remote.AutogenFn, m *metrics.RemoteAlertmanager, tracer tracing.Tracer) (*remote.Alertmanager, error) {
|
||||
return remote.NewAlertmanager(cfg, notifier.NewFileStore(cfg.OrgID, kvstore), decryptFn, autogenFn, m, tracer)
|
||||
}
|
||||
|
||||
func createRecordingWriter(featureToggles featuremgmt.FeatureToggles, settings setting.RecordingRuleSettings) (schedule.RecordingWriter, error) {
|
||||
|
@ -62,12 +62,13 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
||||
t.Run("fail initialization if invalid backend", func(t *testing.T) {
|
||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||
logger := log.NewNopLogger()
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||
Enabled: true,
|
||||
Backend: "invalid-backend",
|
||||
}
|
||||
|
||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||
|
||||
require.ErrorContains(t, err, "unrecognized")
|
||||
})
|
||||
@ -75,13 +76,14 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
||||
t.Run("fail initialization if invalid multi-backend primary", func(t *testing.T) {
|
||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||
logger := log.NewNopLogger()
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||
Enabled: true,
|
||||
Backend: "multiple",
|
||||
MultiPrimary: "invalid-backend",
|
||||
}
|
||||
|
||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||
|
||||
require.ErrorContains(t, err, "multi-backend target")
|
||||
require.ErrorContains(t, err, "unrecognized")
|
||||
@ -90,6 +92,7 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
||||
t.Run("fail initialization if invalid multi-backend secondary", func(t *testing.T) {
|
||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||
logger := log.NewNopLogger()
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||
Enabled: true,
|
||||
Backend: "multiple",
|
||||
@ -97,7 +100,7 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
||||
MultiSecondaries: []string{"annotations", "invalid-backend"},
|
||||
}
|
||||
|
||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||
|
||||
require.ErrorContains(t, err, "multi-backend target")
|
||||
require.ErrorContains(t, err, "unrecognized")
|
||||
@ -106,6 +109,7 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
||||
t.Run("do not fail initialization if pinging Loki fails", func(t *testing.T) {
|
||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||
logger := log.NewNopLogger()
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||
Enabled: true,
|
||||
Backend: "loki",
|
||||
@ -114,7 +118,7 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
||||
LokiWriteURL: "http://gone.invalid",
|
||||
}
|
||||
|
||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||
|
||||
require.NotNil(t, h)
|
||||
require.NoError(t, err)
|
||||
@ -124,12 +128,13 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
||||
reg := prometheus.NewRegistry()
|
||||
met := metrics.NewHistorianMetrics(reg, metrics.Subsystem)
|
||||
logger := log.NewNopLogger()
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||
Enabled: true,
|
||||
Backend: "annotations",
|
||||
}
|
||||
|
||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||
|
||||
require.NotNil(t, h)
|
||||
require.NoError(t, err)
|
||||
@ -146,11 +151,12 @@ grafana_alerting_state_history_info{backend="annotations"} 1
|
||||
reg := prometheus.NewRegistry()
|
||||
met := metrics.NewHistorianMetrics(reg, metrics.Subsystem)
|
||||
logger := log.NewNopLogger()
|
||||
tracer := tracing.InitializeTracerForTest()
|
||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||
Enabled: false,
|
||||
}
|
||||
|
||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||
|
||||
require.NotNil(t, h)
|
||||
require.NoError(t, err)
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
@ -66,7 +67,7 @@ func TestMultiorgAlertmanager_RemoteSecondaryMode(t *testing.T) {
|
||||
DefaultConfig: setting.GetAlertmanagerDefaultConfiguration(),
|
||||
}
|
||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||
remoteAM, err := remote.NewAlertmanager(externalAMCfg, notifier.NewFileStore(orgID, kvStore), secretsService.Decrypt, remote.NoopAutogenFn, m)
|
||||
remoteAM, err := remote.NewAlertmanager(externalAMCfg, notifier.NewFileStore(orgID, kvStore), secretsService.Decrypt, remote.NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||
require.NoError(t, err)
|
||||
|
||||
// Use both Alertmanager implementations in the forked Alertmanager.
|
||||
|
@ -88,13 +88,14 @@ func (ecp *ContactPointService) GetContactPoints(ctx context.Context, q ContactP
|
||||
}
|
||||
}
|
||||
|
||||
var contactPoints []apimodels.EmbeddedContactPoint
|
||||
for _, gr := range grafanaReceivers {
|
||||
contactPoints := make([]apimodels.EmbeddedContactPoint, len(grafanaReceivers))
|
||||
for i, gr := range grafanaReceivers {
|
||||
contactPoint, err := GettableGrafanaReceiverToEmbeddedContactPoint(gr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
contactPoints = append(contactPoints, contactPoint)
|
||||
|
||||
contactPoints[i] = contactPoint
|
||||
}
|
||||
|
||||
sort.SliceStable(contactPoints, func(i, j int) bool {
|
||||
|
@ -31,17 +31,19 @@ func (t *TemplateService) GetTemplates(ctx context.Context, orgID int64) ([]defi
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var templates []definitions.NotificationTemplate
|
||||
templates := make([]definitions.NotificationTemplate, 0, len(revision.cfg.TemplateFiles))
|
||||
for name, tmpl := range revision.cfg.TemplateFiles {
|
||||
tmpl := definitions.NotificationTemplate{
|
||||
Name: name,
|
||||
Template: tmpl,
|
||||
}
|
||||
|
||||
provenance, err := t.provenanceStore.GetProvenance(ctx, &tmpl, orgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tmpl.Provenance = definitions.Provenance(provenance)
|
||||
|
||||
templates = append(templates, tmpl)
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
@ -100,7 +101,7 @@ func (cfg *AlertmanagerConfig) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn DecryptFn, autogenFn AutogenFn, metrics *metrics.RemoteAlertmanager) (*Alertmanager, error) {
|
||||
func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn DecryptFn, autogenFn AutogenFn, metrics *metrics.RemoteAlertmanager, tracer tracing.Tracer) (*Alertmanager, error) {
|
||||
if err := cfg.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -118,7 +119,7 @@ func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn Decrypt
|
||||
URL: u,
|
||||
PromoteConfig: cfg.PromoteConfig,
|
||||
}
|
||||
mc, err := remoteClient.New(mcCfg, metrics)
|
||||
mc, err := remoteClient.New(mcCfg, metrics, tracer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -129,7 +130,7 @@ func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn Decrypt
|
||||
Password: cfg.BasicAuthPassword,
|
||||
Logger: logger,
|
||||
}
|
||||
amc, err := remoteClient.NewAlertmanager(amcCfg, metrics)
|
||||
amc, err := remoteClient.NewAlertmanager(amcCfg, metrics, tracer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -492,13 +493,14 @@ func (am *Alertmanager) GetReceivers(ctx context.Context) ([]apimodels.Receiver,
|
||||
return []apimodels.Receiver{}, err
|
||||
}
|
||||
|
||||
var rcvs []apimodels.Receiver
|
||||
for _, rcv := range res.Payload {
|
||||
rcvs = append(rcvs, apimodels.Receiver{
|
||||
rcvs := make([]apimodels.Receiver, len(res.Payload))
|
||||
for i, rcv := range res.Payload {
|
||||
rcvs[i] = apimodels.Receiver{
|
||||
Name: *rcv.Name,
|
||||
Integrations: []apimodels.Integration{},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return rcvs, nil
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"github.com/grafana/alerting/definition"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
@ -105,7 +106,7 @@ func TestNewAlertmanager(t *testing.T) {
|
||||
DefaultConfig: defaultGrafanaConfig,
|
||||
}
|
||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||
if test.expErr != "" {
|
||||
require.EqualError(tt, err, test.expErr)
|
||||
return
|
||||
@ -177,7 +178,7 @@ func TestApplyConfig(t *testing.T) {
|
||||
|
||||
// An error response from the remote Alertmanager should result in the readiness check failing.
|
||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||
am, err := NewAlertmanager(cfg, fstore, secretsService.Decrypt, NoopAutogenFn, m)
|
||||
am, err := NewAlertmanager(cfg, fstore, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||
require.NoError(t, err)
|
||||
|
||||
config := &ngmodels.AlertConfiguration{
|
||||
@ -305,6 +306,7 @@ func TestCompareAndSendConfiguration(t *testing.T) {
|
||||
decryptFn,
|
||||
test.autogenFn,
|
||||
m,
|
||||
tracing.InitializeTracerForTest(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -364,7 +366,7 @@ func TestIntegrationRemoteAlertmanagerConfiguration(t *testing.T) {
|
||||
|
||||
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(db.InitTestDB(t)))
|
||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||
am, err := NewAlertmanager(cfg, fstore, secretsService.Decrypt, NoopAutogenFn, m)
|
||||
am, err := NewAlertmanager(cfg, fstore, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||
require.NoError(t, err)
|
||||
|
||||
encodedFullState, err := am.getFullState(ctx)
|
||||
@ -521,7 +523,7 @@ func TestIntegrationRemoteAlertmanagerGetStatus(t *testing.T) {
|
||||
|
||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||
require.NoError(t, err)
|
||||
|
||||
// We should get the default Cloud Alertmanager configuration.
|
||||
@ -555,7 +557,7 @@ func TestIntegrationRemoteAlertmanagerSilences(t *testing.T) {
|
||||
|
||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||
require.NoError(t, err)
|
||||
|
||||
// We should have no silences at first.
|
||||
@ -640,7 +642,7 @@ func TestIntegrationRemoteAlertmanagerAlerts(t *testing.T) {
|
||||
|
||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||
require.NoError(t, err)
|
||||
|
||||
// Wait until the Alertmanager is ready to send alerts.
|
||||
@ -709,7 +711,7 @@ func TestIntegrationRemoteAlertmanagerReceivers(t *testing.T) {
|
||||
|
||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||
require.NoError(t, err)
|
||||
|
||||
// We should start with the default config.
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/client"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
amclient "github.com/prometheus/alertmanager/api/v2/client"
|
||||
@ -31,7 +32,7 @@ type Alertmanager struct {
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
func NewAlertmanager(cfg *AlertmanagerConfig, metrics *metrics.RemoteAlertmanager) (*Alertmanager, error) {
|
||||
func NewAlertmanager(cfg *AlertmanagerConfig, metrics *metrics.RemoteAlertmanager, tracer tracing.Tracer) (*Alertmanager, error) {
|
||||
// First, add the authentication middleware.
|
||||
c := &http.Client{Transport: &MimirAuthRoundTripper{
|
||||
TenantID: cfg.TenantID,
|
||||
@ -40,14 +41,15 @@ func NewAlertmanager(cfg *AlertmanagerConfig, metrics *metrics.RemoteAlertmanage
|
||||
}}
|
||||
|
||||
tc := client.NewTimedClient(c, metrics.RequestLatency)
|
||||
trc := client.NewTracedClient(tc, tracer, "remote.alertmanager.client")
|
||||
apiEndpoint := *cfg.URL
|
||||
|
||||
// Next, make sure you set the right path.
|
||||
u := apiEndpoint.JoinPath(alertmanagerAPIMountPath, amclient.DefaultBasePath)
|
||||
|
||||
// Create an Alertmanager client using the timed client as the transport.
|
||||
// Create an Alertmanager client using the instrumented client as the transport.
|
||||
r := httptransport.New(u.Host, u.Path, []string{u.Scheme})
|
||||
r.Transport = tc
|
||||
r.Transport = trc
|
||||
|
||||
return &Alertmanager{
|
||||
logger: cfg.Logger,
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/client"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
@ -68,7 +69,7 @@ func (e *errorResponse) Error() string {
|
||||
return e.Error2
|
||||
}
|
||||
|
||||
func New(cfg *Config, metrics *metrics.RemoteAlertmanager) (*Mimir, error) {
|
||||
func New(cfg *Config, metrics *metrics.RemoteAlertmanager, tracer tracing.Tracer) (*Mimir, error) {
|
||||
rt := &MimirAuthRoundTripper{
|
||||
TenantID: cfg.TenantID,
|
||||
Password: cfg.Password,
|
||||
@ -78,10 +79,12 @@ func New(cfg *Config, metrics *metrics.RemoteAlertmanager) (*Mimir, error) {
|
||||
c := &http.Client{
|
||||
Transport: rt,
|
||||
}
|
||||
tc := client.NewTimedClient(c, metrics.RequestLatency)
|
||||
trc := client.NewTracedClient(tc, tracer, "remote.alertmanager.client")
|
||||
|
||||
return &Mimir{
|
||||
endpoint: cfg.URL,
|
||||
client: client.NewTimedClient(c, metrics.RequestLatency),
|
||||
client: trc,
|
||||
logger: cfg.Logger,
|
||||
metrics: metrics,
|
||||
promoteConfig: cfg.PromoteConfig,
|
||||
|
@ -205,15 +205,17 @@ func (d *AlertsRouter) SyncAndApplyConfigFromDatabase(ctx context.Context) error
|
||||
}
|
||||
|
||||
func buildRedactedAMs(l log.Logger, alertmanagers []ExternalAMcfg, ordId int64) []string {
|
||||
var redactedAMs []string
|
||||
redactedAMs := make([]string, 0, len(alertmanagers))
|
||||
for _, am := range alertmanagers {
|
||||
parsedAM, err := url.Parse(am.URL)
|
||||
if err != nil {
|
||||
l.Error("Failed to parse alertmanager string", "org", ordId, "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
redactedAMs = append(redactedAMs, parsedAM.Redacted())
|
||||
}
|
||||
|
||||
return redactedAMs
|
||||
}
|
||||
|
||||
@ -225,9 +227,6 @@ func asSHA256(strings []string) string {
|
||||
}
|
||||
|
||||
func (d *AlertsRouter) alertmanagersFromDatasources(orgID int64) ([]ExternalAMcfg, error) {
|
||||
var (
|
||||
alertmanagers []ExternalAMcfg
|
||||
)
|
||||
// We might have alertmanager datasources that are acting as external
|
||||
// alertmanager, let's fetch them.
|
||||
query := &datasources.GetDataSourcesByTypeQuery{
|
||||
@ -240,6 +239,9 @@ func (d *AlertsRouter) alertmanagersFromDatasources(orgID int64) ([]ExternalAMcf
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch datasources for org: %w", err)
|
||||
}
|
||||
|
||||
alertmanagers := make([]ExternalAMcfg, 0, len(dataSources))
|
||||
|
||||
for _, ds := range dataSources {
|
||||
if !ds.JsonData.Get(definitions.HandleGrafanaManagedAlerts).MustBool(false) {
|
||||
continue
|
||||
@ -262,11 +264,13 @@ func (d *AlertsRouter) alertmanagersFromDatasources(orgID int64) ([]ExternalAMcf
|
||||
"error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
alertmanagers = append(alertmanagers, ExternalAMcfg{
|
||||
URL: amURL,
|
||||
Headers: headers,
|
||||
})
|
||||
}
|
||||
|
||||
return alertmanagers, nil
|
||||
}
|
||||
|
||||
|
@ -712,7 +712,7 @@ func TestAlertManagers_buildRedactedAMs(t *testing.T) {
|
||||
amUrls: []string{"1234://user:password@localhost:9094"},
|
||||
errCalls: 1,
|
||||
errLog: "Failed to parse alertmanager string",
|
||||
expected: nil,
|
||||
expected: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
@ -724,6 +724,7 @@ func TestAlertManagers_buildRedactedAMs(t *testing.T) {
|
||||
URL: url,
|
||||
})
|
||||
}
|
||||
|
||||
require.Equal(t, tt.expected, buildRedactedAMs(&fakeLogger, cfgs, tt.orgId))
|
||||
require.Equal(t, tt.errCalls, fakeLogger.ErrorLogs.Calls)
|
||||
require.Equal(t, tt.errLog, fakeLogger.ErrorLogs.Message)
|
||||
|
@ -141,9 +141,9 @@ func errorAlert(labels, annotations data.Labels, alertState *State, urlStr strin
|
||||
|
||||
func FromStateTransitionToPostableAlerts(firingStates []StateTransition, stateManager *Manager, appURL *url.URL) apimodels.PostableAlerts {
|
||||
alerts := apimodels.PostableAlerts{PostableAlerts: make([]models.PostableAlert, 0, len(firingStates))}
|
||||
var sentAlerts []*State
|
||||
ts := time.Now()
|
||||
|
||||
sentAlerts := make([]*State, 0, len(firingStates))
|
||||
for _, alertState := range firingStates {
|
||||
if !alertState.NeedsSending(stateManager.ResendDelay) {
|
||||
continue
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/client"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
@ -55,9 +56,9 @@ type RemoteLokiBackend struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func NewRemoteLokiBackend(logger log.Logger, cfg LokiConfig, req client.Requester, metrics *metrics.Historian) *RemoteLokiBackend {
|
||||
func NewRemoteLokiBackend(logger log.Logger, cfg LokiConfig, req client.Requester, metrics *metrics.Historian, tracer tracing.Tracer) *RemoteLokiBackend {
|
||||
return &RemoteLokiBackend{
|
||||
client: NewLokiClient(cfg, req, metrics, logger),
|
||||
client: NewLokiClient(cfg, req, metrics, logger, tracer),
|
||||
externalLabels: cfg.ExternalLabels,
|
||||
clock: clock.New(),
|
||||
metrics: metrics,
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/client"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@ -103,10 +104,11 @@ const (
|
||||
NeqRegEx Operator = "!~"
|
||||
)
|
||||
|
||||
func NewLokiClient(cfg LokiConfig, req client.Requester, metrics *metrics.Historian, logger log.Logger) *HttpLokiClient {
|
||||
func NewLokiClient(cfg LokiConfig, req client.Requester, metrics *metrics.Historian, logger log.Logger, tracer tracing.Tracer) *HttpLokiClient {
|
||||
tc := client.NewTimedClient(req, metrics.WriteDuration)
|
||||
trc := client.NewTracedClient(tc, tracer, "ngalert.historian.client")
|
||||
return &HttpLokiClient{
|
||||
client: tc,
|
||||
client: trc,
|
||||
encoder: cfg.Encoder,
|
||||
cfg: cfg,
|
||||
metrics: metrics,
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
)
|
||||
|
||||
func TestLokiConfig(t *testing.T) {
|
||||
@ -227,7 +228,7 @@ func TestLokiHTTPClient_Manual(t *testing.T) {
|
||||
ReadPathURL: url,
|
||||
WritePathURL: url,
|
||||
Encoder: JsonEncoder{},
|
||||
}, NewRequester(), metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem), log.NewNopLogger())
|
||||
}, NewRequester(), metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem), log.NewNopLogger(), tracing.InitializeTracerForTest())
|
||||
|
||||
// Unauthorized request should fail against Grafana Cloud.
|
||||
err = client.Ping(context.Background())
|
||||
@ -255,7 +256,7 @@ func TestLokiHTTPClient_Manual(t *testing.T) {
|
||||
BasicAuthUser: "<your_username>",
|
||||
BasicAuthPassword: "<your_password>",
|
||||
Encoder: JsonEncoder{},
|
||||
}, NewRequester(), metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem), log.NewNopLogger())
|
||||
}, NewRequester(), metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem), log.NewNopLogger(), tracing.InitializeTracerForTest())
|
||||
|
||||
// When running on prem, you might need to set the tenant id,
|
||||
// so the x-scope-orgid header is set.
|
||||
@ -389,7 +390,7 @@ func createTestLokiClient(req client.Requester) *HttpLokiClient {
|
||||
Encoder: JsonEncoder{},
|
||||
}
|
||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||
return NewLokiClient(cfg, req, met, log.NewNopLogger())
|
||||
return NewLokiClient(cfg, req, met, log.NewNopLogger(), tracing.InitializeTracerForTest())
|
||||
}
|
||||
|
||||
func reqBody(t *testing.T, req *http.Request) string {
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/client"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
@ -514,7 +515,7 @@ func createTestLokiBackend(req client.Requester, met *metrics.Historian) *Remote
|
||||
ExternalLabels: map[string]string{"externalLabelKey": "externalLabelValue"},
|
||||
}
|
||||
lokiBackendLogger := log.New("ngalert.state.historian", "backend", "loki")
|
||||
return NewRemoteLokiBackend(lokiBackendLogger, cfg, req, met)
|
||||
return NewRemoteLokiBackend(lokiBackendLogger, cfg, req, met, tracing.InitializeTracerForTest())
|
||||
}
|
||||
|
||||
func singleFromNormal(st *state.State) []state.StateTransition {
|
||||
|
@ -787,7 +787,8 @@ func (st DBstore) RenameReceiverInNotificationSettings(ctx context.Context, orgI
|
||||
if len(rules) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
var updates []ngmodels.UpdateRule
|
||||
|
||||
updates := make([]ngmodels.UpdateRule, 0, len(rules))
|
||||
for _, rule := range rules {
|
||||
r := ngmodels.CopyRule(rule)
|
||||
for idx := range r.NotificationSettings {
|
||||
@ -795,6 +796,7 @@ func (st DBstore) RenameReceiverInNotificationSettings(ctx context.Context, orgI
|
||||
r.NotificationSettings[idx].Receiver = newReceiver
|
||||
}
|
||||
}
|
||||
|
||||
updates = append(updates, ngmodels.UpdateRule{
|
||||
Existing: rule,
|
||||
New: *r,
|
||||
|
@ -401,15 +401,15 @@ type pluginsSettingsServiceMock struct {
|
||||
func (s *pluginsSettingsServiceMock) GetPluginSettings(_ context.Context, args *pluginsettings.GetArgs) ([]*pluginsettings.InfoDTO, error) {
|
||||
s.getPluginSettingsArgs = append(s.getPluginSettingsArgs, args.OrgID)
|
||||
|
||||
var res []*pluginsettings.InfoDTO
|
||||
for _, ps := range s.storedPluginSettings {
|
||||
res = append(res, &pluginsettings.InfoDTO{
|
||||
res := make([]*pluginsettings.InfoDTO, len(s.storedPluginSettings))
|
||||
for i, ps := range s.storedPluginSettings {
|
||||
res[i] = &pluginsettings.InfoDTO{
|
||||
PluginID: ps.PluginID,
|
||||
OrgID: ps.OrgID,
|
||||
Enabled: ps.Enabled,
|
||||
Pinned: ps.Pinned,
|
||||
PluginVersion: ps.PluginVersion,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return res, s.err
|
||||
|
@ -163,17 +163,23 @@ func (p *EnvVarsProvider) tracingEnvVars(plugin *plugins.Plugin) []string {
|
||||
|
||||
func (p *EnvVarsProvider) pluginSettingsEnvVars(pluginID string) []string {
|
||||
const customConfigPrefix = "GF_PLUGIN"
|
||||
var env []string
|
||||
for k, v := range p.cfg.PluginSettings[pluginID] {
|
||||
|
||||
pluginSettings := p.cfg.PluginSettings[pluginID]
|
||||
|
||||
env := make([]string, 0, len(pluginSettings))
|
||||
for k, v := range pluginSettings {
|
||||
if k == "path" || strings.ToLower(k) == "id" {
|
||||
continue
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%s_%s", customConfigPrefix, strings.ToUpper(k))
|
||||
if value := os.Getenv(key); value != "" {
|
||||
v = value
|
||||
}
|
||||
|
||||
env = append(env, fmt.Sprintf("%s=%s", key, v))
|
||||
}
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/annotations"
|
||||
"github.com/grafana/grafana/pkg/services/annotations/annotationsimpl"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
@ -29,7 +30,7 @@ func newPublicDashboardServiceImpl(
|
||||
db, cfg := db.InitTestDBWithCfg(t)
|
||||
tagService := tagimpl.ProvideService(db)
|
||||
if annotationsRepo == nil {
|
||||
annotationsRepo = annotationsimpl.ProvideService(db, cfg, featuremgmt.WithFeatures(), tagService)
|
||||
annotationsRepo = annotationsimpl.ProvideService(db, cfg, featuremgmt.WithFeatures(), tagService, tracing.InitializeTracerForTest())
|
||||
}
|
||||
|
||||
if publicDashboardStore == nil {
|
||||
|
@ -191,7 +191,9 @@ func getNonFolderDashboardDoc(dash dashboard, location string) *bluge.Document {
|
||||
func getDashboardPanelDocs(dash dashboard, location string) []*bluge.Document {
|
||||
dashURL := fmt.Sprintf("/d/%s/%s", dash.uid, slugify.Slugify(dash.summary.Name))
|
||||
|
||||
var docs []*bluge.Document
|
||||
// pre-allocating a little bit more than necessary, possibly
|
||||
docs := make([]*bluge.Document, 0, len(dash.summary.Nested))
|
||||
|
||||
for _, panel := range dash.summary.Nested {
|
||||
if panel.Fields["type"] == "row" {
|
||||
continue // skip rows
|
||||
@ -239,7 +241,7 @@ func getDashboardPanelDocs(dash dashboard, location string) []*bluge.Document {
|
||||
}
|
||||
|
||||
// Names need to be indexed a few ways to support key features
|
||||
func newSearchDocument(uid string, name string, descr string, url string) *bluge.Document {
|
||||
func newSearchDocument(uid, name, descr, url string) *bluge.Document {
|
||||
doc := bluge.NewDocument(uid)
|
||||
|
||||
if name != "" {
|
||||
|
@ -51,9 +51,11 @@ func Test_punctuationCharFilter_Filter(t1 *testing.T) {
|
||||
func TestNgramIndexAnalyzer(t *testing.T) {
|
||||
stream := ngramIndexAnalyzer.Analyze([]byte("x-rays.and.xRays, and НемногоКириллицы"))
|
||||
expectedTerms := []string{"x", "r", "ra", "ray", "rays", "a", "an", "and", "x", "r", "ra", "ray", "rays", "a", "an", "and", "н", "не", "нем", "немн", "немно", "немног", "немного", "к", "ки", "кир", "кири", "кирил", "кирилл", "кирилли"}
|
||||
var actualTerms []string
|
||||
|
||||
actualTerms := make([]string, 0, len(stream))
|
||||
for _, t := range stream {
|
||||
actualTerms = append(actualTerms, string(t.Term))
|
||||
}
|
||||
|
||||
require.Equal(t, expectedTerms, actualTerms)
|
||||
}
|
||||
|
@ -97,9 +97,8 @@ func (e externalAlertmanagerToDatasources) Exec(sess *xorm.Session, mg *migrator
|
||||
}
|
||||
|
||||
func removeDuplicates(strs []string) []string {
|
||||
var res []string
|
||||
found := map[string]bool{}
|
||||
|
||||
found := make(map[string]bool, len(strs))
|
||||
res := make([]string, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
if found[str] {
|
||||
continue
|
||||
|
@ -435,8 +435,10 @@ func (f *accessControlDashboardPermissionFilter) nestedFoldersSelectors(permSele
|
||||
}
|
||||
|
||||
func getAllowedUIDs(action string, user identity.Requester, scopePrefix string) []any {
|
||||
var args []any
|
||||
for _, uidScope := range user.GetPermissions()[action] {
|
||||
uidScopes := user.GetPermissions()[action]
|
||||
|
||||
args := make([]any, 0, len(uidScopes))
|
||||
for _, uidScope := range uidScopes {
|
||||
if !strings.HasPrefix(uidScope, scopePrefix) {
|
||||
continue
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ func (api *Api) getAuthorizedList(ctx context.Context, identity identity.Request
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var authorizedProviders []*models.SSOSettings
|
||||
authorizedProviders := make([]*models.SSOSettings, 0, len(allProviders))
|
||||
for _, provider := range allProviders {
|
||||
ev := ac.EvalPermission(ac.ActionSettingsRead, ac.Scope("settings", "auth."+provider.Provider, "*"))
|
||||
hasAccess, err := api.AccessControl.Evaluate(ctx, identity, ev)
|
||||
|
@ -1986,19 +1986,23 @@ func (cfg *Cfg) readLiveSettings(iniFile *ini.File) error {
|
||||
cfg.LiveHAEngineAddress = section.Key("ha_engine_address").MustString("127.0.0.1:6379")
|
||||
cfg.LiveHAEnginePassword = section.Key("ha_engine_password").MustString("")
|
||||
|
||||
var originPatterns []string
|
||||
allowedOrigins := section.Key("allowed_origins").MustString("")
|
||||
for _, originPattern := range strings.Split(allowedOrigins, ",") {
|
||||
origins := strings.Split(allowedOrigins, ",")
|
||||
|
||||
originPatterns := make([]string, 0, len(origins))
|
||||
for _, originPattern := range origins {
|
||||
originPattern = strings.TrimSpace(originPattern)
|
||||
if originPattern == "" {
|
||||
continue
|
||||
}
|
||||
originPatterns = append(originPatterns, originPattern)
|
||||
}
|
||||
|
||||
_, err := GetAllowedOriginGlobs(originPatterns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.LiveAllowedOrigins = originPatterns
|
||||
return nil
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ func readSecureSocksDSProxySettings(iniFile *ini.File) (SecureSocksDSProxySettin
|
||||
s.ClientKey = string(keyPEMBlock)
|
||||
}
|
||||
|
||||
var rootCAs []string
|
||||
rootCAs := make([]string, 0, len(s.RootCAFilePaths))
|
||||
for _, rootCAFile := range s.RootCAFilePaths {
|
||||
// nolint:gosec
|
||||
// The gosec G304 warning can be ignored because `rootCAFile` comes from config ini, and we check below if
|
||||
|
@ -88,9 +88,8 @@ type argJSONQuery struct {
|
||||
}
|
||||
|
||||
func (e *AzureResourceGraphDatasource) buildQueries(queries []backend.DataQuery, dsInfo types.DatasourceInfo) ([]*AzureResourceGraphQuery, error) {
|
||||
var azureResourceGraphQueries []*AzureResourceGraphQuery
|
||||
|
||||
for _, query := range queries {
|
||||
azureResourceGraphQueries := make([]*AzureResourceGraphQuery, len(queries))
|
||||
for i, query := range queries {
|
||||
queryJSONModel := argJSONQuery{}
|
||||
err := json.Unmarshal(query.JSON, &queryJSONModel)
|
||||
if err != nil {
|
||||
@ -105,19 +104,18 @@ func (e *AzureResourceGraphDatasource) buildQueries(queries []backend.DataQuery,
|
||||
}
|
||||
|
||||
interpolatedQuery, err := macros.KqlInterpolate(query, dsInfo, azureResourceGraphTarget.Query)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
azureResourceGraphQueries = append(azureResourceGraphQueries, &AzureResourceGraphQuery{
|
||||
azureResourceGraphQueries[i] = &AzureResourceGraphQuery{
|
||||
RefID: query.RefID,
|
||||
ResultFormat: resultFormat,
|
||||
JSON: query.JSON,
|
||||
InterpolatedQuery: interpolatedQuery,
|
||||
TimeRange: query.TimeRange,
|
||||
QueryType: query.QueryType,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return azureResourceGraphQueries, nil
|
||||
|
@ -129,8 +129,8 @@ type AzureMonitorDimensionFilterBackend struct {
|
||||
}
|
||||
|
||||
func ConstructFiltersString(a dataquery.AzureMetricDimension) string {
|
||||
var filterStrings []string
|
||||
for _, filter := range a.Filters {
|
||||
filterStrings := make([]string, len(a.Filters))
|
||||
for i, filter := range a.Filters {
|
||||
dimension := ""
|
||||
operator := ""
|
||||
if a.Dimension != nil {
|
||||
@ -139,11 +139,14 @@ func ConstructFiltersString(a dataquery.AzureMetricDimension) string {
|
||||
if a.Operator != nil {
|
||||
operator = *a.Operator
|
||||
}
|
||||
filterStrings = append(filterStrings, fmt.Sprintf("%v %v '%v'", dimension, operator, filter))
|
||||
|
||||
filterStrings[i] = fmt.Sprintf("%v %v '%v'", dimension, operator, filter)
|
||||
}
|
||||
|
||||
if a.Operator != nil && *a.Operator == "eq" {
|
||||
return strings.Join(filterStrings, " or ")
|
||||
}
|
||||
|
||||
return strings.Join(filterStrings, " and ")
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func valuesToListMetricRespone[T any](values []T) []resources.ResourceResponse[T] {
|
||||
var response []resources.ResourceResponse[T]
|
||||
response := make([]resources.ResourceResponse[T], 0, len(values))
|
||||
for _, value := range values {
|
||||
response = append(response, resources.ResourceResponse[T]{Value: value})
|
||||
}
|
||||
|
@ -84,15 +84,16 @@ func newFlowTestQueries(allJsonBytes []byte) ([]backend.DataQuery, error) {
|
||||
return nil, fmt.Errorf("error unmarshaling query-json: %w", err)
|
||||
}
|
||||
|
||||
var queries []backend.DataQuery
|
||||
|
||||
for _, jsonBytes := range jsonBytesArray {
|
||||
queries := make([]backend.DataQuery, len(jsonBytesArray))
|
||||
for i, jsonBytes := range jsonBytesArray {
|
||||
// we need to extract some fields from the json-array
|
||||
var jsonInfo queryDataTestQueryJSON
|
||||
|
||||
err = json.Unmarshal(jsonBytes, &jsonInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// we setup the DataQuery, with values loaded from the json
|
||||
query := backend.DataQuery{
|
||||
RefID: jsonInfo.RefID,
|
||||
@ -101,7 +102,8 @@ func newFlowTestQueries(allJsonBytes []byte) ([]backend.DataQuery, error) {
|
||||
TimeRange: timeRange,
|
||||
JSON: jsonBytes,
|
||||
}
|
||||
queries = append(queries, query)
|
||||
|
||||
queries[i] = query
|
||||
}
|
||||
return queries, nil
|
||||
}
|
||||
|
@ -873,16 +873,16 @@ func trimDatapoints(queryResult backend.DataResponse, target *Query) {
|
||||
// we sort the label's pairs by the label-key,
|
||||
// and return the label-values
|
||||
func getSortedLabelValues(labels data.Labels) []string {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(labels))
|
||||
for key := range labels {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
var values []string
|
||||
for _, key := range keys {
|
||||
values = append(values, labels[key])
|
||||
values := make([]string, len(keys))
|
||||
for i, key := range keys {
|
||||
values[i] = labels[key]
|
||||
}
|
||||
|
||||
return values
|
||||
|
@ -60,7 +60,7 @@ func TestNewQueryDataResponse(t *testing.T) {
|
||||
newJSONArray(`[0, 1, 2]`, &arrow.TimestampType{}),
|
||||
}
|
||||
|
||||
var arr []arrow.Array
|
||||
arr := make([]arrow.Array, 0, len(strValues))
|
||||
for _, v := range strValues {
|
||||
tarr, _, err := array.FromJSON(
|
||||
alloc,
|
||||
|
@ -269,12 +269,12 @@ func transformRowsForTimeSeries(rows []models.Row, query models.Query) data.Fram
|
||||
}
|
||||
|
||||
func newFrameWithTimeField(row models.Row, column string, colIndex int, query models.Query, frameName []byte) *data.Frame {
|
||||
var timeArray []time.Time
|
||||
var floatArray []*float64
|
||||
var stringArray []*string
|
||||
var boolArray []*bool
|
||||
valType := util.Typeof(row.Values, colIndex)
|
||||
|
||||
timeArray := make([]time.Time, 0, len(row.Values))
|
||||
for _, valuePair := range row.Values {
|
||||
timestamp, timestampErr := util.ParseTimestamp(valuePair[0])
|
||||
// we only add this row if the timestamp is valid
|
||||
|
@ -136,10 +136,11 @@ func rootSpan(frame *BetterFrame) Row {
|
||||
}
|
||||
|
||||
func fieldNames(frame *data.Frame) []string {
|
||||
var names []string
|
||||
for _, f := range frame.Fields {
|
||||
names = append(names, f.Name)
|
||||
names := make([]string, len(frame.Fields))
|
||||
for i, f := range frame.Fields {
|
||||
names[i] = f.Name
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,13 @@ func SplitString(str string) []string {
|
||||
return res
|
||||
}
|
||||
|
||||
var result []string
|
||||
matches := stringListItemMatcher.FindAllString(str, -1)
|
||||
for _, match := range matches {
|
||||
result = append(result, strings.Trim(match, "\""))
|
||||
|
||||
result := make([]string, len(matches))
|
||||
for i, match := range matches {
|
||||
result[i] = strings.Trim(match, "\"")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -30,22 +30,26 @@ func TlsCiphersToIDs(names []string) ([]uint16, error) {
|
||||
// no ciphers specified, use defaults
|
||||
return nil, nil
|
||||
}
|
||||
var ids []uint16
|
||||
var missing []string
|
||||
|
||||
ciphers := tls.CipherSuites()
|
||||
var cipherMap = make(map[string]uint16, len(ciphers))
|
||||
|
||||
cipherMap := make(map[string]uint16, len(ciphers))
|
||||
for _, cipher := range ciphers {
|
||||
cipherMap[cipher.Name] = cipher.ID
|
||||
}
|
||||
|
||||
missing := []string{}
|
||||
ids := make([]uint16, 0, len(names))
|
||||
|
||||
for _, name := range names {
|
||||
name = strings.ToUpper(name)
|
||||
|
||||
id, ok := cipherMap[name]
|
||||
if !ok {
|
||||
missing = append(missing, name)
|
||||
continue
|
||||
}
|
||||
|
||||
ids = append(ids, id)
|
||||
}
|
||||
|
||||
|
@ -52,10 +52,11 @@ export interface DataTrailState extends SceneObjectState {
|
||||
|
||||
// Synced with url
|
||||
metric?: string;
|
||||
metricSearch?: string;
|
||||
}
|
||||
|
||||
export class DataTrail extends SceneObjectBase<DataTrailState> {
|
||||
protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['metric'] });
|
||||
protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['metric', 'metricSearch'] });
|
||||
|
||||
public constructor(state: Partial<DataTrailState>) {
|
||||
super({
|
||||
@ -109,7 +110,7 @@ export class DataTrail extends SceneObjectBase<DataTrailState> {
|
||||
|
||||
protected _variableDependency = new VariableDependencyConfig(this, {
|
||||
variableNames: [VAR_DATASOURCE],
|
||||
onReferencedVariableValueChanged: (variable: SceneVariable) => {
|
||||
onReferencedVariableValueChanged: async (variable: SceneVariable) => {
|
||||
const { name } = variable.state;
|
||||
if (name === VAR_DATASOURCE) {
|
||||
this.datasourceHelper.reset();
|
||||
@ -156,6 +157,7 @@ export class DataTrail extends SceneObjectBase<DataTrailState> {
|
||||
sceneUtils.cloneSceneObjectState(state, {
|
||||
history: this.state.history,
|
||||
metric: !state.metric ? undefined : state.metric,
|
||||
metricSearch: !state.metricSearch ? undefined : state.metricSearch,
|
||||
})
|
||||
);
|
||||
|
||||
@ -184,7 +186,8 @@ export class DataTrail extends SceneObjectBase<DataTrailState> {
|
||||
}
|
||||
|
||||
getUrlState() {
|
||||
return { metric: this.state.metric };
|
||||
const { metric, metricSearch } = this.state;
|
||||
return { metric, metricSearch };
|
||||
}
|
||||
|
||||
updateFromUrl(values: SceneObjectUrlValues) {
|
||||
@ -199,6 +202,12 @@ export class DataTrail extends SceneObjectBase<DataTrailState> {
|
||||
stateUpdate.topScene = new MetricSelectScene({});
|
||||
}
|
||||
|
||||
if (typeof values.metricSearch === 'string') {
|
||||
stateUpdate.metricSearch = values.metricSearch;
|
||||
} else if (values.metric == null) {
|
||||
stateUpdate.metricSearch = undefined;
|
||||
}
|
||||
|
||||
this.setState(stateUpdate);
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { debounce } from 'lodash';
|
||||
import React, { useCallback } from 'react';
|
||||
import { debounce, isEqual } from 'lodash';
|
||||
import React, { useReducer } from 'react';
|
||||
|
||||
import { GrafanaTheme2, VariableRefresh } from '@grafana/data';
|
||||
import { GrafanaTheme2, RawTimeRange } from '@grafana/data';
|
||||
import { isFetchError } from '@grafana/runtime';
|
||||
import {
|
||||
AdHocFiltersVariable,
|
||||
PanelBuilders,
|
||||
QueryVariable,
|
||||
SceneComponentProps,
|
||||
SceneCSSGridItem,
|
||||
SceneCSSGridLayout,
|
||||
@ -15,12 +16,13 @@ import {
|
||||
SceneObjectBase,
|
||||
SceneObjectRef,
|
||||
SceneObjectState,
|
||||
SceneObjectStateChangedEvent,
|
||||
SceneTimeRange,
|
||||
SceneVariable,
|
||||
SceneVariableSet,
|
||||
VariableDependencyConfig,
|
||||
} from '@grafana/scenes';
|
||||
import { VariableHide } from '@grafana/schema';
|
||||
import { Input, InlineSwitch, Field, Alert, Icon, useStyles2 } from '@grafana/ui';
|
||||
import { InlineSwitch, Field, Alert, Icon, useStyles2, Tooltip, Input } from '@grafana/ui';
|
||||
|
||||
import { MetricScene } from '../MetricScene';
|
||||
import { StatusWrapper } from '../StatusWrapper';
|
||||
@ -29,16 +31,17 @@ import { reportExploreMetrics } from '../interactions';
|
||||
import {
|
||||
getVariablesWithMetricConstant,
|
||||
MetricSelectedEvent,
|
||||
trailDS,
|
||||
VAR_DATASOURCE,
|
||||
VAR_FILTERS_EXPR,
|
||||
VAR_METRIC_NAMES,
|
||||
VAR_DATASOURCE_EXPR,
|
||||
VAR_FILTERS,
|
||||
} from '../shared';
|
||||
import { getFilters, getTrailFor } from '../utils';
|
||||
import { getFilters, getTrailFor, isSceneTimeRangeState } from '../utils';
|
||||
|
||||
import { SelectMetricAction } from './SelectMetricAction';
|
||||
import { getMetricNames } from './api';
|
||||
import { getPreviewPanelFor } from './previewPanel';
|
||||
import { sortRelatedMetrics } from './relatedMetrics';
|
||||
import { createJSRegExpFromSearchTerms, createPromRegExp, deriveSearchTermsFromInput } from './util';
|
||||
|
||||
interface MetricPanel {
|
||||
name: string;
|
||||
@ -51,21 +54,25 @@ interface MetricPanel {
|
||||
|
||||
export interface MetricSelectSceneState extends SceneObjectState {
|
||||
body: SceneCSSGridLayout;
|
||||
searchQuery?: string;
|
||||
showPreviews?: boolean;
|
||||
metricsAfterSearch?: string[];
|
||||
metricNames?: string[];
|
||||
metricNamesLoading?: boolean;
|
||||
metricNamesError?: string;
|
||||
metricNamesWarning?: string;
|
||||
}
|
||||
|
||||
const ROW_PREVIEW_HEIGHT = '175px';
|
||||
const ROW_CARD_HEIGHT = '64px';
|
||||
|
||||
const MAX_METRIC_NAMES = 20000;
|
||||
|
||||
export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
private previewCache: Record<string, MetricPanel> = {};
|
||||
private ignoreNextUpdate = false;
|
||||
|
||||
constructor(state: Partial<MetricSelectSceneState>) {
|
||||
super({
|
||||
$variables: state.$variables ?? getMetricNamesVariableSet(),
|
||||
$variables: state.$variables,
|
||||
body:
|
||||
state.body ??
|
||||
new SceneCSSGridLayout({
|
||||
@ -82,19 +89,10 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
}
|
||||
|
||||
protected _variableDependency = new VariableDependencyConfig(this, {
|
||||
variableNames: [VAR_METRIC_NAMES, VAR_DATASOURCE],
|
||||
variableNames: [VAR_DATASOURCE, VAR_FILTERS],
|
||||
onReferencedVariableValueChanged: (variable: SceneVariable) => {
|
||||
const { name } = variable.state;
|
||||
|
||||
if (name === VAR_DATASOURCE) {
|
||||
// Clear all panels for the previous data source
|
||||
this.state.body.setState({ children: [] });
|
||||
} else if (name === VAR_METRIC_NAMES) {
|
||||
this.onMetricNamesChange();
|
||||
// Entire pipeline must be performed
|
||||
this.updateMetrics();
|
||||
this.buildLayout();
|
||||
}
|
||||
// In all cases, we want to reload the metric names
|
||||
this._debounceRefreshMetricNames();
|
||||
},
|
||||
});
|
||||
|
||||
@ -108,24 +106,111 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
|
||||
const trail = getTrailFor(this);
|
||||
|
||||
const metricChangeSubscription = trail.subscribeToEvent(MetricSelectedEvent, (event) => {
|
||||
const { steps, currentStep } = trail.state.history.state;
|
||||
const prevStep = steps[currentStep].parentIndex;
|
||||
const previousMetric = steps[prevStep].trailState.metric;
|
||||
const isRelatedMetricSelector = previousMetric !== undefined;
|
||||
this._subs.add(
|
||||
trail.subscribeToEvent(MetricSelectedEvent, (event) => {
|
||||
const { steps, currentStep } = trail.state.history.state;
|
||||
const prevStep = steps[currentStep].parentIndex;
|
||||
const previousMetric = steps[prevStep].trailState.metric;
|
||||
const isRelatedMetricSelector = previousMetric !== undefined;
|
||||
|
||||
const terms = this.state.searchQuery?.split(splitSeparator).filter((part) => part.length > 0);
|
||||
if (event.payload !== undefined) {
|
||||
reportExploreMetrics('metric_selected', {
|
||||
from: isRelatedMetricSelector ? 'related_metrics' : 'metric_list',
|
||||
searchTermCount: terms?.length || 0,
|
||||
});
|
||||
if (event.payload !== undefined) {
|
||||
const metricSearch = getMetricSearch(trail);
|
||||
const searchTermCount = deriveSearchTermsFromInput(metricSearch).length;
|
||||
|
||||
reportExploreMetrics('metric_selected', {
|
||||
from: isRelatedMetricSelector ? 'related_metrics' : 'metric_list',
|
||||
searchTermCount,
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this._subs.add(
|
||||
trail.subscribeToEvent(SceneObjectStateChangedEvent, (evt) => {
|
||||
if (evt.payload.changedObject instanceof SceneTimeRange) {
|
||||
const { prevState, newState } = evt.payload;
|
||||
|
||||
if (isSceneTimeRangeState(prevState) && isSceneTimeRangeState(newState)) {
|
||||
if (prevState.from === newState.from && prevState.to === newState.to) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this._subs.add(
|
||||
trail.subscribeToState(({ metricSearch }, oldState) => {
|
||||
const oldSearchTerms = deriveSearchTermsFromInput(oldState.metricSearch);
|
||||
const newSearchTerms = deriveSearchTermsFromInput(metricSearch);
|
||||
if (!isEqual(oldSearchTerms, newSearchTerms)) {
|
||||
this._debounceRefreshMetricNames();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this.subscribeToState((newState, prevState) => {
|
||||
if (newState.metricNames !== prevState.metricNames) {
|
||||
this.onMetricNamesChanged();
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
metricChangeSubscription.unsubscribe();
|
||||
};
|
||||
this._debounceRefreshMetricNames();
|
||||
}
|
||||
|
||||
private _debounceRefreshMetricNames = debounce(() => this._refreshMetricNames(), 1000);
|
||||
|
||||
private async _refreshMetricNames() {
|
||||
const trail = getTrailFor(this);
|
||||
const timeRange: RawTimeRange | undefined = trail.state.$timeRange?.state;
|
||||
|
||||
if (!timeRange) {
|
||||
return;
|
||||
}
|
||||
|
||||
const matchTerms = [];
|
||||
|
||||
const filtersVar = sceneGraph.lookupVariable(VAR_FILTERS, this);
|
||||
const hasFilters = filtersVar instanceof AdHocFiltersVariable && filtersVar.getValue()?.valueOf();
|
||||
if (hasFilters) {
|
||||
matchTerms.push(sceneGraph.interpolate(trail, '${filters}'));
|
||||
}
|
||||
|
||||
const metricSearchRegex = createPromRegExp(trail.state.metricSearch);
|
||||
if (metricSearchRegex) {
|
||||
matchTerms.push(`__name__=~"${metricSearchRegex}"`);
|
||||
}
|
||||
|
||||
const match = `{${matchTerms.join(',')}}`;
|
||||
const datasourceUid = sceneGraph.interpolate(trail, VAR_DATASOURCE_EXPR);
|
||||
this.setState({ metricNamesLoading: true, metricNamesError: undefined, metricNamesWarning: undefined });
|
||||
|
||||
try {
|
||||
const response = await getMetricNames(datasourceUid, timeRange, match, MAX_METRIC_NAMES);
|
||||
const searchRegex = createJSRegExpFromSearchTerms(getMetricSearch(this));
|
||||
const metricNames = searchRegex
|
||||
? response.data.filter((metric) => !searchRegex || searchRegex.test(metric))
|
||||
: response.data;
|
||||
|
||||
const metricNamesWarning = response.limitReached
|
||||
? `This feature will only return up to ${MAX_METRIC_NAMES} metric names for performance reasons. ` +
|
||||
`This limit is being exceeded for the current data source. ` +
|
||||
`Add search terms or label filters to narrow down the number of metric names returned.`
|
||||
: undefined;
|
||||
|
||||
this.setState({ metricNames, metricNamesLoading: false, metricNamesWarning, metricNamesError: response.error });
|
||||
} catch (err: unknown) {
|
||||
let error = 'Unknown error';
|
||||
if (isFetchError(err)) {
|
||||
if (err.cancelled) {
|
||||
error = 'Request cancelled';
|
||||
} else if (err.statusText) {
|
||||
error = err.statusText;
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({ metricNames: undefined, metricNamesLoading: false, metricNamesError: error });
|
||||
}
|
||||
}
|
||||
|
||||
private sortedPreviewMetrics() {
|
||||
@ -143,22 +228,10 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
});
|
||||
}
|
||||
|
||||
private currentMetricNames = new Set<string>();
|
||||
private onMetricNamesChanged() {
|
||||
const metricNames = this.state.metricNames || [];
|
||||
|
||||
private onMetricNamesChange() {
|
||||
// Get the datasource metrics list from the VAR_METRIC_NAMES variable
|
||||
const variable = sceneGraph.lookupVariable(VAR_METRIC_NAMES, this);
|
||||
|
||||
if (!(variable instanceof QueryVariable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (variable.state.loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nameList = variable.state.options.map((option) => option.value.toString());
|
||||
const nameSet = new Set(nameList);
|
||||
const nameSet = new Set(metricNames);
|
||||
|
||||
Object.values(this.previewCache).forEach((panel) => {
|
||||
if (!nameSet.has(panel.name)) {
|
||||
@ -166,35 +239,6 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
}
|
||||
});
|
||||
|
||||
this.currentMetricNames = nameSet;
|
||||
this.buildLayout();
|
||||
}
|
||||
|
||||
private applyMetricSearch() {
|
||||
// This should only occur when the `searchQuery` changes, of if the `metricNames` change
|
||||
const metricNames = Array.from(this.currentMetricNames);
|
||||
if (metricNames == null) {
|
||||
return;
|
||||
}
|
||||
const searchRegex = createSearchRegExp(this.state.searchQuery);
|
||||
|
||||
if (!searchRegex) {
|
||||
this.setState({ metricsAfterSearch: metricNames });
|
||||
} else {
|
||||
const metricsAfterSearch = metricNames.filter((metric) => !searchRegex || searchRegex.test(metric));
|
||||
this.setState({ metricsAfterSearch });
|
||||
}
|
||||
}
|
||||
|
||||
private updateMetrics(applySearchAndFilter = true) {
|
||||
if (applySearchAndFilter) {
|
||||
// Set to false if these are not required (because they can be assumed to have been suitably called).
|
||||
this.applyMetricSearch();
|
||||
}
|
||||
|
||||
const { metricsAfterSearch } = this.state;
|
||||
|
||||
const metricNames = metricsAfterSearch || [];
|
||||
const trail = getTrailFor(this);
|
||||
const sortedMetricNames =
|
||||
trail.state.metric !== undefined ? sortRelatedMetrics(metricNames, trail.state.metric) : metricNames;
|
||||
@ -203,7 +247,7 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
|
||||
// Clear absent metrics from cache
|
||||
Object.keys(this.previewCache).forEach((metric) => {
|
||||
if (!this.currentMetricNames.has(metric)) {
|
||||
if (!nameSet.has(metric)) {
|
||||
delete this.previewCache[metric];
|
||||
}
|
||||
});
|
||||
@ -231,6 +275,7 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
}
|
||||
|
||||
this.previewCache = metricsMap;
|
||||
this.buildLayout();
|
||||
}
|
||||
|
||||
private async buildLayout() {
|
||||
@ -240,20 +285,6 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
return;
|
||||
}
|
||||
|
||||
const variable = sceneGraph.lookupVariable(VAR_METRIC_NAMES, this);
|
||||
|
||||
if (!(variable instanceof QueryVariable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (variable.state.loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Object.keys(this.previewCache).length) {
|
||||
this.updateMetrics();
|
||||
}
|
||||
|
||||
const children: SceneFlexItem[] = [];
|
||||
|
||||
const trail = getTrailFor(this);
|
||||
@ -309,30 +340,32 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
};
|
||||
|
||||
public onSearchQueryChange = (evt: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
this.setState({ searchQuery: evt.currentTarget.value });
|
||||
this.searchQueryChangedDebounced();
|
||||
const metricSearch = evt.currentTarget.value;
|
||||
const trail = getTrailFor(this);
|
||||
// Update the variable
|
||||
trail.setState({ metricSearch });
|
||||
};
|
||||
|
||||
private searchQueryChangedDebounced = debounce(() => {
|
||||
this.updateMetrics(); // Need to repeat entire pipeline
|
||||
this.buildLayout();
|
||||
}, 500);
|
||||
|
||||
public onTogglePreviews = () => {
|
||||
this.setState({ showPreviews: !this.state.showPreviews });
|
||||
this.buildLayout();
|
||||
};
|
||||
|
||||
public static Component = ({ model }: SceneComponentProps<MetricSelectScene>) => {
|
||||
const { searchQuery, showPreviews, body } = model.useState();
|
||||
const { showPreviews, body, metricNames, metricNamesError, metricNamesLoading, metricNamesWarning } =
|
||||
model.useState();
|
||||
const { children } = body.useState();
|
||||
const trail = getTrailFor(model);
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const metricNamesStatus = useVariableStatus(VAR_METRIC_NAMES, model);
|
||||
const tooStrict = children.length === 0 && searchQuery;
|
||||
const noMetrics = !metricNamesStatus.isLoading && model.currentMetricNames.size === 0;
|
||||
const [warningDismissed, dismissWarning] = useReducer(() => true, false);
|
||||
|
||||
const isLoading = metricNamesStatus.isLoading && children.length === 0;
|
||||
const { metricSearch } = trail.useState();
|
||||
|
||||
const tooStrict = children.length === 0 && metricSearch;
|
||||
const noMetrics = !metricNamesLoading && metricNames && metricNames.length === 0;
|
||||
|
||||
const isLoading = metricNamesLoading && children.length === 0;
|
||||
|
||||
const blockingMessage = isLoading
|
||||
? undefined
|
||||
@ -340,7 +373,18 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
(tooStrict && 'There are no results found. Try adjusting your search or filters.') ||
|
||||
undefined;
|
||||
|
||||
const disableSearch = metricNamesStatus.error || metricNamesStatus.isLoading;
|
||||
const metricNamesWarningIcon = metricNamesWarning ? (
|
||||
<Tooltip
|
||||
content={
|
||||
<>
|
||||
<h4>Unable to retrieve metric names</h4>
|
||||
<p>{metricNamesWarning}</p>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Icon className={styles.warningIcon} name="exclamation-triangle" />
|
||||
</Tooltip>
|
||||
) : undefined;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@ -349,23 +393,27 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
<Input
|
||||
placeholder="Search metrics"
|
||||
prefix={<Icon name={'search'} />}
|
||||
value={searchQuery}
|
||||
value={metricSearch}
|
||||
onChange={model.onSearchQueryChange}
|
||||
disabled={disableSearch}
|
||||
suffix={metricNamesWarningIcon}
|
||||
/>
|
||||
</Field>
|
||||
<InlineSwitch
|
||||
showLabel={true}
|
||||
label="Show previews"
|
||||
value={showPreviews}
|
||||
onChange={model.onTogglePreviews}
|
||||
disabled={disableSearch}
|
||||
/>
|
||||
<InlineSwitch showLabel={true} label="Show previews" value={showPreviews} onChange={model.onTogglePreviews} />
|
||||
</div>
|
||||
{metricNamesStatus.error && (
|
||||
{metricNamesError && (
|
||||
<Alert title="Unable to retrieve metric names" severity="error">
|
||||
<div>We are unable to connect to your data source. Double check your data source URL and credentials.</div>
|
||||
<div>({metricNamesStatus.error})</div>
|
||||
<div>({metricNamesError})</div>
|
||||
</Alert>
|
||||
)}
|
||||
{metricNamesWarning && !warningDismissed && (
|
||||
<Alert
|
||||
title="Unable to retrieve all metric names"
|
||||
severity="warning"
|
||||
onSubmit={dismissWarning}
|
||||
onRemove={dismissWarning}
|
||||
>
|
||||
<div>{metricNamesWarning}</div>
|
||||
</Alert>
|
||||
)}
|
||||
<StatusWrapper {...{ isLoading, blockingMessage }}>
|
||||
@ -376,23 +424,6 @@ export class MetricSelectScene extends SceneObjectBase<MetricSelectSceneState> {
|
||||
};
|
||||
}
|
||||
|
||||
function getMetricNamesVariableSet() {
|
||||
return new SceneVariableSet({
|
||||
variables: [
|
||||
new QueryVariable({
|
||||
name: VAR_METRIC_NAMES,
|
||||
datasource: trailDS,
|
||||
hide: VariableHide.hideVariable,
|
||||
includeAll: true,
|
||||
defaultToAll: true,
|
||||
skipUrlSync: true,
|
||||
refresh: VariableRefresh.onTimeRangeChanged,
|
||||
query: { query: `label_values(${VAR_FILTERS_EXPR},__name__)`, refId: 'A' },
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
function getCardPanelFor(metric: string, description?: string) {
|
||||
return PanelBuilders.text()
|
||||
.setTitle(metric)
|
||||
@ -423,43 +454,13 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
flexGrow: 1,
|
||||
marginBottom: 0,
|
||||
}),
|
||||
warningIcon: css({
|
||||
color: theme.colors.warning.main,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
// Consider any sequence of characters not permitted for metric names as a sepratator
|
||||
const splitSeparator = /[^a-z0-9_:]+/;
|
||||
|
||||
function createSearchRegExp(spaceSeparatedMetricNames?: string) {
|
||||
if (!spaceSeparatedMetricNames) {
|
||||
return null;
|
||||
}
|
||||
const searchParts = spaceSeparatedMetricNames
|
||||
?.toLowerCase()
|
||||
.split(splitSeparator)
|
||||
.filter((part) => part.length > 0)
|
||||
.map((part) => `(?=(.*${part}.*))`);
|
||||
|
||||
if (searchParts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const regex = searchParts.join('');
|
||||
// (?=(.*expr1.*))(?=().*expr2.*))...
|
||||
// The ?=(...) lookahead allows us to match these in any order.
|
||||
return new RegExp(regex, 'igy');
|
||||
}
|
||||
|
||||
function useVariableStatus(name: string, sceneObject: SceneObject) {
|
||||
const variable = sceneGraph.lookupVariable(name, sceneObject);
|
||||
|
||||
const useVariableState = useCallback(() => {
|
||||
if (variable) {
|
||||
return variable.useState();
|
||||
}
|
||||
return undefined;
|
||||
}, [variable]);
|
||||
|
||||
const { error, loading } = useVariableState() || {};
|
||||
|
||||
return { isLoading: !!loading, error };
|
||||
function getMetricSearch(scene: SceneObject) {
|
||||
const trail = getTrailFor(scene);
|
||||
return trail.state.metricSearch || '';
|
||||
}
|
||||
|
30
public/app/features/trails/MetricSelect/api.ts
Normal file
30
public/app/features/trails/MetricSelect/api.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { RawTimeRange } from '@grafana/data';
|
||||
import { getPrometheusTime } from '@grafana/prometheus/src/language_utils';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
|
||||
type MetricValuesResponse = {
|
||||
data: string[];
|
||||
status: 'success' | 'error';
|
||||
error?: 'string';
|
||||
warnings?: string[];
|
||||
};
|
||||
|
||||
const LIMIT_REACHED = 'results truncated due to limit';
|
||||
|
||||
export async function getMetricNames(dataSourceUid: string, timeRange: RawTimeRange, filters: string, limit?: number) {
|
||||
const url = `/api/datasources/uid/${dataSourceUid}/resources/api/v1/label/__name__/values`;
|
||||
const params: Record<string, string | number> = {
|
||||
start: getPrometheusTime(timeRange.from, false),
|
||||
end: getPrometheusTime(timeRange.to, true),
|
||||
...(filters && filters !== '{}' ? { 'match[]': filters } : {}),
|
||||
...(limit ? { limit } : {}),
|
||||
};
|
||||
|
||||
const response = await getBackendSrv().get<MetricValuesResponse>(url, params, 'explore-metrics-names');
|
||||
|
||||
if (limit && response.warnings?.includes(LIMIT_REACHED)) {
|
||||
return { ...response, limitReached: true };
|
||||
}
|
||||
|
||||
return { ...response, limitReached: false };
|
||||
}
|
51
public/app/features/trails/MetricSelect/util.ts
Normal file
51
public/app/features/trails/MetricSelect/util.ts
Normal file
@ -0,0 +1,51 @@
|
||||
// Consider any sequence of characters not permitted for metric names as a sepratator
|
||||
const splitSeparator = /[^a-z0-9_:]+/;
|
||||
|
||||
export function deriveSearchTermsFromInput(whiteSpaceSeparatedTerms?: string) {
|
||||
return (
|
||||
whiteSpaceSeparatedTerms
|
||||
?.toLowerCase()
|
||||
.split(splitSeparator)
|
||||
.filter((term) => term.length > 0) || []
|
||||
);
|
||||
}
|
||||
|
||||
export function createJSRegExpFromSearchTerms(searchQuery?: string) {
|
||||
const searchParts = deriveSearchTermsFromInput(searchQuery).map((part) => `(?=(.*${part.toLowerCase()}.*))`);
|
||||
|
||||
if (searchParts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const regex = searchParts.join('');
|
||||
// (?=(.*expr1.*)(?=(.*expr2.*))...
|
||||
// The ?=(...) lookahead allows us to match these in any order.
|
||||
return new RegExp(regex, 'igy');
|
||||
}
|
||||
|
||||
export function createPromRegExp(searchQuery?: string) {
|
||||
const searchParts = getUniqueTerms(deriveSearchTermsFromInput(searchQuery))
|
||||
.filter((term) => term.length > 0)
|
||||
.map((term) => `(.*${term.toLowerCase()}.*)`);
|
||||
|
||||
const count = searchParts.length;
|
||||
|
||||
if (searchParts.length === 0) {
|
||||
// avoid match[] must contain at least one non-empty matcher
|
||||
return null; //'..*';
|
||||
}
|
||||
|
||||
const regex = `(?i:${searchParts.join('|')}){${count}}`;
|
||||
// (?i:(.*expr_1.*)|.*expr_2.*)|...|.*expr_n.*){n}
|
||||
// ?i: to ignore case
|
||||
// {n} to ensure that it matches n times, one match per term
|
||||
// - This isn't ideal, since it doesn't enforce that each unique term is matched,
|
||||
// but it's the best we can do with the Prometheus / Go stdlib implementation of regex.
|
||||
|
||||
return regex;
|
||||
}
|
||||
|
||||
function getUniqueTerms(terms: string[] = []) {
|
||||
const set = new Set(terms.map((term) => term.toLowerCase().trim()));
|
||||
return Array.from(set);
|
||||
}
|
@ -191,9 +191,11 @@ function getUrlStateForComparison(trail: DataTrail) {
|
||||
const urlState = getUrlSyncManager().getUrlState(trail);
|
||||
// Make a few corrections
|
||||
|
||||
// Omit some URL parameters that are not useful for state comparison
|
||||
// Omit some URL parameters that are not useful for state comparison,
|
||||
// as they can change in the URL without creating new steps
|
||||
delete urlState.actionView;
|
||||
delete urlState.layout;
|
||||
delete urlState.metricSearch;
|
||||
|
||||
// Populate defaults
|
||||
if (urlState['var-groupby'] === '') {
|
||||
|
@ -13,7 +13,6 @@ export interface ActionViewDefinition {
|
||||
export const TRAILS_ROUTE = '/explore/metrics/trail';
|
||||
export const HOME_ROUTE = '/explore/metrics';
|
||||
|
||||
export const VAR_METRIC_NAMES = 'metricNames';
|
||||
export const VAR_FILTERS = 'filters';
|
||||
export const VAR_FILTERS_EXPR = '{${filters}}';
|
||||
export const VAR_METRIC = 'metric';
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { createEmpty, extend, Extent } from 'ol/extent';
|
||||
import LayerGroup from 'ol/layer/Group';
|
||||
import VectorLayer from 'ol/layer/Vector';
|
||||
import VectorImage from 'ol/layer/VectorImage';
|
||||
|
||||
import { MapLayerState } from '../types';
|
||||
|
||||
@ -11,12 +12,12 @@ export function getLayersExtent(
|
||||
layer: string | undefined
|
||||
): Extent {
|
||||
return layers
|
||||
.filter((l) => l.layer instanceof VectorLayer || l.layer instanceof LayerGroup)
|
||||
.filter((l) => l.layer instanceof VectorLayer || l.layer instanceof LayerGroup || l.layer instanceof VectorImage)
|
||||
.flatMap((ll) => {
|
||||
const l = ll.layer;
|
||||
if (l instanceof LayerGroup) {
|
||||
return getLayerGroupExtent(l);
|
||||
} else if (l instanceof VectorLayer) {
|
||||
} else if (l instanceof VectorLayer || l instanceof VectorImage) {
|
||||
if (allLayers) {
|
||||
// Return everything from all layers
|
||||
return [l.getSource().getExtent()] ?? [];
|
||||
|
@ -46,7 +46,7 @@ export interface HistogramProps extends Themeable2 {
|
||||
structureRev?: number; // a number that will change when the frames[] structure changes
|
||||
legend: VizLegendOptions;
|
||||
rawSeries?: DataFrame[];
|
||||
children?: (builder: UPlotConfigBuilder, frame: DataFrame) => React.ReactNode;
|
||||
children?: (builder: UPlotConfigBuilder, frame: DataFrame, xMinOnlyFrame: DataFrame) => React.ReactNode;
|
||||
}
|
||||
|
||||
export function getBucketSize(frame: DataFrame) {
|
||||
@ -283,6 +283,7 @@ interface State {
|
||||
alignedData: AlignedData;
|
||||
alignedFrame: DataFrame;
|
||||
config?: UPlotConfigBuilder;
|
||||
xMinOnlyFrame: DataFrame;
|
||||
}
|
||||
|
||||
export class Histogram extends React.Component<HistogramProps, State> {
|
||||
@ -295,12 +296,14 @@ export class Histogram extends React.Component<HistogramProps, State> {
|
||||
const { alignedFrame } = props;
|
||||
|
||||
const config = withConfig ? prepConfig(alignedFrame, this.props.theme) : this.state.config!;
|
||||
const alignedData = preparePlotData(config, xMinOnlyFrame(alignedFrame));
|
||||
const xMinOnly = xMinOnlyFrame(alignedFrame);
|
||||
const alignedData = preparePlotData(config, xMinOnly);
|
||||
|
||||
return {
|
||||
alignedFrame,
|
||||
alignedData,
|
||||
config,
|
||||
xMinOnlyFrame: xMinOnly,
|
||||
};
|
||||
}
|
||||
|
||||
@ -347,7 +350,7 @@ export class Histogram extends React.Component<HistogramProps, State> {
|
||||
<VizLayout width={width} height={height} legend={this.renderLegend(config)}>
|
||||
{(vizWidth: number, vizHeight: number) => (
|
||||
<UPlotChart config={this.state.config!} data={this.state.alignedData} width={vizWidth} height={vizHeight}>
|
||||
{children ? children(config, alignedFrame) : null}
|
||||
{children ? children(config, alignedFrame, this.state.xMinOnlyFrame) : null}
|
||||
</UPlotChart>
|
||||
)}
|
||||
</VizLayout>
|
||||
|
@ -2,9 +2,11 @@ import React, { useMemo } from 'react';
|
||||
|
||||
import { PanelProps, buildHistogram, getHistogramFields } from '@grafana/data';
|
||||
import { histogramFieldsToFrame } from '@grafana/data/src/transformations/transformers/histogram';
|
||||
import { useTheme2 } from '@grafana/ui';
|
||||
import { TooltipDisplayMode, TooltipPlugin2, useTheme2 } from '@grafana/ui';
|
||||
import { TooltipHoverMode } from '@grafana/ui/src/components/uPlot/plugins/TooltipPlugin2';
|
||||
|
||||
import { Histogram, getBucketSize } from './Histogram';
|
||||
import { HistogramTooltip } from './HistogramTooltip';
|
||||
import { Options } from './panelcfg.gen';
|
||||
|
||||
type Props = PanelProps<Options>;
|
||||
@ -67,8 +69,34 @@ export const HistogramPanel = ({ data, options, width, height }: Props) => {
|
||||
bucketSize={bucketSize}
|
||||
bucketCount={options.bucketCount}
|
||||
>
|
||||
{(config, alignedFrame) => {
|
||||
return null; // <TooltipPlugin data={alignedFrame} config={config} mode={options.tooltip.mode} timeZone={timeZone} />;
|
||||
{(builder, alignedFrame, xMinOnlyFrame) => {
|
||||
return (
|
||||
<>
|
||||
{options.tooltip.mode !== TooltipDisplayMode.None && (
|
||||
<TooltipPlugin2
|
||||
config={builder}
|
||||
hoverMode={
|
||||
options.tooltip.mode === TooltipDisplayMode.Single ? TooltipHoverMode.xOne : TooltipHoverMode.xAll
|
||||
}
|
||||
render={(u, dataIdxs, seriesIdx, isPinned = false) => {
|
||||
return (
|
||||
<HistogramTooltip
|
||||
series={histogram}
|
||||
xMinOnlyFrame={xMinOnlyFrame}
|
||||
dataIdxs={dataIdxs}
|
||||
seriesIdx={seriesIdx}
|
||||
mode={options.tooltip.mode}
|
||||
sortOrder={options.tooltip.sort}
|
||||
isPinned={isPinned}
|
||||
maxHeight={options.tooltip.maxHeight}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
maxWidth={options.tooltip.maxWidth}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</Histogram>
|
||||
);
|
||||
|
95
public/app/plugins/panel/histogram/HistogramTooltip.tsx
Normal file
95
public/app/plugins/panel/histogram/HistogramTooltip.tsx
Normal file
@ -0,0 +1,95 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { ReactNode, useMemo } from 'react';
|
||||
|
||||
import { DataFrame, formattedValueToString } from '@grafana/data';
|
||||
import { SortOrder, TooltipDisplayMode } from '@grafana/schema/dist/esm/common/common.gen';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent';
|
||||
import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter';
|
||||
import { VizTooltipHeader } from '@grafana/ui/src/components/VizTooltip/VizTooltipHeader';
|
||||
import { VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types';
|
||||
import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils';
|
||||
|
||||
import { getDataLinks } from '../status-history/utils';
|
||||
import { isTooltipScrollable } from '../timeseries/utils';
|
||||
|
||||
export interface HistogramTooltipProps {
|
||||
// aligned series frame
|
||||
series: DataFrame;
|
||||
xMinOnlyFrame: DataFrame;
|
||||
|
||||
// hovered points
|
||||
dataIdxs: Array<number | null>;
|
||||
// closest/hovered series
|
||||
seriesIdx?: number | null;
|
||||
mode?: TooltipDisplayMode;
|
||||
sortOrder?: SortOrder;
|
||||
|
||||
isPinned: boolean;
|
||||
maxHeight?: number;
|
||||
}
|
||||
|
||||
export const HistogramTooltip = ({
|
||||
series,
|
||||
xMinOnlyFrame,
|
||||
dataIdxs,
|
||||
seriesIdx,
|
||||
mode = TooltipDisplayMode.Single,
|
||||
sortOrder = SortOrder.None,
|
||||
isPinned,
|
||||
maxHeight,
|
||||
}: HistogramTooltipProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const xMinField = series.fields[0];
|
||||
const xMaxField = series.fields[1];
|
||||
|
||||
// use the formatter from other bucket bound if none is defined
|
||||
const { display: xMinDisp } = xMinField.config.unit != null ? xMinField : xMaxField;
|
||||
const { display: xMaxDisp } = xMaxField.config.unit != null ? xMaxField : xMinField;
|
||||
|
||||
const xMinVal = formattedValueToString(xMinDisp!(xMinField.values[dataIdxs[0]!]));
|
||||
const xMaxVal = formattedValueToString(xMaxDisp!(xMaxField.values[dataIdxs[1]!]));
|
||||
|
||||
const headerItem: VizTooltipItem | null = xMinField.config.custom?.hideFrom?.tooltip
|
||||
? null
|
||||
: {
|
||||
label: 'Bucket',
|
||||
value: `${xMinVal} - ${xMaxVal}`,
|
||||
};
|
||||
|
||||
const contentItems = useMemo(
|
||||
() => getContentItems(xMinOnlyFrame.fields, xMinField, dataIdxs, seriesIdx, mode, sortOrder),
|
||||
[xMinOnlyFrame.fields, xMinField, dataIdxs, seriesIdx, mode, sortOrder]
|
||||
);
|
||||
|
||||
let footer: ReactNode;
|
||||
|
||||
if (isPinned && seriesIdx != null) {
|
||||
const field = series.fields[seriesIdx];
|
||||
const dataIdx = dataIdxs[seriesIdx]!;
|
||||
const links = getDataLinks(field, dataIdx);
|
||||
|
||||
footer = <VizTooltipFooter dataLinks={links} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
{headerItem != null && <VizTooltipHeader item={headerItem} isPinned={isPinned} />}
|
||||
<VizTooltipContent
|
||||
items={contentItems}
|
||||
isPinned={isPinned}
|
||||
scrollable={isTooltipScrollable({ mode, maxHeight })}
|
||||
maxHeight={maxHeight}
|
||||
/>
|
||||
{footer}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const getStyles = () => ({
|
||||
wrapper: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}),
|
||||
});
|
@ -66,7 +66,7 @@ export const plugin = new PanelPlugin<Options, FieldConfig>(HistogramPanel)
|
||||
showIf: (opts, data) => !originalDataHasHistogram(data),
|
||||
});
|
||||
|
||||
// commonOptionsBuilder.addTooltipOptions(builder);
|
||||
commonOptionsBuilder.addTooltipOptions(builder);
|
||||
commonOptionsBuilder.addLegendOptions(builder);
|
||||
})
|
||||
.useFieldConfig({
|
||||
|
@ -55,6 +55,42 @@ labels:
|
||||
title: Transform data
|
||||
description: Use transformations to rename fields, join time series/SQL-like data, apply mathematical operations, and more
|
||||
weight: 100
|
||||
refs:
|
||||
sparkline-cell-type:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/table/#sparkline
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/table/#sparkline
|
||||
calculation-types:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/query-transform-data/calculation-types/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types/
|
||||
configuration-file:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#configuration-file-location
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#configuration-file-location
|
||||
dashboard-variable:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/dashboards/variables/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/visualizations/dashboards/variables/
|
||||
feature-toggle:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#feature_toggles
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#feature_toggles
|
||||
table-panel:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/table/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/table/
|
||||
time-series-panel:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/time-series/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/time-series/
|
||||
---`;
|
||||
|
||||
const templateIntroContent = `# Transform data
|
||||
@ -143,34 +179,14 @@ ${templateIntroContent}
|
||||
|
||||
You can perform the following transformations on your data.
|
||||
${buildTransformationDocsContent(transformationDocsContent)}
|
||||
{{% docs/reference %}}
|
||||
[Table panel]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/table"
|
||||
[Table panel]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/table"
|
||||
|
||||
[Calculation types]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/query-transform-data/calculation-types"
|
||||
[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types"
|
||||
|
||||
[sparkline cell type]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/table#sparkline"
|
||||
[sparkline cell type]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/table#sparkline"
|
||||
|
||||
[Heatmap panel]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/heatmap"
|
||||
[Heatmap panel]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/heatmap"
|
||||
|
||||
[configuration file]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/setup-grafana/configure-grafana#configuration-file-location"
|
||||
[configuration file]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/setup-grafana/configure-grafana#configuration-file-location"
|
||||
|
||||
[Time series panel]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/time-series"
|
||||
[Time series panel]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/time-series"
|
||||
|
||||
[feature toggle]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/setup-grafana/configure-grafana#feature_toggles"
|
||||
[feature toggle]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/setup-grafana/configure-grafana#feature_toggles"
|
||||
|
||||
[dashboard variable]: "/docs/grafana/ -> docs/grafana/<GRAFANA VERSION>/dashboards/variables"
|
||||
[dashboard variable]: "/docs/grafana-cloud/ -> docs/grafana/<GRAFANA VERSION>/dashboards/variables"
|
||||
|
||||
{{% /docs/reference %}}
|
||||
|
||||
[Data frames]: https://grafana.com/developers/plugin-tools/introduction/data-frames/
|
||||
[Table panel]: ref:table-panel
|
||||
[Calculation types]: ref:calculation-types
|
||||
[sparkline cell type]: ref:sparkline-cell-type
|
||||
[configuration file]: ref:configuration-file
|
||||
[Time series panel]: ref:time-series-panel
|
||||
[feature toggle]: ref:feature-toggle
|
||||
[dashboard variable]: ref:dashboard-variable
|
||||
`;
|
||||
|
||||
function buildTransformationDocsContent(transformationDocsContent: TransformationDocsContentType) {
|
||||
|
Loading…
Reference in New Issue
Block a user