From 10e335c10d9fa6e88839a15c387505742ace1f2d Mon Sep 17 00:00:00 2001 From: Andreas Christou Date: Thu, 11 Sep 2025 20:02:50 +0200 Subject: [PATCH 01/48] Graphite: Backend metrics find endpoint (#110610) * Add lint rules * Backend decoupling - Add standalone files - Add graphite query type - Add logger to Service - Create logger in the ProvideService method - Use a pointer for the HTTP client provider - Update logger usage everywhere - Update tracer type - Replace simplejson with json - Add dummy CallResource and CheckHealth methods - Update tests * Update ConfigEditor imports * Update types imports * Update datasource - Switch to using semver package - Update imports * Update store imports * Update helper imports and notification creation * Update context import * Update version numbers and logic * Copy array_move from core * Test updates * Add required files and update plugin.json * Update core references and packages * Remove commented code * Update wire * Lint * Fix import * Copy null type * More lint * Update snapshot * Refactor backend - Split query logic into separate file - Move utils to separate file * Add health-check logic - Support backend healthcheck if the FF is enabled * Remove query import support as unneeded * Add test * Add util function for decoding responses * Add events types * Add resource handler * Add events handler and generic resource req handler * Tests * Update frontend - Add types - Update events function to support backend requests * Lint and typing * Lint * Add metrics find endpoint - Add types - Add generic response parser - Add endpoint - Tests * Update FE functoin to use backend endpoint * Lint * Simplify request * Update test * Add tests * Review * Review * Fix packages * Format * Fix merge issues --- pkg/tsdb/graphite/resource_handler.go | 110 ++++++++++-- pkg/tsdb/graphite/resource_handler_test.go | 165 +++++++++++++++++- pkg/tsdb/graphite/types.go | 14 ++ .../plugins/datasource/graphite/datasource.ts | 10 +- 4 files changed, 274 insertions(+), 25 deletions(-) diff --git a/pkg/tsdb/graphite/resource_handler.go b/pkg/tsdb/graphite/resource_handler.go index 51eea3775d5..53130cbee6b 100644 --- a/pkg/tsdb/graphite/resource_handler.go +++ b/pkg/tsdb/graphite/resource_handler.go @@ -7,6 +7,7 @@ import ( "io" "net/http" "net/url" + "strings" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" @@ -19,6 +20,7 @@ type resourceHandler func(context.Context, *datasourceInfo, []byte) ([]byte, int func (s *Service) newResourceMux() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("/events", s.handleResourceReq(s.handleEvents)) + mux.HandleFunc("/metrics/find", s.handleResourceReq(s.handleMetricsFind)) return mux } @@ -43,7 +45,7 @@ func (s *Service) handleResourceReq(handlerFn resourceHandler) func(rw http.Resp }() requestBody, err := io.ReadAll(req.Body) if err != nil { - s.logger.Error("Failed to read events request body", "error", err) + s.logger.Error("Failed to read request body", "error", err) writeErrorResponse(rw, http.StatusInternalServerError, fmt.Sprintf("unexpected error %v", err)) return } @@ -62,7 +64,7 @@ func (s *Service) handleResourceReq(handlerFn resourceHandler) func(rw http.Resp rw.WriteHeader(statusCode) _, err = rw.Write(response) if err != nil { - writeErrorResponse(rw, http.StatusInternalServerError, fmt.Sprintf("failed to write events response: %v", err)) + writeErrorResponse(rw, http.StatusInternalServerError, fmt.Sprintf("failed to write response: %v", err)) return } } @@ -90,11 +92,10 @@ func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, requ eventsUrl.RawQuery = queryValues.Encode() - p := eventsUrl.String() - graphiteReq, err := http.NewRequestWithContext(ctx, http.MethodGet, p, nil) + graphiteReq, err := http.NewRequestWithContext(ctx, http.MethodGet, eventsUrl.String(), nil) if err != nil { - s.logger.Info("Failed to create request", "error", err) - return nil, http.StatusInternalServerError, fmt.Errorf("failed to create request: %v", err) + s.logger.Info("Failed to create events request", "error", err) + return nil, http.StatusInternalServerError, fmt.Errorf("failed to create events request: %v", err) } _, span := tracing.DefaultTracer().Start(ctx, "graphite events") @@ -119,21 +120,14 @@ func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, requ } }() - encoding := res.Header.Get("Content-Encoding") - body, err := decode(encoding, res.Body) + events, err := parseResponse[[]GraphiteEventsResponse](res) if err != nil { - return nil, res.StatusCode, fmt.Errorf("failed to read events response: %v", err) - } - - events := []GraphiteEventsResponse{} - err = json.Unmarshal(body, &events) - if err != nil { - return nil, http.StatusInternalServerError, fmt.Errorf("failed to unmarshal events response: %v", err) + return nil, http.StatusInternalServerError, fmt.Errorf("failed to parse events response: %v", err) } // We construct this struct to avoid frontend changes. graphiteEventsResponse, err := json.Marshal(map[string][]GraphiteEventsResponse{ - "data": events, + "data": *events, }) if err != nil { return nil, http.StatusInternalServerError, fmt.Errorf("failed to marshal events response: %s", err) @@ -142,6 +136,90 @@ func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, requ return graphiteEventsResponse, res.StatusCode, nil } +func (s *Service) handleMetricsFind(ctx context.Context, dsInfo *datasourceInfo, requestBody []byte) ([]byte, int, error) { + metricsFindRequestJson := GraphiteMetricsFindRequest{} + err := json.Unmarshal(requestBody, &metricsFindRequestJson) + if err != nil { + s.logger.Error("Failed to unmarshal metrics find request body to JSON", "error", err) + return nil, http.StatusInternalServerError, fmt.Errorf("unexpected error %v", err) + } + + if metricsFindRequestJson.Query == "" { + return nil, http.StatusBadRequest, fmt.Errorf("query is required") + } + + metricsFindUrl, err := url.Parse(fmt.Sprintf("%s/metrics/find", dsInfo.URL)) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("unexpected error %v", err) + } + + queryValues := metricsFindUrl.Query() + if metricsFindRequestJson.From != "" { + queryValues.Set("from", metricsFindRequestJson.From) + } + if metricsFindRequestJson.Until != "" { + queryValues.Set("until", metricsFindRequestJson.Until) + } + + data := url.Values{} + data.Set("query", metricsFindRequestJson.Query) + + graphiteReq, err := http.NewRequestWithContext(ctx, http.MethodPost, metricsFindUrl.String(), strings.NewReader(data.Encode())) + if err != nil { + s.logger.Info("Failed to create metrics find request", "error", err) + return nil, http.StatusInternalServerError, fmt.Errorf("failed to create metrics find request: %v", err) + } + graphiteReq.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + _, span := tracing.DefaultTracer().Start(ctx, "graphite metrics find") + defer span.End() + span.SetAttributes( + attribute.Int64("datasource_id", dsInfo.Id), + ) + res, err := dsInfo.HTTPClient.Do(graphiteReq) + if res != nil { + span.SetAttributes(attribute.Int("graphite.response.code", res.StatusCode)) + } + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + return nil, http.StatusInternalServerError, fmt.Errorf("failed to complete metrics find request: %v", err) + } + defer func() { + err := res.Body.Close() + if err != nil { + s.logger.Warn("Failed to close response body", "error", err) + } + }() + + metrics, err := parseResponse[[]GraphiteMetricsFindResponse](res) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("failed to parse metrics find response: %v", err) + } + + metricsFindResponse, err := json.Marshal(*metrics) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("failed to marshal metrics find response: %s", err) + } + + return metricsFindResponse, res.StatusCode, nil +} + +func parseResponse[V any](res *http.Response) (*V, error) { + encoding := res.Header.Get("Content-Encoding") + body, err := decode(encoding, res.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response: %v", err) + } + + data := new(V) + err = json.Unmarshal(body, &data) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal response: %v", err) + } + return data, nil +} + func writeErrorResponse(rw http.ResponseWriter, code int, msg string) { rw.WriteHeader(code) errorBody := map[string]string{ diff --git a/pkg/tsdb/graphite/resource_handler_test.go b/pkg/tsdb/graphite/resource_handler_test.go index a1aeee3697d..5857af1e146 100644 --- a/pkg/tsdb/graphite/resource_handler_test.go +++ b/pkg/tsdb/graphite/resource_handler_test.go @@ -68,7 +68,7 @@ func TestHandleEvents(t *testing.T) { name: "Success with tags", dsInfo: &datasourceInfo{ Id: 1, - URL: "http://example.com", + URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, }, requestBody: func() []byte { @@ -84,7 +84,7 @@ func TestHandleEvents(t *testing.T) { name: "Success without tags", dsInfo: &datasourceInfo{ Id: 1, - URL: "http://example.com", + URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, }, requestBody: func() []byte { @@ -98,7 +98,7 @@ func TestHandleEvents(t *testing.T) { }, { name: "Invalid request body", - dsInfo: &datasourceInfo{Id: 1, URL: "http://example.com"}, + dsInfo: &datasourceInfo{Id: 1, URL: "http://graphite.grafana"}, requestBody: []byte(`{"invalid": json}`), expectedStatus: http.StatusInternalServerError, expectError: true, @@ -123,7 +123,7 @@ func TestHandleEvents(t *testing.T) { name: "HTTP client error", dsInfo: &datasourceInfo{ Id: 1, - URL: "http://example.com", + URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{err: errors.New("network error")}}, }, requestBody: func() []byte { @@ -139,7 +139,7 @@ func TestHandleEvents(t *testing.T) { name: "Invalid response JSON", dsInfo: &datasourceInfo{ Id: 1, - URL: "http://example.com", + URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: []byte("invalid json"), status: 200}}, }, requestBody: func() []byte { @@ -149,7 +149,7 @@ func TestHandleEvents(t *testing.T) { }(), expectedStatus: http.StatusInternalServerError, expectError: true, - errorContains: "failed to unmarshal events response", + errorContains: "failed to parse events response", }, } @@ -181,13 +181,162 @@ func TestHandleEvents(t *testing.T) { } } +func TestHandleMetricsFind(t *testing.T) { + mockMetrics := []GraphiteMetricsFindResponse{ + {Text: "metric1", Id: "metric1.id", AllowChildren: 1, Expandable: 1, Leaf: 0}, + {Text: "metric2", Id: "metric2.id", AllowChildren: 0, Expandable: 0, Leaf: 1}, + } + mockResp, _ := json.Marshal(mockMetrics) + + tests := []struct { + name string + dsInfo *datasourceInfo + requestBody []byte + expectedStatus int + expectError bool + errorContains string + expectedMetrics []GraphiteMetricsFindResponse + }{ + { + name: "Success with query", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, + }, + requestBody: func() []byte { + request := GraphiteMetricsFindRequest{Query: "app.grafana.*"} + body, _ := json.Marshal(request) + return body + }(), + expectedStatus: 200, + expectError: false, + expectedMetrics: mockMetrics, + }, + { + name: "Success with query and time range", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, + }, + requestBody: func() []byte { + request := GraphiteMetricsFindRequest{ + Query: "app.grafana.*", + From: "now-1h", + Until: "now", + } + body, _ := json.Marshal(request) + return body + }(), + expectedStatus: 200, + expectError: false, + expectedMetrics: mockMetrics, + }, + { + name: "Invalid request body", + dsInfo: &datasourceInfo{Id: 1, URL: "http://graphite.grafana"}, + requestBody: []byte(`{"invalid": json}`), + expectedStatus: http.StatusInternalServerError, + expectError: true, + errorContains: "unexpected error", + }, + { + name: "Empty query", + dsInfo: &datasourceInfo{Id: 1, URL: "http://graphite.grafana"}, + requestBody: func() []byte { + request := GraphiteMetricsFindRequest{Query: ""} + body, _ := json.Marshal(request) + return body + }(), + expectedStatus: http.StatusBadRequest, + expectError: true, + errorContains: "query is required", + }, + { + name: "Invalid URL", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "ht tp://invalid url", // Invalid URL + }, + requestBody: func() []byte { + request := GraphiteMetricsFindRequest{Query: "app.grafana.*"} + body, _ := json.Marshal(request) + return body + }(), + expectedStatus: http.StatusInternalServerError, + expectError: true, + errorContains: "unexpected error", + }, + { + name: "HTTP client error", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{err: errors.New("network error")}}, + }, + requestBody: func() []byte { + request := GraphiteMetricsFindRequest{Query: "app.grafana.*"} + body, _ := json.Marshal(request) + return body + }(), + expectedStatus: http.StatusInternalServerError, + expectError: true, + errorContains: "failed to complete metrics find request", + }, + { + name: "Invalid response JSON", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: []byte("invalid json"), status: 200}}, + }, + requestBody: func() []byte { + request := GraphiteMetricsFindRequest{Query: "app.grafana.*"} + body, _ := json.Marshal(request) + return body + }(), + expectedStatus: http.StatusInternalServerError, + expectError: true, + errorContains: "failed to parse metrics find response", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + svc := &Service{logger: log.NewNullLogger()} + + respBody, status, err := svc.handleMetricsFind(context.Background(), tt.dsInfo, tt.requestBody) + + assert.Equal(t, tt.expectedStatus, status) + + if tt.expectError { + assert.Error(t, err) + assert.Nil(t, respBody) + if tt.errorContains != "" { + assert.Contains(t, err.Error(), tt.errorContains) + } + } else { + require.NoError(t, err) + assert.NotNil(t, respBody) + + if tt.expectedMetrics != nil { + var result []GraphiteMetricsFindResponse + require.NoError(t, json.Unmarshal(respBody, &result)) + assert.Equal(t, tt.expectedMetrics, result) + } + } + }) + } +} + func TestHandleResourceReq_Success(t *testing.T) { mockEvents := []GraphiteEventsResponse{{When: 1234567890, What: "event1"}} mockResp, _ := json.Marshal(mockEvents) dsInfo := datasourceInfo{ Id: 1, - URL: "http://example.com", + URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, } @@ -234,7 +383,7 @@ func TestHandleResourceReq_GetDSInfoError(t *testing.T) { } func TestHandleResourceReq_NilHandler(t *testing.T) { - dsInfo := datasourceInfo{Id: 1, URL: "http://example.com"} + dsInfo := datasourceInfo{Id: 1, URL: "http://graphite.grafana"} svc := &Service{ logger: log.NewNullLogger(), diff --git a/pkg/tsdb/graphite/types.go b/pkg/tsdb/graphite/types.go index 9265b6c4855..8bc46177cf0 100644 --- a/pkg/tsdb/graphite/types.go +++ b/pkg/tsdb/graphite/types.go @@ -31,3 +31,17 @@ type GraphiteEventsResponse struct { Tags []string `json:"tags"` Data string `json:"data"` } + +type GraphiteMetricsFindRequest struct { + From string `json:"from"` + Until string `json:"until"` + Query string `json:"query"` +} + +type GraphiteMetricsFindResponse struct { + Text string `json:"text"` + Id string `json:"id"` + AllowChildren int `json:"allowChildren"` + Expandable int `json:"expandable"` + Leaf int `json:"leaf"` +} diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts index 8d1df35715d..2a51d0107d6 100644 --- a/public/app/plugins/datasource/graphite/datasource.ts +++ b/public/app/plugins/datasource/graphite/datasource.ts @@ -690,7 +690,7 @@ export class GraphiteDatasource * * For more complex searches use requestMetricExpand */ - private requestMetricFind( + private async requestMetricFind( query: string, requestId: string, range?: { from: string | number; until: string | number } @@ -702,6 +702,14 @@ export class GraphiteDatasource params.until = range.until; } + if (config.featureToggles.graphiteBackendMode) { + return await this.postResource('metrics/find', { + from: typeof params.from === 'string' ? params.from : `${params.from}`, + until: typeof params.until === 'string' ? params.until : `${params.until}`, + query, + }); + } + const httpOptions: BackendSrvRequest = { method: 'POST', url: '/metrics/find', From c28a9178716cd5026884456354468970798e5ad8 Mon Sep 17 00:00:00 2001 From: Kevin Minehart <5140827+kminehart@users.noreply.github.com> Date: Thu, 11 Sep 2025 13:03:16 -0500 Subject: [PATCH 02/48] CI: fix bump version action to use grafana-delivery-bot (#110976) * update bump-version * Add id-token: write * update generate-token step * pull-requests -> pull_requests * clone with token and set right name --- .github/workflows/bump-version.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index a67c69b2915..5f2a44fbf53 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -13,17 +13,29 @@ on: required: false permissions: - contents: write - pull-requests: write + id-token: write + contents: read jobs: bump-version: runs-on: ubuntu-latest steps: + - uses: grafana/shared-workflows/actions/get-vault-secrets@main + with: + repo_secrets: | + GRAFANA_DELIVERY_BOT_APP_PEM=delivery-bot-app:PRIVATE_KEY + - name: Generate token + id: generate_token + uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a + with: + app_id: ${{ vars.DELIVERY_BOT_APP_ID }} + private_key: ${{ env.GRAFANA_DELIVERY_BOT_APP_PEM }} + repositories: '["grafana"]' + permissions: '{"contents": "write", "pull_requests": "write"}' - name: Checkout Grafana uses: actions/checkout@v5 with: - persist-credentials: false + token: ${{ steps.generate_token.outputs.token }} - name: Update package.json versions uses: ./pkg/build/actions/bump-version with: @@ -35,10 +47,10 @@ jobs: DRY_RUN: ${{ inputs.dry_run }} REF_NAME: ${{ github.ref_name }} RUN_ID: ${{ github.run_id }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.generate_token.outputs.token }} run: | - git config --local user.name "github-actions[bot]" - git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "grafana-delivery-bot[bot]" + git config --local user.email "grafana-delivery-bot[bot]@users.noreply.github.com" git config --local --add --bool push.autoSetupRemote true git checkout -b "bump-version/${RUN_ID}/${VERSION}" git add . From f5457c79093f1a6e2b8d1bfd4d6d1cdc8f820bda Mon Sep 17 00:00:00 2001 From: Andreas Christou Date: Thu, 11 Sep 2025 20:19:10 +0200 Subject: [PATCH 03/48] InfluxDB: Update feature toggle retrieval (#110941) * Update how feature toggles are retrieved * Update wire * Update Influx registration * Update test --- pkg/plugins/backendplugin/coreplugin/registry.go | 2 +- pkg/server/wire_gen.go | 4 ++-- .../pluginsintegration/plugintest/plugins_test.go | 2 +- pkg/tsdb/influxdb/healthcheck.go | 7 +++---- pkg/tsdb/influxdb/influxdb.go | 11 ++++------- pkg/tsdb/influxdb/influxql/influxql.go | 13 +++++++------ pkg/tsdb/influxdb/mocks_test.go | 4 ---- 7 files changed, 18 insertions(+), 25 deletions(-) diff --git a/pkg/plugins/backendplugin/coreplugin/registry.go b/pkg/plugins/backendplugin/coreplugin/registry.go index 0cb8ed82103..8bc9ab1cf94 100644 --- a/pkg/plugins/backendplugin/coreplugin/registry.go +++ b/pkg/plugins/backendplugin/coreplugin/registry.go @@ -227,7 +227,7 @@ func NewPlugin(pluginID string, cfg *setting.Cfg, httpClientProvider *httpclient case Graphite: svc = graphite.ProvideService(httpClientProvider, tracer) case InfluxDB: - svc = influxdb.ProvideService(httpClientProvider, features) + svc = influxdb.ProvideService(httpClientProvider) case Loki: svc = loki.ProvideService(httpClientProvider, tracer) case OpenTSDB: diff --git a/pkg/server/wire_gen.go b/pkg/server/wire_gen.go index fbb357adeba..08ffe116470 100644 --- a/pkg/server/wire_gen.go +++ b/pkg/server/wire_gen.go @@ -385,7 +385,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api elasticsearchService := elasticsearch.ProvideService(httpclientProvider) tracer := otelTracer() graphiteService := graphite.ProvideService(httpclientProvider, tracer) - influxdbService := influxdb.ProvideService(httpclientProvider, featureToggles) + influxdbService := influxdb.ProvideService(httpclientProvider) lokiService := loki.ProvideService(httpclientProvider, tracer) opentsdbService := opentsdb.ProvideService(httpclientProvider) prometheusService := prometheus.ProvideService(httpclientProvider) @@ -976,7 +976,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac elasticsearchService := elasticsearch.ProvideService(httpclientProvider) tracer := otelTracer() graphiteService := graphite.ProvideService(httpclientProvider, tracer) - influxdbService := influxdb.ProvideService(httpclientProvider, featureToggles) + influxdbService := influxdb.ProvideService(httpclientProvider) lokiService := loki.ProvideService(httpclientProvider, tracer) opentsdbService := opentsdb.ProvideService(httpclientProvider) prometheusService := prometheus.ProvideService(httpclientProvider) diff --git a/pkg/services/pluginsintegration/plugintest/plugins_test.go b/pkg/services/pluginsintegration/plugintest/plugins_test.go index 803936eac00..8a183f03091 100644 --- a/pkg/services/pluginsintegration/plugintest/plugins_test.go +++ b/pkg/services/pluginsintegration/plugintest/plugins_test.go @@ -155,7 +155,7 @@ func TestIntegrationPluginManager(t *testing.T) { cm := cloudmonitoring.ProvideService(hcp) es := elasticsearch.ProvideService(hcp) grap := graphite.ProvideService(hcp, tracer) - idb := influxdb.ProvideService(hcp, features) + idb := influxdb.ProvideService(hcp) lk := loki.ProvideService(hcp, tracer) otsdb := opentsdb.ProvideService(hcp) pr := prometheus.ProvideService(hcp) diff --git a/pkg/tsdb/influxdb/healthcheck.go b/pkg/tsdb/influxdb/healthcheck.go index b1080bf6f78..d997ff10aaa 100644 --- a/pkg/tsdb/influxdb/healthcheck.go +++ b/pkg/tsdb/influxdb/healthcheck.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/tsdb/influxdb/flux" "github.com/grafana/grafana/pkg/tsdb/influxdb/fsql" "github.com/grafana/grafana/pkg/tsdb/influxdb/influxql" @@ -37,7 +36,7 @@ func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthReque case influxVersionFlux: return CheckFluxHealth(ctx, dsInfo, req) case influxVersionInfluxQL: - return CheckInfluxQLHealth(ctx, dsInfo, req, s.features) + return CheckInfluxQLHealth(ctx, dsInfo, req) case influxVersionSQL: return CheckSQLHealth(ctx, dsInfo, req) default: @@ -80,7 +79,7 @@ func CheckFluxHealth(ctx context.Context, dsInfo *models.DatasourceInfo, return getHealthCheckMessage(logger, "", errors.New("error getting flux query buckets")) } -func CheckInfluxQLHealth(ctx context.Context, dsInfo *models.DatasourceInfo, req *backend.CheckHealthRequest, features featuremgmt.FeatureToggles) (*backend.CheckHealthResult, error) { +func CheckInfluxQLHealth(ctx context.Context, dsInfo *models.DatasourceInfo, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) { logger := logger.FromContext(ctx) tracer := tracing.DefaultTracer() resp, err := influxql.Query(ctx, tracer, dsInfo, &backend.QueryDataRequest{ @@ -93,7 +92,7 @@ func CheckInfluxQLHealth(ctx context.Context, dsInfo *models.DatasourceInfo, req JSON: []byte(`{"query": "SHOW measurements", "rawQuery": true}`), }, }, - }, features) + }) if err != nil { return getHealthCheckMessage(logger, "error performing influxQL query", err) } diff --git a/pkg/tsdb/influxdb/influxdb.go b/pkg/tsdb/influxdb/influxdb.go index c4a04e19008..f99f01f8516 100644 --- a/pkg/tsdb/influxdb/influxdb.go +++ b/pkg/tsdb/influxdb/influxdb.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/tsdb/influxdb/flux" "github.com/grafana/grafana/pkg/tsdb/influxdb/fsql" @@ -23,14 +22,12 @@ import ( var logger log.Logger = log.New("tsdb.influxdb") type Service struct { - im instancemgmt.InstanceManager - features featuremgmt.FeatureToggles + im instancemgmt.InstanceManager } -func ProvideService(httpClient httpclient.Provider, features featuremgmt.FeatureToggles) *Service { +func ProvideService(httpClient httpclient.Provider) *Service { return &Service{ - im: datasource.NewInstanceManager(newInstanceSettings(httpClient)), - features: features, + im: datasource.NewInstanceManager(newInstanceSettings(httpClient)), } } @@ -115,7 +112,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) case influxVersionFlux: return flux.Query(ctx, dsInfo, *req) case influxVersionInfluxQL: - return influxql.Query(ctx, tracer, dsInfo, req, s.features) + return influxql.Query(ctx, tracer, dsInfo, req) case influxVersionSQL: return fsql.Query(ctx, dsInfo, *req) default: diff --git a/pkg/tsdb/influxdb/influxql/influxql.go b/pkg/tsdb/influxdb/influxql/influxql.go index 854f942470f..de740040572 100644 --- a/pkg/tsdb/influxdb/influxql/influxql.go +++ b/pkg/tsdb/influxdb/influxql/influxql.go @@ -16,7 +16,6 @@ import ( "go.opentelemetry.io/otel/trace" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/influxdb/influxql/buffered" "github.com/grafana/grafana/pkg/tsdb/influxdb/influxql/querydata" @@ -34,16 +33,18 @@ var ( glog = log.New("tsdb.influx_influxql") ) -func Query(ctx context.Context, tracer trace.Tracer, dsInfo *models.DatasourceInfo, req *backend.QueryDataRequest, features featuremgmt.FeatureToggles) (*backend.QueryDataResponse, error) { +func Query(ctx context.Context, tracer trace.Tracer, dsInfo *models.DatasourceInfo, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { logger := glog.FromContext(ctx) response := backend.NewQueryDataResponse() var err error + config := backend.GrafanaConfigFromContext(ctx) + // We are testing running of queries in parallel behind feature flag - if features.IsEnabled(ctx, featuremgmt.FlagInfluxdbRunQueriesInParallel) { + if config.FeatureToggles().IsEnabled("influxdbRunQueriesInParallel") { concurrentQueryCount, err := req.PluginContext.GrafanaConfig.ConcurrentQueryCount() if err != nil { - logger.Debug(fmt.Sprintf("Concurrent Query Count read/parse error: %v", err), featuremgmt.FlagInfluxdbRunQueriesInParallel) + logger.Debug(fmt.Sprintf("Concurrent Query Count read/parse error: %v", err), "influxdbRunQueriesInParallel") concurrentQueryCount = 10 } @@ -82,7 +83,7 @@ func Query(ctx context.Context, tracer trace.Tracer, dsInfo *models.DatasourceIn return nil } - resp, err := execute(ctx, tracer, dsInfo, logger, query, request, features.IsEnabled(ctx, featuremgmt.FlagInfluxqlStreamingParser)) + resp, err := execute(ctx, tracer, dsInfo, logger, query, request, config.FeatureToggles().IsEnabled("influxqlStreamingParser")) responseLock.Lock() defer responseLock.Unlock() @@ -127,7 +128,7 @@ func Query(ctx context.Context, tracer trace.Tracer, dsInfo *models.DatasourceIn continue } - resp, err := execute(ctx, tracer, dsInfo, logger, query, request, features.IsEnabled(ctx, featuremgmt.FlagInfluxqlStreamingParser)) + resp, err := execute(ctx, tracer, dsInfo, logger, query, request, config.FeatureToggles().IsEnabled("influxqlStreamingParser")) if err != nil { response.Responses[query.RefID] = backend.DataResponse{Error: err} diff --git a/pkg/tsdb/influxdb/mocks_test.go b/pkg/tsdb/influxdb/mocks_test.go index c08090bb747..4dc690c4ccb 100644 --- a/pkg/tsdb/influxdb/mocks_test.go +++ b/pkg/tsdb/influxdb/mocks_test.go @@ -14,7 +14,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" "github.com/grafana/grafana/pkg/infra/httpclient" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/tsdb/influxdb/models" ) @@ -118,8 +117,5 @@ func GetMockService(version string, rt RoundTripper) *Service { version: version, fakeRoundTripper: rt, }, - - // featuremgmt.FlagInfluxqlStreamingParser: false - features: featuremgmt.WithFeatures(), } } From ca9982dc1529b45eeb63703f5fdbd098e071276b Mon Sep 17 00:00:00 2001 From: Stephanie Hingtgen Date: Thu, 11 Sep 2025 12:43:03 -0600 Subject: [PATCH 04/48] Folders: Fix panic in unified storage only mode (#110979) --- pkg/registry/apis/folders/register.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/registry/apis/folders/register.go b/pkg/registry/apis/folders/register.go index 93537deca30..092dbfcf792 100644 --- a/pkg/registry/apis/folders/register.go +++ b/pkg/registry/apis/folders/register.go @@ -143,6 +143,10 @@ func (b *FolderAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.API storage := map[string]rest.Storage{} if b.ignoreLegacy { + opts.StorageOptsRegister(resourceInfo.GroupResource(), apistore.StorageOptions{ + EnableFolderSupport: true, + RequireDeprecatedInternalID: true}) + store, err := grafanaregistry.NewRegistryStore(opts.Scheme, resourceInfo, opts.OptsGetter) if err != nil { return err @@ -150,6 +154,7 @@ func (b *FolderAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.API storage[resourceInfo.StoragePath()] = store apiGroupInfo.VersionedResourcesStorageMap[folders.VERSION] = storage b.storage = storage[resourceInfo.StoragePath()].(grafanarest.Storage) + b.parents = newParentsGetter(store, folder.MaxNestedFolderDepth) return nil } From 041fa843dae3005a942d7f44b33783a0c4a8e75d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Philippe=20Qu=C3=A9m=C3=A9ner?= Date: Thu, 11 Sep 2025 20:44:14 +0200 Subject: [PATCH 05/48] fix(unified-storage): use GetOldObject for delete validation (#110878) --- pkg/registry/apis/folders/register.go | 18 +++++++++++++++--- pkg/registry/apis/folders/register_test.go | 2 +- pkg/tests/apis/folder/folders_test.go | 2 +- pkg/tests/apis/provisioning/files_test.go | 7 +++++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/pkg/registry/apis/folders/register.go b/pkg/registry/apis/folders/register.go index 092dbfcf792..0c606990fde 100644 --- a/pkg/registry/apis/folders/register.go +++ b/pkg/registry/apis/folders/register.go @@ -246,9 +246,21 @@ func (b *FolderAPIBuilder) Mutate(ctx context.Context, a admission.Attributes, _ } func (b *FolderAPIBuilder) Validate(ctx context.Context, a admission.Attributes, _ admission.ObjectInterfaces) error { - obj := a.GetObject() - if obj == nil || a.GetOperation() == admission.Connect { - return nil // This is normal for sub-resource + var obj runtime.Object + verb := a.GetOperation() + + switch verb { + case admission.Create, admission.Update: + obj = a.GetObject() + case admission.Delete: + obj = a.GetOldObject() + if obj == nil { + return fmt.Errorf("old object is nil for delete request") + } + case admission.Connect: + return nil + default: + obj = a.GetObject() } f, ok := obj.(*folders.Folder) diff --git a/pkg/registry/apis/folders/register_test.go b/pkg/registry/apis/folders/register_test.go index 80e257d6cae..762fb309278 100644 --- a/pkg/registry/apis/folders/register_test.go +++ b/pkg/registry/apis/folders/register_test.go @@ -199,8 +199,8 @@ func TestFolderAPIBuilder_Validate_Delete(t *testing.T) { } err := b.Validate(context.Background(), admission.NewAttributesRecord( - obj, nil, + obj, folders.SchemeGroupVersion.WithKind("folder"), obj.Namespace, obj.Name, diff --git a/pkg/tests/apis/folder/folders_test.go b/pkg/tests/apis/folder/folders_test.go index e614af162aa..fe94bb6d9c2 100644 --- a/pkg/tests/apis/folder/folders_test.go +++ b/pkg/tests/apis/folder/folders_test.go @@ -1252,7 +1252,7 @@ func TestIntegrationRootFolderDeletionBlockedByLibraryElementsInSubfolder(t *tes t.Skip("test only on sqlite for now") } - for mode := 0; mode <= 2; mode++ { + for mode := 0; mode <= 5; mode++ { t.Run(fmt.Sprintf("with dual write (unified storage, mode %v, delete parent blocked by library elements in child)", grafanarest.DualWriterMode(mode)), func(t *testing.T) { modeDw := grafanarest.DualWriterMode(mode) diff --git a/pkg/tests/apis/provisioning/files_test.go b/pkg/tests/apis/provisioning/files_test.go index 0dc36d1dce8..41aad60fd6c 100644 --- a/pkg/tests/apis/provisioning/files_test.go +++ b/pkg/tests/apis/provisioning/files_test.go @@ -304,6 +304,10 @@ func TestIntegrationProvisioning_MoveResources(t *testing.T) { }) t.Run("move directory", func(t *testing.T) { + t.Skip("Skip as implementation is broken and leaves dashboards behind in the move") + // FIXME: https://github.com/grafana/git-ui-sync-project/issues/379 + // The current implementation of moving directories is flawed. + // It will be deprecated in favor of queuing a move job // Create some files in a directory first using existing testdata files helper.CopyToProvisioningPath(t, "testdata/timeline-demo.json", "source-dir/timeline-demo.json") helper.CopyToProvisioningPath(t, "testdata/text-options.json", "source-dir/text-options.json") @@ -322,6 +326,9 @@ func TestIntegrationProvisioning_MoveResources(t *testing.T) { }) // nolint:errcheck defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + require.NoError(t, err, "should read response body") + t.Logf("Response Body: %s", string(body)) require.Equal(t, http.StatusOK, resp.StatusCode, "directory move should succeed") // Verify source directory no longer exists From 9a54243f0946988ac84d6230e88c0b39f1099193 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Thu, 11 Sep 2025 22:13:07 +0300 Subject: [PATCH 06/48] Chore: update golang.org/x/exp (#110980) --- apps/alerting/alertenrichment/go.mod | 4 +- apps/alerting/alertenrichment/go.sum | 8 ++-- apps/alerting/notifications/go.mod | 14 +++--- apps/alerting/notifications/go.sum | 32 +++++++------- apps/alerting/rules/go.mod | 14 +++--- apps/alerting/rules/go.sum | 28 ++++++------ apps/dashboard/go.mod | 21 ++++----- apps/dashboard/go.sum | 42 +++++++++--------- apps/folder/go.mod | 10 ++--- apps/folder/go.sum | 20 ++++----- apps/iam/go.mod | 21 ++++----- apps/iam/go.sum | 44 ++++++++++--------- apps/investigations/go.mod | 14 +++--- apps/investigations/go.sum | 28 ++++++------ apps/playlist/go.mod | 14 +++--- apps/playlist/go.sum | 28 ++++++------ apps/plugins/go.mod | 16 +++---- apps/plugins/go.sum | 32 +++++++------- apps/preferences/go.mod | 10 ++--- apps/preferences/go.sum | 20 ++++----- apps/provisioning/go.mod | 16 +++---- apps/provisioning/go.sum | 32 +++++++------- apps/secret/go.mod | 10 ++--- apps/secret/go.sum | 20 ++++----- apps/shorturl/go.mod | 14 +++--- apps/shorturl/go.sum | 28 ++++++------ go.mod | 22 +++++----- go.sum | 44 ++++++++++--------- go.work.sum | 26 ++++------- pkg/aggregator/go.mod | 21 ++++----- pkg/aggregator/go.sum | 42 +++++++++--------- pkg/apimachinery/go.mod | 10 ++--- pkg/apimachinery/go.sum | 20 ++++----- pkg/apiserver/go.mod | 16 +++---- pkg/apiserver/go.sum | 32 +++++++------- pkg/build/go.mod | 8 ++-- pkg/build/go.sum | 16 +++---- pkg/build/wire/go.mod | 6 +-- pkg/build/wire/go.sum | 12 ++--- pkg/codegen/go.mod | 10 ++--- pkg/codegen/go.sum | 20 ++++----- pkg/plugins/codegen/go.mod | 10 ++--- pkg/plugins/codegen/go.sum | 24 +++++----- pkg/promlib/go.mod | 16 ++++--- pkg/promlib/go.sum | 38 ++++++++-------- .../resourcepermissions/service.go | 3 +- .../dashboards/service/dashboard_service.go | 2 +- pkg/services/folder/folderimpl/folder.go | 2 +- .../folderimpl/folder_unifiedstorage.go | 2 +- pkg/services/ngalert/state/manager_test.go | 4 +- pkg/services/sqlstore/migrator/dialect.go | 3 +- .../cloud-monitoring/converter/converter.go | 6 +-- 52 files changed, 483 insertions(+), 472 deletions(-) diff --git a/apps/alerting/alertenrichment/go.mod b/apps/alerting/alertenrichment/go.mod index 3b07ef45283..f309d1cc413 100644 --- a/apps/alerting/alertenrichment/go.mod +++ b/apps/alerting/alertenrichment/go.mod @@ -25,8 +25,8 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/x448/float16 v0.8.4 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/text v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/text v0.29.0 // indirect google.golang.org/protobuf v1.36.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/apps/alerting/alertenrichment/go.sum b/apps/alerting/alertenrichment/go.sum index 38e734949de..62361150638 100644 --- a/apps/alerting/alertenrichment/go.sum +++ b/apps/alerting/alertenrichment/go.sum @@ -69,8 +69,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= 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= @@ -79,8 +79,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= diff --git a/apps/alerting/notifications/go.mod b/apps/alerting/notifications/go.mod index 974455b6499..873cd19332f 100644 --- a/apps/alerting/notifications/go.mod +++ b/apps/alerting/notifications/go.mod @@ -82,14 +82,14 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect diff --git a/apps/alerting/notifications/go.sum b/apps/alerting/notifications/go.sum index e8fd06f910f..81750c2da22 100644 --- a/apps/alerting/notifications/go.sum +++ b/apps/alerting/notifications/go.sum @@ -252,8 +252,8 @@ go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= 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= @@ -270,8 +270,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= @@ -280,24 +280,24 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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-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-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -308,8 +308,8 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn 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.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/apps/alerting/rules/go.mod b/apps/alerting/rules/go.mod index 201af235384..076f3468432 100644 --- a/apps/alerting/rules/go.mod +++ b/apps/alerting/rules/go.mod @@ -64,14 +64,14 @@ require ( go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect diff --git a/apps/alerting/rules/go.sum b/apps/alerting/rules/go.sum index 2f26b92ca0c..3c3ab51328f 100644 --- a/apps/alerting/rules/go.sum +++ b/apps/alerting/rules/go.sum @@ -159,34 +159,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/apps/dashboard/go.mod b/apps/dashboard/go.mod index 0c730140bc0..cef324bcda9 100644 --- a/apps/dashboard/go.mod +++ b/apps/dashboard/go.mod @@ -11,7 +11,7 @@ require ( github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e github.com/prometheus/client_golang v1.23.0 github.com/stretchr/testify v1.10.0 - golang.org/x/net v0.43.0 + golang.org/x/net v0.44.0 k8s.io/apimachinery v0.33.3 k8s.io/apiserver v0.33.3 k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff @@ -119,16 +119,17 @@ require ( go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/mod v0.27.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect + golang.org/x/mod v0.28.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect diff --git a/apps/dashboard/go.sum b/apps/dashboard/go.sum index 11152e65be3..78e25c56f6d 100644 --- a/apps/dashboard/go.sum +++ b/apps/dashboard/go.sum @@ -326,16 +326,16 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= 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= @@ -344,8 +344,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -353,8 +353,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20191020152052-9984515f0562/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -373,33 +373,35 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/apps/folder/go.mod b/apps/folder/go.mod index 652fec43489..d15cbb0fb3f 100644 --- a/apps/folder/go.mod +++ b/apps/folder/go.mod @@ -47,12 +47,12 @@ require ( go.opentelemetry.io/otel v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect google.golang.org/protobuf v1.36.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/apps/folder/go.sum b/apps/folder/go.sum index ccbf0420c0e..ff619de1424 100644 --- a/apps/folder/go.sum +++ b/apps/folder/go.sum @@ -122,8 +122,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -132,16 +132,16 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= diff --git a/apps/iam/go.mod b/apps/iam/go.mod index 54ae9805548..407c553de5f 100644 --- a/apps/iam/go.mod +++ b/apps/iam/go.mod @@ -403,17 +403,18 @@ require ( go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect gocloud.dev v0.42.0 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect diff --git a/apps/iam/go.sum b/apps/iam/go.sum index 63e2512ddaf..42bddc83c25 100644 --- a/apps/iam/go.sum +++ b/apps/iam/go.sum @@ -1480,8 +1480,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1495,8 +1495,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1527,8 +1527,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1588,8 +1588,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1630,8 +1630,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1731,8 +1731,10 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -1740,8 +1742,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1755,13 +1757,13 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1827,8 +1829,10 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= +golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg= 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= diff --git a/apps/investigations/go.mod b/apps/investigations/go.mod index 278334ce0f1..ad72d49baa1 100644 --- a/apps/investigations/go.mod +++ b/apps/investigations/go.mod @@ -65,14 +65,14 @@ require ( go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect diff --git a/apps/investigations/go.sum b/apps/investigations/go.sum index 2f26b92ca0c..3c3ab51328f 100644 --- a/apps/investigations/go.sum +++ b/apps/investigations/go.sum @@ -159,34 +159,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/apps/playlist/go.mod b/apps/playlist/go.mod index 96637140467..c40105464ff 100644 --- a/apps/playlist/go.mod +++ b/apps/playlist/go.mod @@ -65,14 +65,14 @@ require ( go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect diff --git a/apps/playlist/go.sum b/apps/playlist/go.sum index 2f26b92ca0c..3c3ab51328f 100644 --- a/apps/playlist/go.sum +++ b/apps/playlist/go.sum @@ -159,34 +159,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/apps/plugins/go.mod b/apps/plugins/go.mod index a6713c10599..51d951541ad 100644 --- a/apps/plugins/go.mod +++ b/apps/plugins/go.mod @@ -71,15 +71,15 @@ require ( go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect diff --git a/apps/plugins/go.sum b/apps/plugins/go.sum index c07e28b199a..5a4166c7a6d 100644 --- a/apps/plugins/go.sum +++ b/apps/plugins/go.sum @@ -171,8 +171,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -185,8 +185,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -194,8 +194,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -206,33 +206,33 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/apps/preferences/go.mod b/apps/preferences/go.mod index 7dac6cc88e6..c502f07d0c4 100644 --- a/apps/preferences/go.mod +++ b/apps/preferences/go.mod @@ -47,12 +47,12 @@ require ( go.opentelemetry.io/otel v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect google.golang.org/protobuf v1.36.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/apps/preferences/go.sum b/apps/preferences/go.sum index 1a57d097497..148a969504b 100644 --- a/apps/preferences/go.sum +++ b/apps/preferences/go.sum @@ -122,8 +122,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -132,16 +132,16 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= diff --git a/apps/provisioning/go.mod b/apps/provisioning/go.mod index 6a8db51186b..6ada7417be6 100644 --- a/apps/provisioning/go.mod +++ b/apps/provisioning/go.mod @@ -64,14 +64,14 @@ require ( go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/grpc v1.74.2 // indirect google.golang.org/protobuf v1.36.6 // indirect diff --git a/apps/provisioning/go.sum b/apps/provisioning/go.sum index fd6f49d74bb..03cdcd70638 100644 --- a/apps/provisioning/go.sum +++ b/apps/provisioning/go.sum @@ -149,8 +149,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -163,8 +163,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -172,8 +172,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -184,33 +184,33 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/apps/secret/go.mod b/apps/secret/go.mod index 26df11b118a..1a69cb79f98 100644 --- a/apps/secret/go.mod +++ b/apps/secret/go.mod @@ -52,12 +52,12 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/client-go v0.33.3 // indirect diff --git a/apps/secret/go.sum b/apps/secret/go.sum index 62cfe8b9ac1..f8054f2bf2d 100644 --- a/apps/secret/go.sum +++ b/apps/secret/go.sum @@ -134,8 +134,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -144,16 +144,16 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= diff --git a/apps/shorturl/go.mod b/apps/shorturl/go.mod index 144f22332c3..1caa6741faa 100644 --- a/apps/shorturl/go.mod +++ b/apps/shorturl/go.mod @@ -66,14 +66,14 @@ require ( go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect diff --git a/apps/shorturl/go.sum b/apps/shorturl/go.sum index 2f26b92ca0c..3c3ab51328f 100644 --- a/apps/shorturl/go.sum +++ b/apps/shorturl/go.sum @@ -159,34 +159,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/go.mod b/go.mod index 8e4ef9a0423..73c2d153ed8 100644 --- a/go.mod +++ b/go.mod @@ -198,15 +198,15 @@ require ( go.uber.org/zap v1.27.0 // @grafana/identity-access-team gocloud.dev v0.42.0 // @grafana/grafana-app-platform-squad gocloud.dev/secrets/hashivault v0.42.0 // @grafana/grafana-operator-experience-squad - golang.org/x/crypto v0.41.0 // @grafana/grafana-backend-group - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // @grafana/alerting-backend - golang.org/x/mod v0.27.0 // indirect; @grafana/grafana-backend-group - golang.org/x/net v0.43.0 // @grafana/oss-big-tent @grafana/partner-datasources + golang.org/x/crypto v0.42.0 // @grafana/grafana-backend-group + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // @grafana/alerting-backend + golang.org/x/mod v0.28.0 // indirect; @grafana/grafana-backend-group + golang.org/x/net v0.44.0 // @grafana/oss-big-tent @grafana/partner-datasources golang.org/x/oauth2 v0.30.0 // @grafana/identity-access-team - golang.org/x/sync v0.16.0 // @grafana/alerting-backend - golang.org/x/text v0.28.0 // @grafana/grafana-backend-group - golang.org/x/time v0.11.0 // @grafana/grafana-backend-group - golang.org/x/tools v0.36.0 // indirect; @grafana/grafana-as-code + golang.org/x/sync v0.17.0 // @grafana/alerting-backend + golang.org/x/text v0.29.0 // @grafana/grafana-backend-group + golang.org/x/time v0.13.0 // @grafana/grafana-backend-group + golang.org/x/tools v0.37.0 // indirect; @grafana/grafana-as-code gonum.org/v1/gonum v0.16.0 // @grafana/oss-big-tent google.golang.org/api v0.235.0 // @grafana/grafana-backend-group google.golang.org/grpc v1.74.2 // @grafana/plugins-platform-backend @@ -619,8 +619,8 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect @@ -646,6 +646,8 @@ require ( require ( github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/smarty/assertions v1.15.0 // indirect + golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect + golang.org/x/tools/godoc v0.1.0-deprecated // indirect ) // Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream diff --git a/go.sum b/go.sum index 0b376c0e8ca..806c79cc1a3 100644 --- a/go.sum +++ b/go.sum @@ -2723,8 +2723,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2740,8 +2740,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -2788,8 +2788,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= @@ -2875,8 +2875,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2939,8 +2939,8 @@ golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -3072,9 +3072,11 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE= 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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -3093,8 +3095,8 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3117,16 +3119,16 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -3204,8 +3206,10 @@ golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= +golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg= 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= diff --git a/go.work.sum b/go.work.sum index adc1941ad28..653ad2af469 100644 --- a/go.work.sum +++ b/go.work.sum @@ -530,8 +530,6 @@ github.com/Azure/go-amqp v1.0.5 h1:po5+ljlcNSU8xtapHTe8gIc8yHxCzC03E8afH2g1ftU= github.com/Azure/go-amqp v1.0.5/go.mod h1:vZAogwdrkbyK3Mla8m/CxSc/aKdnTZ4IbPxl51Y5WZE= github.com/Azure/go-amqp v1.4.0 h1:Xj3caqi4comOF/L1Uc5iuBxR/pB6KumejC01YQOqOR4= github.com/Azure/go-amqp v1.4.0/go.mod h1:vZAogwdrkbyK3Mla8m/CxSc/aKdnTZ4IbPxl51Y5WZE= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 h1:Ov8avRZi2vmrE2JcXw+tu5K/yB41r7xK9GZDiBF7NdM= github.com/Azure/go-autorest/autorest/azure/auth v0.5.13/go.mod h1:5BAVfWLWXihP47vYrPuBKKf4cS0bXI+KM9Qx6ETDJYo= github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc= @@ -734,8 +732,6 @@ github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJP github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= @@ -1006,7 +1002,6 @@ github.com/grafana/grafana-app-sdk/logging v0.39.0 h1:3GgN5+dUZYqq74Q+GT9/ET+yo+ github.com/grafana/grafana-app-sdk/logging v0.39.0/go.mod h1:WhDENSnaGHtyVVwZGVnAR7YLvh2xlLDYR3D7E6h7XVk= github.com/grafana/grafana-app-sdk/logging v0.39.1/go.mod h1:WhDENSnaGHtyVVwZGVnAR7YLvh2xlLDYR3D7E6h7XVk= github.com/grafana/grafana-app-sdk/logging v0.40.0/go.mod h1:otUD9XpJD7A5sCLb8mcs9hIXGdeV6lnhzVwe747g4RU= -github.com/grafana/grafana-app-sdk/logging v0.40.2/go.mod h1:otUD9XpJD7A5sCLb8mcs9hIXGdeV6lnhzVwe747g4RU= github.com/grafana/grafana-app-sdk/plugin v0.41.0 h1:ShUvGpAVzM3UxcsfwS6l/lwW4ytDeTbCQXf8w2P8Yp8= github.com/grafana/grafana-app-sdk/plugin v0.41.0/go.mod h1:YIhimVfAqtOp3kdhxOanaSZjypVKh/bYxf9wfFfhDm0= github.com/grafana/grafana-aws-sdk v0.38.2 h1:TzQD0OpWsNjtldi5G5TLDlBRk8OyDf+B5ujcoAu4Dp0= @@ -1109,8 +1104,6 @@ github.com/jon-whit/go-grpc-prometheus v1.4.0/go.mod h1:iTPm+Iuhh3IIqR0iGZ91JJEg github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/joncrlsn/dque v0.0.0-20211108142734-c2ef48c5192a h1:sfe532Ipn7GX0V6mHdynBk393rDmqgI0QmjLK7ct7TU= github.com/joncrlsn/dque v0.0.0-20211108142734-c2ef48c5192a/go.mod h1:dNKs71rs2VJGBAmttu7fouEsRQlRjxy0p1Sx+T5wbpY= -github.com/joshlf/testutil v0.0.0-20170608050642-b5d8aa79d93d h1:J8tJzRyiddAFF65YVgxli+TyWBi0f79Sld6rJP6CBcY= -github.com/joshlf/testutil v0.0.0-20170608050642-b5d8aa79d93d/go.mod h1:b+Q3v8Yrg5o15d71PSUraUzYb+jWl6wQMSBXSGS/hv0= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jsternberg/zap-logfmt v1.2.0 h1:1v+PK4/B48cy8cfQbxL4FmmNZrjnIMr2BsnyEmXqv2o= github.com/jsternberg/zap-logfmt v1.2.0/go.mod h1:kz+1CUmCutPWABnNkOu9hOHKdT2q3TDYCcsFy9hpqb0= @@ -1229,20 +1222,12 @@ github.com/moby/moby v27.5.1+incompatible h1:/pN59F/t3U7Q4FPzV88nzqf7Fp0qqCSL2Kz github.com/moby/moby v27.5.1+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= -github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= -github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= -github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/go-grpc-compression v1.2.3 h1:42/BKWMy0KEJGSdWvzqIyOZ95YcR9mLPqKctH7Uo//I= github.com/mostynb/go-grpc-compression v1.2.3/go.mod h1:AghIxF3P57umzqM9yz795+y1Vjs47Km/Y2FE6ouQ7Lg= github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8 h1:P48LjvUQpTReR3TQRbxSeSBsMXzfK0uol7eRcr7VBYQ= @@ -1532,6 +1517,8 @@ github.com/ydb-platform/ydb-go-sdk/v3 v3.108.1/go.mod h1:l5sSv153E18VvYcsmr51hok github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= +github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= @@ -1791,6 +1778,7 @@ golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1806,6 +1794,7 @@ golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -1845,6 +1834,8 @@ golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= @@ -1857,8 +1848,11 @@ golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= +golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= +golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= @@ -1957,8 +1951,6 @@ gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= gopkg.in/vmihailenco/msgpack.v2 v2.9.2 h1:gjPqo9orRVlSAH/065qw3MsFCDpH7fa1KpiizXyllY4= gopkg.in/vmihailenco/msgpack.v2 v2.9.2/go.mod h1:/3Dn1Npt9+MYyLpYYXjInO/5jvMLamn+AEGwNEOatn8= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34= honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= diff --git a/pkg/aggregator/go.mod b/pkg/aggregator/go.mod index 878b0903611..39ead4943b8 100644 --- a/pkg/aggregator/go.mod +++ b/pkg/aggregator/go.mod @@ -137,17 +137,18 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect diff --git a/pkg/aggregator/go.sum b/pkg/aggregator/go.sum index 8272f46f151..e44608059e8 100644 --- a/pkg/aggregator/go.sum +++ b/pkg/aggregator/go.sum @@ -404,19 +404,19 @@ go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= 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/lint v0.0.0-20190930215403-16217165b5de/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.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= 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-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -426,8 +426,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= @@ -436,8 +436,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -452,16 +452,18 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -472,8 +474,8 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn 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.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/pkg/apimachinery/go.mod b/pkg/apimachinery/go.mod index ce231290790..b903d2c7e3f 100644 --- a/pkg/apimachinery/go.mod +++ b/pkg/apimachinery/go.mod @@ -43,11 +43,11 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/grpc v1.74.2 // indirect google.golang.org/protobuf v1.36.6 // indirect diff --git a/pkg/apimachinery/go.sum b/pkg/apimachinery/go.sum index 45a22c473b8..e9dfb27a6b3 100644 --- a/pkg/apimachinery/go.sum +++ b/pkg/apimachinery/go.sum @@ -96,8 +96,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -110,15 +110,15 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= 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.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -129,8 +129,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -142,8 +142,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= diff --git a/pkg/apiserver/go.mod b/pkg/apiserver/go.mod index 8a363f0fa04..2d699ea0538 100644 --- a/pkg/apiserver/go.mod +++ b/pkg/apiserver/go.mod @@ -82,15 +82,15 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect diff --git a/pkg/apiserver/go.sum b/pkg/apiserver/go.sum index b44bbb5bcaf..bb49d49a2d6 100644 --- a/pkg/apiserver/go.sum +++ b/pkg/apiserver/go.sum @@ -240,8 +240,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= 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= @@ -264,8 +264,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= @@ -276,8 +276,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -291,25 +291,25 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -322,8 +322,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/pkg/build/go.mod b/pkg/build/go.mod index e5b4ab234d8..8c96eac0617 100644 --- a/pkg/build/go.mod +++ b/pkg/build/go.mod @@ -13,9 +13,9 @@ require ( go.opentelemetry.io/otel v1.37.0 // indirect; @grafana/grafana-backend-group go.opentelemetry.io/otel/sdk v1.37.0 // indirect; @grafana/grafana-backend-group go.opentelemetry.io/otel/trace v1.37.0 // indirect; @grafana/grafana-backend-group - golang.org/x/net v0.43.0 // indirect; @grafana/oss-big-tent @grafana/partner-datasources - golang.org/x/sync v0.16.0 // @grafana/alerting-backend - golang.org/x/text v0.28.0 // indirect; @grafana/grafana-backend-group + golang.org/x/net v0.44.0 // indirect; @grafana/oss-big-tent @grafana/partner-datasources + golang.org/x/sync v0.17.0 // @grafana/alerting-backend + golang.org/x/text v0.29.0 // indirect; @grafana/grafana-backend-group google.golang.org/grpc v1.74.2 // indirect; @grafana/plugins-platform-backend google.golang.org/protobuf v1.36.6 // indirect; @grafana/plugins-platform-backend ) @@ -29,7 +29,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect - golang.org/x/sys v0.35.0 // indirect + golang.org/x/sys v0.36.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect ) diff --git a/pkg/build/go.sum b/pkg/build/go.sum index 8e049a4067c..90a2a582248 100644 --- a/pkg/build/go.sum +++ b/pkg/build/go.sum @@ -95,14 +95,14 @@ go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= diff --git a/pkg/build/wire/go.mod b/pkg/build/wire/go.mod index 1dbb83c5b34..e6276f37657 100644 --- a/pkg/build/wire/go.mod +++ b/pkg/build/wire/go.mod @@ -6,10 +6,10 @@ require ( github.com/google/go-cmp v0.7.0 github.com/google/subcommands v1.2.0 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 - golang.org/x/tools v0.36.0 + golang.org/x/tools v0.37.0 ) require ( - golang.org/x/mod v0.27.0 // indirect - golang.org/x/sync v0.16.0 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/sync v0.17.0 // indirect ) diff --git a/pkg/build/wire/go.sum b/pkg/build/wire/go.sum index 54bfd049a5f..e4262703495 100644 --- a/pkg/build/wire/go.sum +++ b/pkg/build/wire/go.sum @@ -4,9 +4,9 @@ github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= diff --git a/pkg/codegen/go.mod b/pkg/codegen/go.mod index 55a4d6ee4da..6d5b2ce23a2 100644 --- a/pkg/codegen/go.mod +++ b/pkg/codegen/go.mod @@ -9,7 +9,7 @@ require ( github.com/grafana/cog v0.0.37 github.com/grafana/cuetsy v0.1.11 github.com/matryer/is v1.4.1 - golang.org/x/tools v0.36.0 + golang.org/x/tools v0.37.0 ) require ( @@ -46,10 +46,10 @@ require ( github.com/ugorji/go/codec v1.2.11 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/yalue/merged_fs v1.3.0 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/text v0.28.0 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/text v0.29.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/codegen/go.sum b/pkg/codegen/go.sum index 9afab1f859e..9677a22ca8a 100644 --- a/pkg/codegen/go.sum +++ b/pkg/codegen/go.sum @@ -98,16 +98,16 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yalue/merged_fs v1.3.0 h1:qCeh9tMPNy/i8cwDsQTJ5bLr6IRxbs6meakNE5O+wyY= github.com/yalue/merged_fs v1.3.0/go.mod h1:WqqchfVYQyclV2tnR7wtRhBddzBvLVR83Cjw9BKQw0M= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/plugins/codegen/go.mod b/pkg/plugins/codegen/go.mod index 2aa1c140a0b..d2e49da61bd 100644 --- a/pkg/plugins/codegen/go.mod +++ b/pkg/plugins/codegen/go.mod @@ -42,11 +42,11 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/yalue/merged_fs v1.3.0 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/tools v0.37.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/plugins/codegen/go.sum b/pkg/plugins/codegen/go.sum index cd78ae32b2d..1e5ef948d96 100644 --- a/pkg/plugins/codegen/go.sum +++ b/pkg/plugins/codegen/go.sum @@ -92,20 +92,20 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yalue/merged_fs v1.3.0 h1:qCeh9tMPNy/i8cwDsQTJ5bLr6IRxbs6meakNE5O+wyY= github.com/yalue/merged_fs v1.3.0/go.mod h1:WqqchfVYQyclV2tnR7wtRhBddzBvLVR83Cjw9BKQw0M= -golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/promlib/go.mod b/pkg/promlib/go.mod index 24421c1fe0a..bd17282e6ce 100644 --- a/pkg/promlib/go.mod +++ b/pkg/promlib/go.mod @@ -117,13 +117,15 @@ require ( go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.13.0 // indirect + golang.org/x/tools v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/api v0.235.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect diff --git a/pkg/promlib/go.sum b/pkg/promlib/go.sum index 8e155c7d7f9..185183352cd 100644 --- a/pkg/promlib/go.sum +++ b/pkg/promlib/go.sum @@ -353,27 +353,27 @@ go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= 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.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20191020152052-9984515f0562/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -385,20 +385,22 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8= +golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= diff --git a/pkg/services/accesscontrol/resourcepermissions/service.go b/pkg/services/accesscontrol/resourcepermissions/service.go index 276ab2a5d3e..da90da70b86 100644 --- a/pkg/services/accesscontrol/resourcepermissions/service.go +++ b/pkg/services/accesscontrol/resourcepermissions/service.go @@ -4,11 +4,10 @@ import ( "context" "errors" "fmt" + "slices" "sort" "strings" - "golang.org/x/exp/slices" - "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/infra/db" diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go index 7f037738c85..193d5566eae 100644 --- a/pkg/services/dashboards/service/dashboard_service.go +++ b/pkg/services/dashboards/service/dashboard_service.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "slices" "strconv" "strings" "time" @@ -14,7 +15,6 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "golang.org/x/exp/maps" - "golang.org/x/exp/slices" apierrors "k8s.io/apimachinery/pkg/api/errors" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/pkg/services/folder/folderimpl/folder.go b/pkg/services/folder/folderimpl/folder.go index 4a872f45eb8..a709ecd1e40 100644 --- a/pkg/services/folder/folderimpl/folder.go +++ b/pkg/services/folder/folderimpl/folder.go @@ -7,6 +7,7 @@ import ( "fmt" "log/slog" "runtime" + "slices" "strings" "sync" "time" @@ -14,7 +15,6 @@ import ( "github.com/prometheus/client_golang/prometheus" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - "golang.org/x/exp/slices" "github.com/grafana/dskit/concurrency" dashboardv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1" diff --git a/pkg/services/folder/folderimpl/folder_unifiedstorage.go b/pkg/services/folder/folderimpl/folder_unifiedstorage.go index abf715f87df..30aea5f2985 100644 --- a/pkg/services/folder/folderimpl/folder_unifiedstorage.go +++ b/pkg/services/folder/folderimpl/folder_unifiedstorage.go @@ -3,13 +3,13 @@ package folderimpl import ( "context" "fmt" + "slices" "strconv" "strings" "time" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - "golang.org/x/exp/slices" "k8s.io/apimachinery/pkg/selection" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/services/ngalert/state/manager_test.go b/pkg/services/ngalert/state/manager_test.go index ad28896a0a6..363d7aef78d 100644 --- a/pkg/services/ngalert/state/manager_test.go +++ b/pkg/services/ngalert/state/manager_test.go @@ -7,6 +7,7 @@ import ( "fmt" "math" "math/rand" + "slices" "sort" "strings" "testing" @@ -15,13 +16,12 @@ import ( "github.com/benbjohnson/clock" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "golang.org/x/exp/slices" + "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/tracing" diff --git a/pkg/services/sqlstore/migrator/dialect.go b/pkg/services/sqlstore/migrator/dialect.go index a4d5c3061dd..bec421e36e2 100644 --- a/pkg/services/sqlstore/migrator/dialect.go +++ b/pkg/services/sqlstore/migrator/dialect.go @@ -3,11 +3,10 @@ package migrator import ( "context" "fmt" + "slices" "strconv" "strings" - "golang.org/x/exp/slices" - "github.com/grafana/grafana/pkg/services/sqlstore/session" "github.com/grafana/grafana/pkg/util/xorm" ) diff --git a/pkg/tsdb/cloud-monitoring/converter/converter.go b/pkg/tsdb/cloud-monitoring/converter/converter.go index 6007d309ed3..94867b51450 100644 --- a/pkg/tsdb/cloud-monitoring/converter/converter.go +++ b/pkg/tsdb/cloud-monitoring/converter/converter.go @@ -3,15 +3,15 @@ package converter import ( "encoding/json" "fmt" + "slices" "strconv" "time" + jsoniter "github.com/json-iterator/go" + "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" sdkjsoniter "github.com/grafana/grafana-plugin-sdk-go/data/utils/jsoniter" - jsoniter "github.com/json-iterator/go" - - "golang.org/x/exp/slices" ) // helpful while debugging all the options that may appear From 113d61c02761f0f5913449e0d771336971e00a32 Mon Sep 17 00:00:00 2001 From: Akhil Singh <35478226+akhilsingh-git@users.noreply.github.com> Date: Thu, 11 Sep 2025 12:37:17 -0700 Subject: [PATCH 07/48] I18n: Prevent Intl.DateTimeFormat crash with invalid locales (#110522) * fix: prevent Intl.DateTimeFormat crash with invalid locales like 'c' - Add locale validation utilities to prevent crashes when LANG=c is set - Filter out invalid locales from navigator.languages before creating DateTimeFormat - Add fallback handling to use browser defaults when all locales are invalid - Fixes issue #110494 where Grafana crashes with 'RangeError: Incorrect locale information provided' - Maintains backward compatibility for valid locales Signed-off-by: Akhil Singh * refactor: simplify locale fix to use direct try-catch approach - Remove locale-utils.ts and locale-utils.test.ts files - Use simple try-catch in dates.ts files: try locale, fallback to 'en-US' - Use Laura's suggested approach in formats.ts with explicit variable declaration - Remove unused utility exports from index.ts - Maintains same functionality with cleaner, simpler code - Avoids adding to public API while still preventing crashes with invalid locales like 'c' Signed-off-by: Akhil Singh * style: run prettier to fix linting issues - Format code according to project prettier configuration - Fixes failing Lint Frontend check Signed-off-by: Akhil Singh --------- Signed-off-by: Akhil Singh --- packages/grafana-data/src/datetime/formats.ts | 8 +++++++- packages/grafana-i18n/src/dates.ts | 6 +++++- public/app/core/internationalization/dates.ts | 6 +++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/grafana-data/src/datetime/formats.ts b/packages/grafana-data/src/datetime/formats.ts index 92b9a99db62..67d0e4e6948 100644 --- a/packages/grafana-data/src/datetime/formats.ts +++ b/packages/grafana-data/src/datetime/formats.ts @@ -105,7 +105,13 @@ export function localTimeFormat( } // https://momentjs.com/docs/#/displaying/format/ - const dateTimeFormat = new Intl.DateTimeFormat(locale || undefined, options); + let dateTimeFormat: Intl.DateTimeFormat; + + try { + dateTimeFormat = new Intl.DateTimeFormat(locale || undefined, options); + } catch { + dateTimeFormat = new Intl.DateTimeFormat('en-US', options); + } const parts = dateTimeFormat.formatToParts(new Date()); const hour12 = dateTimeFormat.resolvedOptions().hour12; diff --git a/packages/grafana-i18n/src/dates.ts b/packages/grafana-i18n/src/dates.ts index c75cd2c86f4..c942226dfba 100644 --- a/packages/grafana-i18n/src/dates.ts +++ b/packages/grafana-i18n/src/dates.ts @@ -11,7 +11,11 @@ function clearMemoizedCache(fn: Memoized) { let regionalFormat: string | undefined; const createDateTimeFormatter = deepMemoize((locale: string | undefined, options: Intl.DateTimeFormatOptions) => { - return new Intl.DateTimeFormat(locale, options); + try { + return new Intl.DateTimeFormat(locale, options); + } catch { + return new Intl.DateTimeFormat('en-US', options); + } }); const createDurationFormatter = deepMemoize((locale: string | undefined, options: Intl.DurationFormatOptions) => { diff --git a/public/app/core/internationalization/dates.ts b/public/app/core/internationalization/dates.ts index 8d1e7467a93..9ef7bbbdb82 100644 --- a/public/app/core/internationalization/dates.ts +++ b/public/app/core/internationalization/dates.ts @@ -9,7 +9,11 @@ const deepMemoize: typeof memoize = (fn) => memoize(fn, { isEqual: deepEqual }); const isLocaleEnabled = config.featureToggles.localeFormatPreference; const createDateTimeFormatter = deepMemoize((locale: string, options: Intl.DateTimeFormatOptions) => { - return new Intl.DateTimeFormat(locale, options); + try { + return new Intl.DateTimeFormat(locale, options); + } catch { + return new Intl.DateTimeFormat('en-US', options); + } }); const createDurationFormatter = deepMemoize((locale: string, options: Intl.DurationFormatOptions) => { From ec0fa444b450882dfc4c1e9f8f1917d0bc7c94ed Mon Sep 17 00:00:00 2001 From: Paul Marbach Date: Thu, 11 Sep 2025 15:42:28 -0400 Subject: [PATCH 08/48] Table: Use higher contrast color for Tooltip from Field chip (#110966) --- packages/grafana-ui/src/components/Table/TableNG/styles.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/grafana-ui/src/components/Table/TableNG/styles.ts b/packages/grafana-ui/src/components/Table/TableNG/styles.ts index 2cc95024d80..feb5e650d90 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/styles.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/styles.ts @@ -228,10 +228,7 @@ export const getTooltipStyles = (theme: GrafanaTheme2, textAlign: TextAlign) => [textAlign === 'right' ? 'right' : 'left']: theme.spacing(0.25), width: theme.spacing(1.75), height: theme.spacing(1.75), - background: caretTriangle(textAlign === 'right' ? 'right' : 'left', theme.colors.border.medium), - '&:hover, &[aria-pressed=true]': { - background: caretTriangle(textAlign === 'right' ? 'right' : 'left', theme.colors.border.strong), - }, + background: caretTriangle(textAlign === 'right' ? 'right' : 'left', theme.colors.border.strong), }), }); From b6567e5abc821d5ed0b9dbad6cd94f695d0bc7ad Mon Sep 17 00:00:00 2001 From: Stephanie Hingtgen Date: Thu, 11 Sep 2025 13:46:00 -0600 Subject: [PATCH 09/48] Folders: Fix deletion in api server (#110984) --- pkg/registry/apis/folders/register.go | 4 ++-- pkg/services/apiserver/options/storage.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/registry/apis/folders/register.go b/pkg/registry/apis/folders/register.go index 0c606990fde..b07ce13b90b 100644 --- a/pkg/registry/apis/folders/register.go +++ b/pkg/registry/apis/folders/register.go @@ -91,13 +91,13 @@ func RegisterAPIService(cfg *setting.Cfg, return builder } -func NewAPIService(ac authlib.AccessClient) *FolderAPIBuilder { +func NewAPIService(ac authlib.AccessClient, searcher resource.ResourceClient) *FolderAPIBuilder { return &FolderAPIBuilder{ authorizer: newMultiTenantAuthorizer(ac), + searcher: searcher, ignoreLegacy: true, } } - func (b *FolderAPIBuilder) GetGroupVersion() schema.GroupVersion { return resourceInfo.GroupVersion() } diff --git a/pkg/services/apiserver/options/storage.go b/pkg/services/apiserver/options/storage.go index f692c40b293..e6979e05ee1 100644 --- a/pkg/services/apiserver/options/storage.go +++ b/pkg/services/apiserver/options/storage.go @@ -98,6 +98,7 @@ func (o *StorageOptions) AddFlags(fs *pflag.FlagSet) { fs.StringVar((*string)(&o.StorageType), "grafana-apiserver-storage-type", string(o.StorageType), "Storage type") fs.StringVar(&o.DataPath, "grafana-apiserver-storage-path", o.DataPath, "Storage path for file storage") fs.StringVar(&o.Address, "grafana-apiserver-storage-address", o.Address, "Remote grpc address endpoint") + fs.StringVar(&o.SearchServerAddress, "grafana-apiserver-search-address", o.SearchServerAddress, "Remote grpc address endpoint for search server") fs.StringVar(&o.GrpcClientAuthenticationToken, "grpc-client-authentication-token", o.GrpcClientAuthenticationToken, "Token for grpc client authentication") fs.StringVar(&o.GrpcClientAuthenticationTokenExchangeURL, "grpc-client-authentication-token-exchange-url", o.GrpcClientAuthenticationTokenExchangeURL, "Token exchange url for grpc client authentication") fs.StringVar(&o.GrpcClientAuthenticationTokenNamespace, "grpc-client-authentication-token-namespace", o.GrpcClientAuthenticationTokenNamespace, "Token namespace for grpc client authentication") From 310893292f3104c507ca653da5e5ab743fef5fe4 Mon Sep 17 00:00:00 2001 From: owensmallwood Date: Thu, 11 Sep 2025 14:12:30 -0600 Subject: [PATCH 10/48] Unified Storage: Add sort order to keys func in datastore (#110714) * Add sort order to keys func in datastore. Add test to not prune deleted events. * include sort field in the ListRequestKey instead of it being a separate param --- pkg/storage/unified/resource/datastore.go | 2 + .../unified/resource/storage_backend.go | 28 +++++--- .../unified/resource/storage_backend_test.go | 70 +++++++++++++++++++ 3 files changed, 90 insertions(+), 10 deletions(-) diff --git a/pkg/storage/unified/resource/datastore.go b/pkg/storage/unified/resource/datastore.go index a3301062048..f939f18f1df 100644 --- a/pkg/storage/unified/resource/datastore.go +++ b/pkg/storage/unified/resource/datastore.go @@ -106,6 +106,7 @@ type ListRequestKey struct { Group string Resource string Name string + Sort SortOrder } func (k ListRequestKey) Validate() error { @@ -194,6 +195,7 @@ func (d *dataStore) Keys(ctx context.Context, key ListRequestKey) iter.Seq2[Data for k, err := range d.kv.Keys(ctx, dataSection, ListOptions{ StartKey: prefix, EndKey: PrefixRangeEnd(prefix), + Sort: key.Sort, }) { if err != nil { yield(DataKey{}, err) diff --git a/pkg/storage/unified/resource/storage_backend.go b/pkg/storage/unified/resource/storage_backend.go index 0408a758b0b..4f5490f7c7d 100644 --- a/pkg/storage/unified/resource/storage_backend.go +++ b/pkg/storage/unified/resource/storage_backend.go @@ -85,25 +85,33 @@ func (k *kvStorageBackend) pruneEvents(ctx context.Context, key PruningKey) erro return fmt.Errorf("invalid pruning key, all fields must be set: %+v", key) } - keepEvents := make([]DataKey, 0, prunerMaxEvents) - + listKey := ListRequestKey{ + Namespace: key.Namespace, + Group: key.Group, + Resource: key.Resource, + Name: key.Name, + Sort: SortOrderDesc, + } + counter := 0 // iterate over all keys for the resource and delete versions beyond the latest 20 - for datakey, err := range k.dataStore.Keys(ctx, ListRequestKey(key)) { + for datakey, err := range k.dataStore.Keys(ctx, listKey) { if err != nil { return err } - if len(keepEvents) < prunerMaxEvents { - keepEvents = append(keepEvents, datakey) + // Pruner needs to exclude deleted events + if counter < prunerMaxEvents && datakey.Action != DataActionDeleted { + counter++ continue } - // If we already have 20 versions, delete the oldest one and append the new one - err := k.dataStore.Delete(ctx, keepEvents[0]) - if err != nil { - return err + // If we already have 20 versions, delete any more create or update events + if datakey.Action != DataActionDeleted { + err := k.dataStore.Delete(ctx, datakey) + if err != nil { + return err + } } - keepEvents = append(keepEvents[1:], datakey) } return nil diff --git a/pkg/storage/unified/resource/storage_backend_test.go b/pkg/storage/unified/resource/storage_backend_test.go index f69a7900cc6..65cd65354d3 100644 --- a/pkg/storage/unified/resource/storage_backend_test.go +++ b/pkg/storage/unified/resource/storage_backend_test.go @@ -1258,6 +1258,7 @@ func TestKvStorageBackend_PruneEvents(t *testing.T) { Group: "apps", Resource: "resources", Name: "test-resource", + Sort: SortOrderDesc, }) { require.NoError(t, err) require.NotEqual(t, rv1, datakey.ResourceVersion) @@ -1324,12 +1325,81 @@ func TestKvStorageBackend_PruneEvents(t *testing.T) { Group: "apps", Resource: "resources", Name: "test-resource", + Sort: SortOrderDesc, }) { require.NoError(t, err) counter++ } require.Equal(t, prunerMaxEvents, counter) }) + + t.Run("will not prune deleted events", func(t *testing.T) { + backend := setupTestStorageBackend(t) + ctx := context.Background() + + // Create a resource + ns := NamespacedResource{ + Namespace: "default", + Group: "apps", + Resource: "resources", + } + testObj, err := createTestObjectWithName("test-resource", ns, "test-data") + require.NoError(t, err) + metaAccessor, err := utils.MetaAccessor(testObj) + require.NoError(t, err) + writeEvent := WriteEvent{ + Type: resourcepb.WatchEvent_DELETED, + Key: &resourcepb.ResourceKey{ + Namespace: "default", + Group: "apps", + Resource: "resources", + Name: "test-resource", + }, + Value: objectToJSONBytes(t, testObj), + Object: metaAccessor, + ObjectOld: metaAccessor, + PreviousRV: 0, + } + rv1, err := backend.WriteEvent(ctx, writeEvent) + require.NoError(t, err) + + // Add prunerMaxEvents+1 deleted events + // Multiple deleted events for a resource shouldn't happen - this is just to ensure the pruner won't remove deleted events + previousRV := rv1 + for i := 0; i < prunerMaxEvents; i++ { + testObj.Object["spec"].(map[string]any)["value"] = fmt.Sprintf("delete-%d", i) + writeEvent.Type = resourcepb.WatchEvent_DELETED + writeEvent.Value = objectToJSONBytes(t, testObj) + writeEvent.PreviousRV = previousRV + newRv, err := backend.WriteEvent(ctx, writeEvent) + require.NoError(t, err) + previousRV = newRv + } + + pruningKey := PruningKey{ + Namespace: "default", + Group: "apps", + Resource: "resources", + Name: "test-resource", + } + + err = backend.pruneEvents(ctx, pruningKey) + require.NoError(t, err) + + // assert all deleted events exist + counter := 0 + for _, err := range backend.dataStore.Keys(ctx, ListRequestKey{ + Namespace: "default", + Group: "apps", + Resource: "resources", + Name: "test-resource", + Sort: SortOrderDesc, + }) { + require.NoError(t, err) + counter++ + } + require.Equal(t, prunerMaxEvents+1, counter) + }) } // createTestObject creates a test unstructured object with standard values From ac13da2d1d55e006333398b3f7214a0b58158f88 Mon Sep 17 00:00:00 2001 From: Mihai Turdean <6640685+mihai-turdean@users.noreply.github.com> Date: Thu, 11 Sep 2025 14:57:07 -0600 Subject: [PATCH 11/48] Use concurrent informer for iam-folder-reconciler (#110987) --- apps/iam/cmd/operator/config.go | 13 ++++++- apps/iam/cmd/operator/main.go | 3 ++ apps/iam/pkg/app/app.go | 38 ++++++++++++++++++- .../iam/zanzana_folder_reconciler.go | 2 + 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/apps/iam/cmd/operator/config.go b/apps/iam/cmd/operator/config.go index 2784c961a3e..f5481dfb9bd 100644 --- a/apps/iam/cmd/operator/config.go +++ b/apps/iam/cmd/operator/config.go @@ -31,7 +31,8 @@ type WebhookServerConfig struct { } type FolderReconcilerConfig struct { - Namespace string + Namespace string + MaxConcurrentWorkers uint64 } func LoadConfigFromEnv() (*Config, error) { @@ -115,6 +116,16 @@ func LoadConfigFromEnv() (*Config, error) { cfg.ZanzanaClient.ServerCertFile = os.Getenv("ZANZANA_SERVER_CERT_FILE") cfg.FolderReconciler.Namespace = os.Getenv("FOLDER_RECONCILER_NAMESPACE") + maxConcurrentWorkersStr := os.Getenv("FOLDER_RECONCILER_MAX_CONCURRENT_WORKERS") + if maxConcurrentWorkersStr == "" { + cfg.FolderReconciler.MaxConcurrentWorkers = 20 + } else { + maxConcurrentWorkers, err := strconv.ParseUint(maxConcurrentWorkersStr, 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid FOLDER_RECONCILER_MAX_CONCURRENT_WORKERS '%s': %w", maxConcurrentWorkersStr, err) + } + cfg.FolderReconciler.MaxConcurrentWorkers = maxConcurrentWorkers + } return &cfg, nil } diff --git a/apps/iam/cmd/operator/main.go b/apps/iam/cmd/operator/main.go index 786673a8665..79cfa6fc1a4 100644 --- a/apps/iam/cmd/operator/main.go +++ b/apps/iam/cmd/operator/main.go @@ -69,6 +69,9 @@ func main() { appCfg := app.AppConfig{ ZanzanaClientCfg: cfg.ZanzanaClient, FolderReconcilerNamespace: cfg.FolderReconciler.Namespace, + InformerConfig: app.InformerConfig{ + MaxConcurrentWorkers: cfg.FolderReconciler.MaxConcurrentWorkers, + }, } // Run diff --git a/apps/iam/pkg/app/app.go b/apps/iam/pkg/app/app.go index 1a1ddca4e92..d8c00c5faab 100644 --- a/apps/iam/pkg/app/app.go +++ b/apps/iam/pkg/app/app.go @@ -6,6 +6,8 @@ import ( "github.com/grafana/grafana-app-sdk/app" "github.com/grafana/grafana-app-sdk/logging" + "github.com/grafana/grafana-app-sdk/operator" + "github.com/grafana/grafana-app-sdk/resource" "github.com/grafana/grafana-app-sdk/simple" foldersKind "github.com/grafana/grafana/apps/folder/pkg/apis/folder/v1beta1" "github.com/grafana/grafana/apps/iam/pkg/reconcilers" @@ -17,8 +19,13 @@ var appManifestData = app.ManifestData{ Group: "iam.grafana.app", } +type InformerConfig struct { + MaxConcurrentWorkers uint64 +} + type AppConfig struct { ZanzanaClientCfg authz.ZanzanaClientConfig + InformerConfig InformerConfig FolderReconcilerNamespace string } @@ -26,6 +33,35 @@ func Provider(appCfg app.SpecificConfig) app.Provider { return simple.NewAppProvider(app.NewEmbeddedManifest(appManifestData), appCfg, New) } +func generateInformerSupplier(informerConfig InformerConfig) simple.InformerSupplier { + return func(kind resource.Kind, clients resource.ClientGenerator, options operator.ListWatchOptions) (operator.Informer, error) { + client, err := clients.ClientFor(kind) + if err != nil { + return nil, err + } + + informer, err := operator.NewKubernetesBasedInformer( + kind, client, + operator.KubernetesBasedInformerOptions{ + ListWatchOptions: options, + }, + ) + if err != nil { + return nil, err + } + + return operator.NewConcurrentInformer( + informer, + operator.ConcurrentInformerOptions{ + MaxConcurrentWorkers: informerConfig.MaxConcurrentWorkers, + ErrorHandler: func(ctx context.Context, err error) { + logging.FromContext(ctx).With("error", err).Error("ConcurrentInformer processing error") + }, + }, + ) + } +} + func New(cfg app.Config) (app.App, error) { appSpecificConfig, ok := cfg.SpecificConfig.(AppConfig) if !ok { @@ -53,8 +89,8 @@ func New(cfg app.Config) (app.App, error) { Name: cfg.ManifestData.AppName, KubeConfig: cfg.KubeConfig, InformerConfig: simple.AppInformerConfig{ + InformerSupplier: generateInformerSupplier(appSpecificConfig.InformerConfig), ErrorHandler: func(ctx context.Context, err error) { - // FIXME: add your own error handling here logging.FromContext(ctx).With("error", err).Error("Informer processing error") }, }, diff --git a/pkg/operators/iam/zanzana_folder_reconciler.go b/pkg/operators/iam/zanzana_folder_reconciler.go index 68974df7c92..ca0cc38e736 100644 --- a/pkg/operators/iam/zanzana_folder_reconciler.go +++ b/pkg/operators/iam/zanzana_folder_reconciler.go @@ -106,6 +106,8 @@ func buildIAMConfigFromSettings(cfg *setting.Cfg) (*iamConfig, error) { } iamCfg.AppConfig.ZanzanaClientCfg.URL = zanzanaURL + iamCfg.AppConfig.InformerConfig.MaxConcurrentWorkers = operatorSec.Key("max_concurrent_workers").MustUint64(20) + folderAppURL := operatorSec.Key("folder_app_url").MustString("") if folderAppURL == "" { return nil, fmt.Errorf("folder_app_url is required in [operator] section") From 55b7b4fade0dc8b04e2858db3cea191d413a4de3 Mon Sep 17 00:00:00 2001 From: "alerting-team[bot]" <158350966+alerting-team[bot]@users.noreply.github.com> Date: Thu, 11 Sep 2025 21:27:22 +0000 Subject: [PATCH 12/48] Alerting: Update alerting module to 2b26ef8f17eb91ce179a51dde6d86839a680e1b4 (#110975) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [create-pull-request] automated change * update Alertmanager fork --------- Co-authored-by: santihernandezc <41638679+santihernandezc@users.noreply.github.com> Co-authored-by: Santiago Hernández Co-authored-by: Yuri Tseretyan --- go.mod | 7 +++---- go.sum | 8 ++++---- go.work | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 73c2d153ed8..27556b64a3d 100644 --- a/go.mod +++ b/go.mod @@ -86,7 +86,7 @@ require ( github.com/googleapis/gax-go/v2 v2.14.2 // @grafana/grafana-backend-group github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // @grafana/grafana-app-platform-squad - github.com/grafana/alerting v0.0.0-20250903205312-24567882c5d1 // @grafana/alerting-backend + github.com/grafana/alerting v0.0.0-20250911172908-2b26ef8f17eb // @grafana/alerting-backend github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 // @grafana/identity-access-team github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 // @grafana/identity-access-team github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics @@ -653,9 +653,8 @@ require ( // 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.20240917091248-ae3bbdad8a56 -// 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.20250821192752-903ba9e90238 +// Use our fork of the upstream Alertmanager. +replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604 exclude github.com/mattn/go-sqlite3 v2.0.3+incompatible diff --git a/go.sum b/go.sum index 806c79cc1a3..883b100df76 100644 --- a/go.sum +++ b/go.sum @@ -1590,8 +1590,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/grafana/alerting v0.0.0-20250903205312-24567882c5d1 h1:1Xjk9zr9P4jeRsdHlWkQPiByd16YEEeTVqkwn8i6iMQ= -github.com/grafana/alerting v0.0.0-20250903205312-24567882c5d1/go.mod h1:EfKE30jNw2b4whbJjtgea3JXUfUSVadmVSL/IAGgJeQ= +github.com/grafana/alerting v0.0.0-20250911172908-2b26ef8f17eb h1:g/gbEJoncYghiojMM6OwWJi1P+SC/mnjBG+E422p48o= +github.com/grafana/alerting v0.0.0-20250911172908-2b26ef8f17eb/go.mod h1:XWqj/rlsy4OV/E9XNNyFn+a7U4GNsSugPb2rDBj9+58= github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 h1:vVPT0i5Y1vI6qzecYStV2yk7cHKrC3Pc7AgvwT5KydQ= github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43/go.mod h1:1fWkOiL+m32NBgRHZtlZGz2ji868tPZACYbqP3nBRJI= github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 h1:NlkGMnVi/oUn6Cr90QbJYpQJ4FnjyAIG9Ex5GtTZIzw= @@ -1640,8 +1640,8 @@ github.com/grafana/nanogit v0.0.0-20250723104447-68f58f5ecec0 h1:cS0SlJGIlZbmDLc github.com/grafana/nanogit v0.0.0-20250723104447-68f58f5ecec0/go.mod h1:ToqLjIdvV3AZQa3K6e5m9hy/nsGaUByc2dWQlctB9iA= github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls= -github.com/grafana/prometheus-alertmanager v0.25.1-0.20250821192752-903ba9e90238 h1:0UYzSzpVFKCc4OhVB8dZai3lO0ANg7IIdSZhMiBhdOg= -github.com/grafana/prometheus-alertmanager v0.25.1-0.20250821192752-903ba9e90238/go.mod h1:O/QP1BCm0HHIzbKvgMzqb5sSyH88rzkFk84F4TfJjBU= +github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604 h1:aXfUhVN/Ewfpbko2CCtL65cIiGgwStOo4lWH2b6gw2U= +github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604/go.mod h1:O/QP1BCm0HHIzbKvgMzqb5sSyH88rzkFk84F4TfJjBU= github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/pyroscope/api v1.2.1-0.20250415190842-3ff7247547ae h1:35W3Wjp9KWnSoV/DuymmyIj5aHE0CYlDQ5m2KeXUPAc= diff --git a/go.work b/go.work index 70c91d135c6..eb1e142b168 100644 --- a/go.work +++ b/go.work @@ -30,6 +30,6 @@ use ( ./pkg/semconv ) -replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20250620093340-be61a673dee6 +replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604 replace github.com/crewjam/saml => github.com/grafana/saml v0.4.15-0.20240917091248-ae3bbdad8a56 From d20ade0c2acc34e371f5d3e6932f900d7db894c9 Mon Sep 17 00:00:00 2001 From: Stephanie Hingtgen Date: Thu, 11 Sep 2025 16:25:19 -0600 Subject: [PATCH 13/48] Provisioning: Fix settings panic (#110993) --- pkg/registry/apis/provisioning/routes.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/registry/apis/provisioning/routes.go b/pkg/registry/apis/provisioning/routes.go index dd063f0fe0e..724e23de1c9 100644 --- a/pkg/registry/apis/provisioning/routes.go +++ b/pkg/registry/apis/provisioning/routes.go @@ -156,10 +156,15 @@ func (b *APIBuilder) handleSettings(w http.ResponseWriter, r *http.Request) { return } + legacyStorage := false + if b.storageStatus != nil { + legacyStorage = dualwrite.IsReadingLegacyDashboardsAndFolders(ctx, b.storageStatus) + } + settings := provisioning.RepositoryViewList{ Items: make([]provisioning.RepositoryView, len(all)), // FIXME: this shouldn't be here in provisioning but at the dual writer or something about the storage - LegacyStorage: dualwrite.IsReadingLegacyDashboardsAndFolders(ctx, b.storageStatus), + LegacyStorage: legacyStorage, AvailableRepositoryTypes: b.repoFactory.Types(), } From a676dc6638897cac5497f785e54711759cca648e Mon Sep 17 00:00:00 2001 From: Stephanie Hingtgen Date: Thu, 11 Sep 2025 16:36:25 -0600 Subject: [PATCH 14/48] Stats: Add repository stats (#110989) --- pkg/infra/metrics/metrics.go | 10 +++ .../statscollector/concurrent_users_test.go | 15 ++++- .../usagestats/statscollector/service.go | 2 + pkg/server/wire_gen.go | 4 +- pkg/services/stats/models.go | 1 + pkg/services/stats/statsimpl/stats.go | 62 +++++++++++++++---- pkg/services/stats/statsimpl/stats_test.go | 28 +++++++-- 7 files changed, 100 insertions(+), 22 deletions(-) diff --git a/pkg/infra/metrics/metrics.go b/pkg/infra/metrics/metrics.go index 4230cf784b8..a8af3153d4c 100644 --- a/pkg/infra/metrics/metrics.go +++ b/pkg/infra/metrics/metrics.go @@ -213,6 +213,9 @@ var ( // MStatTotalCorrelations is a metric total amount of correlations MStatTotalCorrelations prometheus.Gauge + + // MStatTotalRepositories is a metric total amount of repositories + MStatTotalRepositories prometheus.Gauge ) const ( @@ -658,6 +661,12 @@ func init() { Help: "total amount of correlations", Namespace: ExporterName, }) + + MStatTotalRepositories = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "stat_totals_repositories", + Help: "total amount of repositories", + Namespace: ExporterName, + }) } // SetBuildInformation sets the build information for this binary @@ -778,6 +787,7 @@ func initMetricVars(reg prometheus.Registerer) { MPublicDashboardRequestCount, MPublicDashboardDatasourceQuerySuccess, MStatTotalCorrelations, + MStatTotalRepositories, MFolderIDsAPICount, MFolderIDsServiceCount, ) diff --git a/pkg/infra/usagestats/statscollector/concurrent_users_test.go b/pkg/infra/usagestats/statscollector/concurrent_users_test.go index 1acf9767441..8b8145a1fb8 100644 --- a/pkg/infra/usagestats/statscollector/concurrent_users_test.go +++ b/pkg/infra/usagestats/statscollector/concurrent_users_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/infra/db" @@ -18,6 +19,8 @@ import ( "github.com/grafana/grafana/pkg/services/org/orgtest" "github.com/grafana/grafana/pkg/services/stats/statsimpl" "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/storage/unified/resource" + "github.com/grafana/grafana/pkg/storage/unified/resourcepb" "github.com/grafana/grafana/pkg/tests/testsuite" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util/testutil" @@ -32,7 +35,11 @@ func TestIntegrationConcurrentUsersMetrics(t *testing.T) { testutil.SkipIntegrationTestInShortMode(t) sqlStore, cfg := db.InitTestDBWithCfg(t) - statsService := statsimpl.ProvideService(&setting.Cfg{}, sqlStore, &dashboards.FakeDashboardService{}, &foldertest.FakeService{}, &orgtest.FakeOrgService{}, featuremgmt.WithFeatures()) + unifiedStorage := new(resource.MockResourceClient) + unifiedStorage.On("GetStats", mock.Anything, mock.Anything).Return(&resourcepb.ResourceStatsResponse{ + Stats: []*resourcepb.ResourceStatsResponse_Stats{{Count: 0}}, + }, nil) + statsService := statsimpl.ProvideService(&setting.Cfg{}, sqlStore, &dashboards.FakeDashboardService{}, &foldertest.FakeService{}, &orgtest.FakeOrgService{}, unifiedStorage, featuremgmt.WithFeatures()) s := createService(t, cfg, sqlStore, statsService) createConcurrentTokens(t, sqlStore) @@ -52,7 +59,11 @@ func TestIntegrationConcurrentUsersStats(t *testing.T) { testutil.SkipIntegrationTestInShortMode(t) sqlStore, cfg := db.InitTestDBWithCfg(t) - statsService := statsimpl.ProvideService(&setting.Cfg{}, sqlStore, &dashboards.FakeDashboardService{}, &foldertest.FakeService{}, &orgtest.FakeOrgService{}, featuremgmt.WithFeatures()) + unifiedStorage := new(resource.MockResourceClient) + unifiedStorage.On("GetStats", mock.Anything, mock.Anything).Return(&resourcepb.ResourceStatsResponse{ + Stats: []*resourcepb.ResourceStatsResponse_Stats{{Count: 0}}, + }, nil) + statsService := statsimpl.ProvideService(&setting.Cfg{}, sqlStore, &dashboards.FakeDashboardService{}, &foldertest.FakeService{}, &orgtest.FakeOrgService{}, unifiedStorage, featuremgmt.WithFeatures()) s := createService(t, cfg, sqlStore, statsService) createConcurrentTokens(t, sqlStore) diff --git a/pkg/infra/usagestats/statscollector/service.go b/pkg/infra/usagestats/statscollector/service.go index 832a5d15d8d..1fdbad2482e 100644 --- a/pkg/infra/usagestats/statscollector/service.go +++ b/pkg/infra/usagestats/statscollector/service.go @@ -190,6 +190,7 @@ func (s *Service) collectSystemStats(ctx context.Context) (map[string]any, error m["stats.active_data_keys.count"] = statsResult.ActiveDataKeys m["stats.public_dashboards.count"] = statsResult.PublicDashboards m["stats.correlations.count"] = statsResult.Correlations + m["stats.repositories.count"] = statsResult.Repositories if statsResult.DatabaseCreatedTime != nil { m["stats.database.created.time"] = statsResult.DatabaseCreatedTime.Unix() } @@ -351,6 +352,7 @@ func (s *Service) updateTotalStats(ctx context.Context) bool { metrics.MStatTotalPublicDashboards.Set(float64(statsResult.PublicDashboards)) metrics.MStatTotalCorrelations.Set(float64(statsResult.Correlations)) + metrics.MStatTotalRepositories.Set(float64(statsResult.Repositories)) s.usageStats.SetReadyToReport(ctx) diff --git a/pkg/server/wire_gen.go b/pkg/server/wire_gen.go index 08ffe116470..ff6274fe9d7 100644 --- a/pkg/server/wire_gen.go +++ b/pkg/server/wire_gen.go @@ -700,7 +700,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api authnService := authnimpl.ProvideAuthnService(authnimplService) navtreeService := navtreeimpl.ProvideService(cfg, accessControl, pluginstoreService, service13, starService, featureToggles, dashboardService, acimplService, kvStore, apikeyService, ossLicensingService, authnService) searchHTTPService := searchV2.ProvideSearchHTTPService(searchService) - statsService := statsimpl.ProvideService(cfg, sqlStore, dashboardService, folderimplService, orgService, featureToggles) + statsService := statsimpl.ProvideService(cfg, sqlStore, dashboardService, folderimplService, orgService, resourceClient, featureToggles) gatherer := metrics.ProvideGatherer() apiAPI := api3.ProvideApi(starService, dashboardService) anonUserLimitValidatorImpl := validator2.ProvideAnonUserLimitValidator() @@ -1293,7 +1293,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac authnService := authnimpl.ProvideAuthnService(authnimplService) navtreeService := navtreeimpl.ProvideService(cfg, accessControl, pluginstoreService, service13, starService, featureToggles, dashboardService, acimplService, kvStore, apikeyService, ossLicensingService, authnService) searchHTTPService := searchV2.ProvideSearchHTTPService(searchService) - statsService := statsimpl.ProvideService(cfg, sqlStore, dashboardService, folderimplService, orgService, featureToggles) + statsService := statsimpl.ProvideService(cfg, sqlStore, dashboardService, folderimplService, orgService, resourceClient, featureToggles) gatherer := metrics.ProvideGathererForTest(registerer) apiAPI := api3.ProvideApi(starService, dashboardService) anonUserLimitValidatorImpl := validator2.ProvideAnonUserLimitValidator() diff --git a/pkg/services/stats/models.go b/pkg/services/stats/models.go index bf1531d95c2..25f8854f945 100644 --- a/pkg/services/stats/models.go +++ b/pkg/services/stats/models.go @@ -49,6 +49,7 @@ type SystemStats struct { PublicDashboards int64 Correlations int64 DatabaseCreatedTime *time.Time + Repositories int64 // name of the driver DatabaseDriver string diff --git a/pkg/services/stats/statsimpl/stats.go b/pkg/services/stats/statsimpl/stats.go index 6399fc8b771..a48da197fc2 100644 --- a/pkg/services/stats/statsimpl/stats.go +++ b/pkg/services/stats/statsimpl/stats.go @@ -6,8 +6,10 @@ import ( "strconv" "time" + provisioningv1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/infra/db" + "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" @@ -16,29 +18,37 @@ import ( "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/services/stats" "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/storage/unified/resource" + "github.com/grafana/grafana/pkg/storage/unified/resourcepb" ) const activeUserTimeLimit = time.Hour * 24 * 30 const dailyActiveUserTimeLimit = time.Hour * 24 -func ProvideService(cfg *setting.Cfg, db db.DB, dashSvc dashboards.DashboardService, folderSvc folder.Service, orgSvc org.Service, features featuremgmt.FeatureToggles) stats.Service { +func ProvideService(cfg *setting.Cfg, db db.DB, dashSvc dashboards.DashboardService, folderSvc folder.Service, + orgSvc org.Service, unifiedStorage resource.ResourceClient, features featuremgmt.FeatureToggles) stats.Service { + namespacer := request.GetNamespaceMapper(cfg) return &sqlStatsService{ - cfg: cfg, - db: db, - folderSvc: folderSvc, - dashSvc: dashSvc, - orgSvc: orgSvc, - features: features, + cfg: cfg, + db: db, + folderSvc: folderSvc, + namespacer: namespacer, + unifiedStorage: unifiedStorage, + dashSvc: dashSvc, + orgSvc: orgSvc, + features: features, } } type sqlStatsService struct { - db db.DB - cfg *setting.Cfg - dashSvc dashboards.DashboardService - features featuremgmt.FeatureToggles - folderSvc folder.Service - orgSvc org.Service + db db.DB + cfg *setting.Cfg + dashSvc dashboards.DashboardService + features featuremgmt.FeatureToggles + folderSvc folder.Service + orgSvc org.Service + namespacer request.NamespaceMapper + unifiedStorage resource.ResourceClient } func (ss *sqlStatsService) getDashboardCount(ctx context.Context, orgs []*org.OrgDTO) (int64, error) { @@ -83,6 +93,26 @@ func (ss *sqlStatsService) getFolderCount(ctx context.Context, orgs []*org.OrgDT return total, nil } +func (ss *sqlStatsService) getRepositoryCount(ctx context.Context, orgs []*org.OrgDTO) (int64, error) { + total := int64(0) + for _, org := range orgs { + ctx, _ = identity.WithServiceIdentity(ctx, org.ID) + resp, err := ss.unifiedStorage.GetStats(ctx, &resourcepb.ResourceStatsRequest{ + Namespace: ss.namespacer(org.ID), + Kinds: []string{ + provisioningv1.GROUP + "/" + provisioningv1.RepositoryResourceInfo.GroupResource().Resource, + }, + }) + if err != nil { + return 0, err + } + if len(resp.Stats) != 0 { + total += resp.Stats[0].Count + } + } + return total, nil +} + func (ss *sqlStatsService) GetAlertNotifiersUsageStats(ctx context.Context, query *stats.GetAlertNotifierUsageStatsQuery) (result []*stats.NotifierUsageStats, err error) { err = ss.db.WithDbSession(ctx, func(dbSession *db.Session) error { var rawSQL = `SELECT COUNT(*) AS count, type FROM ` + ss.db.GetDialect().Quote("alert_notification") + ` GROUP BY type` @@ -196,6 +226,12 @@ func (ss *sqlStatsService) GetSystemStats(ctx context.Context, query *stats.GetS } result.Folders = folderCount + repositoryCount, err := ss.getRepositoryCount(ctx, orgs) + if err != nil { + return result, err + } + result.Repositories = repositoryCount + return result, err } diff --git a/pkg/services/stats/statsimpl/stats_test.go b/pkg/services/stats/statsimpl/stats_test.go index f70daa89699..53b5d50e872 100644 --- a/pkg/services/stats/statsimpl/stats_test.go +++ b/pkg/services/stats/statsimpl/stats_test.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/tracing" + "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" "github.com/grafana/grafana/pkg/services/correlations" "github.com/grafana/grafana/pkg/services/correlations/correlationstest" "github.com/grafana/grafana/pkg/services/dashboards" @@ -26,6 +27,8 @@ import ( "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/storage/unified/resource" + "github.com/grafana/grafana/pkg/storage/unified/resourcepb" "github.com/grafana/grafana/pkg/tests/testsuite" "github.com/grafana/grafana/pkg/util/testutil" ) @@ -49,13 +52,19 @@ func TestIntegrationStatsDataAccess(t *testing.T) { folderService := &foldertest.FakeService{} folderService.ExpectedFolders = []*folder.Folder{{ID: 1}, {ID: 2}, {ID: 3}} + unifiedStorage := new(resource.MockResourceClient) + unifiedStorage.On("GetStats", mock.Anything, mock.Anything).Return(&resourcepb.ResourceStatsResponse{ + Stats: []*resourcepb.ResourceStatsResponse_Stats{{Count: 5}}, + }, nil) statsService := &sqlStatsService{ - db: db, - dashSvc: dashSvc, - orgSvc: orgSvc, - folderSvc: folderService, - features: featuremgmt.WithFeatures(), + db: db, + dashSvc: dashSvc, + orgSvc: orgSvc, + folderSvc: folderService, + features: featuremgmt.WithFeatures(), + namespacer: request.GetNamespaceMapper(cfg), + unifiedStorage: unifiedStorage, } t.Run("Get system stats should not results in error", func(t *testing.T) { @@ -109,6 +118,15 @@ func TestIntegrationStatsDataAccess(t *testing.T) { assert.Equal(t, int64(3), stats.Dashboards) assert.Equal(t, int64(3), stats.Orgs) }) + + t.Run("Get repository count", func(t *testing.T) { + orgs := []*org.OrgDTO{ + {ID: 1}, {ID: 2}, {ID: 3}, + } + count, err := statsService.getRepositoryCount(context.Background(), orgs) + require.NoError(t, err) + assert.Equal(t, int64(15), count) + }) } func populateDB(t *testing.T, db db.DB, cfg *setting.Cfg) org.Service { From b8fe82432fd41538bed85788c0fabb68df73dacc Mon Sep 17 00:00:00 2001 From: "grafana-pr-automation[bot]" <140550294+grafana-pr-automation[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 00:37:25 +0000 Subject: [PATCH 15/48] I18n: Download translations from Crowdin (#110998) New Crowdin translations by GitHub Action Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- public/locales/cs-CZ/grafana.json | 27 ++++++++++++++++++++------- public/locales/de-DE/grafana.json | 21 ++++++++++++++------- public/locales/es-ES/grafana.json | 21 ++++++++++++++------- public/locales/fr-FR/grafana.json | 21 ++++++++++++++------- public/locales/hu-HU/grafana.json | 21 ++++++++++++++------- public/locales/id-ID/grafana.json | 18 +++++++++++------- public/locales/it-IT/grafana.json | 21 ++++++++++++++------- public/locales/ja-JP/grafana.json | 18 +++++++++++------- public/locales/ko-KR/grafana.json | 18 +++++++++++------- public/locales/nl-NL/grafana.json | 21 ++++++++++++++------- public/locales/pl-PL/grafana.json | 27 ++++++++++++++++++++------- public/locales/pt-BR/grafana.json | 21 ++++++++++++++------- public/locales/pt-PT/grafana.json | 21 ++++++++++++++------- public/locales/ru-RU/grafana.json | 27 ++++++++++++++++++++------- public/locales/sv-SE/grafana.json | 21 ++++++++++++++------- public/locales/tr-TR/grafana.json | 21 ++++++++++++++------- public/locales/zh-Hans/grafana.json | 18 +++++++++++------- public/locales/zh-Hant/grafana.json | 18 +++++++++++------- 18 files changed, 255 insertions(+), 126 deletions(-) diff --git a/public/locales/cs-CZ/grafana.json b/public/locales/cs-CZ/grafana.json index ba90e568345..78326412626 100644 --- a/public/locales/cs-CZ/grafana.json +++ b/public/locales/cs-CZ/grafana.json @@ -2072,9 +2072,6 @@ "text-loading-rules": "Načítání pravidel…", "title-dashboard-not-saved": "Nástěnka není uložena" }, - "paused-badge": { - "paused": "Pozastaveno" - }, "payload-editor": { "edit-payload": "Upravit datový obsah", "label-add-custom-alert-instance": "Přidat vlastní instanci výstrahy", @@ -2231,9 +2228,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min. Interval = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "Od <0>{{from}} doteď" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Vybrané dotazy a výrazy nelze převést na výchozí. Pokud deaktivujete pokročilé možnosti, váš dotaz a podmínka budou obnoveny do výchozího nastavení." @@ -2587,6 +2581,10 @@ "error_many": "Počet chyb: {{count}}", "error_other": "Počet chyb: {{count}}" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Pokud nemáte zdroj dat Mimir, Loki nebo Cortex s povoleným rozhraním API pravidla, vyberte možnost „Spravováno Grafanou“." }, @@ -3699,7 +3697,19 @@ "text": "Nebyly nalezeny žádné výsledky pro váš dotaz" }, "restore": { - "success": "Nástěnka {{name}} byla obnovena" + "success": "", + "all-failed_one": "", + "all-failed_few": "", + "all-failed_many": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_few": "", + "failed-count_many": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_few": "", + "success-count_many": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Pokud máte přímý přístup k cíli, zkopírujte JSON a vložte ho tam.", "trash-state-manager": { @@ -11721,6 +11731,7 @@ "tooltip-unhealthy-repository": "Nelze stáhnout nezdravé úložiště" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Zahrnout předložení pro každou historickou hodnotu", "synchronization-options": "Možnosti synchronizace" }, @@ -11744,6 +11755,8 @@ "alert-point-3": "Doba trvání tohoto procesu závisí na počtu zapojených zdrojů.", "alert-point-4": "Správci podnikových instancí mohou uživatelům zobrazit banner oznámení. Podrobné pokyny najdete v <2>této příručce.", "alert-title": "Důležité: Nebudou ztracena žádná data ani konfigurace, ale nástěnky budou na několik minut dočasně nedostupné.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Dokončit", "button-start": "Zahájit synchronizaci", "discard-modal": { diff --git a/public/locales/de-DE/grafana.json b/public/locales/de-DE/grafana.json index 4de94ddd70b..75c5062dcf8 100644 --- a/public/locales/de-DE/grafana.json +++ b/public/locales/de-DE/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Regeln werden geladen …", "title-dashboard-not-saved": "Dashboard nicht gespeichert" }, - "paused-badge": { - "paused": "Pausiert" - }, "payload-editor": { "edit-payload": "Payload bearbeiten", "label-add-custom-alert-instance": "Benutzerdefinierte Warnungsinstanz hinzufügen", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Mind. Intervall = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} bis jetzt" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Die ausgewählten Abfragen und Ausdrücke können nicht in die Standardeinstellung konvertiert werden. Wenn Sie die erweiterten Optionen deaktivieren, werden Ihre Abfrage und Bedingung auf die Standardeinstellungen zurückgesetzt." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} Fehler", "error_other": "{{count}} Fehler" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Wählen Sie “Grafana managed”, es sei denn, Sie verfügen über eine Mimir-, Loki- oder Cortex-Datenquelle mit aktivierter Ruler-API." }, @@ -3663,7 +3661,13 @@ "text": "Keine Ergebnisse für deine Abfrage gefunden" }, "restore": { - "success": "Dashboard {{name}} wiederhergestellt" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Wenn Sie direkten Zugriff auf das Ziel haben, kopieren Sie den JSON und fügen Sie ihn dort ein.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "Ein fehlerhaftes Repository kann nicht abgerufen werden" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Commits für jeden historischen Wert erfassen", "synchronization-options": "Synchronisierungsoptionen" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "Die Dauer dieses Prozesses hängt von der Anzahl der betroffenen Ressourcen ab.", "alert-point-4": "Administratoren von Enterprise-Instanzen können Nutzern gegenüber ein Ankündigungsbanner anzeigen. Schritt-für-Schritt-Anweisungen finden Sie in <2>dieser Anleitung.", "alert-title": "Wichtig: Es gehen keine Daten oder Konfigurationen verloren, aber die Dashboards sind für einige Minuten vorübergehend nicht verfügbar.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Fertigstellen", "button-start": "Synchronisierung starten", "discard-modal": { diff --git a/public/locales/es-ES/grafana.json b/public/locales/es-ES/grafana.json index c5e17d56321..7f10dcdd53c 100644 --- a/public/locales/es-ES/grafana.json +++ b/public/locales/es-ES/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Cargando reglas...", "title-dashboard-not-saved": "Dashboard no guardado" }, - "paused-badge": { - "paused": "En pausa" - }, "payload-editor": { "edit-payload": "Editar carga útil", "label-add-custom-alert-instance": "Añadir instancia de alerta personalizada", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Tamaño min. Intervalo = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} hasta ahora" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Las consultas y expresiones seleccionadas no se pueden convertir a predeterminadas. Si desactivas las opciones avanzadas, tu consulta y condición se restablecerán a la configuración predeterminada." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} errores", "error_other": "{{count}} errores" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Selecciona «Gestionadas por Grafana» a menos que tengas una fuente de datos Mimir, Loki o Cortex con la API de Ruler habilitada." }, @@ -3663,7 +3661,13 @@ "text": "No se han encontrado resultados para tu consulta" }, "restore": { - "success": "Dashboard {{name}} restaurado" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Si tienes acceso directo al destino, copia el JSON y pégalo allí.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "No se puede extraer un repositorio que no está en buen estado" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Incluir confirmaciones para cada valor histórico", "synchronization-options": "Opciones de sincronización" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "La duración de este proceso depende del número de recursos involucrados.", "alert-point-4": "Los administradores de instancias empresariales pueden mostrar un báner de anuncio a los usuarios. Consulta <2>esta guía para obtener instrucciones paso a paso.", "alert-title": "Importante: No se perderán datos ni configuraciones, pero los dashboards no estarán disponibles temporalmente durante unos minutos.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Terminar", "button-start": "Iniciar la sincronización", "discard-modal": { diff --git a/public/locales/fr-FR/grafana.json b/public/locales/fr-FR/grafana.json index e8e10936455..eec2d831c88 100644 --- a/public/locales/fr-FR/grafana.json +++ b/public/locales/fr-FR/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Chargement des règles...", "title-dashboard-not-saved": "Tableau de bord non enregistré" }, - "paused-badge": { - "paused": "En pause" - }, "payload-editor": { "edit-payload": "Modifier la charge utile", "label-add-custom-alert-instance": "Ajouter une instance d’alerte personnalisée", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min. Intervalle = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} à maintenant" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Les requêtes et expressions sélectionnées ne peuvent pas être converties en valeurs par défaut. Si vous désactivez les options avancées, votre requête et votre condition seront réinitialisées aux valeurs par défaut." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} erreurs", "error_other": "{{count}} erreurs" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Sélectionnez « Grafana géré » à moins que vous n’ayez une source de données Mimir, Loki ou Cortex avec l’API Ruler activée." }, @@ -3663,7 +3661,13 @@ "text": "Aucun résultat n'a été trouvé pour votre requête" }, "restore": { - "success": "Tableau de bord {{name}} restauré" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Si vous avez un accès direct à la cible, copiez le JSON et collez-le à cet endroit.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "Impossible de fusionner un référentiel en mauvais état" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Inclure les commits pour chaque valeur historique", "synchronization-options": "Options de synchronisation" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "La durée de ce processus dépend du nombre de ressources impliquées.", "alert-point-4": "Les administrateurs d’instances d’entreprise peuvent afficher une bannière d’annonce aux utilisateurs. Consultez <2>ce guide pour obtenir des instructions étape par étape.", "alert-title": "Important : aucune donnée ou configuration ne sera perdue, mais les tableaux de bord seront temporairement indisponibles pendant quelques minutes.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Terminer", "button-start": "Commencer la synchronisation", "discard-modal": { diff --git a/public/locales/hu-HU/grafana.json b/public/locales/hu-HU/grafana.json index edafa6664b5..bfdb13e2708 100644 --- a/public/locales/hu-HU/grafana.json +++ b/public/locales/hu-HU/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Szabályok betöltése…", "title-dashboard-not-saved": "Az irányítópult nincs mentve" }, - "paused-badge": { - "paused": "Szüneteltetett" - }, "payload-editor": { "edit-payload": "Hasznos tartalom szerkesztése", "label-add-custom-alert-instance": "Egyéni riasztási példány hozzáadása", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min. intervallum = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} és a jelen között" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "A kijelölt lekérdezések és kifejezések nem konvertálhatók alapértelmezettre. Ha kikapcsolja a speciális beállításokat, a lekérdezés és a feltétel visszaáll az alapértelmezett beállításokra." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} hiba", "error_other": "{{count}} hiba" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Válassza a „Grafana által felügyelt” lehetőséget, kivéve, ha Mimir-, Loki- vagy Cortex-adatforrása van engedélyezett Ruler API-val." }, @@ -3663,7 +3661,13 @@ "text": "Nincs találat a lekérdezésre" }, "restore": { - "success": "{{name}} irányítópult visszaállítva" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Ha közvetlen hozzáférése van a célhoz, másolja ki a JSON-kódot, és illessze be oda.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "Nem lehet beolvasni egy nem megfelelő állapotú adattárat" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Változtatások belefoglalása minden előzményértékhez", "synchronization-options": "Szinkronizálási beállítások" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "A folyamat időtartama az érintett erőforrások számától függ.", "alert-point-4": "A vállalati példányok adminisztrátorai megjeleníthetnek egy értesítési szalagot a felhasználóknak. A lépésenkénti utasításokat lásd az <2>útmutatóban.", "alert-title": "Fontos: Egyetlen adat vagy konfiguráció sem fog elveszni, de az irányítópultok néhány percig átmenetileg nem lesznek elérhetők.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Befejezés", "button-start": "Szinkronizálás indítása", "discard-modal": { diff --git a/public/locales/id-ID/grafana.json b/public/locales/id-ID/grafana.json index 990835de3b9..f36f2d86a5f 100644 --- a/public/locales/id-ID/grafana.json +++ b/public/locales/id-ID/grafana.json @@ -2051,9 +2051,6 @@ "text-loading-rules": "Memuat aturan...", "title-dashboard-not-saved": "Dasbor tidak disimpan" }, - "paused-badge": { - "paused": "Dijeda" - }, "payload-editor": { "edit-payload": "Edit payload", "label-add-custom-alert-instance": "Tambah instans peringatan kustom", @@ -2204,9 +2201,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min. Interval = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} hingga sekarang" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Kueri dan ekspresi yang dipilih tidak dapat dikonversi ke default. Jika Anda menonaktifkan opsi lanjutan, kueri dan kondisi Anda akan diatur ulang ke pengaturan default." @@ -2548,6 +2542,10 @@ "recovering": "{{recoveringStats}} memulihkan", "error_other": "{{count}} kesalahan" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Pilih “dikelola Grafana” kecuali Anda memiliki sumber data Mimir, Loki, atau Cortex yang mengaktifkan API Ruler." }, @@ -3645,7 +3643,10 @@ "text": "Hasil untuk kueri Anda tidak ditemukan" }, "restore": { - "success": "Dasbor {{name}} dipulihkan" + "success": "", + "all-failed_other": "", + "failed-count_other": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Jika Anda memiliki akses langsung ke target, salin JSON dan tempel di sana.", "trash-state-manager": { @@ -11613,6 +11614,7 @@ "tooltip-unhealthy-repository": "Tidak dapat menerapkan pull pada repositori yang tidak sehat" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Sertakan commit untuk setiap nilai historis", "synchronization-options": "Opsi sinkronisasi" }, @@ -11636,6 +11638,8 @@ "alert-point-3": "Durasi proses ini bergantung pada jumlah sumber daya yang terlibat.", "alert-point-4": "Administrator instans Enterprise dapat menampilkan banner pengumuman kepada pengguna. Lihat <2>panduan ini untuk petunjuk langkah demi langkah.", "alert-title": "Penting: Tidak ada data atau konfigurasi yang akan hilang, tetapi dasbor tidak akan tersedia sementara selama beberapa menit.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Selesai", "button-start": "Mulai sinkronisasi", "discard-modal": { diff --git a/public/locales/it-IT/grafana.json b/public/locales/it-IT/grafana.json index 7ba8c5b443d..88b4480c1e7 100644 --- a/public/locales/it-IT/grafana.json +++ b/public/locales/it-IT/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Caricamento regole in corso...", "title-dashboard-not-saved": "La dashboard non è stata salvata" }, - "paused-badge": { - "paused": "In pausa" - }, "payload-editor": { "edit-payload": "Modifica carico utile", "label-add-custom-alert-instance": "Aggiungi istanza di avviso personalizzata", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min Intervallo = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} a ora" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Le query e le espressioni selezionate non possono essere convertite in predefinite. Se disattivi le opzioni avanzate, la query e la condizione verranno ripristinate alle impostazioni predefinite." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} errori", "error_other": "{{count}} errori" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Seleziona \"Gestito da Grafana\" a meno che tu non disponga di un'origine dei dati Mimir, Loki o Cortex con l'API Ruler abilitata." }, @@ -3663,7 +3661,13 @@ "text": "Nessun risultato trovato per la ricerca" }, "restore": { - "success": "Dashboard {{name}} ripristinata" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Se hai accesso diretto alla destinazione, copia il file JSON e incollalo lì.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "Impossibile eseguire il pull di un repository non integro" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Includi commit per ogni valore storico", "synchronization-options": "Opzioni di sincronizzazione" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "La durata di questo processo dipende dal numero di risorse coinvolte.", "alert-point-4": "Gli amministratori dell'istanza aziendale possono mostrare un banner di annuncio agli utenti. Consulta <2>questa guida per istruzioni dettagliate.", "alert-title": "Importante: nessun dato o configurazione andrà perso, ma le dashboard non saranno disponibili per alcuni minuti.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Fine", "button-start": "Inizia la sincronizzazione", "discard-modal": { diff --git a/public/locales/ja-JP/grafana.json b/public/locales/ja-JP/grafana.json index 7e1fda1ca0c..a756119bfb5 100644 --- a/public/locales/ja-JP/grafana.json +++ b/public/locales/ja-JP/grafana.json @@ -2051,9 +2051,6 @@ "text-loading-rules": "ルールを読み込み中...", "title-dashboard-not-saved": "ダッシュボードは保存されていません" }, - "paused-badge": { - "paused": "中断しています" - }, "payload-editor": { "edit-payload": "ペイロードを編集", "label-add-custom-alert-instance": "カスタムアラートインスタンスを追加", @@ -2204,9 +2201,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "最小間隔= {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}}から現在" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "選択したクエリと式はデフォルトに変換できません。高度なオプションを無効にすると、クエリと条件はデフォルト設定にリセットされます。" @@ -2548,6 +2542,10 @@ "recovering": "{{recoveringStats}}件が復旧中", "error_other": "{{count}}件のエラー" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Ruler APIが有効なMimir、Loki、またはCortexデータソースがない限り、「Grafana管理」を選択してください。" }, @@ -3645,7 +3643,10 @@ "text": "クエリに一致する結果が見つかりませんでした。" }, "restore": { - "success": "ダッシュボード{{name}}が復元されました" + "success": "", + "all-failed_other": "", + "failed-count_other": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "ターゲットに直接アクセスできる場合は、JSONをコピーしてそこに貼り付けます。", "trash-state-manager": { @@ -11613,6 +11614,7 @@ "tooltip-unhealthy-repository": "問題のあるリポジトリをプルできません" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "各履歴値のコミットを含める", "synchronization-options": "同期オプション" }, @@ -11636,6 +11638,8 @@ "alert-point-3": "このプロセスの所要時間は、関連するリソースの数によって異なります。", "alert-point-4": "エンタープライズインスタンス管理者は、ユーザーにお知らせバナーを表示できます。詳しい手順については<2>このガイドをご覧ください。", "alert-title": "重要:データや設定は失われませんが、ダッシュボードは数分間一時的に利用できなくなります。", + "button-cancel": "", + "button-cancelling": "", "button-next": "完了", "button-start": "同期を開始", "discard-modal": { diff --git a/public/locales/ko-KR/grafana.json b/public/locales/ko-KR/grafana.json index ae8a098edc6..391c119f6b0 100644 --- a/public/locales/ko-KR/grafana.json +++ b/public/locales/ko-KR/grafana.json @@ -2051,9 +2051,6 @@ "text-loading-rules": "규칙 로딩 중...", "title-dashboard-not-saved": "대시보드 저장되지 않음" }, - "paused-badge": { - "paused": "일시 중지됨" - }, "payload-editor": { "edit-payload": "페이로드 편집", "label-add-custom-alert-instance": "사용자 지정 경고 인스턴스 추가", @@ -2204,9 +2201,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "최소 간격 = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}}부터 현재까지" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "선택한 쿼리와 표현식을 기본값으로 변환할 수 없습니다. 고급 옵션을 비활성화하면 쿼리와 조건이 기본 설정으로 재설정됩니다." @@ -2548,6 +2542,10 @@ "recovering": "{{recoveringStats}}개 복구 중", "error_other": "오류 {{count}}개" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Ruler API가 활성화된 Mimir, Loki 또는 Cortex 데이터 소스가 없는 경우 “Grafana 관리형”을 선택합니다." }, @@ -3645,7 +3643,10 @@ "text": "쿼리에 대해 찾은 결과 없음" }, "restore": { - "success": "{{name}} 대시보드 복원됨" + "success": "", + "all-failed_other": "", + "failed-count_other": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "대상에 직접 액세스할 수 있는 경우 JSON을 복사하여 붙여넣으세요.", "trash-state-manager": { @@ -11613,6 +11614,7 @@ "tooltip-unhealthy-repository": "상태가 좋지 않은 리포지토리를 가져올 수 없습니다" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "각 과거 값에 대한 커밋을 포함합니다", "synchronization-options": "동기화 옵션" }, @@ -11636,6 +11638,8 @@ "alert-point-3": "이 프로세스의 지속 시간은 관련된 리소스 수에 따라 달라집니다.", "alert-point-4": "Enterprise 인스턴스 관리자는 사용자에게 공지 배너를 표시할 수 있습니다. 단계별 지침은 <2>이 가이드를 확인하세요.", "alert-title": "중요: 데이터나 구성은 손실되지 않지만 대시보드를 몇 분 동안 일시적으로 사용할 수 없습니다.", + "button-cancel": "", + "button-cancelling": "", "button-next": "완료", "button-start": "동기화 시작", "discard-modal": { diff --git a/public/locales/nl-NL/grafana.json b/public/locales/nl-NL/grafana.json index 7162841e197..c546246a335 100644 --- a/public/locales/nl-NL/grafana.json +++ b/public/locales/nl-NL/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Regels laden...", "title-dashboard-not-saved": "Dashboard is niet opgeslagen" }, - "paused-badge": { - "paused": "Gepauzeerd" - }, "payload-editor": { "edit-payload": "Payload bewerken", "label-add-custom-alert-instance": "Aangepaste waarschuwingsinstantie toevoegen", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min. Interval = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} tot nu" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "De geselecteerde query's en expressies kunnen niet worden geconverteerd naar standaard. Als je geavanceerde opties deactiveert, worden je query en voorwaarde teruggezet naar de standaardinstellingen." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} fouten", "error_other": "{{count}} fouten" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Selecteer 'Grafana beheerd', tenzij je een Mimir-, Loki- of Cortex-gegevensbron hebt met de Ruler-API ingeschakeld." }, @@ -3663,7 +3661,13 @@ "text": "Geen resultaten gevonden voor je zoekopdracht" }, "restore": { - "success": " {{name}} dashboard is hersteld" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Als je directe toegang hebt tot het doel, kopieer je de JSON en plak je deze daar.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "Kan geen ongezonde repository ophalen" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Commits opnemen voor elke historische waarde", "synchronization-options": "Synchronisatie-opties" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "De duur van dit proces is afhankelijk van het aantal betrokken bronnen.", "alert-point-4": "Enterprise-instantiebeheerders kunnen een aankondigingsbanner weergeven aan gebruikers. Zie <2>deze handleiding voor stapsgewijze instructies.", "alert-title": "Belangrijk: er zullen geen gegevens of configuratie verloren gaan, maar dashboards zullen tijdelijk een paar minuten niet beschikbaar zijn.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Voltooien", "button-start": "Synchronisatie starten", "discard-modal": { diff --git a/public/locales/pl-PL/grafana.json b/public/locales/pl-PL/grafana.json index c14303ee159..f2a4451488a 100644 --- a/public/locales/pl-PL/grafana.json +++ b/public/locales/pl-PL/grafana.json @@ -2072,9 +2072,6 @@ "text-loading-rules": "Ładowanie reguł…", "title-dashboard-not-saved": "Nie zapisano pulpitu" }, - "paused-badge": { - "paused": "Wstrzymano" - }, "payload-editor": { "edit-payload": "Edytuj ładunek", "label-add-custom-alert-instance": "Dodaj niestandardową instancję alertu", @@ -2231,9 +2228,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min. odstęp czasu = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "Od <0>{{from}} do teraz" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Nie można przekonwertować wybranych zapytań i wyrażeń na domyślne. Jeśli wyłączysz opcje zaawansowane, zapytanie i warunek zostaną zresetowane do ustawień domyślnych." @@ -2587,6 +2581,10 @@ "error_many": "{{count}} błędów", "error_other": "{{count}} błędu" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Wybierz „Zarządzane przez Grafana”, chyba że masz źródło danych Mimir, Loki lub Cortex z włączonym interfejsem API Ruler." }, @@ -3699,7 +3697,19 @@ "text": "Nie znaleziono wyników dla tego zapytania" }, "restore": { - "success": "Przywrócono pulpit {{name}}" + "success": "", + "all-failed_one": "", + "all-failed_few": "", + "all-failed_many": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_few": "", + "failed-count_many": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_few": "", + "success-count_many": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Jeśli masz bezpośredni dostęp do celu, skopiuj kod JSON i wklej go tam.", "trash-state-manager": { @@ -11721,6 +11731,7 @@ "tooltip-unhealthy-repository": "Nie można pobrać danych z niesprawnego repozytorium" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Uwzględnij zatwierdzenia dla każdej wartości historycznej", "synchronization-options": "Opcje synchronizacji" }, @@ -11744,6 +11755,8 @@ "alert-point-3": "Czas trwania tego procesu zależy od liczby zasobów.", "alert-point-4": "Administratorzy instancji Enterprise mogą włączyć wyświetlanie użytkownikom banera z ogłoszeniem. Szczegółowe instrukcje znajdziesz w <2>tym przewodniku.", "alert-title": "Ważne: dane ani konfiguracja nie zostaną utracone, ale pulpity będą niedostępne przez kilka minut.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Zakończ", "button-start": "Rozpocznij synchronizację", "discard-modal": { diff --git a/public/locales/pt-BR/grafana.json b/public/locales/pt-BR/grafana.json index 89812156544..a5ec46da596 100644 --- a/public/locales/pt-BR/grafana.json +++ b/public/locales/pt-BR/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Carregando regras…", "title-dashboard-not-saved": "O painel não foi salvo" }, - "paused-badge": { - "paused": "Pausado" - }, "payload-editor": { "edit-payload": "Editar carga útil", "label-add-custom-alert-instance": "Adicionar instância de alerta personalizada", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Mín. Intervalo = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} até agora" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "As consultas e expressões selecionadas não podem ser convertidas para o padrão. Se você desativar as opções avançadas, sua consulta e condição serão redefinidas para as configurações padrão." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} erros", "error_other": "{{count}} erros" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Selecione \"Gerenciado pela Grafana\", a menos que você tenha uma fonte de dados Mimir, Loki ou Cortex com a API do Ruler ativada." }, @@ -3663,7 +3661,13 @@ "text": "Nenhum resultado encontrado para sua consulta" }, "restore": { - "success": "Painel {{name}} restaurado" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Se você tiver acesso direto ao destino, copie o JSON e cole-o lá.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "Não é possível fazer extração de um repositório instável" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Incluir confirmações para cada valor histórico", "synchronization-options": "Opções de sincronização" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "A duração deste processo depende da quantidade de recursos envolvidos.", "alert-point-4": "Os administradores de instâncias corporativas podem exibir um banner de anúncio para os usuários. Consulte <2>este guia para conferir instruções passo a passo.", "alert-title": "Importante: nenhum dado ou configuração será perdido, mas os painéis ficarão indisponíveis por alguns minutos.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Finalizar", "button-start": "Iniciar sincronização", "discard-modal": { diff --git a/public/locales/pt-PT/grafana.json b/public/locales/pt-PT/grafana.json index 1b1ed25f7b9..564166fd27e 100644 --- a/public/locales/pt-PT/grafana.json +++ b/public/locales/pt-PT/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "A carregar regras...", "title-dashboard-not-saved": "Painel de controlo não guardado" }, - "paused-badge": { - "paused": "Em pausa" - }, "payload-editor": { "edit-payload": "Editar carga útil", "label-add-custom-alert-instance": "Adicionar instância de alerta personalizado", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min. Intervalo = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} até agora" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "As consultas e expressões selecionadas não podem ser convertidas para padrão. Se desativar as opções avançadas, a sua consulta e condição serão repostas para as definições padrão." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} erros", "error_other": "{{count}} erros" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Selecione \"Gerido pela Grafana\", a menos que tenha uma origem de dados Mimir, Loki ou Cortex com a Ruler API ativada." }, @@ -3663,7 +3661,13 @@ "text": "Não foram encontrados resultados para a sua consulta" }, "restore": { - "success": "Painel de controlo {{name}} restaurado" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Se tiver acesso direto ao destino, copie o JSON e cole-o lá.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "Não foi possível obter um repositório que não está em bom estado" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Incluir commits para cada valor histórico", "synchronization-options": "Opções de sincronização" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "A duração deste processo depende do número de recursos envolvidos.", "alert-point-4": "Os administradores de instâncias empresariais podem exibir um banner de anúncio aos utilizadores. Consulte <2>este guia para obter instruções passo a passo.", "alert-title": "Importante: não serão perdidos dados ou configurações, mas os painéis de controlo ficarão temporariamente indisponíveis durante alguns minutos.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Concluir", "button-start": "Iniciar sincronização", "discard-modal": { diff --git a/public/locales/ru-RU/grafana.json b/public/locales/ru-RU/grafana.json index 81d602940da..b473fe13523 100644 --- a/public/locales/ru-RU/grafana.json +++ b/public/locales/ru-RU/grafana.json @@ -2072,9 +2072,6 @@ "text-loading-rules": "Загрузка правил...", "title-dashboard-not-saved": "Дашборд не сохранен" }, - "paused-badge": { - "paused": "Приостановлено" - }, "payload-editor": { "edit-payload": "Редактировать полезные данные", "label-add-custom-alert-instance": "Добавить экземпляр пользовательского оповещения", @@ -2231,9 +2228,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Мин. интервал = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "С <0>{{from}} до текущего момента" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Выбранные запросы и выражения не могут быть преобразованы в используемые по умолчанию. Если вы отключите расширенные параметры, ваш запрос и условие будут сброшены до настроек по умолчанию." @@ -2587,6 +2581,10 @@ "error_many": "{{count}} ошибок", "error_other": "{{count}} ошибок" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Выберите «Управляемые Grafana», если у вас нет источника данных Mimir, Loki или Cortex с включенным Ruler API." }, @@ -3699,7 +3697,19 @@ "text": "По вашему запросу ничего не найдено" }, "restore": { - "success": "Дашборд {{name}} восстановлен" + "success": "", + "all-failed_one": "", + "all-failed_few": "", + "all-failed_many": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_few": "", + "failed-count_many": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_few": "", + "success-count_many": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Если у вас есть прямой доступ к целевому объекту, скопируйте JSON-файл и вставьте его туда.", "trash-state-manager": { @@ -11721,6 +11731,7 @@ "tooltip-unhealthy-repository": "Невозможно внести изменения в неисправный репозиторий" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Включить фиксации для каждого ранее зафиксированного значения", "synchronization-options": "Параметры синхронизации" }, @@ -11744,6 +11755,8 @@ "alert-point-3": "Длительность процесса зависит от количества задействованных ресурсов.", "alert-point-4": "Администраторы экземпляров Enterprise могут показывать пользователям баннер с объявлением. Пошаговые инструкции см. в <2>руководстве.", "alert-title": "Важно. Данные и конфигурация не будут потеряны, однако дашборды будут недоступны в течение нескольких минут.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Готово", "button-start": "Начать синхронизацию", "discard-modal": { diff --git a/public/locales/sv-SE/grafana.json b/public/locales/sv-SE/grafana.json index dfe01844930..881f152769a 100644 --- a/public/locales/sv-SE/grafana.json +++ b/public/locales/sv-SE/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Laddar regler …", "title-dashboard-not-saved": "Instrumentpanelen sparades inte" }, - "paused-badge": { - "paused": "Pausad" - }, "payload-editor": { "edit-payload": "Redigera nyttolast", "label-add-custom-alert-instance": "Lägg till anpassad larminstans", @@ -2213,9 +2210,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "Min. Intervall = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} till nu" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "De valda frågorna och uttrycken kan inte konverteras till standard. Om du inaktiverar avancerade alternativ kommer din fråga och ditt villkor att återställas till standardinställningarna." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} fel", "error_other": "{{count}} fel" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Välj ”Grafana-hanterad” om du inte har en Mimir-, Loki- eller Cortex-datakälla med Ruler API aktiverat." }, @@ -3663,7 +3661,13 @@ "text": "Inga resultat hittades för din fråga" }, "restore": { - "success": "Instrumentpanelen {{name}} har återställts" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Om du har direkt åtkomst till målet kopierar du JSON och klistrar in den där.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "Det gick inte att hämta en ohälsosam lagringsplats" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Inkludera åtaganden för varje historiskt värde", "synchronization-options": "Synkroniseringsalternativ" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "Hur lång den här processen är beror på hur många resurser som är inblandade.", "alert-point-4": "Enterprise-instansadministratörer kan visa en meddelandebanner för användare. Se <2>denna guide för steg för steg-anvisningar.", "alert-title": "Viktigt: Inga data eller konfigurationer kommer att förloras, men instrumentpaneler kommer att vara tillfälligt otillgängliga under några minuter.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Slutför", "button-start": "Påbörja synkronisering", "discard-modal": { diff --git a/public/locales/tr-TR/grafana.json b/public/locales/tr-TR/grafana.json index 85da581638d..bcb4f372011 100644 --- a/public/locales/tr-TR/grafana.json +++ b/public/locales/tr-TR/grafana.json @@ -2058,9 +2058,6 @@ "text-loading-rules": "Kurallar yükleniyor...", "title-dashboard-not-saved": "Pano kaydedilmedi" }, - "paused-badge": { - "paused": "Duraklatıldı" - }, "payload-editor": { "edit-payload": "Yükü düzenle", "label-add-custom-alert-instance": "Özel uyarı örneği ekle", @@ -2213,9 +2210,6 @@ "max-data-points": "MD (Maks. Veri Noktası) = {{maxDataPoints}}", "min-interval": "Min. Aralık = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}} itibarıyla şimdiye kadar" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "Seçilen sorgular ve ifadeler varsayılana dönüştürülemez. Gelişmiş seçenekleri devre dışı bırakırsanız sorgunuz ve koşulunuz varsayılan ayarlara sıfırlanır." @@ -2561,6 +2555,10 @@ "error_one": "{{count}} hata", "error_other": "{{count}} hata" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "Ruler API etkin olan bir Mimir, Loki veya Cortex veri kaynağınız yoksa \"Grafana tarafından yönetilen\" seçeneğini belirleyin." }, @@ -3663,7 +3661,13 @@ "text": "Sorgunuz için sonuç bulunamadı" }, "restore": { - "success": "{{name}} panosu geri yüklendi" + "success": "", + "all-failed_one": "", + "all-failed_other": "", + "failed-count_one": "", + "failed-count_other": "", + "success-count_one": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "Hedefe doğrudan erişiminiz varsa JSON'u kopyalayıp oraya yapıştırın.", "trash-state-manager": { @@ -11649,6 +11653,7 @@ "tooltip-unhealthy-repository": "İyi durumda olmayan bir depo çekilemedi" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "Her geçmiş değer için yürütmeyi dahil et", "synchronization-options": "Senkronizasyon seçenekleri" }, @@ -11672,6 +11677,8 @@ "alert-point-3": "Bu işlemin süresi dâhil olan kaynakların sayısına bağlıdır.", "alert-point-4": "Enterprise örnek yöneticileri, kullanıcılara bir duyuru afişi gösterebilir. Adım adım talimatlar için <2>bu kılavuza bakın.", "alert-title": "Önemli: Veri veya yapılandırma kaybı yaşanmayacak ancak panolar birkaç dakika boyunca geçici olarak kullanılamayacaktır.", + "button-cancel": "", + "button-cancelling": "", "button-next": "Sonlandır", "button-start": "Senkronizasyonu başlat", "discard-modal": { diff --git a/public/locales/zh-Hans/grafana.json b/public/locales/zh-Hans/grafana.json index d51c0f9b642..fb2aa1cb48b 100644 --- a/public/locales/zh-Hans/grafana.json +++ b/public/locales/zh-Hans/grafana.json @@ -2051,9 +2051,6 @@ "text-loading-rules": "正在加载规则...", "title-dashboard-not-saved": "数据面板未保存" }, - "paused-badge": { - "paused": "已暂停" - }, "payload-editor": { "edit-payload": "编辑负载", "label-add-custom-alert-instance": "添加自定义警报实例", @@ -2204,9 +2201,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "最小间隔 = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}}至现在" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "无法将所选查询和表达式转换为默认值。如果停用高级选项,您的查询和条件将重置为默认设置。" @@ -2548,6 +2542,10 @@ "recovering": "{{recoveringStats}}正在恢复", "error_other": "{{count}} 个错误" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "选择“Grafana 托管”,除非您有启用了 Ruler API 的 Mimir、Loki 或 Cortex 数据源。" }, @@ -3645,7 +3643,10 @@ "text": "未找到与您的查询相关的结果" }, "restore": { - "success": "数据面板 {{name}} 已恢复" + "success": "", + "all-failed_other": "", + "failed-count_other": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "如果您可以直接访问目标,请复制 JSON 并将其粘贴到那里。", "trash-state-manager": { @@ -11613,6 +11614,7 @@ "tooltip-unhealthy-repository": "无法拉取状态不良的存储库" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "包括每个历史值的提交", "synchronization-options": "同步选项" }, @@ -11636,6 +11638,8 @@ "alert-point-3": "此过程的持续时间取决于所涉及资源的数量。", "alert-point-4": "企业实例管理员可以向用户显示公告横幅。有关分步说明,请参阅<2>本指南。", "alert-title": "重要提示:数据或配置不会丢失,但数据面板将在几分钟内暂时不可用。", + "button-cancel": "", + "button-cancelling": "", "button-next": "完成", "button-start": "开始同步", "discard-modal": { diff --git a/public/locales/zh-Hant/grafana.json b/public/locales/zh-Hant/grafana.json index 1e8cf9c58f0..874b2559929 100644 --- a/public/locales/zh-Hant/grafana.json +++ b/public/locales/zh-Hant/grafana.json @@ -2051,9 +2051,6 @@ "text-loading-rules": "正在載入規則...", "title-dashboard-not-saved": "儀表板未儲存" }, - "paused-badge": { - "paused": "已暫停" - }, "payload-editor": { "edit-payload": "編輯負載", "label-add-custom-alert-instance": "新增自訂警報執行個體", @@ -2204,9 +2201,6 @@ "max-data-points": "MD = {{maxDataPoints}}", "min-interval": "最小間隔 = {{minInterval}}" }, - "query-preview": { - "relative-time-range": "<0>{{from}}至現在" - }, "queryAndExpressionsStep": { "disableAdvancedOptions": { "text": "所選查詢和表達式無法轉換為預設值。如果停用進階選項,您的查詢和條件將重設為預設設定。" @@ -2548,6 +2542,10 @@ "recovering": "正在復原{{recoveringStats}}", "error_other": "{{count}} 個錯誤" }, + "rule-time-range-label": { + "relative": "", + "relative-with-to": "" + }, "rule-type-picker": { "grafana-managed": "選擇「Grafana 管理」,除非有已啟用 Ruler API 的 Mimir、Loki 或 Cortex 資料來源。" }, @@ -3645,7 +3643,10 @@ "text": "未找到您的查詢結果" }, "restore": { - "success": "儀表板 {{name}} 已復原" + "success": "", + "all-failed_other": "", + "failed-count_other": "", + "success-count_other": "" }, "text-this-repository-is-read-only": "如果您可以直接存取目標,請複製 JSON 並將其貼上至該處。", "trash-state-manager": { @@ -11613,6 +11614,7 @@ "tooltip-unhealthy-repository": "無法拉取狀態不佳的儲存庫" }, "synchronize-step": { + "repository-unhealthy": "", "synchronization-description": "包含每個歷史數值的提交", "synchronization-options": "同步選項" }, @@ -11636,6 +11638,8 @@ "alert-point-3": "此流程的持續時間取決於所涉及的資源數量。", "alert-point-4": "企業執行個體管理員可以向使用者顯示公告橫幅。請參閱<2>本指南,了解逐步說明。", "alert-title": "重要事項:不會遺失任何資料或設定,但儀表板將在幾分鐘內暫時無法使用。", + "button-cancel": "", + "button-cancelling": "", "button-next": "結束", "button-start": "開始同步處理", "discard-modal": { From 7805f6b62d18faaa48ce48e43402b4d00dd3a8a5 Mon Sep 17 00:00:00 2001 From: Matt Adams Date: Thu, 11 Sep 2025 21:06:55 -0400 Subject: [PATCH 16/48] Alerting: Include `@emotion/css` as pkg dep (#110994) * alerting: include `@emotion/css` as pkg dep * alerting: modify lock file based on new pkg dep --- packages/grafana-alerting/package.json | 1 + yarn.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/grafana-alerting/package.json b/packages/grafana-alerting/package.json index bdf6d72c568..cf497d215c7 100644 --- a/packages/grafana-alerting/package.json +++ b/packages/grafana-alerting/package.json @@ -91,6 +91,7 @@ "react-dom": "^18.0.0" }, "dependencies": { + "@emotion/css": "11.13.5", "@faker-js/faker": "^9.8.0", "@grafana/i18n": "12.2.0-pre", "fishery": "^2.3.1", diff --git a/yarn.lock b/yarn.lock index 10ce4baafe4..5759752061e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2957,6 +2957,7 @@ __metadata: version: 0.0.0-use.local resolution: "@grafana/alerting@workspace:packages/grafana-alerting" dependencies: + "@emotion/css": "npm:11.13.5" "@faker-js/faker": "npm:^9.8.0" "@grafana/i18n": "npm:12.2.0-pre" "@grafana/test-utils": "workspace:*" From 6b2b949f8f0f957feb063fd7c1d485ada4486578 Mon Sep 17 00:00:00 2001 From: Daniele Stefano Ferru Date: Fri, 12 Sep 2025 04:38:41 +0200 Subject: [PATCH 17/48] Provisioning: check finalizers when validating Repository object (#110955) --- apps/provisioning/pkg/repository/finalizers.go | 10 ++++++++++ apps/provisioning/pkg/repository/test.go | 11 +++++++++++ .../apis/provisioning/controller/finalizers.go | 15 +++------------ pkg/registry/apis/provisioning/register.go | 4 ++-- 4 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 apps/provisioning/pkg/repository/finalizers.go diff --git a/apps/provisioning/pkg/repository/finalizers.go b/apps/provisioning/pkg/repository/finalizers.go new file mode 100644 index 00000000000..ea8ae2a9021 --- /dev/null +++ b/apps/provisioning/pkg/repository/finalizers.go @@ -0,0 +1,10 @@ +package repository + +// RemoveOrphanResourcesFinalizer removes everything this repo created +const RemoveOrphanResourcesFinalizer = "remove-orphan-resources" + +// ReleaseOrphanResourcesFinalizer removes the metadata for anything this repo created +const ReleaseOrphanResourcesFinalizer = "release-orphan-resources" + +// CleanFinalizer calls the "OnDelete" function for resource +const CleanFinalizer = "cleanup" diff --git a/apps/provisioning/pkg/repository/test.go b/apps/provisioning/pkg/repository/test.go index 83a549851af..cba9736e2d6 100644 --- a/apps/provisioning/pkg/repository/test.go +++ b/apps/provisioning/pkg/repository/test.go @@ -84,6 +84,17 @@ func ValidateRepository(repo Repository) field.ErrorList { } } + if slices.Contains(cfg.Finalizers, RemoveOrphanResourcesFinalizer) && + slices.Contains(cfg.Finalizers, ReleaseOrphanResourcesFinalizer) { + list = append(list, + field.Invalid( + field.NewPath("medatada", "finalizers"), + cfg.Finalizers, + "cannot have both remove and release orphan resources finalizers", + ), + ) + } + return list } diff --git a/pkg/registry/apis/provisioning/controller/finalizers.go b/pkg/registry/apis/provisioning/controller/finalizers.go index f4037326480..3980db5ec6f 100644 --- a/pkg/registry/apis/provisioning/controller/finalizers.go +++ b/pkg/registry/apis/provisioning/controller/finalizers.go @@ -19,15 +19,6 @@ import ( "github.com/grafana/grafana/pkg/registry/apis/provisioning/resources" ) -// RemoveOrphanResourcesFinalizer removes everything this repo created -const RemoveOrphanResourcesFinalizer = "remove-orphan-resources" - -// ReleaseOrphanResourcesFinalizer removes the metadata for anything this repo created -const ReleaseOrphanResourcesFinalizer = "release-orphan-resources" - -// CleanFinalizer calls the "OnDelete" function for resource -const CleanFinalizer = "cleanup" - type finalizer struct { lister resources.ResourceLister clientFactory resources.ClientFactory @@ -41,7 +32,7 @@ func (f *finalizer) process(ctx context.Context, for _, finalizer := range finalizers { switch finalizer { - case CleanFinalizer: + case repository.CleanFinalizer: // NOTE: the controller loop will never get run unless a finalizer is set hooks, ok := repo.(repository.Hooks) if ok { @@ -50,7 +41,7 @@ func (f *finalizer) process(ctx context.Context, } } - case ReleaseOrphanResourcesFinalizer: + case repository.ReleaseOrphanResourcesFinalizer: err := f.processExistingItems(ctx, repo.Config(), func(client dynamic.ResourceInterface, item *provisioning.ResourceListItem) error { patchAnnotations, err := getPatchedAnnotations(item) @@ -67,7 +58,7 @@ func (f *finalizer) process(ctx context.Context, return err } - case RemoveOrphanResourcesFinalizer: + case repository.RemoveOrphanResourcesFinalizer: err := f.processExistingItems(ctx, repo.Config(), func(client dynamic.ResourceInterface, item *provisioning.ResourceListItem) error { return client.Delete(ctx, item.Name, v1.DeleteOptions{}) diff --git a/pkg/registry/apis/provisioning/register.go b/pkg/registry/apis/provisioning/register.go index 3a325b67d95..6affff92583 100644 --- a/pkg/registry/apis/provisioning/register.go +++ b/pkg/registry/apis/provisioning/register.go @@ -485,8 +485,8 @@ func (b *APIBuilder) Mutate(ctx context.Context, a admission.Attributes, o admis // This is called on every update, so be careful to only add the finalizer for create if len(r.Finalizers) == 0 && a.GetOperation() == admission.Create { r.Finalizers = []string{ - controller.RemoveOrphanResourcesFinalizer, - controller.CleanFinalizer, + repository.RemoveOrphanResourcesFinalizer, + repository.CleanFinalizer, } } From 165e2f5022f17cb630b7b21f48a77759dda4136e Mon Sep 17 00:00:00 2001 From: Levente Balogh Date: Fri, 12 Sep 2025 08:19:14 +0200 Subject: [PATCH 18/48] Dashboard Controls - Adjust styling for links (#110924) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: adjust styling for the dashboard-controls menu * refactor: remove unused file DashboardVariableControls.tsx --------- Co-authored-by: Torkel Ödegaard --- .../scene/DashboardControlsMenu.tsx | 38 ++++++++--- .../scene/DashboardLinkRenderer.tsx | 16 ++++- .../scene/DropdownVariableControls.tsx | 68 ------------------- 3 files changed, 40 insertions(+), 82 deletions(-) delete mode 100644 public/app/features/dashboard-scene/scene/DropdownVariableControls.tsx diff --git a/public/app/features/dashboard-scene/scene/DashboardControlsMenu.tsx b/public/app/features/dashboard-scene/scene/DashboardControlsMenu.tsx index ecf54b057bf..e41b23270ce 100644 --- a/public/app/features/dashboard-scene/scene/DashboardControlsMenu.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardControlsMenu.tsx @@ -1,10 +1,10 @@ -import { css } from '@emotion/css'; +import { css, cx } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; import { t } from '@grafana/i18n'; import { sceneGraph, SceneVariable } from '@grafana/scenes'; import { DashboardLink } from '@grafana/schema'; -import { Box, Dropdown, ToolbarButton, useStyles2 } from '@grafana/ui'; +import { Box, Dropdown, Menu, ToolbarButton, useStyles2 } from '@grafana/ui'; import { DashboardLinkRenderer } from './DashboardLinkRenderer'; import { DashboardScene } from './DashboardScene'; @@ -15,7 +15,11 @@ export const DASHBOARD_CONTROLS_MENU_TITLE = 'Dashboard controls'; export function DashboardControlsButton({ dashboard }: { dashboard: DashboardScene }) { const { links, uid } = dashboard.useState(); - const filteredLinks = links.filter((link) => link.placement === 'inControlsMenu'); + // Dashboard links are not supported at the moment. + // Reason: nesting components causes issues since the inner dropdown is rendered in a portal, + // so clicking it closes the parent dropdown (the parent sees it as an overlay click, and the event cannot easily be intercepted, + // as it is in different HTML subtree). + const filteredLinks = links.filter((link) => link.placement === 'inControlsMenu' && link.type !== 'dashboards'); const variables = sceneGraph .getVariables(dashboard)! .useState() @@ -42,13 +46,13 @@ export function DashboardControlsButton({ dashboard }: { dashboard: DashboardSce ); } -interface VariablesMenuProps { +interface DashboardControlsMenuProps { variables: SceneVariable[]; links: DashboardLink[]; dashboardUID: string; } -function DashboardControlsMenu({ variables, links, dashboardUID }: VariablesMenuProps) { +function DashboardControlsMenu({ variables, links, dashboardUID }: DashboardControlsMenuProps) { const styles = useStyles2(getStyles); return ( @@ -61,23 +65,31 @@ function DashboardControlsMenu({ variables, links, dashboardUID }: VariablesMenu direction={'column'} borderRadius={'default'} backgroundColor={'primary'} - padding={1} + padding={1.5} gap={0.5} onClick={(e) => { + // Normally, clicking the overlay closes the dropdown. + // We stop event propagation here to keep it open while users interact with variable controls. e.stopPropagation(); }} > {/* Variables */} - {variables.map((variable) => ( -
+ {variables.map((variable, index) => ( +
0 && styles.menuItem)} key={variable.state.key}>
))} + {variables.length > 0 && links.length > 0 && ( +
+ +
+ )} + {/* Links */} {links.map((link, index) => ( -
- +
+
))} @@ -85,7 +97,11 @@ function DashboardControlsMenu({ variables, links, dashboardUID }: VariablesMenu } const getStyles = (theme: GrafanaTheme2) => ({ + divider: css({ + marginTop: theme.spacing(1), + padding: theme.spacing(0, 0.5), + }), menuItem: css({ - padding: theme.spacing(0.5), + marginTop: theme.spacing(2), }), }); diff --git a/public/app/features/dashboard-scene/scene/DashboardLinkRenderer.tsx b/public/app/features/dashboard-scene/scene/DashboardLinkRenderer.tsx index cf60d70b91e..be6c5d772bc 100644 --- a/public/app/features/dashboard-scene/scene/DashboardLinkRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardLinkRenderer.tsx @@ -1,7 +1,7 @@ import { sanitizeUrl } from '@grafana/data/internal'; import { selectors } from '@grafana/e2e-selectors'; import { DashboardLink } from '@grafana/schema'; -import { Tooltip } from '@grafana/ui'; +import { MenuItem, Tooltip } from '@grafana/ui'; import { DashboardLinkButton, DashboardLinksDashboard, @@ -13,9 +13,11 @@ import { LINK_ICON_MAP } from '../settings/links/utils'; export interface Props { link: DashboardLink; dashboardUID: string; + // Set to `true` if displaying a link in a drop-down menu (e.g. dashboard controls) + inMenu?: boolean; } -export function DashboardLinkRenderer({ link, dashboardUID }: Props) { +export function DashboardLinkRenderer({ link, dashboardUID, inMenu }: Props) { const linkInfo = getLinkSrv().getAnchorInfo(link); if (link.type === 'dashboards') { @@ -24,7 +26,15 @@ export function DashboardLinkRenderer({ link, dashboardUID }: Props) { const icon = LINK_ICON_MAP[link.icon]; - const linkElement = ( + const linkElement = inMenu ? ( + + ) : ( v.state.showInControlsMenu !== true); - - if (variables.length === 0) { - return null; - } - - return ( - { - e.stopPropagation(); - }} - > - {variables.map((variable) => ( -
- -
- ))} - - } - > - -
- ); -} - -const getStyles = (theme: GrafanaTheme2) => ({ - menuItem: css({ - padding: theme.spacing(0.5), - }), -}); From 0b9e0ef4dc043060268aacea2ccf76d8c2ce990c Mon Sep 17 00:00:00 2001 From: Alexander Akhmetov Date: Fri, 12 Sep 2025 08:56:13 +0200 Subject: [PATCH 19/48] Alerting: Add a feature toggle to enable Assistant enrichment (#110940) Alerting: Add a feature toggle to enable Assistant Investigations enrichment --- .../src/types/featureToggles.gen.ts | 5 +++ pkg/services/featuremgmt/registry.go | 9 ++++++ pkg/services/featuremgmt/toggles_gen.csv | 1 + pkg/services/featuremgmt/toggles_gen.go | 4 +++ pkg/services/featuremgmt/toggles_gen.json | 31 +++++++++++++++++++ 5 files changed, 50 insertions(+) diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 8b62b52c1ec..b98349e852d 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -766,6 +766,11 @@ export interface FeatureToggles { */ alertingEnrichmentPerRule?: boolean; /** + * Enable Assistant Investigations enrichment type. + * @default false + */ + alertingEnrichmentAssistantInvestigations?: boolean; + /** * Enable AI-analyze central state history. * @default false */ diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 802b5234bfc..a19ae8f3f96 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -1316,6 +1316,15 @@ var ( HideFromDocs: true, Expression: "false", }, + { + Name: "alertingEnrichmentAssistantInvestigations", + Description: "Enable Assistant Investigations enrichment type.", + Stage: FeatureStageExperimental, + Owner: grafanaAlertingSquad, + HideFromAdminPage: true, + HideFromDocs: true, + Expression: "false", + }, { Name: "alertingAIAnalyzeCentralStateHistory", Description: "Enable AI-analyze central state history.", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 0af8cc7c543..0294b58ccf3 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -171,6 +171,7 @@ alertingAIFeedback,experimental,@grafana/alerting-squad,false,false,false alertingAIImproveAlertRules,experimental,@grafana/alerting-squad,false,false,false alertingAIGenTemplates,experimental,@grafana/alerting-squad,false,false,false alertingEnrichmentPerRule,experimental,@grafana/alerting-squad,false,false,false +alertingEnrichmentAssistantInvestigations,experimental,@grafana/alerting-squad,false,false,false alertingAIAnalyzeCentralStateHistory,experimental,@grafana/alerting-squad,false,false,false alertingNotificationsStepMode,GA,@grafana/alerting-squad,false,false,true feedbackButton,experimental,@grafana/grafana-operator-experience-squad,false,false,false diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 2b87218e5cf..f337c991e09 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -695,6 +695,10 @@ const ( // Enable enrichment per rule in the alerting UI. FlagAlertingEnrichmentPerRule = "alertingEnrichmentPerRule" + // FlagAlertingEnrichmentAssistantInvestigations + // Enable Assistant Investigations enrichment type. + FlagAlertingEnrichmentAssistantInvestigations = "alertingEnrichmentAssistantInvestigations" + // FlagAlertingAIAnalyzeCentralStateHistory // Enable AI-analyze central state history. FlagAlertingAIAnalyzeCentralStateHistory = "alertingAIAnalyzeCentralStateHistory" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 081bfde8a62..9337a5f30e7 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -248,6 +248,37 @@ "hideFromDocs": true } }, + { + "metadata": { + "name": "alertingEnrichmentAssistantInvestigations", + "resourceVersion": "1757606567075", + "creationTimestamp": "2025-09-11T16:02:47Z" + }, + "spec": { + "description": "Enable Assistant Investigations enrichment type.", + "stage": "experimental", + "codeowner": "@grafana/alerting-squad", + "hideFromAdminPage": true, + "hideFromDocs": true, + "expression": "false" + } + }, + { + "metadata": { + "name": "alertingEnrichmentAssistantInvestigationsUI", + "resourceVersion": "1757541861834", + "creationTimestamp": "2025-09-10T22:04:21Z", + "deletionTimestamp": "2025-09-11T16:02:47Z" + }, + "spec": { + "description": "Enable Assistant Investigations enrichment type in the UI.", + "stage": "experimental", + "codeowner": "@grafana/alerting-squad", + "hideFromAdminPage": true, + "hideFromDocs": true, + "expression": "false" + } + }, { "metadata": { "name": "alertingEnrichmentPerRule", From 1944d2dd0ebe4217d555dc38fc8f009adc3defdd Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Fri, 12 Sep 2025 10:50:10 +0300 Subject: [PATCH 20/48] Provisioing: Update provisioned folder with a manager identity (#110988) --- pkg/services/dashboards/dashboard.go | 3 +- .../dashboards/dashboard_provisioning_mock.go | 51 +++++++++++++++---- .../dashboards/service/dashboard_service.go | 21 ++++++++ pkg/services/dashboards/store_mock.go | 31 ----------- .../folderimpl/folder_unifiedstorage.go | 21 ++++---- .../folder/folderimpl/unifiedstore.go | 16 ++++-- pkg/services/folder/model.go | 7 +++ .../provisioning/dashboards/dashboard.go | 18 +++++-- .../provisioning/dashboards/file_reader.go | 9 ++++ .../dashboards/file_reader_test.go | 8 +-- .../provisioning/dashboards/validator_test.go | 4 +- pkg/services/provisioning/provisioning.go | 1 + 12 files changed, 123 insertions(+), 67 deletions(-) diff --git a/pkg/services/dashboards/dashboard.go b/pkg/services/dashboards/dashboard.go index bd2eeb9e661..4e077e08d9d 100644 --- a/pkg/services/dashboards/dashboard.go +++ b/pkg/services/dashboards/dashboard.go @@ -65,7 +65,8 @@ type DashboardProvisioningService interface { GetProvisionedDashboardData(ctx context.Context, name string) ([]*DashboardProvisioning, error) GetProvisionedDashboardDataByDashboardID(ctx context.Context, dashboardID int64) (*DashboardProvisioning, error) GetProvisionedDashboardDataByDashboardUID(ctx context.Context, orgID int64, dashboardUID string) (*DashboardProvisioning, error) - SaveFolderForProvisionedDashboards(ctx context.Context, cmd *folder.CreateFolderCommand, readerName string) (*folder.Folder, error) + SaveFolderForProvisionedDashboards(ctx context.Context, cmd *folder.CreateFolderCommand, managerIdentity string) (*folder.Folder, error) + UpdateFolderWithManagedByAnnotation(ctx context.Context, folder *folder.Folder, managerIdentity string) (*folder.Folder, error) SaveProvisionedDashboard(ctx context.Context, dto *SaveDashboardDTO, provisioning *DashboardProvisioning) (*Dashboard, error) UnprovisionDashboard(ctx context.Context, dashboardID int64) error } diff --git a/pkg/services/dashboards/dashboard_provisioning_mock.go b/pkg/services/dashboards/dashboard_provisioning_mock.go index eca2c66306f..65521984741 100644 --- a/pkg/services/dashboards/dashboard_provisioning_mock.go +++ b/pkg/services/dashboards/dashboard_provisioning_mock.go @@ -5,9 +5,8 @@ package dashboards import ( context "context" - mock "github.com/stretchr/testify/mock" - folder "github.com/grafana/grafana/pkg/services/folder" + mock "github.com/stretchr/testify/mock" ) // FakeDashboardProvisioning is an autogenerated mock type for the DashboardProvisioningService type @@ -141,9 +140,9 @@ func (_m *FakeDashboardProvisioning) GetProvisionedDashboardDataByDashboardUID(c return r0, r1 } -// SaveFolderForProvisionedDashboards provides a mock function with given fields: _a0, _a1 -func (_m *FakeDashboardProvisioning) SaveFolderForProvisionedDashboards(_a0 context.Context, _a1 *folder.CreateFolderCommand, _ string) (*folder.Folder, error) { - ret := _m.Called(_a0, _a1) +// SaveFolderForProvisionedDashboards provides a mock function with given fields: ctx, cmd, readerName +func (_m *FakeDashboardProvisioning) SaveFolderForProvisionedDashboards(ctx context.Context, cmd *folder.CreateFolderCommand, readerName string) (*folder.Folder, error) { + ret := _m.Called(ctx, cmd, readerName) if len(ret) == 0 { panic("no return value specified for SaveFolderForProvisionedDashboards") @@ -151,19 +150,19 @@ func (_m *FakeDashboardProvisioning) SaveFolderForProvisionedDashboards(_a0 cont var r0 *folder.Folder var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *folder.CreateFolderCommand) (*folder.Folder, error)); ok { - return rf(_a0, _a1) + if rf, ok := ret.Get(0).(func(context.Context, *folder.CreateFolderCommand, string) (*folder.Folder, error)); ok { + return rf(ctx, cmd, readerName) } - if rf, ok := ret.Get(0).(func(context.Context, *folder.CreateFolderCommand) *folder.Folder); ok { - r0 = rf(_a0, _a1) + if rf, ok := ret.Get(0).(func(context.Context, *folder.CreateFolderCommand, string) *folder.Folder); ok { + r0 = rf(ctx, cmd, readerName) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*folder.Folder) } } - if rf, ok := ret.Get(1).(func(context.Context, *folder.CreateFolderCommand) error); ok { - r1 = rf(_a0, _a1) + if rf, ok := ret.Get(1).(func(context.Context, *folder.CreateFolderCommand, string) error); ok { + r1 = rf(ctx, cmd, readerName) } else { r1 = ret.Error(1) } @@ -219,6 +218,36 @@ func (_m *FakeDashboardProvisioning) UnprovisionDashboard(ctx context.Context, d return r0 } +// UpdateFolderWithManagedByAnnotation provides a mock function with given fields: ctx, _a1, readerName +func (_m *FakeDashboardProvisioning) UpdateFolderWithManagedByAnnotation(ctx context.Context, _a1 *folder.Folder, readerName string) (*folder.Folder, error) { + ret := _m.Called(ctx, _a1, readerName) + + if len(ret) == 0 { + panic("no return value specified for UpdateFolderWithManagedByAnnotation") + } + + var r0 *folder.Folder + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *folder.Folder, string) (*folder.Folder, error)); ok { + return rf(ctx, _a1, readerName) + } + if rf, ok := ret.Get(0).(func(context.Context, *folder.Folder, string) *folder.Folder); ok { + r0 = rf(ctx, _a1, readerName) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*folder.Folder) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *folder.Folder, string) error); ok { + r1 = rf(ctx, _a1, readerName) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewFakeDashboardProvisioning creates a new instance of FakeDashboardProvisioning. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewFakeDashboardProvisioning(t interface { diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go index 193d5566eae..7d329290b88 100644 --- a/pkg/services/dashboards/service/dashboard_service.go +++ b/pkg/services/dashboards/service/dashboard_service.go @@ -990,6 +990,27 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C return f, nil } +// UpdateFolderWithManagedByAnnotation implements dashboards.DashboardProvisioningService. +func (dr *DashboardServiceImpl) UpdateFolderWithManagedByAnnotation(ctx context.Context, f *folder.Folder, readerName string) (*folder.Folder, error) { + ctx, span := tracer.Start(ctx, "dashboards.service.UpdateFolderWithManagedByAnnotation") + defer span.End() + + ctx, ident := identity.WithServiceIdentity(ctx, f.OrgID) + updated, err := dr.folderService.Update(ctx, &folder.UpdateFolderCommand{ + UID: f.UID, + OrgID: f.OrgID, + SignedInUser: ident, + ManagerKindClassicFP: readerName, // nolint:staticcheck + Overwrite: true, + Version: f.Version, + }) + if err != nil { + dr.log.Error("failed to update folder for provisioned dashboards", "folder", f.Title, "org", f.OrgID, "err", err) + return nil, err + } + return updated, nil +} + func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO, allowUiUpdate bool) (*dashboards.Dashboard, error) { ctx, span := tracer.Start(ctx, "dashboards.service.SaveDashboard") diff --git a/pkg/services/dashboards/store_mock.go b/pkg/services/dashboards/store_mock.go index 74259652fbf..4a3e0d15d90 100644 --- a/pkg/services/dashboards/store_mock.go +++ b/pkg/services/dashboards/store_mock.go @@ -5,7 +5,6 @@ package dashboards import ( context "context" - quota "github.com/grafana/grafana/pkg/services/quota" mock "github.com/stretchr/testify/mock" ) @@ -32,36 +31,6 @@ func (_m *FakeDashboardStore) CleanupAfterDelete(ctx context.Context, cmd *Delet return r0 } -// Count provides a mock function with given fields: _a0, _a1 -func (_m *FakeDashboardStore) Count(_a0 context.Context, _a1 *quota.ScopeParameters) (*quota.Map, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for Count") - } - - var r0 *quota.Map - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *quota.ScopeParameters) (*quota.Map, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *quota.ScopeParameters) *quota.Map); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*quota.Map) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *quota.ScopeParameters) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // CountInOrg provides a mock function with given fields: ctx, orgID, isFolder func (_m *FakeDashboardStore) CountInOrg(ctx context.Context, orgID int64, isFolder bool) (int64, error) { ret := _m.Called(ctx, orgID, isFolder) diff --git a/pkg/services/folder/folderimpl/folder_unifiedstorage.go b/pkg/services/folder/folderimpl/folder_unifiedstorage.go index 30aea5f2985..f9f7af3b8ea 100644 --- a/pkg/services/folder/folderimpl/folder_unifiedstorage.go +++ b/pkg/services/folder/folderimpl/folder_unifiedstorage.go @@ -562,14 +562,15 @@ func (s *Service) updateOnApiServer(ctx context.Context, cmd *folder.UpdateFolde user := cmd.SignedInUser - foldr, err := s.unifiedStore.Update(ctx, folder.UpdateFolderCommand{ - UID: cmd.UID, - OrgID: cmd.OrgID, - NewTitle: cmd.NewTitle, - NewDescription: cmd.NewDescription, - SignedInUser: user, - Overwrite: cmd.Overwrite, - Version: cmd.Version, + folder, err := s.unifiedStore.Update(ctx, folder.UpdateFolderCommand{ + UID: cmd.UID, + OrgID: cmd.OrgID, + NewTitle: cmd.NewTitle, + NewDescription: cmd.NewDescription, + SignedInUser: user, + Overwrite: cmd.Overwrite, + Version: cmd.Version, + ManagerKindClassicFP: cmd.ManagerKindClassicFP, // nolint:staticcheck }) if err != nil { @@ -579,7 +580,7 @@ func (s *Service) updateOnApiServer(ctx context.Context, cmd *folder.UpdateFolde if cmd.NewTitle != nil { metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Folder).Inc() - if err := s.publishFolderFullPathUpdatedEventViaApiServer(ctx, foldr.Updated, cmd.OrgID, cmd.UID); err != nil { + if err := s.publishFolderFullPathUpdatedEventViaApiServer(ctx, folder.Updated, cmd.OrgID, cmd.UID); err != nil { return nil, err } } @@ -587,7 +588,7 @@ func (s *Service) updateOnApiServer(ctx context.Context, cmd *folder.UpdateFolde // always expose the dashboard store sequential ID metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Folder).Inc() - return foldr, nil + return folder, nil } func (s *Service) deleteFromApiServer(ctx context.Context, cmd *folder.DeleteFolderCommand) error { diff --git a/pkg/services/folder/folderimpl/unifiedstore.go b/pkg/services/folder/folderimpl/unifiedstore.go index 8f062d722f9..c3dd6347b11 100644 --- a/pkg/services/folder/folderimpl/unifiedstore.go +++ b/pkg/services/folder/folderimpl/unifiedstore.go @@ -97,6 +97,10 @@ func (ss *FolderUnifiedStoreImpl) Update(ctx context.Context, cmd folder.UpdateF return nil, err } updated := obj.DeepCopy() + meta, err := utils.MetaAccessor(updated) + if err != nil { + return nil, err + } if cmd.NewTitle != nil { err = unstructured.SetNestedField(updated.Object, *cmd.NewTitle, "spec", "title") @@ -111,10 +115,6 @@ func (ss *FolderUnifiedStoreImpl) Update(ctx context.Context, cmd folder.UpdateF } } if cmd.NewParentUID != nil { - meta, err := utils.MetaAccessor(updated) - if err != nil { - return nil, err - } meta.SetFolder(*cmd.NewParentUID) } else { // only compare versions if not moving the folder @@ -123,6 +123,14 @@ func (ss *FolderUnifiedStoreImpl) Update(ctx context.Context, cmd folder.UpdateF } } + // nolint:staticcheck + if cmd.ManagerKindClassicFP != "" { + meta.SetManagerProperties(utils.ManagerProperties{ + Kind: utils.ManagerKindClassicFP, + Identity: cmd.ManagerKindClassicFP, + }) + } + out, err := ss.k8sclient.Update(ctx, updated, cmd.OrgID, v1.UpdateOptions{ FieldValidation: v1.FieldValidationIgnore, }) diff --git a/pkg/services/folder/model.go b/pkg/services/folder/model.go index 3eeedcb2e08..5dbfa4e945c 100644 --- a/pkg/services/folder/model.go +++ b/pkg/services/folder/model.go @@ -158,6 +158,13 @@ type UpdateFolderCommand struct { Overwrite bool `json:"overwrite"` SignedInUser identity.Requester `json:"-"` + + // When running classic file provisioning with folders saved in kubernetes, + // folders will be marked with a manager of kind ManagerKindClassicFP + // NOTE: this is ignored when running legacy SQL storage + // + // Deprecated: this should only be used by the legacy file provisioning system + ManagerKindClassicFP string `json:"-"` } // MoveFolderCommand captures the information required by the folder service diff --git a/pkg/services/provisioning/dashboards/dashboard.go b/pkg/services/provisioning/dashboards/dashboard.go index 061a5f3f60d..e0c24c6ab07 100644 --- a/pkg/services/provisioning/dashboards/dashboard.go +++ b/pkg/services/provisioning/dashboards/dashboard.go @@ -6,7 +6,8 @@ import ( "os" "time" - dashboard "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1" + dashboardV1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1" + folderV1 "github.com/grafana/grafana/apps/folder/pkg/apis/folder/v1beta1" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/folder" @@ -57,8 +58,17 @@ func New(ctx context.Context, configDirectory string, provisioner dashboards.Das return nil, fmt.Errorf("%v: %w", "Failed to initialize file readers", err) } - if dual != nil && !dual.ShouldManage(dashboard.DashboardResourceInfo.GroupResource()) { - dual = nil // not actively managed + if dual != nil { + foldersInUnified, _ := dual.ReadFromUnified(context.Background(), folderV1.FolderResourceInfo.GroupResource()) + if foldersInUnified { + for _, reader := range fileReaders { + reader.foldersInUnified = true + } + } + + if !dual.ShouldManage(dashboardV1.DashboardResourceInfo.GroupResource()) { + dual = nil // not actively managed + } } d := &Provisioner{ @@ -78,7 +88,7 @@ func New(ctx context.Context, configDirectory string, provisioner dashboards.Das func (provider *Provisioner) Provision(ctx context.Context) error { // skip provisioning during migrations to prevent multi-replica instances from crashing when another replica is migrating if provider.dual != nil { - status, _ := provider.dual.Status(context.Background(), dashboard.DashboardResourceInfo.GroupResource()) + status, _ := provider.dual.Status(context.Background(), dashboardV1.DashboardResourceInfo.GroupResource()) if status.Migrating > 0 { provider.log.Info("dashboard migrations are running, skipping provisioning", "elapsed", time.Since(time.UnixMilli(status.Migrating))) return nil diff --git a/pkg/services/provisioning/dashboards/file_reader.go b/pkg/services/provisioning/dashboards/file_reader.go index e5de306f9f1..73cd50fef90 100644 --- a/pkg/services/provisioning/dashboards/file_reader.go +++ b/pkg/services/provisioning/dashboards/file_reader.go @@ -40,6 +40,7 @@ type FileReader struct { dashboardStore utils.DashboardStore FoldersFromFilesStructure bool folderService folder.Service + foldersInUnified bool mux sync.RWMutex usageTracker *usageTracker @@ -382,6 +383,14 @@ func (fr *FileReader) getOrCreateFolder(ctx context.Context, cfg *config, servic return 0, "", dashboards.ErrFolderInvalidUID } + // When we expect folders in unified storage, they should have a manager indicated + if err == nil && result != nil && result.ManagedBy == "" && fr.foldersInUnified { + result, err = service.UpdateFolderWithManagedByAnnotation(ctx, result, fr.Cfg.Name) + if err != nil { + return 0, "", fmt.Errorf("unable to update provisioned folder") + } + } + // dashboard folder not found. create one. if errors.Is(err, dashboards.ErrFolderNotFound) { createCmd := &folder.CreateFolderCommand{ diff --git a/pkg/services/provisioning/dashboards/file_reader_test.go b/pkg/services/provisioning/dashboards/file_reader_test.go index 798d6e62d5a..631b11bbc51 100644 --- a/pkg/services/provisioning/dashboards/file_reader_test.go +++ b/pkg/services/provisioning/dashboards/file_reader_test.go @@ -145,7 +145,7 @@ func TestIntegrationDashboardFileReader(t *testing.T) { cfg.Folder = "Team A" fakeService.On("GetProvisionedDashboardData", mock.Anything, configName).Return(nil, nil).Once() - fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&folder.Folder{ID: 1}, nil).Once() + fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything, configName).Return(&folder.Folder{ID: 1}, nil).Once() fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&dashboards.Dashboard{ID: 2}, nil).Times(2) reader, err := NewDashboardFileReader(cfg, logger, nil, fakeStore, folderSvc) reader.dashboardProvisioningService = fakeService @@ -324,7 +324,7 @@ func TestIntegrationDashboardFileReader(t *testing.T) { cfg.Options["foldersFromFilesStructure"] = true fakeService.On("GetProvisionedDashboardData", mock.Anything, configName).Return(nil, nil).Once() - fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&folder.Folder{}, nil).Times(2) + fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything, configName).Return(&folder.Folder{}, nil).Times(2) fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&dashboards.Dashboard{}, nil).Times(3) reader, err := NewDashboardFileReader(cfg, logger, nil, fakeStore, folderSvc) @@ -362,7 +362,7 @@ func TestIntegrationDashboardFileReader(t *testing.T) { cfg2 := &config{Name: "2", Type: "file", OrgID: 1, Folder: "f2", Options: map[string]any{"path": containingID}} fakeService.On("GetProvisionedDashboardData", mock.Anything, mock.AnythingOfType("string")).Return(nil, nil).Times(2) - fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&folder.Folder{}, nil).Times(2) + fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything, mock.Anything).Return(&folder.Folder{}, nil).Times(2) fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&dashboards.Dashboard{}, nil).Times(2) reader1, err := NewDashboardFileReader(cfg1, logger, nil, fakeStore, folderSvc) @@ -410,7 +410,7 @@ func TestIntegrationDashboardFileReader(t *testing.T) { "folder": defaultDashboards, }, } - fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&folder.Folder{ID: 1}, nil).Once() + fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything, cfg.Name).Return(&folder.Folder{ID: 1}, nil).Once() r, err := NewDashboardFileReader(cfg, logger, nil, fakeStore, folderSvc) require.NoError(t, err) diff --git a/pkg/services/provisioning/dashboards/validator_test.go b/pkg/services/provisioning/dashboards/validator_test.go index e5346bed303..d74fda1ff8d 100644 --- a/pkg/services/provisioning/dashboards/validator_test.go +++ b/pkg/services/provisioning/dashboards/validator_test.go @@ -66,7 +66,7 @@ func TestIntegrationDuplicatesValidator(t *testing.T) { fakeStore := &fakeDashboardStore{} r, err := NewDashboardFileReader(cfg, logger, nil, fakeStore, folderSvc) require.NoError(t, err) - fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&folder.Folder{}, nil).Times(6) + fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything, mock.Anything).Return(&folder.Folder{}, nil).Times(6) fakeService.On("GetProvisionedDashboardData", mock.Anything, mock.AnythingOfType("string")).Return([]*dashboards.DashboardProvisioning{}, nil).Times(4) fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&dashboards.Dashboard{}, nil).Times(5) _, folderUID, err := r.getOrCreateFolder(ctx, cfg, fakeService, folderName) @@ -183,7 +183,7 @@ func TestIntegrationDuplicatesValidator(t *testing.T) { }) t.Run("Duplicates validator should restrict write access only for readers with duplicates", func(t *testing.T) { - fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything).Return(&folder.Folder{}, nil).Times(5) + fakeService.On("SaveFolderForProvisionedDashboards", mock.Anything, mock.Anything, mock.Anything).Return(&folder.Folder{}, nil).Times(5) fakeService.On("GetProvisionedDashboardData", mock.Anything, mock.AnythingOfType("string")).Return([]*dashboards.DashboardProvisioning{}, nil).Times(3) fakeService.On("SaveProvisionedDashboard", mock.Anything, mock.Anything, mock.Anything).Return(&dashboards.Dashboard{}, nil).Times(5) fakeStore := &fakeDashboardStore{} diff --git a/pkg/services/provisioning/provisioning.go b/pkg/services/provisioning/provisioning.go index 3f831f9d4a3..b40b6136a46 100644 --- a/pkg/services/provisioning/provisioning.go +++ b/pkg/services/provisioning/provisioning.go @@ -88,6 +88,7 @@ func ProvideService( resourcePermissions: resourcePermissions, tracer: tracer, migratePrometheusType: promTypeMigrationProvider.Run, + dual: dual, } if err := s.setDashboardProvisioner(); err != nil { From b747ec8f2400f059de7cd46ea3d4f17fe3a7f3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Fri, 12 Sep 2025 10:26:50 +0200 Subject: [PATCH 21/48] Chore: prevents imports from grafana packages in i18n (#111000) --- eslint.config.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/eslint.config.js b/eslint.config.js index 508d40808a4..a00588a17db 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -552,4 +552,24 @@ module.exports = [ 'no-barrel-files/no-barrel-files': 'error', }, }, + + { + // @grafana/i18n shouldn't import from our 'library' NPM packages + name: 'grafana/packages-that-i18n-cant-import', + files: ['packages/grafana-i18n/**/*.{ts,tsx}'], + ignores: [], + rules: { + 'no-restricted-imports': [ + 'error', + withBaseRestrictedImportsConfig({ + patterns: [ + { + group: ['@grafana/*'], + message: "'@grafana/* packages' should not be imported in @grafana/i18n", + }, + ], + }), + ], + }, + }, ]; From 1004b26a4a34d4b95d50b10e392e0412b9f38284 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Fri, 12 Sep 2025 12:23:02 +0300 Subject: [PATCH 22/48] Provisioning: Avoid using listers.RepositoryLister outside a controller (#110948) * use raw storage * avoid informer cached lister --- pkg/registry/apis/provisioning/register.go | 47 +++++++++++++------ pkg/registry/apis/provisioning/routes.go | 4 +- pkg/registry/apis/provisioning/usage/usage.go | 7 ++- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/pkg/registry/apis/provisioning/register.go b/pkg/registry/apis/provisioning/register.go index 6affff92583..73dfe11cee8 100644 --- a/pkg/registry/apis/provisioning/register.go +++ b/pkg/registry/apis/provisioning/register.go @@ -10,14 +10,15 @@ import ( "github.com/prometheus/client_golang/prometheus" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" genericapiserver "k8s.io/apiserver/pkg/server" "k8s.io/kube-openapi/pkg/common" @@ -29,21 +30,20 @@ import ( dashboard "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1" folders "github.com/grafana/grafana/apps/folder/pkg/apis/folder/v1beta1" provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + appcontroller "github.com/grafana/grafana/apps/provisioning/pkg/controller" clientset "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned" client "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1" informers "github.com/grafana/grafana/apps/provisioning/pkg/generated/informers/externalversions" - listers "github.com/grafana/grafana/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1" + "github.com/grafana/grafana/apps/provisioning/pkg/loki" + "github.com/grafana/grafana/apps/provisioning/pkg/repository" "github.com/grafana/grafana/pkg/apimachinery/identity" apiutils "github.com/grafana/grafana/pkg/apimachinery/utils" grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" + grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" "github.com/grafana/grafana/pkg/registry/apis/provisioning/controller" - - appcontroller "github.com/grafana/grafana/apps/provisioning/pkg/controller" - "github.com/grafana/grafana/apps/provisioning/pkg/loki" - "github.com/grafana/grafana/apps/provisioning/pkg/repository" "github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs" deletepkg "github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs/delete" "github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs/export" @@ -87,7 +87,7 @@ type APIBuilder struct { usageStats usagestats.Service tracer tracing.Tracer - getter rest.Getter + store grafanarest.Storage parsers resources.ParserFactory repositoryResources resources.RepositoryResourcesFactory clients resources.ClientFactory @@ -98,7 +98,6 @@ type APIBuilder struct { jobHistoryConfig *JobHistoryConfig jobHistoryLoki *jobs.LokiJobHistory resourceLister resources.ResourceLister - repositoryLister listers.RepositoryLister legacyMigrator legacy.LegacyMigrator storageStatus dualwrite.Service unified resource.ResourceClient @@ -403,7 +402,7 @@ func (b *APIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupI return fmt.Errorf("failed to create repository storage: %w", err) } repositoryStatusStorage := grafanaregistry.NewRegistryStatusStore(opts.Scheme, repositoryStorage) - b.getter = repositoryStorage + b.store = repositoryStorage jobStore, err := grafanaregistry.NewCompleteRegistryStore(opts.Scheme, provisioning.JobResourceInfo, opts.OptsGetter) if err != nil { @@ -564,7 +563,7 @@ func (b *APIBuilder) Validate(ctx context.Context, a admission.Attributes, o adm } // Exit early if we have already found errors - targetError := b.verifyAgaintsExistingRepositories(cfg) + targetError := b.verifyAgainstExistingRepositories(cfg) if targetError != nil { return invalidRepositoryError(a.GetName(), field.ErrorList{targetError}) } @@ -578,9 +577,28 @@ func invalidRepositoryError(name string, list field.ErrorList) error { name, list) } +func (b *APIBuilder) getRepositoriesInNamespace(ctx context.Context) ([]provisioning.Repository, error) { + obj, err := b.store.List(ctx, &internalversion.ListOptions{ + Limit: 100, + }) + if err != nil { + return nil, err + } + + all, ok := obj.(*provisioning.RepositoryList) + if !ok { + return nil, fmt.Errorf("expected repository list") + } + return all.Items, nil +} + // TODO: move this to a more appropriate place. Probably controller/validation.go -func (b *APIBuilder) verifyAgaintsExistingRepositories(cfg *provisioning.Repository) *field.Error { - all, err := b.repositoryLister.Repositories(cfg.Namespace).List(labels.Everything()) +func (b *APIBuilder) verifyAgainstExistingRepositories(cfg *provisioning.Repository) *field.Error { + ctx, _, err := identity.WithProvisioningIdentity(context.Background(), cfg.Namespace) + if err != nil { + return &field.Error{Type: field.ErrorTypeInternal, Detail: err.Error()} + } + all, err := b.getRepositoriesInNamespace(request.WithNamespace(ctx, cfg.Namespace)) if err != nil { return field.Forbidden(field.NewPath("spec"), "Unable to verify root target: "+err.Error()) @@ -633,7 +651,6 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH jobInformer := sharedInformerFactory.Provisioning().V0alpha1().Jobs() b.client = c.ProvisioningV0alpha1() - b.repositoryLister = repoInformer.Lister() // Initialize the API client-based job store b.jobs, err = jobs.NewJobStore(b.client, 30*time.Second) @@ -659,7 +676,7 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH } // Create the repository resources factory - usageMetricCollector := usage.MetricCollector(b.tracer, b.repositoryLister, b.unified) + usageMetricCollector := usage.MetricCollector(b.tracer, b.getRepositoriesInNamespace, b.unified) b.usageStats.RegisterMetricsFunc(usageMetricCollector) stageIfPossible := repository.WrapWithStageAndPushIfPossible @@ -1231,7 +1248,7 @@ func (b *APIBuilder) tryRunningOnlyUnifiedStorage() error { // TODO: where should the helpers live? func (b *APIBuilder) GetRepository(ctx context.Context, name string) (repository.Repository, error) { - obj, err := b.getter.Get(ctx, name, &metav1.GetOptions{}) + obj, err := b.store.Get(ctx, name, &metav1.GetOptions{}) if err != nil { return nil, err } diff --git a/pkg/registry/apis/provisioning/routes.go b/pkg/registry/apis/provisioning/routes.go index 724e23de1c9..36d88433cc7 100644 --- a/pkg/registry/apis/provisioning/routes.go +++ b/pkg/registry/apis/provisioning/routes.go @@ -6,8 +6,8 @@ import ( "net/http" "time" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/kube-openapi/pkg/spec3" "k8s.io/kube-openapi/pkg/validation/spec" @@ -150,7 +150,7 @@ func (b *APIBuilder) handleSettings(w http.ResponseWriter, r *http.Request) { } // TODO: check if lister could list too many repositories or resources - all, err := b.repositoryLister.Repositories(u.GetNamespace()).List(labels.Everything()) + all, err := b.getRepositoriesInNamespace(request.WithNamespace(r.Context(), u.GetNamespace())) if err != nil { errhttp.Write(r.Context(), err, w) return diff --git a/pkg/registry/apis/provisioning/usage/usage.go b/pkg/registry/apis/provisioning/usage/usage.go index b9a1ed938c9..8fba893ac92 100644 --- a/pkg/registry/apis/provisioning/usage/usage.go +++ b/pkg/registry/apis/provisioning/usage/usage.go @@ -6,10 +6,9 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apiserver/pkg/endpoints/request" - listers "github.com/grafana/grafana/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1" + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/usagestats" @@ -17,7 +16,7 @@ import ( "github.com/grafana/grafana/pkg/storage/unified/resourcepb" ) -func MetricCollector(tracer tracing.Tracer, repositoryLister listers.RepositoryLister, unified resource.ResourceClient) usagestats.MetricsFunc { +func MetricCollector(tracer tracing.Tracer, repositoryLister func(ctx context.Context) ([]provisioning.Repository, error), unified resource.ResourceClient) usagestats.MetricsFunc { return func(ctx context.Context) (metrics map[string]any, err error) { ctx, span := tracer.Start(ctx, "Provisioning.Usage.collectProvisioningStats") defer func() { @@ -65,7 +64,7 @@ func MetricCollector(tracer tracing.Tracer, repositoryLister listers.RepositoryL } // Inspect all configs - repos, err := repositoryLister.List(labels.Everything()) + repos, err := repositoryLister(ctx) if err != nil { return m, fmt.Errorf("list repositories: %w", err) } From d4399e6eda327332a241750e09ea97e86d8cd465 Mon Sep 17 00:00:00 2001 From: Ieva Date: Fri, 12 Sep 2025 10:43:51 +0100 Subject: [PATCH 23/48] `grafana-iam`: Implement `resourcepermission` update (#110891) * first go at update implementation * template tests * SQL tests * more tests * set namespace for read resource permissions * fix a bug with perms being removed right after they're added * remove unwanted changes * fix tests and check error * PR feedback * Update pkg/registry/apis/iam/resourcepermission/sql.go --------- Co-authored-by: Gabriel MABILLE --- .../queries/permission_insert.sql | 16 +- .../queries/permission_remove.sql | 9 + .../apis/iam/resourcepermission/sql.go | 144 +++++++++-- .../apis/iam/resourcepermission/sql_test.go | 124 ++++++++- .../iam/resourcepermission/storage_backend.go | 27 +- .../storage_backend_test.go | 237 ++++++++++++++++++ .../apis/iam/resourcepermission/templates.go | 32 +++ .../iam/resourcepermission/templates_test.go | 20 ++ ...l--permission_remove-remove_permission.sql | 9 + ...s--permission_remove-remove_permission.sql | 9 + ...e--permission_remove-remove_permission.sql | 9 + 11 files changed, 595 insertions(+), 41 deletions(-) create mode 100644 pkg/registry/apis/iam/resourcepermission/queries/permission_remove.sql create mode 100755 pkg/registry/apis/iam/resourcepermission/testdata/mysql--permission_remove-remove_permission.sql create mode 100755 pkg/registry/apis/iam/resourcepermission/testdata/postgres--permission_remove-remove_permission.sql create mode 100755 pkg/registry/apis/iam/resourcepermission/testdata/sqlite--permission_remove-remove_permission.sql diff --git a/pkg/registry/apis/iam/resourcepermission/queries/permission_insert.sql b/pkg/registry/apis/iam/resourcepermission/queries/permission_insert.sql index 1ba966e21eb..1dc0ac83e3b 100644 --- a/pkg/registry/apis/iam/resourcepermission/queries/permission_insert.sql +++ b/pkg/registry/apis/iam/resourcepermission/queries/permission_insert.sql @@ -1,11 +1,11 @@ INSERT INTO {{ .Ident .PermissionTable }} (role_id, action, scope, created, updated, kind, attribute, identifier) VALUES ( - {{ .Arg $.RoleID }}, - {{ .Arg $.Permission.Action }}, - {{ .Arg $.Permission.Scope }}, - {{ .Arg $.Now }}, - {{ .Arg $.Now }}, - {{ .Arg $.Permission.Kind }}, - {{ .Arg $.Permission.Attribute }}, - {{ .Arg $.Permission.Identifier }} + {{ .Arg .RoleID }}, + {{ .Arg .Permission.Action }}, + {{ .Arg .Permission.Scope }}, + {{ .Arg .Now }}, + {{ .Arg .Now }}, + {{ .Arg .Permission.Kind }}, + {{ .Arg .Permission.Attribute }}, + {{ .Arg .Permission.Identifier }} ) diff --git a/pkg/registry/apis/iam/resourcepermission/queries/permission_remove.sql b/pkg/registry/apis/iam/resourcepermission/queries/permission_remove.sql new file mode 100644 index 00000000000..56ffa56dab0 --- /dev/null +++ b/pkg/registry/apis/iam/resourcepermission/queries/permission_remove.sql @@ -0,0 +1,9 @@ +DELETE FROM {{ .Ident .PermissionTable }} AS p +WHERE p.scope = {{ .Arg .Scope }} AND p.action = {{ .Arg .Action }} +AND p.role_id = ( + SELECT r.id + FROM {{ .Ident .RoleTable }} AS r + WHERE r.org_id = {{ .Arg .OrgID }} + AND r.name = {{ .Arg .RoleName }} + LIMIT 1 +) diff --git a/pkg/registry/apis/iam/resourcepermission/sql.go b/pkg/registry/apis/iam/resourcepermission/sql.go index ba8c0d93ea1..e66542f2e76 100644 --- a/pkg/registry/apis/iam/resourcepermission/sql.go +++ b/pkg/registry/apis/iam/resourcepermission/sql.go @@ -156,7 +156,7 @@ func (s *ResourcePermSqlBackend) getRbacAssignmentsWithTx(ctx context.Context, s } // getResourcePermission retrieves a single ResourcePermission by its name in the format -- (e.g. dashboard.grafana.app-dashboards-ad5rwqs) -func (s *ResourcePermSqlBackend) getResourcePermission(ctx context.Context, sql *legacysql.LegacyDatabaseHelper, ns types.NamespaceInfo, name string) (*v0alpha1.ResourcePermission, error) { +func (s *ResourcePermSqlBackend) getResourcePermission(ctx context.Context, sql *legacysql.LegacyDatabaseHelper, tx *session.SessionTx, ns types.NamespaceInfo, name string) (*v0alpha1.ResourcePermission, error) { mapper, grn, err := s.splitResourceName(name) if err != nil { return nil, err @@ -168,11 +168,10 @@ func (s *ResourcePermSqlBackend) getResourcePermission(ctx context.Context, sql ActionSets: mapper.ActionSets(), } - var assignments []rbacAssignment - err = sql.DB.GetSqlxSession().WithTransaction(ctx, func(tx *session.SessionTx) error { - assignments, err = s.getRbacAssignmentsWithTx(ctx, sql, tx, resourceQuery) - return err - }) + assignments, err := s.getRbacAssignmentsWithTx(ctx, sql, tx, resourceQuery) + if err != nil { + return nil, err + } if len(assignments) == 0 { return nil, fmt.Errorf("resource permission %q: %w", resourceQuery.Scopes, errNotFound) @@ -263,10 +262,10 @@ func (s *ResourcePermSqlBackend) storeRbacAssignment(ctx context.Context, dbHelp // buildRbacAssignments builds the list of assignments (role assignments and permissions) for a given ResourcePermission spec // It resolves user/team/service account UIDs to internal IDs for the role name and assignee subjectID -func (s *ResourcePermSqlBackend) buildRbacAssignments(ctx context.Context, ns types.NamespaceInfo, mapper Mapper, v0ResourcePerm *v0alpha1.ResourcePermission, rbacScope string) ([]rbacAssignmentCreate, error) { - assignments := make([]rbacAssignmentCreate, 0, len(v0ResourcePerm.Spec.Permissions)) +func (s *ResourcePermSqlBackend) buildRbacAssignments(ctx context.Context, ns types.NamespaceInfo, mapper Mapper, v0ResourcePerm []v0alpha1.ResourcePermissionspecPermission, rbacScope string) ([]rbacAssignmentCreate, error) { + assignments := make([]rbacAssignmentCreate, 0, len(v0ResourcePerm)) - for _, perm := range v0ResourcePerm.Spec.Permissions { + for _, perm := range v0ResourcePerm { rbacActionSet, err := mapper.ActionSet(perm.Verb) if err != nil { return nil, err @@ -371,22 +370,11 @@ func (s *ResourcePermSqlBackend) existsResourcePermission(ctx context.Context, t func (s *ResourcePermSqlBackend) createResourcePermission( ctx context.Context, dbHelper *legacysql.LegacyDatabaseHelper, ns types.NamespaceInfo, mapper Mapper, grn *groupResourceName, v0ResourcePerm *v0alpha1.ResourcePermission, ) (int64, error) { - if v0ResourcePerm == nil { - return 0, fmt.Errorf("resource permission cannot be nil") + if err := validateCreateAndUpdateInput(v0ResourcePerm, grn); err != nil { + return 0, err } - if len(v0ResourcePerm.Spec.Permissions) == 0 { - return 0, fmt.Errorf("resource permission must have at least one permission: %w", errInvalidSpec) - } - - // Validate that the group/resource/name in the name matches the spec - if grn.Group != v0ResourcePerm.Spec.Resource.ApiGroup || - grn.Resource != v0ResourcePerm.Spec.Resource.Resource || - grn.Name != v0ResourcePerm.Spec.Resource.Name { - return 0, fmt.Errorf("resource permission name does not match spec: %w", errInvalidSpec) - } - - assignments, err := s.buildRbacAssignments(ctx, ns, mapper, v0ResourcePerm, mapper.Scope(grn.Name)) + assignments, err := s.buildRbacAssignments(ctx, ns, mapper, v0ResourcePerm.Spec.Permissions, mapper.Scope(grn.Name)) if err != nil { return 0, err } @@ -416,6 +404,116 @@ func (s *ResourcePermSqlBackend) createResourcePermission( // Update +func (s *ResourcePermSqlBackend) updateResourcePermission(ctx context.Context, dbHelper *legacysql.LegacyDatabaseHelper, ns types.NamespaceInfo, mapper Mapper, grn *groupResourceName, v0ResourcePerm *v0alpha1.ResourcePermission) (int64, error) { + if err := validateCreateAndUpdateInput(v0ResourcePerm, grn); err != nil { + return 0, err + } + + err := dbHelper.DB.GetSqlxSession().WithTransaction(ctx, func(tx *session.SessionTx) error { + currentPerms, err := s.getResourcePermission(ctx, dbHelper, tx, ns, grn.string()) + if err != nil { + if errors.Is(err, errNotFound) { + return fmt.Errorf("resource permissions not found: %w", errNotFound) + } + s.logger.Error("could not get resource permissions", "orgID", ns.OrgID, "scope", grn.Name, "error", err.Error()) + return fmt.Errorf("could not get the existing resource permissions for resource %s", grn.Name) + } + + permissionsToAdd, permissionsToRemove := diffPermissions(currentPerms.Spec.Permissions, v0ResourcePerm.Spec.Permissions) + + if len(permissionsToRemove) > 0 { + permsToRemove, err := s.buildRbacAssignments(ctx, ns, mapper, permissionsToRemove, mapper.Scope(grn.Name)) + if err != nil { + return err + } + + for _, perm := range permsToRemove { + removePermQuery, args, err := buildRemovePermissionQuery(dbHelper, perm.Scope, perm.Action, perm.RoleName, ns.OrgID) + if err != nil { + return err + } + _, err = tx.Exec(ctx, removePermQuery, args...) + if err != nil { + s.logger.Error("could not remove role permission", "scope", perm.Scope, "role", perm.RoleName, "error", err.Error()) + return fmt.Errorf("could not remove role permission") + } + } + } + + if len(permissionsToAdd) > 0 { + permsToAdd, err := s.buildRbacAssignments(ctx, ns, mapper, permissionsToAdd, mapper.Scope(grn.Name)) + if err != nil { + return err + } + + for _, assignment := range permsToAdd { + if err := s.storeRbacAssignment(ctx, dbHelper, tx, ns.OrgID, assignment); err != nil { + return err + } + } + } + + return nil + }) + + if err != nil { + return 0, err + } + + // Return a timestamp as resource version + return timeNow().UnixMilli(), nil +} + +func diffPermissions(currentPermissions, desiredPermissions []v0alpha1.ResourcePermissionspecPermission) (permissionsToAdd, permissionsToRemove []v0alpha1.ResourcePermissionspecPermission) { + for _, desired := range desiredPermissions { + found := false + for _, existing := range currentPermissions { + if desired.Name == existing.Name && desired.Kind == existing.Kind && desired.Verb == existing.Verb { + found = true + break + } + } + if !found { + permissionsToAdd = append(permissionsToAdd, desired) + } + } + + // Compile a list of permissions to remove + for _, existing := range currentPermissions { + found := false + for _, desired := range desiredPermissions { + if desired.Name == existing.Name && desired.Kind == existing.Kind && desired.Verb == existing.Verb { + found = true + break + } + } + if !found { + permissionsToRemove = append(permissionsToRemove, existing) + } + } + + return permissionsToAdd, permissionsToRemove +} + +func validateCreateAndUpdateInput(v0ResourcePerm *v0alpha1.ResourcePermission, grn *groupResourceName) error { + if v0ResourcePerm == nil { + return fmt.Errorf("resource permission cannot be nil") + } + + if len(v0ResourcePerm.Spec.Permissions) == 0 { + return fmt.Errorf("resource permission must have at least one permission: %w", errInvalidSpec) + } + + // Validate that the group/resource/name in the name matches the spec + if grn.Group != v0ResourcePerm.Spec.Resource.ApiGroup || + grn.Resource != v0ResourcePerm.Spec.Resource.Resource || + grn.Name != v0ResourcePerm.Spec.Resource.Name { + return fmt.Errorf("resource permission name does not match spec: %w", errInvalidSpec) + } + + return nil +} + // Delete // deleteResourcePermission deletes resource permissions for a single ResourcePermission resource referenced by its name in the format -- (e.g. dashboard.grafana.app-dashboards-ad5rwqs) diff --git a/pkg/registry/apis/iam/resourcepermission/sql_test.go b/pkg/registry/apis/iam/resourcepermission/sql_test.go index 977ac4b9981..7d6b492c590 100644 --- a/pkg/registry/apis/iam/resourcepermission/sql_test.go +++ b/pkg/registry/apis/iam/resourcepermission/sql_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/registry/apis/iam/common" "github.com/grafana/grafana/pkg/registry/apis/iam/legacy" "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/sqlstore/session" "github.com/grafana/grafana/pkg/storage/legacysql" "github.com/grafana/grafana/pkg/tests/testsuite" "github.com/grafana/grafana/pkg/util/testutil" @@ -297,7 +298,12 @@ func TestIntegration_ResourcePermSqlBackend_getResourcePermission(t *testing.T) ns := types.NamespaceInfo{ OrgID: tt.orgID, } - got, err := backend.getResourcePermission(context.Background(), sql, ns, tt.resource) + var got *v0alpha1.ResourcePermission + err = sql.DB.GetSqlxSession().WithTransaction(context.Background(), func(tx *session.SessionTx) error { + got, err = backend.getResourcePermission(context.Background(), sql, tx, ns, tt.resource) + return err + }) + if tt.err != nil { require.Error(t, err) require.ErrorIs(t, err, tt.err) @@ -369,7 +375,10 @@ func TestIntegration_ResourcePermSqlBackend_deleteResourcePermission(t *testing. require.NoError(t, err) // check that the resource has been deleted - _, err = backend.getResourcePermission(context.Background(), sql, ns, tt.resource) + err = sql.DB.GetSqlxSession().WithTransaction(context.Background(), func(tx *session.SessionTx) error { + _, err = backend.getResourcePermission(context.Background(), sql, tx, ns, tt.resource) + return err + }) require.Error(t, err) }) } @@ -487,6 +496,113 @@ func TestIntegration_ResourcePermSqlBackend_CreateResourcePermission(t *testing. }) } +func TestIntegration_ResourcePermSqlBackend_UpdateResourcePermission(t *testing.T) { + testutil.SkipIntegrationTestInShortMode(t) + + backend := setupBackend(t) + backend.identityStore = NewFakeIdentityStore(t) + ctx := context.Background() + sql, err := backend.dbProvider(ctx) + require.NoError(t, err) + setupTestRoles(t, sql.DB) + + t.Run("should fail to update resource permission for a resource that doesn't have any permissions yet", func(t *testing.T) { + resourcePerm := &v0alpha1.ResourcePermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "folder.grafana.app-folders-newfold", + Namespace: "default", + }, + Spec: v0alpha1.ResourcePermissionSpec{ + Resource: v0alpha1.ResourcePermissionspecResource{ + ApiGroup: "folder.grafana.app", + Resource: "folders", + Name: "newfold", + }, + Permissions: []v0alpha1.ResourcePermissionspecPermission{ + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindBasicRole, + Name: "Viewer", + Verb: "view", + }, + }, + }, + } + + mapper, grn, err := backend.splitResourceName(resourcePerm.Name) + require.NoError(t, err) + + _, err = backend.updateResourcePermission(ctx, sql, types.NamespaceInfo{Value: "default", OrgID: 1}, mapper, grn, resourcePerm) + require.Error(t, err) + require.ErrorIs(t, err, errNotFound) + }) + + t.Run("should update resource permission", func(t *testing.T) { + resourcePerm := &v0alpha1.ResourcePermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "folder.grafana.app-folders-fold1", + Namespace: "default", + }, + Spec: v0alpha1.ResourcePermissionSpec{ + Resource: v0alpha1.ResourcePermissionspecResource{ + ApiGroup: "folder.grafana.app", + Resource: "folders", + Name: "fold1", + }, + Permissions: []v0alpha1.ResourcePermissionspecPermission{ + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindBasicRole, + Name: "Editor", + Verb: "view", + }, + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindUser, + Name: "user-1", + Verb: "view", + }, + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindServiceAccount, + Name: "sa-1", + Verb: "admin", + }, + }, + }, + } + + mapper, grn, err := backend.splitResourceName(resourcePerm.Name) + require.NoError(t, err) + + rv, err := backend.updateResourcePermission(ctx, sql, types.NamespaceInfo{Value: "default", OrgID: 1}, mapper, grn, resourcePerm) + require.NoError(t, err) + require.Equal(t, timeNow().UnixMilli(), rv) + + var permission accesscontrol.Permission + sess := sql.DB.GetSqlxSession() + + // Check that the right permissions exist and that the old ones have been removed + // User-1 should still have view access to fold1 + // User-2 should no longer have edit on fold1 + // Service account should now have admin on fold1 + // Builtin Editor should now have view access to fold1 + + err = sess.Get(ctx, &permission, "SELECT action FROM permission WHERE scope = ? AND role_id = (SELECT role_id FROM user_role WHERE org_id = ? AND user_id = ?)", "folders:uid:fold1", 1, "1") + require.NoError(t, err) + require.Equal(t, "folders:view", permission.Action) + + count := 0 + err = sess.Get(ctx, &count, "SELECT COUNT(*) FROM permission WHERE role_id = (SELECT role_id FROM user_role WHERE org_id = ? AND user_id = ?)", 1, "2") + require.NoError(t, err) + require.Equal(t, 0, count) + + err = sess.Get(ctx, &permission, "SELECT action FROM permission WHERE scope = ? AND role_id = (SELECT role_id FROM user_role WHERE org_id = ? AND user_id = ?)", "folders:uid:fold1", 1, "3") + require.NoError(t, err) + require.Equal(t, "folders:admin", permission.Action) + + err = sess.Get(ctx, &permission, "SELECT action FROM permission WHERE scope = ? AND role_id = (SELECT role_id FROM builtin_role WHERE org_id = ? AND role = ?)", "folders:uid:fold1", 1, "Editor") + require.NoError(t, err) + require.Equal(t, "folders:view", permission.Action) + }) +} + type fakeIdentityStore struct { t *testing.T @@ -499,8 +615,8 @@ type fakeIdentityStore struct { func NewFakeIdentityStore(t *testing.T) *fakeIdentityStore { return &fakeIdentityStore{ t: t, - users: map[string]int64{"captain": 101}, - serviceAccounts: map[string]int64{"robot": 201}, + users: map[string]int64{"captain": 101, "user-1": 1, "user-2": 2}, + serviceAccounts: map[string]int64{"robot": 201, "sa-1": 3}, teams: map[string]int64{"devs": 301}, expectedNs: types.NamespaceInfo{Value: "default"}, } diff --git a/pkg/registry/apis/iam/resourcepermission/storage_backend.go b/pkg/registry/apis/iam/resourcepermission/storage_backend.go index 01d3434c1ff..72449ce4bca 100644 --- a/pkg/registry/apis/iam/resourcepermission/storage_backend.go +++ b/pkg/registry/apis/iam/resourcepermission/storage_backend.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/registry/apis/iam/common" idStore "github.com/grafana/grafana/pkg/registry/apis/iam/legacy" + "github.com/grafana/grafana/pkg/services/sqlstore/session" "github.com/grafana/grafana/pkg/storage/legacysql" "github.com/grafana/grafana/pkg/storage/unified/resource" "github.com/grafana/grafana/pkg/storage/unified/resourcepb" @@ -156,7 +157,12 @@ func (s *ResourcePermSqlBackend) ReadResource(ctx context.Context, req *resource return rsp } - resourcePermission, err := s.getResourcePermission(ctx, dbHelper, ns, req.Key.Name) + var resourcePermission *v0alpha1.ResourcePermission + err = dbHelper.DB.GetSqlxSession().WithTransaction(ctx, func(tx *session.SessionTx) error { + resourcePermission, err = s.getResourcePermission(ctx, dbHelper, tx, ns, req.Key.Name) + return err + }) + if err != nil { if errors.Is(err, errNotFound) { rsp.Error = resource.AsErrorResult( @@ -171,6 +177,7 @@ func (s *ResourcePermSqlBackend) ReadResource(ctx context.Context, req *resource } rsp.ResourceVersion = resourcePermission.GetUpdateTimestamp().UnixMilli() + resourcePermission.Namespace = ns.Value // ensure namespace is set, this is required when existing and new resources are compared for updates rsp.Value, err = json.Marshal(resourcePermission) if err != nil { rsp.Error = resource.AsErrorResult(err) @@ -245,7 +252,7 @@ func (s *ResourcePermSqlBackend) WriteEvent(ctx context.Context, event resource. switch event.Type { case resourcepb.WatchEvent_DELETED: err = s.deleteResourcePermission(ctx, dbHelper, ns, event.Key.Name) - case resourcepb.WatchEvent_ADDED: + case resourcepb.WatchEvent_ADDED, resourcepb.WatchEvent_MODIFIED: { var v0resourceperm *v0alpha1.ResourcePermission v0resourceperm, err = getResourcePermissionFromEvent(event) @@ -264,14 +271,22 @@ func (s *ResourcePermSqlBackend) WriteEvent(ctx context.Context, event resource. ) } - rv, err = s.createResourcePermission(ctx, dbHelper, ns, mapper, grn, v0resourceperm) + if event.Type == resourcepb.WatchEvent_ADDED { + rv, err = s.createResourcePermission(ctx, dbHelper, ns, mapper, grn, v0resourceperm) + if err != nil && errors.Is(err, errConflict) { + return 0, apierrors.NewConflict(v0alpha1.ResourcePermissionInfo.GroupResource(), event.Key.Name, err) + } + } else { + rv, err = s.updateResourcePermission(ctx, dbHelper, ns, mapper, grn, v0resourceperm) + if errors.Is(err, errNotFound) { + return 0, apierrors.NewNotFound(v0alpha1.ResourcePermissionInfo.GroupResource(), event.Key.Name) + } + } + if err != nil { if errors.Is(err, errInvalidSpec) || errors.Is(err, errInvalidName) { return 0, apierrors.NewBadRequest(err.Error()) } - if errors.Is(err, errConflict) { - return 0, apierrors.NewConflict(v0alpha1.ResourcePermissionInfo.GroupResource(), event.Key.Name, err) - } return 0, err } } diff --git a/pkg/registry/apis/iam/resourcepermission/storage_backend_test.go b/pkg/registry/apis/iam/resourcepermission/storage_backend_test.go index f8ace252491..0192251cf5c 100644 --- a/pkg/registry/apis/iam/resourcepermission/storage_backend_test.go +++ b/pkg/registry/apis/iam/resourcepermission/storage_backend_test.go @@ -708,3 +708,240 @@ func TestIntegration_WriteEvent_Delete(t *testing.T) { require.Len(t, permission.Spec.Permissions, 4) }) } + +func TestWriteEvent_Modify(t *testing.T) { + store := db.InitTestDB(t) + + timeNow = func() time.Time { + return time.Date(2025, 8, 28, 17, 13, 0, 0, time.UTC) + } + + sqlHelper := &legacysql.LegacyDatabaseHelper{ + DB: store, + Table: func(name string) string { return name }, + } + + dbProvider := func(ctx context.Context) (*legacysql.LegacyDatabaseHelper, error) { + return sqlHelper, nil + } + + t.Run("should error with invalid namespace", func(t *testing.T) { + backend := ProvideStorageBackend(dbProvider) + + rv, err := backend.WriteEvent(context.Background(), resource.WriteEvent{ + Type: resourcepb.WatchEvent_MODIFIED, + Key: &resourcepb.ResourceKey{Name: "folder.grafana.app-folders-fold1", Namespace: "invalid"}, + }) + + require.Zero(t, rv) + require.NotNil(t, err) + require.Contains(t, err.Error(), "requires a valid namespace") + }) + + t.Run("should error if there are no permission specified in the body", func(t *testing.T) { + backend := ProvideStorageBackend(dbProvider) + + resourcePerm, err := utils.MetaAccessor(&v0alpha1.ResourcePermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "folder.grafana.app-folders-fold1", + Namespace: "default", + }, + Spec: v0alpha1.ResourcePermissionSpec{ + Resource: v0alpha1.ResourcePermissionspecResource{ + ApiGroup: "folder.grafana.app", + Resource: "folders", + Name: "fold1", + }, + }, + }) + require.NoError(t, err) + + gr := v0alpha1.ResourcePermissionInfo.GroupResource() + rv, err := backend.WriteEvent(context.Background(), resource.WriteEvent{ + Type: resourcepb.WatchEvent_MODIFIED, + Key: &resourcepb.ResourceKey{Group: gr.Group, Resource: gr.Resource, Name: "folder.grafana.app-folders-fold1", Namespace: "default"}, + Object: resourcePerm, + }) + require.Zero(t, rv) + require.NotNil(t, err) + require.Contains(t, err.Error(), errInvalidSpec.Error()) + }) + + t.Run("should error if name and spec do not match", func(t *testing.T) { + backend := ProvideStorageBackend(dbProvider) + + resourcePerm, err := utils.MetaAccessor(&v0alpha1.ResourcePermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "folder.grafana.app-folders-fold1", + Namespace: "default", + }, + Spec: v0alpha1.ResourcePermissionSpec{ + Resource: v0alpha1.ResourcePermissionspecResource{ + ApiGroup: "folder.grafana.app", + Resource: "folders", + Name: "fold2", + }, + Permissions: []v0alpha1.ResourcePermissionspecPermission{ + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindBasicRole, + Name: "Viewer", + Verb: "Admin", + }, + }, + }, + }) + require.NoError(t, err) + + gr := v0alpha1.ResourcePermissionInfo.GroupResource() + rv, err := backend.WriteEvent(context.Background(), resource.WriteEvent{ + Type: resourcepb.WatchEvent_MODIFIED, + Key: &resourcepb.ResourceKey{Group: gr.Group, Resource: gr.Resource, Name: "folder.grafana.app-folders-fold1", Namespace: "default"}, + Object: resourcePerm, + }) + require.Zero(t, rv) + require.NotNil(t, err) + require.Contains(t, err.Error(), errInvalidSpec.Error()) + }) + + t.Run("should error if resource name is empty", func(t *testing.T) { + backend := ProvideStorageBackend(dbProvider) + + resourcePerm, err := utils.MetaAccessor(&v0alpha1.ResourcePermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "folder.grafana.app-folders-", + Namespace: "default", + }, + Spec: v0alpha1.ResourcePermissionSpec{ + Resource: v0alpha1.ResourcePermissionspecResource{ + ApiGroup: "folder.grafana.app", + Resource: "folders", + Name: "", + }, + Permissions: []v0alpha1.ResourcePermissionspecPermission{ + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindBasicRole, + Name: "Viewer", + Verb: "Admin", + }, + }, + }, + }) + require.NoError(t, err) + + gr := v0alpha1.ResourcePermissionInfo.GroupResource() + rv, err := backend.WriteEvent(context.Background(), resource.WriteEvent{ + Type: resourcepb.WatchEvent_MODIFIED, + Key: &resourcepb.ResourceKey{Group: gr.Group, Resource: gr.Resource, Name: "folder.grafana.app-folders-", Namespace: "default"}, + Object: resourcePerm, + }) + require.Zero(t, rv) + require.NotNil(t, err) + require.Contains(t, err.Error(), errInvalidName.Error()) + }) + + t.Run("should error if the resource is unknown", func(t *testing.T) { + backend := ProvideStorageBackend(dbProvider) + + resourcePerm, err := utils.MetaAccessor(&v0alpha1.ResourcePermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "unknown.grafana.app-unknown-ukn1", + Namespace: "default", + }, + Spec: v0alpha1.ResourcePermissionSpec{ + Resource: v0alpha1.ResourcePermissionspecResource{ + ApiGroup: "unknown.grafana.app", + Resource: "unknown", + Name: "ukn1", + }, + Permissions: []v0alpha1.ResourcePermissionspecPermission{ + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindBasicRole, + Name: "Viewer", + Verb: "Admin", + }, + }, + }, + }) + require.NoError(t, err) + + gr := v0alpha1.ResourcePermissionInfo.GroupResource() + rv, err := backend.WriteEvent(context.Background(), resource.WriteEvent{ + Type: resourcepb.WatchEvent_MODIFIED, + Key: &resourcepb.ResourceKey{Group: gr.Group, Resource: gr.Resource, Name: "unknown.grafana.app-unknown-ukn1", Namespace: "default"}, + Object: resourcePerm, + }) + require.Zero(t, rv) + require.NotNil(t, err) + require.Contains(t, err.Error(), errUnknownGroupResource.Error()) + }) + + t.Run("should work with valid resource permission", func(t *testing.T) { + backend := ProvideStorageBackend(dbProvider) + backend.identityStore = NewFakeIdentityStore(t) + + resourcePerm, err := utils.MetaAccessor(&v0alpha1.ResourcePermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "folder.grafana.app-folders-fold1", + Namespace: "default", + }, + Spec: v0alpha1.ResourcePermissionSpec{ + Resource: v0alpha1.ResourcePermissionspecResource{ + ApiGroup: "folder.grafana.app", + Resource: "folders", + Name: "fold1", + }, + Permissions: []v0alpha1.ResourcePermissionspecPermission{ + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindBasicRole, + Name: "Viewer", + Verb: "Admin", + }, + }, + }, + }) + require.NoError(t, err) + + // Create resource first + gr := v0alpha1.ResourcePermissionInfo.GroupResource() + rv, err := backend.WriteEvent(context.Background(), resource.WriteEvent{ + Type: resourcepb.WatchEvent_ADDED, + Key: &resourcepb.ResourceKey{Group: gr.Group, Resource: gr.Resource, Name: "folder.grafana.app-folders-fold1", Namespace: "default"}, + Object: resourcePerm, + }) + + require.NoError(t, err) + require.Equal(t, timeNow().UnixMilli(), rv) + + // Modify resource + resourcePerm, err = utils.MetaAccessor(&v0alpha1.ResourcePermission{ + ObjectMeta: metav1.ObjectMeta{ + Name: "folder.grafana.app-folders-fold1", + Namespace: "default", + }, + Spec: v0alpha1.ResourcePermissionSpec{ + Resource: v0alpha1.ResourcePermissionspecResource{ + ApiGroup: "folder.grafana.app", + Resource: "folders", + Name: "fold1", + }, + Permissions: []v0alpha1.ResourcePermissionspecPermission{ + { + Kind: v0alpha1.ResourcePermissionSpecPermissionKindBasicRole, + Name: "Viewer", + Verb: "Edit", + }, + }, + }, + }) + require.NoError(t, err) + + rv, err = backend.WriteEvent(context.Background(), resource.WriteEvent{ + Type: resourcepb.WatchEvent_MODIFIED, + Key: &resourcepb.ResourceKey{Group: gr.Group, Resource: gr.Resource, Name: "folder.grafana.app-folders-fold1", Namespace: "default"}, + Object: resourcePerm, + }) + + require.NoError(t, err) + require.Equal(t, timeNow().UnixMilli(), rv) + }) +} diff --git a/pkg/registry/apis/iam/resourcepermission/templates.go b/pkg/registry/apis/iam/resourcepermission/templates.go index 234a840d561..79a30fe70e8 100644 --- a/pkg/registry/apis/iam/resourcepermission/templates.go +++ b/pkg/registry/apis/iam/resourcepermission/templates.go @@ -23,6 +23,7 @@ var ( roleInsertTplt = mustTemplate("role_insert.sql") assignmentInsertTplt = mustTemplate("assignment_insert.sql") permissionInsertTplt = mustTemplate("permission_insert.sql") + permissionRemoveTplt = mustTemplate("permission_remove.sql") pageQueryTplt = mustTemplate("page_query.sql") latestUpdateTplt = mustTemplate("latest_update_query.sql") ) @@ -236,6 +237,37 @@ func buildInsertPermissionQuery(dbHelper *legacysql.LegacyDatabaseHelper, roleID // Update +type removePermissionTemplate struct { + sqltemplate.SQLTemplate + PermissionTable string + RoleTable string + Scope string + Action string + OrgID int64 + RoleName string +} + +func (t removePermissionTemplate) Validate() error { + return nil +} + +func buildRemovePermissionQuery(dbHelper *legacysql.LegacyDatabaseHelper, scope, action, roleName string, orgID int64) (string, []any, error) { + req := removePermissionTemplate{ + SQLTemplate: sqltemplate.New(dbHelper.DialectForDriver()), + PermissionTable: dbHelper.Table("permission"), + RoleTable: dbHelper.Table("role"), + Scope: scope, + Action: action, + OrgID: orgID, + RoleName: roleName, + } + rawQuery, err := sqltemplate.Execute(permissionRemoveTplt, req) + if err != nil { + return "", nil, fmt.Errorf("rendering sql template: %w", err) + } + return rawQuery, req.GetArgs(), nil +} + // Delete type deleteResourcePermissionsQueryTemplate struct { diff --git a/pkg/registry/apis/iam/resourcepermission/templates_test.go b/pkg/registry/apis/iam/resourcepermission/templates_test.go index 6bc492587b7..6229add4140 100644 --- a/pkg/registry/apis/iam/resourcepermission/templates_test.go +++ b/pkg/registry/apis/iam/resourcepermission/templates_test.go @@ -43,6 +43,20 @@ func TestTemplates(t *testing.T) { return &v } + getRemovePermission := func(scope, action, roleName string) sqltemplate.SQLTemplate { + v := removePermissionTemplate{ + SQLTemplate: sqltemplate.New(nodb.DialectForDriver()), + PermissionTable: nodb.Table("permission"), + RoleTable: nodb.Table("role"), + Scope: scope, + Action: action, + OrgID: 55, + RoleName: roleName, + } + v.SQLTemplate = mocks.NewTestingSQLTemplate() + return &v + } + getInsertAssignment := func(orgID int64, roleID int64, assignment rbacAssignmentCreate) sqltemplate.SQLTemplate { v := insertAssignmentTemplate{ SQLTemplate: sqltemplate.New(nodb.DialectForDriver()), @@ -137,6 +151,12 @@ func TestTemplates(t *testing.T) { }), }, }, + permissionRemoveTplt: { + { + Name: "remove_permission", + Data: getRemovePermission("folders:uid:folder1", "folders:edit", "managed:users:1:permissions"), + }, + }, assignmentInsertTplt: { { Name: "insert user assignment", diff --git a/pkg/registry/apis/iam/resourcepermission/testdata/mysql--permission_remove-remove_permission.sql b/pkg/registry/apis/iam/resourcepermission/testdata/mysql--permission_remove-remove_permission.sql new file mode 100755 index 00000000000..2ad8648da08 --- /dev/null +++ b/pkg/registry/apis/iam/resourcepermission/testdata/mysql--permission_remove-remove_permission.sql @@ -0,0 +1,9 @@ +DELETE FROM `grafana`.`permission` AS p +WHERE p.scope = 'folders:uid:folder1' AND p.action = 'folders:edit' +AND p.role_id = ( + SELECT r.id + FROM `grafana`.`role` AS r + WHERE r.org_id = 55 + AND r.name = 'managed:users:1:permissions' + LIMIT 1 +) diff --git a/pkg/registry/apis/iam/resourcepermission/testdata/postgres--permission_remove-remove_permission.sql b/pkg/registry/apis/iam/resourcepermission/testdata/postgres--permission_remove-remove_permission.sql new file mode 100755 index 00000000000..1a5e5326586 --- /dev/null +++ b/pkg/registry/apis/iam/resourcepermission/testdata/postgres--permission_remove-remove_permission.sql @@ -0,0 +1,9 @@ +DELETE FROM "grafana"."permission" AS p +WHERE p.scope = 'folders:uid:folder1' AND p.action = 'folders:edit' +AND p.role_id = ( + SELECT r.id + FROM "grafana"."role" AS r + WHERE r.org_id = 55 + AND r.name = 'managed:users:1:permissions' + LIMIT 1 +) diff --git a/pkg/registry/apis/iam/resourcepermission/testdata/sqlite--permission_remove-remove_permission.sql b/pkg/registry/apis/iam/resourcepermission/testdata/sqlite--permission_remove-remove_permission.sql new file mode 100755 index 00000000000..1a5e5326586 --- /dev/null +++ b/pkg/registry/apis/iam/resourcepermission/testdata/sqlite--permission_remove-remove_permission.sql @@ -0,0 +1,9 @@ +DELETE FROM "grafana"."permission" AS p +WHERE p.scope = 'folders:uid:folder1' AND p.action = 'folders:edit' +AND p.role_id = ( + SELECT r.id + FROM "grafana"."role" AS r + WHERE r.org_id = 55 + AND r.name = 'managed:users:1:permissions' + LIMIT 1 +) From 842ae463b719d87d6e5993aba39a236c696fdfd9 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Fri, 12 Sep 2025 13:11:56 +0300 Subject: [PATCH 24/48] Chore: update otel v1.37.0 to v1.38.0 (#110985) --- apps/advisor/go.mod | 16 ++-- apps/alerting/alertenrichment/go.mod | 3 +- apps/alerting/alertenrichment/go.sum | 8 +- apps/alerting/notifications/go.mod | 28 +++---- apps/alerting/notifications/go.sum | 70 +++++++++-------- apps/alerting/rules/go.mod | 29 ++++--- apps/alerting/rules/go.sum | 70 +++++++++-------- apps/dashboard/go.mod | 29 ++++--- apps/dashboard/go.sum | 64 +++++++-------- apps/folder/go.mod | 9 ++- apps/folder/go.sum | 20 ++--- apps/iam/go.mod | 48 ++++++------ apps/iam/go.sum | 112 +++++++++++++-------------- apps/investigations/go.mod | 29 ++++--- apps/investigations/go.sum | 70 +++++++++-------- apps/playlist/go.mod | 29 ++++--- apps/playlist/go.sum | 70 +++++++++-------- apps/plugins/go.mod | 29 ++++--- apps/plugins/go.sum | 70 +++++++++-------- apps/preferences/go.mod | 9 ++- apps/preferences/go.sum | 20 ++--- apps/provisioning/go.mod | 16 ++-- apps/provisioning/go.sum | 42 +++++----- apps/secret/go.mod | 15 ++-- apps/secret/go.sum | 42 +++++----- apps/shorturl/go.mod | 29 ++++--- apps/shorturl/go.sum | 70 +++++++++-------- go.mod | 48 ++++++------ go.sum | 112 +++++++++++++-------------- go.work.sum | 27 ++++++- pkg/aggregator/go.mod | 28 +++---- pkg/aggregator/go.sum | 64 +++++++-------- pkg/apimachinery/go.mod | 16 ++-- pkg/apimachinery/go.sum | 38 ++++----- pkg/apiserver/go.mod | 28 +++---- pkg/apiserver/go.sum | 66 ++++++++-------- pkg/build/go.mod | 34 ++++---- pkg/build/go.sum | 74 +++++++++--------- pkg/codegen/go.mod | 1 + pkg/codegen/go.sum | 4 +- pkg/plugins/codegen/go.sum | 4 +- pkg/promlib/go.mod | 29 ++++--- pkg/promlib/go.sum | 60 +++++++------- pkg/semconv/go.mod | 2 +- pkg/semconv/go.sum | 8 +- 45 files changed, 867 insertions(+), 822 deletions(-) diff --git a/apps/advisor/go.mod b/apps/advisor/go.mod index 41a8a3ccccf..a373972b216 100644 --- a/apps/advisor/go.mod +++ b/apps/advisor/go.mod @@ -244,14 +244,14 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect @@ -291,7 +291,7 @@ require ( modernc.org/libc v1.65.0 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.10.0 // indirect - modernc.org/sqlite v1.37.0 // indirect + modernc.org/sqlite v1.38.0 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect diff --git a/apps/alerting/alertenrichment/go.mod b/apps/alerting/alertenrichment/go.mod index f309d1cc413..f63cc376563 100644 --- a/apps/alerting/alertenrichment/go.mod +++ b/apps/alerting/alertenrichment/go.mod @@ -23,11 +23,12 @@ require ( github.com/mailru/easyjson v0.9.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/stretchr/testify v1.11.1 // indirect github.com/x448/float16 v0.8.4 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/text v0.29.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect diff --git a/apps/alerting/alertenrichment/go.sum b/apps/alerting/alertenrichment/go.sum index 62361150638..5fa5cfd9fd4 100644 --- a/apps/alerting/alertenrichment/go.sum +++ b/apps/alerting/alertenrichment/go.sum @@ -52,8 +52,8 @@ github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -89,8 +89,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/alerting/notifications/go.mod b/apps/alerting/notifications/go.mod index 873cd19332f..b6e76e96157 100644 --- a/apps/alerting/notifications/go.mod +++ b/apps/alerting/notifications/go.mod @@ -14,7 +14,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -38,7 +38,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/jonboulle/clockwork v0.5.0 // indirect @@ -71,14 +71,14 @@ require ( go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect @@ -92,10 +92,10 @@ require ( golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/apps/alerting/notifications/go.sum b/apps/alerting/notifications/go.sum index 81750c2da22..54b5de51bdc 100644 --- a/apps/alerting/notifications/go.sum +++ b/apps/alerting/notifications/go.sum @@ -8,8 +8,8 @@ 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/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -94,8 +94,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -183,8 +183,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= @@ -217,24 +217,24 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -247,8 +247,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -316,6 +316,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= 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= @@ -323,20 +325,20 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= 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.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= 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= diff --git a/apps/alerting/rules/go.mod b/apps/alerting/rules/go.mod index 076f3468432..529c8dc68e1 100644 --- a/apps/alerting/rules/go.mod +++ b/apps/alerting/rules/go.mod @@ -12,7 +12,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect @@ -30,7 +30,7 @@ require ( github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -54,15 +54,14 @@ require ( github.com/spf13/pflag v1.0.7 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect @@ -73,10 +72,10 @@ require ( golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.33.3 // indirect diff --git a/apps/alerting/rules/go.sum b/apps/alerting/rules/go.sum index 3c3ab51328f..8e94a91aa99 100644 --- a/apps/alerting/rules/go.sum +++ b/apps/alerting/rules/go.sum @@ -2,8 +2,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -51,8 +51,8 @@ github.com/grafana/grafana-app-sdk v0.40.3 h1:JFo7uAfbAJUfZ9neD7/4sODKm1xgu9zhck github.com/grafana/grafana-app-sdk v0.40.3/go.mod h1:j0KzHo3Sa6kd+lnwSScBNoV9Vobkg/YY9HtEjxpyPrk= github.com/grafana/grafana-app-sdk/logging v0.40.3 h1:2VXsXXEQiqAavRP8wusRDB6rDqf5lufP7A6NfjELqPE= github.com/grafana/grafana-app-sdk/logging v0.40.3/go.mod h1:otUD9XpJD7A5sCLb8mcs9hIXGdeV6lnhzVwe747g4RU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -116,8 +116,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -126,30 +126,30 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -193,14 +193,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/dashboard/go.mod b/apps/dashboard/go.mod index cef324bcda9..18d5ed38638 100644 --- a/apps/dashboard/go.mod +++ b/apps/dashboard/go.mod @@ -10,7 +10,7 @@ require ( github.com/grafana/grafana-plugin-sdk-go v0.278.0 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e github.com/prometheus/client_golang v1.23.0 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 golang.org/x/net v0.44.0 k8s.io/apimachinery v0.33.3 k8s.io/apiserver v0.33.3 @@ -23,7 +23,7 @@ require ( github.com/apache/arrow-go/v18 v18.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/chromedp/cdproto v0.0.0-20250429231605-6ed5b53462d4 // indirect @@ -58,7 +58,7 @@ require ( github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -110,14 +110,13 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/crypto v0.42.0 // indirect golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect @@ -131,10 +130,10 @@ require ( golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/apps/dashboard/go.sum b/apps/dashboard/go.sum index 78e25c56f6d..900a70892a1 100644 --- a/apps/dashboard/go.sum +++ b/apps/dashboard/go.sum @@ -18,8 +18,8 @@ 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/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= @@ -120,8 +120,8 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -260,8 +260,8 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 h1:aVGB3YnaS/JNfOW3tiHIlmNmTDg618va+eT0mVomgyI= @@ -296,31 +296,31 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.36.0/go.mod h1:VHu48l0YTRKSObd go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 h1:bQ1Gvah4Sp8z7epSkgJaNTuZm7sutfA6Fji2/7cKFMc= go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0/go.mod h1:9b8Q9rH52NgYH3ShiTFB5wf18Vt3RTH/VMB7LDcC1ug= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -410,14 +410,14 @@ golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhS golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/folder/go.mod b/apps/folder/go.mod index d15cbb0fb3f..08388e82581 100644 --- a/apps/folder/go.mod +++ b/apps/folder/go.mod @@ -42,18 +42,19 @@ require ( github.com/prometheus/common v0.65.0 // indirect github.com/prometheus/procfs v0.16.1 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/stretchr/testify v1.10.0 // indirect + github.com/stretchr/testify v1.11.1 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/term v0.35.0 // indirect golang.org/x/text v0.29.0 // indirect golang.org/x/time v0.13.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/client-go v0.33.3 // indirect diff --git a/apps/folder/go.sum b/apps/folder/go.sum index ff619de1424..e61f142abbf 100644 --- a/apps/folder/go.sum +++ b/apps/folder/go.sum @@ -95,24 +95,24 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -150,8 +150,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/iam/go.mod b/apps/iam/go.mod index 407c553de5f..23de89d859b 100644 --- a/apps/iam/go.mod +++ b/apps/iam/go.mod @@ -28,8 +28,8 @@ require ( github.com/grafana/grafana-app-sdk/plugin v0.40.3 github.com/grafana/grafana/apps/folder v0.0.0 github.com/grafana/grafana/pkg/apimachinery v0.0.0 - go.opentelemetry.io/otel v1.37.0 - go.opentelemetry.io/otel/trace v1.37.0 + go.opentelemetry.io/otel v1.38.0 + go.opentelemetry.io/otel/trace v1.38.0 k8s.io/apimachinery v0.33.3 k8s.io/client-go v0.33.3 k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff @@ -56,7 +56,7 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect github.com/BurntSushi/toml v1.5.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect @@ -121,7 +121,7 @@ require ( github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/caio/go-tdigest v3.1.0+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/chromedp/cdproto v0.0.0-20250429231605-6ed5b53462d4 // indirect @@ -160,7 +160,7 @@ require ( github.com/getkin/kin-openapi v0.132.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect github.com/go-jose/go-jose/v3 v3.0.4 // indirect - github.com/go-jose/go-jose/v4 v4.1.0 // indirect + github.com/go-jose/go-jose/v4 v4.1.1 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-ldap/ldap/v3 v3.4.4 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect @@ -226,7 +226,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/consul/api v1.31.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -350,7 +350,7 @@ require ( github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/stretchr/testify v1.10.0 // indirect + github.com/stretchr/testify v1.11.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tetratelabs/wazero v1.8.2 // indirect github.com/thomaspoignant/go-feature-flag v1.42.0 // indirect @@ -382,21 +382,21 @@ require ( go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.59.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect go.opentelemetry.io/otel/log v0.12.2 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.5.2 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -420,10 +420,10 @@ require ( gonum.org/v1/gonum v0.16.0 // indirect google.golang.org/api v0.235.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect @@ -442,10 +442,10 @@ require ( k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kms v0.33.3 // indirect k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect - modernc.org/libc v1.65.0 // indirect + modernc.org/libc v1.65.10 // indirect modernc.org/mathutil v1.7.1 // indirect - modernc.org/memory v1.10.0 // indirect - modernc.org/sqlite v1.37.0 // indirect + modernc.org/memory v1.11.0 // indirect + modernc.org/sqlite v1.38.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/apps/iam/go.sum b/apps/iam/go.sum index 42bddc83c25..b0389806073 100644 --- a/apps/iam/go.sum +++ b/apps/iam/go.sum @@ -115,8 +115,8 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0 h1:OqVGm6Ei3x5+yZmSJG1Mh2NwHvpVmZ08CB5qJhT9Nuk= @@ -321,8 +321,8 @@ github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6L github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -499,8 +499,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY= -github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -776,8 +776,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/api v1.31.2 h1:NicObVJHcCmyOIl7Z9iHPvvFrocgTYo9cITSGg0/7pw= @@ -1286,8 +1286,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO 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/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= @@ -1395,52 +1395,52 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.36.0/go.mod h1:VHu48l0YTRKSObd go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 h1:bQ1Gvah4Sp8z7epSkgJaNTuZm7sutfA6Fji2/7cKFMc= go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0/go.mod h1:9b8Q9rH52NgYH3ShiTFB5wf18Vt3RTH/VMB7LDcC1ug= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 h1:9PgnL3QNlj10uGxExowIDIZu66aVBwWhXmbOp1pa6RA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0/go.mod h1:0ineDcLELf6JmKfuo0wvvhAVMuxWFYvkTin2iV4ydPQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= go.opentelemetry.io/otel/exporters/prometheus v0.59.0 h1:HHf+wKS6o5++XZhS98wvILrLVgHxjA/AMjqHKes+uzo= go.opentelemetry.io/otel/exporters/prometheus v0.59.0/go.mod h1:R8GpRXTZrqvXHDEGVH5bF6+JqAZcK8PjJcZ5nGhEWiE= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 h1:12vMqzLLNZtXuXbJhSENRg+Vvx+ynNilV8twBLBsXMY= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2/go.mod h1:ZccPZoPOoq8x3Trik/fCsba7DEYDUnN6yX79pgp2BUQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -1458,8 +1458,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= gocloud.dev v0.42.0 h1:qzG+9ItUL3RPB62/Amugws28n+4vGZXEoJEAMfjutzw= gocloud.dev v0.42.0/go.mod h1:zkaYAapZfQisXOA4bzhsbA4ckiStGQ3Psvs9/OQ5dPM= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1984,10 +1984,10 @@ google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -2021,8 +2021,8 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5 google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -2038,8 +2038,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -2111,26 +2111,26 @@ k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUy k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -modernc.org/cc/v4 v4.26.0 h1:QMYvbVduUGH0rrO+5mqF/PSPPRZNpRtg2CLELy7vUpA= -modernc.org/cc/v4 v4.26.0/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= -modernc.org/ccgo/v4 v4.26.0 h1:gVzXaDzGeBYJ2uXTOpR8FR7OlksDOe9jxnjhIKCsiTc= -modernc.org/ccgo/v4 v4.26.0/go.mod h1:Sem8f7TFUtVXkG2fiaChQtyyfkqhJBg/zjEJBkmuAVY= -modernc.org/fileutil v1.3.1 h1:8vq5fe7jdtEvoCf3Zf9Nm0Q05sH6kGx0Op2CPx1wTC8= -modernc.org/fileutil v1.3.1/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= +modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s= +modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU= +modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE= +modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA= +modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/libc v1.65.0 h1:e183gLDnAp9VJh6gWKdTy0CThL9Pt7MfcR/0bgb7Y1Y= -modernc.org/libc v1.65.0/go.mod h1:7m9VzGq7APssBTydds2zBcxGREwvIGpuUBaKTXdm2Qs= +modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc= +modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= -modernc.org/memory v1.10.0 h1:fzumd51yQ1DxcOxSO+S6X7+QTuVU+n8/Aj7swYjFfC4= -modernc.org/memory v1.10.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.37.0 h1:s1TMe7T3Q3ovQiK2Ouz4Jwh7dw4ZDqbebSDTlSJdfjI= -modernc.org/sqlite v1.37.0/go.mod h1:5YiWv+YviqGMuGw4V+PNplcyaJ5v+vQd7TQOgkACoJM= +modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI= +modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/apps/investigations/go.mod b/apps/investigations/go.mod index ad72d49baa1..c9e76433875 100644 --- a/apps/investigations/go.mod +++ b/apps/investigations/go.mod @@ -12,7 +12,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect @@ -31,7 +31,7 @@ require ( github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grafana/grafana-app-sdk/logging v0.40.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -55,15 +55,14 @@ require ( github.com/spf13/pflag v1.0.7 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect @@ -74,10 +73,10 @@ require ( golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.33.3 // indirect diff --git a/apps/investigations/go.sum b/apps/investigations/go.sum index 3c3ab51328f..8e94a91aa99 100644 --- a/apps/investigations/go.sum +++ b/apps/investigations/go.sum @@ -2,8 +2,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -51,8 +51,8 @@ github.com/grafana/grafana-app-sdk v0.40.3 h1:JFo7uAfbAJUfZ9neD7/4sODKm1xgu9zhck github.com/grafana/grafana-app-sdk v0.40.3/go.mod h1:j0KzHo3Sa6kd+lnwSScBNoV9Vobkg/YY9HtEjxpyPrk= github.com/grafana/grafana-app-sdk/logging v0.40.3 h1:2VXsXXEQiqAavRP8wusRDB6rDqf5lufP7A6NfjELqPE= github.com/grafana/grafana-app-sdk/logging v0.40.3/go.mod h1:otUD9XpJD7A5sCLb8mcs9hIXGdeV6lnhzVwe747g4RU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -116,8 +116,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -126,30 +126,30 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -193,14 +193,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/playlist/go.mod b/apps/playlist/go.mod index c40105464ff..1eb90d41986 100644 --- a/apps/playlist/go.mod +++ b/apps/playlist/go.mod @@ -12,7 +12,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect @@ -31,7 +31,7 @@ require ( github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grafana/grafana-app-sdk/logging v0.40.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -55,15 +55,14 @@ require ( github.com/spf13/pflag v1.0.7 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect @@ -74,10 +73,10 @@ require ( golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.33.3 // indirect diff --git a/apps/playlist/go.sum b/apps/playlist/go.sum index 3c3ab51328f..8e94a91aa99 100644 --- a/apps/playlist/go.sum +++ b/apps/playlist/go.sum @@ -2,8 +2,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -51,8 +51,8 @@ github.com/grafana/grafana-app-sdk v0.40.3 h1:JFo7uAfbAJUfZ9neD7/4sODKm1xgu9zhck github.com/grafana/grafana-app-sdk v0.40.3/go.mod h1:j0KzHo3Sa6kd+lnwSScBNoV9Vobkg/YY9HtEjxpyPrk= github.com/grafana/grafana-app-sdk/logging v0.40.3 h1:2VXsXXEQiqAavRP8wusRDB6rDqf5lufP7A6NfjELqPE= github.com/grafana/grafana-app-sdk/logging v0.40.3/go.mod h1:otUD9XpJD7A5sCLb8mcs9hIXGdeV6lnhzVwe747g4RU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -116,8 +116,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -126,30 +126,30 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -193,14 +193,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/plugins/go.mod b/apps/plugins/go.mod index 51d951541ad..e588df3e680 100644 --- a/apps/plugins/go.mod +++ b/apps/plugins/go.mod @@ -15,7 +15,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect @@ -37,7 +37,7 @@ require ( github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 // indirect github.com/grafana/dskit v0.0.0-20250611075409-46f51e1ce914 // indirect github.com/grafana/grafana-app-sdk/logging v0.40.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -61,15 +61,14 @@ require ( github.com/spf13/pflag v1.0.7 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/crypto v0.42.0 // indirect golang.org/x/net v0.44.0 // indirect @@ -81,10 +80,10 @@ require ( golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.33.3 // indirect diff --git a/apps/plugins/go.sum b/apps/plugins/go.sum index 5a4166c7a6d..8876a7257e0 100644 --- a/apps/plugins/go.sum +++ b/apps/plugins/go.sum @@ -4,8 +4,8 @@ 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/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -63,8 +63,8 @@ github.com/grafana/grafana-app-sdk/logging v0.40.3 h1:2VXsXXEQiqAavRP8wusRDB6rDq github.com/grafana/grafana-app-sdk/logging v0.40.3/go.mod h1:otUD9XpJD7A5sCLb8mcs9hIXGdeV6lnhzVwe747g4RU= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250428110029-a8ea72012bde h1:ydSrBIOCxJQ84+JU+cyYsOLL40QeXrB7rYfsY/ezU4w= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250428110029-a8ea72012bde/go.mod h1:3MwgP0ISxGviTy3ZUJZsNz/56NNtHztMlH+gcxDt6Tw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -131,8 +131,8 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -142,30 +142,30 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -239,14 +239,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/preferences/go.mod b/apps/preferences/go.mod index c502f07d0c4..c14bd047fac 100644 --- a/apps/preferences/go.mod +++ b/apps/preferences/go.mod @@ -42,18 +42,19 @@ require ( github.com/prometheus/common v0.65.0 // indirect github.com/prometheus/procfs v0.16.1 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/stretchr/testify v1.10.0 // indirect + github.com/stretchr/testify v1.11.1 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/term v0.35.0 // indirect golang.org/x/text v0.29.0 // indirect golang.org/x/time v0.13.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/client-go v0.33.3 // indirect diff --git a/apps/preferences/go.sum b/apps/preferences/go.sum index 148a969504b..040ff075f8d 100644 --- a/apps/preferences/go.sum +++ b/apps/preferences/go.sum @@ -95,24 +95,24 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -150,8 +150,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/provisioning/go.mod b/apps/provisioning/go.mod index 6ada7417be6..dca6b391b23 100644 --- a/apps/provisioning/go.mod +++ b/apps/provisioning/go.mod @@ -11,7 +11,7 @@ require ( github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2 github.com/grafana/nanogit v0.0.0-20250723104447-68f58f5ecec0 github.com/migueleliasweb/go-github-mock v1.1.0 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 golang.org/x/oauth2 v0.30.0 k8s.io/apimachinery v0.33.3 k8s.io/apiserver v0.33.3 @@ -60,10 +60,12 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.42.0 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/sync v0.17.0 // indirect @@ -72,9 +74,9 @@ require ( golang.org/x/text v0.29.0 // indirect golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.37.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/apps/provisioning/go.sum b/apps/provisioning/go.sum index 03cdcd70638..f1f1b810347 100644 --- a/apps/provisioning/go.sum +++ b/apps/provisioning/go.sum @@ -119,8 +119,8 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -128,22 +128,22 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -215,12 +215,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/secret/go.mod b/apps/secret/go.mod index 1a69cb79f98..dd0419d4bdd 100644 --- a/apps/secret/go.mod +++ b/apps/secret/go.mod @@ -5,9 +5,9 @@ go 1.24.6 require ( github.com/grafana/grafana-app-sdk v0.40.3 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250710134100-1f3dc0533caf - github.com/stretchr/testify v1.10.0 - google.golang.org/grpc v1.74.2 - google.golang.org/protobuf v1.36.6 + github.com/stretchr/testify v1.11.1 + google.golang.org/grpc v1.75.0 + google.golang.org/protobuf v1.36.8 gopkg.in/yaml.v3 v3.0.1 k8s.io/apimachinery v0.33.3 k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff @@ -48,17 +48,18 @@ require ( github.com/prometheus/procfs v0.16.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/term v0.35.0 // indirect golang.org/x/text v0.29.0 // indirect golang.org/x/time v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/client-go v0.33.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect diff --git a/apps/secret/go.sum b/apps/secret/go.sum index f8054f2bf2d..b00cab6299c 100644 --- a/apps/secret/go.sum +++ b/apps/secret/go.sum @@ -99,8 +99,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -109,22 +109,22 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -162,12 +162,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/apps/shorturl/go.mod b/apps/shorturl/go.mod index 1caa6741faa..dda67ada683 100644 --- a/apps/shorturl/go.mod +++ b/apps/shorturl/go.mod @@ -13,7 +13,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect @@ -32,7 +32,7 @@ require ( github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grafana/grafana-app-sdk/logging v0.40.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -56,15 +56,14 @@ require ( github.com/spf13/pflag v1.0.7 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect @@ -75,10 +74,10 @@ require ( golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.33.3 // indirect diff --git a/apps/shorturl/go.sum b/apps/shorturl/go.sum index 3c3ab51328f..8e94a91aa99 100644 --- a/apps/shorturl/go.sum +++ b/apps/shorturl/go.sum @@ -2,8 +2,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -51,8 +51,8 @@ github.com/grafana/grafana-app-sdk v0.40.3 h1:JFo7uAfbAJUfZ9neD7/4sODKm1xgu9zhck github.com/grafana/grafana-app-sdk v0.40.3/go.mod h1:j0KzHo3Sa6kd+lnwSScBNoV9Vobkg/YY9HtEjxpyPrk= github.com/grafana/grafana-app-sdk/logging v0.40.3 h1:2VXsXXEQiqAavRP8wusRDB6rDqf5lufP7A6NfjELqPE= github.com/grafana/grafana-app-sdk/logging v0.40.3/go.mod h1:otUD9XpJD7A5sCLb8mcs9hIXGdeV6lnhzVwe747g4RU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -116,8 +116,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -126,30 +126,30 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -193,14 +193,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/go.mod b/go.mod index 27556b64a3d..7165cace114 100644 --- a/go.mod +++ b/go.mod @@ -60,7 +60,7 @@ require ( github.com/gchaincl/sqlhooks v1.3.0 // @grafana/grafana-search-and-storage github.com/getkin/kin-openapi v0.132.0 // @grafana/grafana-app-platform-squad github.com/go-jose/go-jose/v3 v3.0.4 // @grafana/identity-access-team - github.com/go-jose/go-jose/v4 v4.1.0 // indirect; @grafana/identity-access-team + github.com/go-jose/go-jose/v4 v4.1.1 // indirect; @grafana/identity-access-team github.com/go-kit/log v0.2.1 // @grafana/grafana-backend-group github.com/go-ldap/ldap/v3 v3.4.4 // @grafana/identity-access-team github.com/go-logfmt/logfmt v0.6.0 // @grafana/oss-big-tent @@ -113,7 +113,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // @grafana/grafana-search-and-storage github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // @grafana/plugins-platform-backend github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // @grafana/grafana-backend-group - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // @grafana/identity-access-team + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // @grafana/identity-access-team github.com/hashicorp/go-hclog v1.6.3 // @grafana/plugins-platform-backend github.com/hashicorp/go-multierror v1.1.1 // @grafana/alerting-squad github.com/hashicorp/go-plugin v1.6.3 // @grafana/plugins-platform-backend @@ -168,7 +168,7 @@ require ( github.com/spf13/cobra v1.9.1 // @grafana/grafana-app-platform-squad github.com/spf13/pflag v1.0.7 // @grafana-app-platform-squad github.com/spyzhov/ajson v0.9.6 // @grafana/grafana-sharing-squad - github.com/stretchr/testify v1.10.0 // @grafana/grafana-backend-group + github.com/stretchr/testify v1.11.1 // @grafana/grafana-backend-group github.com/thomaspoignant/go-feature-flag v1.42.0 // @grafana/grafana-backend-group github.com/tjhop/slog-gokit v0.1.3 // @grafana/grafana-app-platform-squad github.com/ua-parser/uap-go v0.0.0-20250213224047-9c035f085b90 // @grafana/grafana-backend-group @@ -186,12 +186,12 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // @grafana/sharing-squad go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 // @grafana/grafana-backend-group go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel v1.37.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel v1.38.0 // @grafana/grafana-backend-group go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/sdk v1.37.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/trace v1.37.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/sdk v1.38.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/trace v1.38.0 // @grafana/grafana-backend-group go.uber.org/atomic v1.11.0 // @grafana/alerting-backend go.uber.org/goleak v1.3.0 // @grafana/grafana-search-and-storage go.uber.org/mock v0.5.2 // @grafana/grafana-operator-experience-squad @@ -209,8 +209,8 @@ require ( golang.org/x/tools v0.37.0 // indirect; @grafana/grafana-as-code gonum.org/v1/gonum v0.16.0 // @grafana/oss-big-tent google.golang.org/api v0.235.0 // @grafana/grafana-backend-group - google.golang.org/grpc v1.74.2 // @grafana/plugins-platform-backend - google.golang.org/protobuf v1.36.6 // @grafana/plugins-platform-backend + google.golang.org/grpc v1.75.0 // @grafana/plugins-platform-backend + google.golang.org/protobuf v1.36.8 // @grafana/plugins-platform-backend gopkg.in/ini.v1 v1.67.0 // @grafana/alerting-backend gopkg.in/mail.v2 v2.3.1 // @grafana/grafana-backend-group gopkg.in/yaml.v2 v2.4.0 // @grafana/alerting-backend @@ -224,7 +224,7 @@ require ( k8s.io/kube-aggregator v0.33.3 // @grafana/grafana-app-platform-squad k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // @grafana/grafana-app-platform-squad k8s.io/utils v0.0.0-20241210054802-24370beab758 // @grafana/partner-datasources - modernc.org/sqlite v1.37.0 // @grafana/grafana-backend-group + modernc.org/sqlite v1.38.0 // @grafana/grafana-backend-group pgregory.net/rapid v1.2.0 // @grafana/grafana-operator-experience-squad sigs.k8s.io/randfill v1.0.0 // @grafana/grafana-app-platform-squad sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // @grafana-app-platform-squad @@ -303,7 +303,7 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect github.com/FZambia/eagle v0.2.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect @@ -371,7 +371,7 @@ require ( github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 // indirect github.com/caio/go-tdigest v3.1.0+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // @grafana/alerting-backend - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/centrifugal/protocol v0.16.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -604,18 +604,18 @@ require ( go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.59.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect go.opentelemetry.io/otel/log v0.12.2 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect @@ -624,8 +624,8 @@ require ( golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect @@ -635,9 +635,9 @@ require ( gopkg.in/telebot.v3 v3.2.1 // indirect k8s.io/apiextensions-apiserver v0.33.3 // indirect k8s.io/kms v0.33.3 // indirect - modernc.org/libc v1.65.0 // indirect + modernc.org/libc v1.65.10 // indirect modernc.org/mathutil v1.7.1 // indirect - modernc.org/memory v1.10.0 // indirect + modernc.org/memory v1.11.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/yaml v1.5.0 // indirect diff --git a/go.sum b/go.sum index 883b100df76..ab196b94b3c 100644 --- a/go.sum +++ b/go.sum @@ -722,8 +722,8 @@ github.com/FZambia/eagle v0.2.0 h1:1kQaZpJvbkvAXFRE/9K2ucBMuVqo+E29EMLYB74hIis= github.com/FZambia/eagle v0.2.0/go.mod h1:LKMYBwGYhao5sJI0TppvQ4SvvldFj9gITxrl8NvGwG0= github.com/FZambia/sentinel v1.0.0 h1:KJ0ryjKTZk5WMp0dXvSdNqp3lFaW1fNFuEYfrkLOYIc= github.com/FZambia/sentinel v1.0.0/go.mod h1:ytL1Am/RLlAoAXG6Kj5LNuw/TRRQrv2rt2FT26vP5gI= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0 h1:OqVGm6Ei3x5+yZmSJG1Mh2NwHvpVmZ08CB5qJhT9Nuk= @@ -996,8 +996,8 @@ github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8 github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= @@ -1228,8 +1228,8 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY= -github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -1669,8 +1669,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= @@ -2438,8 +2438,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/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/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= @@ -2604,59 +2604,59 @@ go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0/go.mod h1:9b8Q9rH52NgY go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 h1:9PgnL3QNlj10uGxExowIDIZu66aVBwWhXmbOp1pa6RA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0/go.mod h1:0ineDcLELf6JmKfuo0wvvhAVMuxWFYvkTin2iV4ydPQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= go.opentelemetry.io/otel/exporters/prometheus v0.59.0 h1:HHf+wKS6o5++XZhS98wvILrLVgHxjA/AMjqHKes+uzo= go.opentelemetry.io/otel/exporters/prometheus v0.59.0/go.mod h1:R8GpRXTZrqvXHDEGVH5bF6+JqAZcK8PjJcZ5nGhEWiE= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 h1:12vMqzLLNZtXuXbJhSENRg+Vvx+ynNilV8twBLBsXMY= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2/go.mod h1:ZccPZoPOoq8x3Trik/fCsba7DEYDUnN6yX79pgp2BUQ= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE= go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= go.opentelemetry.io/otel/sdk v1.17.0/go.mod h1:U87sE0f5vQB7hwUoW98pW5Rz4ZDuCFBZFNUBlSgmDFQ= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -2674,8 +2674,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= gocloud.dev v0.42.0 h1:qzG+9ItUL3RPB62/Amugws28n+4vGZXEoJEAMfjutzw= @@ -3456,15 +3456,15 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go. google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -3511,8 +3511,8 @@ google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -3535,8 +3535,8 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -3633,19 +3633,19 @@ lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v4 v4.26.0 h1:QMYvbVduUGH0rrO+5mqF/PSPPRZNpRtg2CLELy7vUpA= -modernc.org/cc/v4 v4.26.0/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s= +modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= -modernc.org/ccgo/v4 v4.26.0 h1:gVzXaDzGeBYJ2uXTOpR8FR7OlksDOe9jxnjhIKCsiTc= -modernc.org/ccgo/v4 v4.26.0/go.mod h1:Sem8f7TFUtVXkG2fiaChQtyyfkqhJBg/zjEJBkmuAVY= +modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU= +modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/fileutil v1.3.1 h1:8vq5fe7jdtEvoCf3Zf9Nm0Q05sH6kGx0Op2CPx1wTC8= -modernc.org/fileutil v1.3.1/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= +modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA= +modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= @@ -3656,8 +3656,8 @@ modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= -modernc.org/libc v1.65.0 h1:e183gLDnAp9VJh6gWKdTy0CThL9Pt7MfcR/0bgb7Y1Y= -modernc.org/libc v1.65.0/go.mod h1:7m9VzGq7APssBTydds2zBcxGREwvIGpuUBaKTXdm2Qs= +modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc= +modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= @@ -3666,8 +3666,8 @@ modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJ modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/memory v1.10.0 h1:fzumd51yQ1DxcOxSO+S6X7+QTuVU+n8/Aj7swYjFfC4= -modernc.org/memory v1.10.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= @@ -3675,8 +3675,8 @@ modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= -modernc.org/sqlite v1.37.0 h1:s1TMe7T3Q3ovQiK2Ouz4Jwh7dw4ZDqbebSDTlSJdfjI= -modernc.org/sqlite v1.37.0/go.mod h1:5YiWv+YviqGMuGw4V+PNplcyaJ5v+vQd7TQOgkACoJM= +modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI= +modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= diff --git a/go.work.sum b/go.work.sum index 653ad2af469..3a6b155ab72 100644 --- a/go.work.sum +++ b/go.work.sum @@ -944,6 +944,7 @@ github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMc github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= @@ -1760,10 +1761,12 @@ golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0Y golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM= golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ= @@ -1817,6 +1820,7 @@ golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b h1:DU+gwOBXU+6bO0sEyO7o/NeMlxZxCZEvI7v+J4a1zRQ= @@ -1830,12 +1834,12 @@ golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= -golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= @@ -1894,6 +1898,9 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go. google.golang.org/genproto/googleapis/api v0.0.0-20250512202823-5a2f75b736a9/go.mod h1:W3S/3np0/dPWsWLi1h/UymYctGXaGBM2StwzD0y140U= google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237/go.mod h1:ezi0AVyMKDWy5xAncvjLWH7UcLBB5n7y2fQ8MzjJcto= google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw= +google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA= +google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs= +google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c/go.mod h1:ea2MjsO70ssTfCjiwHgI0ZFqcw45Ksuk2ckf9G468GA= google.golang.org/genproto/googleapis/bytestream v0.0.0-20250505200425-f936aa4a68b2 h1:DbpkGFGRkd4GORg+IWQW2EhxUaa/My/PM8d1CGyTDMY= google.golang.org/genproto/googleapis/bytestream v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:h6yxum/C2qRb4txaZRLDHK8RyS0H/o2oEDeKY4onY/Y= google.golang.org/genproto/googleapis/bytestream v0.0.0-20250512202823-5a2f75b736a9 h1:YI36gCL8AQMhzYN6+jH8PdV/iZ0On+Zd0rO/7lCH3k8= @@ -1916,6 +1923,9 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250505200425-f936aa4a68b2/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= @@ -1939,6 +1949,7 @@ google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= @@ -1975,11 +1986,23 @@ knative.dev/hack v0.0.0-20250514121446-f525e187efdc h1:8HmclJlA0zNE/G1SkgdC3/IFS knative.dev/hack v0.0.0-20250514121446-f525e187efdc/go.mod h1:R0ritgYtjLDO9527h5vb5X6gfvt5LCrJ55BNbVDsWiY= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= modernc.org/cc/v3 v3.36.3 h1:uISP3F66UlixxWEcKuIWERa4TwrZENHSL8tWxZz8bHg= +modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= modernc.org/ccgo/v3 v3.16.9 h1:AXquSwg7GuMk11pIdw7fmO1Y/ybgazVkMhsZWCV0mHM= +modernc.org/ccgo/v3 v3.17.0 h1:o3OmOqx4/OFnl4Vm3G8Bgmqxnvxnh0nbxeT5p/dWChA= +modernc.org/ccgo/v3 v3.17.0/go.mod h1:Sg3fwVpmLvCUTaqEUjiBDAvshIaKDB0RXaf+zgqFu8I= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= +modernc.org/ccorpus2 v1.5.2 h1:Ui+4tc58mf/W+2arcYCJR903y3zl3ecsI7Fpaaqozyw= +modernc.org/ccorpus2 v1.5.2/go.mod h1:Wifvo4Q/qS/h1aRoC2TffcHsnxwTikmi1AuLANuucJQ= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +modernc.org/lex v1.1.1 h1:prSCNTLw1R4rn7M/RzwsuMtAuOytfyR3cnyM07P+Pas= +modernc.org/lex v1.1.1/go.mod h1:6r8o8DLJkAnOsQaGi8fMoi+Vt6LTbDaCrkUK729D8xM= +modernc.org/lexer v1.0.4 h1:hU7xVbZsqwPphyzChc7nMSGrsuaD2PDNOmzrzkS5AlE= +modernc.org/lexer v1.0.4/go.mod h1:tOajb8S4sdfOYitzCgXDFmbVJ/LE0v1fNJ7annTw36U= +modernc.org/scannertest v1.0.2 h1:JPtfxcVdbRvzmRf2YUvsDibJsQRw8vKA/3jb31y7cy0= +modernc.org/scannertest v1.0.2/go.mod h1:RzTm5RwglF/6shsKoEivo8N91nQIoWtcWI7ns+zPyGA= modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao= modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= diff --git a/pkg/aggregator/go.mod b/pkg/aggregator/go.mod index 39ead4943b8..d891f959abc 100644 --- a/pkg/aggregator/go.mod +++ b/pkg/aggregator/go.mod @@ -8,8 +8,8 @@ require ( github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e github.com/grafana/grafana/pkg/semconv v0.0.0-20250514132646-acbc7b54ed9e github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 - github.com/stretchr/testify v1.10.0 - go.opentelemetry.io/otel v1.37.0 + github.com/stretchr/testify v1.11.1 + go.opentelemetry.io/otel v1.38.0 k8s.io/api v0.33.3 k8s.io/apimachinery v0.33.3 k8s.io/apiserver v0.33.3 @@ -28,7 +28,7 @@ require ( github.com/apache/arrow-go/v18 v18.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/chromedp/cdproto v0.0.0-20250429231605-6ed5b53462d4 // indirect @@ -67,7 +67,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-plugin v1.6.3 // indirect github.com/hashicorp/yamux v0.1.1 // indirect @@ -128,12 +128,12 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect @@ -151,10 +151,10 @@ require ( golang.org/x/tools v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/pkg/aggregator/go.sum b/pkg/aggregator/go.sum index e44608059e8..733a9307fd4 100644 --- a/pkg/aggregator/go.sum +++ b/pkg/aggregator/go.sum @@ -23,8 +23,8 @@ 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/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -155,8 +155,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg= @@ -313,8 +313,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO 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/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= @@ -368,25 +368,25 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.36.0/go.mod h1:VHu48l0YTRKSObd go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 h1:bQ1Gvah4Sp8z7epSkgJaNTuZm7sutfA6Fji2/7cKFMc= go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0/go.mod h1:9b8Q9rH52NgYH3ShiTFB5wf18Vt3RTH/VMB7LDcC1ug= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -399,8 +399,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -491,20 +491,20 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= 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.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= 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= diff --git a/pkg/apimachinery/go.mod b/pkg/apimachinery/go.mod index b903d2c7e3f..2c89407b8c8 100644 --- a/pkg/apimachinery/go.mod +++ b/pkg/apimachinery/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-jose/go-jose/v3 v3.0.4 // @grafana/identity-access-team github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 // @grafana/identity-access-team github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 // @grafana/identity-access-team - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 gopkg.in/yaml.v3 v3.0.1 k8s.io/apimachinery v0.33.3 k8s.io/apiserver v0.33.3 @@ -38,19 +38,19 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/crypto v0.42.0 // indirect golang.org/x/net v0.44.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.29.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect diff --git a/pkg/apimachinery/go.sum b/pkg/apimachinery/go.sum index e9dfb27a6b3..0803e9c7919 100644 --- a/pkg/apimachinery/go.sum +++ b/pkg/apimachinery/go.sum @@ -70,8 +70,8 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -79,16 +79,16 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -154,12 +154,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/apiserver/go.mod b/pkg/apiserver/go.mod index 2d699ea0538..e863b538af4 100644 --- a/pkg/apiserver/go.mod +++ b/pkg/apiserver/go.mod @@ -8,10 +8,10 @@ require ( github.com/grafana/grafana-app-sdk/logging v0.40.3 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e github.com/prometheus/client_golang v1.23.0 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 - go.opentelemetry.io/otel v1.37.0 - go.opentelemetry.io/otel/trace v1.37.0 + go.opentelemetry.io/otel v1.38.0 + go.opentelemetry.io/otel/trace v1.38.0 k8s.io/apimachinery v0.33.3 k8s.io/apiserver v0.33.3 k8s.io/component-base v0.33.3 @@ -23,7 +23,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -47,7 +47,7 @@ require ( github.com/grafana/dskit v0.0.0-20250611075409-46f51e1ce914 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/jonboulle/clockwork v0.5.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -74,11 +74,11 @@ require ( go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect @@ -92,10 +92,10 @@ require ( golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.37.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/apiserver/go.sum b/pkg/apiserver/go.sum index bb49d49a2d6..fae4c4614b5 100644 --- a/pkg/apiserver/go.sum +++ b/pkg/apiserver/go.sum @@ -6,8 +6,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 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/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -94,8 +94,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -170,8 +170,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -205,22 +205,22 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/X go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 h1:SoCgXYF4ISDtNyfLUzsGDaaudZVTx2yJhOyBO0+/GYk= go.opentelemetry.io/contrib/propagators/jaeger v1.36.0/go.mod h1:VHu48l0YTRKSObdPQ+Sb8xMZvdnJlN7yhHuHoPgNqHM= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -233,8 +233,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= -go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -328,6 +328,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= 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= @@ -335,20 +337,20 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= 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.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= 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= diff --git a/pkg/build/go.mod b/pkg/build/go.mod index 8c96eac0617..4e508a233a2 100644 --- a/pkg/build/go.mod +++ b/pkg/build/go.mod @@ -10,14 +10,14 @@ replace github.com/docker/docker => github.com/moby/moby v27.5.1+incompatible require ( github.com/google/uuid v1.6.0 // indirect; @grafana/grafana-backend-group github.com/urfave/cli/v2 v2.27.7 // @grafana/grafana-backend-group - go.opentelemetry.io/otel v1.37.0 // indirect; @grafana/grafana-backend-group - go.opentelemetry.io/otel/sdk v1.37.0 // indirect; @grafana/grafana-backend-group - go.opentelemetry.io/otel/trace v1.37.0 // indirect; @grafana/grafana-backend-group + go.opentelemetry.io/otel v1.38.0 // indirect; @grafana/grafana-backend-group + go.opentelemetry.io/otel/sdk v1.38.0 // indirect; @grafana/grafana-backend-group + go.opentelemetry.io/otel/trace v1.38.0 // indirect; @grafana/grafana-backend-group golang.org/x/net v0.44.0 // indirect; @grafana/oss-big-tent @grafana/partner-datasources golang.org/x/sync v0.17.0 // @grafana/alerting-backend golang.org/x/text v0.29.0 // indirect; @grafana/grafana-backend-group - google.golang.org/grpc v1.74.2 // indirect; @grafana/plugins-platform-backend - google.golang.org/protobuf v1.36.6 // indirect; @grafana/plugins-platform-backend + google.golang.org/grpc v1.75.0 // indirect; @grafana/plugins-platform-backend + google.golang.org/protobuf v1.36.8 // indirect; @grafana/plugins-platform-backend ) require ( @@ -28,10 +28,10 @@ require ( 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-20240521201337-686a1a2994c1 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect golang.org/x/sys v0.36.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect ) require ( @@ -45,8 +45,8 @@ require ( github.com/99designs/gqlgen v0.17.73 // indirect github.com/Khan/genqlient v0.8.1 // indirect github.com/adrg/xdg v0.5.3 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect @@ -54,15 +54,15 @@ require ( go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect go.opentelemetry.io/otel/log v0.12.2 // indirect go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect ) // Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream diff --git a/pkg/build/go.sum b/pkg/build/go.sum index 90a2a582248..444f9bdd5a4 100644 --- a/pkg/build/go.sum +++ b/pkg/build/go.sum @@ -10,8 +10,8 @@ github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -29,8 +29,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 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= @@ -49,8 +49,8 @@ github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I= @@ -61,38 +61,38 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGC github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 h1:9PgnL3QNlj10uGxExowIDIZu66aVBwWhXmbOp1pa6RA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0/go.mod h1:0ineDcLELf6JmKfuo0wvvhAVMuxWFYvkTin2iV4ydPQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= @@ -103,14 +103,16 @@ golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/codegen/go.mod b/pkg/codegen/go.mod index 6d5b2ce23a2..2d8cefb63e4 100644 --- a/pkg/codegen/go.mod +++ b/pkg/codegen/go.mod @@ -43,6 +43,7 @@ require ( github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/stretchr/testify v1.11.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/yalue/merged_fs v1.3.0 // indirect diff --git a/pkg/codegen/go.sum b/pkg/codegen/go.sum index 9677a22ca8a..76cfff62e3d 100644 --- a/pkg/codegen/go.sum +++ b/pkg/codegen/go.sum @@ -90,8 +90,8 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= diff --git a/pkg/plugins/codegen/go.sum b/pkg/plugins/codegen/go.sum index 1e5ef948d96..27445f9e9cf 100644 --- a/pkg/plugins/codegen/go.sum +++ b/pkg/plugins/codegen/go.sum @@ -84,8 +84,8 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= diff --git a/pkg/promlib/go.mod b/pkg/promlib/go.mod index bd17282e6ce..ef4aa0d8670 100644 --- a/pkg/promlib/go.mod +++ b/pkg/promlib/go.mod @@ -9,10 +9,10 @@ require ( github.com/prometheus/client_golang v1.23.0 github.com/prometheus/common v0.65.0 github.com/prometheus/prometheus v0.303.1 - github.com/stretchr/testify v1.10.0 - go.opentelemetry.io/otel v1.37.0 - go.opentelemetry.io/otel/trace v1.37.0 - google.golang.org/protobuf v1.36.6 + github.com/stretchr/testify v1.11.1 + go.opentelemetry.io/otel v1.38.0 + go.opentelemetry.io/otel/trace v1.38.0 + google.golang.org/protobuf v1.36.8 k8s.io/apimachinery v0.33.3 ) @@ -25,7 +25,7 @@ require ( github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/chromedp/cdproto v0.0.0-20250429231605-6ed5b53462d4 // indirect @@ -59,7 +59,7 @@ require ( github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-plugin v1.6.3 // indirect github.com/hashicorp/yamux v0.1.1 // indirect @@ -109,12 +109,11 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect @@ -128,9 +127,9 @@ require ( golang.org/x/tools v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/api v0.235.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.74.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/grpc v1.75.0 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/promlib/go.sum b/pkg/promlib/go.sum index 185183352cd..be9dfb735fc 100644 --- a/pkg/promlib/go.sum +++ b/pkg/promlib/go.sum @@ -39,8 +39,8 @@ 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/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= @@ -147,8 +147,8 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg= @@ -286,8 +286,8 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 h1:aVGB3YnaS/JNfOW3tiHIlmNmTDg618va+eT0mVomgyI= @@ -325,25 +325,25 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.36.0/go.mod h1:VHu48l0YTRKSObd go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0 h1:bQ1Gvah4Sp8z7epSkgJaNTuZm7sutfA6Fji2/7cKFMc= go.opentelemetry.io/contrib/samplers/jaegerremote v0.30.0/go.mod h1:9b8Q9rH52NgYH3ShiTFB5wf18Vt3RTH/VMB7LDcC1ug= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -411,14 +411,14 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.235.0 h1:C3MkpQSRxS1Jy6AkzTGKKrpSCOd2WOGrezZ+icKSkKo= google.golang.org/api v0.235.0/go.mod h1:QpeJkemzkFKe5VCE/PMv7GsUfn9ZF+u+q1Q7w6ckxTg= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= +google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/semconv/go.mod b/pkg/semconv/go.mod index 782ae759d51..2821de78bab 100644 --- a/pkg/semconv/go.mod +++ b/pkg/semconv/go.mod @@ -2,7 +2,7 @@ module github.com/grafana/grafana/pkg/semconv go 1.24.6 -require go.opentelemetry.io/otel v1.37.0 +require go.opentelemetry.io/otel v1.38.0 require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/pkg/semconv/go.sum b/pkg/semconv/go.sum index aca512fb7f1..ee3256f1e7a 100644 --- a/pkg/semconv/go.sum +++ b/pkg/semconv/go.sum @@ -4,9 +4,9 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/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/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 076c52e1b236178d5903404dcc4b79d3a8ffb9ce Mon Sep 17 00:00:00 2001 From: Galen Kistler <109082771+gtk-grafana@users.noreply.github.com> Date: Fri, 12 Sep 2025 05:37:33 -0500 Subject: [PATCH 25/48] feat: add new expanded state to log options menu (#110725) * feat: add new expanded state to log options menu --- public/app/features/explore/Logs/Logs.tsx | 1 + .../logs/components/ControlledLogsTable.tsx | 14 +- .../logs/components/panel/LogListContext.tsx | 18 + .../components/panel/LogListControls.test.tsx | 205 ++++++++---- .../logs/components/panel/LogListControls.tsx | 311 ++++++++++++------ .../panel/LogListControlsOption.tsx | 211 ++++++++++++ .../panel/__mocks__/LogListContext.tsx | 11 +- public/locales/en-US/grafana.json | 44 ++- 8 files changed, 623 insertions(+), 192 deletions(-) create mode 100644 public/app/features/logs/components/panel/LogListControlsOption.tsx diff --git a/public/app/features/explore/Logs/Logs.tsx b/public/app/features/explore/Logs/Logs.tsx index 3b04394faf8..f2950a31887 100644 --- a/public/app/features/explore/Logs/Logs.tsx +++ b/public/app/features/explore/Logs/Logs.tsx @@ -1011,6 +1011,7 @@ const UnthemedLogs: React.FunctionComponent = (props: Props) => { hasData && (
{ - const { sortOrder } = useLogListContext(); + const { sortOrder, controlsExpanded } = useLogListContext(); const eventBus = useMemo(() => new EventBusSrv(), []); + const ref = useRef(null); const theme = useTheme2(); const styles = getStyles(theme); @@ -37,8 +38,11 @@ export const ControlledLogsTable = ({ return; } + const tableWidthExpandedControls = width - (CONTROLS_WIDTH_EXPANDED + 12); + const tableWidth = width - (CONTROLS_WIDTH + 12); + return ( -
+
{/* Width should be full width minus logs navigation and padding */} @@ -47,7 +51,7 @@ export const ControlledLogsTable = ({ range={range} splitOpen={splitOpen} timeZone={rest.timeZone} - width={width - 45} + width={controlsExpanded ? tableWidthExpandedControls : tableWidth} logsFrames={logsTableFrames ?? []} onClickFilterLabel={onClickFilterLabel} onClickFilterOutLabel={onClickFilterOutLabel} diff --git a/public/app/features/logs/components/panel/LogListContext.tsx b/public/app/features/logs/components/panel/LogListContext.tsx index dda8fed0c4b..244ce97fcf0 100644 --- a/public/app/features/logs/components/panel/LogListContext.tsx +++ b/public/app/features/logs/components/panel/LogListContext.tsx @@ -40,6 +40,7 @@ import { getScrollbarWidth, LOG_LIST_CONTROLS_WIDTH, LOG_LIST_MIN_WIDTH } from ' export interface LogListContextData extends Omit { closeDetails: () => void; + controlsExpanded: boolean; detailsDisplayed: (log: LogListModel) => boolean; detailsMode: LogLineDetailsMode; detailsWidth: number; @@ -51,6 +52,7 @@ export interface LogListContextData extends Omit void; setDedupStrategy: (dedupStrategy: LogsDedupStrategy) => void; setDetailsMode: (mode: LogLineDetailsMode) => void; setDetailsWidth: (width: number) => void; @@ -76,6 +78,7 @@ export interface LogListContextData extends Omit({ app: CoreApp.Unknown, closeDetails: () => {}, + controlsExpanded: false, dedupStrategy: LogsDedupStrategy.none, detailsDisplayed: () => false, detailsMode: 'sidebar', @@ -88,6 +91,7 @@ export const LogListContext = createContext({ fontSize: 'default', hasUnescapedContent: false, noInteractions: false, + setControlsExpanded: () => {}, setDedupStrategy: () => {}, setDetailsMode: () => {}, setDetailsWidth: () => {}, @@ -393,6 +397,13 @@ export const LogListContextProvider = ({ })); }, [timestampResolution]); + const controlsExpandedFromStore = store.getBool( + `${logOptionsStorageKey}.controlsExpanded`, + getDefaultControlsExpandedMode(containerElement ?? null) + ); + // If the user has a large viewport, show the expanded state by default + const [controlsExpanded, setControlsExpanded] = useState(controlsExpandedFromStore); + const detailsDisplayed = useCallback( (log: LogListModel) => !!showDetails.find((shownLog) => shownLog.uid === log.uid), [showDetails] @@ -594,6 +605,7 @@ export const LogListContextProvider = ({ value={{ app, closeDetails, + controlsExpanded, detailsDisplayed, dedupStrategy: logListState.dedupStrategy, detailsMode, @@ -628,6 +640,7 @@ export const LogListContextProvider = ({ pinLineButtonTooltipTitle, pinnedLogs: logListState.pinnedLogs, prettifyJSON, + setControlsExpanded, setDedupStrategy, setDetailsMode, setDetailsWidth, @@ -754,3 +767,8 @@ export function getDefaultDetailsMode(container: HTMLDivElement | undefined): Lo const width = container?.clientWidth ?? window.innerWidth; return width > 1440 ? 'sidebar' : 'inline'; } + +export function getDefaultControlsExpandedMode(container: HTMLDivElement | null): boolean { + const width = container?.clientWidth ?? window.innerWidth; + return width > 1200; +} diff --git a/public/app/features/logs/components/panel/LogListControls.test.tsx b/public/app/features/logs/components/panel/LogListControls.test.tsx index d61bfbde5bb..a0e32c09ccf 100644 --- a/public/app/features/logs/components/panel/LogListControls.test.tsx +++ b/public/app/features/logs/components/panel/LogListControls.test.tsx @@ -12,6 +12,35 @@ import { LogListContextProvider } from './LogListContext'; import { LogListControls } from './LogListControls'; import { ScrollToLogsEvent } from './virtualization'; +const FILTER_LEVELS_LABEL_COPY = 'Filter levels'; +const SCROLL_BOTTOM_LABEL_COPY = 'Scroll to bottom'; +const SCROLL_TOP_LABEL_COPY = 'Scroll to top'; +const OLDEST_LOGS_LABEL_COPY = 'Oldest logs first'; +const DEDUPE_LABEL_COPY = 'Deduplication'; +const SHOW_TIMESTAMP_LABEL_COPY = 'Show timestamps'; +const WRAP_LINES_LABEL_COPY = 'Wrap lines'; +const WRAP_JSON_TOOLTIP_COPY = 'Enable line wrapping and prettify JSON'; +const WRAP_JSON_LABEL_COPY = 'Wrap JSON'; +const WRAP_DISABLE_LABEL_COPY = 'Disable line wrapping'; +const ENABLE_HIGHLIGHTING_LABEL_COPY = 'Enable highlighting'; +const EXPANDED_LABEL_COPY = 'Expanded'; +const COLLAPSED_LABEL_COPY = 'Collapsed'; +const SHOW_UNIQUE_LABELS_LABEL_COPY = 'Show unique labels'; +const HIDE_UNIQUE_LABELS_LABEL_COPY = 'Hide unique labels'; +const EXPAND_JSON_LOGS_LABEL_COPY = 'Expand JSON logs'; +const COLLAPSE_JSON_LOGS_LABEL_COPY = 'Collapse JSON logs'; +const ESCAPE_NEWLINES_TOOLTIP_COPY = 'Fix incorrectly escaped newline and tab sequences in log lines'; +const REMOVE_ESCAPE_NEWLINES_LABEL_COPY = 'Remove escaping'; +const TIMESTAMP_LABEL_COPY = 'Log timestamps'; +const TIMESTAMP_HIDE_LABEL_COPY = 'Hide timestamps'; +const FONT_SIZE_LARGE_LABEL_COPY = 'Large font'; +const FONT_SIZE_LARGE_TOOLTIP_COPY = 'Set large font'; +const FONT_SIZE_SMALL_LABEL_COPY = 'Small font'; +const FONT_SIZE_SMALL_TOOLTIP_COPY = 'Set small font'; +const DOWNLOAD_LOGS_LABEL_COPY = 'Download logs'; + +const OLDEST_LOGS_LABEL_REGEX = /oldest logs first/; + jest.mock('../../utils', () => ({ ...jest.requireActual('../../utils'), downloadLogs: jest.fn(), @@ -42,6 +71,13 @@ const contextProps = { openAssistantByLog: () => {}, }; +const assertExpandedOptionsCopyVisible = () => { + expect(screen.getByText(EXPANDED_LABEL_COPY)).toBeVisible(); + expect(screen.getByText(SCROLL_BOTTOM_LABEL_COPY)).toBeVisible(); + expect(screen.getByText(OLDEST_LOGS_LABEL_COPY)).toBeVisible(); + expect(screen.getByText(DEDUPE_LABEL_COPY)).toBeVisible(); + expect(screen.getByText(SCROLL_TOP_LABEL_COPY)).toBeVisible(); +}; describe('LogListControls', () => { test('Renders without errors', () => { render( @@ -49,20 +85,18 @@ describe('LogListControls', () => { ); - expect(screen.getByLabelText('Scroll to bottom')).toBeInTheDocument(); - expect(screen.getByLabelText(/oldest logs first/)).toBeInTheDocument(); - expect(screen.getByLabelText('Deduplication')).toBeInTheDocument(); - expect(screen.getByLabelText('Display levels')).toBeInTheDocument(); - expect(screen.getByLabelText('Show timestamps')).toBeInTheDocument(); - expect(screen.getByLabelText('Wrap lines')).toBeInTheDocument(); - expect(screen.getByLabelText('Enable highlighting')).toBeInTheDocument(); - expect(screen.getByLabelText('Scroll to top')).toBeInTheDocument(); - expect(screen.queryByLabelText('Show unique labels')).not.toBeInTheDocument(); - expect(screen.queryByLabelText('Expand JSON logs')).not.toBeInTheDocument(); - expect( - screen.queryByLabelText('Fix incorrectly escaped newline and tab sequences in log lines') - ).not.toBeInTheDocument(); - expect(screen.queryByLabelText('Remove escaping')).not.toBeInTheDocument(); + expect(screen.getByLabelText(SCROLL_BOTTOM_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(OLDEST_LOGS_LABEL_REGEX)).toBeInTheDocument(); + expect(screen.getByLabelText(DEDUPE_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(FILTER_LEVELS_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(SHOW_TIMESTAMP_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(WRAP_LINES_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(ENABLE_HIGHLIGHTING_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(SCROLL_TOP_LABEL_COPY)).toBeInTheDocument(); + expect(screen.queryByLabelText(SHOW_UNIQUE_LABELS_LABEL_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(EXPAND_JSON_LOGS_LABEL_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(ESCAPE_NEWLINES_TOOLTIP_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(REMOVE_ESCAPE_NEWLINES_LABEL_COPY)).not.toBeInTheDocument(); }); test('Renders legacy controls', () => { @@ -71,8 +105,8 @@ describe('LogListControls', () => { ); - expect(screen.getByLabelText('Show unique labels')).toBeInTheDocument(); - expect(screen.getByLabelText('Expand JSON logs')).toBeInTheDocument(); + expect(screen.getByLabelText(SHOW_UNIQUE_LABELS_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(EXPAND_JSON_LOGS_LABEL_COPY)).toBeInTheDocument(); }); test.each([CoreApp.Dashboard, CoreApp.PanelEditor, CoreApp.PanelViewer])( @@ -83,14 +117,14 @@ describe('LogListControls', () => { ); - expect(screen.getByLabelText('Scroll to bottom')).toBeInTheDocument(); - expect(screen.getByLabelText('Scroll to top')).toBeInTheDocument(); - expect(screen.getByLabelText('Display levels')).toBeInTheDocument(); - expect(screen.queryByLabelText(/oldest logs first/)).not.toBeInTheDocument(); - expect(screen.queryByLabelText('Deduplication')).not.toBeInTheDocument(); - expect(screen.queryByLabelText('Show timestamps')).not.toBeInTheDocument(); - expect(screen.queryByLabelText('Wrap lines')).not.toBeInTheDocument(); - expect(screen.queryByLabelText('Enable highlighting')).not.toBeInTheDocument(); + expect(screen.getByLabelText(SCROLL_BOTTOM_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(SCROLL_TOP_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(FILTER_LEVELS_LABEL_COPY)).toBeInTheDocument(); + expect(screen.queryByLabelText(OLDEST_LOGS_LABEL_REGEX)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(DEDUPE_LABEL_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(SHOW_TIMESTAMP_LABEL_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(WRAP_LINES_LABEL_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(ENABLE_HIGHLIGHTING_LABEL_COPY)).not.toBeInTheDocument(); } ); @@ -100,20 +134,18 @@ describe('LogListControls', () => { ); - expect(screen.getByLabelText('Scroll to bottom')).toBeInTheDocument(); - expect(screen.getByLabelText(/oldest logs first/)).toBeInTheDocument(); - expect(screen.getByLabelText('Deduplication')).toBeInTheDocument(); - expect(screen.getByLabelText('Display levels')).toBeInTheDocument(); - expect(screen.getByLabelText('Show timestamps')).toBeInTheDocument(); - expect(screen.getByLabelText('Wrap lines')).toBeInTheDocument(); - expect(screen.getByLabelText('Enable highlighting')).toBeInTheDocument(); - expect(screen.getByLabelText('Scroll to top')).toBeInTheDocument(); - expect(screen.queryByLabelText('Show unique labels')).not.toBeInTheDocument(); - expect(screen.queryByLabelText('Expand JSON logs')).not.toBeInTheDocument(); - expect( - screen.queryByLabelText('Fix incorrectly escaped newline and tab sequences in log lines') - ).not.toBeInTheDocument(); - expect(screen.queryByLabelText('Remove escaping')).not.toBeInTheDocument(); + expect(screen.getByLabelText(SCROLL_BOTTOM_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(OLDEST_LOGS_LABEL_REGEX)).toBeInTheDocument(); + expect(screen.getByLabelText(DEDUPE_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(FILTER_LEVELS_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(SHOW_TIMESTAMP_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(WRAP_LINES_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(ENABLE_HIGHLIGHTING_LABEL_COPY)).toBeInTheDocument(); + expect(screen.getByLabelText(SCROLL_TOP_LABEL_COPY)).toBeInTheDocument(); + expect(screen.queryByLabelText(SHOW_UNIQUE_LABELS_LABEL_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(EXPAND_JSON_LOGS_LABEL_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(ESCAPE_NEWLINES_TOOLTIP_COPY)).not.toBeInTheDocument(); + expect(screen.queryByLabelText(REMOVE_ESCAPE_NEWLINES_LABEL_COPY)).not.toBeInTheDocument(); }); test('Allows to scroll', async () => { @@ -124,8 +156,8 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Scroll to bottom')); - await userEvent.click(screen.getByLabelText('Scroll to top')); + await userEvent.click(screen.getByLabelText(SCROLL_BOTTOM_LABEL_COPY)); + await userEvent.click(screen.getByLabelText(SCROLL_TOP_LABEL_COPY)); expect(eventBus.publish).toHaveBeenCalledTimes(2); expect(eventBus.publish).toHaveBeenCalledWith( new ScrollToLogsEvent({ @@ -139,6 +171,45 @@ describe('LogListControls', () => { ); }); + test('Expands options', async () => { + render( + + + + ); + // Initial state should be collapsed + expect(screen.getByLabelText(COLLAPSED_LABEL_COPY)).toBeVisible(); + // Expanded label should not be visible + expect(screen.queryByText(EXPANDED_LABEL_COPY)).not.toBeInTheDocument(); + // Expand options + await userEvent.click(screen.getByLabelText(COLLAPSED_LABEL_COPY)); + // Verify that the label (state) is not collapsed + expect(screen.queryByLabelText(COLLAPSED_LABEL_COPY)).not.toBeInTheDocument(); + expect(screen.getByLabelText(EXPANDED_LABEL_COPY)).toBeVisible(); + // Verify the expanded labels are rendered + assertExpandedOptionsCopyVisible(); + }); + + test('Expands options shown by default with container width > 1200', async () => { + const div = document.createElement('div'); + const divSpy = jest.spyOn(div, 'clientWidth', 'get'); + //@ts-expect-error + divSpy['clientWidth'] = 1201; + render( + //@ts-expect-error + + + + ); + + // Verify the expanded labels are rendered + assertExpandedOptionsCopyVisible(); + // Collapse options + await userEvent.click(screen.getByLabelText(EXPANDED_LABEL_COPY)); + // State should be collapsed + expect(screen.getByLabelText(COLLAPSED_LABEL_COPY)).toBeVisible(); + }); + test('Controls sort order', async () => { const onLogOptionsChange = jest.fn(); render( @@ -150,7 +221,7 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText(/oldest logs first/)); + await userEvent.click(screen.getByLabelText(OLDEST_LOGS_LABEL_REGEX)); expect(onLogOptionsChange).toHaveBeenCalledTimes(1); expect(onLogOptionsChange).toHaveBeenCalledWith('sortOrder', LogsSortOrder.Descending); }); @@ -162,7 +233,7 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Deduplication')); + await userEvent.click(screen.getByLabelText(DEDUPE_LABEL_COPY)); await userEvent.click(screen.getByText('Numbers')); expect(onLogOptionsChange).toHaveBeenCalledTimes(1); expect(onLogOptionsChange).toHaveBeenCalledWith('dedupStrategy', LogsDedupStrategy.numbers); @@ -175,7 +246,7 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Display levels')); + await userEvent.click(screen.getByLabelText(FILTER_LEVELS_LABEL_COPY)); expect(await screen.findByText('All levels')).toBeVisible(); expect(screen.getByText('Info')).toBeVisible(); expect(screen.getByText('Debug')).toBeVisible(); @@ -194,7 +265,7 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Show timestamps')); + await userEvent.click(screen.getByLabelText(SHOW_TIMESTAMP_LABEL_COPY)); expect(onLogOptionsChange).toHaveBeenCalledTimes(1); expect(onLogOptionsChange).toHaveBeenCalledWith('showTime', true); }); @@ -206,7 +277,7 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Wrap lines')); + await userEvent.click(screen.getByLabelText(WRAP_LINES_LABEL_COPY)); expect(onLogOptionsChange).toHaveBeenCalledTimes(1); expect(onLogOptionsChange).toHaveBeenCalledWith('wrapLogMessage', true); }); @@ -227,21 +298,21 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Log line wrapping')); + await userEvent.click(screen.getByLabelText('Wrap disabled')); await userEvent.click(screen.getByText('Enable line wrapping')); expect(onLogOptionsChange).toHaveBeenCalledTimes(2); expect(onLogOptionsChange).toHaveBeenCalledWith('wrapLogMessage', true); expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyJSON', false); - await userEvent.click(screen.getByLabelText('Log line wrapping')); - await userEvent.click(screen.getByText('Enable line wrapping and prettify JSON')); + await userEvent.click(screen.getByLabelText(WRAP_LINES_LABEL_COPY)); + await userEvent.click(screen.getByText(WRAP_JSON_TOOLTIP_COPY)); expect(onLogOptionsChange).toHaveBeenCalledTimes(4); expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyJSON', true); - await userEvent.click(screen.getByLabelText('Log line wrapping')); - await userEvent.click(screen.getByText('Disable line wrapping')); + await userEvent.click(screen.getByLabelText(WRAP_JSON_LABEL_COPY)); + await userEvent.click(screen.getByText(WRAP_DISABLE_LABEL_COPY)); expect(onLogOptionsChange).toHaveBeenCalledWith('wrapLogMessage', false); expect(onLogOptionsChange).toHaveBeenCalledWith('prettifyJSON', false); @@ -262,19 +333,19 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Log timestamps')); + await userEvent.click(screen.getByLabelText(TIMESTAMP_LABEL_COPY)); await userEvent.click(screen.getByText('Show millisecond timestamps')); expect(onLogOptionsChange).toHaveBeenCalledTimes(1); expect(onLogOptionsChange).toHaveBeenCalledWith('showTime', true); - await userEvent.click(screen.getByLabelText('Log timestamps')); + await userEvent.click(screen.getByLabelText(TIMESTAMP_LABEL_COPY)); await userEvent.click(screen.getByText('Show nanosecond timestamps')); expect(onLogOptionsChange).toHaveBeenCalledTimes(2); - await userEvent.click(screen.getByLabelText('Log timestamps')); - await userEvent.click(screen.getByText('Hide timestamps')); + await userEvent.click(screen.getByLabelText(TIMESTAMP_LABEL_COPY)); + await userEvent.click(screen.getByText(TIMESTAMP_HIDE_LABEL_COPY)); expect(onLogOptionsChange).toHaveBeenCalledTimes(3); expect(onLogOptionsChange).toHaveBeenCalledWith('showTime', false); @@ -289,7 +360,7 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Enable highlighting')); + await userEvent.click(screen.getByLabelText(ENABLE_HIGHLIGHTING_LABEL_COPY)); expect(onLogOptionsChange).toHaveBeenCalledTimes(1); expect(onLogOptionsChange).toHaveBeenCalledWith('syntaxHighlighting', true); }); @@ -300,13 +371,13 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Show unique labels')); + await userEvent.click(screen.getByLabelText(SHOW_UNIQUE_LABELS_LABEL_COPY)); rerender( ); - expect(screen.getByLabelText('Hide unique labels')); + expect(screen.getByLabelText(HIDE_UNIQUE_LABELS_LABEL_COPY)); }); test('Controls Expand JSON logs', async () => { @@ -315,13 +386,13 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Expand JSON logs')); + await userEvent.click(screen.getByLabelText(EXPAND_JSON_LOGS_LABEL_COPY)); rerender( ); - expect(screen.getByLabelText('Collapse JSON logs')); + expect(screen.getByLabelText(COLLAPSE_JSON_LOGS_LABEL_COPY)); }); test('Controls font size', async () => { @@ -333,11 +404,11 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Use small font size')); - await screen.findByLabelText('Use default font size'); + await userEvent.click(screen.getByLabelText(FONT_SIZE_LARGE_LABEL_COPY)); + await screen.findByLabelText(FONT_SIZE_LARGE_TOOLTIP_COPY); - await userEvent.click(screen.getByLabelText('Use default font size')); - await screen.findByLabelText('Use small font size'); + await userEvent.click(screen.getByLabelText(FONT_SIZE_SMALL_LABEL_COPY)); + await screen.findByLabelText(FONT_SIZE_SMALL_TOOLTIP_COPY); config.featureToggles.newLogsPanel = originalValue; }); @@ -353,7 +424,7 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Download logs')); + await userEvent.click(screen.getByLabelText(DOWNLOAD_LOGS_LABEL_COPY)); await userEvent.click(await screen.findByText(label)); expect(downloadLogs).toHaveBeenCalledTimes(1); expect(downloadLogs).toHaveBeenCalledWith(format, [], undefined); @@ -371,7 +442,7 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Download logs')); + await userEvent.click(screen.getByLabelText(DOWNLOAD_LOGS_LABEL_COPY)); await userEvent.click(await screen.findByText('txt')); expect(downloadLogs).toHaveBeenCalledWith('text', filteredLogs, undefined); }); @@ -383,12 +454,12 @@ describe('LogListControls', () => { ); - await userEvent.click(screen.getByLabelText('Fix incorrectly escaped newline and tab sequences in log lines')); + await userEvent.click(screen.getByLabelText(ESCAPE_NEWLINES_TOOLTIP_COPY)); rerender( ); - await userEvent.click(screen.getByLabelText('Remove escaping')); + await userEvent.click(screen.getByLabelText(REMOVE_ESCAPE_NEWLINES_LABEL_COPY)); }); }); diff --git a/public/app/features/logs/components/panel/LogListControls.tsx b/public/app/features/logs/components/panel/LogListControls.tsx index bb8ebd398f8..8446fd13ed8 100644 --- a/public/app/features/logs/components/panel/LogListControls.tsx +++ b/public/app/features/logs/components/panel/LogListControls.tsx @@ -1,17 +1,26 @@ -import { css } from '@emotion/css'; +import { css, cx } from '@emotion/css'; import { capitalize } from 'lodash'; import { MouseEvent, useCallback, useMemo } from 'react'; -import { CoreApp, EventBus, LogLevel, LogsDedupDescription, LogsDedupStrategy, LogsSortOrder } from '@grafana/data'; +import { + CoreApp, + EventBus, + LogLevel, + LogsDedupDescription, + LogsDedupStrategy, + LogsSortOrder, + store, +} from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data/'; import { t } from '@grafana/i18n'; import { config, reportInteraction } from '@grafana/runtime'; -import { Dropdown, Icon, IconButton, Menu, Tooltip, useStyles2 } from '@grafana/ui'; +import { Dropdown, Menu, useStyles2 } from '@grafana/ui'; import { LogsVisualisationType } from '../../../explore/Logs/Logs'; import { DownloadFormat } from '../../utils'; import { useLogListContext } from './LogListContext'; +import { LogListControlsOption, LogListControlsSelectOption } from './LogListControlsOption'; import { useLogListSearchContext } from './LogListSearchContext'; import { ScrollToLogsEvent } from './virtualization'; @@ -38,9 +47,9 @@ const FILTER_LEVELS: LogLevel[] = [ ]; export const LogListControls = ({ eventBus, visualisationType = 'logs' }: Props) => { - const styles = useStyles2(getStyles); const { app, + controlsExpanded, dedupStrategy, downloadLogs, filterLevels, @@ -48,6 +57,7 @@ export const LogListControls = ({ eventBus, visualisationType = 'logs' }: Props) forceEscape, hasUnescapedContent, prettifyJSON, + setControlsExpanded, setDedupStrategy, setFilterLevels, setFontSize, @@ -63,9 +73,12 @@ export const LogListControls = ({ eventBus, visualisationType = 'logs' }: Props) sortOrder, syntaxHighlighting, wrapLogMessage, + logOptionsStorageKey, } = useLogListContext(); const { hideSearch, searchVisible, showSearch } = useLogListSearchContext(); + const styles = useStyles2(getStyles, controlsExpanded); + const onScrollToTopClick = useCallback(() => { reportInteraction('logs_log_list_controls_scroll_top_clicked'); eventBus.publish( @@ -84,6 +97,12 @@ export const LogListControls = ({ eventBus, visualisationType = 'logs' }: Props) ); }, [eventBus]); + const onExpandControlsClick = useCallback(() => { + reportInteraction('logs_log_list_controls_expand_controls_clicked'); + setControlsExpanded(!controlsExpanded); + store.set(`${logOptionsStorageKey}.controlsExpanded`, !controlsExpanded); + }, [controlsExpanded, logOptionsStorageKey, setControlsExpanded]); + const onForceEscapeClick = useCallback(() => { reportInteraction('logs_log_list_controls_force_escape_clicked'); setForceEscape(!forceEscape); @@ -242,22 +261,47 @@ export const LogListControls = ({ eventBus, visualisationType = 'logs' }: Props) return (
- {visualisationType === 'logs' && ( - + - )} + {visualisationType === 'logs' && ( + + )} + {!inDashboard ? ( <> -
{config.featureToggles.newLogsPanel && ( - )} - - 0 ? styles.controlButtonActive : styles.controlButton } - tooltip={t('logs.logs-controls.display-level', 'Display levels')} + label={t('logs.logs-controls.filter-levels', 'Filter levels')} + tooltip={t('logs.logs-controls.tooltip.filter-level', 'Filter logs result by level')} size="lg" />
{config.featureToggles.newLogsPanel ? ( - + ) : ( - )} {config.featureToggles.newLogsPanel ? ( - + ) : ( - )} {prettifyJSON !== undefined && !config.featureToggles.newLogsPanel && ( - )} {syntaxHighlighting !== undefined && ( - )} {config.featureToggles.newLogsPanel && ( - )} {hasUnescapedContent && ( -
- @@ -427,10 +504,16 @@ export const LogListControls = ({ eventBus, visualisationType = 'logs' }: Props) ) : ( <> {config.featureToggles.newLogsPanel && ( - )} - 0 ? styles.controlButtonActive : styles.controlButton} - tooltip={t('logs.logs-controls.display-level', 'Display levels')} + label={t('logs.logs-controls.filter-levels', 'Filter levels')} + tooltip={t('logs.logs-controls.tooltip.filter-level', 'Filter logs result by level')} size="lg" /> {visualisationType === 'logs' && hasUnescapedContent && ( - )} {visualisationType === 'logs' && ( - { - const styles = useStyles2(getStyles); +interface LogSelectOptionProps { + expanded: boolean; +} + +const TimestampResolutionButton = ({ expanded }: LogSelectOptionProps) => { + const styles = useStyles2(getWrapButtonStyles, expanded); const { setTimestampResolution, setShowTime, showTime, timestampResolution } = useLogListContext(); const hide = useCallback(() => { @@ -533,33 +630,32 @@ const TimestampResolutionButton = () => { [hide, showMs, showNs, showTime, styles.menuItemActive, timestampResolution] ); + const labelText = !showTime + ? t('logs.logs-controls.timestamp.label-hide', 'Hide timestamps') + : timestampResolution === 'ms' + ? t('logs.logs-controls.timestamp.label-ms', 'Display ms') + : t('logs.logs-controls.timestamp.label-ns', 'Display ns'); + + const customTagText = + timestampResolution === 'ms' + ? t('logs.logs-controls.resolution-ms', 'ms') + : t('logs.logs-controls.resolution-ns', 'ns'); + return ( - -
- - - -
-
+ ); }; - -const WrapLogMessageButton = () => { - const styles = useStyles2(getStyles); +const WrapLogMessageButton = ({ expanded }: LogSelectOptionProps) => { + const styles = useStyles2(getWrapButtonStyles, expanded); const { prettifyJSON, setPrettifyJSON, setWrapLogMessage, wrapLogMessage } = useLogListContext(); /** @@ -622,39 +718,62 @@ const WrapLogMessageButton = () => { [disable, prettifyJSON, styles.menuItemActive, wrap, wrapAndPrettify, wrapLogMessage] ); + const wrapStateText = !wrapLogMessage + ? t('logs.logs-controls.line-wrapping.state.hide', 'Wrap disabled') + : wrapLogMessage && !prettifyJSON + ? t('logs.logs-controls.line-wrapping.state.wrap', 'Wrap lines') + : t('logs.logs-controls.line-wrapping.state.json', 'Wrap JSON'); + + const tooltip = t('logs.logs-controls.line-wrapping.tooltip', 'Set line wrap'); + return ( - -
- - - -
-
+ ); }; -const getStyles = (theme: GrafanaTheme2) => { +const getWrapButtonStyles = (theme: GrafanaTheme2, expanded: boolean) => { + return { + menuItemActive: css({ + '&:before': { + content: '""', + position: 'absolute', + left: 0, + top: theme.spacing(0.5), + height: `calc(100% - ${theme.spacing(1)})`, + width: '2px', + backgroundColor: theme.colors.warning.main, + }, + }), + }; +}; + +export const CONTROLS_WIDTH = 35; +export const CONTROLS_WIDTH_EXPANDED = 176; + +const getStyles = (theme: GrafanaTheme2, controlsExpanded: boolean) => { return { navContainer: css({ maxHeight: '100%', display: 'flex', + flex: '1 0 auto', gap: theme.spacing(3), flexDirection: 'column', justifyContent: 'flex-start', - width: theme.spacing(4), + width: controlsExpanded ? CONTROLS_WIDTH_EXPANDED : CONTROLS_WIDTH, paddingTop: theme.spacing(0.75), paddingLeft: theme.spacing(1), borderLeft: `solid 1px ${theme.colors.border.medium}`, - overflow: 'hidden', minWidth: theme.spacing(4), + backgroundColor: theme.colors.background.primary, }), scrollToTopButton: css({ margin: 0, @@ -662,6 +781,9 @@ const getStyles = (theme: GrafanaTheme2) => { color: theme.colors.text.secondary, height: theme.spacing(2), }), + controlsExpandedButton: css({ + transform: !controlsExpanded ? 'rotate(180deg)' : '', + }), controlButton: css({ margin: 0, color: theme.colors.text.secondary, @@ -685,7 +807,7 @@ const getStyles = (theme: GrafanaTheme2) => { borderRadius: theme.shape.radius.default, bottom: theme.spacing(-1), backgroundImage: theme.colors.gradients.brandHorizontal, - width: '95%', + width: theme.spacing(2.25), opacity: 1, }, }), @@ -700,32 +822,5 @@ const getStyles = (theme: GrafanaTheme2) => { backgroundColor: theme.colors.warning.main, }, }), - customControlButton: css({ - position: 'relative', - zIndex: 0, - margin: 0, - boxShadow: 'none', - border: 'none', - display: 'flex', - background: 'transparent', - justifyContent: 'center', - alignItems: 'center', - padding: 0, - overflow: 'visible', - width: '100%', - }), - customControlIcon: css({ - verticalAlign: 'baseline', - }), - customControlTag: css({ - color: theme.colors.primary.text, - fontSize: 10, - position: 'absolute', - bottom: -4, - right: 1, - lineHeight: '10px', - backgroundColor: theme.colors.background.primary, - paddingLeft: 2, - }), }; }; diff --git a/public/app/features/logs/components/panel/LogListControlsOption.tsx b/public/app/features/logs/components/panel/LogListControlsOption.tsx new file mode 100644 index 00000000000..2c3e6738c1e --- /dev/null +++ b/public/app/features/logs/components/panel/LogListControlsOption.tsx @@ -0,0 +1,211 @@ +import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Dropdown, Icon, IconButton, Tooltip, useStyles2 } from '@grafana/ui'; + +interface LogControlOptionProps { + label?: string; + expanded: boolean; + tooltip: string; + stickToBottom?: boolean; +} + +export type Props = React.ComponentProps & LogControlOptionProps; + +export const LogListControlsOption = React.forwardRef( + ( + { + stickToBottom, + expanded, + label, + tooltip, + className: iconButtonClassName, + name: iconButtonName, + ...iconButtonProps + }: Props, + ref + ) => { + const styles = useStyles2(getStyles, expanded); + + return ( +
+ +
+ ); + } +); + +interface LogControlSelectOptionProps { + label?: string; + expanded: boolean; + tooltip: string; + stickToBottom?: boolean; + dropdown: JSX.Element; + isActive: boolean; + customTagText: string; + buttonAriaLabel: string; +} +export type SelectProps = React.ComponentProps & LogControlSelectOptionProps; + +export const LogListControlsSelectOption = React.forwardRef( + ( + { + stickToBottom, + expanded, + label, + tooltip, + className: iconButtonClassName, + name: iconButtonName, + dropdown, + isActive: isActive, + customTagText, + buttonAriaLabel, + ...iconButtonProps + }: SelectProps, + ref + ) => { + const styles = useStyles2(getStyles, expanded); + + return ( +
+ +
+ ); + } +); + +LogListControlsSelectOption.displayName = 'LogListControlsSelectOption'; +const getStyles = (theme: GrafanaTheme2, expanded: boolean) => { + const hoverSize = '26'; + return { + customControlTag: css({ + color: theme.colors.primary.text, + fontSize: 10, + position: 'absolute', + bottom: -4, + right: 1, + lineHeight: '10px', + backgroundColor: theme.colors.background.primary, + paddingLeft: 2, + }), + customControlIcon: css({ + verticalAlign: 'baseline', + }), + customControlButton: css({ + position: 'relative', + zIndex: 0, + margin: 0, + boxShadow: 'none', + border: 'none', + display: 'flex', + background: 'transparent', + justifyContent: 'center', + alignItems: 'center', + padding: 0, + overflow: 'visible', + width: '100%', + }), + controlButtonActive: css({ + margin: 0, + color: theme.colors.text.secondary, + height: theme.spacing(2), + '&:hover': { + '&:before': { + backgroundColor: theme.colors.action.hover, + opacity: 1, + }, + }, + '&:before': { + zIndex: -1, + position: 'absolute', + opacity: 0, + width: `${hoverSize}px`, + height: `${hoverSize}px`, + borderRadius: theme.shape.radius.default, + content: '""', + [theme.transitions.handleMotion('no-preference', 'reduce')]: { + transitionDuration: '0.2s', + transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)', + transitionProperty: 'opacity', + }, + }, + '&:after': { + display: 'block', + content: '" "', + position: 'absolute', + height: 2, + borderRadius: theme.shape.radius.default, + bottom: theme.spacing(-1), + backgroundImage: theme.colors.gradients.brandHorizontal, + width: theme.spacing(2.25), + opacity: 1, + }, + }), + controlButton: css({ + margin: 0, + color: theme.colors.text.secondary, + height: theme.spacing(2), + }), + marginTopAuto: css({ + marginTop: 'auto', + marginBottom: theme.spacing(1), + }), + labelText: css({ + display: expanded ? 'block' : 'none', + }), + iconContainer: css({ + display: 'flex', + alignItems: 'center', + height: '16px', + }), + container: css({ + fontSize: theme.typography.pxToRem(12), + height: theme.spacing(2), + width: 'auto', + }), + label: css({ + display: 'flex', + justifyContent: expanded ? 'space-between' : 'center', + marginRight: expanded ? '2.5px' : 0, + }), + }; +}; + +LogListControlsOption.displayName = 'LogListControlsOption'; diff --git a/public/app/features/logs/components/panel/__mocks__/LogListContext.tsx b/public/app/features/logs/components/panel/__mocks__/LogListContext.tsx index 007ac591dca..03e5e394870 100644 --- a/public/app/features/logs/components/panel/__mocks__/LogListContext.tsx +++ b/public/app/features/logs/components/panel/__mocks__/LogListContext.tsx @@ -3,7 +3,6 @@ import { createContext, useContext } from 'react'; import { CoreApp, LogsDedupStrategy, LogsSortOrder } from '@grafana/data'; import { checkLogsError, checkLogsSampled } from 'app/features/logs/utils'; -import { LogLineDetailsMode } from '../LogLineDetails'; import { LogListContextData, Props } from '../LogListContext'; import { LogListModel } from '../processing'; @@ -49,11 +48,11 @@ export const LogListContext = createContext({ toggleDetails: () => {}, wrapLogMessage: false, detailsMode: 'sidebar', - setDetailsMode: function (mode: LogLineDetailsMode): void { - throw new Error('Function not implemented.'); - }, + setDetailsMode: () => {}, isAssistantAvailable: false, openAssistantByLog: () => {}, + controlsExpanded: false, + setControlsExpanded: () => {}, }); export const useLogListContextData = (key: keyof LogListContextData) => { @@ -110,8 +109,10 @@ export const defaultValue: LogListContextData = { sortOrder: LogsSortOrder.Ascending, wrapLogMessage: false, isAssistantAvailable: false, - openAssistantByLog: () => {}, + openAssistantByLog: jest.fn(), timestampResolution: 'ns', + controlsExpanded: false, + setControlsExpanded: jest.fn(), }; export const defaultProps: Props = { diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index dbd9423b48d..2434af01c23 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "Collapse", "deduplication": "Deduplication", - "disable-highlighting": "Disable highlighting", "disable-prettify-json": "Collapse JSON logs", - "display-level": "Display levels", "display-level-all": "All levels", "download": "Download logs", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Enable highlighting", "escape-newlines": "Fix incorrectly escaped newline and tab sequences in log lines", - "font-size-default": "Use small font size", - "font-size-small": "Use default font size", + "expand": "Expand", + "filter-levels": "Filter levels", + "font-large": "Set large font", + "font-small": "Set small font", "hide-search": "Close search", "hide-timestamps": "Hide timestamps", "hide-unique-labels": "Hide unique labels", + "label": { + "collapse": "Expanded", + "disable-highlighting": "Highlight text", + "enable-highlighting": "Plain text", + "escape-newlines": "Escape newlines", + "expand": "Collapsed" + }, + "labels": { + "font-large": "Large font", + "font-small": "Small font", + "hide-search": "Close search", + "newest-first": "Newest logs first", + "oldest-first": "Oldest logs first", + "show-search": "Search logs" + }, "line-wrapping": { "enable": "Enable line wrapping", "enable-prettify": "Enable line wrapping and prettify JSON", "hide": "Disable line wrapping", - "label": "Log line wrapping" + "state": { + "hide": "Wrap disabled", + "json": "Wrap JSON", + "wrap": "Wrap lines" + }, + "tooltip": "Set line wrap" }, "newest-first": "Sorted by newest logs first - Click to show oldest first", "oldest-first": "Sorted by oldest logs first - Click to show newest first", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "Hide timestamps", "label": "Log timestamps", + "label-hide": "Hide timestamps", + "label-ms": "Display ms", + "label-ns": "Display ns", "milliseconds": "Show millisecond timestamps", - "nanoseconds": "Show nanosecond timestamps" + "nanoseconds": "Show nanosecond timestamps", + "tooltip": "Set timestamp format" + }, + "tooltip": { + "disable-highlighting": "Disable highlighting", + "download": "Download", + "enable-highlighting": "Enable highlighting", + "filter-level": "Filter logs result by level" }, "unwrap-lines": "Unwrap lines", "wrap-lines": "Wrap lines" From 1f7afc6b6a96f888546f9ef4daf94086ad773864 Mon Sep 17 00:00:00 2001 From: Daniele Stefano Ferru Date: Fri, 12 Sep 2025 13:57:31 +0200 Subject: [PATCH 26/48] Provisioning: add unit and integration tests for finalizer validation (#111012) * Add unit testS * add integration tests --- apps/provisioning/pkg/repository/test_test.go | 25 +++++++++ .../apis/provisioning/repository_test.go | 53 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/apps/provisioning/pkg/repository/test_test.go b/apps/provisioning/pkg/repository/test_test.go index 5b7c8c6b815..0a35c024ca4 100644 --- a/apps/provisioning/pkg/repository/test_test.go +++ b/apps/provisioning/pkg/repository/test_test.go @@ -26,6 +26,9 @@ func TestValidateRepository(t *testing.T) { repository: func() *MockRepository { m := NewMockRepository(t) m.On("Config").Return(&provisioning.Repository{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{CleanFinalizer, RemoveOrphanResourcesFinalizer}, + }, Spec: provisioning.RepositorySpec{ Title: "Test Repo", }, @@ -232,6 +235,28 @@ func TestValidateRepository(t *testing.T) { require.Contains(t, errors.ToAggregate().Error(), "spec.workflow: Invalid value: \"invalid\": invalid workflow") }, }, + { + name: "mutual exclusive finalizers are set together", + repository: func() *MockRepository { + m := NewMockRepository(t) + m.On("Config").Return(&provisioning.Repository{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{RemoveOrphanResourcesFinalizer, ReleaseOrphanResourcesFinalizer}, + }, + Spec: provisioning.RepositorySpec{ + Title: "Test Repo", + Type: provisioning.GitHubRepositoryType, + Workflows: []provisioning.Workflow{provisioning.WriteWorkflow}, + }, + }) + m.On("Validate").Return(field.ErrorList{}) + return m + }(), + expectedErrs: 1, + validateError: func(t *testing.T, errors field.ErrorList) { + require.Contains(t, errors.ToAggregate().Error(), "cannot have both remove and release orphan resources finalizers") + }, + }, } for _, tt := range tests { diff --git a/pkg/tests/apis/provisioning/repository_test.go b/pkg/tests/apis/provisioning/repository_test.go index b48c7d82add..8d3e7daa089 100644 --- a/pkg/tests/apis/provisioning/repository_test.go +++ b/pkg/tests/apis/provisioning/repository_test.go @@ -18,6 +18,7 @@ import ( "k8s.io/apimachinery/pkg/types" provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + "github.com/grafana/grafana/apps/provisioning/pkg/repository" "github.com/grafana/grafana/pkg/apimachinery/utils" "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/tests/apis" @@ -162,6 +163,58 @@ func TestIntegrationProvisioning_CreatingAndGetting(t *testing.T) { }) } +func TestIntegrationProvisioning_RepositoryValidation(t *testing.T) { + testutil.SkipIntegrationTestInShortMode(t) + + helper := runGrafana(t) + ctx := context.Background() + + for _, testCase := range []struct { + name string + repo *unstructured.Unstructured + expectedErr string + }{ + { + name: "should succeed with valid local repository", + repo: func() *unstructured.Unstructured { + return helper.RenderObject(t, "testdata/local-readonly.json.tmpl", map[string]any{ + "Name": "valid-repo", + "SyncEnabled": true, + }) + }(), + }, + { + name: "should error if mutually exclusive finalizers are set", + repo: func() *unstructured.Unstructured { + localTmp := helper.RenderObject(t, "testdata/local-readonly.json.tmpl", map[string]any{ + "Name": "repo-with-invalid-finalizers", + "SyncEnabled": true, + }) + + // Setting finalizers to trigger a failure + localTmp.SetFinalizers([]string{ + repository.CleanFinalizer, + repository.ReleaseOrphanResourcesFinalizer, + repository.RemoveOrphanResourcesFinalizer, + }) + + return localTmp + }(), + expectedErr: "cannot have both remove and release orphan resources finalizers", + }, + } { + t.Run(testCase.name, func(t *testing.T) { + _, err := helper.Repositories.Resource.Create(ctx, testCase.repo, metav1.CreateOptions{}) + if testCase.expectedErr == "" { + assert.NoError(t, err) + } else { + assert.Error(t, err) + assert.ErrorContains(t, err, testCase.expectedErr) + } + }) + } +} + func TestIntegrationProvisioning_FailInvalidSchema(t *testing.T) { testutil.SkipIntegrationTestInShortMode(t) From edcd1130543e2a71c0e192fc29c3bbd4875ac72f Mon Sep 17 00:00:00 2001 From: Jo Date: Fri, 12 Sep 2025 12:59:37 +0100 Subject: [PATCH 27/48] Authz: Remove legacy API Key permissions (#110860) * remove API key roles * remove API key gen * remove frontend and doc mentions * restore legacy keygen * restore codeowners * prettier * update swagger * remove permissions including apikeys * add migrator for removing deprecated permissions * add tracing * update openapi3 * simplify migrator for now * accesscontrol/migrator: remove batching for deprecated permissions deletion --- .../custom-role-actions-scopes/index.md | 3 - .../index.md | 14 +- pkg/api/accesscontrol.go | 37 +-- pkg/api/api.go | 1 - pkg/api/dtos/apikey.go | 1 - pkg/components/apikeygen/apikeygen.go | 8 +- pkg/components/satokengen/errors.go | 14 -- pkg/components/satokengen/tokengen.go | 9 +- pkg/services/accesscontrol/acimpl/service.go | 7 +- .../accesscontrol/migrator/migrator.go | 87 +++++++ .../accesscontrol/migrator/migrator_test.go | 213 ++++++++++++++++++ pkg/services/accesscontrol/models.go | 12 - pkg/services/accesscontrol/permreg/permreg.go | 1 - pkg/services/apikey/apikeyimpl/store_test.go | 21 +- pkg/services/apikey/model.go | 1 - pkg/services/authn/clients/api_key.go | 4 +- pkg/services/authn/clients/api_key_test.go | 9 +- .../grpcserver/interceptors/auth_test.go | 6 +- .../database/token_store_test.go | 10 +- .../serviceaccounts/extsvcaccounts/service.go | 2 +- public/api-enterprise-spec.json | 21 -- public/api-merged.json | 21 -- public/app/core/reducers/navModel.test.ts | 7 +- public/app/core/reducers/navModel.ts | 1 - public/app/types/accessControl.ts | 4 - public/openapi3.json | 21 -- 26 files changed, 346 insertions(+), 189 deletions(-) delete mode 100644 pkg/components/satokengen/errors.go diff --git a/docs/sources/administration/roles-and-permissions/access-control/custom-role-actions-scopes/index.md b/docs/sources/administration/roles-and-permissions/access-control/custom-role-actions-scopes/index.md index 31aeaa1a99a..466e0aa99b7 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/custom-role-actions-scopes/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/custom-role-actions-scopes/index.md @@ -69,8 +69,6 @@ The following list contains role-based access control actions. | `annotations:delete` |
  • `annotations:*`
  • `annotations:type:*`
  • `dashboards:*`
  • `dashboards:uid:*`
  • `folders:*`
  • `folders:uid:*`
| Delete annotations. | | `annotations:read` |
  • `annotations:*`
  • `annotations:type:*`
  • `dashboards:*`
  • `dashboards:uid:*`
  • `folders:*`
  • `folders:uid:*`
| Read annotations and annotation tags. | | `annotations:write` |
  • `annotations:*`
  • `annotations:type:*`
  • `dashboards:*`
  • `dashboards:uid:*`
  • `folders:*`
  • `folders:uid:*`
| Update annotations. | -| `apikeys:read` |
  • `apikeys:*`
  • `apikeys:id:*`
| Read API keys. | -| `apikeys:delete` |
  • `apikeys:*`
  • `apikeys:id:*`
| Delete API keys. | | `banners:write` | None | Create [announcement banners](/docs/grafana-cloud/whats-new/2024-09-10-announcement-banner/). | | `dashboards:create` |
  • `folders:*`
  • `folders:uid:*`
| Create dashboards in one or more folders and their subfolders. | | `dashboards:delete` |
  • `dashboards:*`
  • `dashboards:uid:*`
  • `folders:*`
  • `folders:uid:*`
| Delete one or more dashboards. | @@ -268,7 +266,6 @@ The following list contains role-based access control scopes. | Scopes | Descriptions | | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
  • `annotations:*`
  • `annotations:type:*`
| Restrict an action to a set of annotations. For example, `annotations:*` matches any annotation, `annotations:type:dashboard` matches annotations associated with dashboards and `annotations:type:organization` matches organization annotations. | -|
  • `apikeys:*`
  • `apikeys:id:*`
| Restrict an action to a set of API keys. For example, `apikeys:*` matches any API key, `apikey:id:1` matches the API key whose id is `1`. | |
  • `dashboards:*`
  • `dashboards:uid:*`
| Restrict an action to a set of dashboards. For example, `dashboards:*` matches any dashboard, and `dashboards:uid:1` matches the dashboard whose UID is `1`. | |
  • `datasources:*`
  • `datasources:uid:*`
| Restrict an action to a set of data sources. For example, `datasources:*` matches any data source, and `datasources:uid:1` matches the data source whose UID is `1`. | |
  • `folders:*`
  • `folders:uid:*`
| Restrict an action to a set of folders. For example, `folders:*` matches any folder, and `folders:uid:1` matches the folder whose UID is `1`. Note that permissions granted to a folder cascade down to subfolders located under it. | diff --git a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md index e6c7b1fd51c..1495886a032 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md @@ -54,14 +54,14 @@ The following tables list permissions associated with basic and fixed roles. Thi ## Basic role assignments -| Basic role | UID | Associated fixed roles | Description | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| Basic role | UID | Associated fixed roles | Description | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | Grafana Admin | `basic_grafana_admin` | | `fixed:authentication.config:writer`
`fixed:general.auth.config:writer`
`fixed:ldap:writer`
`fixed:licensing:writer`
`fixed:migrationassistant:migrator`
`fixed:org.users:writer`
`fixed:organization:maintainer`
`fixed:plugins:maintainer`
`fixed:provisioning:writer`
`fixed:roles:writer`
`fixed:settings:reader`
`fixed:settings:writer`
`fixed:stats:reader`
`fixed:support.bundles:writer`
`fixed:usagestats:reader`
`fixed:users:writer` | Default [Grafana server administrator](/docs/grafana//administration/roles-and-permissions/#grafana-server-administrators) assignments. | -| Admin | `basic_admin` | All roles assigned to Editor and `fixed:reports:writer`
`fixed:datasources:writer`
`fixed:organization:writer`
`fixed:datasources.permissions:writer`
`fixed:teams:writer`
`fixed:dashboards:writer`
`fixed:dashboards.permissions:writer`
`fixed:dashboards.public:writer`
`fixed:folders:writer`
`fixed:folders.permissions:writer`
`fixed:alerting:writer`
`fixed:apikeys:writer`
`fixed:alerting.provisioning.secrets:reader`
`fixed:alerting.provisioning:writer`
`fixed:datasources.caching:writer`
`fixed:plugins:writer`
`fixed:library.panels:writer` | Default [Grafana organization administrator](ref:rbac-basic-roles) assignments. | -| Editor | `basic_editor` | All roles assigned to Viewer and `fixed:datasources:explorer`
`fixed:dashboards:creator`
`fixed:folders:creator`
`fixed:annotations:writer`
`fixed:alerting:writer`
`fixed:library.panels:creator`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer` | Default [Editor](ref:rbac-basic-roles) assignments. | -| Viewer | `basic_viewer` | `fixed:datasources.id:reader`
`fixed:organization:reader`
`fixed:annotations:reader`
`fixed:annotations.dashboard:writer`
`fixed:alerting:reader`
`fixed:plugins.app:reader`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:general.reader`
`fixed:folders.general:reader`
`fixed:datasources.builtin:reader` | Default [Viewer](ref:rbac-basic-roles) assignments. | -| No Basic Role | n/a | | Default [No Basic Role](ref:rbac-basic-roles) | +| Admin | `basic_admin` | All roles assigned to Editor and `fixed:reports:writer`
`fixed:datasources:writer`
`fixed:organization:writer`
`fixed:datasources.permissions:writer`
`fixed:teams:writer`
`fixed:dashboards:writer`
`fixed:dashboards.permissions:writer`
`fixed:dashboards.public:writer`
`fixed:folders:writer`
`fixed:folders.permissions:writer`
`fixed:alerting:writer`
`fixed:alerting.provisioning.secrets:reader`
`fixed:alerting.provisioning:writer`
`fixed:datasources.caching:writer`
`fixed:plugins:writer`
`fixed:library.panels:writer` | Default [Grafana organization administrator](ref:rbac-basic-roles) assignments. | +| Editor | `basic_editor` | All roles assigned to Viewer and `fixed:datasources:explorer`
`fixed:dashboards:creator`
`fixed:folders:creator`
`fixed:annotations:writer`
`fixed:alerting:writer`
`fixed:library.panels:creator`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer` | Default [Editor](ref:rbac-basic-roles) assignments. | +| Viewer | `basic_viewer` | `fixed:datasources.id:reader`
`fixed:organization:reader`
`fixed:annotations:reader`
`fixed:annotations.dashboard:writer`
`fixed:alerting:reader`
`fixed:plugins.app:reader`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:general.reader`
`fixed:folders.general:reader`
`fixed:datasources.builtin:reader` | Default [Viewer](ref:rbac-basic-roles) assignments. | +| No Basic Role | n/a | | Default [No Basic Role](ref:rbac-basic-roles) | ## Fixed role definitions @@ -90,8 +90,6 @@ To learn how to use the roles API to determine the role UUIDs, refer to [Manage | `fixed:annotations:reader` | `fixed_hpZnoizrfAJsrceNcNQqWYV-xNU` | `annotations:read` for scopes `annotations:type:*` | Read all annotations and annotation tags. | | `fixed:annotations:writer` | `fixed_ZVW-Aa9Tzle6J4s2aUFcq1StKWE` | All permissions from `fixed:annotations:reader`
`annotations:write`
`annotations.create`
`annotations:delete` for scope `annotations:type:*` | Read, create, update and delete all annotations and annotation tags. | | `fixed:annotations.dashboard:writer` | `fixed_8A775xenXeKaJk4Cr7bchP9yXOA` | `annotations:write`
`annotations.create`
`annotations:delete` for scope `annotations:type:dashboard` | Create, update and delete dashboard annotations and annotation tags. | -| `fixed:apikeys:reader` | `fixed_kYZ7UEkwEvGmCCjTrq07cFAVFws` | `apikeys:read` for scope `apikeys:*` | Read all api keys. | -| `fixed:apikeys:writer` | `fixed_anTrcpRkm21NBO1Q2CsX8y0fiCQ` | All permissions from `fixed:apikeys:reader` and
`apikeys:create`
`apikeys:delete` for scope `apikeys:*` | Read, create, delete all api keys. | | `fixed:authentication.config:writer` | `fixed_0rYhZ2Qnzs8AdB1nX7gexk3fHDw` | `settings:read` for scope `settings:auth.saml:*`
`settings:write` for scope `settings:auth.saml:*` | Read and update authentication and SAML settings. | | `fixed:general.auth.config:writer` | `fixed_QFxIT_FGtBqbIVJIwx1bLgI5z6c` | `settings:read` for scope `settings:auth:oauth_allow_insecure_email_lookup`
`settings:write` for scope `settings:auth:oauth_allow_insecure_email_lookup` | Read and update the Grafana instance's general authentication configuration settings. | | `fixed:dashboards:creator` | `fixed_ZorKUcEPCM01A1fPakEzGBUyU64` | `dashboards:create`
`folders:read` | Create dashboards. | diff --git a/pkg/api/accesscontrol.go b/pkg/api/accesscontrol.go index de783d3309e..1bddc9490cc 100644 --- a/pkg/api/accesscontrol.go +++ b/pkg/api/accesscontrol.go @@ -176,41 +176,6 @@ func (hs *HTTPServer) declareFixedRoles() error { Grants: []string{string(org.RoleViewer)}, } - apikeyReaderRole := ac.RoleRegistration{ - Role: ac.RoleDTO{ - Name: "fixed:apikeys:reader", - DisplayName: "Reader", - Description: "Gives access to read api keys.", - Group: "API Keys", - Permissions: []ac.Permission{ - { - Action: ac.ActionAPIKeyRead, - Scope: ac.ScopeAPIKeysAll, - }, - }, - }, - Grants: []string{string(org.RoleAdmin)}, - } - - apikeyWriterRole := ac.RoleRegistration{ - Role: ac.RoleDTO{ - Name: "fixed:apikeys:writer", - DisplayName: "Writer", - Description: "Gives access to add and delete api keys.", - Group: "API Keys", - Permissions: ac.ConcatPermissions(apikeyReaderRole.Role.Permissions, []ac.Permission{ - { - Action: ac.ActionAPIKeyCreate, - }, - { - Action: ac.ActionAPIKeyDelete, - Scope: ac.ScopeAPIKeysAll, - }, - }), - }, - Grants: []string{string(org.RoleAdmin)}, - } - orgReaderRole := ac.RoleRegistration{ Role: ac.RoleDTO{ Name: "fixed:organization:reader", @@ -649,7 +614,7 @@ func (hs *HTTPServer) declareFixedRoles() error { orgMaintainerRole, teamsCreatorRole, teamsWriterRole, teamsReaderRole, datasourcesExplorerRole, annotationsReaderRole, dashboardAnnotationsWriterRole, annotationsWriterRole, dashboardsCreatorRole, dashboardsReaderRole, dashboardsWriterRole, - foldersCreatorRole, foldersReaderRole, generalFolderReaderRole, foldersWriterRole, apikeyReaderRole, apikeyWriterRole, + foldersCreatorRole, foldersReaderRole, generalFolderReaderRole, foldersWriterRole, publicDashboardsWriterRole, featuremgmtReaderRole, featuremgmtWriterRole, libraryPanelsCreatorRole, libraryPanelsReaderRole, libraryPanelsWriterRole, libraryPanelsGeneralReaderRole, libraryPanelsGeneralWriterRole, snapshotsCreatorRole, snapshotsDeleterRole, snapshotsReaderRole} diff --git a/pkg/api/api.go b/pkg/api/api.go index d9689f92eb4..ec6c3c3cbe3 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -107,7 +107,6 @@ func (hs *HTTPServer) registerRoutes() { r.Get("/org/teams/new", authorize(ac.EvalPermission(ac.ActionTeamsCreate)), hs.Index) r.Get("/org/serviceaccounts", authorize(ac.EvalPermission(serviceaccounts.ActionRead)), hs.Index) r.Get("/org/serviceaccounts/:serviceAccountId", authorize(ac.EvalPermission(serviceaccounts.ActionRead)), hs.Index) - r.Get("/org/apikeys/", authorize(ac.EvalPermission(ac.ActionAPIKeyRead)), hs.Index) r.Get("/dashboard/import/", reqSignedIn, hs.Index) r.Get("/configuration", reqGrafanaAdmin, hs.Index) r.Get("/admin", reqOrgAdmin, hs.Index) diff --git a/pkg/api/dtos/apikey.go b/pkg/api/dtos/apikey.go index 28dd1389810..ec77c18a550 100644 --- a/pkg/api/dtos/apikey.go +++ b/pkg/api/dtos/apikey.go @@ -1,6 +1,5 @@ package dtos -// swagger:model type NewApiKeyResult struct { // example: 1 ID int64 `json:"id"` diff --git a/pkg/components/apikeygen/apikeygen.go b/pkg/components/apikeygen/apikeygen.go index f907573bf95..ba10258519d 100644 --- a/pkg/components/apikeygen/apikeygen.go +++ b/pkg/components/apikeygen/apikeygen.go @@ -3,13 +3,11 @@ package apikeygen import ( "encoding/base64" "encoding/json" - "errors" + "github.com/grafana/grafana/pkg/components/satokengen" "github.com/grafana/grafana/pkg/util" ) -var ErrInvalidApiKey = errors.New("invalid API key") - type KeyGenResult struct { HashedKey string ClientSecret string @@ -50,13 +48,13 @@ func New(orgId int64, name string) (KeyGenResult, error) { func Decode(keyString string) (*ApiKeyJson, error) { jsonString, err := base64.StdEncoding.DecodeString(keyString) if err != nil { - return nil, ErrInvalidApiKey + return nil, satokengen.ErrInvalidApiKey } var keyObj ApiKeyJson err = json.Unmarshal(jsonString, &keyObj) if err != nil { - return nil, ErrInvalidApiKey + return nil, satokengen.ErrInvalidApiKey } return &keyObj, nil diff --git a/pkg/components/satokengen/errors.go b/pkg/components/satokengen/errors.go deleted file mode 100644 index bd6eef8e411..00000000000 --- a/pkg/components/satokengen/errors.go +++ /dev/null @@ -1,14 +0,0 @@ -package satokengen - -import "github.com/grafana/grafana/pkg/components/apikeygen" - -type ErrInvalidApiKey struct { -} - -func (e *ErrInvalidApiKey) Error() string { - return "invalid API key" -} - -func (e *ErrInvalidApiKey) Unwrap() error { - return apikeygen.ErrInvalidApiKey -} diff --git a/pkg/components/satokengen/tokengen.go b/pkg/components/satokengen/tokengen.go index 3e96e9f080e..b2e0f0a0ffa 100644 --- a/pkg/components/satokengen/tokengen.go +++ b/pkg/components/satokengen/tokengen.go @@ -2,6 +2,7 @@ package satokengen import ( "encoding/hex" + "errors" "hash/crc32" "strings" @@ -10,6 +11,8 @@ import ( const GrafanaPrefix = "gl" +var ErrInvalidApiKey = errors.New("invalid API key") + type KeyGenResult struct { HashedKey string ClientSecret string @@ -72,12 +75,12 @@ func New(serviceID string) (KeyGenResult, error) { func Decode(keyString string) (*PrefixedKey, error) { if !strings.HasPrefix(keyString, GrafanaPrefix) { - return nil, &ErrInvalidApiKey{} + return nil, ErrInvalidApiKey } parts := strings.Split(keyString, "_") if len(parts) != 3 { - return nil, &ErrInvalidApiKey{} + return nil, ErrInvalidApiKey } key := &PrefixedKey{ @@ -86,7 +89,7 @@ func Decode(keyString string) (*PrefixedKey, error) { Checksum: parts[2], } if key.CalculateChecksum() != key.Checksum { - return nil, &ErrInvalidApiKey{} + return nil, ErrInvalidApiKey } return key, nil diff --git a/pkg/services/accesscontrol/acimpl/service.go b/pkg/services/accesscontrol/acimpl/service.go index 86adbdbfcb0..ecc0210edcd 100644 --- a/pkg/services/accesscontrol/acimpl/service.go +++ b/pkg/services/accesscontrol/acimpl/service.go @@ -81,6 +81,11 @@ func ProvideService( return nil, err } + // Migrating to remove deprecated permissions from the database + if err := migrator.MigrateRemoveDeprecatedPermissions(db, service.log); err != nil { + return nil, err + } + return service, nil } @@ -699,7 +704,7 @@ func PermissionMatchesSearchOptions(permission accesscontrol.Permission, searchO if searchOptions.Scope != "" { // Permissions including the scope should also match scopes := append(searchOptions.Wildcards(), searchOptions.Scope) - if !slices.Contains[[]string, string](scopes, permission.Scope) { + if !slices.Contains(scopes, permission.Scope) { return false } } diff --git a/pkg/services/accesscontrol/migrator/migrator.go b/pkg/services/accesscontrol/migrator/migrator.go index 8ecc20ad553..1463ffd9eaa 100644 --- a/pkg/services/accesscontrol/migrator/migrator.go +++ b/pkg/services/accesscontrol/migrator/migrator.go @@ -4,8 +4,11 @@ import ( "context" "time" + "go.opentelemetry.io/otel/attribute" + "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/infra/tracing" ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/session" @@ -120,6 +123,90 @@ func batch(count, batchSize int, eachFn func(start, end int) error) error { return nil } +// MigrateRemoveDeprecatedPermissions removes deprecated permissions from the database +func MigrateRemoveDeprecatedPermissions(db db.DB, log log.Logger) error { + ctx := context.Background() + ctx, span := tracing.Start(ctx, "migrator.removeDeprecatedPermissions", + attribute.String("migration.type", "removeDeprecatedPermissions")) + defer span.End() + + t := time.Now() + + // Define the deprecated permissions to remove + deprecatedPermissions := []string{ + "apikeys:", // remove this line in 2026/03, no apikeys:read/write/create should exist by then and downgrade/upgrade scenarios are less likely + } + if len(deprecatedPermissions) == 0 { + span.SetAttributes(attribute.Bool("migration.skipped", true)) + log.Debug("No deprecated permissions to remove", "migration", "removeDeprecatedPermissions") + return nil + } + + span.SetAttributes(attribute.Int("deprecated.patterns.count", len(deprecatedPermissions))) + log.Info("Starting migration to remove deprecated permissions", "migration", "removeDeprecatedPermissions") + + // Find and remove permissions matching the deprecated patterns + var totalRemoved int + for _, permPattern := range deprecatedPermissions { + patternCtx, patternSpan := tracing.Start(ctx, "migrator.removeDeprecatedPermissions.pattern", + attribute.String("pattern", permPattern)) + patternSpan.SetAttributes(attribute.String("migration.type", "removeDeprecatedPermissions")) + + var permissions []ac.Permission + if errFind := db.WithTransactionalDbSession(patternCtx, func(sess *sqlstore.DBSession) error { + return sess.SQL("SELECT id FROM permission WHERE action LIKE ?", permPattern+"%").Find(&permissions) + }); errFind != nil { + log.Error("Could not search for deprecated permissions to remove", "migration", "removeDeprecatedPermissions", "pattern", permPattern, "error", errFind) + patternSpan.RecordError(errFind) + patternSpan.End() + return errFind + } + + patternSpan.SetAttributes(attribute.Int("permissions.found", len(permissions))) + + if len(permissions) == 0 { + log.Debug("No permissions found for pattern", "migration", "removeDeprecatedPermissions", "pattern", permPattern) + patternSpan.End() + continue + } + + // Remove permissions by the exact IDs we found + if errDel := db.GetSqlxSession().WithTransaction(patternCtx, func(tx *session.SessionTx) error { + delQuery := "DELETE FROM permission WHERE id IN (" + delArgs := make([]any, 0, len(permissions)) + for i := range permissions { + delQuery += "?," + delArgs = append(delArgs, permissions[i].ID) + } + // close the IN clause + delQuery = delQuery[:len(delQuery)-1] + ")" + + _, err := tx.Exec(patternCtx, delQuery, delArgs...) + return err + }); errDel != nil { + log.Error("Error deleting deprecated permissions", "migration", "removeDeprecatedPermissions", "pattern", permPattern, "error", errDel) + patternSpan.RecordError(errDel) + patternSpan.End() + return errDel + } + + // We previously fetched matching permissions; count them as removed + totalRemoved += len(permissions) + patternSpan.SetAttributes(attribute.Int("permissions.removed", len(permissions))) + log.Info("Removed deprecated permissions for pattern", "migration", "removeDeprecatedPermissions", "pattern", permPattern, "count", len(permissions)) + + patternSpan.End() + } + + span.SetAttributes( + attribute.Int("permissions.total.removed", totalRemoved), + attribute.Int("migration.duration.ms", int(time.Since(t).Milliseconds())), + ) + + log.Info("Completed migration to remove deprecated permissions", "migration", "removeDeprecatedPermissions", "totalRemoved", totalRemoved, "duration", time.Since(t)) + return nil +} + func trimToMaxLen(s string, maxLen int) string { if len(s) > maxLen { return s[:maxLen] diff --git a/pkg/services/accesscontrol/migrator/migrator_test.go b/pkg/services/accesscontrol/migrator/migrator_test.go index a9714d9677c..5595a251c81 100644 --- a/pkg/services/accesscontrol/migrator/migrator_test.go +++ b/pkg/services/accesscontrol/migrator/migrator_test.go @@ -88,3 +88,216 @@ func TestIntegrationMigrateScopeSplitTruncation(t *testing.T) { } } } + +// batchInsertTestPermissions inserts test permissions for migration testing +func batchInsertTestPermissions(cnt int, sqlStore db.DB, actionPrefix string) error { + now := time.Now() + suffixes := []string{"read", "write", "delete"} + + return batch(cnt, batchSize, func(start, end int) error { + n := end - start + permissions := make([]ac.Permission, 0, n) + for i := start; i < end; i++ { + suffix := suffixes[i%len(suffixes)] + permissions = append(permissions, ac.Permission{ + RoleID: 1, + Action: fmt.Sprintf("%s:%s", actionPrefix, suffix), + Scope: fmt.Sprintf("%s:uid:%v", actionPrefix, i+1), + Created: now, + Updated: now, + }) + } + return sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + _, err := sess.Insert(permissions) + return err + }) + }) +} + +// TestIntegrationMigrateRemoveDeprecatedPermissions tests the deprecated permissions removal migration +func TestIntegrationMigrateRemoveDeprecatedPermissions(t *testing.T) { + testutil.SkipIntegrationTestInShortMode(t) + + sqlStore := db.InitTestDB(t) + logger := log.New("accesscontrol.migrator.test") + + // Test 1: Basic functionality - remove deprecated permissions + t.Run("removes deprecated permissions", func(t *testing.T) { + // Insert deprecated permissions (apikeys: pattern) + require.NoError(t, batchInsertTestPermissions(5, sqlStore, "apikeys"), "could not insert deprecated permissions") + + // Insert non-deprecated permissions + require.NoError(t, batchInsertTestPermissions(3, sqlStore, "dashboards"), "could not insert non-deprecated permissions") + + // Count permissions before migration + var permissionsBefore []ac.Permission + err := sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissionsBefore) + }) + require.NoError(t, err, "could not count permissions before migration") + assert.Equal(t, 8, len(permissionsBefore), "expected 8 permissions before migration") + + // Run migration + require.NoError(t, MigrateRemoveDeprecatedPermissions(sqlStore, logger)) + + // Count permissions after migration + var permissionsAfter []ac.Permission + err = sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissionsAfter) + }) + require.NoError(t, err, "could not count permissions after migration") + assert.Equal(t, 3, len(permissionsAfter), "expected 3 permissions after migration") + + // Verify only non-deprecated permissions remain + for _, perm := range permissionsAfter { + assert.NotContains(t, perm.Action, "apikeys:", "deprecated permission should have been removed") + } + }) +} + +// TestIntegrationMigrateRemoveDeprecatedPermissionsEmptyDB tests migration with empty database +func TestIntegrationMigrateRemoveDeprecatedPermissionsEmptyDB(t *testing.T) { + testutil.SkipIntegrationTestInShortMode(t) + + sqlStore := db.InitTestDB(t) + logger := log.New("accesscontrol.migrator.test") + + // Run migration on empty database + require.NoError(t, MigrateRemoveDeprecatedPermissions(sqlStore, logger)) + + // Verify no permissions exist + var permissions []ac.Permission + err := sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissions) + }) + require.NoError(t, err, "could not query permissions") + assert.Empty(t, permissions, "expected no permissions in empty database") +} + +// TestIntegrationMigrateRemoveDeprecatedPermissionsBatchProcessing tests batch processing with large dataset +func TestIntegrationMigrateRemoveDeprecatedPermissionsBatchProcessing(t *testing.T) { + testutil.SkipIntegrationTestInShortMode(t) + + sqlStore := db.InitTestDB(t) + logger := log.New("accesscontrol.migrator.test") + + // Set small batch size for testing + originalBatchSize := batchSize + batchSize = 3 + defer func() { batchSize = originalBatchSize }() + + // Insert more deprecated permissions than batch size + require.NoError(t, batchInsertTestPermissions(10, sqlStore, "apikeys"), "could not insert deprecated permissions") + + // Insert some non-deprecated permissions + require.NoError(t, batchInsertTestPermissions(2, sqlStore, "folders"), "could not insert non-deprecated permissions") + + // Count permissions before migration + var permissionsBefore []ac.Permission + err := sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissionsBefore) + }) + require.NoError(t, err, "could not count permissions before migration") + assert.Equal(t, 12, len(permissionsBefore), "expected 12 permissions before migration") + + // Run migration + require.NoError(t, MigrateRemoveDeprecatedPermissions(sqlStore, logger)) + + // Count permissions after migration + var permissionsAfter []ac.Permission + err = sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissionsAfter) + }) + require.NoError(t, err, "could not count permissions after migration") + assert.Equal(t, 2, len(permissionsAfter), "expected 2 permissions after migration") + + // Verify only non-deprecated permissions remain + for _, perm := range permissionsAfter { + assert.NotContains(t, perm.Action, "apikeys:", "deprecated permission should have been removed") + assert.Contains(t, perm.Action, "folders:", "non-deprecated permission should remain") + } +} + +// TestIntegrationMigrateRemoveDeprecatedPermissionsNoDeprecated tests when no deprecated permissions exist +func TestIntegrationMigrateRemoveDeprecatedPermissionsNoDeprecated(t *testing.T) { + testutil.SkipIntegrationTestInShortMode(t) + + sqlStore := db.InitTestDB(t) + logger := log.New("accesscontrol.migrator.test") + + // Insert only non-deprecated permissions + require.NoError(t, batchInsertTestPermissions(5, sqlStore, "users"), "could not insert non-deprecated permissions") + + // Count permissions before migration + var permissionsBefore []ac.Permission + err := sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissionsBefore) + }) + require.NoError(t, err, "could not count permissions before migration") + assert.Equal(t, 5, len(permissionsBefore), "expected 5 permissions before migration") + + // Run migration + require.NoError(t, MigrateRemoveDeprecatedPermissions(sqlStore, logger)) + + // Count permissions after migration + var permissionsAfter []ac.Permission + err = sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissionsAfter) + }) + require.NoError(t, err, "could not count permissions after migration") + assert.Equal(t, 5, len(permissionsAfter), "expected 5 permissions after migration (none should be removed)") + + // Verify all permissions remain unchanged + for _, perm := range permissionsAfter { + assert.NotContains(t, perm.Action, "apikeys:", "no deprecated permissions should exist") + assert.Contains(t, perm.Action, "users:", "non-deprecated permissions should remain") + } +} + +// TestIntegrationMigrateRemoveDeprecatedPermissionsMixedPatterns tests mixed deprecated and non-deprecated patterns +func TestIntegrationMigrateRemoveDeprecatedPermissionsMixedPatterns(t *testing.T) { + testutil.SkipIntegrationTestInShortMode(t) + + sqlStore := db.InitTestDB(t) + logger := log.New("accesscontrol.migrator.test") + + // Insert deprecated permissions + require.NoError(t, batchInsertTestPermissions(3, sqlStore, "apikeys"), "could not insert deprecated permissions") + + // Insert various non-deprecated permissions + require.NoError(t, batchInsertTestPermissions(2, sqlStore, "dashboards"), "could not insert dashboard permissions") + require.NoError(t, batchInsertTestPermissions(2, sqlStore, "folders"), "could not insert folder permissions") + require.NoError(t, batchInsertTestPermissions(2, sqlStore, "datasources"), "could not insert datasource permissions") + + // Count permissions before migration + var permissionsBefore []ac.Permission + err := sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissionsBefore) + }) + require.NoError(t, err, "could not count permissions before migration") + assert.Equal(t, 9, len(permissionsBefore), "expected 9 permissions before migration") + + // Run migration + require.NoError(t, MigrateRemoveDeprecatedPermissions(sqlStore, logger)) + + // Count permissions after migration + var permissionsAfter []ac.Permission + err = sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error { + return sess.Find(&permissionsAfter) + }) + require.NoError(t, err, "could not count permissions after migration") + assert.Equal(t, 6, len(permissionsAfter), "expected 6 permissions after migration") + + // Verify deprecated permissions are removed and others remain + deprecatedCount := 0 + validCount := 0 + for _, perm := range permissionsAfter { + if strings.HasPrefix(perm.Action, "apikeys:") { + deprecatedCount++ + } else { + validCount++ + } + } + assert.Equal(t, 0, deprecatedCount, "no deprecated permissions should remain") + assert.Equal(t, 6, validCount, "expected 6 valid permissions to remain") +} diff --git a/pkg/services/accesscontrol/models.go b/pkg/services/accesscontrol/models.go index dc12171eaa5..8cfb9d5121b 100644 --- a/pkg/services/accesscontrol/models.go +++ b/pkg/services/accesscontrol/models.go @@ -328,12 +328,6 @@ const ( K6FolderUID = "k6-app" RoleGrafanaAdmin = "Grafana Admin" - // Permission actions - - ActionAPIKeyRead = "apikeys:read" - ActionAPIKeyCreate = "apikeys:create" - ActionAPIKeyDelete = "apikeys:delete" - // Users actions ActionUsersRead = "users:read" ActionUsersWrite = "users:write" @@ -391,9 +385,6 @@ const ( // Global Scopes ScopeGlobalUsersAll = "global.users:*" - // APIKeys scope - ScopeAPIKeysAll = "apikeys:*" - // Users scope ScopeUsersAll = "users:*" ScopeUsersPrefix = "users:id:" @@ -587,9 +578,6 @@ var OrgsCreateAccessEvaluator = EvalAll( EvalPermission(ActionOrgsCreate), ) -// ApiKeyAccessEvaluator is used to protect the "Configuration > API keys" page access -var ApiKeyAccessEvaluator = EvalPermission(ActionAPIKeyRead) - type QueryWithOrg struct { OrgId *int64 `json:"orgId"` Global bool `json:"global"` diff --git a/pkg/services/accesscontrol/permreg/permreg.go b/pkg/services/accesscontrol/permreg/permreg.go index 1d46d749b38..5d025a1258b 100644 --- a/pkg/services/accesscontrol/permreg/permreg.go +++ b/pkg/services/accesscontrol/permreg/permreg.go @@ -82,7 +82,6 @@ func newPermissionRegistry() *permissionRegistry { "dashboards": "dashboards:uid:", "folders": "folders:uid:", "annotations": "annotations:type:", - "apikeys": "apikeys:id:", "orgs": "orgs:id:", "plugins": "plugins:id:", "provisioners": "provisioners:", diff --git a/pkg/services/apikey/apikeyimpl/store_test.go b/pkg/services/apikey/apikeyimpl/store_test.go index ac2cfb06088..dda62c750bd 100644 --- a/pkg/services/apikey/apikeyimpl/store_test.go +++ b/pkg/services/apikey/apikeyimpl/store_test.go @@ -56,6 +56,9 @@ func seedApiKeys(t *testing.T, store store, num int) { } func testIntegrationApiKeyDataAccess(t *testing.T, fn getStore) { + if testing.Short() { + t.Skip("skipping integration test") + } t.Helper() mockTimeNow() @@ -188,24 +191,18 @@ func testIntegrationApiKeyDataAccess(t *testing.T, fn getStore) { t.Run("Testing Get API keys", func(t *testing.T) { tests := []getApiKeysTestCase{ { - desc: "expect all keys for wildcard scope", - user: &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{ - 1: {"apikeys:read": {"apikeys:*"}}, - }}, + desc: "expect all keys for wildcard scope", + user: &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{}}, expectedAllNumKeys: 10, }, { - desc: "expect only api keys that user have scopes for", - user: &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{ - 1: {"apikeys:read": {"apikeys:id:1", "apikeys:id:3"}}, - }}, + desc: "expect only api keys that user have scopes for", + user: &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{}}, expectedAllNumKeys: 10, }, { - desc: "expect no keys when user have no scopes", - user: &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{ - 1: {"apikeys:read": {}}, - }}, + desc: "expect no keys when user have no scopes", + user: &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{}}, expectedAllNumKeys: 10, }, } diff --git a/pkg/services/apikey/model.go b/pkg/services/apikey/model.go index 7e1bcf71446..7a2118590d4 100644 --- a/pkg/services/apikey/model.go +++ b/pkg/services/apikey/model.go @@ -31,7 +31,6 @@ type APIKey struct { func (k APIKey) TableName() string { return "api_key" } -// swagger:model AddAPIKeyCommand type AddCommand struct { Name string `json:"name" binding:"Required"` Role org.RoleType `json:"role" binding:"Required"` diff --git a/pkg/services/authn/clients/api_key.go b/pkg/services/authn/clients/api_key.go index 2023cb4e418..d2357f10f1f 100644 --- a/pkg/services/authn/clients/api_key.go +++ b/pkg/services/authn/clients/api_key.go @@ -60,7 +60,7 @@ func (s *APIKey) Authenticate(ctx context.Context, r *authn.Request) (*authn.Ide defer span.End() key, err := s.getAPIKey(ctx, getTokenFromRequest(r)) if err != nil { - if errors.Is(err, apikeygen.ErrInvalidApiKey) { + if errors.Is(err, satokengen.ErrInvalidApiKey) { return nil, errAPIKeyInvalid.Errorf("API key is invalid") } return nil, err @@ -141,7 +141,7 @@ func (s *APIKey) getFromTokenLegacy(ctx context.Context, token string) (*apikey. return nil, err } if !isValid { - return nil, apikeygen.ErrInvalidApiKey + return nil, satokengen.ErrInvalidApiKey } return key, nil diff --git a/pkg/services/authn/clients/api_key_test.go b/pkg/services/authn/clients/api_key_test.go index 62fc83bc7f0..5a47b1879db 100644 --- a/pkg/services/authn/clients/api_key_test.go +++ b/pkg/services/authn/clients/api_key_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/assert" claims "github.com/grafana/authlib/types" - "github.com/grafana/grafana/pkg/components/apikeygen" "github.com/grafana/grafana/pkg/components/satokengen" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/apikey" @@ -22,7 +21,7 @@ import ( var ( revoked = true - secret, hash = genApiKey(false) + secret, hash = genApiKey() ) func TestAPIKey_Authenticate(t *testing.T) { @@ -188,11 +187,7 @@ func boolPtr(b bool) *bool { return &b } -func genApiKey(legacy bool) (string, string) { - if legacy { - res, _ := apikeygen.New(1, "test") - return res.ClientSecret, res.HashedKey - } +func genApiKey() (string, string) { res, _ := satokengen.New("test") return res.ClientSecret, res.HashedKey } diff --git a/pkg/services/grpcserver/interceptors/auth_test.go b/pkg/services/grpcserver/interceptors/auth_test.go index 5f989ddd79a..389459311bf 100644 --- a/pkg/services/grpcserver/interceptors/auth_test.go +++ b/pkg/services/grpcserver/interceptors/auth_test.go @@ -102,8 +102,8 @@ func TestAuthenticator_Authenticate(t *testing.T) { }, nil) permissions := []accesscontrol.Permission{ { - Action: accesscontrol.ActionAPIKeyRead, - Scope: accesscontrol.ScopeAPIKeysAll, + Action: accesscontrol.ActionUsersWrite, + Scope: accesscontrol.ScopeUsersAll, }, } ac := accesscontrolmock.New().WithPermissions(permissions) @@ -114,7 +114,7 @@ func TestAuthenticator_Authenticate(t *testing.T) { require.NoError(t, err) signedInUser := grpccontext.FromContext(ctx).SignedInUser require.Equal(t, serviceAccountId, signedInUser.UserID) - require.Equal(t, []string{accesscontrol.ScopeAPIKeysAll}, signedInUser.Permissions[1][accesscontrol.ActionAPIKeyRead]) + require.Equal(t, []string{accesscontrol.ScopeUsersAll}, signedInUser.Permissions[1][accesscontrol.ActionUsersWrite]) }) } diff --git a/pkg/services/serviceaccounts/database/token_store_test.go b/pkg/services/serviceaccounts/database/token_store_test.go index bef863abd11..45767c349b9 100644 --- a/pkg/services/serviceaccounts/database/token_store_test.go +++ b/pkg/services/serviceaccounts/database/token_store_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/components/apikeygen" + "github.com/grafana/grafana/pkg/components/satokengen" "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/serviceaccounts/tests" "github.com/grafana/grafana/pkg/util/testutil" @@ -29,7 +29,7 @@ func TestIntegration_Store_AddServiceAccountToken(t *testing.T) { for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { keyName := t.Name() - key, err := apikeygen.New(user.OrgID, keyName) + key, err := satokengen.New(keyName) require.NoError(t, err) cmd := serviceaccounts.AddServiceAccountTokenCommand{ @@ -84,7 +84,7 @@ func TestIntegration_Store_AddServiceAccountToken_WrongServiceAccount(t *testing sa := tests.SetupUserServiceAccount(t, db, store.cfg, saToCreate) keyName := t.Name() - key, err := apikeygen.New(sa.OrgID, keyName) + key, err := satokengen.New(keyName) require.NoError(t, err) cmd := serviceaccounts.AddServiceAccountTokenCommand{ @@ -106,7 +106,7 @@ func TestIntegration_Store_RevokeServiceAccountToken(t *testing.T) { sa := tests.SetupUserServiceAccount(t, db, store.cfg, userToCreate) keyName := t.Name() - key, err := apikeygen.New(sa.OrgID, keyName) + key, err := satokengen.New(keyName) require.NoError(t, err) cmd := serviceaccounts.AddServiceAccountTokenCommand{ @@ -148,7 +148,7 @@ func TestIntegration_Store_DeleteServiceAccountToken(t *testing.T) { sa := tests.SetupUserServiceAccount(t, db, store.cfg, userToCreate) keyName := t.Name() - key, err := apikeygen.New(sa.OrgID, keyName) + key, err := satokengen.New(keyName) require.NoError(t, err) cmd := serviceaccounts.AddServiceAccountTokenCommand{ diff --git a/pkg/services/serviceaccounts/extsvcaccounts/service.go b/pkg/services/serviceaccounts/extsvcaccounts/service.go index d51df9964ca..c27b8aadb85 100644 --- a/pkg/services/serviceaccounts/extsvcaccounts/service.go +++ b/pkg/services/serviceaccounts/extsvcaccounts/service.go @@ -350,7 +350,7 @@ func (esa *ExtSvcAccountsService) getExtSvcAccountToken(ctx context.Context, org // Get credentials from store credentials, err := esa.GetExtSvcCredentials(ctx, orgID, extSvcSlug) if err != nil && !errors.Is(err, ErrCredentialsNotFound) { - if !errors.Is(err, &satokengen.ErrInvalidApiKey{}) { + if !errors.Is(err, satokengen.ErrInvalidApiKey) { return "", err } ctxLogger.Warn("Invalid token found in store, recovering...", "service", extSvcSlug, "orgID", orgID) diff --git a/public/api-enterprise-spec.json b/public/api-enterprise-spec.json index 9fa1d213c0a..ea2046dedd7 100644 --- a/public/api-enterprise-spec.json +++ b/public/api-enterprise-spec.json @@ -2475,27 +2475,6 @@ } } }, - "AddAPIKeyCommand": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "role": { - "type": "string", - "enum": [ - "None", - "Viewer", - "Editor", - "Admin" - ] - }, - "secondsToLive": { - "type": "integer", - "format": "int64" - } - } - }, "AddDataSourceCommand": { "description": "Also acts as api DTO", "type": "object", diff --git a/public/api-merged.json b/public/api-merged.json index 5b0d1291c82..830f4f4c309 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -12622,27 +12622,6 @@ } } }, - "AddAPIKeyCommand": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "role": { - "type": "string", - "enum": [ - "None", - "Viewer", - "Editor", - "Admin" - ] - }, - "secondsToLive": { - "type": "integer", - "format": "int64" - } - } - }, "AddDataSourceCommand": { "description": "Also acts as api DTO", "type": "object", diff --git a/public/app/core/reducers/navModel.test.ts b/public/app/core/reducers/navModel.test.ts index 0b6b00ebede..3655efdb400 100644 --- a/public/app/core/reducers/navModel.test.ts +++ b/public/app/core/reducers/navModel.test.ts @@ -49,31 +49,28 @@ describe('navModelReducer', () => { const teams = { id: 'teams', text: 'Teams' }; const plugins = { id: 'plugins', text: 'Plugins' }; const orgsettings = { id: 'org-settings', text: 'Preferences' }; - const apikeys = { id: 'apikeys', text: 'API Keys' }; const initialState = { - cfg: { ...originalCfg, children: [datasources, users, teams, plugins, orgsettings, apikeys] }, + cfg: { ...originalCfg, children: [datasources, users, teams, plugins, orgsettings] }, datasources: { ...datasources, parentItem: originalCfg }, correlations: { ...correlations, parentItem: originalCfg }, users: { ...users, parentItem: originalCfg }, teams: { ...teams, parentItem: originalCfg }, plugins: { ...plugins, parentItem: originalCfg }, 'org-settings': { ...orgsettings, parentItem: originalCfg }, - apikeys: { ...apikeys, parentItem: originalCfg }, }; const newOrgName = 'Org 2'; const subTitle = `Organization: ${newOrgName}`; const newCfg = { ...originalCfg, subTitle }; const expectedState = { - cfg: { ...newCfg, children: [datasources, users, teams, plugins, orgsettings, apikeys] }, + cfg: { ...newCfg, children: [datasources, users, teams, plugins, orgsettings] }, datasources: { ...datasources, parentItem: newCfg }, correlations: { ...correlations, parentItem: newCfg }, users: { ...users, parentItem: newCfg }, teams: { ...teams, parentItem: newCfg }, plugins: { ...plugins, parentItem: newCfg }, 'org-settings': { ...orgsettings, parentItem: newCfg }, - apikeys: { ...apikeys, parentItem: newCfg }, }; reducerTester() diff --git a/public/app/core/reducers/navModel.ts b/public/app/core/reducers/navModel.ts index 6717c66b350..ed6b798bb0a 100644 --- a/public/app/core/reducers/navModel.ts +++ b/public/app/core/reducers/navModel.ts @@ -122,7 +122,6 @@ export const navIndexReducer = (state: NavIndex = initialState, action: AnyActio teams: getItemWithNewSubTitle(state.teams, subTitle), plugins: getItemWithNewSubTitle(state.plugins, subTitle), 'org-settings': getItemWithNewSubTitle(state['org-settings'], subTitle), - apikeys: getItemWithNewSubTitle(state.apikeys, subTitle), }; } else if (removeNavIndex.match(action)) { delete state[action.payload]; diff --git a/public/app/types/accessControl.ts b/public/app/types/accessControl.ts index 7ef86382edc..abbf8969b05 100644 --- a/public/app/types/accessControl.ts +++ b/public/app/types/accessControl.ts @@ -155,10 +155,6 @@ export enum AccessControlAction { AlertingTemplatesWrite = 'alert.notifications.templates:write', AlertingTemplatesDelete = 'alert.notifications.templates:delete', - ActionAPIKeysRead = 'apikeys:read', - ActionAPIKeysCreate = 'apikeys:create', - ActionAPIKeysDelete = 'apikeys:delete', - PluginsInstall = 'plugins:install', PluginsWrite = 'plugins:write', diff --git a/public/openapi3.json b/public/openapi3.json index d786cb53437..9140c87244d 100644 --- a/public/openapi3.json +++ b/public/openapi3.json @@ -2150,27 +2150,6 @@ }, "type": "object" }, - "AddAPIKeyCommand": { - "properties": { - "name": { - "type": "string" - }, - "role": { - "enum": [ - "None", - "Viewer", - "Editor", - "Admin" - ], - "type": "string" - }, - "secondsToLive": { - "format": "int64", - "type": "integer" - } - }, - "type": "object" - }, "AddDataSourceCommand": { "description": "Also acts as api DTO", "properties": { From fbdfab8ceba7bd480a17d3a9915de458030dd2db Mon Sep 17 00:00:00 2001 From: Cory Forseth Date: Fri, 12 Sep 2025 07:04:31 -0500 Subject: [PATCH 28/48] Authz: add logs for monitoring (#110959) * add logs for monitoring * add logging around hook enablement --- pkg/registry/apis/folders/hooks.go | 17 +++++++++++++++-- pkg/registry/apis/folders/register.go | 6 ++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pkg/registry/apis/folders/hooks.go b/pkg/registry/apis/folders/hooks.go index e686304cba5..f0c954ecfeb 100644 --- a/pkg/registry/apis/folders/hooks.go +++ b/pkg/registry/apis/folders/hooks.go @@ -12,43 +12,56 @@ import ( ) // "Almost nobody should use this hook" but we do because we need ctx and AfterCreate doesn't have it. -func (b *FolderAPIBuilder) beginCreate(_ context.Context, obj runtime.Object, _ *metav1.CreateOptions) (registry.FinishFunc, error) { +func (b *FolderAPIBuilder) beginCreate(ctx context.Context, obj runtime.Object, _ *metav1.CreateOptions) (registry.FinishFunc, error) { + log := logging.FromContext(ctx) meta, err := utils.MetaAccessor(obj) if err != nil { + log.Error("Failed to access new folder object metadata", "error", err) return nil, err } if meta.GetFolder() == "" { // Zanzana only cares about parent-child folder relationships; nothing to do if folder is at root. + log.Info("Skipping Zanzana folder propagation for new root-level folder", "folder", meta.GetName()) return func(ctx context.Context, success bool) {}, nil } return func(ctx context.Context, success bool) { if success { + log.Info("Propagating new folder to Zanzana", "folder", meta.GetName(), "parent", meta.GetFolder()) b.writeFolderToZanzana(ctx, meta) + } else { + log.Info("Got success=false in folder create hook", "folder", meta.GetName()) } }, nil } // "Almost nobody should use this hook" but we do because we need ctx and AfterUpdate doesn't have it. -func (b *FolderAPIBuilder) beginUpdate(_ context.Context, obj runtime.Object, old runtime.Object, _ *metav1.UpdateOptions) (registry.FinishFunc, error) { +func (b *FolderAPIBuilder) beginUpdate(ctx context.Context, obj runtime.Object, old runtime.Object, _ *metav1.UpdateOptions) (registry.FinishFunc, error) { + log := logging.FromContext(ctx) updatedMeta, err := utils.MetaAccessor(obj) if err != nil { + log.Error("Failed to access updated folder object metadata", "error", err) return nil, err } oldMeta, err := utils.MetaAccessor(old) if err != nil { + log.Error("Failed to access existing folder object metadata", "error", err) return nil, err } if updatedMeta.GetFolder() == oldMeta.GetFolder() { // No change to parent folder, nothing to do. + log.Info("Skipping Zanzana folder propagation; no change in parent", "folder", oldMeta.GetName()) return func(ctx context.Context, success bool) {}, nil } return func(ctx context.Context, success bool) { if success { + log.Info("Propagating updated folder to Zanzana", "folder", oldMeta.GetName(), "oldParent", oldMeta.GetFolder(), "newParent", updatedMeta.GetFolder()) b.writeFolderToZanzana(ctx, updatedMeta) + } else { + log.Info("Got success=false in folder update hook", "folder", oldMeta.GetName()) } }, nil } diff --git a/pkg/registry/apis/folders/register.go b/pkg/registry/apis/folders/register.go index b07ce13b90b..a82fdbf1182 100644 --- a/pkg/registry/apis/folders/register.go +++ b/pkg/registry/apis/folders/register.go @@ -19,6 +19,8 @@ import ( authlib "github.com/grafana/authlib/types" + "github.com/grafana/grafana-app-sdk/logging" + folders "github.com/grafana/grafana/apps/folder/pkg/apis/folder/v1beta1" "github.com/grafana/grafana/apps/iam/pkg/reconcilers" "github.com/grafana/grafana/pkg/apimachinery/identity" @@ -181,9 +183,13 @@ func (b *FolderAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.API return err } + log := logging.FromContext(context.Background()) if b.features.IsEnabledGlobally(featuremgmt.FlagZanzana) { + log.Info("Enabling Zanzana folder propagation hooks") store.BeginCreate = b.beginCreate store.BeginUpdate = b.beginUpdate + } else { + log.Info("Zanzana is not enabled; skipping folder propagation hooks") } dw, err := dualWriteBuilder(resourceInfo.GroupResource(), legacyStore, store) From 1b066c3565c8c66d4bd968bdc450d73bbc829215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Fri, 12 Sep 2025 14:31:15 +0200 Subject: [PATCH 29/48] Devenv: expose internal faro.receiver server (#111014) --- devenv/docker/blocks/self-instrumentation/docker-compose.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/devenv/docker/blocks/self-instrumentation/docker-compose.yaml b/devenv/docker/blocks/self-instrumentation/docker-compose.yaml index fb7f7b62090..8dd3dec1ed6 100644 --- a/devenv/docker/blocks/self-instrumentation/docker-compose.yaml +++ b/devenv/docker/blocks/self-instrumentation/docker-compose.yaml @@ -42,6 +42,7 @@ - --stability.level=experimental # Enable all functionality ports: - '12345:12345' + - '12347:12347' volumes: - ./docker/blocks/self-instrumentation/config.alloy:/etc/alloy/config.alloy - ../data/log:/var/log/grafana:ro # Mount Grafana logs directory From fc2de49b88a0ce9f6803f6bcb9717d787c4cca5a Mon Sep 17 00:00:00 2001 From: Yunwen Zheng Date: Fri, 12 Sep 2025 10:20:29 -0400 Subject: [PATCH 30/48] RepositoryList: Display managed resource count (#110916) * RepositoryList: display managed resource count * display partial managed alert * Update public/app/features/provisioning/Wizard/hooks/useResourceStats.ts Co-authored-by: Alex Khomenko * Update public/locales/en-US/grafana.json Co-authored-by: Alex Khomenko * only count dashboard and folder --------- Co-authored-by: Alex Khomenko --- .../provisioning/Shared/RepositoryList.tsx | 89 ++++++++++++++----- .../Wizard/hooks/useResourceStats.ts | 69 ++++++++++---- public/locales/en-US/grafana.json | 4 + 3 files changed, 122 insertions(+), 40 deletions(-) diff --git a/public/app/features/provisioning/Shared/RepositoryList.tsx b/public/app/features/provisioning/Shared/RepositoryList.tsx index 0aa0d63c301..c129564a9bd 100644 --- a/public/app/features/provisioning/Shared/RepositoryList.tsx +++ b/public/app/features/provisioning/Shared/RepositoryList.tsx @@ -1,10 +1,12 @@ import { useState } from 'react'; -import { t } from '@grafana/i18n'; -import { EmptyState, FilterInput, Stack } from '@grafana/ui'; +import { t, Trans } from '@grafana/i18n'; +import { Alert, Box, EmptyState, FilterInput, Icon, Stack } from '@grafana/ui'; import { Repository } from 'app/api/clients/provisioning/v0alpha1'; import { RepositoryCard } from '../Repository/RepositoryCard'; +import { useResourceStats } from '../Wizard/hooks/useResourceStats'; +import { useIsProvisionedInstance } from '../hooks/useIsProvisionedInstance'; import { checkSyncSettings } from '../utils/checkSyncSettings'; interface Props { @@ -13,33 +15,72 @@ interface Props { export function RepositoryList({ items }: Props) { const [query, setQuery] = useState(''); + const isProvisionedInstance = useIsProvisionedInstance(); + const { resourceCount, managedCount, unmanagedCount } = useResourceStats(items[0].metadata?.name); const filteredItems = items.filter((item) => item.metadata?.name?.includes(query)); const { instanceConnected } = checkSyncSettings(items); - return ( - - {!instanceConnected && ( - - + + const getResourceCountSection = () => { + if (isProvisionedInstance) { + return ( + + + + + All {{ count: resourceCount }} resources are managed + + + + ); + } + + if (filteredItems.length) { + return ( + + + + {{ managedCount }}/{{ count: resourceCount }} resources managed. {{ unmanagedCount }} resources + aren't managed as code yet. + + - )} - - {filteredItems.length ? ( - filteredItems.map((item) => ) - ) : ( - + ); + } + return null; + }; + + return ( + <> + {getResourceCountSection()} + + {!instanceConnected && ( + + + )} + + {filteredItems.length ? ( + filteredItems.map((item) => ) + ) : ( + + )} + - + ); } diff --git a/public/app/features/provisioning/Wizard/hooks/useResourceStats.ts b/public/app/features/provisioning/Wizard/hooks/useResourceStats.ts index 03d259303b8..edf90010ce4 100644 --- a/public/app/features/provisioning/Wizard/hooks/useResourceStats.ts +++ b/public/app/features/provisioning/Wizard/hooks/useResourceStats.ts @@ -5,10 +5,52 @@ import { t } from '@grafana/i18n'; import { GetRepositoryFilesApiResponse, GetResourceStatsApiResponse, + ManagerStats, + ResourceCount, useGetRepositoryFilesQuery, useGetResourceStatsQuery, } from 'app/api/clients/provisioning/v0alpha1'; +function getManagedCount(managed?: ManagerStats[]) { + let totalCount = 0; + + // Loop through each managed repository + managed?.forEach((manager) => { + // Loop through stats inside each manager and sum up the counts + manager.stats.forEach((stat) => { + if (stat.group === 'folder.grafana.app' || stat.group === 'dashboard.grafana.app') { + totalCount += stat.count; + } + }); + }); + + return totalCount; +} + +function getResourceCount(stats?: ResourceCount[]) { + let counts: string[] = []; + let resourceCount = 0; + + stats?.forEach((stat) => { + switch (stat.group) { + case 'folders': + case 'folder.grafana.app': + resourceCount += stat.count; + counts.push(t('provisioning.bootstrap-step.folders-count', '{{count}} folder', { count: stat.count })); + break; + case 'dashboard.grafana.app': + resourceCount += stat.count; + counts.push(t('provisioning.bootstrap-step.dashboards-count', '{{count}} dashboard', { count: stat.count })); + break; + } + }); + + return { + counts, + resourceCount, + }; +} + /** * Calculates resource statistics from API responses */ @@ -22,22 +64,7 @@ function getResourceStats(files?: GetRepositoryFilesApiResponse, stats?: GetReso return isSupportedFile(path); }).length; - let counts: string[] = []; - let resourceCount = 0; - - stats?.instance?.forEach((stat) => { - switch (stat.group) { - case 'folders': - case 'folder.grafana.app': - resourceCount += stat.count; - counts.push(t('provisioning.bootstrap-step.folders-count', '{{count}} folder', { count: stat.count })); - break; - case 'dashboard.grafana.app': - resourceCount += stat.count; - counts.push(t('provisioning.bootstrap-step.dashboards-count', '{{count}} dashboard', { count: stat.count })); - break; - } - }); + const { counts, resourceCount } = getResourceCount(stats?.instance); return { fileCount, @@ -60,6 +87,14 @@ export function useResourceStats(repoName?: string, isLegacyStorage?: boolean) { [filesQuery.data, resourceStatsQuery.data] ); + const { managedCount, unmanagedCount } = useMemo(() => { + return { + // managed does not exist in response when first time connecting to a repo + managedCount: getManagedCount(resourceStatsQuery.data?.managed), + unmanagedCount: getResourceCount(resourceStatsQuery.data?.unmanaged).resourceCount, + }; + }, [resourceStatsQuery.data]); + const requiresMigration = isLegacyStorage || resourceCount > 0; const shouldSkipSync = !requiresMigration && resourceCount === 0 && fileCount === 0; @@ -72,6 +107,8 @@ export function useResourceStats(repoName?: string, isLegacyStorage?: boolean) { : t('provisioning.bootstrap-step.empty', 'Empty'); return { + managedCount, + unmanagedCount, resourceCount, resourceCountString: resourceCountDisplay, fileCount, diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 2434af01c23..9e4a0376ac0 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -11384,7 +11384,11 @@ "label-sync-interval": "Sync Interval (seconds)" }, "folder-repository-list": { + "all-resources-managed_one": "All {{count}} resource is managed", + "all-resources-managed_other": "All {{count}} resources are managed", "no-results-matching-your-query": "No results matching your query", + "partial-managed_one": "{{managedCount}}/{{count}} resources managed. {{unmanagedCount}} resources aren't managed as code yet.", + "partial-managed_other": "{{managedCount}}/{{count}} resources managed. {{unmanagedCount}} resources aren't managed as code yet.", "placeholder-search": "Search" }, "get-default-values": { From a27ace5cfb24952bf4be0c83400293013e7d7d56 Mon Sep 17 00:00:00 2001 From: Luminessa Starlight Date: Fri, 12 Sep 2025 10:44:40 -0400 Subject: [PATCH 31/48] Accessibility: enable responsive reflow of variables in dashboard edit (#110967) enable responsive reflow of variables in dashboard edit --- .../dashboard-scene/scene/DashboardControls.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/public/app/features/dashboard-scene/scene/DashboardControls.tsx b/public/app/features/dashboard-scene/scene/DashboardControls.tsx index f1d5a83abe4..f553cdb77b3 100644 --- a/public/app/features/dashboard-scene/scene/DashboardControls.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardControls.tsx @@ -152,10 +152,10 @@ function DashboardControlsRenderer({ model }: SceneComponentProps} {!hideTimeControls && ( - +
- +
)} {(hasControlMenuVariables || hasControlMenuLinks) && ( @@ -198,6 +198,7 @@ function getStyles(theme: GrafanaTheme2) { }, }), controlsPanelEdit: css({ + flexWrap: 'wrap-reverse', // In panel edit we do not need any right padding as the splitter is providing it paddingRight: 0, }), @@ -205,5 +206,14 @@ function getStyles(theme: GrafanaTheme2) { background: 'unset', position: 'unset', }), + timeControls: css({ + display: 'flex', + justifyContent: 'flex-end', + gap: theme.spacing(1), + }), + timeControlsWrap: css({ + flexWrap: 'wrap', + marginLeft: 'auto', + }), }; } From e22fec10b6627ae6d9589c5ef645314fcc8eb1b5 Mon Sep 17 00:00:00 2001 From: Isabella Siu Date: Fri, 12 Sep 2025 10:59:05 -0400 Subject: [PATCH 32/48] Update docs for pdc+sigv4 (#110787) * Update docs for pdc+sigv4 * Apply suggestions from code review Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com> --------- Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com> --- .../elasticsearch/configure-elasticsearch-data-source.md | 2 ++ docs/sources/datasources/prometheus/configure/_index.md | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md b/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md index 4233b218136..6b145841bbf 100644 --- a/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md +++ b/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md @@ -200,6 +200,8 @@ Each data link configuration consists of: Use private data source connect (PDC) to connect to and query data within a secure network without opening that network to inbound traffic from Grafana Cloud. See [Private data source connect](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/) for more information on how PDC works and [Configure Grafana private data source connect (PDC)](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/#configure-grafana-private-data-source-connect-pdc) for steps on setting up a PDC connection. +If you use PDC with SIGv4 (AWS Signature Version 4 Authentication), the PDC agent must allow internet egress to`sts..amazonaws.com:443`. + - **Private data source connect** - Click in the box to set the default PDC connection from the dropdown menu or create a new connection. Once you have configured your Elasticsearch data source options, click **Save & test** at the bottom to test out your data source connection. You can also remove a connection by clicking **Delete**. diff --git a/docs/sources/datasources/prometheus/configure/_index.md b/docs/sources/datasources/prometheus/configure/_index.md index 98cf92271fa..6e2c0d974f6 100644 --- a/docs/sources/datasources/prometheus/configure/_index.md +++ b/docs/sources/datasources/prometheus/configure/_index.md @@ -233,7 +233,9 @@ You can add multiple exemplars. - **Private data source connect** - _Only for Grafana Cloud users._ Private data source connect, or PDC, allows you to establish a private, secured connection between a Grafana Cloud instance, or stack, and data sources secured within a private network. Click the drop-down to locate the URL for PDC. For more information regarding Grafana PDC refer to [Private data source connect (PDC)](ref:private-data-source-connect) and [Configure Grafana private data source connect (PDC)](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/#configure-grafana-private-data-source-connect-pdc) for steps on setting up a PDC connection. -Click **Manage private data source connect** to be taken to your PDC connection page, where you’ll find your PDC configuration details. + If you use PDC with SIGv4 (AWS Signature Version 4 Authentication), the PDC agent must allow internet egress to`sts..amazonaws.com:443`. + + Click **Manage private data source connect** to open your PDC connection page and view your configuration details. After you have configured your Prometheus data source options, click **Save & test** at the bottom to test out your data source connection. From ccc87a03f0ec70eb28f9ce49221834718abeca7d Mon Sep 17 00:00:00 2001 From: Misi Date: Fri, 12 Sep 2025 17:15:15 +0200 Subject: [PATCH 33/48] Fix: Fix redirection after login when Grafana is served from subpath (#110889) Fix short link (/goto) redirection when Grafana is served from subpath --- public/app/app.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/public/app/app.ts b/public/app/app.ts index 05f6a2e0ab0..8269bb6a2d7 100644 --- a/public/app/app.ts +++ b/public/app/app.ts @@ -472,14 +472,18 @@ function handleRedirectTo(): void { } window.sessionStorage.removeItem(RedirectToUrlKey); - const decodedRedirectTo = decodeURIComponent(redirectTo); + let decodedRedirectTo = decodeURIComponent(redirectTo); if (decodedRedirectTo.startsWith('/goto/')) { // In this case there should be a request to the backend + if (config.appSubUrl && !decodedRedirectTo.startsWith(config.appSubUrl)) { + decodedRedirectTo = config.appSubUrl + decodedRedirectTo; + } window.location.replace(decodedRedirectTo); - } else { - const stripped = locationUtil.stripBaseFromUrl(decodedRedirectTo); - locationService.replace(stripped); + return; } + // Ensure that the appsuburl is stripped from the redirect to in case of a frontend redirect + const stripped = locationUtil.stripBaseFromUrl(decodedRedirectTo); + locationService.replace(stripped); } export default new GrafanaApp(); From de01b3e2092ce0f4cabb8920387d0671dd1ed3ec Mon Sep 17 00:00:00 2001 From: Haris Rozajac <58232930+harisrozajac@users.noreply.github.com> Date: Fri, 12 Sep 2025 11:31:05 -0600 Subject: [PATCH 34/48] Dashboard Schema V2: Support panel actions (#110842) * support panel actions * refactor * add test; move action transformer to utils * refactor so v2 headers and queryParams are just a simple record * update open api * update actions to be same shape accross all dashboard schemas and add validation on the backend * cleanup * update snapshot * add tests to validation --- .../kinds/v2alpha1/dashboard_spec.cue | 44 ++ .../kinds/v2beta1/dashboard_spec.cue | 45 ++ .../dashboard/v0alpha1/dashboard_kind.cue | 56 ++ .../apis/dashboard/v1beta1/dashboard_kind.cue | 56 ++ .../dashboard/v2alpha1/dashboard_spec.cue | 44 ++ .../dashboard/v2alpha1/dashboard_spec_gen.go | 101 ++++ .../pkg/apis/dashboard/v2alpha1/validation.go | 58 ++ .../dashboard/v2alpha1/validation_test.go | 495 ++++++++++++++++++ .../v2alpha1/zz_generated.openapi.go | 301 ++++++++++- ...enerated.openapi_violation_exceptions.list | 6 + .../apis/dashboard/v2beta1/dashboard_spec.cue | 45 ++ .../dashboard/v2beta1/dashboard_spec_gen.go | 101 ++++ .../pkg/apis/dashboard/v2beta1/validation.go | 58 ++ .../apis/dashboard/v2beta1/validation_test.go | 495 ++++++++++++++++++ .../dashboard/v2beta1/zz_generated.openapi.go | 301 ++++++++++- ...enerated.openapi_violation_exceptions.list | 6 + kinds/dashboard/dashboard_kind.cue | 56 ++ packages/grafana-schema/src/index.gen.ts | 10 + .../raw/dashboard/x/dashboard_types.gen.ts | 86 +++ .../dashboard/v2alpha1/types.spec.gen.ts | 77 +++ .../dashboard/v2beta1/types.spec.gen.ts | 77 +++ pkg/kinds/dashboard/dashboard_spec_gen.go | 97 ++++ .../dashboard.grafana.app-v2alpha1.json | 172 ++++++ .../transformToV2TypesUtils.test.ts | 46 +- 24 files changed, 2808 insertions(+), 25 deletions(-) create mode 100644 apps/dashboard/pkg/apis/dashboard/v2alpha1/validation_test.go create mode 100644 apps/dashboard/pkg/apis/dashboard/v2beta1/validation_test.go diff --git a/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue b/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue index 2aba16b9489..6bad69b84a9 100644 --- a/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue +++ b/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue @@ -221,6 +221,9 @@ FieldConfig: { // The behavior when clicking on a result links?: [...] + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: [...Action] + // Alternative to empty string noValue?: string @@ -364,6 +367,47 @@ FieldColor: { // Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) DashboardLinkType: "link" | "dashboards" +ActionType: "fetch" | "infinity" + +FetchOptions: { + method: HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] +} + +InfinityOptions: FetchOptions & { + datasourceUid: string +} + +HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" + +// Action variable type +ActionVariableType: "string" + +ActionVariable: { + key: string + name: string + type: ActionVariableType +} + +Action: { + type: ActionType + title: string + fetch?: FetchOptions + infinity?: InfinityOptions + confirmation?: string + oneClick?: bool + variables?: [...ActionVariable] + style?: { + backgroundColor?: string + } +} + // --- Common types --- Kind: { kind: string diff --git a/apps/dashboard/kinds/v2beta1/dashboard_spec.cue b/apps/dashboard/kinds/v2beta1/dashboard_spec.cue index 0e9dcee43b4..93a195a732e 100644 --- a/apps/dashboard/kinds/v2beta1/dashboard_spec.cue +++ b/apps/dashboard/kinds/v2beta1/dashboard_spec.cue @@ -219,6 +219,9 @@ FieldConfig: { // The behavior when clicking on a result links?: [...] + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: [...Action] + // Alternative to empty string noValue?: string @@ -362,6 +365,48 @@ FieldColor: { // Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) DashboardLinkType: "link" | "dashboards" +ActionType: "fetch" | "infinity" + +FetchOptions: { + method: HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] +} + +InfinityOptions: FetchOptions & { + datasourceUid: string +} + +HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" + +// Action variable type +ActionVariableType: "string" + +ActionVariable: { + key: string + name: string + type: ActionVariableType +} + +Action: { + type: ActionType + title: string + fetch?: FetchOptions + infinity?: InfinityOptions + confirmation?: string + oneClick?: bool + variables?: [...ActionVariable] + style?: { + backgroundColor?: string + } +} + + // --- Common types --- Kind: { kind: string diff --git a/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue b/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue index 895a7bc946a..fb971b2cc3f 100644 --- a/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue +++ b/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue @@ -302,6 +302,59 @@ lineage: schemas: [{ // - "inControlsMenu" renders the link in bottom part of the dashboard controls dropdown menu #DashboardLinkPlacement: "inControlsMenu" @cuetsy(kind="type") + // Dashboard action type + #ActionType: "fetch" | "infinity" @cuetsy(kind="type") + + // Fetch options + #FetchOptions: { + method: #HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] + } @cuetsy(kind="interface") + + // Infinity options + #InfinityOptions: { + method: #HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] + datasourceUid: string + } @cuetsy(kind="interface") + + #HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" @cuetsy(kind="type") + + // Action variable type + #ActionVariableType: "string" @cuetsy(kind="type") + + #ActionVariable: { + key: string + name: string + type: #ActionVariableType + } @cuetsy(kind="interface") + + // Dashboard action + #Action: { + type: #ActionType + title: string + fetch?: #FetchOptions + infinity?: #InfinityOptions + confirmation?: string + oneClick?: bool + variables?: [...#ActionVariable] + style?: { + backgroundColor?: string + } + } @cuetsy(kind="interface") + // Dashboard variable type // `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on. // `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only). @@ -731,6 +784,9 @@ lineage: schemas: [{ // The behavior when clicking on a result links?: [...] @grafanamaturity(NeedsExpertReview) + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: [...#Action] @grafanamaturity(NeedsExpertReview) + // Alternative to empty string noValue?: string @grafanamaturity(NeedsExpertReview) diff --git a/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue b/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue index 895a7bc946a..fb971b2cc3f 100644 --- a/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue +++ b/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue @@ -302,6 +302,59 @@ lineage: schemas: [{ // - "inControlsMenu" renders the link in bottom part of the dashboard controls dropdown menu #DashboardLinkPlacement: "inControlsMenu" @cuetsy(kind="type") + // Dashboard action type + #ActionType: "fetch" | "infinity" @cuetsy(kind="type") + + // Fetch options + #FetchOptions: { + method: #HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] + } @cuetsy(kind="interface") + + // Infinity options + #InfinityOptions: { + method: #HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] + datasourceUid: string + } @cuetsy(kind="interface") + + #HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" @cuetsy(kind="type") + + // Action variable type + #ActionVariableType: "string" @cuetsy(kind="type") + + #ActionVariable: { + key: string + name: string + type: #ActionVariableType + } @cuetsy(kind="interface") + + // Dashboard action + #Action: { + type: #ActionType + title: string + fetch?: #FetchOptions + infinity?: #InfinityOptions + confirmation?: string + oneClick?: bool + variables?: [...#ActionVariable] + style?: { + backgroundColor?: string + } + } @cuetsy(kind="interface") + // Dashboard variable type // `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on. // `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only). @@ -731,6 +784,9 @@ lineage: schemas: [{ // The behavior when clicking on a result links?: [...] @grafanamaturity(NeedsExpertReview) + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: [...#Action] @grafanamaturity(NeedsExpertReview) + // Alternative to empty string noValue?: string @grafanamaturity(NeedsExpertReview) diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec.cue b/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec.cue index f566d3775b6..602f639f81a 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec.cue +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec.cue @@ -225,6 +225,9 @@ FieldConfig: { // The behavior when clicking on a result links?: [...] + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: [...Action] + // Alternative to empty string noValue?: string @@ -368,6 +371,47 @@ FieldColor: { // Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) DashboardLinkType: "link" | "dashboards" +ActionType: "fetch" | "infinity" + +FetchOptions: { + method: HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] +} + +InfinityOptions: FetchOptions & { + datasourceUid: string +} + +HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" + +// Action variable type +ActionVariableType: "string" + +ActionVariable: { + key: string + name: string + type: ActionVariableType +} + +Action: { + type: ActionType + title: string + fetch?: FetchOptions + infinity?: InfinityOptions + confirmation?: string + oneClick?: bool + variables?: [...ActionVariable] + style?: { + backgroundColor?: string + } +} + // --- Common types --- Kind: { kind: string diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go b/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go index f1e36092724..3f4c7d9f1f5 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go @@ -392,6 +392,8 @@ type DashboardFieldConfig struct { Color *DashboardFieldColor `json:"color,omitempty"` // The behavior when clicking on a result Links []interface{} `json:"links,omitempty"` + // Define interactive HTTP requests that can be triggered from data visualizations. + Actions []DashboardAction `json:"actions,omitempty"` // Alternative to empty string NoValue *string `json:"noValue,omitempty"` // custom is specified by the FieldConfig field @@ -623,6 +625,95 @@ const ( DashboardFieldColorSeriesByModeLast DashboardFieldColorSeriesByMode = "last" ) +// +k8s:openapi-gen=true +type DashboardAction struct { + Type DashboardActionType `json:"type"` + Title string `json:"title"` + Fetch *DashboardFetchOptions `json:"fetch,omitempty"` + Infinity *DashboardInfinityOptions `json:"infinity,omitempty"` + Confirmation *string `json:"confirmation,omitempty"` + OneClick *bool `json:"oneClick,omitempty"` + Variables []DashboardActionVariable `json:"variables,omitempty"` + Style *DashboardV2alpha1ActionStyle `json:"style,omitempty"` +} + +// NewDashboardAction creates a new DashboardAction object. +func NewDashboardAction() *DashboardAction { + return &DashboardAction{} +} + +// +k8s:openapi-gen=true +type DashboardActionType string + +const ( + DashboardActionTypeFetch DashboardActionType = "fetch" + DashboardActionTypeInfinity DashboardActionType = "infinity" +) + +// +k8s:openapi-gen=true +type DashboardFetchOptions struct { + Method DashboardHttpRequestMethod `json:"method"` + Url string `json:"url"` + Body *string `json:"body,omitempty"` + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + QueryParams [][]string `json:"queryParams,omitempty"` + Headers [][]string `json:"headers,omitempty"` +} + +// NewDashboardFetchOptions creates a new DashboardFetchOptions object. +func NewDashboardFetchOptions() *DashboardFetchOptions { + return &DashboardFetchOptions{} +} + +// +k8s:openapi-gen=true +type DashboardHttpRequestMethod string + +const ( + DashboardHttpRequestMethodGET DashboardHttpRequestMethod = "GET" + DashboardHttpRequestMethodPUT DashboardHttpRequestMethod = "PUT" + DashboardHttpRequestMethodPOST DashboardHttpRequestMethod = "POST" + DashboardHttpRequestMethodDELETE DashboardHttpRequestMethod = "DELETE" + DashboardHttpRequestMethodPATCH DashboardHttpRequestMethod = "PATCH" +) + +// +k8s:openapi-gen=true +type DashboardInfinityOptions struct { + Method DashboardHttpRequestMethod `json:"method"` + Url string `json:"url"` + Body *string `json:"body,omitempty"` + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + QueryParams [][]string `json:"queryParams,omitempty"` + DatasourceUid string `json:"datasourceUid"` + Headers [][]string `json:"headers,omitempty"` +} + +// NewDashboardInfinityOptions creates a new DashboardInfinityOptions object. +func NewDashboardInfinityOptions() *DashboardInfinityOptions { + return &DashboardInfinityOptions{} +} + +// +k8s:openapi-gen=true +type DashboardActionVariable struct { + Key string `json:"key"` + Name string `json:"name"` + Type string `json:"type"` +} + +// NewDashboardActionVariable creates a new DashboardActionVariable object. +func NewDashboardActionVariable() *DashboardActionVariable { + return &DashboardActionVariable{ + Type: DashboardActionVariableType, + } +} + +// Action variable type +// +k8s:openapi-gen=true +const DashboardActionVariableType = "string" + // +k8s:openapi-gen=true type DashboardDynamicConfigValue struct { Id string `json:"id"` @@ -1831,6 +1922,16 @@ func NewDashboardV2alpha1SpecialValueMapOptions() *DashboardV2alpha1SpecialValue } } +// +k8s:openapi-gen=true +type DashboardV2alpha1ActionStyle struct { + BackgroundColor *string `json:"backgroundColor,omitempty"` +} + +// NewDashboardV2alpha1ActionStyle creates a new DashboardV2alpha1ActionStyle object. +func NewDashboardV2alpha1ActionStyle() *DashboardV2alpha1ActionStyle { + return &DashboardV2alpha1ActionStyle{} +} + // +k8s:openapi-gen=true type DashboardRepeatOptionsDirection string diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/validation.go b/apps/dashboard/pkg/apis/dashboard/v2alpha1/validation.go index 7445000d7f8..7c61faa8924 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/validation.go +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/validation.go @@ -23,6 +23,9 @@ func ValidateDashboardSpec(obj *Dashboard) field.ErrorList { } } + // Custom validation for action query params and headers + validateAndTrimActionArrays(obj) + if err := cuejson.Validate(data, getCueSchema()); err != nil { errs := field.ErrorList{} @@ -60,6 +63,61 @@ func ValidateDashboardSpec(obj *Dashboard) field.ErrorList { return nil } +// Validates and trims action query params and headers to exactly 2 elements each +// This is because we couldn't generate with cue a go struct that would have exactly two strings in each sub-array +func validateAndTrimActionArrays(obj *Dashboard) { + for _, element := range obj.Spec.Elements { + if element.PanelKind != nil { + panelElement := element.PanelKind + if panelElement.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions != nil { + processActions(panelElement.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions) + } + } + } +} + +// Helper function to process action arrays +func processActions(actions []DashboardAction) { + for _, action := range actions { + // Process FetchOptions if present + if action.Fetch != nil { + if action.Fetch.QueryParams != nil { + action.Fetch.QueryParams = trimStringArrays(action.Fetch.QueryParams) + } + if action.Fetch.Headers != nil { + action.Fetch.Headers = trimStringArrays(action.Fetch.Headers) + } + } + + // Process InfinityOptions if present + if action.Infinity != nil { + if action.Infinity.QueryParams != nil { + action.Infinity.QueryParams = trimStringArrays(action.Infinity.QueryParams) + } + if action.Infinity.Headers != nil { + action.Infinity.Headers = trimStringArrays(action.Infinity.Headers) + } + } + } +} + +// Helper function to trim 2D string arrays to exactly 2 elements per sub-array +func trimStringArrays(arrays [][]string) [][]string { + if arrays == nil { + return arrays + } + + result := make([][]string, len(arrays)) + for i, arr := range arrays { + if len(arr) > 2 { + result[i] = arr[:2] + } else { + result[i] = arr + } + } + return result +} + func formatErrorPath(path []string) string { return strings.Join(path, ".") } diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/validation_test.go b/apps/dashboard/pkg/apis/dashboard/v2alpha1/validation_test.go new file mode 100644 index 00000000000..1bac5cfa9e8 --- /dev/null +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/validation_test.go @@ -0,0 +1,495 @@ +package v2alpha1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestTrimStringArrays(t *testing.T) { + tests := []struct { + name string + input [][]string + expected [][]string + }{ + { + name: "nil input", + input: nil, + expected: nil, + }, + { + name: "empty input", + input: [][]string{}, + expected: [][]string{}, + }, + { + name: "arrays with exactly 2 elements", + input: [][]string{{"key1", "value1"}, {"key2", "value2"}}, + expected: [][]string{{"key1", "value1"}, {"key2", "value2"}}, + }, + { + name: "arrays with less than 2 elements", + input: [][]string{{"key1"}, {}}, + expected: [][]string{{"key1"}, {}}, + }, + { + name: "arrays with more than 2 elements", + input: [][]string{{"key1", "value1", "extra1"}, {"key2", "value2", "extra2", "extra3"}}, + expected: [][]string{{"key1", "value1"}, {"key2", "value2"}}, + }, + { + name: "mixed arrays", + input: [][]string{{"key1"}, {"key2", "value2"}, {"key3", "value3", "extra"}}, + expected: [][]string{{"key1"}, {"key2", "value2"}, {"key3", "value3"}}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := trimStringArrays(tt.input) + assert.Equal(t, tt.expected, result) + }) + } +} + +func TestProcessActions(t *testing.T) { + tests := []struct { + name string + actions []DashboardAction + expected []DashboardAction + }{ + { + name: "empty actions", + actions: []DashboardAction{}, + expected: []DashboardAction{}, + }, + { + name: "action with fetch options having oversized arrays", + actions: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Fetch", + Fetch: &DashboardFetchOptions{ + Method: DashboardHttpRequestMethodGET, + Url: "http://example.com", + QueryParams: [][]string{ + {"param1", "value1", "extra1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1", "extra1", "extra2"}, + {"header2", "value2"}, + }, + }, + }, + }, + expected: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Fetch", + Fetch: &DashboardFetchOptions{ + Method: DashboardHttpRequestMethodGET, + Url: "http://example.com", + QueryParams: [][]string{ + {"param1", "value1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1"}, + {"header2", "value2"}, + }, + }, + }, + }, + }, + { + name: "action with infinity options having oversized arrays", + actions: []DashboardAction{ + { + Type: DashboardActionTypeInfinity, + Title: "Test Infinity", + Infinity: &DashboardInfinityOptions{ + Method: DashboardHttpRequestMethodPOST, + Url: "http://example.com", + DatasourceUid: "test-uid", + QueryParams: [][]string{ + {"param1", "value1", "extra1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1", "extra1", "extra2"}, + {"header2", "value2"}, + }, + }, + }, + }, + expected: []DashboardAction{ + { + Type: DashboardActionTypeInfinity, + Title: "Test Infinity", + Infinity: &DashboardInfinityOptions{ + Method: DashboardHttpRequestMethodPOST, + Url: "http://example.com", + DatasourceUid: "test-uid", + QueryParams: [][]string{ + {"param1", "value1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1"}, + {"header2", "value2"}, + }, + }, + }, + }, + }, + { + name: "action without fetch or infinity options", + actions: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Action", + }, + }, + expected: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Action", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a copy to avoid modifying the original + actionsCopy := make([]DashboardAction, len(tt.actions)) + for i, action := range tt.actions { + actionsCopy[i] = action + // Deep copy the fetch options if they exist + if action.Fetch != nil { + fetchCopy := *action.Fetch + if action.Fetch.QueryParams != nil { + fetchCopy.QueryParams = make([][]string, len(action.Fetch.QueryParams)) + for j, param := range action.Fetch.QueryParams { + fetchCopy.QueryParams[j] = make([]string, len(param)) + copy(fetchCopy.QueryParams[j], param) + } + } + if action.Fetch.Headers != nil { + fetchCopy.Headers = make([][]string, len(action.Fetch.Headers)) + for j, header := range action.Fetch.Headers { + fetchCopy.Headers[j] = make([]string, len(header)) + copy(fetchCopy.Headers[j], header) + } + } + actionsCopy[i].Fetch = &fetchCopy + } + // Deep copy the infinity options if they exist + if action.Infinity != nil { + infinityCopy := *action.Infinity + if action.Infinity.QueryParams != nil { + infinityCopy.QueryParams = make([][]string, len(action.Infinity.QueryParams)) + for j, param := range action.Infinity.QueryParams { + infinityCopy.QueryParams[j] = make([]string, len(param)) + copy(infinityCopy.QueryParams[j], param) + } + } + if action.Infinity.Headers != nil { + infinityCopy.Headers = make([][]string, len(action.Infinity.Headers)) + for j, header := range action.Infinity.Headers { + infinityCopy.Headers[j] = make([]string, len(header)) + copy(infinityCopy.Headers[j], header) + } + } + actionsCopy[i].Infinity = &infinityCopy + } + } + + processActions(actionsCopy) + assert.Equal(t, tt.expected, actionsCopy) + }) + } +} + +func TestValidateAndTrimActionArrays(t *testing.T) { + tests := []struct { + name string + dashboard *Dashboard + expected *Dashboard + }{ + { + name: "dashboard with no elements", + dashboard: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{}, + }, + }, + expected: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{}, + }, + }, + }, + { + name: "dashboard with panel having actions with oversized arrays", + dashboard: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{ + "panel1": { + PanelKind: &DashboardPanelKind{ + Spec: DashboardPanelSpec{ + VizConfig: DashboardVizConfigKind{ + Spec: DashboardVizConfigSpec{ + FieldConfig: DashboardFieldConfigSource{ + Defaults: DashboardFieldConfig{ + Actions: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Action", + Fetch: &DashboardFetchOptions{ + Method: DashboardHttpRequestMethodGET, + Url: "http://example.com", + QueryParams: [][]string{ + {"param1", "value1", "extra1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1", "extra1", "extra2"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expected: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{ + "panel1": { + PanelKind: &DashboardPanelKind{ + Spec: DashboardPanelSpec{ + VizConfig: DashboardVizConfigKind{ + Spec: DashboardVizConfigSpec{ + FieldConfig: DashboardFieldConfigSource{ + Defaults: DashboardFieldConfig{ + Actions: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Action", + Fetch: &DashboardFetchOptions{ + Method: DashboardHttpRequestMethodGET, + Url: "http://example.com", + QueryParams: [][]string{ + {"param1", "value1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "dashboard with panel having no actions", + dashboard: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{ + "panel1": { + PanelKind: &DashboardPanelKind{ + Spec: DashboardPanelSpec{ + VizConfig: DashboardVizConfigKind{ + Spec: DashboardVizConfigSpec{ + FieldConfig: DashboardFieldConfigSource{ + Defaults: DashboardFieldConfig{ + Actions: nil, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expected: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{ + "panel1": { + PanelKind: &DashboardPanelKind{ + Spec: DashboardPanelSpec{ + VizConfig: DashboardVizConfigKind{ + Spec: DashboardVizConfigSpec{ + FieldConfig: DashboardFieldConfigSource{ + Defaults: DashboardFieldConfig{ + Actions: nil, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a deep copy to avoid modifying the original + dashboardCopy := deepCopyDashboard(tt.dashboard) + + validateAndTrimActionArrays(dashboardCopy) + assert.Equal(t, tt.expected, dashboardCopy) + }) + } +} + +// Helper function to create a deep copy of a Dashboard for testing +func deepCopyDashboard(original *Dashboard) *Dashboard { + if original == nil { + return nil + } + + result := &Dashboard{ + TypeMeta: original.TypeMeta, + ObjectMeta: original.ObjectMeta, + Spec: DashboardSpec{ + Elements: make(map[string]DashboardElement), + }, + Status: original.Status, + } + + for key, element := range original.Spec.Elements { + elementCopy := element + + if element.PanelKind != nil { + panelCopy := *element.PanelKind + elementCopy.PanelKind = &panelCopy + + if element.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions != nil { + actions := element.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions + actionsCopy := make([]DashboardAction, len(actions)) + + for j, action := range actions { + actionsCopy[j] = action + + // Deep copy fetch options + if action.Fetch != nil { + fetchCopy := *action.Fetch + if action.Fetch.QueryParams != nil { + fetchCopy.QueryParams = make([][]string, len(action.Fetch.QueryParams)) + for k, param := range action.Fetch.QueryParams { + fetchCopy.QueryParams[k] = make([]string, len(param)) + copy(fetchCopy.QueryParams[k], param) + } + } + if action.Fetch.Headers != nil { + fetchCopy.Headers = make([][]string, len(action.Fetch.Headers)) + for k, header := range action.Fetch.Headers { + fetchCopy.Headers[k] = make([]string, len(header)) + copy(fetchCopy.Headers[k], header) + } + } + actionsCopy[j].Fetch = &fetchCopy + } + + // Deep copy infinity options + if action.Infinity != nil { + infinityCopy := *action.Infinity + if action.Infinity.QueryParams != nil { + infinityCopy.QueryParams = make([][]string, len(action.Infinity.QueryParams)) + for k, param := range action.Infinity.QueryParams { + infinityCopy.QueryParams[k] = make([]string, len(param)) + copy(infinityCopy.QueryParams[k], param) + } + } + if action.Infinity.Headers != nil { + infinityCopy.Headers = make([][]string, len(action.Infinity.Headers)) + for k, header := range action.Infinity.Headers { + infinityCopy.Headers[k] = make([]string, len(header)) + copy(infinityCopy.Headers[k], header) + } + } + actionsCopy[j].Infinity = &infinityCopy + } + } + + elementCopy.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions = actionsCopy + } + } + + if element.LibraryPanelKind != nil { + libraryCopy := *element.LibraryPanelKind + elementCopy.LibraryPanelKind = &libraryCopy + } + + result.Spec.Elements[key] = elementCopy + } + + return result +} diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go index a53ba6483cb..0d2d96af8bc 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go @@ -18,6 +18,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v2alpha1_AnnotationPermission(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.Dashboard": schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAccess": schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAction": schema_pkg_apis_dashboard_v2alpha1_DashboardAction(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardActionVariable": schema_pkg_apis_dashboard_v2alpha1_DashboardActionVariable(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAdHocFilterWithLabels": schema_pkg_apis_dashboard_v2alpha1_DashboardAdHocFilterWithLabels(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardAdhocVariableKind(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardAdhocVariableSpec(ref), @@ -52,6 +54,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardDatasourceVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardDatasourceVariableSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardDynamicConfigValue": schema_pkg_apis_dashboard_v2alpha1_DashboardDynamicConfigValue(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardElementReference": schema_pkg_apis_dashboard_v2alpha1_DashboardElementReference(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFetchOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardFetchOptions(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldColor": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldColor(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldConfig": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldConfigSource": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfigSource(ref), @@ -63,6 +66,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableKind(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableSpec(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardInfinityOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardInfinityOptions(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableKind(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardJSONCodec": schema_pkg_apis_dashboard_v2alpha1_DashboardJSONCodec(ref), @@ -109,6 +113,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardTimeRangeOption": schema_pkg_apis_dashboard_v2alpha1_DashboardTimeRangeOption(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardTimeSettingsSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardTimeSettingsSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardTransformationKind": schema_pkg_apis_dashboard_v2alpha1_DashboardTransformationKind(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1ActionStyle": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1ActionStyle(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1FieldConfigSourceOverrides": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1FieldConfigSourceOverrides(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RangeMapOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1RangeMapOptions(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RegexMapOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1RegexMapOptions(ref), @@ -309,6 +314,109 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref common.ReferenceCall } } +func schema_pkg_apis_dashboard_v2alpha1_DashboardAction(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "fetch": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFetchOptions"), + }, + }, + "infinity": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardInfinityOptions"), + }, + }, + "confirmation": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "oneClick": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "variables": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardActionVariable"), + }, + }, + }, + }, + }, + "style": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1ActionStyle"), + }, + }, + }, + Required: []string{"type", "title"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardActionVariable", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFetchOptions", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardInfinityOptions", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1ActionStyle"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardActionVariable(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "key": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "type": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"key", "name", "type"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2alpha1_DashboardAdHocFilterWithLabels(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1805,6 +1913,82 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardElementReference(ref common.Ref } } +func schema_pkg_apis_dashboard_v2alpha1_DashboardFetchOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "method": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "body": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "queryParams": { + SchemaProps: spec.SchemaProps{ + Description: "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + "headers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + }, + Required: []string{"method", "url"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldColor(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1957,6 +2141,20 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref common.Referenc }, }, }, + "actions": { + SchemaProps: spec.SchemaProps{ + Description: "Define interactive HTTP requests that can be triggered from data visualizations.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAction"), + }, + }, + }, + }, + }, "noValue": { SchemaProps: spec.SchemaProps{ Description: "Alternative to empty string", @@ -1983,7 +2181,7 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref common.Referenc }, }, Dependencies: []string{ - "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldColor", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardThresholdsConfig", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"}, + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardAction", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardFieldColor", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardThresholdsConfig", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"}, } } @@ -2345,6 +2543,89 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableSpec(ref common. } } +func schema_pkg_apis_dashboard_v2alpha1_DashboardInfinityOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "method": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "body": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "queryParams": { + SchemaProps: spec.SchemaProps{ + Description: "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + "datasourceUid": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "headers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + }, + Required: []string{"method", "url", "datasourceUid"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -4337,6 +4618,24 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardTransformationKind(ref common.R } } +func schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1ActionStyle(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "backgroundColor": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1FieldConfigSourceOverrides(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list index 95eb59de600..84157df6895 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list @@ -1,3 +1,4 @@ +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAction,Variables API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdHocFilterWithLabels,ValueLabels API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdHocFilterWithLabels,Values API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardAdhocVariableSpec,BaseFilters @@ -9,11 +10,16 @@ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardCustomVariableSpec,Options API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardDashboardLink,Tags API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardDatasourceVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFetchOptions,Headers +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFetchOptions,QueryParams +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFieldConfig,Actions API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFieldConfig,Links API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFieldConfig,Mappings API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardFieldConfigSource,Overrides API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutSpec,Items API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardGroupByVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardInfinityOptions,Headers +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardInfinityOptions,QueryParams API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardIntervalVariableSpec,Options API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardMetadata,Finalizers API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1,DashboardPanelSpec,Links diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue index 000383a069e..8e0ea0ef763 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue @@ -223,6 +223,9 @@ FieldConfig: { // The behavior when clicking on a result links?: [...] + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: [...Action] + // Alternative to empty string noValue?: string @@ -366,6 +369,48 @@ FieldColor: { // Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) DashboardLinkType: "link" | "dashboards" +ActionType: "fetch" | "infinity" + +FetchOptions: { + method: HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] +} + +InfinityOptions: FetchOptions & { + datasourceUid: string +} + +HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" + +// Action variable type +ActionVariableType: "string" + +ActionVariable: { + key: string + name: string + type: ActionVariableType +} + +Action: { + type: ActionType + title: string + fetch?: FetchOptions + infinity?: InfinityOptions + confirmation?: string + oneClick?: bool + variables?: [...ActionVariable] + style?: { + backgroundColor?: string + } +} + + // --- Common types --- Kind: { kind: string diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go index fedd4dfd20a..b94789abcbd 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go @@ -386,6 +386,8 @@ type DashboardFieldConfig struct { Color *DashboardFieldColor `json:"color,omitempty"` // The behavior when clicking on a result Links []interface{} `json:"links,omitempty"` + // Define interactive HTTP requests that can be triggered from data visualizations. + Actions []DashboardAction `json:"actions,omitempty"` // Alternative to empty string NoValue *string `json:"noValue,omitempty"` // custom is specified by the FieldConfig field @@ -617,6 +619,95 @@ const ( DashboardFieldColorSeriesByModeLast DashboardFieldColorSeriesByMode = "last" ) +// +k8s:openapi-gen=true +type DashboardAction struct { + Type DashboardActionType `json:"type"` + Title string `json:"title"` + Fetch *DashboardFetchOptions `json:"fetch,omitempty"` + Infinity *DashboardInfinityOptions `json:"infinity,omitempty"` + Confirmation *string `json:"confirmation,omitempty"` + OneClick *bool `json:"oneClick,omitempty"` + Variables []DashboardActionVariable `json:"variables,omitempty"` + Style *DashboardV2beta1ActionStyle `json:"style,omitempty"` +} + +// NewDashboardAction creates a new DashboardAction object. +func NewDashboardAction() *DashboardAction { + return &DashboardAction{} +} + +// +k8s:openapi-gen=true +type DashboardActionType string + +const ( + DashboardActionTypeFetch DashboardActionType = "fetch" + DashboardActionTypeInfinity DashboardActionType = "infinity" +) + +// +k8s:openapi-gen=true +type DashboardFetchOptions struct { + Method DashboardHttpRequestMethod `json:"method"` + Url string `json:"url"` + Body *string `json:"body,omitempty"` + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + QueryParams [][]string `json:"queryParams,omitempty"` + Headers [][]string `json:"headers,omitempty"` +} + +// NewDashboardFetchOptions creates a new DashboardFetchOptions object. +func NewDashboardFetchOptions() *DashboardFetchOptions { + return &DashboardFetchOptions{} +} + +// +k8s:openapi-gen=true +type DashboardHttpRequestMethod string + +const ( + DashboardHttpRequestMethodGET DashboardHttpRequestMethod = "GET" + DashboardHttpRequestMethodPUT DashboardHttpRequestMethod = "PUT" + DashboardHttpRequestMethodPOST DashboardHttpRequestMethod = "POST" + DashboardHttpRequestMethodDELETE DashboardHttpRequestMethod = "DELETE" + DashboardHttpRequestMethodPATCH DashboardHttpRequestMethod = "PATCH" +) + +// +k8s:openapi-gen=true +type DashboardInfinityOptions struct { + Method DashboardHttpRequestMethod `json:"method"` + Url string `json:"url"` + Body *string `json:"body,omitempty"` + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + QueryParams [][]string `json:"queryParams,omitempty"` + DatasourceUid string `json:"datasourceUid"` + Headers [][]string `json:"headers,omitempty"` +} + +// NewDashboardInfinityOptions creates a new DashboardInfinityOptions object. +func NewDashboardInfinityOptions() *DashboardInfinityOptions { + return &DashboardInfinityOptions{} +} + +// +k8s:openapi-gen=true +type DashboardActionVariable struct { + Key string `json:"key"` + Name string `json:"name"` + Type string `json:"type"` +} + +// NewDashboardActionVariable creates a new DashboardActionVariable object. +func NewDashboardActionVariable() *DashboardActionVariable { + return &DashboardActionVariable{ + Type: DashboardActionVariableType, + } +} + +// Action variable type +// +k8s:openapi-gen=true +const DashboardActionVariableType = "string" + // +k8s:openapi-gen=true type DashboardDynamicConfigValue struct { Id string `json:"id"` @@ -1853,6 +1944,16 @@ func NewDashboardV2beta1SpecialValueMapOptions() *DashboardV2beta1SpecialValueMa } } +// +k8s:openapi-gen=true +type DashboardV2beta1ActionStyle struct { + BackgroundColor *string `json:"backgroundColor,omitempty"` +} + +// NewDashboardV2beta1ActionStyle creates a new DashboardV2beta1ActionStyle object. +func NewDashboardV2beta1ActionStyle() *DashboardV2beta1ActionStyle { + return &DashboardV2beta1ActionStyle{} +} + // +k8s:openapi-gen=true type DashboardV2beta1GroupByVariableKindDatasource struct { Name *string `json:"name,omitempty"` diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/validation.go b/apps/dashboard/pkg/apis/dashboard/v2beta1/validation.go index 3946c0d9b14..7c859626b98 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/validation.go +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/validation.go @@ -23,6 +23,9 @@ func ValidateDashboardSpec(obj *Dashboard) field.ErrorList { } } + // Custom validation for action query params and headers + validateAndTrimActionArrays(obj) + if err := cuejson.Validate(data, getCueSchema()); err != nil { errs := field.ErrorList{} @@ -60,6 +63,61 @@ func ValidateDashboardSpec(obj *Dashboard) field.ErrorList { return nil } +// Validates and trims action query params and headers to exactly 2 elements each +// This is because we couldn't generate with cue a go struct that would have exactly two strings in each sub-array +func validateAndTrimActionArrays(obj *Dashboard) { + for _, element := range obj.Spec.Elements { + if element.PanelKind != nil { + panelElement := element.PanelKind + if panelElement.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions != nil { + processActions(panelElement.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions) + } + } + } +} + +// Helper function to process action arrays +func processActions(actions []DashboardAction) { + for _, action := range actions { + // Process FetchOptions if present + if action.Fetch != nil { + if action.Fetch.QueryParams != nil { + action.Fetch.QueryParams = trimStringArrays(action.Fetch.QueryParams) + } + if action.Fetch.Headers != nil { + action.Fetch.Headers = trimStringArrays(action.Fetch.Headers) + } + } + + // Process InfinityOptions if present + if action.Infinity != nil { + if action.Infinity.QueryParams != nil { + action.Infinity.QueryParams = trimStringArrays(action.Infinity.QueryParams) + } + if action.Infinity.Headers != nil { + action.Infinity.Headers = trimStringArrays(action.Infinity.Headers) + } + } + } +} + +// Helper function to trim 2D string arrays to exactly 2 elements per sub-array +func trimStringArrays(arrays [][]string) [][]string { + if arrays == nil { + return arrays + } + + result := make([][]string, len(arrays)) + for i, arr := range arrays { + if len(arr) > 2 { + result[i] = arr[:2] + } else { + result[i] = arr + } + } + return result +} + func formatErrorPath(path []string) string { return strings.Join(path, ".") } diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/validation_test.go b/apps/dashboard/pkg/apis/dashboard/v2beta1/validation_test.go new file mode 100644 index 00000000000..226f329a761 --- /dev/null +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/validation_test.go @@ -0,0 +1,495 @@ +package v2beta1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestTrimStringArrays(t *testing.T) { + tests := []struct { + name string + input [][]string + expected [][]string + }{ + { + name: "nil input", + input: nil, + expected: nil, + }, + { + name: "empty input", + input: [][]string{}, + expected: [][]string{}, + }, + { + name: "arrays with exactly 2 elements", + input: [][]string{{"key1", "value1"}, {"key2", "value2"}}, + expected: [][]string{{"key1", "value1"}, {"key2", "value2"}}, + }, + { + name: "arrays with less than 2 elements", + input: [][]string{{"key1"}, {}}, + expected: [][]string{{"key1"}, {}}, + }, + { + name: "arrays with more than 2 elements", + input: [][]string{{"key1", "value1", "extra1"}, {"key2", "value2", "extra2", "extra3"}}, + expected: [][]string{{"key1", "value1"}, {"key2", "value2"}}, + }, + { + name: "mixed arrays", + input: [][]string{{"key1"}, {"key2", "value2"}, {"key3", "value3", "extra"}}, + expected: [][]string{{"key1"}, {"key2", "value2"}, {"key3", "value3"}}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := trimStringArrays(tt.input) + assert.Equal(t, tt.expected, result) + }) + } +} + +func TestProcessActions(t *testing.T) { + tests := []struct { + name string + actions []DashboardAction + expected []DashboardAction + }{ + { + name: "empty actions", + actions: []DashboardAction{}, + expected: []DashboardAction{}, + }, + { + name: "action with fetch options having oversized arrays", + actions: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Fetch", + Fetch: &DashboardFetchOptions{ + Method: DashboardHttpRequestMethodGET, + Url: "http://example.com", + QueryParams: [][]string{ + {"param1", "value1", "extra1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1", "extra1", "extra2"}, + {"header2", "value2"}, + }, + }, + }, + }, + expected: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Fetch", + Fetch: &DashboardFetchOptions{ + Method: DashboardHttpRequestMethodGET, + Url: "http://example.com", + QueryParams: [][]string{ + {"param1", "value1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1"}, + {"header2", "value2"}, + }, + }, + }, + }, + }, + { + name: "action with infinity options having oversized arrays", + actions: []DashboardAction{ + { + Type: DashboardActionTypeInfinity, + Title: "Test Infinity", + Infinity: &DashboardInfinityOptions{ + Method: DashboardHttpRequestMethodPOST, + Url: "http://example.com", + DatasourceUid: "test-uid", + QueryParams: [][]string{ + {"param1", "value1", "extra1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1", "extra1", "extra2"}, + {"header2", "value2"}, + }, + }, + }, + }, + expected: []DashboardAction{ + { + Type: DashboardActionTypeInfinity, + Title: "Test Infinity", + Infinity: &DashboardInfinityOptions{ + Method: DashboardHttpRequestMethodPOST, + Url: "http://example.com", + DatasourceUid: "test-uid", + QueryParams: [][]string{ + {"param1", "value1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1"}, + {"header2", "value2"}, + }, + }, + }, + }, + }, + { + name: "action without fetch or infinity options", + actions: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Action", + }, + }, + expected: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Action", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a copy to avoid modifying the original + actionsCopy := make([]DashboardAction, len(tt.actions)) + for i, action := range tt.actions { + actionsCopy[i] = action + // Deep copy the fetch options if they exist + if action.Fetch != nil { + fetchCopy := *action.Fetch + if action.Fetch.QueryParams != nil { + fetchCopy.QueryParams = make([][]string, len(action.Fetch.QueryParams)) + for j, param := range action.Fetch.QueryParams { + fetchCopy.QueryParams[j] = make([]string, len(param)) + copy(fetchCopy.QueryParams[j], param) + } + } + if action.Fetch.Headers != nil { + fetchCopy.Headers = make([][]string, len(action.Fetch.Headers)) + for j, header := range action.Fetch.Headers { + fetchCopy.Headers[j] = make([]string, len(header)) + copy(fetchCopy.Headers[j], header) + } + } + actionsCopy[i].Fetch = &fetchCopy + } + // Deep copy the infinity options if they exist + if action.Infinity != nil { + infinityCopy := *action.Infinity + if action.Infinity.QueryParams != nil { + infinityCopy.QueryParams = make([][]string, len(action.Infinity.QueryParams)) + for j, param := range action.Infinity.QueryParams { + infinityCopy.QueryParams[j] = make([]string, len(param)) + copy(infinityCopy.QueryParams[j], param) + } + } + if action.Infinity.Headers != nil { + infinityCopy.Headers = make([][]string, len(action.Infinity.Headers)) + for j, header := range action.Infinity.Headers { + infinityCopy.Headers[j] = make([]string, len(header)) + copy(infinityCopy.Headers[j], header) + } + } + actionsCopy[i].Infinity = &infinityCopy + } + } + + processActions(actionsCopy) + assert.Equal(t, tt.expected, actionsCopy) + }) + } +} + +func TestValidateAndTrimActionArrays(t *testing.T) { + tests := []struct { + name string + dashboard *Dashboard + expected *Dashboard + }{ + { + name: "dashboard with no elements", + dashboard: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{}, + }, + }, + expected: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{}, + }, + }, + }, + { + name: "dashboard with panel having actions with oversized arrays", + dashboard: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{ + "panel1": { + PanelKind: &DashboardPanelKind{ + Spec: DashboardPanelSpec{ + VizConfig: DashboardVizConfigKind{ + Spec: DashboardVizConfigSpec{ + FieldConfig: DashboardFieldConfigSource{ + Defaults: DashboardFieldConfig{ + Actions: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Action", + Fetch: &DashboardFetchOptions{ + Method: DashboardHttpRequestMethodGET, + Url: "http://example.com", + QueryParams: [][]string{ + {"param1", "value1", "extra1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1", "extra1", "extra2"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expected: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{ + "panel1": { + PanelKind: &DashboardPanelKind{ + Spec: DashboardPanelSpec{ + VizConfig: DashboardVizConfigKind{ + Spec: DashboardVizConfigSpec{ + FieldConfig: DashboardFieldConfigSource{ + Defaults: DashboardFieldConfig{ + Actions: []DashboardAction{ + { + Type: DashboardActionTypeFetch, + Title: "Test Action", + Fetch: &DashboardFetchOptions{ + Method: DashboardHttpRequestMethodGET, + Url: "http://example.com", + QueryParams: [][]string{ + {"param1", "value1"}, + {"param2", "value2"}, + }, + Headers: [][]string{ + {"header1", "value1"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "dashboard with panel having no actions", + dashboard: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{ + "panel1": { + PanelKind: &DashboardPanelKind{ + Spec: DashboardPanelSpec{ + VizConfig: DashboardVizConfigKind{ + Spec: DashboardVizConfigSpec{ + FieldConfig: DashboardFieldConfigSource{ + Defaults: DashboardFieldConfig{ + Actions: nil, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + expected: &Dashboard{ + TypeMeta: metav1.TypeMeta{ + Kind: "Dashboard", + APIVersion: "v2beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + }, + Spec: DashboardSpec{ + Elements: map[string]DashboardElement{ + "panel1": { + PanelKind: &DashboardPanelKind{ + Spec: DashboardPanelSpec{ + VizConfig: DashboardVizConfigKind{ + Spec: DashboardVizConfigSpec{ + FieldConfig: DashboardFieldConfigSource{ + Defaults: DashboardFieldConfig{ + Actions: nil, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a deep copy to avoid modifying the original + dashboardCopy := deepCopyDashboard(tt.dashboard) + + validateAndTrimActionArrays(dashboardCopy) + assert.Equal(t, tt.expected, dashboardCopy) + }) + } +} + +// Helper function to create a deep copy of a Dashboard for testing +func deepCopyDashboard(original *Dashboard) *Dashboard { + if original == nil { + return nil + } + + result := &Dashboard{ + TypeMeta: original.TypeMeta, + ObjectMeta: original.ObjectMeta, + Spec: DashboardSpec{ + Elements: make(map[string]DashboardElement), + }, + Status: original.Status, + } + + for key, element := range original.Spec.Elements { + elementCopy := element + + if element.PanelKind != nil { + panelCopy := *element.PanelKind + elementCopy.PanelKind = &panelCopy + + if element.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions != nil { + actions := element.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions + actionsCopy := make([]DashboardAction, len(actions)) + + for j, action := range actions { + actionsCopy[j] = action + + // Deep copy fetch options + if action.Fetch != nil { + fetchCopy := *action.Fetch + if action.Fetch.QueryParams != nil { + fetchCopy.QueryParams = make([][]string, len(action.Fetch.QueryParams)) + for k, param := range action.Fetch.QueryParams { + fetchCopy.QueryParams[k] = make([]string, len(param)) + copy(fetchCopy.QueryParams[k], param) + } + } + if action.Fetch.Headers != nil { + fetchCopy.Headers = make([][]string, len(action.Fetch.Headers)) + for k, header := range action.Fetch.Headers { + fetchCopy.Headers[k] = make([]string, len(header)) + copy(fetchCopy.Headers[k], header) + } + } + actionsCopy[j].Fetch = &fetchCopy + } + + // Deep copy infinity options + if action.Infinity != nil { + infinityCopy := *action.Infinity + if action.Infinity.QueryParams != nil { + infinityCopy.QueryParams = make([][]string, len(action.Infinity.QueryParams)) + for k, param := range action.Infinity.QueryParams { + infinityCopy.QueryParams[k] = make([]string, len(param)) + copy(infinityCopy.QueryParams[k], param) + } + } + if action.Infinity.Headers != nil { + infinityCopy.Headers = make([][]string, len(action.Infinity.Headers)) + for k, header := range action.Infinity.Headers { + infinityCopy.Headers[k] = make([]string, len(header)) + copy(infinityCopy.Headers[k], header) + } + } + actionsCopy[j].Infinity = &infinityCopy + } + } + + elementCopy.PanelKind.Spec.VizConfig.Spec.FieldConfig.Defaults.Actions = actionsCopy + } + } + + if element.LibraryPanelKind != nil { + libraryCopy := *element.LibraryPanelKind + elementCopy.LibraryPanelKind = &libraryCopy + } + + result.Spec.Elements[key] = elementCopy + } + + return result +} diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go b/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go index 8e3e22c83be..064f5f395b0 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go @@ -18,6 +18,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.AnnotationPermission": schema_pkg_apis_dashboard_v2beta1_AnnotationPermission(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.Dashboard": schema_pkg_apis_dashboard_v2beta1_Dashboard(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAccess": schema_pkg_apis_dashboard_v2beta1_DashboardAccess(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAction": schema_pkg_apis_dashboard_v2beta1_DashboardAction(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardActionVariable": schema_pkg_apis_dashboard_v2beta1_DashboardActionVariable(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAdHocFilterWithLabels": schema_pkg_apis_dashboard_v2beta1_DashboardAdHocFilterWithLabels(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAdhocVariableKind": schema_pkg_apis_dashboard_v2beta1_DashboardAdhocVariableKind(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAdhocVariableSpec": schema_pkg_apis_dashboard_v2beta1_DashboardAdhocVariableSpec(ref), @@ -51,6 +53,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardDatasourceVariableSpec": schema_pkg_apis_dashboard_v2beta1_DashboardDatasourceVariableSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardDynamicConfigValue": schema_pkg_apis_dashboard_v2beta1_DashboardDynamicConfigValue(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardElementReference": schema_pkg_apis_dashboard_v2beta1_DashboardElementReference(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFetchOptions": schema_pkg_apis_dashboard_v2beta1_DashboardFetchOptions(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldColor": schema_pkg_apis_dashboard_v2beta1_DashboardFieldColor(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldConfig": schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfig(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldConfigSource": schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfigSource(ref), @@ -62,6 +65,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardGridLayoutSpec": schema_pkg_apis_dashboard_v2beta1_DashboardGridLayoutSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardGroupByVariableKind": schema_pkg_apis_dashboard_v2beta1_DashboardGroupByVariableKind(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardGroupByVariableSpec": schema_pkg_apis_dashboard_v2beta1_DashboardGroupByVariableSpec(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardInfinityOptions": schema_pkg_apis_dashboard_v2beta1_DashboardInfinityOptions(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardIntervalVariableKind": schema_pkg_apis_dashboard_v2beta1_DashboardIntervalVariableKind(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardIntervalVariableSpec": schema_pkg_apis_dashboard_v2beta1_DashboardIntervalVariableSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardJSONCodec": schema_pkg_apis_dashboard_v2beta1_DashboardJSONCodec(ref), @@ -108,6 +112,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardTimeRangeOption": schema_pkg_apis_dashboard_v2beta1_DashboardTimeRangeOption(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardTimeSettingsSpec": schema_pkg_apis_dashboard_v2beta1_DashboardTimeSettingsSpec(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardTransformationKind": schema_pkg_apis_dashboard_v2beta1_DashboardTransformationKind(ref), + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1ActionStyle": schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1ActionStyle(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1AdhocVariableKindDatasource": schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1AdhocVariableKindDatasource(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1DataQueryKindDatasource": schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1DataQueryKindDatasource(ref), "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1FieldConfigSourceOverrides": schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1FieldConfigSourceOverrides(ref), @@ -311,6 +316,109 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardAccess(ref common.ReferenceCallb } } +func schema_pkg_apis_dashboard_v2beta1_DashboardAction(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "fetch": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFetchOptions"), + }, + }, + "infinity": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardInfinityOptions"), + }, + }, + "confirmation": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "oneClick": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "variables": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardActionVariable"), + }, + }, + }, + }, + }, + "style": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1ActionStyle"), + }, + }, + }, + Required: []string{"type", "title"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardActionVariable", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFetchOptions", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardInfinityOptions", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardV2beta1ActionStyle"}, + } +} + +func schema_pkg_apis_dashboard_v2beta1_DashboardActionVariable(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "key": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "type": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"key", "name", "type"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2beta1_DashboardAdHocFilterWithLabels(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1836,6 +1944,82 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardElementReference(ref common.Refe } } +func schema_pkg_apis_dashboard_v2beta1_DashboardFetchOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "method": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "body": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "queryParams": { + SchemaProps: spec.SchemaProps{ + Description: "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + "headers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + }, + Required: []string{"method", "url"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2beta1_DashboardFieldColor(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1988,6 +2172,20 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfig(ref common.Reference }, }, }, + "actions": { + SchemaProps: spec.SchemaProps{ + Description: "Define interactive HTTP requests that can be triggered from data visualizations.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAction"), + }, + }, + }, + }, + }, "noValue": { SchemaProps: spec.SchemaProps{ Description: "Alternative to empty string", @@ -2014,7 +2212,7 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfig(ref common.Reference }, }, Dependencies: []string{ - "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldColor", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardThresholdsConfig", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"}, + "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardAction", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardFieldColor", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardThresholdsConfig", "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"}, } } @@ -2389,6 +2587,89 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardGroupByVariableSpec(ref common.R } } +func schema_pkg_apis_dashboard_v2beta1_DashboardInfinityOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "method": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "body": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "queryParams": { + SchemaProps: spec.SchemaProps{ + Description: "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + "datasourceUid": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "headers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + }, + Required: []string{"method", "url", "datasourceUid"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2beta1_DashboardIntervalVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -4389,6 +4670,24 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardTransformationKind(ref common.Re } } +func schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1ActionStyle(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "backgroundColor": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2beta1_DashboardV2beta1AdhocVariableKindDatasource(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi_violation_exceptions.list b/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi_violation_exceptions.list index d516d5c8748..ef7c8aa4a3a 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi_violation_exceptions.list +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi_violation_exceptions.list @@ -1,3 +1,4 @@ +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardAction,Variables API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardAdHocFilterWithLabels,ValueLabels API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardAdHocFilterWithLabels,Values API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardAdhocVariableSpec,BaseFilters @@ -9,11 +10,16 @@ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/ API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardCustomVariableSpec,Options API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardDashboardLink,Tags API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardDatasourceVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFetchOptions,Headers +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFetchOptions,QueryParams +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFieldConfig,Actions API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFieldConfig,Links API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFieldConfig,Mappings API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardFieldConfigSource,Overrides API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardGridLayoutSpec,Items API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardGroupByVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardInfinityOptions,Headers +API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardInfinityOptions,QueryParams API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardIntervalVariableSpec,Options API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardMetadata,Finalizers API rule violation: list_type_missing,github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1,DashboardPanelSpec,Links diff --git a/kinds/dashboard/dashboard_kind.cue b/kinds/dashboard/dashboard_kind.cue index ab4da8db7d9..20571c8211a 100644 --- a/kinds/dashboard/dashboard_kind.cue +++ b/kinds/dashboard/dashboard_kind.cue @@ -298,6 +298,59 @@ lineage: schemas: [{ // - "inControlsMenu" renders the link in bottom part of the dashboard controls dropdown menu #DashboardLinkPlacement: "inControlsMenu" @cuetsy(kind="type") + // Dashboard action type + #ActionType: "fetch" | "infinity" @cuetsy(kind="type") + + // Fetch options + #FetchOptions: { + method: #HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] + } @cuetsy(kind="interface") + + // Infinity options + #InfinityOptions: { + method: #HttpRequestMethod + url: string + body?: string + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: [...[...string]] + headers?: [...[...string]] + datasourceUid: string + } @cuetsy(kind="interface") + + #HttpRequestMethod: "GET" | "PUT" | "POST" | "DELETE" | "PATCH" @cuetsy(kind="type") + + // Action variable type + #ActionVariableType: "string" @cuetsy(kind="type") + + #ActionVariable: { + key: string + name: string + type: #ActionVariableType + } @cuetsy(kind="interface") + + // Dashboard action + #Action: { + type: #ActionType + title: string + fetch?: #FetchOptions + infinity?: #InfinityOptions + confirmation?: string + oneClick?: bool + variables?: [...#ActionVariable] + style?: { + backgroundColor?: string + } + } @cuetsy(kind="interface") + // Dashboard variable type // `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on. // `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only). @@ -727,6 +780,9 @@ lineage: schemas: [{ // The behavior when clicking on a result links?: [...] @grafanamaturity(NeedsExpertReview) + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: [...#Action] @grafanamaturity(NeedsExpertReview) + // Alternative to empty string noValue?: string @grafanamaturity(NeedsExpertReview) diff --git a/packages/grafana-schema/src/index.gen.ts b/packages/grafana-schema/src/index.gen.ts index b608be01349..5646058691b 100644 --- a/packages/grafana-schema/src/index.gen.ts +++ b/packages/grafana-schema/src/index.gen.ts @@ -15,6 +15,13 @@ export type { DashboardLink, DashboardLinkType, DashboardLinkPlacement, + ActionType, + FetchOptions, + InfinityOptions, + HttpRequestMethod, + ActionVariableType, + ActionVariable, + Action, VariableType, FieldColorSeriesByMode, FieldColor, @@ -37,6 +44,9 @@ export { VariableRefresh, VariableSort, defaultDashboardLink, + defaultFetchOptions, + defaultInfinityOptions, + defaultAction, FieldColorModeId, defaultGridPos, ThresholdsMode, diff --git a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts index baf09ea16ce..d158d884aa0 100644 --- a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts +++ b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts @@ -363,6 +363,87 @@ export type DashboardLinkType = ('link' | 'dashboards'); */ export type DashboardLinkPlacement = 'inControlsMenu'; +/** + * Dashboard action type + */ +export type ActionType = ('fetch' | 'infinity'); + +/** + * Fetch options + */ +export interface FetchOptions { + body?: string; + headers?: Array>; + method: HttpRequestMethod; + /** + * These are 2D arrays of strings, each representing a key-value pair + * We are defining this way because we can't generate a go struct that + * that would have exactly two strings in each sub-array + */ + queryParams?: Array>; + url: string; +} + +export const defaultFetchOptions: Partial = { + headers: [], + queryParams: [], +}; + +/** + * Infinity options + */ +export interface InfinityOptions { + body?: string; + datasourceUid: string; + headers?: Array>; + method: HttpRequestMethod; + /** + * These are 2D arrays of strings, each representing a key-value pair + * We are defining them this way because we can't generate a go struct that + * that would have exactly two strings in each sub-array + */ + queryParams?: Array>; + url: string; +} + +export const defaultInfinityOptions: Partial = { + headers: [], + queryParams: [], +}; + +export type HttpRequestMethod = ('GET' | 'PUT' | 'POST' | 'DELETE' | 'PATCH'); + +/** + * Action variable type + */ +export type ActionVariableType = 'string'; + +export interface ActionVariable { + key: string; + name: string; + type: ActionVariableType; +} + +/** + * Dashboard action + */ +export interface Action { + confirmation?: string; + fetch?: FetchOptions; + infinity?: InfinityOptions; + oneClick?: boolean; + style?: { + backgroundColor?: string; + }; + title: string; + type: ActionType; + variables?: Array; +} + +export const defaultAction: Partial = { + variables: [], +}; + /** * Dashboard variable type * `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on. @@ -916,6 +997,10 @@ export const defaultMatcherConfig: Partial = { * Field options allow you to change how the data is displayed in your visualizations. */ export interface FieldConfig { + /** + * Define interactive HTTP requests that can be triggered from data visualizations. + */ + actions?: Array; /** * Panel color configuration */ @@ -1001,6 +1086,7 @@ export interface FieldConfig { } export const defaultFieldConfig: Partial = { + actions: [], links: [], mappings: [], }; diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.spec.gen.ts b/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.spec.gen.ts index d821bff4532..8c6adae3078 100644 --- a/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.spec.gen.ts +++ b/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.spec.gen.ts @@ -318,6 +318,8 @@ export interface FieldConfig { color?: FieldColor; // The behavior when clicking on a result links?: any[]; + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: Action[]; // Alternative to empty string noValue?: string; // custom is specified by the FieldConfig field @@ -505,6 +507,81 @@ export type FieldColorSeriesByMode = "min" | "max" | "last"; export const defaultFieldColorSeriesByMode = (): FieldColorSeriesByMode => ("min"); +export interface Action { + type: ActionType; + title: string; + fetch?: FetchOptions; + infinity?: InfinityOptions; + confirmation?: string; + oneClick?: boolean; + variables?: ActionVariable[]; + style?: { + backgroundColor?: string; + }; +} + +export const defaultAction = (): Action => ({ + type: "fetch", + title: "", +}); + +export type ActionType = "fetch" | "infinity"; + +export const defaultActionType = (): ActionType => ("fetch"); + +export interface FetchOptions { + method: HttpRequestMethod; + url: string; + body?: string; + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: string[][]; + headers?: string[][]; +} + +export const defaultFetchOptions = (): FetchOptions => ({ + method: "GET", + url: "", +}); + +export type HttpRequestMethod = "GET" | "PUT" | "POST" | "DELETE" | "PATCH"; + +export const defaultHttpRequestMethod = (): HttpRequestMethod => ("GET"); + +export interface InfinityOptions { + method: HttpRequestMethod; + url: string; + body?: string; + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: string[][]; + datasourceUid: string; + headers?: string[][]; +} + +export const defaultInfinityOptions = (): InfinityOptions => ({ + method: "GET", + url: "", + datasourceUid: "", +}); + +export interface ActionVariable { + key: string; + name: string; + type: "string"; +} + +export const defaultActionVariable = (): ActionVariable => ({ + key: "", + name: "", + type: ActionVariableType, +}); + +// Action variable type +export const ActionVariableType = "string"; + export interface DynamicConfigValue { id: string; value?: any; diff --git a/packages/grafana-schema/src/schema/dashboard/v2beta1/types.spec.gen.ts b/packages/grafana-schema/src/schema/dashboard/v2beta1/types.spec.gen.ts index 65739dc88ec..e095f7b948b 100644 --- a/packages/grafana-schema/src/schema/dashboard/v2beta1/types.spec.gen.ts +++ b/packages/grafana-schema/src/schema/dashboard/v2beta1/types.spec.gen.ts @@ -317,6 +317,8 @@ export interface FieldConfig { color?: FieldColor; // The behavior when clicking on a result links?: any[]; + // Define interactive HTTP requests that can be triggered from data visualizations. + actions?: Action[]; // Alternative to empty string noValue?: string; // custom is specified by the FieldConfig field @@ -504,6 +506,81 @@ export type FieldColorSeriesByMode = "min" | "max" | "last"; export const defaultFieldColorSeriesByMode = (): FieldColorSeriesByMode => ("min"); +export interface Action { + type: ActionType; + title: string; + fetch?: FetchOptions; + infinity?: InfinityOptions; + confirmation?: string; + oneClick?: boolean; + variables?: ActionVariable[]; + style?: { + backgroundColor?: string; + }; +} + +export const defaultAction = (): Action => ({ + type: "fetch", + title: "", +}); + +export type ActionType = "fetch" | "infinity"; + +export const defaultActionType = (): ActionType => ("fetch"); + +export interface FetchOptions { + method: HttpRequestMethod; + url: string; + body?: string; + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: string[][]; + headers?: string[][]; +} + +export const defaultFetchOptions = (): FetchOptions => ({ + method: "GET", + url: "", +}); + +export type HttpRequestMethod = "GET" | "PUT" | "POST" | "DELETE" | "PATCH"; + +export const defaultHttpRequestMethod = (): HttpRequestMethod => ("GET"); + +export interface InfinityOptions { + method: HttpRequestMethod; + url: string; + body?: string; + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + queryParams?: string[][]; + datasourceUid: string; + headers?: string[][]; +} + +export const defaultInfinityOptions = (): InfinityOptions => ({ + method: "GET", + url: "", + datasourceUid: "", +}); + +export interface ActionVariable { + key: string; + name: string; + type: "string"; +} + +export const defaultActionVariable = (): ActionVariable => ({ + key: "", + name: "", + type: ActionVariableType, +}); + +// Action variable type +export const ActionVariableType = "string"; + export interface DynamicConfigValue { id: string; value?: any; diff --git a/pkg/kinds/dashboard/dashboard_spec_gen.go b/pkg/kinds/dashboard/dashboard_spec_gen.go index e01c43d2229..fa72f781f75 100644 --- a/pkg/kinds/dashboard/dashboard_spec_gen.go +++ b/pkg/kinds/dashboard/dashboard_spec_gen.go @@ -427,6 +427,8 @@ type FieldConfig struct { Color *FieldColor `json:"color,omitempty"` // The behavior when clicking on a result Links []any `json:"links,omitempty"` + // Define interactive HTTP requests that can be triggered from data visualizations. + Actions []Action `json:"actions,omitempty"` // Alternative to empty string NoValue *string `json:"noValue,omitempty"` // custom is specified by the FieldConfig field @@ -654,6 +656,92 @@ const ( FieldColorSeriesByModeLast FieldColorSeriesByMode = "last" ) +// Dashboard action +type Action struct { + Type ActionType `json:"type"` + Title string `json:"title"` + Fetch *FetchOptions `json:"fetch,omitempty"` + Infinity *InfinityOptions `json:"infinity,omitempty"` + Confirmation *string `json:"confirmation,omitempty"` + OneClick *bool `json:"oneClick,omitempty"` + Variables []ActionVariable `json:"variables,omitempty"` + Style *DashboardActionStyle `json:"style,omitempty"` +} + +// NewAction creates a new Action object. +func NewAction() *Action { + return &Action{} +} + +// Dashboard action type +type ActionType string + +const ( + ActionTypeFetch ActionType = "fetch" + ActionTypeInfinity ActionType = "infinity" +) + +// Fetch options +type FetchOptions struct { + Method HttpRequestMethod `json:"method"` + Url string `json:"url"` + Body *string `json:"body,omitempty"` + // These are 2D arrays of strings, each representing a key-value pair + // We are defining this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + QueryParams [][]string `json:"queryParams,omitempty"` + Headers [][]string `json:"headers,omitempty"` +} + +// NewFetchOptions creates a new FetchOptions object. +func NewFetchOptions() *FetchOptions { + return &FetchOptions{} +} + +type HttpRequestMethod string + +const ( + HttpRequestMethodGET HttpRequestMethod = "GET" + HttpRequestMethodPUT HttpRequestMethod = "PUT" + HttpRequestMethodPOST HttpRequestMethod = "POST" + HttpRequestMethodDELETE HttpRequestMethod = "DELETE" + HttpRequestMethodPATCH HttpRequestMethod = "PATCH" +) + +// Infinity options +type InfinityOptions struct { + Method HttpRequestMethod `json:"method"` + Url string `json:"url"` + Body *string `json:"body,omitempty"` + // These are 2D arrays of strings, each representing a key-value pair + // We are defining them this way because we can't generate a go struct that + // that would have exactly two strings in each sub-array + QueryParams [][]string `json:"queryParams,omitempty"` + Headers [][]string `json:"headers,omitempty"` + DatasourceUid string `json:"datasourceUid"` +} + +// NewInfinityOptions creates a new InfinityOptions object. +func NewInfinityOptions() *InfinityOptions { + return &InfinityOptions{} +} + +type ActionVariable struct { + Key string `json:"key"` + Name string `json:"name"` + Type string `json:"type"` +} + +// NewActionVariable creates a new ActionVariable object. +func NewActionVariable() *ActionVariable { + return &ActionVariable{ + Type: ActionVariableType, + } +} + +// Action variable type +const ActionVariableType = "string" + type DynamicConfigValue struct { Id string `json:"id"` Value any `json:"value,omitempty"` @@ -1042,6 +1130,15 @@ func NewDashboardSpecialValueMapOptions() *DashboardSpecialValueMapOptions { } } +type DashboardActionStyle struct { + BackgroundColor *string `json:"backgroundColor,omitempty"` +} + +// NewDashboardActionStyle creates a new DashboardActionStyle object. +func NewDashboardActionStyle() *DashboardActionStyle { + return &DashboardActionStyle{} +} + type PanelRepeatDirection string const ( diff --git a/pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v2alpha1.json b/pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v2alpha1.json index aab8e377285..ddc33887775 100644 --- a/pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v2alpha1.json +++ b/pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v2alpha1.json @@ -1060,6 +1060,71 @@ } } }, + "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardAction": { + "type": "object", + "required": [ + "type", + "title" + ], + "properties": { + "confirmation": { + "type": "string" + }, + "fetch": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardFetchOptions" + }, + "infinity": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardInfinityOptions" + }, + "oneClick": { + "type": "boolean" + }, + "style": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardV2alpha1ActionStyle" + }, + "title": { + "type": "string", + "default": "" + }, + "type": { + "type": "string", + "default": "" + }, + "variables": { + "type": "array", + "items": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardActionVariable" + } + ] + } + } + } + }, + "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardActionVariable": { + "type": "object", + "required": [ + "key", + "name", + "type" + ], + "properties": { + "key": { + "type": "string", + "default": "" + }, + "name": { + "type": "string", + "default": "" + }, + "type": { + "type": "string", + "default": "" + } + } + }, "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardAdHocFilterWithLabels": { "description": "Define the AdHocFilterWithLabels type", "type": "object", @@ -2062,6 +2127,47 @@ } } }, + "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardFetchOptions": { + "type": "object", + "required": [ + "method", + "url" + ], + "properties": { + "body": { + "type": "string" + }, + "headers": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string", + "default": "" + } + } + }, + "method": { + "type": "string", + "default": "" + }, + "queryParams": { + "description": "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string", + "default": "" + } + } + }, + "url": { + "type": "string", + "default": "" + } + } + }, "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardFieldColor": { "description": "Map a field to a color.", "type": "object", @@ -2088,6 +2194,18 @@ "description": "The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. Each column within this structure is called a field. A field can represent a single time series or table column. Field options allow you to change how the data is displayed in your visualizations.", "type": "object", "properties": { + "actions": { + "description": "Define interactive HTTP requests that can be triggered from data visualizations.", + "type": "array", + "items": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardAction" + } + ] + } + }, "color": { "description": "Panel color configuration", "allOf": [ @@ -2427,6 +2545,52 @@ } } }, + "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardInfinityOptions": { + "type": "object", + "required": [ + "method", + "url", + "datasourceUid" + ], + "properties": { + "body": { + "type": "string" + }, + "datasourceUid": { + "type": "string", + "default": "" + }, + "headers": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string", + "default": "" + } + } + }, + "method": { + "type": "string", + "default": "" + }, + "queryParams": { + "description": "These are 2D arrays of strings, each representing a key-value pair We are defining them this way because we can't generate a go struct that that would have exactly two strings in each sub-array", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string", + "default": "" + } + } + }, + "url": { + "type": "string", + "default": "" + } + } + }, "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardIntervalVariableKind": { "description": "Interval variable kind", "type": "object", @@ -3735,6 +3899,14 @@ } } }, + "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardV2alpha1ActionStyle": { + "type": "object", + "properties": { + "backgroundColor": { + "type": "string" + } + } + }, "com.github.grafana.grafana.apps.dashboard.pkg.apis.dashboard.v2alpha1.DashboardV2alpha1FieldConfigSourceOverrides": { "type": "object", "required": [ diff --git a/public/app/features/dashboard-scene/serialization/transformToV2TypesUtils.test.ts b/public/app/features/dashboard-scene/serialization/transformToV2TypesUtils.test.ts index b1633283c97..548be1e0233 100644 --- a/public/app/features/dashboard-scene/serialization/transformToV2TypesUtils.test.ts +++ b/public/app/features/dashboard-scene/serialization/transformToV2TypesUtils.test.ts @@ -21,33 +21,33 @@ describe('transformToV2TypesUtils', () => { expect(transformCursorSynctoEnum(undefined)).toBe(defaultDashboardCursorSync()); }); }); -}); -describe('transformVariableRefreshToEnum', () => { - it('should return the correct enum value for variable refresh', () => { - expect(transformVariableRefreshToEnum(0)).toBe('never'); - expect(transformVariableRefreshToEnum(1)).toBe('onDashboardLoad'); - expect(transformVariableRefreshToEnum(2)).toBe('onTimeRangeChanged'); - expect(transformVariableRefreshToEnum(undefined)).toBe(defaultVariableRefresh()); + describe('transformVariableRefreshToEnum', () => { + it('should return the correct enum value for variable refresh', () => { + expect(transformVariableRefreshToEnum(0)).toBe('never'); + expect(transformVariableRefreshToEnum(1)).toBe('onDashboardLoad'); + expect(transformVariableRefreshToEnum(2)).toBe('onTimeRangeChanged'); + expect(transformVariableRefreshToEnum(undefined)).toBe(defaultVariableRefresh()); + }); }); -}); -describe('transformVariableHideToEnum', () => { - it('should return the correct enum value for variable hide', () => { - expect(transformVariableHideToEnum(0)).toBe('dontHide'); - expect(transformVariableHideToEnum(1)).toBe('hideLabel'); - expect(transformVariableHideToEnum(2)).toBe('hideVariable'); - expect(transformVariableHideToEnum(undefined)).toBe(defaultVariableHide()); + describe('transformVariableHideToEnum', () => { + it('should return the correct enum value for variable hide', () => { + expect(transformVariableHideToEnum(0)).toBe('dontHide'); + expect(transformVariableHideToEnum(1)).toBe('hideLabel'); + expect(transformVariableHideToEnum(2)).toBe('hideVariable'); + expect(transformVariableHideToEnum(undefined)).toBe(defaultVariableHide()); + }); }); -}); -describe('transformSortVariableToEnum', () => { - it('should return the correct enum value for variable sort', () => { - expect(transformSortVariableToEnum(0)).toBe('disabled'); - expect(transformSortVariableToEnum(1)).toBe('alphabeticalAsc'); - expect(transformSortVariableToEnum(2)).toBe('alphabeticalDesc'); - expect(transformSortVariableToEnum(3)).toBe('numericalAsc'); - expect(transformSortVariableToEnum(4)).toBe('numericalDesc'); - expect(transformSortVariableToEnum(undefined)).toBe(defaultVariableSort()); + describe('transformSortVariableToEnum', () => { + it('should return the correct enum value for variable sort', () => { + expect(transformSortVariableToEnum(0)).toBe('disabled'); + expect(transformSortVariableToEnum(1)).toBe('alphabeticalAsc'); + expect(transformSortVariableToEnum(2)).toBe('alphabeticalDesc'); + expect(transformSortVariableToEnum(3)).toBe('numericalAsc'); + expect(transformSortVariableToEnum(4)).toBe('numericalDesc'); + expect(transformSortVariableToEnum(undefined)).toBe(defaultVariableSort()); + }); }); }); From 6afd532635ed33c9ce33d07bac22cc2d209cc1e4 Mon Sep 17 00:00:00 2001 From: Yuri Tseretyan Date: Fri, 12 Sep 2025 13:32:06 -0400 Subject: [PATCH 35/48] Make alerting team a sole owner of alerting tests (#111036) make alerting team sole owner of alerting tests --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 905cfad2951..a052bdbac8c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -187,7 +187,7 @@ /pkg/setting/ @grafana/grafana-backend-services-squad /pkg/tests/ @grafana/grafana-backend-services-squad /pkg/tests/apis/ @grafana/grafana-app-platform-squad -/pkg/tests/apis/alerting @grafana/grafana-app-platform-squad @grafana/alerting-backend +/pkg/tests/apis/alerting @grafana/alerting-backend /pkg/tests/apis/features @grafana/grafana-backend-services-squad /pkg/tests/apis/folder @grafana/grafana-search-and-storage /pkg/tests/apis/iam @grafana/identity-access-team From afc536118d4b17567289393a39394f19df70d217 Mon Sep 17 00:00:00 2001 From: "grafana-delivery-bot[bot]" <132647405+grafana-delivery-bot[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 17:54:11 +0000 Subject: [PATCH 36/48] Release: Bump version to 12.3.0-pre (#110974) * update bump-version * Add id-token: write * update generate-token step * pull-requests -> pull_requests * clone with token and set right name * bump version 12.3.0-pre --------- Co-authored-by: Kevin Minehart <5140827+kminehart@users.noreply.github.com> Co-authored-by: grafana-delivery-bot[bot] --- .../grafana-extensionstest-app/package.json | 2 +- .../grafana-test-datasource/package.json | 2 +- lerna.json | 2 +- package.json | 2 +- packages/grafana-alerting/package.json | 4 +- packages/grafana-data/package.json | 6 +- packages/grafana-e2e-selectors/package.json | 2 +- packages/grafana-eslint-rules/package.json | 2 +- packages/grafana-flamegraph/package.json | 6 +- packages/grafana-i18n/package.json | 2 +- .../grafana-o11y-ds-frontend/package.json | 12 +- packages/grafana-plugin-configs/package.json | 2 +- packages/grafana-prometheus/package.json | 14 +- packages/grafana-runtime/package.json | 10 +- packages/grafana-schema/package.json | 2 +- .../x/AnnotationsListPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/BarChartPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/BarGaugePanelCfg_types.gen.ts | 2 +- .../x/CandlestickPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/CanvasPanelCfg_types.gen.ts | 2 +- .../x/CloudWatchDataQuery_types.gen.ts | 2 +- .../x/DashboardListPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/DatagridPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/DebugPanelCfg_types.gen.ts | 2 +- .../x/ElasticsearchDataQuery_types.gen.ts | 2 +- .../panelcfg/x/GaugePanelCfg_types.gen.ts | 2 +- .../panelcfg/x/GeomapPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/HeatmapPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/HistogramPanelCfg_types.gen.ts | 2 +- .../logs/panelcfg/x/LogsPanelCfg_types.gen.ts | 2 +- .../news/panelcfg/x/NewsPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/NodeGraphPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/PieChartPanelCfg_types.gen.ts | 2 +- .../stat/panelcfg/x/StatPanelCfg_types.gen.ts | 2 +- .../x/StateTimelinePanelCfg_types.gen.ts | 2 +- .../x/StatusHistoryPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/TablePanelCfg_types.gen.ts | 2 +- .../text/panelcfg/x/TextPanelCfg_types.gen.ts | 2 +- .../x/TimeSeriesPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/TrendPanelCfg_types.gen.ts | 2 +- .../panelcfg/x/XYChartPanelCfg_types.gen.ts | 2 +- packages/grafana-sql/package.json | 12 +- packages/grafana-test-utils/package.json | 2 +- packages/grafana-ui/package.json | 10 +- .../datasource/azuremonitor/package.json | 16 +- .../datasource/cloud-monitoring/package.json | 14 +- .../package.json | 14 +- .../grafana-pyroscope-datasource/package.json | 12 +- .../grafana-testdata-datasource/package.json | 14 +- .../plugins/datasource/graphite/package.json | 14 +- .../plugins/datasource/jaeger/package.json | 2 +- .../app/plugins/datasource/loki/package.json | 14 +- .../app/plugins/datasource/mssql/package.json | 16 +- .../app/plugins/datasource/mysql/package.json | 14 +- .../app/plugins/datasource/parca/package.json | 12 +- .../app/plugins/datasource/tempo/package.json | 4 +- .../plugins/datasource/zipkin/package.json | 2 +- yarn.lock | 196 +++++++++--------- 58 files changed, 245 insertions(+), 245 deletions(-) diff --git a/e2e-playwright/test-plugins/grafana-extensionstest-app/package.json b/e2e-playwright/test-plugins/grafana-extensionstest-app/package.json index 89d6c90be5d..e1960c9515e 100644 --- a/e2e-playwright/test-plugins/grafana-extensionstest-app/package.json +++ b/e2e-playwright/test-plugins/grafana-extensionstest-app/package.json @@ -1,6 +1,6 @@ { "name": "@test-plugins/extensions-test-app", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "private": true, "scripts": { "build": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -c ./webpack.config.ts --env production", diff --git a/e2e-playwright/test-plugins/grafana-test-datasource/package.json b/e2e-playwright/test-plugins/grafana-test-datasource/package.json index 7ed88373c45..71b032b1d88 100644 --- a/e2e-playwright/test-plugins/grafana-test-datasource/package.json +++ b/e2e-playwright/test-plugins/grafana-test-datasource/package.json @@ -1,6 +1,6 @@ { "name": "@test-plugins/grafana-e2etest-datasource", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "private": true, "scripts": { "build": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -c ./webpack.config.ts --env production", diff --git a/lerna.json b/lerna.json index fe2cdbf0402..70b729cb019 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "npmClient": "yarn", - "version": "12.2.0-pre" + "version": "12.3.0-pre" } diff --git a/package.json b/package.json index 20bbe6043fa..747a6a6bce3 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "license": "AGPL-3.0-only", "private": true, "name": "grafana", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "repository": "github:grafana/grafana", "scripts": { "predev": "./scripts/check-frontend-dev.sh", diff --git a/packages/grafana-alerting/package.json b/packages/grafana-alerting/package.json index cf497d215c7..f162791a6bf 100644 --- a/packages/grafana-alerting/package.json +++ b/packages/grafana-alerting/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/alerting", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana Alerting Library – Build vertical integrations on top of the industry-leading alerting solution", "keywords": [ "typescript", @@ -93,7 +93,7 @@ "dependencies": { "@emotion/css": "11.13.5", "@faker-js/faker": "^9.8.0", - "@grafana/i18n": "12.2.0-pre", + "@grafana/i18n": "12.3.0-pre", "fishery": "^2.3.1", "lodash": "^4.17.21" } diff --git a/packages/grafana-data/package.json b/packages/grafana-data/package.json index 9b0733b3441..bb6a57974c8 100644 --- a/packages/grafana-data/package.json +++ b/packages/grafana-data/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/data", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana Data Library", "keywords": [ "typescript" @@ -56,8 +56,8 @@ }, "dependencies": { "@braintree/sanitize-url": "7.0.1", - "@grafana/i18n": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", + "@grafana/i18n": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", "@leeoniya/ufuzzy": "1.0.18", "@types/d3-interpolate": "^3.0.0", "@types/string-hash": "1.1.3", diff --git a/packages/grafana-e2e-selectors/package.json b/packages/grafana-e2e-selectors/package.json index b5bf9b4b27c..1b6dde9a254 100644 --- a/packages/grafana-e2e-selectors/package.json +++ b/packages/grafana-e2e-selectors/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/e2e-selectors", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana End-to-End Test Selectors Library", "keywords": [ "cli", diff --git a/packages/grafana-eslint-rules/package.json b/packages/grafana-eslint-rules/package.json index 71203b6d524..f182cd0281b 100644 --- a/packages/grafana-eslint-rules/package.json +++ b/packages/grafana-eslint-rules/package.json @@ -1,7 +1,7 @@ { "name": "@grafana/eslint-plugin", "description": "ESLint rules for use within the Grafana repo. Not suitable (or supported) for external use.", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "main": "./index.cjs", "author": "Grafana Labs", "license": "Apache-2.0", diff --git a/packages/grafana-flamegraph/package.json b/packages/grafana-flamegraph/package.json index 3313be6f7f0..5d9087e4516 100644 --- a/packages/grafana-flamegraph/package.json +++ b/packages/grafana-flamegraph/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/flamegraph", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana flamegraph visualization component", "keywords": [ "grafana", @@ -44,8 +44,8 @@ ], "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "@leeoniya/ufuzzy": "1.0.18", "d3": "^7.8.5", "lodash": "4.17.21", diff --git a/packages/grafana-i18n/package.json b/packages/grafana-i18n/package.json index 12680665aea..365211e2faa 100644 --- a/packages/grafana-i18n/package.json +++ b/packages/grafana-i18n/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/i18n", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana Internationalization Library", "keywords": [ "grafana", diff --git a/packages/grafana-o11y-ds-frontend/package.json b/packages/grafana-o11y-ds-frontend/package.json index b252f5c9246..5694659ab70 100644 --- a/packages/grafana-o11y-ds-frontend/package.json +++ b/packages/grafana-o11y-ds-frontend/package.json @@ -3,7 +3,7 @@ "license": "AGPL-3.0-only", "name": "@grafana/o11y-ds-frontend", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Library to manage traces in Grafana.", "sideEffects": false, "repository": { @@ -18,12 +18,12 @@ }, "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", - "@grafana/e2e-selectors": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "react-select": "5.10.2", "react-use": "17.6.0", "rxjs": "7.8.2", diff --git a/packages/grafana-plugin-configs/package.json b/packages/grafana-plugin-configs/package.json index aebe52115bc..d016c3b8504 100644 --- a/packages/grafana-plugin-configs/package.json +++ b/packages/grafana-plugin-configs/package.json @@ -2,7 +2,7 @@ "name": "@grafana/plugin-configs", "description": "Shared dependencies and files for core plugins", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "tslib": "2.8.1" }, diff --git a/packages/grafana-prometheus/package.json b/packages/grafana-prometheus/package.json index 4fd2566ce4e..be492d4c455 100644 --- a/packages/grafana-prometheus/package.json +++ b/packages/grafana-prometheus/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "AGPL-3.0-only", "name": "@grafana/prometheus", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana Prometheus Library", "keywords": [ "typescript", @@ -41,13 +41,13 @@ "dependencies": { "@emotion/css": "11.13.5", "@floating-ui/react": "0.27.16", - "@grafana/data": "12.2.0-pre", - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/i18n": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/i18n": "12.3.0-pre", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "@hello-pangea/dnd": "18.0.1", "@leeoniya/ufuzzy": "1.0.18", "@lezer/common": "1.2.3", diff --git a/packages/grafana-runtime/package.json b/packages/grafana-runtime/package.json index 368ce72381f..c4e32ce6340 100644 --- a/packages/grafana-runtime/package.json +++ b/packages/grafana-runtime/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/runtime", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana Runtime Library", "keywords": [ "grafana", @@ -53,11 +53,11 @@ "postpack": "mv package.json.bak package.json && rimraf ./unstable" }, "dependencies": { - "@grafana/data": "12.2.0-pre", - "@grafana/e2e-selectors": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", "@grafana/faro-web-sdk": "^1.13.2", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "@types/systemjs": "6.15.3", "history": "4.10.1", "lodash": "4.17.21", diff --git a/packages/grafana-schema/package.json b/packages/grafana-schema/package.json index 159111d986b..773a4a663d2 100644 --- a/packages/grafana-schema/package.json +++ b/packages/grafana-schema/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/schema", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana Schema Library", "keywords": [ "typescript" diff --git a/packages/grafana-schema/src/raw/composable/annotationslist/panelcfg/x/AnnotationsListPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/annotationslist/panelcfg/x/AnnotationsListPanelCfg_types.gen.ts index 63bb4339949..c9d2e73432e 100644 --- a/packages/grafana-schema/src/raw/composable/annotationslist/panelcfg/x/AnnotationsListPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/annotationslist/panelcfg/x/AnnotationsListPanelCfg_types.gen.ts @@ -8,7 +8,7 @@ // // Run 'make gen-cue' from repository root to regenerate. -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options { limit: number; diff --git a/packages/grafana-schema/src/raw/composable/barchart/panelcfg/x/BarChartPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/barchart/panelcfg/x/BarChartPanelCfg_types.gen.ts index 59924a010ae..275d5d7c921 100644 --- a/packages/grafana-schema/src/raw/composable/barchart/panelcfg/x/BarChartPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/barchart/panelcfg/x/BarChartPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip, common.OptionsWithTextFormatting { /** diff --git a/packages/grafana-schema/src/raw/composable/bargauge/panelcfg/x/BarGaugePanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/bargauge/panelcfg/x/BarGaugePanelCfg_types.gen.ts index c086da202b8..dcf792aadbd 100644 --- a/packages/grafana-schema/src/raw/composable/bargauge/panelcfg/x/BarGaugePanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/bargauge/panelcfg/x/BarGaugePanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options extends common.OptionsWithLegend, common.SingleStatBaseOptions { displayMode: common.BarGaugeDisplayMode; diff --git a/packages/grafana-schema/src/raw/composable/candlestick/panelcfg/x/CandlestickPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/candlestick/panelcfg/x/CandlestickPanelCfg_types.gen.ts index ea817787d65..ab38df01ee6 100644 --- a/packages/grafana-schema/src/raw/composable/candlestick/panelcfg/x/CandlestickPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/candlestick/panelcfg/x/CandlestickPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export enum VizDisplayMode { Candles = 'candles', diff --git a/packages/grafana-schema/src/raw/composable/canvas/panelcfg/x/CanvasPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/canvas/panelcfg/x/CanvasPanelCfg_types.gen.ts index 04fec030dfa..13939c556d6 100644 --- a/packages/grafana-schema/src/raw/composable/canvas/panelcfg/x/CanvasPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/canvas/panelcfg/x/CanvasPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as ui from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export enum HorizontalConstraint { Center = 'center', diff --git a/packages/grafana-schema/src/raw/composable/cloudwatch/dataquery/x/CloudWatchDataQuery_types.gen.ts b/packages/grafana-schema/src/raw/composable/cloudwatch/dataquery/x/CloudWatchDataQuery_types.gen.ts index f0e4394451d..2334d1d1efd 100644 --- a/packages/grafana-schema/src/raw/composable/cloudwatch/dataquery/x/CloudWatchDataQuery_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/cloudwatch/dataquery/x/CloudWatchDataQuery_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface MetricStat { /** diff --git a/packages/grafana-schema/src/raw/composable/dashboardlist/panelcfg/x/DashboardListPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/dashboardlist/panelcfg/x/DashboardListPanelCfg_types.gen.ts index 1348c30dbad..a1ec65bf148 100644 --- a/packages/grafana-schema/src/raw/composable/dashboardlist/panelcfg/x/DashboardListPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/dashboardlist/panelcfg/x/DashboardListPanelCfg_types.gen.ts @@ -8,7 +8,7 @@ // // Run 'make gen-cue' from repository root to regenerate. -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options { /** diff --git a/packages/grafana-schema/src/raw/composable/datagrid/panelcfg/x/DatagridPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/datagrid/panelcfg/x/DatagridPanelCfg_types.gen.ts index d8db9ef7edf..65ef7e9883d 100644 --- a/packages/grafana-schema/src/raw/composable/datagrid/panelcfg/x/DatagridPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/datagrid/panelcfg/x/DatagridPanelCfg_types.gen.ts @@ -8,7 +8,7 @@ // // Run 'make gen-cue' from repository root to regenerate. -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options { selectedSeries: number; diff --git a/packages/grafana-schema/src/raw/composable/debug/panelcfg/x/DebugPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/debug/panelcfg/x/DebugPanelCfg_types.gen.ts index 811836dff43..443add70b78 100644 --- a/packages/grafana-schema/src/raw/composable/debug/panelcfg/x/DebugPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/debug/panelcfg/x/DebugPanelCfg_types.gen.ts @@ -8,7 +8,7 @@ // // Run 'make gen-cue' from repository root to regenerate. -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export type UpdateConfig = { render: boolean, diff --git a/packages/grafana-schema/src/raw/composable/elasticsearch/dataquery/x/ElasticsearchDataQuery_types.gen.ts b/packages/grafana-schema/src/raw/composable/elasticsearch/dataquery/x/ElasticsearchDataQuery_types.gen.ts index dfb50c2c981..d63d368d534 100644 --- a/packages/grafana-schema/src/raw/composable/elasticsearch/dataquery/x/ElasticsearchDataQuery_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/elasticsearch/dataquery/x/ElasticsearchDataQuery_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export type BucketAggregation = (DateHistogram | Histogram | Terms | Filters | GeoHashGrid | Nested); diff --git a/packages/grafana-schema/src/raw/composable/gauge/panelcfg/x/GaugePanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/gauge/panelcfg/x/GaugePanelCfg_types.gen.ts index 36aa14da169..ac1fd6808c2 100644 --- a/packages/grafana-schema/src/raw/composable/gauge/panelcfg/x/GaugePanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/gauge/panelcfg/x/GaugePanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options extends common.SingleStatBaseOptions { minVizHeight: number; diff --git a/packages/grafana-schema/src/raw/composable/geomap/panelcfg/x/GeomapPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/geomap/panelcfg/x/GeomapPanelCfg_types.gen.ts index fa1e3eaf299..4819a4cfc1b 100644 --- a/packages/grafana-schema/src/raw/composable/geomap/panelcfg/x/GeomapPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/geomap/panelcfg/x/GeomapPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as ui from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options { basemap: ui.MapLayerOptions; diff --git a/packages/grafana-schema/src/raw/composable/heatmap/panelcfg/x/HeatmapPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/heatmap/panelcfg/x/HeatmapPanelCfg_types.gen.ts index b0a2a2b5233..d905b1bd2ea 100644 --- a/packages/grafana-schema/src/raw/composable/heatmap/panelcfg/x/HeatmapPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/heatmap/panelcfg/x/HeatmapPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as ui from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; /** * Controls the color mode of the heatmap diff --git a/packages/grafana-schema/src/raw/composable/histogram/panelcfg/x/HistogramPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/histogram/panelcfg/x/HistogramPanelCfg_types.gen.ts index 59b82823d78..2d5705e31e5 100644 --- a/packages/grafana-schema/src/raw/composable/histogram/panelcfg/x/HistogramPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/histogram/panelcfg/x/HistogramPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip { /** diff --git a/packages/grafana-schema/src/raw/composable/logs/panelcfg/x/LogsPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/logs/panelcfg/x/LogsPanelCfg_types.gen.ts index 5a048b59af0..4fc8ccf355a 100644 --- a/packages/grafana-schema/src/raw/composable/logs/panelcfg/x/LogsPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/logs/panelcfg/x/LogsPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options { controlsStorageKey?: string; diff --git a/packages/grafana-schema/src/raw/composable/news/panelcfg/x/NewsPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/news/panelcfg/x/NewsPanelCfg_types.gen.ts index eb0b74331d4..5f46545f820 100644 --- a/packages/grafana-schema/src/raw/composable/news/panelcfg/x/NewsPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/news/panelcfg/x/NewsPanelCfg_types.gen.ts @@ -8,7 +8,7 @@ // // Run 'make gen-cue' from repository root to regenerate. -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options { /** diff --git a/packages/grafana-schema/src/raw/composable/nodegraph/panelcfg/x/NodeGraphPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/nodegraph/panelcfg/x/NodeGraphPanelCfg_types.gen.ts index a5e4657464a..17fe57fcc44 100644 --- a/packages/grafana-schema/src/raw/composable/nodegraph/panelcfg/x/NodeGraphPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/nodegraph/panelcfg/x/NodeGraphPanelCfg_types.gen.ts @@ -8,7 +8,7 @@ // // Run 'make gen-cue' from repository root to regenerate. -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface ArcOption { /** diff --git a/packages/grafana-schema/src/raw/composable/piechart/panelcfg/x/PieChartPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/piechart/panelcfg/x/PieChartPanelCfg_types.gen.ts index 913fa45c9ac..067c6d7d146 100644 --- a/packages/grafana-schema/src/raw/composable/piechart/panelcfg/x/PieChartPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/piechart/panelcfg/x/PieChartPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; /** * Select the pie chart display style. diff --git a/packages/grafana-schema/src/raw/composable/stat/panelcfg/x/StatPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/stat/panelcfg/x/StatPanelCfg_types.gen.ts index 8296f089a14..0fb48020d23 100644 --- a/packages/grafana-schema/src/raw/composable/stat/panelcfg/x/StatPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/stat/panelcfg/x/StatPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options extends common.SingleStatBaseOptions { colorMode: common.BigValueColorMode; diff --git a/packages/grafana-schema/src/raw/composable/statetimeline/panelcfg/x/StateTimelinePanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/statetimeline/panelcfg/x/StateTimelinePanelCfg_types.gen.ts index 58b487eb4d3..b8220d24d3a 100644 --- a/packages/grafana-schema/src/raw/composable/statetimeline/panelcfg/x/StateTimelinePanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/statetimeline/panelcfg/x/StateTimelinePanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as ui from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options extends ui.OptionsWithLegend, ui.OptionsWithTooltip, ui.OptionsWithTimezones { /** diff --git a/packages/grafana-schema/src/raw/composable/statushistory/panelcfg/x/StatusHistoryPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/statushistory/panelcfg/x/StatusHistoryPanelCfg_types.gen.ts index 0ddf8a30c7a..030a310ff8b 100644 --- a/packages/grafana-schema/src/raw/composable/statushistory/panelcfg/x/StatusHistoryPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/statushistory/panelcfg/x/StatusHistoryPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as ui from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options extends ui.OptionsWithLegend, ui.OptionsWithTooltip, ui.OptionsWithTimezones { /** diff --git a/packages/grafana-schema/src/raw/composable/table/panelcfg/x/TablePanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/table/panelcfg/x/TablePanelCfg_types.gen.ts index aebc8fd7be4..3964c70f630 100644 --- a/packages/grafana-schema/src/raw/composable/table/panelcfg/x/TablePanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/table/panelcfg/x/TablePanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as ui from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options { /** diff --git a/packages/grafana-schema/src/raw/composable/text/panelcfg/x/TextPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/text/panelcfg/x/TextPanelCfg_types.gen.ts index 4fbda90032b..39053ebb9af 100644 --- a/packages/grafana-schema/src/raw/composable/text/panelcfg/x/TextPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/text/panelcfg/x/TextPanelCfg_types.gen.ts @@ -8,7 +8,7 @@ // // Run 'make gen-cue' from repository root to regenerate. -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export enum TextMode { Code = 'code', diff --git a/packages/grafana-schema/src/raw/composable/timeseries/panelcfg/x/TimeSeriesPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/timeseries/panelcfg/x/TimeSeriesPanelCfg_types.gen.ts index 30349a9ff9c..538860716da 100644 --- a/packages/grafana-schema/src/raw/composable/timeseries/panelcfg/x/TimeSeriesPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/timeseries/panelcfg/x/TimeSeriesPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export interface Options extends common.OptionsWithTimezones { legend: common.VizLegendOptions; diff --git a/packages/grafana-schema/src/raw/composable/trend/panelcfg/x/TrendPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/trend/panelcfg/x/TrendPanelCfg_types.gen.ts index aa3b48c20ab..7ec6ddd5686 100644 --- a/packages/grafana-schema/src/raw/composable/trend/panelcfg/x/TrendPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/trend/panelcfg/x/TrendPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; /** * Identical to timeseries... except it does not have timezone settings diff --git a/packages/grafana-schema/src/raw/composable/xychart/panelcfg/x/XYChartPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/xychart/panelcfg/x/XYChartPanelCfg_types.gen.ts index 13516a37619..450721304fe 100644 --- a/packages/grafana-schema/src/raw/composable/xychart/panelcfg/x/XYChartPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/xychart/panelcfg/x/XYChartPanelCfg_types.gen.ts @@ -10,7 +10,7 @@ import * as common from '@grafana/schema'; -export const pluginVersion = "12.2.0-pre"; +export const pluginVersion = "12.3.0-pre"; export enum PointShape { Circle = 'circle', diff --git a/packages/grafana-sql/package.json b/packages/grafana-sql/package.json index d15ad0a5df6..a0206458ad3 100644 --- a/packages/grafana-sql/package.json +++ b/packages/grafana-sql/package.json @@ -3,7 +3,7 @@ "license": "AGPL-3.0-only", "private": true, "name": "@grafana/sql", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "repository": { "type": "git", "url": "http://github.com/grafana/grafana.git", @@ -16,12 +16,12 @@ }, "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/i18n": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/i18n": "12.3.0-pre", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "@react-awesome-query-builder/ui": "6.6.15", "immutable": "5.1.3", "lodash": "4.17.21", diff --git a/packages/grafana-test-utils/package.json b/packages/grafana-test-utils/package.json index 842cc9d6517..60e375d77cb 100644 --- a/packages/grafana-test-utils/package.json +++ b/packages/grafana-test-utils/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/test-utils", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "private": true, "description": "Grafana test utils & Mock API", "keywords": [ diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index fb1a899ca6e..25f637bbff7 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -2,7 +2,7 @@ "author": "Grafana Labs", "license": "Apache-2.0", "name": "@grafana/ui", - "version": "12.2.0-pre", + "version": "12.3.0-pre", "description": "Grafana Components Library", "keywords": [ "grafana", @@ -67,11 +67,11 @@ "@emotion/react": "11.14.0", "@emotion/serialize": "1.3.3", "@floating-ui/react": "0.27.16", - "@grafana/data": "12.2.0-pre", - "@grafana/e2e-selectors": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", "@grafana/faro-web-sdk": "^1.13.2", - "@grafana/i18n": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", + "@grafana/i18n": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", "@hello-pangea/dnd": "18.0.1", "@monaco-editor/react": "4.7.0", "@popperjs/core": "2.11.8", diff --git a/public/app/plugins/datasource/azuremonitor/package.json b/public/app/plugins/datasource/azuremonitor/package.json index e74bbab3853..a3d172bdfee 100644 --- a/public/app/plugins/datasource/azuremonitor/package.json +++ b/public/app/plugins/datasource/azuremonitor/package.json @@ -2,15 +2,15 @@ "name": "@grafana-plugins/grafana-azure-monitor-datasource", "description": "Grafana data source for Azure Monitor", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", - "@grafana/i18n": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/i18n": "12.3.0-pre", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "@kusto/monaco-kusto": "^10.0.0", "fast-deep-equal": "^3.1.3", "i18next": "^25.0.0", @@ -26,8 +26,8 @@ "tslib": "2.8.1" }, "devDependencies": { - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.6.4", "@testing-library/react": "16.3.0", diff --git a/public/app/plugins/datasource/cloud-monitoring/package.json b/public/app/plugins/datasource/cloud-monitoring/package.json index 080e3faab65..34eab1a19fb 100644 --- a/public/app/plugins/datasource/cloud-monitoring/package.json +++ b/public/app/plugins/datasource/cloud-monitoring/package.json @@ -2,15 +2,15 @@ "name": "@grafana-plugins/stackdriver", "description": "Grafana data source for Google Cloud Monitoring", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", "@grafana/google-sdk": "0.3.4", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "debounce-promise": "3.1.2", "fast-deep-equal": "^3.1.3", "i18next": "^25.0.0", @@ -26,8 +26,8 @@ "tslib": "2.8.1" }, "devDependencies": { - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.6.4", "@testing-library/react": "16.3.0", diff --git a/public/app/plugins/datasource/grafana-postgresql-datasource/package.json b/public/app/plugins/datasource/grafana-postgresql-datasource/package.json index 7994c090a5e..66dff7a32ce 100644 --- a/public/app/plugins/datasource/grafana-postgresql-datasource/package.json +++ b/public/app/plugins/datasource/grafana-postgresql-datasource/package.json @@ -2,22 +2,22 @@ "name": "@grafana-plugins/grafana-postgresql-datasource", "description": "PostgreSQL data source plugin", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/sql": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/sql": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "lodash": "4.17.21", "react": "18.3.1", "rxjs": "7.8.2", "tslib": "2.8.1" }, "devDependencies": { - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/react": "16.3.0", "@testing-library/user-event": "14.6.1", diff --git a/public/app/plugins/datasource/grafana-pyroscope-datasource/package.json b/public/app/plugins/datasource/grafana-pyroscope-datasource/package.json index 6ddf061952d..44e8655d367 100644 --- a/public/app/plugins/datasource/grafana-pyroscope-datasource/package.json +++ b/public/app/plugins/datasource/grafana-pyroscope-datasource/package.json @@ -2,13 +2,13 @@ "name": "@grafana-plugins/grafana-pyroscope-datasource", "description": "Continuous profiling for analysis of CPU and memory usage, down to the line number and throughout time. Saving infrastructure cost, improving performance, and increasing reliability.", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "fast-deep-equal": "^3.1.3", "lodash": "4.17.21", "monaco-editor": "0.34.1", @@ -20,7 +20,7 @@ "tslib": "2.8.1" }, "devDependencies": { - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.6.4", "@testing-library/react": "16.3.0", diff --git a/public/app/plugins/datasource/grafana-testdata-datasource/package.json b/public/app/plugins/datasource/grafana-testdata-datasource/package.json index 544457c4a16..bd5077f4294 100644 --- a/public/app/plugins/datasource/grafana-testdata-datasource/package.json +++ b/public/app/plugins/datasource/grafana-testdata-datasource/package.json @@ -2,13 +2,13 @@ "name": "@grafana-plugins/grafana-testdata-datasource", "description": "Generates test data in different forms", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "d3-random": "^3.0.1", "lodash": "4.17.21", "micro-memoize": "^4.1.2", @@ -21,8 +21,8 @@ "uuid": "11.1.0" }, "devDependencies": { - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.6.4", "@testing-library/react": "16.3.0", diff --git a/public/app/plugins/datasource/graphite/package.json b/public/app/plugins/datasource/graphite/package.json index ca3d33b93d9..2b7e0ec4eda 100644 --- a/public/app/plugins/datasource/graphite/package.json +++ b/public/app/plugins/datasource/graphite/package.json @@ -2,14 +2,14 @@ "name": "@grafana-plugins/graphite", "description": "Graphite data source plugin for Grafana", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "@reduxjs/toolkit": "2.8.2", "lodash": "4.17.21", "moment": "2.30.1", @@ -23,8 +23,8 @@ "uuid": "11.1.0" }, "devDependencies": { - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.6.4", "@testing-library/react": "16.3.0", diff --git a/public/app/plugins/datasource/jaeger/package.json b/public/app/plugins/datasource/jaeger/package.json index deccbf6277b..cee33f17a4d 100644 --- a/public/app/plugins/datasource/jaeger/package.json +++ b/public/app/plugins/datasource/jaeger/package.json @@ -2,7 +2,7 @@ "name": "@grafana-plugins/jaeger", "description": "Jaeger plugin for Grafana", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", "@grafana/data": "workspace:*", diff --git a/public/app/plugins/datasource/loki/package.json b/public/app/plugins/datasource/loki/package.json index b98404726cd..abdc101521d 100644 --- a/public/app/plugins/datasource/loki/package.json +++ b/public/app/plugins/datasource/loki/package.json @@ -2,16 +2,16 @@ "name": "@grafana-plugins/loki", "description": "Loki data source plugin for Grafana", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", "@grafana/lezer-logql": "0.2.8", "@grafana/llm": "0.22.1", "@grafana/monaco-logql": "^0.0.8", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "d3-random": "^3.0.1", "lodash": "4.17.21", "micro-memoize": "^4.1.2", @@ -24,8 +24,8 @@ "uuid": "11.1.0" }, "devDependencies": { - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.6.4", "@testing-library/react": "16.3.0", diff --git a/public/app/plugins/datasource/mssql/package.json b/public/app/plugins/datasource/mssql/package.json index a818c7e39ec..4ff7632191b 100644 --- a/public/app/plugins/datasource/mssql/package.json +++ b/public/app/plugins/datasource/mssql/package.json @@ -2,23 +2,23 @@ "name": "@grafana-plugins/mssql", "description": "MSSQL data source plugin", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", - "@grafana/i18n": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/i18n": "12.3.0-pre", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/sql": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/sql": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "lodash": "4.17.21", "react": "18.3.1", "rxjs": "7.8.2", "tslib": "2.8.1" }, "devDependencies": { - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/react": "16.3.0", "@testing-library/user-event": "14.6.1", diff --git a/public/app/plugins/datasource/mysql/package.json b/public/app/plugins/datasource/mysql/package.json index a7d528a2856..ba0622abbbe 100644 --- a/public/app/plugins/datasource/mysql/package.json +++ b/public/app/plugins/datasource/mysql/package.json @@ -2,22 +2,22 @@ "name": "@grafana-plugins/mysql", "description": "MySQL data source plugin", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", "@grafana/plugin-ui": "^0.10.10", - "@grafana/runtime": "12.2.0-pre", - "@grafana/sql": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/sql": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "lodash": "4.17.21", "react": "18.3.1", "rxjs": "7.8.2", "tslib": "2.8.1" }, "devDependencies": { - "@grafana/e2e-selectors": "12.2.0-pre", - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/e2e-selectors": "12.3.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/react": "16.3.0", "@testing-library/user-event": "14.6.1", diff --git a/public/app/plugins/datasource/parca/package.json b/public/app/plugins/datasource/parca/package.json index 3b08680a41a..2adf3dd538f 100644 --- a/public/app/plugins/datasource/parca/package.json +++ b/public/app/plugins/datasource/parca/package.json @@ -2,13 +2,13 @@ "name": "@grafana-plugins/parca", "description": "Continuous profiling for analysis of CPU and memory usage, down to the line number and throughout time. Saving infrastructure cost, improving performance, and increasing reliability.", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", - "@grafana/data": "12.2.0-pre", - "@grafana/runtime": "12.2.0-pre", - "@grafana/schema": "12.2.0-pre", - "@grafana/ui": "12.2.0-pre", + "@grafana/data": "12.3.0-pre", + "@grafana/runtime": "12.3.0-pre", + "@grafana/schema": "12.3.0-pre", + "@grafana/ui": "12.3.0-pre", "lodash": "4.17.21", "monaco-editor": "0.34.1", "react": "18.3.1", @@ -18,7 +18,7 @@ "tslib": "2.8.1" }, "devDependencies": { - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/react": "16.3.0", "@testing-library/user-event": "14.6.1", diff --git a/public/app/plugins/datasource/tempo/package.json b/public/app/plugins/datasource/tempo/package.json index f157bd5254d..fac7933eb79 100644 --- a/public/app/plugins/datasource/tempo/package.json +++ b/public/app/plugins/datasource/tempo/package.json @@ -2,7 +2,7 @@ "name": "@grafana-plugins/tempo", "description": "Grafana plugin for the Tempo data source.", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", "@grafana/data": "workspace:*", @@ -38,7 +38,7 @@ "uuid": "11.1.0" }, "devDependencies": { - "@grafana/plugin-configs": "12.2.0-pre", + "@grafana/plugin-configs": "12.3.0-pre", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.6.4", "@testing-library/react": "16.3.0", diff --git a/public/app/plugins/datasource/zipkin/package.json b/public/app/plugins/datasource/zipkin/package.json index 68e76e39fce..1b368d16eaf 100644 --- a/public/app/plugins/datasource/zipkin/package.json +++ b/public/app/plugins/datasource/zipkin/package.json @@ -2,7 +2,7 @@ "name": "@grafana-plugins/zipkin", "description": "Zipkin plugin for Grafana", "private": true, - "version": "12.2.0-pre", + "version": "12.3.0-pre", "dependencies": { "@emotion/css": "11.13.5", "@grafana/data": "workspace:*", diff --git a/yarn.lock b/yarn.lock index 5759752061e..91c46d31c3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2426,14 +2426,14 @@ __metadata: resolution: "@grafana-plugins/grafana-azure-monitor-datasource@workspace:public/app/plugins/datasource/azuremonitor" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" - "@grafana/i18n": "npm:12.2.0-pre" - "@grafana/plugin-configs": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" + "@grafana/i18n": "npm:12.3.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@kusto/monaco-kusto": "npm:^10.0.0" "@testing-library/dom": "npm:10.4.1" "@testing-library/jest-dom": "npm:6.6.4" @@ -2473,13 +2473,13 @@ __metadata: resolution: "@grafana-plugins/grafana-postgresql-datasource@workspace:public/app/plugins/datasource/grafana-postgresql-datasource" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" - "@grafana/plugin-configs": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/sql": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/sql": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/react": "npm:16.3.0" "@testing-library/user-event": "npm:14.6.1" @@ -2505,11 +2505,11 @@ __metadata: resolution: "@grafana-plugins/grafana-pyroscope-datasource@workspace:public/app/plugins/datasource/grafana-pyroscope-datasource" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/plugin-configs": "npm:12.2.0-pre" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/jest-dom": "npm:6.6.4" "@testing-library/react": "npm:16.3.0" @@ -2546,12 +2546,12 @@ __metadata: resolution: "@grafana-plugins/grafana-testdata-datasource@workspace:public/app/plugins/datasource/grafana-testdata-datasource" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" - "@grafana/plugin-configs": "npm:12.2.0-pre" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/jest-dom": "npm:6.6.4" "@testing-library/react": "npm:16.3.0" @@ -2587,13 +2587,13 @@ __metadata: resolution: "@grafana-plugins/graphite@workspace:public/app/plugins/datasource/graphite" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" - "@grafana/plugin-configs": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@reduxjs/toolkit": "npm:2.8.2" "@testing-library/dom": "npm:10.4.1" "@testing-library/jest-dom": "npm:6.6.4" @@ -2673,15 +2673,15 @@ __metadata: resolution: "@grafana-plugins/loki@workspace:public/app/plugins/datasource/loki" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" "@grafana/lezer-logql": "npm:0.2.8" "@grafana/llm": "npm:0.22.1" "@grafana/monaco-logql": "npm:^0.0.8" - "@grafana/plugin-configs": "npm:12.2.0-pre" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/jest-dom": "npm:6.6.4" "@testing-library/react": "npm:16.3.0" @@ -2717,14 +2717,14 @@ __metadata: resolution: "@grafana-plugins/mssql@workspace:public/app/plugins/datasource/mssql" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" - "@grafana/i18n": "npm:12.2.0-pre" - "@grafana/plugin-configs": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" + "@grafana/i18n": "npm:12.3.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/sql": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/sql": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/react": "npm:16.3.0" "@testing-library/user-event": "npm:14.6.1" @@ -2750,13 +2750,13 @@ __metadata: resolution: "@grafana-plugins/mysql@workspace:public/app/plugins/datasource/mysql" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" - "@grafana/plugin-configs": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/sql": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/sql": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/react": "npm:16.3.0" "@testing-library/user-event": "npm:14.6.1" @@ -2782,11 +2782,11 @@ __metadata: resolution: "@grafana-plugins/parca@workspace:public/app/plugins/datasource/parca" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/plugin-configs": "npm:12.2.0-pre" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/react": "npm:16.3.0" "@testing-library/user-event": "npm:14.6.1" @@ -2815,14 +2815,14 @@ __metadata: resolution: "@grafana-plugins/stackdriver@workspace:public/app/plugins/datasource/cloud-monitoring" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" "@grafana/google-sdk": "npm:0.3.4" - "@grafana/plugin-configs": "npm:12.2.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/jest-dom": "npm:6.6.4" "@testing-library/react": "npm:16.3.0" @@ -2867,7 +2867,7 @@ __metadata: "@grafana/lezer-traceql": "npm:0.0.23" "@grafana/monaco-logql": "npm:^0.0.8" "@grafana/o11y-ds-frontend": "workspace:*" - "@grafana/plugin-configs": "npm:12.2.0-pre" + "@grafana/plugin-configs": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" "@grafana/runtime": "workspace:*" "@grafana/schema": "workspace:*" @@ -2959,7 +2959,7 @@ __metadata: dependencies: "@emotion/css": "npm:11.13.5" "@faker-js/faker": "npm:^9.8.0" - "@grafana/i18n": "npm:12.2.0-pre" + "@grafana/i18n": "npm:12.3.0-pre" "@grafana/test-utils": "workspace:*" "@rtk-query/codegen-openapi": "npm:^2.0.0" "@testing-library/jest-dom": "npm:^6.6.3" @@ -3035,13 +3035,13 @@ __metadata: languageName: node linkType: hard -"@grafana/data@npm:12.2.0-pre, @grafana/data@workspace:*, @grafana/data@workspace:packages/grafana-data": +"@grafana/data@npm:12.3.0-pre, @grafana/data@workspace:*, @grafana/data@workspace:packages/grafana-data": version: 0.0.0-use.local resolution: "@grafana/data@workspace:packages/grafana-data" dependencies: "@braintree/sanitize-url": "npm:7.0.1" - "@grafana/i18n": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" + "@grafana/i18n": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" "@leeoniya/ufuzzy": "npm:1.0.18" "@rollup/plugin-node-resolve": "npm:16.0.1" "@types/d3-interpolate": "npm:^3.0.0" @@ -3088,7 +3088,7 @@ __metadata: languageName: unknown linkType: soft -"@grafana/e2e-selectors@npm:12.2.0-pre, @grafana/e2e-selectors@workspace:*, @grafana/e2e-selectors@workspace:packages/grafana-e2e-selectors": +"@grafana/e2e-selectors@npm:12.3.0-pre, @grafana/e2e-selectors@workspace:*, @grafana/e2e-selectors@workspace:packages/grafana-e2e-selectors": version: 0.0.0-use.local resolution: "@grafana/e2e-selectors@workspace:packages/grafana-e2e-selectors" dependencies: @@ -3188,8 +3188,8 @@ __metadata: "@babel/preset-env": "npm:7.28.0" "@babel/preset-react": "npm:7.27.1" "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@leeoniya/ufuzzy": "npm:1.0.18" "@rollup/plugin-node-resolve": "npm:16.0.1" "@testing-library/dom": "npm:10.4.1" @@ -3239,7 +3239,7 @@ __metadata: languageName: node linkType: hard -"@grafana/i18n@npm:12.2.0-pre, @grafana/i18n@workspace:*, @grafana/i18n@workspace:packages/grafana-i18n": +"@grafana/i18n@npm:12.3.0-pre, @grafana/i18n@workspace:*, @grafana/i18n@workspace:packages/grafana-i18n": version: 0.0.0-use.local resolution: "@grafana/i18n@workspace:packages/grafana-i18n" dependencies: @@ -3309,12 +3309,12 @@ __metadata: resolution: "@grafana/o11y-ds-frontend@workspace:packages/grafana-o11y-ds-frontend" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@testing-library/dom": "npm:10.4.1" "@testing-library/jest-dom": "npm:^6.1.2" "@testing-library/react": "npm:16.3.0" @@ -3338,7 +3338,7 @@ __metadata: languageName: unknown linkType: soft -"@grafana/plugin-configs@npm:12.2.0-pre, @grafana/plugin-configs@workspace:*, @grafana/plugin-configs@workspace:packages/grafana-plugin-configs": +"@grafana/plugin-configs@npm:12.3.0-pre, @grafana/plugin-configs@workspace:*, @grafana/plugin-configs@workspace:packages/grafana-plugin-configs": version: 0.0.0-use.local resolution: "@grafana/plugin-configs@workspace:packages/grafana-plugin-configs" dependencies: @@ -3415,13 +3415,13 @@ __metadata: dependencies: "@emotion/css": "npm:11.13.5" "@floating-ui/react": "npm:0.27.16" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" - "@grafana/i18n": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" + "@grafana/i18n": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@hello-pangea/dnd": "npm:18.0.1" "@leeoniya/ufuzzy": "npm:1.0.18" "@lezer/common": "npm:1.2.3" @@ -3480,15 +3480,15 @@ __metadata: languageName: unknown linkType: soft -"@grafana/runtime@npm:12.2.0-pre, @grafana/runtime@workspace:*, @grafana/runtime@workspace:packages/grafana-runtime": +"@grafana/runtime@npm:12.3.0-pre, @grafana/runtime@workspace:*, @grafana/runtime@workspace:packages/grafana-runtime": version: 0.0.0-use.local resolution: "@grafana/runtime@workspace:packages/grafana-runtime" dependencies: - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" "@grafana/faro-web-sdk": "npm:^1.13.2" - "@grafana/schema": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/schema": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@rollup/plugin-node-resolve": "npm:16.0.1" "@rollup/plugin-terser": "npm:0.4.4" "@testing-library/dom": "npm:10.4.1" @@ -3567,7 +3567,7 @@ __metadata: languageName: node linkType: hard -"@grafana/schema@npm:12.2.0-pre, @grafana/schema@workspace:*, @grafana/schema@workspace:packages/grafana-schema": +"@grafana/schema@npm:12.3.0-pre, @grafana/schema@workspace:*, @grafana/schema@workspace:packages/grafana-schema": version: 0.0.0-use.local resolution: "@grafana/schema@workspace:packages/grafana-schema" dependencies: @@ -3583,17 +3583,17 @@ __metadata: languageName: unknown linkType: soft -"@grafana/sql@npm:12.2.0-pre, @grafana/sql@workspace:*, @grafana/sql@workspace:packages/grafana-sql": +"@grafana/sql@npm:12.3.0-pre, @grafana/sql@workspace:*, @grafana/sql@workspace:packages/grafana-sql": version: 0.0.0-use.local resolution: "@grafana/sql@workspace:packages/grafana-sql" dependencies: "@emotion/css": "npm:11.13.5" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" - "@grafana/i18n": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" + "@grafana/i18n": "npm:12.3.0-pre" "@grafana/plugin-ui": "npm:^0.10.10" - "@grafana/runtime": "npm:12.2.0-pre" - "@grafana/ui": "npm:12.2.0-pre" + "@grafana/runtime": "npm:12.3.0-pre" + "@grafana/ui": "npm:12.3.0-pre" "@react-awesome-query-builder/ui": "npm:6.6.15" "@testing-library/dom": "npm:10.4.1" "@testing-library/jest-dom": "npm:^6.1.2" @@ -3649,7 +3649,7 @@ __metadata: languageName: node linkType: hard -"@grafana/ui@npm:12.2.0-pre, @grafana/ui@workspace:*, @grafana/ui@workspace:packages/grafana-ui": +"@grafana/ui@npm:12.3.0-pre, @grafana/ui@workspace:*, @grafana/ui@workspace:packages/grafana-ui": version: 0.0.0-use.local resolution: "@grafana/ui@workspace:packages/grafana-ui" dependencies: @@ -3659,11 +3659,11 @@ __metadata: "@emotion/serialize": "npm:1.3.3" "@faker-js/faker": "npm:^9.0.0" "@floating-ui/react": "npm:0.27.16" - "@grafana/data": "npm:12.2.0-pre" - "@grafana/e2e-selectors": "npm:12.2.0-pre" + "@grafana/data": "npm:12.3.0-pre" + "@grafana/e2e-selectors": "npm:12.3.0-pre" "@grafana/faro-web-sdk": "npm:^1.13.2" - "@grafana/i18n": "npm:12.2.0-pre" - "@grafana/schema": "npm:12.2.0-pre" + "@grafana/i18n": "npm:12.3.0-pre" + "@grafana/schema": "npm:12.3.0-pre" "@hello-pangea/dnd": "npm:18.0.1" "@monaco-editor/react": "npm:4.7.0" "@popperjs/core": "npm:2.11.8" From 3e086d11336b4f994f668be72c335ebd18f27e0d Mon Sep 17 00:00:00 2001 From: "alerting-team[bot]" <158350966+alerting-team[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:01:13 -0400 Subject: [PATCH 37/48] Alerting: Update alerting module to f2728ab090eed9c6b70057b53239fb370d68e8ed (#111018) [create-pull-request] automated change Co-authored-by: santihernandezc <41638679+santihernandezc@users.noreply.github.com> Co-authored-by: Yuri Tseretyan --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7165cace114..ec8cc6b2e9c 100644 --- a/go.mod +++ b/go.mod @@ -86,7 +86,7 @@ require ( github.com/googleapis/gax-go/v2 v2.14.2 // @grafana/grafana-backend-group github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // @grafana/grafana-app-platform-squad - github.com/grafana/alerting v0.0.0-20250911172908-2b26ef8f17eb // @grafana/alerting-backend + github.com/grafana/alerting v0.0.0-20250912123435-f2728ab090ee // @grafana/alerting-backend github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 // @grafana/identity-access-team github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 // @grafana/identity-access-team github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics diff --git a/go.sum b/go.sum index ab196b94b3c..aa9d392df3b 100644 --- a/go.sum +++ b/go.sum @@ -1590,8 +1590,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/grafana/alerting v0.0.0-20250911172908-2b26ef8f17eb h1:g/gbEJoncYghiojMM6OwWJi1P+SC/mnjBG+E422p48o= -github.com/grafana/alerting v0.0.0-20250911172908-2b26ef8f17eb/go.mod h1:XWqj/rlsy4OV/E9XNNyFn+a7U4GNsSugPb2rDBj9+58= +github.com/grafana/alerting v0.0.0-20250912123435-f2728ab090ee h1:J/9l2w3Q5JDBEB3t5bDsxhxWldGtFd5KpYGoQi0m/hc= +github.com/grafana/alerting v0.0.0-20250912123435-f2728ab090ee/go.mod h1:XWqj/rlsy4OV/E9XNNyFn+a7U4GNsSugPb2rDBj9+58= github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 h1:vVPT0i5Y1vI6qzecYStV2yk7cHKrC3Pc7AgvwT5KydQ= github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43/go.mod h1:1fWkOiL+m32NBgRHZtlZGz2ji868tPZACYbqP3nBRJI= github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 h1:NlkGMnVi/oUn6Cr90QbJYpQJ4FnjyAIG9Ex5GtTZIzw= From c52eedbf23be6921152ce95d59b9986c6c840fb5 Mon Sep 17 00:00:00 2001 From: "lean.dev" <34773040+leandro-deveikis@users.noreply.github.com> Date: Fri, 12 Sep 2025 20:46:11 +0100 Subject: [PATCH 38/48] CloudMigration: fix flacky test (#111046) --- .../cloudmigrationimpl/cloudmigration_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go index 6b1e89f3096..948c63ea613 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go @@ -176,7 +176,7 @@ func Test_GetSnapshotStatusFromGMS(t *testing.T) { }) require.NoError(t, err) require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusPendingProcessing), time.Second, 10*time.Millisecond) - require.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount()) + require.True(t, gmsClientFake.GetSnapshotStatusCallCount() >= 1) }) t.Run("test case: gms snapshot processing", func(t *testing.T) { @@ -200,7 +200,7 @@ func Test_GetSnapshotStatusFromGMS(t *testing.T) { }) require.NoError(t, err) require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusProcessing), time.Second, 10*time.Millisecond) - require.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount()) + require.True(t, gmsClientFake.GetSnapshotStatusCallCount() >= 1) }) t.Run("test case: gms snapshot finished", func(t *testing.T) { @@ -224,7 +224,7 @@ func Test_GetSnapshotStatusFromGMS(t *testing.T) { }) require.NoError(t, err) require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusFinished), time.Second, 10*time.Millisecond) - require.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount()) + require.True(t, gmsClientFake.GetSnapshotStatusCallCount() >= 1) }) t.Run("test case: gms snapshot canceled", func(t *testing.T) { @@ -248,7 +248,7 @@ func Test_GetSnapshotStatusFromGMS(t *testing.T) { }) require.NoError(t, err) require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusCanceled), time.Second, 10*time.Millisecond) - require.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount()) + require.True(t, gmsClientFake.GetSnapshotStatusCallCount() >= 1) }) t.Run("test case: gms snapshot error", func(t *testing.T) { @@ -272,7 +272,7 @@ func Test_GetSnapshotStatusFromGMS(t *testing.T) { }) require.NoError(t, err) require.Eventually(t, checkStatusSync(ctx, s, snapshotUID, sessionUID, cloudmigration.SnapshotStatusError), time.Second, 10*time.Millisecond) - assert.Equal(t, 1, gmsClientFake.GetSnapshotStatusCallCount()) + assert.True(t, gmsClientFake.GetSnapshotStatusCallCount() >= 1) }) t.Run("test case: gms snapshot unknown", func(t *testing.T) { From c5ed2780abb8cf2c38ec67f1962876395ea96c9a Mon Sep 17 00:00:00 2001 From: Stephanie Hingtgen Date: Fri, 12 Sep 2025 14:02:13 -0600 Subject: [PATCH 39/48] Provisioning: Fix deletion order (#111043) --- .../provisioning/controller/finalizers.go | 36 ++++++++-- .../controller/finalizers_test.go | 66 +++++++++++++++++++ 2 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 pkg/registry/apis/provisioning/controller/finalizers_test.go diff --git a/pkg/registry/apis/provisioning/controller/finalizers.go b/pkg/registry/apis/provisioning/controller/finalizers.go index 3980db5ec6f..72c2209911c 100644 --- a/pkg/registry/apis/provisioning/controller/finalizers.go +++ b/pkg/registry/apis/provisioning/controller/finalizers.go @@ -160,14 +160,36 @@ func sortResourceListForDeletion(list *provisioning.ResourceList) { // Sort by the following logic: // - Put folders at the end so that we empty them first. // - Sort folders by depth so that we remove the deepest first + // - If the repo is created within a folder in grafana, make sure that folder is last. sort.Slice(list.Items, func(i, j int) bool { - switch { - case list.Items[i].Group != folders.RESOURCE: - return true - case list.Items[j].Group != folders.RESOURCE: - return false - default: - return len(strings.Split(list.Items[i].Path, "/")) > len(strings.Split(list.Items[j].Path, "/")) + isFolderI := list.Items[i].Group == folders.GroupVersion.Group + isFolderJ := list.Items[j].Group == folders.GroupVersion.Group + + // non-folders always go first in the order of deletion. + if isFolderI != isFolderJ { + return !isFolderI } + + // if both are not folders, keep order (doesn't matter) + if !isFolderI && !isFolderJ { + return false + } + + hasFolderI := list.Items[i].Folder != "" + hasFolderJ := list.Items[j].Folder != "" + // if one folder is in the root (i.e. does not have a folder specified), put that last + if hasFolderI != hasFolderJ { + return hasFolderI + } + + // if both are nested folder, sort by depth, with the deepest one being first + depthI := len(strings.Split(list.Items[i].Path, "/")) + depthJ := len(strings.Split(list.Items[j].Path, "/")) + if depthI != depthJ { + return depthI > depthJ + } + + // otherwise, keep order (doesn't matter) + return false }) } diff --git a/pkg/registry/apis/provisioning/controller/finalizers_test.go b/pkg/registry/apis/provisioning/controller/finalizers_test.go new file mode 100644 index 00000000000..a44e595afbf --- /dev/null +++ b/pkg/registry/apis/provisioning/controller/finalizers_test.go @@ -0,0 +1,66 @@ +package controller + +import ( + "testing" + + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + "github.com/stretchr/testify/assert" +) + +func TestSortResourceListForDeletion(t *testing.T) { + testCases := []struct { + name string + input provisioning.ResourceList + expected provisioning.ResourceList + }{ + { + name: "Non-folder items first, folders sorted by depth", + input: provisioning.ResourceList{ + Items: []provisioning.ResourceListItem{ + {Group: "dashboard.grafana.app", Path: "dashboard1.json"}, + {Group: "folder.grafana.app", Path: "folder1"}, + {Group: "folder.grafana.app", Path: "folder1/subfolder1/subfolder2", Folder: "subfolder1"}, + {Group: "dashboard.grafana.app", Path: "dashboard2.json"}, + {Group: "folder.grafana.app", Path: "folder2"}, + {Group: "folder.grafana.app", Path: "folder1/subfolder1", Folder: "folder1"}, + }, + }, + expected: provisioning.ResourceList{ + Items: []provisioning.ResourceListItem{ + {Group: "dashboard.grafana.app", Path: "dashboard1.json"}, + {Group: "dashboard.grafana.app", Path: "dashboard2.json"}, + {Group: "folder.grafana.app", Path: "folder1/subfolder1/subfolder2", Folder: "subfolder1"}, + {Group: "folder.grafana.app", Path: "folder1/subfolder1", Folder: "folder1"}, + {Group: "folder.grafana.app", Path: "folder1"}, + {Group: "folder.grafana.app", Path: "folder2"}, + }, + }, + }, + { + name: "Folders without parent should be last", + input: provisioning.ResourceList{ + Items: []provisioning.ResourceListItem{ + {Group: "folder.grafana.app", Path: "folder1"}, + {Group: "folder.grafana.app", Path: "folder2", Folder: "folder1"}, // if a repo is created with a folder in grafana (here folder1), the path will not have /, but the folder will be set + {Group: "folder.grafana.app", Path: "folder2/subfolder1", Folder: "folder2"}, + {Group: "folder.grafana.app", Path: "folder3", Folder: "folder1"}, + }, + }, + expected: provisioning.ResourceList{ + Items: []provisioning.ResourceListItem{ + {Group: "folder.grafana.app", Path: "folder2/subfolder1", Folder: "folder2"}, + {Group: "folder.grafana.app", Path: "folder2", Folder: "folder1"}, + {Group: "folder.grafana.app", Path: "folder3", Folder: "folder1"}, + {Group: "folder.grafana.app", Path: "folder1"}, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sortResourceListForDeletion(&tc.input) + assert.Equal(t, tc.expected, tc.input) + }) + } +} From 7ce971cba116c7ec8f4c8290bd48b969a135f4df Mon Sep 17 00:00:00 2001 From: owensmallwood Date: Fri, 12 Sep 2025 14:40:16 -0600 Subject: [PATCH 40/48] Unified Storage: Adds pruner for kv eventstore (#110785) * Adds pruner for eventstore - default 24 hours. Adds tests. * update comment * remove delay on startup. formatting * updates log message type and removes useless comment * caller handles goroutine for runCleanupOldEvents() * simplify timestamp extraction * adds config for event pruning interval * uses start and end key to get all expired events * remove sort when listing keys in event pruner - order doesnt matter * use snowflake constants * log when we delete 0 rows * pass time.Time to cleanup old events func --- pkg/storage/unified/resource/eventstore.go | 30 ++++ .../unified/resource/eventstore_test.go | 133 ++++++++++++++++++ .../unified/resource/storage_backend.go | 102 ++++++++++---- 3 files changed, 241 insertions(+), 24 deletions(-) diff --git a/pkg/storage/unified/resource/eventstore.go b/pkg/storage/unified/resource/eventstore.go index f2a3bc4e028..651fcb52092 100644 --- a/pkg/storage/unified/resource/eventstore.go +++ b/pkg/storage/unified/resource/eventstore.go @@ -7,6 +7,9 @@ import ( "iter" "strconv" "strings" + "time" + + "github.com/bwmarrin/snowflake" ) const ( @@ -224,3 +227,30 @@ func (n *eventStore) ListSince(ctx context.Context, sinceRV int64) iter.Seq2[Eve } } } + +// CleanupOldEvents deletes events older than the specified retention period. +func (n *eventStore) CleanupOldEvents(ctx context.Context, cutoff time.Time) (int, error) { + deletedCount := 0 + + // Keys are stored in the format of "resource_version~namespace~group~resource~name" + // With a start key of "1" and an end key of the cutoff time we can get all expired events. + endKey := fmt.Sprintf("%d", snowflakeFromTime(cutoff)) + for key, err := range n.kv.Keys(ctx, eventsSection, ListOptions{StartKey: "1", EndKey: endKey}) { + if err != nil { + return deletedCount, fmt.Errorf("failed to list event keys: %w", err) + } + + // TODO should use batch deletes here when available + if err := n.kv.Delete(ctx, eventsSection, key); err != nil { + return deletedCount, fmt.Errorf("failed to delete event key %s: %w", key, err) + } + deletedCount++ + } + + return deletedCount, nil +} + +// snowflake id with last two sections set to 0 (machine id and sequence) +func snowflakeFromTime(t time.Time) int64 { + return (t.UnixMilli() - snowflake.Epoch) << (snowflake.NodeBits + snowflake.StepBits) +} diff --git a/pkg/storage/unified/resource/eventstore_test.go b/pkg/storage/unified/resource/eventstore_test.go index 7782e879094..63ddc999567 100644 --- a/pkg/storage/unified/resource/eventstore_test.go +++ b/pkg/storage/unified/resource/eventstore_test.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -468,3 +469,135 @@ func TestEventStore_Save_InvalidJSON(t *testing.T) { err := store.Save(ctx, event) assert.NoError(t, err) } + +func TestEventStore_CleanupOldEvents(t *testing.T) { + ctx := context.Background() + store := setupTestEventStore(t) + + now := time.Now() + oldRV := snowflakeFromTime(now.Add(-48 * time.Hour)) // 48 hours ago + recentRV := snowflakeFromTime(now.Add(-1 * time.Hour)) // 1 hour ago + + oldEvent := Event{ + Namespace: "default", + Group: "apps", + Resource: "resource", + Name: "old-resource", + ResourceVersion: oldRV, + Action: DataActionCreated, + Folder: "test-folder", + PreviousRV: 999, + } + + recentEvent := Event{ + Namespace: "default", + Group: "apps", + Resource: "resource", + Name: "recent-resource", + ResourceVersion: recentRV, + Action: DataActionCreated, + Folder: "test-folder", + PreviousRV: 999, + } + + // Save both events + err := store.Save(ctx, oldEvent) + require.NoError(t, err) + err = store.Save(ctx, recentEvent) + require.NoError(t, err) + + // Verify both events exist + _, err = store.Get(ctx, EventKey{ + Namespace: oldEvent.Namespace, + Group: oldEvent.Group, + Resource: oldEvent.Resource, + Name: oldEvent.Name, + ResourceVersion: oldEvent.ResourceVersion, + Action: oldEvent.Action, + }) + require.NoError(t, err) + + _, err = store.Get(ctx, EventKey{ + Namespace: recentEvent.Namespace, + Group: recentEvent.Group, + Resource: recentEvent.Resource, + Name: recentEvent.Name, + ResourceVersion: recentEvent.ResourceVersion, + Action: recentEvent.Action, + }) + require.NoError(t, err) + + // Clean up events older than 24 hours + deletedCount, err := store.CleanupOldEvents(ctx, time.Now().Add(-24*time.Hour)) + require.NoError(t, err) + assert.Equal(t, 1, deletedCount, "Should have deleted 1 old event") + + // Verify old event was deleted + _, err = store.Get(ctx, EventKey{ + Namespace: oldEvent.Namespace, + Group: oldEvent.Group, + Resource: oldEvent.Resource, + Name: oldEvent.Name, + ResourceVersion: oldEvent.ResourceVersion, + Action: oldEvent.Action, + }) + assert.Error(t, err, "Old event should have been deleted") + + // Verify recent event still exists + _, err = store.Get(ctx, EventKey{ + Namespace: recentEvent.Namespace, + Group: recentEvent.Group, + Resource: recentEvent.Resource, + Name: recentEvent.Name, + ResourceVersion: recentEvent.ResourceVersion, + Action: recentEvent.Action, + }) + require.NoError(t, err, "Recent event should still exist") +} + +func TestEventStore_CleanupOldEvents_NoOldEvents(t *testing.T) { + ctx := context.Background() + store := setupTestEventStore(t) + + // Create an event 1 hour old + rv := snowflakeFromTime(time.Now().Add(-1 * time.Hour)) + event := Event{ + Namespace: "default", + Group: "apps", + Resource: "resource", + Name: "recent-resource", + ResourceVersion: rv, + Action: DataActionCreated, + Folder: "test-folder", + PreviousRV: 999, + } + + err := store.Save(ctx, event) + require.NoError(t, err) + + // Clean up events older than 24 hours + deletedCount, err := store.CleanupOldEvents(ctx, time.Now().Add(-24*time.Hour)) + require.NoError(t, err) + assert.Equal(t, 0, deletedCount, "Should not have deleted any events") + + // Verify event still exists + _, err = store.Get(ctx, EventKey{ + Namespace: event.Namespace, + Group: event.Group, + Resource: event.Resource, + Name: event.Name, + ResourceVersion: event.ResourceVersion, + Action: event.Action, + }) + require.NoError(t, err, "Recent event should still exist") +} + +func TestEventStore_CleanupOldEvents_EmptyStore(t *testing.T) { + ctx := context.Background() + store := setupTestEventStore(t) + + // Clean up events from empty store + deletedCount, err := store.CleanupOldEvents(ctx, time.Now().Add(-24*time.Hour)) + require.NoError(t, err) + assert.Equal(t, 0, deletedCount, "Should not have deleted any events from empty store") +} diff --git a/pkg/storage/unified/resource/storage_backend.go b/pkg/storage/unified/resource/storage_backend.go index 4f5490f7c7d..54bd33ba67f 100644 --- a/pkg/storage/unified/resource/storage_backend.go +++ b/pkg/storage/unified/resource/storage_backend.go @@ -25,22 +25,26 @@ import ( ) const ( - defaultListBufferSize = 100 - prunerMaxEvents = 20 + defaultListBufferSize = 100 + prunerMaxEvents = 20 + defaultEventRetentionPeriod = 1 * time.Hour + defaultEventPruningInterval = 5 * time.Minute ) // kvStorageBackend Unified storage backend based on KV storage. type kvStorageBackend struct { - snowflake *snowflake.Node - kv KV - dataStore *dataStore - metaStore *metadataStore - eventStore *eventStore - notifier *notifier - builder DocumentBuilder - log logging.Logger - withPruner bool - historyPruner Pruner + snowflake *snowflake.Node + kv KV + dataStore *dataStore + metaStore *metadataStore + eventStore *eventStore + notifier *notifier + builder DocumentBuilder + log logging.Logger + withPruner bool + eventRetentionPeriod time.Duration + eventPruningInterval time.Duration + historyPruner Pruner //tracer trace.Tracer //reg prometheus.Registerer } @@ -48,10 +52,12 @@ type kvStorageBackend struct { var _ StorageBackend = &kvStorageBackend{} type KvBackendOptions struct { - KvStore KV - WithPruner bool - Tracer trace.Tracer // TODO add tracing - Reg prometheus.Registerer // TODO add metrics + KvStore KV + WithPruner bool + EventRetentionPeriod time.Duration // How long to keep events (default: 1 hour) + EventPruningInterval time.Duration // How often to run the event pruning (default: 5 minutes) + Tracer trace.Tracer // TODO add tracing + Reg prometheus.Registerer // TODO add metrics } func NewKvStorageBackend(opts KvBackendOptions) (StorageBackend, error) { @@ -63,23 +69,71 @@ func NewKvStorageBackend(opts KvBackendOptions) (StorageBackend, error) { return nil, fmt.Errorf("failed to create snowflake node: %w", err) } eventStore := newEventStore(kv) + + eventRetentionPeriod := opts.EventRetentionPeriod + if eventRetentionPeriod <= 0 { + eventRetentionPeriod = defaultEventRetentionPeriod + } + + eventPruningInterval := opts.EventPruningInterval + if eventPruningInterval <= 0 { + eventPruningInterval = defaultEventPruningInterval + } + backend := &kvStorageBackend{ - kv: kv, - dataStore: newDataStore(kv), - metaStore: newMetadataStore(kv), - eventStore: eventStore, - notifier: newNotifier(eventStore, notifierOptions{}), - snowflake: s, - builder: StandardDocumentBuilder(), // For now we use the standard document builder. - log: &logging.NoOpLogger{}, // Make this configurable + kv: kv, + dataStore: newDataStore(kv), + metaStore: newMetadataStore(kv), + eventStore: eventStore, + notifier: newNotifier(eventStore, notifierOptions{}), + snowflake: s, + builder: StandardDocumentBuilder(), // For now we use the standard document builder. + log: &logging.NoOpLogger{}, // Make this configurable + eventRetentionPeriod: eventRetentionPeriod, + eventPruningInterval: eventPruningInterval, } err = backend.initPruner(ctx) if err != nil { return nil, fmt.Errorf("failed to initialize pruner: %w", err) } + + // Start the event cleanup background job + go backend.runCleanupOldEvents(ctx) + return backend, nil } +// runCleanupOldEvents starts a background goroutine that periodically cleans up old events +func (k *kvStorageBackend) runCleanupOldEvents(ctx context.Context) { + // Run cleanup every hour + ticker := time.NewTicker(k.eventPruningInterval) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + k.log.Debug("Event cleanup stopped due to context cancellation") + return + case <-ticker.C: + k.cleanupOldEvents(ctx) + } + } +} + +// cleanupOldEvents performs the actual cleanup of old events +func (k *kvStorageBackend) cleanupOldEvents(ctx context.Context) { + cutoff := time.Now().Add(-k.eventRetentionPeriod) + deletedCount, err := k.eventStore.CleanupOldEvents(ctx, cutoff) + if err != nil { + k.log.Error("Failed to cleanup old events", "error", err) + return + } + + if deletedCount == 0 { + k.log.Info("Cleaned up old events", "deleted_count", deletedCount, "retention_period", k.eventRetentionPeriod) + } +} + func (k *kvStorageBackend) pruneEvents(ctx context.Context, key PruningKey) error { if !key.Validate() { return fmt.Errorf("invalid pruning key, all fields must be set: %+v", key) From cb37539ed7ca14230fda6e61012ab519eabccab7 Mon Sep 17 00:00:00 2001 From: Paul Marbach Date: Fri, 12 Sep 2025 17:22:30 -0400 Subject: [PATCH 41/48] Table: Fix logic to calculate footer height (#110954) * Table: Fix logic to calculate footer height * add non-numeric footer case to gdev * Update packages/grafana-ui/src/components/Table/TableNG/utils.ts Co-authored-by: Leon Sorokin * Update packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx Co-authored-by: Leon Sorokin --------- Co-authored-by: Leon Sorokin --- .../panel-table/table_footer.json | 61 +++++++++++++++++++ .../src/components/Table/TableNG/TableNG.tsx | 18 +++--- .../components/Table/TableNG/utils.test.ts | 30 +++++++++ .../src/components/Table/TableNG/utils.ts | 52 +++------------- 4 files changed, 108 insertions(+), 53 deletions(-) diff --git a/devenv/dev-dashboards/panel-table/table_footer.json b/devenv/dev-dashboards/panel-table/table_footer.json index fddbeaa7747..6d7ca427f7b 100644 --- a/devenv/dev-dashboards/panel-table/table_footer.json +++ b/devenv/dev-dashboards/panel-table/table_footer.json @@ -1442,6 +1442,67 @@ } ], "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "footer": { + "reducers": ["lastNotNull", "countAll"] + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 9, + "options": { + "cellHeight": "sm", + "showHeader": true + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "csvContent": "a,b\nfoo,bar\nbaz,bim\nbop,boop", + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "No numeric fields", + "type": "table" } ], "preload": false, diff --git a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx index 5b5fcc5b2a4..e21e3c59be9 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx +++ b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx @@ -108,7 +108,6 @@ export function TableNG(props: TableNGProps) { enablePagination = false, enableSharedCrosshair = false, enableVirtualization, - fieldConfig, frozenColumns = 0, getActions = () => [], height, @@ -125,12 +124,6 @@ export function TableNG(props: TableNGProps) { width, } = props; - const hasFooter = useMemo( - () => data.fields.some((field) => field.config?.custom?.footer?.reducers?.length ?? false), - [data.fields] - ); - const footerHeight = hasFooter ? calculateFooterHeight(data, fieldConfig) : 0; - const theme = useTheme2(); const styles = useStyles2(getGridStyles, enablePagination, transparent); const panelContext = usePanelContext(); @@ -146,7 +139,16 @@ export function TableNG(props: TableNGProps) { [getActions, data, userCanExecuteActions] ); + const visibleFields = useMemo(() => getVisibleFields(data.fields), [data.fields]); const hasHeader = !noHeader; + const hasFooter = useMemo( + () => visibleFields.some((field) => Boolean(field.config.custom?.footer?.reducers?.length)), + [visibleFields] + ); + const footerHeight = useMemo( + () => (hasFooter ? calculateFooterHeight(visibleFields) : 0), + [hasFooter, visibleFields] + ); const resizeHandler = useColumnResize(onColumnResize); @@ -173,7 +175,7 @@ export function TableNG(props: TableNGProps) { const [expandedRows, setExpandedRows] = useState(() => new Set()); // vt scrollbar accounting for column auto-sizing - const visibleFields = useMemo(() => getVisibleFields(data.fields), [data.fields]); + const defaultRowHeight = useMemo( () => getDefaultRowHeight(theme, visibleFields, cellHeight), [theme, visibleFields, cellHeight] diff --git a/packages/grafana-ui/src/components/Table/TableNG/utils.test.ts b/packages/grafana-ui/src/components/Table/TableNG/utils.test.ts index 7331c048a92..946ee3fd799 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/utils.test.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/utils.test.ts @@ -46,6 +46,7 @@ import { getDefaultRowHeight, getDisplayName, predicateByName, + calculateFooterHeight, } from './utils'; describe('TableNG utils', () => { @@ -1380,6 +1381,35 @@ describe('TableNG utils', () => { }); }); + describe('calculateFooterHeight', () => { + it('should return 0 if no footer is present', () => { + const frame = createDataFrame({ + fields: [ + { name: 'time', values: [1, 1, 2], nanos: [100, 99, 0] }, + { name: 'value', values: [10, 20, 30] }, + ], + }); + + expect(calculateFooterHeight(frame.fields)).toBe(0); + }); + + it('should return the height in pixels for the max reducers on a given field', () => { + const frame = createDataFrame({ + fields: [ + { + name: 'time', + values: [1, 1, 2], + nanos: [100, 99, 0], + config: { custom: { footer: { reducers: ['min', 'max', 'count'] } } }, + }, + { name: 'value', values: [10, 20, 30], config: { custom: { footer: { reducers: ['min'] } } } }, + ], + }); + + expect(calculateFooterHeight(frame.fields)).toBe(78); // 3 reducers * 22px line height + 12px padding + }); + }); + describe('getDisplayName', () => { it('should return the display name if set', () => { const field: Field = { diff --git a/packages/grafana-ui/src/components/Table/TableNG/utils.ts b/packages/grafana-ui/src/components/Table/TableNG/utils.ts index 7da729539a3..162c8e6df91 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/utils.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/utils.ts @@ -8,7 +8,6 @@ import { Count, varPreLine } from 'uwrap'; import { FieldType, Field, - FieldConfigSource, formattedValueToString, GrafanaTheme2, DisplayValue, @@ -842,55 +841,18 @@ export const processNestedTableRows = ( return result; }; -/** - * @internal - * Get the maximum number of reducers across all fields - */ -const getMaxReducerCount = (dataFrame: DataFrame, fieldConfig?: FieldConfigSource): number => { - // Filter to only numeric fields that can have reducers - const numericFields = dataFrame.fields.filter(({ type }) => type === FieldType.number); - - // If there are no numeric fields, return 0 - if (numericFields.length === 0) { - return 0; - } - - // Map each field to its reducer count (direct config or override) - const reducerCounts = numericFields.map((field) => { - // Get the direct reducer count from the field config - const directReducers = field.config?.custom?.footer?.reducers ?? []; - let reducerCount = directReducers.length; - - // Check for overrides if field config is available - if (fieldConfig?.overrides) { - // Find override that matches this field - const override = fieldConfig.overrides.find( - ({ matcher: { id, options } }) => id === 'byName' && options === getDisplayName(field) - ); - - // Check if there's a footer reducer property in the override - const footerProperty = override?.properties?.find(({ id }) => id === 'custom.footer.reducers'); - if (footerProperty?.value && Array.isArray(footerProperty.value)) { - // If override exists, it takes precedence over direct config - reducerCount = footerProperty.value.length; - } - } - - return reducerCount; - }); - - // Return the maximum count or 0 if no reducers found - return reducerCounts.length > 0 ? Math.max(...reducerCounts) : 0; -}; - /** * @internal * Calculate the footer height based on the maximum reducer count */ -export const calculateFooterHeight = (dataFrame: DataFrame, fieldConfig?: FieldConfigSource) => { - const maxReducerCount = getMaxReducerCount(dataFrame, fieldConfig); +export const calculateFooterHeight = (fields: Field[]): number => { + let maxReducerCount = 0; + for (const field of fields) { + maxReducerCount = Math.max(maxReducerCount, field.config.custom?.footer?.reducers?.length ?? 0); + } + // Base height (+ padding) + height per reducer - return maxReducerCount * TABLE.LINE_HEIGHT + TABLE.CELL_PADDING * 2; + return maxReducerCount > 0 ? maxReducerCount * TABLE.LINE_HEIGHT + TABLE.CELL_PADDING * 2 : 0; }; /** From f258d8a41726e7bb482ae1cf8549a2686bfdb38c Mon Sep 17 00:00:00 2001 From: Paul Marbach Date: Fri, 12 Sep 2025 17:33:06 -0400 Subject: [PATCH 42/48] Table: Restore previous footer behavior of reducers applying to filtered data (#111041) * Table: Restore previous footer behavior of reducers applying to filtered data * update e2e to match new behavior --- e2e-playwright/panels-suite/table-footer.spec.ts | 4 ++-- packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/e2e-playwright/panels-suite/table-footer.spec.ts b/e2e-playwright/panels-suite/table-footer.spec.ts index 4c7064fa1fc..aecd1df29a3 100644 --- a/e2e-playwright/panels-suite/table-footer.spec.ts +++ b/e2e-playwright/panels-suite/table-footer.spec.ts @@ -11,7 +11,7 @@ const waitForTableLoad = async (loc: Page | Locator) => { }; test.describe('Panels test: Table - Footer', { tag: ['@panels', '@table'] }, () => { - test('Footer unaffected by filtering', async ({ gotoDashboardPage, selectors, page }) => { + test('Footer affected by filtering', async ({ gotoDashboardPage, selectors, page }) => { const dashboardPage = await gotoDashboardPage({ uid: DASHBOARD_UID, queryParams: new URLSearchParams({ editPanel: '4' }), @@ -51,7 +51,7 @@ test.describe('Panels test: Table - Footer', { tag: ['@panels', '@table'] }, () dashboardPage .getByGrafanaSelector(selectors.components.Panels.Visualization.TableNG.Footer.Value) .nth(minColumnIdx) - ).toHaveText(minReducerValue); + ).not.toHaveText(minReducerValue); }); test('Footer unaffected by sorting', async ({ gotoDashboardPage, selectors, page }) => { diff --git a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx index e21e3c59be9..726a9a3ccf0 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx +++ b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx @@ -679,7 +679,7 @@ export function TableNG(props: TableNGProps) { ), renderSummaryCell: () => ( Date: Fri, 12 Sep 2025 23:35:10 +0200 Subject: [PATCH 43/48] Graphite: Backend metrics expand endpoint (#110678) * Add lint rules * Backend decoupling - Add standalone files - Add graphite query type - Add logger to Service - Create logger in the ProvideService method - Use a pointer for the HTTP client provider - Update logger usage everywhere - Update tracer type - Replace simplejson with json - Add dummy CallResource and CheckHealth methods - Update tests * Update ConfigEditor imports * Update types imports * Update datasource - Switch to using semver package - Update imports * Update store imports * Update helper imports and notification creation * Update context import * Update version numbers and logic * Copy array_move from core * Test updates * Add required files and update plugin.json * Update core references and packages * Remove commented code * Update wire * Lint * Fix import * Copy null type * More lint * Update snapshot * Refactor backend - Split query logic into separate file - Move utils to separate file * Add health-check logic - Support backend healthcheck if the FF is enabled * Remove query import support as unneeded * Add test * Add util function for decoding responses * Add events types * Add resource handler * Add events handler and generic resource req handler * Tests * Update frontend - Add types - Update events function to support backend requests * Lint and typing * Lint * Add metrics find endpoint - Add types - Add generic response parser - Add endpoint - Tests * Update FE functoin to use backend endpoint * Lint * Simplify request * Update test * Metrics expand type * Extract shared logic and add metric expand endpoint * Update tests * Call metric expand from backend * Add tests * Review * Review * Fix packages * Format * Fix merge issues * Review * Fix undefined values * Extract request creation - Add method for create requests generically with tests - Replace usage in query method - Update usages in resource handlers - Update tests - Update types --- pkg/tsdb/graphite/graphite.go | 38 ++ pkg/tsdb/graphite/graphite_test.go | 241 +++++++ pkg/tsdb/graphite/query.go | 25 +- pkg/tsdb/graphite/resource_handler.go | 227 ++++--- pkg/tsdb/graphite/resource_handler_test.go | 605 +++++++++++++++--- pkg/tsdb/graphite/types.go | 14 + .../plugins/datasource/graphite/datasource.ts | 18 +- 7 files changed, 959 insertions(+), 209 deletions(-) create mode 100644 pkg/tsdb/graphite/graphite_test.go diff --git a/pkg/tsdb/graphite/graphite.go b/pkg/tsdb/graphite/graphite.go index 406ba10f106..62b932763af 100644 --- a/pkg/tsdb/graphite/graphite.go +++ b/pkg/tsdb/graphite/graphite.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "net/http" + "net/url" + "path" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" @@ -94,3 +96,39 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { return s.resourceHandler.CallResource(ctx, req, sender) } + +func (s *Service) createRequest(ctx context.Context, dsInfo *datasourceInfo, params URLParams) (*http.Request, error) { + u, err := url.Parse(dsInfo.URL) + if err != nil { + return nil, err + } + + if params.SubPath != "" { + u.Path = path.Join(u.Path, params.SubPath) + } + + if params.QueryParams != nil { + queryValues := u.Query() + for k, v := range params.QueryParams { + queryValues.Set(k, v) + } + u.RawQuery = queryValues.Encode() + } + + method := params.Method + if method == "" { + method = http.MethodGet + } + + req, err := http.NewRequestWithContext(ctx, method, u.String(), params.Body) + if err != nil { + s.logger.Info("Failed to create request", "error", err) + return nil, fmt.Errorf("failed to create request: %w", err) + } + + for k, v := range params.Headers { + req.Header.Add(k, v) + } + + return req, err +} diff --git a/pkg/tsdb/graphite/graphite_test.go b/pkg/tsdb/graphite/graphite_test.go new file mode 100644 index 00000000000..bff49068f30 --- /dev/null +++ b/pkg/tsdb/graphite/graphite_test.go @@ -0,0 +1,241 @@ +package graphite + +import ( + "context" + "io" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_CreateRequest(t *testing.T) { + ctx := context.Background() + + service := &Service{} + dsInfo := &datasourceInfo{ + URL: "http://graphite.example.com", + } + + tests := []struct { + name string + dsInfo *datasourceInfo + params URLParams + expectedURL string + expectedMethod string + expectedError string + checkHeaders map[string]string + checkQuery map[string]string + }{ + { + name: "basic request with default GET method", + dsInfo: dsInfo, + params: URLParams{}, + expectedURL: "http://graphite.example.com", + expectedMethod: "GET", + }, + { + name: "request with subpath", + dsInfo: dsInfo, + params: URLParams{ + SubPath: "/metrics/find", + }, + expectedURL: "http://graphite.example.com/metrics/find", + expectedMethod: "GET", + }, + { + name: "request with custom method", + dsInfo: dsInfo, + params: URLParams{ + Method: "POST", + }, + expectedURL: "http://graphite.example.com", + expectedMethod: "POST", + }, + { + name: "request with query parameters", + dsInfo: dsInfo, + params: URLParams{ + QueryParams: map[string]string{ + "query": "stats.counters.*", + "format": "json", + }, + }, + expectedURL: "http://graphite.example.com", + expectedMethod: "GET", + checkQuery: map[string]string{ + "query": "stats.counters.*", + "format": "json", + }, + }, + { + name: "request with headers", + dsInfo: dsInfo, + params: URLParams{ + Headers: map[string]string{ + "Content-Type": "application/json", + }, + }, + expectedURL: "http://graphite.example.com", + expectedMethod: "GET", + checkHeaders: map[string]string{ + "Content-Type": "application/json", + }, + }, + { + name: "request with body", + dsInfo: dsInfo, + params: URLParams{ + Method: "POST", + Body: strings.NewReader(`{"test": "data"}`), + }, + expectedURL: "http://graphite.example.com", + expectedMethod: "POST", + }, + { + name: "complex request with all parameters", + dsInfo: dsInfo, + params: URLParams{ + SubPath: "/metrics/expand", + Method: "POST", + QueryParams: map[string]string{ + "groupByExpr": "true", + "leavesOnly": "false", + }, + Headers: map[string]string{ + "X-Custom-Header": "test-value", + }, + Body: strings.NewReader(`{"query": "stats.*"}`), + }, + expectedURL: "http://graphite.example.com/metrics/expand", + expectedMethod: "POST", + checkQuery: map[string]string{ + "groupByExpr": "true", + "leavesOnly": "false", + }, + checkHeaders: map[string]string{ + "X-Custom-Header": "test-value", + }, + }, + { + name: "invalid URL in datasource", + dsInfo: &datasourceInfo{ + URL: "://invalid-url", + }, + params: URLParams{}, + expectedError: "missing protocol scheme", + }, + { + name: "empty query parameter values", + dsInfo: dsInfo, + params: URLParams{ + QueryParams: map[string]string{ + "empty": "", + "valid": "value", + }, + }, + expectedURL: "http://graphite.example.com", + expectedMethod: "GET", + checkQuery: map[string]string{ + "empty": "", + "valid": "value", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req, err := service.createRequest(ctx, tt.dsInfo, tt.params) + + if tt.expectedError != "" { + require.Error(t, err) + assert.Contains(t, err.Error(), tt.expectedError) + return + } + + require.NoError(t, err) + require.NotNil(t, req) + + // Check URL (base URL without query parameters) + baseURL := req.URL.Scheme + "://" + req.URL.Host + req.URL.Path + assert.Equal(t, tt.expectedURL, baseURL) + assert.Equal(t, tt.expectedMethod, req.Method) + + if tt.checkQuery != nil { + for key, expectedValue := range tt.checkQuery { + actualValue := req.URL.Query().Get(key) + assert.Equal(t, expectedValue, actualValue, "Query parameter %s", key) + } + } + + if tt.checkHeaders != nil { + for key, expectedValue := range tt.checkHeaders { + actualValue := req.Header.Get(key) + assert.Equal(t, expectedValue, actualValue, "Header %s", key) + } + } + + if tt.params.Body != nil { + bodyBytes, err := io.ReadAll(req.Body) + require.NoError(t, err) + + expectedContent := "" + switch tt.name { + case "request with body": + expectedContent = `{"test": "data"}` + case "complex request with all parameters": + expectedContent = `{"query": "stats.*"}` + } + assert.Equal(t, expectedContent, string(bodyBytes)) + } + }) + } +} + +func Test_CreateRequest_Body(t *testing.T) { + ctx := context.Background() + service := &Service{} + dsInfo := &datasourceInfo{URL: "http://graphite.example.com"} + + t.Run("string reader body", func(t *testing.T) { + bodyContent := `{"query": "stats.*", "format": "json"}` + params := URLParams{ + Method: "POST", + Body: strings.NewReader(bodyContent), + } + + req, err := service.createRequest(ctx, dsInfo, params) + require.NoError(t, err) + + // Read the body to verify content + bodyBytes, err := io.ReadAll(req.Body) + require.NoError(t, err) + assert.Equal(t, bodyContent, string(bodyBytes)) + }) + + t.Run("nil body", func(t *testing.T) { + params := URLParams{ + Method: "GET", + Body: nil, + } + + req, err := service.createRequest(ctx, dsInfo, params) + require.NoError(t, err) + assert.Nil(t, req.Body) + }) + + t.Run("empty body reader", func(t *testing.T) { + params := URLParams{ + Method: "POST", + Body: strings.NewReader(""), + } + + req, err := service.createRequest(ctx, dsInfo, params) + require.NoError(t, err) + + bodyBytes, err := io.ReadAll(req.Body) + require.NoError(t, err) + assert.Empty(t, string(bodyBytes)) + }) +} diff --git a/pkg/tsdb/graphite/query.go b/pkg/tsdb/graphite/query.go index 4889328aeee..331dbc1af34 100644 --- a/pkg/tsdb/graphite/query.go +++ b/pkg/tsdb/graphite/query.go @@ -8,7 +8,6 @@ import ( "io" "net/http" "net/url" - "path" "regexp" "strconv" "strings" @@ -173,7 +172,12 @@ func (s *Service) createGraphiteRequest(ctx context.Context, query backend.DataQ s.logger.Debug("Graphite request", "params", formData) - graphiteReq, err := s.createRequest(ctx, dsInfo, formData) + graphiteReq, err := s.createRequest(ctx, dsInfo, URLParams{ + SubPath: "render", + Method: http.MethodPost, + Body: strings.NewReader(formData.Encode()), + Headers: map[string]string{"Content-Type": "application/x-www-form-urlencoded"}, + }) if err != nil { return nil, formData, nil, err } @@ -181,23 +185,6 @@ func (s *Service) createGraphiteRequest(ctx context.Context, query backend.DataQ return graphiteReq, formData, emptyQuery, nil } -func (s *Service) createRequest(ctx context.Context, dsInfo *datasourceInfo, data url.Values) (*http.Request, error) { - u, err := url.Parse(dsInfo.URL) - if err != nil { - return nil, err - } - u.Path = path.Join(u.Path, "render") - - req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), strings.NewReader(data.Encode())) - if err != nil { - s.logger.Info("Failed to create request", "error", err) - return nil, fmt.Errorf("failed to create request: %w", err) - } - - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - return req, err -} - func (s *Service) toDataFrames(response *http.Response, refId string) (frames data.Frames, error error) { responseData, err := s.parseResponse(response) if err != nil { diff --git a/pkg/tsdb/graphite/resource_handler.go b/pkg/tsdb/graphite/resource_handler.go index 53130cbee6b..6988aafaad3 100644 --- a/pkg/tsdb/graphite/resource_handler.go +++ b/pkg/tsdb/graphite/resource_handler.go @@ -10,21 +10,23 @@ import ( "strings" "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" ) -type resourceHandler func(context.Context, *datasourceInfo, []byte) ([]byte, int, error) +type resourceHandler[T any] func(context.Context, *datasourceInfo, T) ([]byte, int, error) func (s *Service) newResourceMux() *http.ServeMux { mux := http.NewServeMux() - mux.HandleFunc("/events", s.handleResourceReq(s.handleEvents)) - mux.HandleFunc("/metrics/find", s.handleResourceReq(s.handleMetricsFind)) + mux.HandleFunc("/events", handleResourceReq[GraphiteEventsRequest](s.handleEvents, s)) + mux.HandleFunc("/metrics/find", handleResourceReq[GraphiteMetricsFindRequest](s.handleMetricsFind, s)) + mux.HandleFunc("/metrics/expand", handleResourceReq[GraphiteMetricsFindRequest](s.handleMetricsExpand, s)) return mux } -func (s *Service) handleResourceReq(handlerFn resourceHandler) func(rw http.ResponseWriter, req *http.Request) { +func handleResourceReq[T any](handlerFn resourceHandler[T], s *Service) func(rw http.ResponseWriter, req *http.Request) { return func(rw http.ResponseWriter, req *http.Request) { s.logger.Debug("Received resource call", "url", req.URL.String(), "method", req.Method) @@ -55,7 +57,13 @@ func (s *Service) handleResourceReq(handlerFn resourceHandler) func(rw http.Resp return } - response, statusCode, err := handlerFn(ctx, dsInfo, requestBody) + parsedBody, err := parseRequestBody[T](requestBody, s.logger) + if err != nil { + writeErrorResponse(rw, http.StatusBadRequest, fmt.Sprintf("failed to parse request body: %v", err)) + return + } + + response, statusCode, err := handlerFn(ctx, dsInfo, *parsedBody) if err != nil { writeErrorResponse(rw, statusCode, fmt.Sprintf("failed to handle resource request: %v", err)) return @@ -70,59 +78,27 @@ func (s *Service) handleResourceReq(handlerFn resourceHandler) func(rw http.Resp } } -func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, requestBody []byte) ([]byte, int, error) { - eventsRequestJson := GraphiteEventsRequest{} - err := json.Unmarshal(requestBody, &eventsRequestJson) - if err != nil { - s.logger.Error("Failed to unmarshal events request body to JSON", "error", err) - return nil, http.StatusInternalServerError, fmt.Errorf("unexpected error %v", err) +func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, eventsRequestJson GraphiteEventsRequest) ([]byte, int, error) { + queryParams := map[string]string{ + "from": eventsRequestJson.From, + "until": eventsRequestJson.Until, } - - eventsUrl, err := url.Parse(fmt.Sprintf("%s/events/get_data", dsInfo.URL)) - if err != nil { - return nil, http.StatusInternalServerError, fmt.Errorf("unexpected error %v", err) - } - - queryValues := eventsUrl.Query() - queryValues.Set("from", eventsRequestJson.From) - queryValues.Set("until", eventsRequestJson.Until) if eventsRequestJson.Tags != "" { - queryValues.Set("tags", eventsRequestJson.Tags) + queryParams["tags"] = eventsRequestJson.Tags } - eventsUrl.RawQuery = queryValues.Encode() - - graphiteReq, err := http.NewRequestWithContext(ctx, http.MethodGet, eventsUrl.String(), nil) + req, err := s.createRequest(ctx, dsInfo, URLParams{ + SubPath: "events/get_data", + Method: http.MethodGet, + QueryParams: queryParams, + }) if err != nil { - s.logger.Info("Failed to create events request", "error", err) - return nil, http.StatusInternalServerError, fmt.Errorf("failed to create events request: %v", err) + return nil, http.StatusInternalServerError, fmt.Errorf("failed to create events request %v", err) } - _, span := tracing.DefaultTracer().Start(ctx, "graphite events") - defer span.End() - span.SetAttributes( - attribute.Int64("datasource_id", dsInfo.Id), - ) - res, err := dsInfo.HTTPClient.Do(graphiteReq) - if res != nil { - span.SetAttributes(attribute.Int("graphite.response.code", res.StatusCode)) - } + events, statusCode, err := doGraphiteRequest[[]GraphiteEventsResponse](ctx, dsInfo, s.logger, req) if err != nil { - span.RecordError(err) - span.SetStatus(codes.Error, err.Error()) - return nil, http.StatusInternalServerError, fmt.Errorf("failed to complete events request: %v", err) - } - - defer func() { - err := res.Body.Close() - if err != nil { - s.logger.Warn("Failed to close response body", "error", err) - } - }() - - events, err := parseResponse[[]GraphiteEventsResponse](res) - if err != nil { - return nil, http.StatusInternalServerError, fmt.Errorf("failed to parse events response: %v", err) + return nil, statusCode, fmt.Errorf("events request failed: %v", err) } // We construct this struct to avoid frontend changes. @@ -133,68 +109,39 @@ func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, requ return nil, http.StatusInternalServerError, fmt.Errorf("failed to marshal events response: %s", err) } - return graphiteEventsResponse, res.StatusCode, nil + return graphiteEventsResponse, statusCode, nil } -func (s *Service) handleMetricsFind(ctx context.Context, dsInfo *datasourceInfo, requestBody []byte) ([]byte, int, error) { - metricsFindRequestJson := GraphiteMetricsFindRequest{} - err := json.Unmarshal(requestBody, &metricsFindRequestJson) - if err != nil { - s.logger.Error("Failed to unmarshal metrics find request body to JSON", "error", err) - return nil, http.StatusInternalServerError, fmt.Errorf("unexpected error %v", err) - } - +func (s *Service) handleMetricsFind(ctx context.Context, dsInfo *datasourceInfo, metricsFindRequestJson GraphiteMetricsFindRequest) ([]byte, int, error) { if metricsFindRequestJson.Query == "" { return nil, http.StatusBadRequest, fmt.Errorf("query is required") } - metricsFindUrl, err := url.Parse(fmt.Sprintf("%s/metrics/find", dsInfo.URL)) - if err != nil { - return nil, http.StatusInternalServerError, fmt.Errorf("unexpected error %v", err) - } - - queryValues := metricsFindUrl.Query() - if metricsFindRequestJson.From != "" { - queryValues.Set("from", metricsFindRequestJson.From) - } - if metricsFindRequestJson.Until != "" { - queryValues.Set("until", metricsFindRequestJson.Until) - } - data := url.Values{} data.Set("query", metricsFindRequestJson.Query) - graphiteReq, err := http.NewRequestWithContext(ctx, http.MethodPost, metricsFindUrl.String(), strings.NewReader(data.Encode())) - if err != nil { - s.logger.Info("Failed to create metrics find request", "error", err) - return nil, http.StatusInternalServerError, fmt.Errorf("failed to create metrics find request: %v", err) + queryParams := map[string]string{} + if metricsFindRequestJson.From != "" { + queryParams["from"] = metricsFindRequestJson.From + } + if metricsFindRequestJson.Until != "" { + queryParams["until"] = metricsFindRequestJson.Until } - graphiteReq.Header.Add("Content-Type", "application/x-www-form-urlencoded") - _, span := tracing.DefaultTracer().Start(ctx, "graphite metrics find") - defer span.End() - span.SetAttributes( - attribute.Int64("datasource_id", dsInfo.Id), - ) - res, err := dsInfo.HTTPClient.Do(graphiteReq) - if res != nil { - span.SetAttributes(attribute.Int("graphite.response.code", res.StatusCode)) - } + req, err := s.createRequest(ctx, dsInfo, URLParams{ + SubPath: "metrics/find", + Method: http.MethodPost, + QueryParams: queryParams, + Body: strings.NewReader(data.Encode()), + Headers: map[string]string{"Content-Type": "application/x-www-form-urlencoded"}, + }) if err != nil { - span.RecordError(err) - span.SetStatus(codes.Error, err.Error()) - return nil, http.StatusInternalServerError, fmt.Errorf("failed to complete metrics find request: %v", err) + return nil, http.StatusInternalServerError, fmt.Errorf("failed to create metrics find request %v", err) } - defer func() { - err := res.Body.Close() - if err != nil { - s.logger.Warn("Failed to close response body", "error", err) - } - }() - metrics, err := parseResponse[[]GraphiteMetricsFindResponse](res) + metrics, statusCode, err := doGraphiteRequest[[]GraphiteMetricsFindResponse](ctx, dsInfo, s.logger, req) if err != nil { - return nil, http.StatusInternalServerError, fmt.Errorf("failed to parse metrics find response: %v", err) + return nil, statusCode, fmt.Errorf("metrics find request failed: %v", err) } metricsFindResponse, err := json.Marshal(*metrics) @@ -202,7 +149,91 @@ func (s *Service) handleMetricsFind(ctx context.Context, dsInfo *datasourceInfo, return nil, http.StatusInternalServerError, fmt.Errorf("failed to marshal metrics find response: %s", err) } - return metricsFindResponse, res.StatusCode, nil + return metricsFindResponse, statusCode, nil +} + +func (s *Service) handleMetricsExpand(ctx context.Context, dsInfo *datasourceInfo, metricsExpandRequestJson GraphiteMetricsFindRequest) ([]byte, int, error) { + if metricsExpandRequestJson.Query == "" { + return nil, http.StatusBadRequest, fmt.Errorf("query is required") + } + + queryParams := map[string]string{ + "query": metricsExpandRequestJson.Query, + } + if metricsExpandRequestJson.From != "" { + queryParams["from"] = metricsExpandRequestJson.From + } + if metricsExpandRequestJson.Until != "" { + queryParams["until"] = metricsExpandRequestJson.Until + } + + req, err := s.createRequest(ctx, dsInfo, URLParams{ + SubPath: "metrics/expand", + Method: http.MethodGet, + QueryParams: queryParams, + }) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("failed to create metrics expand request %v", err) + } + + metrics, statusCode, err := doGraphiteRequest[GraphiteMetricsExpandResponse](ctx, dsInfo, s.logger, req) + if err != nil { + return nil, statusCode, fmt.Errorf("metrics expand request failed: %v", err) + } + + metricsResponse := make([]GraphiteMetricsFindResponse, 0, len(metrics.Results)) + for _, metric := range metrics.Results { + metricsResponse = append(metricsResponse, GraphiteMetricsFindResponse{ + Text: metric, + }) + } + + metricsExpandResponse, err := json.Marshal(metricsResponse) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("failed to marshal metrics expand response: %s", err) + } + + return metricsExpandResponse, statusCode, nil +} + +func doGraphiteRequest[T any](ctx context.Context, dsInfo *datasourceInfo, logger log.Logger, req *http.Request) (*T, int, error) { + _, span := tracing.DefaultTracer().Start(ctx, "graphite request") + defer span.End() + span.SetAttributes( + attribute.Int64("datasource_id", dsInfo.Id), + ) + res, err := dsInfo.HTTPClient.Do(req) + if res != nil { + span.SetAttributes(attribute.Int("graphite.response.code", res.StatusCode)) + } + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + return nil, http.StatusInternalServerError, fmt.Errorf("failed to complete request: %v", err) + } + + defer func() { + if err := res.Body.Close(); err != nil { + logger.Warn("Failed to close response body", "err", err) + } + }() + + parsedResponse, err := parseResponse[T](res) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("failed to parse response: %v", err) + } + + return parsedResponse, res.StatusCode, nil +} + +func parseRequestBody[V any](requestBody []byte, logger log.Logger) (*V, error) { + requestJson := new(V) + err := json.Unmarshal(requestBody, &requestJson) + if err != nil { + logger.Error("Failed to unmarshal request body to JSON", "error", err) + return nil, fmt.Errorf("unexpected error %v", err) + } + return requestJson, nil } func parseResponse[V any](res *http.Response) (*V, error) { diff --git a/pkg/tsdb/graphite/resource_handler_test.go b/pkg/tsdb/graphite/resource_handler_test.go index 5857af1e146..51d5a0fb290 100644 --- a/pkg/tsdb/graphite/resource_handler_test.go +++ b/pkg/tsdb/graphite/resource_handler_test.go @@ -58,7 +58,7 @@ func TestHandleEvents(t *testing.T) { tests := []struct { name string dsInfo *datasourceInfo - requestBody []byte + request GraphiteEventsRequest expectedStatus int expectError bool errorContains string @@ -71,11 +71,7 @@ func TestHandleEvents(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, }, - requestBody: func() []byte { - request := GraphiteEventsRequest{From: "now-1h", Until: "now", Tags: "foo"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteEventsRequest{From: "now-1h", Until: "now", Tags: "foo"}, expectedStatus: 200, expectError: false, expectedEvents: mockEvents, @@ -87,37 +83,21 @@ func TestHandleEvents(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, }, - requestBody: func() []byte { - request := GraphiteEventsRequest{From: "now-1h", Until: "now"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteEventsRequest{From: "now-1h", Until: "now"}, expectedStatus: 200, expectError: false, expectedEvents: mockEvents, }, - { - name: "Invalid request body", - dsInfo: &datasourceInfo{Id: 1, URL: "http://graphite.grafana"}, - requestBody: []byte(`{"invalid": json}`), - expectedStatus: http.StatusInternalServerError, - expectError: true, - errorContains: "unexpected error", - }, { name: "Invalid URL", dsInfo: &datasourceInfo{ Id: 1, URL: "ht tp://invalid url", // Invalid URL }, - requestBody: func() []byte { - request := GraphiteEventsRequest{From: "now-1h", Until: "now"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteEventsRequest{From: "now-1h", Until: "now"}, expectedStatus: http.StatusInternalServerError, expectError: true, - errorContains: "unexpected error", + errorContains: "failed to create events request", }, { name: "HTTP client error", @@ -126,14 +106,10 @@ func TestHandleEvents(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{err: errors.New("network error")}}, }, - requestBody: func() []byte { - request := GraphiteEventsRequest{From: "now-1h", Until: "now"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteEventsRequest{From: "now-1h", Until: "now"}, expectedStatus: http.StatusInternalServerError, expectError: true, - errorContains: "failed to complete events request", + errorContains: "events request failed", }, { name: "Invalid response JSON", @@ -142,14 +118,10 @@ func TestHandleEvents(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: []byte("invalid json"), status: 200}}, }, - requestBody: func() []byte { - request := GraphiteEventsRequest{From: "now-1h", Until: "now"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteEventsRequest{From: "now-1h", Until: "now"}, expectedStatus: http.StatusInternalServerError, expectError: true, - errorContains: "failed to parse events response", + errorContains: "events request failed", }, } @@ -157,7 +129,7 @@ func TestHandleEvents(t *testing.T) { t.Run(tt.name, func(t *testing.T) { svc := &Service{logger: log.NewNullLogger()} - respBody, status, err := svc.handleEvents(context.Background(), tt.dsInfo, tt.requestBody) + respBody, status, err := svc.handleEvents(context.Background(), tt.dsInfo, tt.request) assert.Equal(t, tt.expectedStatus, status) @@ -191,7 +163,7 @@ func TestHandleMetricsFind(t *testing.T) { tests := []struct { name string dsInfo *datasourceInfo - requestBody []byte + request GraphiteMetricsFindRequest expectedStatus int expectError bool errorContains string @@ -204,11 +176,7 @@ func TestHandleMetricsFind(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, }, - requestBody: func() []byte { - request := GraphiteMetricsFindRequest{Query: "app.grafana.*"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, expectedStatus: 200, expectError: false, expectedMetrics: mockMetrics, @@ -220,35 +188,19 @@ func TestHandleMetricsFind(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, }, - requestBody: func() []byte { - request := GraphiteMetricsFindRequest{ - Query: "app.grafana.*", - From: "now-1h", - Until: "now", - } - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteMetricsFindRequest{ + Query: "app.grafana.*", + From: "now-1h", + Until: "now", + }, expectedStatus: 200, expectError: false, expectedMetrics: mockMetrics, }, { - name: "Invalid request body", + name: "Empty query", dsInfo: &datasourceInfo{Id: 1, URL: "http://graphite.grafana"}, - requestBody: []byte(`{"invalid": json}`), - expectedStatus: http.StatusInternalServerError, - expectError: true, - errorContains: "unexpected error", - }, - { - name: "Empty query", - dsInfo: &datasourceInfo{Id: 1, URL: "http://graphite.grafana"}, - requestBody: func() []byte { - request := GraphiteMetricsFindRequest{Query: ""} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteMetricsFindRequest{Query: ""}, expectedStatus: http.StatusBadRequest, expectError: true, errorContains: "query is required", @@ -259,14 +211,10 @@ func TestHandleMetricsFind(t *testing.T) { Id: 1, URL: "ht tp://invalid url", // Invalid URL }, - requestBody: func() []byte { - request := GraphiteMetricsFindRequest{Query: "app.grafana.*"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, expectedStatus: http.StatusInternalServerError, expectError: true, - errorContains: "unexpected error", + errorContains: "failed to create metrics find request", }, { name: "HTTP client error", @@ -275,14 +223,120 @@ func TestHandleMetricsFind(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{err: errors.New("network error")}}, }, - requestBody: func() []byte { - request := GraphiteMetricsFindRequest{Query: "app.grafana.*"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, expectedStatus: http.StatusInternalServerError, expectError: true, - errorContains: "failed to complete metrics find request", + errorContains: "metrics find request failed", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + svc := &Service{logger: log.NewNullLogger()} + + respBody, status, err := svc.handleMetricsFind(context.Background(), tt.dsInfo, tt.request) + + assert.Equal(t, tt.expectedStatus, status) + + if tt.expectError { + assert.Error(t, err) + assert.Nil(t, respBody) + if tt.errorContains != "" { + assert.Contains(t, err.Error(), tt.errorContains) + } + } else { + require.NoError(t, err) + assert.NotNil(t, respBody) + + if tt.expectedMetrics != nil { + var result []GraphiteMetricsFindResponse + require.NoError(t, json.Unmarshal(respBody, &result)) + assert.Equal(t, tt.expectedMetrics, result) + } + } + }) + } +} + +func TestHandleMetricsExpand(t *testing.T) { + mockExpandResponse := GraphiteMetricsExpandResponse{ + Results: []string{"app.grafana.metric1", "app.grafana.metric2", "app.grafana.metric3"}, + } + mockResp, _ := json.Marshal(mockExpandResponse) + + expectedMetrics := []GraphiteMetricsFindResponse{ + {Text: "app.grafana.metric1"}, + {Text: "app.grafana.metric2"}, + {Text: "app.grafana.metric3"}, + } + + tests := []struct { + name string + dsInfo *datasourceInfo + request GraphiteMetricsFindRequest + expectedStatus int + expectError bool + errorContains string + expectedMetrics []GraphiteMetricsFindResponse + }{ + { + name: "Success with query", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, + }, + request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, + expectedStatus: 200, + expectError: false, + expectedMetrics: expectedMetrics, + }, + { + name: "Success with query and time range", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, + }, + request: GraphiteMetricsFindRequest{ + Query: "app.grafana.*", + From: "now-1h", + Until: "now", + }, + expectedStatus: 200, + expectError: false, + expectedMetrics: expectedMetrics, + }, + { + name: "Empty query", + dsInfo: &datasourceInfo{Id: 1, URL: "http://graphite.grafana"}, + request: GraphiteMetricsFindRequest{Query: ""}, + expectedStatus: http.StatusBadRequest, + expectError: true, + errorContains: "query is required", + }, + { + name: "Invalid URL", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "ht tp://invalid url", // Invalid URL + }, + request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, + expectedStatus: http.StatusInternalServerError, + expectError: true, + errorContains: "failed to create metrics expand request", + }, + { + name: "HTTP client error", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{err: errors.New("network error")}}, + }, + request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, + expectedStatus: http.StatusInternalServerError, + expectError: true, + errorContains: "metrics expand request failed", }, { name: "Invalid response JSON", @@ -291,14 +345,22 @@ func TestHandleMetricsFind(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: []byte("invalid json"), status: 200}}, }, - requestBody: func() []byte { - request := GraphiteMetricsFindRequest{Query: "app.grafana.*"} - body, _ := json.Marshal(request) - return body - }(), + request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, expectedStatus: http.StatusInternalServerError, expectError: true, - errorContains: "failed to parse metrics find response", + errorContains: "metrics expand request failed", + }, + { + name: "Empty results", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: []byte(`{"results":[]}`), status: 200}}, + }, + request: GraphiteMetricsFindRequest{Query: "nonexistent.*"}, + expectedStatus: 200, + expectError: false, + expectedMetrics: []GraphiteMetricsFindResponse{}, }, } @@ -306,7 +368,7 @@ func TestHandleMetricsFind(t *testing.T) { t.Run(tt.name, func(t *testing.T) { svc := &Service{logger: log.NewNullLogger()} - respBody, status, err := svc.handleMetricsFind(context.Background(), tt.dsInfo, tt.requestBody) + respBody, status, err := svc.handleMetricsExpand(context.Background(), tt.dsInfo, tt.request) assert.Equal(t, tt.expectedStatus, status) @@ -352,7 +414,7 @@ func TestHandleResourceReq_Success(t *testing.T) { req = req.WithContext(backend.WithPluginContext(context.Background(), backend.PluginContext{})) rr := httptest.NewRecorder() - handler := svc.handleResourceReq(svc.handleEvents) + handler := handleResourceReq(svc.handleEvents, svc) handler(rr, req) assert.Equal(t, http.StatusOK, rr.Code) @@ -372,7 +434,7 @@ func TestHandleResourceReq_GetDSInfoError(t *testing.T) { req = req.WithContext(backend.WithPluginContext(context.Background(), backend.PluginContext{})) rr := httptest.NewRecorder() - handler := svc.handleResourceReq(svc.handleEvents) + handler := handleResourceReq(svc.handleEvents, svc) handler(rr, req) assert.Equal(t, http.StatusInternalServerError, rr.Code) @@ -394,7 +456,7 @@ func TestHandleResourceReq_NilHandler(t *testing.T) { req = req.WithContext(backend.WithPluginContext(context.Background(), backend.PluginContext{})) rr := httptest.NewRecorder() - handler := svc.handleResourceReq(nil) + handler := handleResourceReq[any](nil, svc) handler(rr, req) assert.Equal(t, http.StatusInternalServerError, rr.Code) @@ -414,3 +476,368 @@ func TestWriteErrorResponse(t *testing.T) { require.NoError(t, json.Unmarshal(rr.Body.Bytes(), &errorResp)) assert.Equal(t, "test error message", errorResp["error"]) } + +func TestDoGraphiteRequest(t *testing.T) { + mockResponse := []GraphiteEventsResponse{ + {When: 1234567890, What: "event1", Tags: []string{"tag1"}, Data: "data1"}, + } + mockResp, _ := json.Marshal(mockResponse) + + tests := []struct { + name string + endpoint string + dsInfo *datasourceInfo + method string + body io.Reader + headers map[string]string + expectedStatus int + expectError bool + errorContains string + expectedData []GraphiteEventsResponse + }{ + { + name: "Success GET request", + endpoint: "events", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, + }, + method: "GET", + headers: map[string]string{"Content-Type": "application/json"}, + expectedStatus: 200, + expectError: false, + expectedData: mockResponse, + }, + { + name: "Success POST request with body", + endpoint: "events", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockResp, status: 200}}, + }, + method: "POST", + body: bytes.NewReader([]byte("query=test")), + headers: map[string]string{"Content-Type": "application/x-www-form-urlencoded"}, + expectedStatus: 200, + expectError: false, + expectedData: mockResponse, + }, + { + name: "HTTP client error", + endpoint: "events", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{err: errors.New("network error")}}, + }, + method: "GET", + headers: map[string]string{}, + expectError: true, + errorContains: "failed to complete request", + }, + { + name: "Invalid response JSON", + endpoint: "events", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: []byte("invalid json"), status: 200}}, + }, + method: "GET", + headers: map[string]string{}, + expectError: true, + errorContains: "failed to parse response", + }, + { + name: "Non-200 status code with valid JSON", + endpoint: "events", + dsInfo: &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: []byte("[]"), status: 500}}, + }, + method: "GET", + headers: map[string]string{}, + expectedStatus: 500, + expectError: false, + expectedData: []GraphiteEventsResponse{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + + // Create a service instance for the test + svc := &Service{logger: log.NewNullLogger()} + + // Create the HTTP request using the createRequest method + req, err := svc.createRequest(ctx, tt.dsInfo, URLParams{ + SubPath: tt.endpoint, + Method: tt.method, + Body: tt.body, + Headers: tt.headers, + }) + + if tt.expectError { + // For cases where we expect errors in request creation + if err != nil { + assert.Error(t, err) + if tt.errorContains != "" { + assert.Contains(t, err.Error(), tt.errorContains) + } + return + } + } else { + assert.NoError(t, err) + } + + result, status, err := doGraphiteRequest[[]GraphiteEventsResponse](ctx, tt.dsInfo, svc.logger, req) + + if tt.expectError { + assert.Error(t, err) + assert.Nil(t, result) + if tt.errorContains != "" { + assert.Contains(t, err.Error(), tt.errorContains) + } + } else { + assert.NoError(t, err) + assert.NotNil(t, result) + if tt.expectedStatus != 0 { + assert.Equal(t, tt.expectedStatus, status) + } + if tt.expectedData != nil { + assert.Equal(t, tt.expectedData, *result) + } + } + }) + } +} + +func TestDoGraphiteRequestGenericTypes(t *testing.T) { + // Test with GraphiteMetricsFindResponse + mockMetrics := []GraphiteMetricsFindResponse{ + {Text: "metric1", Id: "metric1.id", AllowChildren: 1, Expandable: 1, Leaf: 0}, + } + mockMetricsResp, _ := json.Marshal(mockMetrics) + + // Test with GraphiteMetricsExpandResponse + mockExpand := GraphiteMetricsExpandResponse{ + Results: []string{"app.grafana.metric1", "app.grafana.metric2"}, + } + mockExpandResp, _ := json.Marshal(mockExpand) + + tests := []struct { + name string + testFunc func(t *testing.T) + }{ + { + name: "Success with GraphiteMetricsFindResponse type", + testFunc: func(t *testing.T) { + dsInfo := &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockMetricsResp, status: 200}}, + } + ctx := context.Background() + + // Create a service instance for the test + svc := &Service{logger: log.NewNullLogger()} + + // Create the HTTP request using the createRequest method + req, err := svc.createRequest(ctx, dsInfo, URLParams{ + SubPath: "test", + Method: "GET", + }) + assert.NoError(t, err) + + result, status, err := doGraphiteRequest[[]GraphiteMetricsFindResponse](ctx, dsInfo, svc.logger, req) + + assert.NoError(t, err) + assert.NotNil(t, result) + assert.Equal(t, 200, status) + assert.Equal(t, mockMetrics, *result) + }, + }, + { + name: "Success with GraphiteMetricsExpandResponse type", + testFunc: func(t *testing.T) { + dsInfo := &datasourceInfo{ + Id: 1, + URL: "http://graphite.grafana", + HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: mockExpandResp, status: 200}}, + } + ctx := context.Background() + + // Create a service instance for the test + svc := &Service{logger: log.NewNullLogger()} + + // Create the HTTP request using the createRequest method + req, err := svc.createRequest(ctx, dsInfo, URLParams{ + SubPath: "test", + Method: "GET", + }) + assert.NoError(t, err) + + result, status, err := doGraphiteRequest[GraphiteMetricsExpandResponse](ctx, dsInfo, svc.logger, req) + + assert.NoError(t, err) + assert.NotNil(t, result) + assert.Equal(t, 200, status) + assert.Equal(t, mockExpand, *result) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, tt.testFunc) + } +} + +func TestParseRequestBody(t *testing.T) { + tests := []struct { + name string + requestBody []byte + expectError bool + errorContains string + expectedData GraphiteEventsRequest + }{ + { + name: "Valid JSON request", + requestBody: []byte(`{"from": "now-1h", "until": "now", "tags": "app.grafana"}`), + expectError: false, + expectedData: GraphiteEventsRequest{From: "now-1h", Until: "now", Tags: "app.grafana"}, + }, + { + name: "Empty JSON object", + requestBody: []byte(`{}`), + expectError: false, + expectedData: GraphiteEventsRequest{}, + }, + { + name: "Invalid JSON", + requestBody: []byte(`{"invalid": json}`), + expectError: true, + errorContains: "unexpected error", + }, + { + name: "Empty request body", + requestBody: []byte(``), + expectError: true, + errorContains: "unexpected error", + }, + { + name: "Malformed JSON", + requestBody: []byte(`{"from": "now-1h", "until": }`), + expectError: true, + errorContains: "unexpected error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + logger := log.NewNullLogger() + + result, err := parseRequestBody[GraphiteEventsRequest](tt.requestBody, logger) + + if tt.expectError { + assert.Error(t, err) + assert.Nil(t, result) + if tt.errorContains != "" { + assert.Contains(t, err.Error(), tt.errorContains) + } + } else { + assert.NoError(t, err) + assert.NotNil(t, result) + assert.Equal(t, tt.expectedData, *result) + } + }) + } +} + +func TestParseResponse(t *testing.T) { + mockEvents := []GraphiteEventsResponse{ + {When: 1234567890, What: "event1", Tags: []string{"tag1"}, Data: "data1"}, + {When: 1234567891, What: "event2", Tags: []string{"tag2"}, Data: "data2"}, + } + mockResp, _ := json.Marshal(mockEvents) + + tests := []struct { + name string + response *http.Response + expectError bool + errorContains string + expectedData []GraphiteEventsResponse + }{ + { + name: "Valid JSON response", + response: &http.Response{ + StatusCode: 200, + Body: io.NopCloser(bytes.NewBuffer(mockResp)), + Header: make(http.Header), + }, + expectError: false, + expectedData: mockEvents, + }, + { + name: "Empty JSON array", + response: &http.Response{ + StatusCode: 200, + Body: io.NopCloser(bytes.NewBuffer([]byte("[]"))), + Header: make(http.Header), + }, + expectError: false, + expectedData: []GraphiteEventsResponse{}, + }, + { + name: "Invalid JSON response", + response: &http.Response{ + StatusCode: 200, + Body: io.NopCloser(bytes.NewBuffer([]byte("invalid json"))), + Header: make(http.Header), + }, + expectError: true, + errorContains: "failed to unmarshal response", + }, + { + name: "Empty response body", + response: &http.Response{ + StatusCode: 200, + Body: io.NopCloser(bytes.NewBuffer([]byte(""))), + Header: make(http.Header), + }, + expectError: true, + errorContains: "failed to unmarshal response", + }, + { + name: "Malformed JSON response", + response: &http.Response{ + StatusCode: 200, + Body: io.NopCloser(bytes.NewBuffer([]byte(`[{"when": 123, "what": }]`))), + Header: make(http.Header), + }, + expectError: true, + errorContains: "failed to unmarshal response", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := parseResponse[[]GraphiteEventsResponse](tt.response) + + if tt.expectError { + assert.Error(t, err) + assert.Nil(t, result) + if tt.errorContains != "" { + assert.Contains(t, err.Error(), tt.errorContains) + } + } else { + assert.NoError(t, err) + assert.NotNil(t, result) + assert.Equal(t, tt.expectedData, *result) + } + }) + } +} diff --git a/pkg/tsdb/graphite/types.go b/pkg/tsdb/graphite/types.go index 8bc46177cf0..30d872f375a 100644 --- a/pkg/tsdb/graphite/types.go +++ b/pkg/tsdb/graphite/types.go @@ -1,5 +1,7 @@ package graphite +import "io" + type TargetResponseDTO struct { Target string `json:"target"` DataPoints DataTimeSeriesPoints `json:"datapoints"` @@ -10,6 +12,14 @@ type TargetResponseDTO struct { type DataTimePoint [2]Float type DataTimeSeriesPoints []DataTimePoint +type URLParams struct { + SubPath string + Method string + Body io.Reader + QueryParams map[string]string + Headers map[string]string +} + type GraphiteQuery struct { QueryType string `json:"queryType"` TextEditor *bool `json:"textEditor,omitempty"` @@ -45,3 +55,7 @@ type GraphiteMetricsFindResponse struct { Expandable int `json:"expandable"` Leaf int `json:"leaf"` } + +type GraphiteMetricsExpandResponse struct { + Results []string `json:"results"` +} diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts index 2a51d0107d6..7f04fa713af 100644 --- a/public/app/plugins/datasource/graphite/datasource.ts +++ b/public/app/plugins/datasource/graphite/datasource.ts @@ -704,8 +704,8 @@ export class GraphiteDatasource if (config.featureToggles.graphiteBackendMode) { return await this.postResource('metrics/find', { - from: typeof params.from === 'string' ? params.from : `${params.from}`, - until: typeof params.until === 'string' ? params.until : `${params.until}`, + from: params.from ? (typeof params.from === 'string' ? params.from : `${params.from}`) : undefined, + until: params.until ? (typeof params.until === 'string' ? params.until : `${params.until}`) : undefined, query, }); } @@ -741,7 +741,7 @@ export class GraphiteDatasource * The result will contain all metrics (with full name) matching provided query. * It's a more flexible version of /metrics/find endpoint (@see requestMetricFind) */ - private requestMetricExpand( + private async requestMetricExpand( query: string, requestId: string, range?: { from: string | number; until: string | number } @@ -752,6 +752,18 @@ export class GraphiteDatasource params.until = range.until; } + if (config.featureToggles.graphiteBackendMode) { + const metrics = await this.postResource('metrics/expand', { + from: params.from ? (typeof params.from === 'string' ? params.from : `${params.from}`) : undefined, + until: params.until ? (typeof params.until === 'string' ? params.until : `${params.until}`) : undefined, + query, + }); + return metrics.map((metric) => ({ + text: metric.text, + expandable: false, + })); + } + const httpOptions: BackendSrvRequest = { method: 'GET', url: '/metrics/expand', From cb7abbaa0f70888bc9c68f642e4cc78a91b90900 Mon Sep 17 00:00:00 2001 From: Moustafa Baiou Date: Fri, 12 Sep 2025 18:15:55 -0400 Subject: [PATCH 44/48] Alerting: Rename expression elements of Rules APIs (#110914) This renames `data` to `expressions` for clarity in the rules apis. Also makes certain fields that are redundant optional in the case of pure expressions, so that users don't have to specify them when they are not needed (e.g. not datasource queries). --- .../rules/definitions/alerting-manifest.yaml | 42 ++- .../alertrule.rules.alerting.grafana.app.yaml | 29 +- ...ordingrule.rules.alerting.grafana.app.yaml | 13 +- .../rules/kinds/v0alpha1/alertRule_spec.cue | 14 +- .../rules/kinds/v0alpha1/rule_spec.cue | 23 +- .../alerting/v0alpha1/alertrule_spec_gen.go | 76 +++-- .../v0alpha1/recordingrule_spec_gen.go | 62 ++-- .../apis/alerting/v0alpha1/zz_openapi_gen.go | 322 +++++++++--------- .../rules/pkg/apis/alerting_manifest.go | 4 +- .../alertrule/v0alpha1/types.spec.gen.ts | 76 +++-- .../recordingrule/v0alpha1/types.spec.gen.ts | 60 ++-- .../apps/alerting/rules/alertrule/compat.go | 74 ++-- .../alerting/rules/recordingrule/compat.go | 110 +++--- .../rules/alertrule/alertrule_test.go | 52 +-- .../alerting/rules/compat/alertrule_test.go | 30 +- .../rules/compat/recordingrule_test.go | 22 +- .../rules/recordingrule/recordingrule_test.go | 52 +-- .../rules.alerting.grafana.app-v0alpha1.json | 40 +-- .../clients/rules/v0alpha1/endpoints.gen.ts | 26 +- 19 files changed, 610 insertions(+), 517 deletions(-) diff --git a/apps/alerting/rules/definitions/alerting-manifest.yaml b/apps/alerting/rules/definitions/alerting-manifest.yaml index f842608a627..2c7b9374a66 100644 --- a/apps/alerting/rules/definitions/alerting-manifest.yaml +++ b/apps/alerting/rules/definitions/alerting-manifest.yaml @@ -19,14 +19,24 @@ spec: additionalProperties: type: string type: object - data: + execErrState: + default: Error + enum: + - Error + - Ok + - Alerting + - KeepLast + type: string + expressions: additionalProperties: properties: datasourceUID: + description: The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource pattern: ^[a-zA-Z0-9_-]+$ type: string model: {} queryType: + description: The type of query if this is a query expression type: string relativeTimeRange: properties: @@ -41,21 +51,16 @@ spec: - to type: object source: + description: |- + Used to mark the expression to be used as the final source for the rule evaluation + Only one expression in a rule can be marked as the source + For AlertRules, this is the expression that will be evaluated against the alerting condition + For RecordingRules, this is the expression that will be recorded type: boolean required: - - queryType - - datasourceUID - model type: object type: object - execErrState: - default: Error - enum: - - Error - - Ok - - Alerting - - KeepLast - type: string for: allOf: - pattern: ^((([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?|0)$ @@ -151,10 +156,10 @@ spec: type: object required: - title - - data - trigger - noDataState - execErrState + - expressions type: object x-kubernetes-preserve-unknown-fields: true status: @@ -207,14 +212,16 @@ spec: schema: spec: properties: - data: + expressions: additionalProperties: properties: datasourceUID: + description: The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource pattern: ^[a-zA-Z0-9_-]+$ type: string model: {} queryType: + description: The type of query if this is a query expression type: string relativeTimeRange: properties: @@ -229,10 +236,13 @@ spec: - to type: object source: + description: |- + Used to mark the expression to be used as the final source for the rule evaluation + Only one expression in a rule can be marked as the source + For AlertRules, this is the expression that will be evaluated against the alerting condition + For RecordingRules, this is the expression that will be recorded type: boolean required: - - queryType - - datasourceUID - model type: object type: object @@ -263,9 +273,9 @@ spec: type: object required: - title - - data - trigger - metric + - expressions - targetDatasourceUID type: object x-kubernetes-preserve-unknown-fields: true diff --git a/apps/alerting/rules/definitions/alertrule.rules.alerting.grafana.app.yaml b/apps/alerting/rules/definitions/alertrule.rules.alerting.grafana.app.yaml index e7d9ab25aaa..e5fdfc57e5e 100644 --- a/apps/alerting/rules/definitions/alertrule.rules.alerting.grafana.app.yaml +++ b/apps/alerting/rules/definitions/alertrule.rules.alerting.grafana.app.yaml @@ -17,14 +17,24 @@ spec: additionalProperties: type: string type: object - data: + execErrState: + default: Error + enum: + - Error + - Ok + - Alerting + - KeepLast + type: string + expressions: additionalProperties: properties: datasourceUID: + description: The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource pattern: ^[a-zA-Z0-9_-]+$ type: string model: {} queryType: + description: The type of query if this is a query expression type: string relativeTimeRange: properties: @@ -39,21 +49,16 @@ spec: - to type: object source: + description: |- + Used to mark the expression to be used as the final source for the rule evaluation + Only one expression in a rule can be marked as the source + For AlertRules, this is the expression that will be evaluated against the alerting condition + For RecordingRules, this is the expression that will be recorded type: boolean required: - - queryType - - datasourceUID - model type: object type: object - execErrState: - default: Error - enum: - - Error - - Ok - - Alerting - - KeepLast - type: string for: allOf: - pattern: ^((([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?|0)$ @@ -149,10 +154,10 @@ spec: type: object required: - title - - data - trigger - noDataState - execErrState + - expressions type: object x-kubernetes-preserve-unknown-fields: true status: diff --git a/apps/alerting/rules/definitions/recordingrule.rules.alerting.grafana.app.yaml b/apps/alerting/rules/definitions/recordingrule.rules.alerting.grafana.app.yaml index b12bdf781f9..368bc5893c0 100644 --- a/apps/alerting/rules/definitions/recordingrule.rules.alerting.grafana.app.yaml +++ b/apps/alerting/rules/definitions/recordingrule.rules.alerting.grafana.app.yaml @@ -13,14 +13,16 @@ spec: properties: spec: properties: - data: + expressions: additionalProperties: properties: datasourceUID: + description: The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource pattern: ^[a-zA-Z0-9_-]+$ type: string model: {} queryType: + description: The type of query if this is a query expression type: string relativeTimeRange: properties: @@ -35,10 +37,13 @@ spec: - to type: object source: + description: |- + Used to mark the expression to be used as the final source for the rule evaluation + Only one expression in a rule can be marked as the source + For AlertRules, this is the expression that will be evaluated against the alerting condition + For RecordingRules, this is the expression that will be recorded type: boolean required: - - queryType - - datasourceUID - model type: object type: object @@ -69,9 +74,9 @@ spec: type: object required: - title - - data - trigger - metric + - expressions - targetDatasourceUID type: object x-kubernetes-preserve-unknown-fields: true diff --git a/apps/alerting/rules/kinds/v0alpha1/alertRule_spec.cue b/apps/alerting/rules/kinds/v0alpha1/alertRule_spec.cue index 0d074d28e6f..140005fe1d6 100644 --- a/apps/alerting/rules/kinds/v0alpha1/alertRule_spec.cue +++ b/apps/alerting/rules/kinds/v0alpha1/alertRule_spec.cue @@ -10,16 +10,16 @@ ExecErrState: *"Error" | "Ok" | "Alerting" | "KeepLast" // FIXME: the For and KeepFiringFor types should be using the AlertRulePromDuration type, but there seems to be an issue with the generator AlertRuleSpec: #RuleSpec & { - noDataState: NoDataState - execErrState: ExecErrState - "for"?: string & #PromDuration - keepFiringFor?: string & #PromDuration - missingSeriesEvalsToResolve?: int & >=0 - notificationSettings?: #NotificationSettings annotations?: { [string]: TemplateString } - panelRef?: #PanelRef + "for"?: string & #PromDuration + keepFiringFor?: string & #PromDuration + missingSeriesEvalsToResolve?: int & >=0 + noDataState: NoDataState + execErrState: ExecErrState + notificationSettings?: #NotificationSettings + panelRef?: #PanelRef } #PanelRef: { diff --git a/apps/alerting/rules/kinds/v0alpha1/rule_spec.cue b/apps/alerting/rules/kinds/v0alpha1/rule_spec.cue index 11c45d3b8fb..7b8cf55e734 100644 --- a/apps/alerting/rules/kinds/v0alpha1/rule_spec.cue +++ b/apps/alerting/rules/kinds/v0alpha1/rule_spec.cue @@ -12,12 +12,12 @@ TemplateString: string #RuleSpec: { title: string - data: #QueryMap paused?: bool trigger: #IntervalTrigger labels?: { [string]: TemplateString } + expressions: #ExpressionMap ... } @@ -34,15 +34,20 @@ TemplateString: string } // TODO: validate that only one can specify source=true -#QueryMap: { - [string]: #Query +#ExpressionMap: { + [string]: #Expression } // & struct.MinFields(1) This doesn't work in Cue ({ + interval: defaultPromDuration(), +}); + +export type PromDuration = string; + +export const defaultPromDuration = (): PromDuration => (""); + +export type TemplateString = string; + +export const defaultTemplateString = (): TemplateString => (""); + +// TODO(@moustafab): validate regex for time interval ref +export type TimeIntervalRef = string; + +export const defaultTimeIntervalRef = (): TimeIntervalRef => (""); + // TODO: validate that only one can specify source=true // & struct.MinFields(1) This doesn't work in Cue ; +export type ExpressionMap = Record; -export const defaultQueryMap = (): QueryMap => ({}); +export const defaultExpressionMap = (): ExpressionMap => ({}); -// TODO: come up with a better name for this. We have expression type things and data source queries -export interface Query { - // TODO: consider making this optional, with the nil value meaning "__expr__" (i.e. expression query) - queryType: string; +export interface Expression { + // The type of query if this is a query expression + queryType?: string; relativeTimeRange?: RelativeTimeRange; - datasourceUID: DatasourceUID; + // The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource + datasourceUID?: DatasourceUID; model: any; + // Used to mark the expression to be used as the final source for the rule evaluation + // Only one expression in a rule can be marked as the source + // For AlertRules, this is the expression that will be evaluated against the alerting condition + // For RecordingRules, this is the expression that will be recorded source?: boolean; } -export const defaultQuery = (): Query => ({ - queryType: "", - datasourceUID: defaultDatasourceUID(), +export const defaultExpression = (): Expression => ({ model: {}, }); @@ -40,37 +63,17 @@ export type DatasourceUID = string; export const defaultDatasourceUID = (): DatasourceUID => (""); -export interface IntervalTrigger { - interval: PromDuration; -} - -export const defaultIntervalTrigger = (): IntervalTrigger => ({ - interval: defaultPromDuration(), -}); - -export type PromDuration = string; - -export const defaultPromDuration = (): PromDuration => (""); - -// TODO(@moustafab): validate regex for time interval ref -export type TimeIntervalRef = string; - -export const defaultTimeIntervalRef = (): TimeIntervalRef => (""); - -export type TemplateString = string; - -export const defaultTemplateString = (): TemplateString => (""); - export interface Spec { title: string; - data: QueryMap; paused?: boolean; trigger: IntervalTrigger; - noDataState: string; - execErrState: string; + labels?: Record; + annotations?: Record; for?: string; keepFiringFor?: string; missingSeriesEvalsToResolve?: number; + noDataState: string; + execErrState: string; notificationSettings?: { receiver: string; groupBy?: string[]; @@ -80,8 +83,7 @@ export interface Spec { muteTimeIntervals?: TimeIntervalRef[]; activeTimeIntervals?: TimeIntervalRef[]; }; - annotations?: Record; - labels?: Record; + expressions: ExpressionMap; panelRef?: { dashboardUID: string; panelID: number; @@ -90,9 +92,9 @@ export interface Spec { export const defaultSpec = (): Spec => ({ title: "", - data: defaultQueryMap(), trigger: defaultIntervalTrigger(), noDataState: "NoData", execErrState: "Error", + expressions: defaultExpressionMap(), }); diff --git a/apps/alerting/rules/plugin/src/generated/recordingrule/v0alpha1/types.spec.gen.ts b/apps/alerting/rules/plugin/src/generated/recordingrule/v0alpha1/types.spec.gen.ts index f9944c8b4d7..fc8923debe6 100644 --- a/apps/alerting/rules/plugin/src/generated/recordingrule/v0alpha1/types.spec.gen.ts +++ b/apps/alerting/rules/plugin/src/generated/recordingrule/v0alpha1/types.spec.gen.ts @@ -1,24 +1,42 @@ // Code generated - EDITING IS FUTILE. DO NOT EDIT. +export interface IntervalTrigger { + interval: PromDuration; +} + +export const defaultIntervalTrigger = (): IntervalTrigger => ({ + interval: defaultPromDuration(), +}); + +export type PromDuration = string; + +export const defaultPromDuration = (): PromDuration => (""); + +export type TemplateString = string; + +export const defaultTemplateString = (): TemplateString => (""); + // TODO: validate that only one can specify source=true // & struct.MinFields(1) This doesn't work in Cue ; +export type ExpressionMap = Record; -export const defaultQueryMap = (): QueryMap => ({}); +export const defaultExpressionMap = (): ExpressionMap => ({}); -// TODO: come up with a better name for this. We have expression type things and data source queries -export interface Query { - // TODO: consider making this optional, with the nil value meaning "__expr__" (i.e. expression query) - queryType: string; +export interface Expression { + // The type of query if this is a query expression + queryType?: string; relativeTimeRange?: RelativeTimeRange; - datasourceUID: DatasourceUID; + // The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource + datasourceUID?: DatasourceUID; model: any; + // Used to mark the expression to be used as the final source for the rule evaluation + // Only one expression in a rule can be marked as the source + // For AlertRules, this is the expression that will be evaluated against the alerting condition + // For RecordingRules, this is the expression that will be recorded source?: boolean; } -export const defaultQuery = (): Query => ({ - queryType: "", - datasourceUID: defaultDatasourceUID(), +export const defaultExpression = (): Expression => ({ model: {}, }); @@ -40,37 +58,21 @@ export type DatasourceUID = string; export const defaultDatasourceUID = (): DatasourceUID => (""); -export interface IntervalTrigger { - interval: PromDuration; -} - -export const defaultIntervalTrigger = (): IntervalTrigger => ({ - interval: defaultPromDuration(), -}); - -export type PromDuration = string; - -export const defaultPromDuration = (): PromDuration => (""); - -export type TemplateString = string; - -export const defaultTemplateString = (): TemplateString => (""); - export interface Spec { title: string; - data: QueryMap; paused?: boolean; trigger: IntervalTrigger; - metric: string; labels?: Record; + metric: string; + expressions: ExpressionMap; targetDatasourceUID: string; } export const defaultSpec = (): Spec => ({ title: "", - data: defaultQueryMap(), trigger: defaultIntervalTrigger(), metric: "", + expressions: defaultExpressionMap(), targetDatasourceUID: "", }); diff --git a/pkg/registry/apps/alerting/rules/alertrule/compat.go b/pkg/registry/apps/alerting/rules/alertrule/compat.go index fbbb2be73d7..0ea9507c6e0 100644 --- a/pkg/registry/apps/alerting/rules/alertrule/compat.go +++ b/pkg/registry/apps/alerting/rules/alertrule/compat.go @@ -8,6 +8,7 @@ import ( "time" "github.com/grafana/grafana/pkg/apimachinery/utils" + "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/util" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -43,8 +44,8 @@ func convertToK8sResource( Labels: make(map[string]string), }, Spec: model.AlertRuleSpec{ - Title: rule.Title, - Data: make(map[string]model.AlertRuleQuery), + Title: rule.Title, + Expressions: make(model.AlertRuleExpressionMap), Trigger: model.AlertRuleIntervalTrigger{ Interval: model.AlertRulePromDuration(interval.String()), }, @@ -90,19 +91,7 @@ func convertToK8sResource( } for _, query := range rule.Data { - k8sQuery := model.AlertRuleQuery{ - QueryType: query.QueryType, - Model: query.Model, - DatasourceUID: model.AlertRuleDatasourceUID(query.DatasourceUID), - Source: util.Pointer(rule.Condition == query.RefID), - } - if time.Duration(query.RelativeTimeRange.From) > 0 || time.Duration(query.RelativeTimeRange.To) > 0 { - k8sQuery.RelativeTimeRange = &model.AlertRuleRelativeTimeRange{ - From: model.AlertRulePromDurationWMillis(query.RelativeTimeRange.From.String()), - To: model.AlertRulePromDurationWMillis(query.RelativeTimeRange.To.String()), - } - } - k8sRule.Spec.Data[query.RefID] = k8sQuery + k8sRule.Spec.Expressions[query.RefID] = convertToK8sExpression(query, rule) } for _, setting := range rule.NotificationSettings { @@ -158,6 +147,29 @@ func convertToK8sResource( return k8sRule, nil } +func convertToK8sExpression(query ngmodels.AlertQuery, rule *ngmodels.AlertRule) model.AlertRuleExpression { + expression := model.AlertRuleExpression{ + Model: query.Model, + } + if query.QueryType != "" { + expression.QueryType = util.Pointer(query.QueryType) + } + // DatasourceUID is optional and defaults to expr datasource + if !expr.IsDataSource(query.DatasourceUID) { + expression.DatasourceUID = util.Pointer(model.AlertRuleDatasourceUID(query.DatasourceUID)) + } + if time.Duration(query.RelativeTimeRange.From) > 0 || time.Duration(query.RelativeTimeRange.To) > 0 { + expression.RelativeTimeRange = &model.AlertRuleRelativeTimeRange{ + From: model.AlertRulePromDurationWMillis(query.RelativeTimeRange.From.String()), + To: model.AlertRulePromDurationWMillis(query.RelativeTimeRange.To.String()), + } + } + if rule.Condition == query.RefID { + expression.Source = util.Pointer(true) + } + return expression +} + func convertToK8sResources( orgID int64, rules []*ngmodels.AlertRule, @@ -201,7 +213,7 @@ func convertToBaseDomainModel(orgID int64, k8sRule *model.AlertRule) (*ngmodels. UID: k8sRule.Name, Title: k8sRule.Spec.Title, NamespaceUID: k8sRule.Namespace, - Data: make([]ngmodels.AlertQuery, 0, len(k8sRule.Spec.Data)), + Data: make([]ngmodels.AlertQuery, 0, len(k8sRule.Spec.Expressions)), IsPaused: k8sRule.Spec.Paused != nil && *k8sRule.Spec.Paused, Labels: make(map[string]string), Annotations: make(map[string]string), @@ -267,13 +279,13 @@ func convertToBaseDomainModel(orgID int64, k8sRule *model.AlertRule) (*ngmodels. } domainRule.IntervalSeconds = int64(time.Duration(interval).Seconds()) - for refID, query := range k8sRule.Spec.Data { - domainQuery, err := convertToDomainQuery(query, refID) + for refID, expression := range k8sRule.Spec.Expressions { + domainQuery, err := convertToDomainQuery(expression, refID) if err != nil { return nil, err } domainRule.Data = append(domainRule.Data, domainQuery) - if query.Source != nil && *query.Source { + if expression.Source != nil && *expression.Source { if domainRule.Condition != "" { return nil, fmt.Errorf("multiple queries marked as source: %s and %s", domainRule.Condition, refID) } @@ -339,23 +351,29 @@ func convertNotificationSettings(sourceSettings *model.AlertRuleV0alpha1SpecNoti return settings, nil } -func convertToDomainQuery(query model.AlertRuleQuery, refID string) (ngmodels.AlertQuery, error) { - modelJson, err := json.Marshal(query.Model) +func convertToDomainQuery(expression model.AlertRuleExpression, refID string) (ngmodels.AlertQuery, error) { + modelJson, err := json.Marshal(expression.Model) if err != nil { return ngmodels.AlertQuery{}, fmt.Errorf("failed to marshal model: %w", err) } domainQuery := ngmodels.AlertQuery{ - RefID: refID, - QueryType: query.QueryType, - DatasourceUID: string(query.DatasourceUID), - Model: modelJson, + RefID: refID, + Model: modelJson, } - if query.RelativeTimeRange != nil { - from, err := prom_model.ParseDuration(string(query.RelativeTimeRange.From)) + if expression.QueryType != nil { + domainQuery.QueryType = *expression.QueryType + } + if expression.DatasourceUID != nil { + domainQuery.DatasourceUID = string(*expression.DatasourceUID) + } else { + domainQuery.DatasourceUID = expr.DatasourceUID + } + if expression.RelativeTimeRange != nil { + from, err := prom_model.ParseDuration(string(expression.RelativeTimeRange.From)) if err != nil { return ngmodels.AlertQuery{}, fmt.Errorf("failed to parse duration: %w", err) } - to, err := prom_model.ParseDuration(string(query.RelativeTimeRange.To)) + to, err := prom_model.ParseDuration(string(expression.RelativeTimeRange.To)) if err != nil { return ngmodels.AlertQuery{}, fmt.Errorf("failed to parse duration: %w", err) } diff --git a/pkg/registry/apps/alerting/rules/recordingrule/compat.go b/pkg/registry/apps/alerting/rules/recordingrule/compat.go index f4479a41d48..e9ef0c4e295 100644 --- a/pkg/registry/apps/alerting/rules/recordingrule/compat.go +++ b/pkg/registry/apps/alerting/rules/recordingrule/compat.go @@ -9,6 +9,7 @@ import ( model "github.com/grafana/grafana/apps/alerting/rules/pkg/apis/alerting/v0alpha1" "github.com/grafana/grafana/pkg/apimachinery/utils" + "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" @@ -42,8 +43,8 @@ func convertToK8sResource( Labels: make(map[string]string), }, Spec: model.RecordingRuleSpec{ - Title: rule.Title, - Data: make(map[string]model.RecordingRuleQuery), + Title: rule.Title, + Expressions: make(model.RecordingRuleExpressionMap), Trigger: model.RecordingRuleIntervalTrigger{ Interval: model.RecordingRulePromDuration(interval.String()), }, @@ -67,21 +68,7 @@ func convertToK8sResource( } for _, query := range rule.Data { - k8sQuery := model.RecordingRuleQuery{ - QueryType: query.QueryType, - Model: query.Model, - DatasourceUID: model.RecordingRuleDatasourceUID(query.DatasourceUID), - } - if time.Duration(query.RelativeTimeRange.From) > 0 || time.Duration(query.RelativeTimeRange.To) > 0 { - k8sQuery.RelativeTimeRange = &model.RecordingRuleRelativeTimeRange{ - From: model.RecordingRulePromDurationWMillis(query.RelativeTimeRange.From.String()), - To: model.RecordingRulePromDurationWMillis(query.RelativeTimeRange.To.String()), - } - } - if rule.Record != nil && rule.Record.From == query.RefID { - k8sQuery.Source = util.Pointer(true) - } - k8sRule.Spec.Data[query.RefID] = k8sQuery + k8sRule.Spec.Expressions[query.RefID] = convertToK8sExpression(query, rule) } meta, err := utils.MetaAccessor(k8sRule) @@ -108,6 +95,29 @@ func convertToK8sResource( return k8sRule, nil } +func convertToK8sExpression(query ngmodels.AlertQuery, rule *ngmodels.AlertRule) model.RecordingRuleExpression { + expression := model.RecordingRuleExpression{ + Model: query.Model, + } + if query.QueryType != "" { + expression.QueryType = util.Pointer(query.QueryType) + } + // DatasourceUID is optional and defaults to expr datasource + if !expr.IsDataSource(query.DatasourceUID) { + expression.DatasourceUID = util.Pointer(model.RecordingRuleDatasourceUID(query.DatasourceUID)) + } + if time.Duration(query.RelativeTimeRange.From) > 0 || time.Duration(query.RelativeTimeRange.To) > 0 { + expression.RelativeTimeRange = &model.RecordingRuleRelativeTimeRange{ + From: model.RecordingRulePromDurationWMillis(query.RelativeTimeRange.From.String()), + To: model.RecordingRulePromDurationWMillis(query.RelativeTimeRange.To.String()), + } + } + if rule.Record != nil && rule.Record.From == query.RefID { + expression.Source = util.Pointer(true) + } + return expression +} + func convertToK8sResources( orgID int64, rules []*ngmodels.AlertRule, @@ -150,7 +160,7 @@ func convertToBaseDomainModel(orgID int64, k8sRule *model.RecordingRule) (*ngmod OrgID: orgID, UID: k8sRule.Name, Title: k8sRule.Spec.Title, - Data: make([]ngmodels.AlertQuery, 0, len(k8sRule.Spec.Data)), + Data: make([]ngmodels.AlertQuery, 0, len(k8sRule.Spec.Expressions)), IsPaused: k8sRule.Spec.Paused != nil && *k8sRule.Spec.Paused, Labels: make(map[string]string), @@ -187,35 +197,13 @@ func convertToBaseDomainModel(orgID int64, k8sRule *model.RecordingRule) (*ngmod for k, v := range k8sRule.Spec.Labels { domainRule.Labels[k] = string(v) } - for refID, query := range k8sRule.Spec.Data { - modelJson, err := json.Marshal(query.Model) + for refID, expression := range k8sRule.Spec.Expressions { + domainQuery, err := convertToDomainQuery(expression, refID) if err != nil { - return nil, fmt.Errorf("failed to marshal model: %w", err) + return nil, err } - domainQuery := ngmodels.AlertQuery{ - RefID: refID, - QueryType: query.QueryType, - DatasourceUID: string(query.DatasourceUID), - Model: modelJson, - } - if query.RelativeTimeRange != nil { - from, err := prom_model.ParseDuration(string(query.RelativeTimeRange.From)) - if err != nil { - return nil, fmt.Errorf("failed to parse duration: %w", err) - } - to, err := prom_model.ParseDuration(string(query.RelativeTimeRange.To)) - if err != nil { - return nil, fmt.Errorf("failed to parse duration: %w", err) - } - domainQuery.RelativeTimeRange = ngmodels.RelativeTimeRange{ - From: ngmodels.Duration(from), - To: ngmodels.Duration(to), - } - } - domainRule.Data = append(domainRule.Data, domainQuery) - - if query.Source != nil && *query.Source { + if expression.Source != nil && *expression.Source { if domainRule.Record.From != "" { return nil, fmt.Errorf("multiple queries marked as source: %s and %s", domainRule.Record.From, refID) } @@ -227,3 +215,37 @@ func convertToBaseDomainModel(orgID int64, k8sRule *model.RecordingRule) (*ngmod } return domainRule, nil } + +func convertToDomainQuery(expression model.RecordingRuleExpression, refID string) (ngmodels.AlertQuery, error) { + modelJson, err := json.Marshal(expression.Model) + if err != nil { + return ngmodels.AlertQuery{}, fmt.Errorf("failed to marshal model: %w", err) + } + domainQuery := ngmodels.AlertQuery{ + RefID: refID, + Model: modelJson, + } + if expression.QueryType != nil { + domainQuery.QueryType = *expression.QueryType + } + if expression.DatasourceUID != nil { + domainQuery.DatasourceUID = string(*expression.DatasourceUID) + } else { + domainQuery.DatasourceUID = expr.DatasourceUID + } + if expression.RelativeTimeRange != nil { + from, err := prom_model.ParseDuration(string(expression.RelativeTimeRange.From)) + if err != nil { + return ngmodels.AlertQuery{}, fmt.Errorf("failed to parse duration: %w", err) + } + to, err := prom_model.ParseDuration(string(expression.RelativeTimeRange.To)) + if err != nil { + return ngmodels.AlertQuery{}, fmt.Errorf("failed to parse duration: %w", err) + } + domainQuery.RelativeTimeRange = ngmodels.RelativeTimeRange{ + From: ngmodels.Duration(from), + To: ngmodels.Duration(to), + } + } + return domainQuery, nil +} diff --git a/pkg/tests/apis/alerting/rules/alertrule/alertrule_test.go b/pkg/tests/apis/alerting/rules/alertrule/alertrule_test.go index 9daedc259ae..5d4a8b67497 100644 --- a/pkg/tests/apis/alerting/rules/alertrule/alertrule_test.go +++ b/pkg/tests/apis/alerting/rules/alertrule/alertrule_test.go @@ -54,10 +54,10 @@ func TestIntegrationResourceIdentifier(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer("query"), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ @@ -154,10 +154,10 @@ func TestIntegrationAccessControl(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ @@ -241,10 +241,10 @@ func TestIntegrationCRUD(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ @@ -295,10 +295,10 @@ func TestIntegrationCRUD(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ @@ -328,8 +328,8 @@ func TestIntegrationCRUD(t *testing.T) { }, }, Spec: v0alpha1.AlertRuleSpec{ - Title: "invalid-rule", - Data: map[string]v0alpha1.AlertRuleQuery{}, // Empty data should fail + Title: "invalid-rule", + Expressions: v0alpha1.AlertRuleExpressionMap{}, // Empty data should fail Trigger: v0alpha1.AlertRuleIntervalTrigger{ Interval: "30", }, @@ -356,10 +356,10 @@ func TestIntegrationCRUD(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ @@ -408,10 +408,10 @@ func TestIntegrationCRUD(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ From: v0alpha1.AlertRulePromDurationWMillis("5m"), @@ -445,10 +445,10 @@ func TestIntegrationCRUD(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ @@ -501,10 +501,10 @@ func TestIntegrationPatch(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ diff --git a/pkg/tests/apis/alerting/rules/compat/alertrule_test.go b/pkg/tests/apis/alerting/rules/compat/alertrule_test.go index d5339bdf7c7..4eb2cc39b52 100644 --- a/pkg/tests/apis/alerting/rules/compat/alertrule_test.go +++ b/pkg/tests/apis/alerting/rules/compat/alertrule_test.go @@ -57,10 +57,10 @@ func TestIntegrationAlertRuleCompatCreateViaK8s(t *testing.T) { }, Spec: v0alpha1.AlertRuleSpec{ Title: rule.Title, - Data: map[string]v0alpha1.AlertRuleQuery{ + Expressions: v0alpha1.AlertRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.AlertRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.AlertRuleRelativeTimeRange{ @@ -91,9 +91,9 @@ func TestIntegrationAlertRuleCompatCreateViaK8s(t *testing.T) { err := json.Unmarshal(retrievedRule.Data[0].Model, &model) require.NoError(t, err) require.NotNil(t, model) - expectedModel, ok := created.Spec.Data["A"].Model.(map[string]interface{}) + expectedModel, ok := created.Spec.Expressions["A"].Model.(map[string]interface{}) if !ok { - t.Fatalf("Expected model to be a map[string]interface{}, got %T", created.Spec.Data["A"].Model) + t.Fatalf("Expected model to be a map[string]interface{}, got %T", created.Spec.Expressions["A"].Model) } for k, v := range expectedModel { require.EqualValues(t, v, model[k], "Model field %s should match", k) @@ -230,13 +230,13 @@ func TestIntegrationAlertRuleCompatCreateViaProvisioning(t *testing.T) { require.NoError(t, err) require.NotNil(t, retrievedRule) require.Equal(t, r.Title, retrievedRule.Spec.Title) - require.NotNil(t, retrievedRule.Spec.Data[r.Data[0].RefID].Source) - require.True(t, *retrievedRule.Spec.Data[r.Data[0].RefID].Source) + require.NotNil(t, retrievedRule.Spec.Expressions[r.Data[0].RefID].Source) + require.True(t, *retrievedRule.Spec.Expressions[r.Data[0].RefID].Source) require.Equal(t, r.FolderUID, retrievedRule.Annotations["grafana.app/folder"]) require.Equal(t, created.Title, retrievedRule.Labels[v0alpha1.GroupLabelKey]) require.Equal(t, fmt.Sprintf("%d", i), retrievedRule.Labels[v0alpha1.GroupIndexLabelKey]) require.Equal(t, ngmodels.ProvenanceAPI, ngmodels.Provenance(retrievedRule.GetProvenanceStatus())) - require.EqualValues(t, r.Data[0].DatasourceUID, retrievedRule.Spec.Data["A"].DatasourceUID) + require.EqualValues(t, r.Data[0].DatasourceUID, *retrievedRule.Spec.Expressions["A"].DatasourceUID) expectedDuration, err := prom_model.ParseDuration(fmt.Sprintf("%ds", created.Interval)) require.NoError(t, err) require.Equal(t, expectedDuration.String(), string(retrievedRule.Spec.Trigger.Interval)) @@ -244,9 +244,9 @@ func TestIntegrationAlertRuleCompatCreateViaProvisioning(t *testing.T) { err = json.Unmarshal(r.Data[0].Model, &expectedModel) require.NoError(t, err) require.NotNil(t, expectedModel) - retrievedModel, ok := retrievedRule.Spec.Data["A"].Model.(map[string]interface{}) + retrievedModel, ok := retrievedRule.Spec.Expressions["A"].Model.(map[string]interface{}) if !ok { - t.Fatalf("Expected model to be a map[string]interface{}, got %T", retrievedRule.Spec.Data["A"].Model) + t.Fatalf("Expected model to be a map[string]interface{}, got %T", retrievedRule.Spec.Expressions["A"].Model) } for k, v := range expectedModel { require.EqualValues(t, v, retrievedModel[k], "Model field %s should match", k) @@ -372,13 +372,13 @@ func TestIntegrationAlertRuleCompatCreateViaProvisioningChangeGroupInK8s(t *test require.NoError(t, err) require.NotNil(t, retrievedRule) require.Equal(t, r.Title, retrievedRule.Spec.Title) - require.NotNil(t, retrievedRule.Spec.Data[r.Data[0].RefID].Source) - require.True(t, *retrievedRule.Spec.Data[r.Data[0].RefID].Source) + require.NotNil(t, retrievedRule.Spec.Expressions[r.Data[0].RefID].Source) + require.True(t, *retrievedRule.Spec.Expressions[r.Data[0].RefID].Source) require.Equal(t, r.FolderUID, retrievedRule.Annotations["grafana.app/folder"]) require.Equal(t, created.Title, retrievedRule.Labels[v0alpha1.GroupLabelKey]) require.Equal(t, fmt.Sprintf("%d", i), retrievedRule.Labels[v0alpha1.GroupIndexLabelKey]) require.Equal(t, ngmodels.ProvenanceAPI, ngmodels.Provenance(retrievedRule.GetProvenanceStatus())) - require.EqualValues(t, r.Data[0].DatasourceUID, retrievedRule.Spec.Data["X"].DatasourceUID) + require.EqualValues(t, r.Data[0].DatasourceUID, *retrievedRule.Spec.Expressions["X"].DatasourceUID) expectedDuration, err := prom_model.ParseDuration(fmt.Sprintf("%ds", created.Interval)) require.NoError(t, err) require.Equal(t, expectedDuration.String(), string(retrievedRule.Spec.Trigger.Interval)) @@ -386,9 +386,9 @@ func TestIntegrationAlertRuleCompatCreateViaProvisioningChangeGroupInK8s(t *test err = json.Unmarshal(r.Data[0].Model, &expectedModel) require.NoError(t, err) require.NotNil(t, expectedModel) - retrievedModel, ok := retrievedRule.Spec.Data["X"].Model.(map[string]interface{}) + retrievedModel, ok := retrievedRule.Spec.Expressions["X"].Model.(map[string]interface{}) if !ok { - t.Fatalf("Expected model to be a map[string]interface{}, got %T", retrievedRule.Spec.Data["X"].Model) + t.Fatalf("Expected model to be a map[string]interface{}, got %T", retrievedRule.Spec.Expressions["X"].Model) } for k, v := range expectedModel { require.EqualValues(t, v, retrievedModel[k], "Model field %s should match", k) diff --git a/pkg/tests/apis/alerting/rules/compat/recordingrule_test.go b/pkg/tests/apis/alerting/rules/compat/recordingrule_test.go index a254901c72f..25f4dbf243b 100644 --- a/pkg/tests/apis/alerting/rules/compat/recordingrule_test.go +++ b/pkg/tests/apis/alerting/rules/compat/recordingrule_test.go @@ -64,10 +64,10 @@ func TestIntegrationRecordingRuleCompatCreateViaK8s(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ @@ -98,9 +98,9 @@ func TestIntegrationRecordingRuleCompatCreateViaK8s(t *testing.T) { err := json.Unmarshal(retrievedRule.Data[0].Model, &model) require.NoError(t, err) require.NotNil(t, model) - expectedModel, ok := created.Spec.Data["A"].Model.(map[string]interface{}) + expectedModel, ok := created.Spec.Expressions["A"].Model.(map[string]interface{}) if !ok { - t.Fatalf("Expected model to be a map[string]interface{}, got %T", created.Spec.Data["A"].Model) + t.Fatalf("Expected model to be a map[string]interface{}, got %T", created.Spec.Expressions["A"].Model) } for k, v := range expectedModel { require.EqualValues(t, v, model[k], "Model field %s should match", k) @@ -247,7 +247,7 @@ func TestIntegrationRecordingRuleCompatCreateViaProvisioning(t *testing.T) { require.Equal(t, created.Title, retrievedRule.Labels[v0alpha1.GroupLabelKey]) require.Equal(t, fmt.Sprintf("%d", i), retrievedRule.Labels[v0alpha1.GroupIndexLabelKey]) require.Equal(t, ngmodels.ProvenanceAPI, ngmodels.Provenance(retrievedRule.GetProvenanceStatus())) - require.EqualValues(t, r.Data[0].DatasourceUID, retrievedRule.Spec.Data["A"].DatasourceUID) + require.EqualValues(t, r.Data[0].DatasourceUID, *retrievedRule.Spec.Expressions["A"].DatasourceUID) expectedDuration, err := prom_model.ParseDuration(fmt.Sprintf("%ds", created.Interval)) require.NoError(t, err) require.Equal(t, expectedDuration.String(), string(retrievedRule.Spec.Trigger.Interval)) @@ -255,9 +255,9 @@ func TestIntegrationRecordingRuleCompatCreateViaProvisioning(t *testing.T) { err = json.Unmarshal(r.Data[0].Model, &expectedModel) require.NoError(t, err) require.NotNil(t, expectedModel) - retrievedModel, ok := retrievedRule.Spec.Data["A"].Model.(map[string]interface{}) + retrievedModel, ok := retrievedRule.Spec.Expressions["A"].Model.(map[string]interface{}) if !ok { - t.Fatalf("Expected model to be a map[string]interface{}, got %T", retrievedRule.Spec.Data["A"].Model) + t.Fatalf("Expected model to be a map[string]interface{}, got %T", retrievedRule.Spec.Expressions["A"].Model) } for k, v := range expectedModel { require.EqualValues(t, v, retrievedModel[k], "Model field %s should match", k) @@ -391,7 +391,7 @@ func TestIntegrationRecordingRuleCompatCreateViaProvisioningChangeGroupInK8s(t * require.Equal(t, created.Title, retrievedRule.Labels[v0alpha1.GroupLabelKey]) require.Equal(t, fmt.Sprintf("%d", i), retrievedRule.Labels[v0alpha1.GroupIndexLabelKey]) require.Equal(t, ngmodels.ProvenanceAPI, ngmodels.Provenance(retrievedRule.GetProvenanceStatus())) - require.EqualValues(t, r.Data[0].DatasourceUID, retrievedRule.Spec.Data["X"].DatasourceUID) + require.EqualValues(t, r.Data[0].DatasourceUID, *retrievedRule.Spec.Expressions["X"].DatasourceUID) expectedDuration, err := prom_model.ParseDuration(fmt.Sprintf("%ds", created.Interval)) require.NoError(t, err) require.Equal(t, expectedDuration.String(), string(retrievedRule.Spec.Trigger.Interval)) @@ -399,9 +399,9 @@ func TestIntegrationRecordingRuleCompatCreateViaProvisioningChangeGroupInK8s(t * err = json.Unmarshal(r.Data[0].Model, &expectedModel) require.NoError(t, err) require.NotNil(t, expectedModel) - retrievedModel, ok := retrievedRule.Spec.Data["X"].Model.(map[string]interface{}) + retrievedModel, ok := retrievedRule.Spec.Expressions["X"].Model.(map[string]interface{}) if !ok { - t.Fatalf("Expected model to be a map[string]interface{}, got %T", retrievedRule.Spec.Data["X"].Model) + t.Fatalf("Expected model to be a map[string]interface{}, got %T", retrievedRule.Spec.Expressions["X"].Model) } for k, v := range expectedModel { require.EqualValues(t, v, retrievedModel[k], "Model field %s should match", k) diff --git a/pkg/tests/apis/alerting/rules/recordingrule/recordingrule_test.go b/pkg/tests/apis/alerting/rules/recordingrule/recordingrule_test.go index df706099124..1f024e9fb7f 100644 --- a/pkg/tests/apis/alerting/rules/recordingrule/recordingrule_test.go +++ b/pkg/tests/apis/alerting/rules/recordingrule/recordingrule_test.go @@ -55,10 +55,10 @@ func TestIntegrationResourceIdentifier(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ @@ -155,10 +155,10 @@ func TestIntegrationAccessControl(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ @@ -242,10 +242,10 @@ func TestIntegrationCRUD(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ @@ -294,10 +294,10 @@ func TestIntegrationCRUD(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ @@ -325,8 +325,8 @@ func TestIntegrationCRUD(t *testing.T) { }, }, Spec: v0alpha1.RecordingRuleSpec{ - Title: "invalid-recording-rule", - Data: map[string]v0alpha1.RecordingRuleQuery{}, // Empty data should fail + Title: "invalid-recording-rule", + Expressions: v0alpha1.RecordingRuleExpressionMap{}, // Empty data should fail Trigger: v0alpha1.RecordingRuleIntervalTrigger{ Interval: "30s", }, @@ -352,10 +352,10 @@ func TestIntegrationCRUD(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ @@ -404,10 +404,10 @@ func TestIntegrationCRUD(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ From: v0alpha1.RecordingRulePromDurationWMillis("5m"), @@ -440,10 +440,10 @@ func TestIntegrationCRUD(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ @@ -496,10 +496,10 @@ func TestIntegrationPatch(t *testing.T) { Spec: v0alpha1.RecordingRuleSpec{ Title: rule.Title, Metric: rule.Record.Metric, - Data: map[string]v0alpha1.RecordingRuleQuery{ + Expressions: v0alpha1.RecordingRuleExpressionMap{ "A": { - QueryType: "query", - DatasourceUID: v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID), + QueryType: util.Pointer(rule.Data[0].QueryType), + DatasourceUID: util.Pointer(v0alpha1.RecordingRuleDatasourceUID(rule.Data[0].DatasourceUID)), Model: rule.Data[0].Model, Source: util.Pointer(true), RelativeTimeRange: &v0alpha1.RecordingRuleRelativeTimeRange{ diff --git a/pkg/tests/apis/openapi_snapshots/rules.alerting.grafana.app-v0alpha1.json b/pkg/tests/apis/openapi_snapshots/rules.alerting.grafana.app-v0alpha1.json index d26d36d1225..afd80701b8c 100644 --- a/pkg/tests/apis/openapi_snapshots/rules.alerting.grafana.app-v0alpha1.json +++ b/pkg/tests/apis/openapi_snapshots/rules.alerting.grafana.app-v0alpha1.json @@ -2369,10 +2369,10 @@ "type": "object", "required": [ "title", - "data", "trigger", "noDataState", - "execErrState" + "execErrState", + "expressions" ], "properties": { "annotations": { @@ -2381,22 +2381,32 @@ "type": "string" } }, - "data": { + "execErrState": { + "type": "string", + "default": "Error", + "enum": [ + "Error", + "Ok", + "Alerting", + "KeepLast" + ] + }, + "expressions": { "type": "object", "additionalProperties": { "type": "object", "required": [ - "queryType", - "datasourceUID", "model" ], "properties": { "datasourceUID": { + "description": "The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource", "type": "string", "pattern": "^[a-zA-Z0-9_-]+$" }, "model": {}, "queryType": { + "description": "The type of query if this is a query expression", "type": "string" }, "relativeTimeRange": { @@ -2417,21 +2427,12 @@ } }, "source": { + "description": "Used to mark the expression to be used as the final source for the rule evaluation\nOnly one expression in a rule can be marked as the source\nFor AlertRules, this is the expression that will be evaluated against the alerting condition\nFor RecordingRules, this is the expression that will be recorded", "type": "boolean" } } } }, - "execErrState": { - "type": "string", - "default": "Error", - "enum": [ - "Error", - "Ok", - "Alerting", - "KeepLast" - ] - }, "for": { "type": "string", "allOf": [ @@ -2730,28 +2731,28 @@ "type": "object", "required": [ "title", - "data", "trigger", "metric", + "expressions", "targetDatasourceUID" ], "properties": { - "data": { + "expressions": { "type": "object", "additionalProperties": { "type": "object", "required": [ - "queryType", - "datasourceUID", "model" ], "properties": { "datasourceUID": { + "description": "The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource", "type": "string", "pattern": "^[a-zA-Z0-9_-]+$" }, "model": {}, "queryType": { + "description": "The type of query if this is a query expression", "type": "string" }, "relativeTimeRange": { @@ -2772,6 +2773,7 @@ } }, "source": { + "description": "Used to mark the expression to be used as the final source for the rule evaluation\nOnly one expression in a rule can be marked as the source\nFor AlertRules, this is the expression that will be evaluated against the alerting condition\nFor RecordingRules, this is the expression that will be recorded", "type": "boolean" } } diff --git a/public/app/api/clients/rules/v0alpha1/endpoints.gen.ts b/public/app/api/clients/rules/v0alpha1/endpoints.gen.ts index 01247d97dd1..604940505db 100644 --- a/public/app/api/clients/rules/v0alpha1/endpoints.gen.ts +++ b/public/app/api/clients/rules/v0alpha1/endpoints.gen.ts @@ -846,19 +846,25 @@ export type AlertRuleSpec = { annotations?: { [key: string]: string; }; - data: { + execErrState: 'Error' | 'Ok' | 'Alerting' | 'KeepLast'; + expressions: { [key: string]: { - datasourceUID: string; + /** The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource */ + datasourceUID?: string; model: any; - queryType: string; + /** The type of query if this is a query expression */ + queryType?: string; relativeTimeRange?: { from: string; to: string; }; + /** Used to mark the expression to be used as the final source for the rule evaluation + Only one expression in a rule can be marked as the source + For AlertRules, this is the expression that will be evaluated against the alerting condition + For RecordingRules, this is the expression that will be recorded */ source?: boolean; }; }; - execErrState: 'Error' | 'Ok' | 'Alerting' | 'KeepLast'; for?: any & any; keepFiringFor?: any & any; labels?: { @@ -982,15 +988,21 @@ export type Status = { }; export type Patch = object; export type RecordingRuleSpec = { - data: { + expressions: { [key: string]: { - datasourceUID: string; + /** The UID of the datasource to run this expression against. If omitted, the expression will be run against the `__expr__` datasource */ + datasourceUID?: string; model: any; - queryType: string; + /** The type of query if this is a query expression */ + queryType?: string; relativeTimeRange?: { from: string; to: string; }; + /** Used to mark the expression to be used as the final source for the rule evaluation + Only one expression in a rule can be marked as the source + For AlertRules, this is the expression that will be evaluated against the alerting condition + For RecordingRules, this is the expression that will be recorded */ source?: boolean; }; }; From 3081ac166adcfe64dfd8e77e1b1c0038dbb4950a Mon Sep 17 00:00:00 2001 From: Andreas Christou Date: Sat, 13 Sep 2025 00:23:44 +0200 Subject: [PATCH 45/48] Graphite: Backend functions endpoint (#110771) * Add lint rules * Backend decoupling - Add standalone files - Add graphite query type - Add logger to Service - Create logger in the ProvideService method - Use a pointer for the HTTP client provider - Update logger usage everywhere - Update tracer type - Replace simplejson with json - Add dummy CallResource and CheckHealth methods - Update tests * Update ConfigEditor imports * Update types imports * Update datasource - Switch to using semver package - Update imports * Update store imports * Update helper imports and notification creation * Update context import * Update version numbers and logic * Copy array_move from core * Test updates * Add required files and update plugin.json * Update core references and packages * Remove commented code * Update wire * Lint * Fix import * Copy null type * More lint * Update snapshot * Refactor backend - Split query logic into separate file - Move utils to separate file * Add health-check logic - Support backend healthcheck if the FF is enabled * Remove query import support as unneeded * Add test * Add util function for decoding responses * Add events types * Add resource handler * Add events handler and generic resource req handler * Tests * Update frontend - Add types - Update events function to support backend requests * Lint and typing * Lint * Add metrics find endpoint - Add types - Add generic response parser - Add endpoint - Tests * Update FE functoin to use backend endpoint * Lint * Simplify request * Update test * Metrics expand type * Extract shared logic and add metric expand endpoint * Update tests * Call metric expand from backend * Rename type for clarity * Add get resource req handler * Refactor doGraphiteRequest, parseResponse Update tests * Migrate functions endpoint to backend * Add tests * Review * Review * Fix packages * Format * Fix merge issues * Review * Fix undefined values * Extract request creation - Add method for create requests generically with tests - Replace usage in query method - Update usages in resource handlers - Update tests - Update types * Lint * Lint --- pkg/tsdb/graphite/resource_handler.go | 106 +++++++++----- pkg/tsdb/graphite/resource_handler_test.go | 131 ++++++++++++++++-- .../plugins/datasource/graphite/datasource.ts | 8 +- 3 files changed, 195 insertions(+), 50 deletions(-) diff --git a/pkg/tsdb/graphite/resource_handler.go b/pkg/tsdb/graphite/resource_handler.go index 6988aafaad3..99199c4de75 100644 --- a/pkg/tsdb/graphite/resource_handler.go +++ b/pkg/tsdb/graphite/resource_handler.go @@ -1,6 +1,7 @@ package graphite import ( + "bytes" "context" "encoding/json" "fmt" @@ -16,13 +17,14 @@ import ( "go.opentelemetry.io/otel/codes" ) -type resourceHandler[T any] func(context.Context, *datasourceInfo, T) ([]byte, int, error) +type resourceHandler[T any] func(context.Context, *datasourceInfo, *T) ([]byte, int, error) func (s *Service) newResourceMux() *http.ServeMux { mux := http.NewServeMux() - mux.HandleFunc("/events", handleResourceReq[GraphiteEventsRequest](s.handleEvents, s)) - mux.HandleFunc("/metrics/find", handleResourceReq[GraphiteMetricsFindRequest](s.handleMetricsFind, s)) - mux.HandleFunc("/metrics/expand", handleResourceReq[GraphiteMetricsFindRequest](s.handleMetricsExpand, s)) + mux.HandleFunc("/events", handleResourceReq(s.handleEvents, s)) + mux.HandleFunc("/metrics/find", handleResourceReq(s.handleMetricsFind, s)) + mux.HandleFunc("/metrics/expand", handleResourceReq(s.handleMetricsExpand, s)) + mux.HandleFunc("/functions", handleResourceReq(s.handleFunctions, s)) return mux } @@ -39,17 +41,28 @@ func handleResourceReq[T any](handlerFn resourceHandler[T], s *Service) func(rw } defer func() { - if err := req.Body.Close(); err != nil { - s.logger.Warn("Failed to close response body", "err", err) + if req.Body != nil { + if err := req.Body.Close(); err != nil { + s.logger.Warn("Failed to close request body", "err", err) + writeErrorResponse(rw, http.StatusInternalServerError, fmt.Sprintf("unexpected error %v", err)) + return + } + } + }() + + var parsedBody *T + if req.Body != nil { + body, err := io.ReadAll(req.Body) + if err != nil { + s.logger.Error("Failed to read request body", "error", err) writeErrorResponse(rw, http.StatusInternalServerError, fmt.Sprintf("unexpected error %v", err)) return } - }() - requestBody, err := io.ReadAll(req.Body) - if err != nil { - s.logger.Error("Failed to read request body", "error", err) - writeErrorResponse(rw, http.StatusInternalServerError, fmt.Sprintf("unexpected error %v", err)) - return + parsedBody, err = parseRequestBody[T](body, s.logger) + if err != nil { + writeErrorResponse(rw, http.StatusBadRequest, fmt.Sprintf("failed to parse request body: %v", err)) + return + } } if handlerFn == nil { @@ -57,13 +70,7 @@ func handleResourceReq[T any](handlerFn resourceHandler[T], s *Service) func(rw return } - parsedBody, err := parseRequestBody[T](requestBody, s.logger) - if err != nil { - writeErrorResponse(rw, http.StatusBadRequest, fmt.Sprintf("failed to parse request body: %v", err)) - return - } - - response, statusCode, err := handlerFn(ctx, dsInfo, *parsedBody) + response, statusCode, err := handlerFn(ctx, dsInfo, parsedBody) if err != nil { writeErrorResponse(rw, statusCode, fmt.Sprintf("failed to handle resource request: %v", err)) return @@ -78,7 +85,7 @@ func handleResourceReq[T any](handlerFn resourceHandler[T], s *Service) func(rw } } -func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, eventsRequestJson GraphiteEventsRequest) ([]byte, int, error) { +func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, eventsRequestJson *GraphiteEventsRequest) ([]byte, int, error) { queryParams := map[string]string{ "from": eventsRequestJson.From, "until": eventsRequestJson.Until, @@ -96,7 +103,7 @@ func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, even return nil, http.StatusInternalServerError, fmt.Errorf("failed to create events request %v", err) } - events, statusCode, err := doGraphiteRequest[[]GraphiteEventsResponse](ctx, dsInfo, s.logger, req) + events, _, statusCode, err := doGraphiteRequest[[]GraphiteEventsResponse](ctx, dsInfo, s.logger, req, false) if err != nil { return nil, statusCode, fmt.Errorf("events request failed: %v", err) } @@ -112,7 +119,7 @@ func (s *Service) handleEvents(ctx context.Context, dsInfo *datasourceInfo, even return graphiteEventsResponse, statusCode, nil } -func (s *Service) handleMetricsFind(ctx context.Context, dsInfo *datasourceInfo, metricsFindRequestJson GraphiteMetricsFindRequest) ([]byte, int, error) { +func (s *Service) handleMetricsFind(ctx context.Context, dsInfo *datasourceInfo, metricsFindRequestJson *GraphiteMetricsFindRequest) ([]byte, int, error) { if metricsFindRequestJson.Query == "" { return nil, http.StatusBadRequest, fmt.Errorf("query is required") } @@ -139,7 +146,7 @@ func (s *Service) handleMetricsFind(ctx context.Context, dsInfo *datasourceInfo, return nil, http.StatusInternalServerError, fmt.Errorf("failed to create metrics find request %v", err) } - metrics, statusCode, err := doGraphiteRequest[[]GraphiteMetricsFindResponse](ctx, dsInfo, s.logger, req) + metrics, _, statusCode, err := doGraphiteRequest[[]GraphiteMetricsFindResponse](ctx, dsInfo, s.logger, req, false) if err != nil { return nil, statusCode, fmt.Errorf("metrics find request failed: %v", err) } @@ -152,7 +159,7 @@ func (s *Service) handleMetricsFind(ctx context.Context, dsInfo *datasourceInfo, return metricsFindResponse, statusCode, nil } -func (s *Service) handleMetricsExpand(ctx context.Context, dsInfo *datasourceInfo, metricsExpandRequestJson GraphiteMetricsFindRequest) ([]byte, int, error) { +func (s *Service) handleMetricsExpand(ctx context.Context, dsInfo *datasourceInfo, metricsExpandRequestJson *GraphiteMetricsFindRequest) ([]byte, int, error) { if metricsExpandRequestJson.Query == "" { return nil, http.StatusBadRequest, fmt.Errorf("query is required") } @@ -176,7 +183,7 @@ func (s *Service) handleMetricsExpand(ctx context.Context, dsInfo *datasourceInf return nil, http.StatusInternalServerError, fmt.Errorf("failed to create metrics expand request %v", err) } - metrics, statusCode, err := doGraphiteRequest[GraphiteMetricsExpandResponse](ctx, dsInfo, s.logger, req) + metrics, _, statusCode, err := doGraphiteRequest[GraphiteMetricsExpandResponse](ctx, dsInfo, s.logger, req, false) if err != nil { return nil, statusCode, fmt.Errorf("metrics expand request failed: %v", err) } @@ -196,7 +203,29 @@ func (s *Service) handleMetricsExpand(ctx context.Context, dsInfo *datasourceInf return metricsExpandResponse, statusCode, nil } -func doGraphiteRequest[T any](ctx context.Context, dsInfo *datasourceInfo, logger log.Logger, req *http.Request) (*T, int, error) { +func (s *Service) handleFunctions(ctx context.Context, dsInfo *datasourceInfo, _ *any) ([]byte, int, error) { + req, err := s.createRequest(ctx, dsInfo, URLParams{ + SubPath: "functions", + Method: http.MethodGet, + }) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("failed to create functions request %v", err) + } + + _, rawBody, statusCode, err := doGraphiteRequest[map[string]any](ctx, dsInfo, s.logger, req, true) + if err != nil { + return nil, statusCode, fmt.Errorf("version request failed: %v", err) + } + + if rawBody == nil { + return []byte{}, statusCode, nil + } + + rawBodyReplaced := bytes.ReplaceAll(*rawBody, []byte("\"default\": Infinity"), []byte("\"default\": 1e9999")) + return rawBodyReplaced, statusCode, nil +} + +func doGraphiteRequest[T any](ctx context.Context, dsInfo *datasourceInfo, logger log.Logger, req *http.Request, isRaw bool) (*T, *[]byte, int, error) { _, span := tracing.DefaultTracer().Start(ctx, "graphite request") defer span.End() span.SetAttributes( @@ -209,7 +238,7 @@ func doGraphiteRequest[T any](ctx context.Context, dsInfo *datasourceInfo, logge if err != nil { span.RecordError(err) span.SetStatus(codes.Error, err.Error()) - return nil, http.StatusInternalServerError, fmt.Errorf("failed to complete request: %v", err) + return nil, nil, http.StatusInternalServerError, fmt.Errorf("failed to complete request: %v", err) } defer func() { @@ -218,12 +247,12 @@ func doGraphiteRequest[T any](ctx context.Context, dsInfo *datasourceInfo, logge } }() - parsedResponse, err := parseResponse[T](res) + parsedResponse, rawBody, err := parseResponse[T](res, isRaw, logger) if err != nil { - return nil, http.StatusInternalServerError, fmt.Errorf("failed to parse response: %v", err) + return nil, nil, http.StatusInternalServerError, fmt.Errorf("failed to parse response: %v", err) } - return parsedResponse, res.StatusCode, nil + return parsedResponse, rawBody, res.StatusCode, nil } func parseRequestBody[V any](requestBody []byte, logger log.Logger) (*V, error) { @@ -236,19 +265,28 @@ func parseRequestBody[V any](requestBody []byte, logger log.Logger) (*V, error) return requestJson, nil } -func parseResponse[V any](res *http.Response) (*V, error) { +func parseResponse[V any](res *http.Response, isRaw bool, logger log.Logger) (*V, *[]byte, error) { encoding := res.Header.Get("Content-Encoding") body, err := decode(encoding, res.Body) if err != nil { - return nil, fmt.Errorf("failed to read response: %v", err) + return nil, nil, fmt.Errorf("failed to read response: %v", err) + } + + if res.StatusCode/100 != 2 { + logger.Warn("Request failed", "status", res.Status, "body", string(body)) + return nil, nil, fmt.Errorf("request failed, status: %d", res.StatusCode) + } + + if isRaw { + return nil, &body, nil } data := new(V) err = json.Unmarshal(body, &data) if err != nil { - return nil, fmt.Errorf("failed to unmarshal response: %v", err) + return nil, nil, fmt.Errorf("failed to unmarshal response: %v", err) } - return data, nil + return data, nil, nil } func writeErrorResponse(rw http.ResponseWriter, code int, msg string) { diff --git a/pkg/tsdb/graphite/resource_handler_test.go b/pkg/tsdb/graphite/resource_handler_test.go index 51d5a0fb290..4352b34cc79 100644 --- a/pkg/tsdb/graphite/resource_handler_test.go +++ b/pkg/tsdb/graphite/resource_handler_test.go @@ -18,12 +18,14 @@ import ( ) type mockRoundTripper struct { - respBody []byte - status int - err error + respBody []byte + status int + err error + lastRequest *http.Request } func (m *mockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + m.lastRequest = req if m.err != nil { return nil, m.err } @@ -129,7 +131,7 @@ func TestHandleEvents(t *testing.T) { t.Run(tt.name, func(t *testing.T) { svc := &Service{logger: log.NewNullLogger()} - respBody, status, err := svc.handleEvents(context.Background(), tt.dsInfo, tt.request) + respBody, status, err := svc.handleEvents(context.Background(), tt.dsInfo, &tt.request) assert.Equal(t, tt.expectedStatus, status) @@ -234,7 +236,7 @@ func TestHandleMetricsFind(t *testing.T) { t.Run(tt.name, func(t *testing.T) { svc := &Service{logger: log.NewNullLogger()} - respBody, status, err := svc.handleMetricsFind(context.Background(), tt.dsInfo, tt.request) + respBody, status, err := svc.handleMetricsFind(context.Background(), tt.dsInfo, &tt.request) assert.Equal(t, tt.expectedStatus, status) @@ -368,7 +370,7 @@ func TestHandleMetricsExpand(t *testing.T) { t.Run(tt.name, func(t *testing.T) { svc := &Service{logger: log.NewNullLogger()} - respBody, status, err := svc.handleMetricsExpand(context.Background(), tt.dsInfo, tt.request) + respBody, status, err := svc.handleMetricsExpand(context.Background(), tt.dsInfo, &tt.request) assert.Equal(t, tt.expectedStatus, status) @@ -392,6 +394,106 @@ func TestHandleMetricsExpand(t *testing.T) { } } +func TestHandleFunctions(t *testing.T) { + tests := []struct { + name string + responseBody string + statusCode int + expectError bool + errorContains string + expectedData string + }{ + { + name: "successful functions request", + responseBody: `{"sum": {"description": "Sum function"}, "avg": {"description": "Average function"}}`, + statusCode: 200, + expectError: false, + expectedData: `{"sum": {"description": "Sum function"}, "avg": {"description": "Average function"}}`, + }, + { + name: "functions with infinity replacement", + responseBody: `{"func": {"default": Infinity, "description": "Test function"}}`, + statusCode: 200, + expectError: false, + expectedData: `{"func": {"default": 1e9999, "description": "Test function"}}`, + }, + { + name: "empty functions response", + responseBody: `{}`, + statusCode: 200, + expectError: false, + expectedData: `{}`, + }, + { + name: "functions request server error", + responseBody: `{"error": "internal error"}`, + statusCode: 500, + expectError: true, + errorContains: "version request failed", + }, + { + name: "functions request not found", + responseBody: `{"error": "not found"}`, + statusCode: 404, + expectError: true, + errorContains: "version request failed", + }, + { + name: "network error", + responseBody: "", + statusCode: 0, + expectError: true, + errorContains: "version request failed", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var mockTransport *mockRoundTripper + + if tt.name == "network error" { + mockTransport = &mockRoundTripper{ + err: errors.New("network connection failed"), + } + } else { + mockTransport = &mockRoundTripper{ + respBody: []byte(tt.responseBody), + status: tt.statusCode, + } + } + + dsInfo := &datasourceInfo{ + HTTPClient: &http.Client{Transport: mockTransport}, + URL: "http://graphite.example.com", + } + + service := &Service{ + logger: log.NewNullLogger(), + } + + result, statusCode, err := service.handleFunctions(context.Background(), dsInfo, nil) + + if tt.expectError { + assert.Error(t, err) + if tt.errorContains != "" { + assert.Contains(t, err.Error(), tt.errorContains) + } + } else { + assert.NoError(t, err) + assert.Equal(t, tt.statusCode, statusCode) + assert.Equal(t, tt.expectedData, string(result)) + } + + // Verify the request was made correctly (except for network error case) + if tt.name != "network error" { + require.NotNil(t, mockTransport.lastRequest) + assert.Equal(t, "http://graphite.example.com/functions", mockTransport.lastRequest.URL.String()) + assert.Equal(t, http.MethodGet, mockTransport.lastRequest.Method) + } + }) + } +} + func TestHandleResourceReq_Success(t *testing.T) { mockEvents := []GraphiteEventsResponse{{When: 1234567890, What: "event1"}} mockResp, _ := json.Marshal(mockEvents) @@ -558,11 +660,10 @@ func TestDoGraphiteRequest(t *testing.T) { URL: "http://graphite.grafana", HTTPClient: &http.Client{Transport: &mockRoundTripper{respBody: []byte("[]"), status: 500}}, }, - method: "GET", - headers: map[string]string{}, - expectedStatus: 500, - expectError: false, - expectedData: []GraphiteEventsResponse{}, + method: "GET", + headers: map[string]string{}, + expectError: true, + errorContains: "request failed, status: 500", }, } @@ -594,7 +695,7 @@ func TestDoGraphiteRequest(t *testing.T) { assert.NoError(t, err) } - result, status, err := doGraphiteRequest[[]GraphiteEventsResponse](ctx, tt.dsInfo, svc.logger, req) + result, _, status, err := doGraphiteRequest[[]GraphiteEventsResponse](ctx, tt.dsInfo, svc.logger, req, false) if tt.expectError { assert.Error(t, err) @@ -653,7 +754,7 @@ func TestDoGraphiteRequestGenericTypes(t *testing.T) { }) assert.NoError(t, err) - result, status, err := doGraphiteRequest[[]GraphiteMetricsFindResponse](ctx, dsInfo, svc.logger, req) + result, _, status, err := doGraphiteRequest[[]GraphiteMetricsFindResponse](ctx, dsInfo, svc.logger, req, false) assert.NoError(t, err) assert.NotNil(t, result) @@ -681,7 +782,7 @@ func TestDoGraphiteRequestGenericTypes(t *testing.T) { }) assert.NoError(t, err) - result, status, err := doGraphiteRequest[GraphiteMetricsExpandResponse](ctx, dsInfo, svc.logger, req) + result, _, status, err := doGraphiteRequest[GraphiteMetricsExpandResponse](ctx, dsInfo, svc.logger, req, false) assert.NoError(t, err) assert.NotNil(t, result) @@ -825,7 +926,7 @@ func TestParseResponse(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result, err := parseResponse[[]GraphiteEventsResponse](tt.response) + result, _, err := parseResponse[[]GraphiteEventsResponse](tt.response, false, log.NewNullLogger()) if tt.expectError { assert.Error(t, err) diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts index 7f04fa713af..fc2e818233f 100644 --- a/public/app/plugins/datasource/graphite/datasource.ts +++ b/public/app/plugins/datasource/graphite/datasource.ts @@ -947,7 +947,7 @@ export class GraphiteDatasource return this.getFuncDefs(); } - getFuncDefs() { + async getFuncDefs() { if (this.funcDefsPromise !== null) { return this.funcDefsPromise; } @@ -966,6 +966,12 @@ export class GraphiteDatasource responseType: 'text' as const, }; + if (config.featureToggles.graphiteBackendMode) { + const functions = await this.getResource('functions'); + this.funcDefs = gfunc.parseFuncDefs(functions); + return this.funcDefs; + } + return lastValueFrom( this.doGraphiteRequest(httpOptions).pipe( map((results: FetchResponse) => { From 211c0ca5c372bb26b152e2efaf22c489d0fd0948 Mon Sep 17 00:00:00 2001 From: Andreas Christou Date: Sat, 13 Sep 2025 00:53:09 +0200 Subject: [PATCH 46/48] Graphite: Backend tags autocomplete endpoint (#110772) * Add lint rules * Backend decoupling - Add standalone files - Add graphite query type - Add logger to Service - Create logger in the ProvideService method - Use a pointer for the HTTP client provider - Update logger usage everywhere - Update tracer type - Replace simplejson with json - Add dummy CallResource and CheckHealth methods - Update tests * Update ConfigEditor imports * Update types imports * Update datasource - Switch to using semver package - Update imports * Update store imports * Update helper imports and notification creation * Update context import * Update version numbers and logic * Copy array_move from core * Test updates * Add required files and update plugin.json * Update core references and packages * Remove commented code * Update wire * Lint * Fix import * Copy null type * More lint * Update snapshot * Refactor backend - Split query logic into separate file - Move utils to separate file * Add health-check logic - Support backend healthcheck if the FF is enabled * Remove query import support as unneeded * Add test * Add util function for decoding responses * Add events types * Add resource handler * Add events handler and generic resource req handler * Tests * Update frontend - Add types - Update events function to support backend requests * Lint and typing * Lint * Add metrics find endpoint - Add types - Add generic response parser - Add endpoint - Tests * Update FE functoin to use backend endpoint * Lint * Simplify request * Update test * Metrics expand type * Extract shared logic and add metric expand endpoint * Update tests * Call metric expand from backend * Rename type for clarity * Add get resource req handler * Refactor doGraphiteRequest, parseResponse Update tests * Migrate functions endpoint to backend * Support tags autocomplete in backend - Add tests - Add types - Remove unneeded comments * Add tests * Review * Review * Fix packages * Format * Fix merge issues * Review * Fix undefined values * Extract request creation - Add method for create requests generically with tests - Replace usage in query method - Update usages in resource handlers - Update tests - Update types --- pkg/tsdb/graphite/resource_handler.go | 30 +++++ pkg/tsdb/graphite/resource_handler_test.go | 110 +++++++++++++++++- pkg/tsdb/graphite/types.go | 7 ++ .../plugins/datasource/graphite/datasource.ts | 14 ++- 4 files changed, 157 insertions(+), 4 deletions(-) diff --git a/pkg/tsdb/graphite/resource_handler.go b/pkg/tsdb/graphite/resource_handler.go index 99199c4de75..d8a1c3508ec 100644 --- a/pkg/tsdb/graphite/resource_handler.go +++ b/pkg/tsdb/graphite/resource_handler.go @@ -25,6 +25,7 @@ func (s *Service) newResourceMux() *http.ServeMux { mux.HandleFunc("/metrics/find", handleResourceReq(s.handleMetricsFind, s)) mux.HandleFunc("/metrics/expand", handleResourceReq(s.handleMetricsExpand, s)) mux.HandleFunc("/functions", handleResourceReq(s.handleFunctions, s)) + mux.HandleFunc("/tags/autoComplete/tags", handleResourceReq(s.handleTagsAutocomplete, s)) return mux } @@ -203,6 +204,35 @@ func (s *Service) handleMetricsExpand(ctx context.Context, dsInfo *datasourceInf return metricsExpandResponse, statusCode, nil } +func (s *Service) handleTagsAutocomplete(ctx context.Context, dsInfo *datasourceInfo, tagsAutocompleteRequestJson *GraphiteTagsRequest) ([]byte, int, error) { + queryParams := map[string]string{ + "from": tagsAutocompleteRequestJson.From, + "until": tagsAutocompleteRequestJson.Until, + "limit": fmt.Sprintf("%d", tagsAutocompleteRequestJson.Limit), + "tagPrefix": tagsAutocompleteRequestJson.TagPrefix, + } + req, err := s.createRequest(ctx, dsInfo, URLParams{ + SubPath: "tags/autoComplete/tags", + Method: http.MethodGet, + QueryParams: queryParams, + }) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("failed to create metrics expand request %v", err) + } + + tags, _, statusCode, err := doGraphiteRequest[[]string](ctx, dsInfo, s.logger, req, false) + if err != nil { + return nil, statusCode, fmt.Errorf("tags autocomplete request failed: %v", err) + } + + tagsResponse, err := json.Marshal(tags) + if err != nil { + return nil, http.StatusInternalServerError, fmt.Errorf("failed to marshal tags autocomplete response: %s", err) + } + + return tagsResponse, statusCode, nil +} + func (s *Service) handleFunctions(ctx context.Context, dsInfo *datasourceInfo, _ *any) ([]byte, int, error) { req, err := s.createRequest(ctx, dsInfo, URLParams{ SubPath: "functions", diff --git a/pkg/tsdb/graphite/resource_handler_test.go b/pkg/tsdb/graphite/resource_handler_test.go index 4352b34cc79..c331c2d2cab 100644 --- a/pkg/tsdb/graphite/resource_handler_test.go +++ b/pkg/tsdb/graphite/resource_handler_test.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "errors" + "fmt" "io" "net/http" "net/http/httptest" @@ -94,7 +95,7 @@ func TestHandleEvents(t *testing.T) { name: "Invalid URL", dsInfo: &datasourceInfo{ Id: 1, - URL: "ht tp://invalid url", // Invalid URL + URL: "ht tp://invalid url", }, request: GraphiteEventsRequest{From: "now-1h", Until: "now"}, expectedStatus: http.StatusInternalServerError, @@ -211,7 +212,7 @@ func TestHandleMetricsFind(t *testing.T) { name: "Invalid URL", dsInfo: &datasourceInfo{ Id: 1, - URL: "ht tp://invalid url", // Invalid URL + URL: "ht tp://invalid url", }, request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, expectedStatus: http.StatusInternalServerError, @@ -321,7 +322,7 @@ func TestHandleMetricsExpand(t *testing.T) { name: "Invalid URL", dsInfo: &datasourceInfo{ Id: 1, - URL: "ht tp://invalid url", // Invalid URL + URL: "ht tp://invalid url", }, request: GraphiteMetricsFindRequest{Query: "app.grafana.*"}, expectedStatus: http.StatusInternalServerError, @@ -394,6 +395,109 @@ func TestHandleMetricsExpand(t *testing.T) { } } +func TestHandleTagsAutocomplete(t *testing.T) { + tests := []struct { + name string + request GraphiteTagsRequest + responseBody string + statusCode int + expectError bool + errorContains string + expectedData []string + }{ + { + name: "successful tags autocomplete request", + request: GraphiteTagsRequest{ + From: "1h", + Until: "now", + Limit: 10, + TagPrefix: "app", + }, + responseBody: `["app", "application", "app_name"]`, + statusCode: 200, + expectedData: []string{"app", "application", "app_name"}, + }, + { + name: "tags autocomplete with minimal request", + request: GraphiteTagsRequest{}, + responseBody: `["tag1", "tag2"]`, + statusCode: 200, + expectedData: []string{"tag1", "tag2"}, + }, + { + name: "tags autocomplete with empty response", + request: GraphiteTagsRequest{ + TagPrefix: "nonexistent", + }, + responseBody: `[]`, + statusCode: 200, + expectedData: []string{}, + }, + { + name: "tags autocomplete server error - invalid JSON causes marshal error", + request: GraphiteTagsRequest{ + From: "invalid", + }, + responseBody: `invalid json response`, + statusCode: 400, + expectError: true, + errorContains: "tags autocomplete request failed", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockTransport := &mockRoundTripper{ + respBody: []byte(tt.responseBody), + status: tt.statusCode, + } + + dsInfo := &datasourceInfo{ + HTTPClient: &http.Client{Transport: mockTransport}, + URL: "http://graphite.example.com", + } + + service := &Service{ + logger: log.NewNullLogger(), + } + + result, statusCode, err := service.handleTagsAutocomplete(context.Background(), dsInfo, &tt.request) + + if tt.expectError { + assert.Error(t, err) + if tt.errorContains != "" { + assert.Contains(t, err.Error(), tt.errorContains) + } + } else { + assert.NoError(t, err) + assert.Equal(t, tt.statusCode, statusCode) + + var tags []string + err = json.Unmarshal(result, &tags) + assert.NoError(t, err) + assert.Equal(t, tt.expectedData, tags) + } + + if !tt.expectError { + expectedURL := "http://graphite.example.com/tags/autoComplete/tags" + assert.Contains(t, mockTransport.lastRequest.URL.String(), expectedURL) + + if tt.request.From != "" { + assert.Contains(t, mockTransport.lastRequest.URL.RawQuery, fmt.Sprintf("from=%s", tt.request.From)) + } + if tt.request.Until != "" { + assert.Contains(t, mockTransport.lastRequest.URL.RawQuery, fmt.Sprintf("until=%s", tt.request.Until)) + } + if tt.request.Limit != 0 { + assert.Contains(t, mockTransport.lastRequest.URL.RawQuery, fmt.Sprintf("limit=%d", tt.request.Limit)) + } + if tt.request.TagPrefix != "" { + assert.Contains(t, mockTransport.lastRequest.URL.RawQuery, fmt.Sprintf("tagPrefix=%s", tt.request.TagPrefix)) + } + } + }) + } +} func TestHandleFunctions(t *testing.T) { tests := []struct { name string diff --git a/pkg/tsdb/graphite/types.go b/pkg/tsdb/graphite/types.go index 30d872f375a..2e427f1d327 100644 --- a/pkg/tsdb/graphite/types.go +++ b/pkg/tsdb/graphite/types.go @@ -59,3 +59,10 @@ type GraphiteMetricsFindResponse struct { type GraphiteMetricsExpandResponse struct { Results []string `json:"results"` } + +type GraphiteTagsRequest struct { + From string `json:"from"` + Until string `json:"until"` + Limit int `json:"limit,omitempty"` + TagPrefix string `json:"tagPrefix,omitempty"` +} diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts index fc2e818233f..14b1139f3ad 100644 --- a/public/app/plugins/datasource/graphite/datasource.ts +++ b/public/app/plugins/datasource/graphite/datasource.ts @@ -854,7 +854,7 @@ export class GraphiteDatasource ); } - getTagsAutoComplete(expressions: string[], tagPrefix?: string, optionalOptions?: any) { + async getTagsAutoComplete(expressions: string[], tagPrefix?: string, optionalOptions?: any) { const options = optionalOptions || {}; const params: BackendSrvRequest['params'] = { expr: _map(expressions, (expression) => this.templateSrv.replace((expression || '').trim())), @@ -871,6 +871,18 @@ export class GraphiteDatasource params.until = this.translateTime(options.range.to, true, options.timezone); } + if (config.featureToggles.graphiteBackendMode) { + const tags = await this.postResource('tags/autoComplete/tags', { + from: typeof params.from === 'string' ? params.from : `${params.from}`, + until: typeof params.until === 'string' ? params.until : `${params.until}`, + tagPrefix, + limit: options.limit, + }); + return tags.map((tag) => ({ + text: tag, + })); + } + const httpOptions: BackendSrvRequest = { method: 'GET', url: '/tags/autoComplete/tags', From 135e9ef1024345e8c7928ab6a59c656f8513235d Mon Sep 17 00:00:00 2001 From: Ezequiel Victorero Date: Fri, 12 Sep 2025 20:23:50 -0300 Subject: [PATCH 47/48] ShortURL: Use the new k8s api in the frontend (#110537) --- .../src/types/featureToggles.gen.ts | 6 +- pkg/services/featuremgmt/registry.go | 9 +- pkg/services/featuremgmt/toggles_gen.csv | 1 + pkg/services/featuremgmt/toggles_gen.go | 6 +- pkg/services/featuremgmt/toggles_gen.json | 25 +- .../shorturl.grafana.app-v1alpha1.json | 1823 +++++++++++++++++ pkg/tests/apis/openapi_test.go | 4 + .../api/clients/shorturl/v1alpha1/baseAPI.ts | 14 + .../shorturl/v1alpha1/endpoints.gen.ts | 582 ++++++ .../api/clients/shorturl/v1alpha1/index.ts | 3 + public/app/core/reducers/root.ts | 2 + public/app/core/utils/shortLinks.test.ts | 79 +- public/app/core/utils/shortLinks.ts | 30 +- public/app/store/configureStore.ts | 2 + scripts/generate-rtk-apis.ts | 5 + 15 files changed, 2573 insertions(+), 18 deletions(-) create mode 100644 pkg/tests/apis/openapi_snapshots/shorturl.grafana.app-v1alpha1.json create mode 100644 public/app/api/clients/shorturl/v1alpha1/baseAPI.ts create mode 100644 public/app/api/clients/shorturl/v1alpha1/endpoints.gen.ts create mode 100644 public/app/api/clients/shorturl/v1alpha1/index.ts diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index b98349e852d..1da6c2612cc 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -274,10 +274,14 @@ export interface FeatureToggles { */ kubernetesDashboards?: boolean; /** - * Routes short url requests from /api to the /apis endpoint + * Enables k8s short url api and uses it under the hood when handling legacy /api */ kubernetesShortURLs?: boolean; /** + * Routes short url requests from /api to the /apis endpoint in the frontend. Depends on kubernetesShortURLs + */ + useKubernetesShortURLsAPI?: boolean; + /** * Adds support for Kubernetes alerting and recording rules */ kubernetesAlertingRules?: boolean; diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index a19ae8f3f96..e347dcf9c1e 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -457,11 +457,18 @@ var ( }, { Name: "kubernetesShortURLs", - Description: "Routes short url requests from /api to the /apis endpoint", + Description: "Enables k8s short url api and uses it under the hood when handling legacy /api", Stage: FeatureStageExperimental, Owner: grafanaAppPlatformSquad, RequiresRestart: true, // changes the API routing }, + { + Name: "useKubernetesShortURLsAPI", + Description: "Routes short url requests from /api to the /apis endpoint in the frontend. Depends on kubernetesShortURLs", + Stage: FeatureStageExperimental, + Owner: grafanaSharingSquad, + FrontendOnly: true, + }, { Name: "kubernetesAlertingRules", Description: "Adds support for Kubernetes alerting and recording rules", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 0294b58ccf3..74b4de46251 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -59,6 +59,7 @@ kubernetesSnapshots,experimental,@grafana/grafana-app-platform-squad,false,true, kubernetesLibraryPanels,experimental,@grafana/grafana-app-platform-squad,false,true,false kubernetesDashboards,GA,@grafana/dashboards-squad,false,false,true kubernetesShortURLs,experimental,@grafana/grafana-app-platform-squad,false,true,false +useKubernetesShortURLsAPI,experimental,@grafana/sharing-squad,false,false,true kubernetesAlertingRules,experimental,@grafana/alerting-squad,false,true,false dashboardDisableSchemaValidationV1,experimental,@grafana/grafana-app-platform-squad,false,false,false dashboardDisableSchemaValidationV2,experimental,@grafana/grafana-app-platform-squad,false,false,false diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index f337c991e09..5376d303c15 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -244,9 +244,13 @@ const ( FlagKubernetesDashboards = "kubernetesDashboards" // FlagKubernetesShortURLs - // Routes short url requests from /api to the /apis endpoint + // Enables k8s short url api and uses it under the hood when handling legacy /api FlagKubernetesShortURLs = "kubernetesShortURLs" + // FlagUseKubernetesShortURLsAPI + // Routes short url requests from /api to the /apis endpoint in the frontend. Depends on kubernetesShortURLs + FlagUseKubernetesShortURLsAPI = "useKubernetesShortURLsAPI" + // FlagKubernetesAlertingRules // Adds support for Kubernetes alerting and recording rules FlagKubernetesAlertingRules = "kubernetesAlertingRules" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 9337a5f30e7..24f00874702 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -2048,11 +2048,14 @@ { "metadata": { "name": "kubernetesShortURLs", - "resourceVersion": "1753722806283", - "creationTimestamp": "2025-08-04T12:12:12Z" + "resourceVersion": "1756914263808", + "creationTimestamp": "2025-08-04T12:12:12Z", + "annotations": { + "grafana.app/updatedTimestamp": "2025-09-03 15:44:23.80856 +0000 UTC" + } }, "spec": { - "description": "Routes short url requests from /api to the /apis endpoint", + "description": "Enables k8s short url api and uses it under the hood when handling legacy /api", "stage": "experimental", "codeowner": "@grafana/grafana-app-platform-squad", "requiresRestart": true @@ -3625,6 +3628,22 @@ "hideFromDocs": true } }, + { + "metadata": { + "name": "useKubernetesShortURLsAPI", + "resourceVersion": "1756914263808", + "creationTimestamp": "2025-09-03T10:49:07Z", + "annotations": { + "grafana.app/updatedTimestamp": "2025-09-03 15:44:23.80856 +0000 UTC" + } + }, + "spec": { + "description": "Routes short url requests from /api to the /apis endpoint in the frontend. Depends on kubernetesShortURLs", + "stage": "experimental", + "codeowner": "@grafana/sharing-squad", + "frontend": true + } + }, { "metadata": { "name": "useScopeSingleNodeEndpoint", diff --git a/pkg/tests/apis/openapi_snapshots/shorturl.grafana.app-v1alpha1.json b/pkg/tests/apis/openapi_snapshots/shorturl.grafana.app-v1alpha1.json new file mode 100644 index 00000000000..9d90de21524 --- /dev/null +++ b/pkg/tests/apis/openapi_snapshots/shorturl.grafana.app-v1alpha1.json @@ -0,0 +1,1823 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "shorturl.grafana.app/v1alpha1" + }, + "paths": { + "/apis/shorturl.grafana.app/v1alpha1/": { + "get": { + "tags": [ + "API Discovery" + ], + "description": "Describe the available kubernetes resources", + "operationId": "getAPIResources", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList" + } + } + } + } + } + } + }, + "/apis/shorturl.grafana.app/v1alpha1/namespaces/{namespace}/shorturls": { + "get": { + "tags": [ + "ShortURL" + ], + "description": "list objects of kind ShortURL", + "operationId": "listShortURL", + "parameters": [ + { + "name": "allowWatchBookmarks", + "in": "query", + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "name": "continue", + "in": "query", + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldSelector", + "in": "query", + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "labelSelector", + "in": "query", + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "limit", + "in": "query", + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "name": "resourceVersion", + "in": "query", + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "resourceVersionMatch", + "in": "query", + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "sendInitialEvents", + "in": "query", + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "name": "timeoutSeconds", + "in": "query", + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "name": "watch", + "in": "query", + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLList" + } + }, + "application/json;stream=watch": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLList" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLList" + } + }, + "application/vnd.kubernetes.protobuf;stream=watch": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLList" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLList" + } + } + } + } + }, + "x-kubernetes-action": "list", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "post": { + "tags": [ + "ShortURL" + ], + "description": "create a ShortURL", + "operationId": "createShortURL", + "parameters": [ + { + "name": "dryRun", + "in": "query", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldManager", + "in": "query", + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldValidation", + "in": "query", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + }, + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + }, + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + } + }, + "x-kubernetes-action": "post", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "delete": { + "tags": [ + "ShortURL" + ], + "description": "delete collection of ShortURL", + "operationId": "deletecollectionShortURL", + "parameters": [ + { + "name": "continue", + "in": "query", + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "dryRun", + "in": "query", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldSelector", + "in": "query", + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "gracePeriodSeconds", + "in": "query", + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "in": "query", + "description": "if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "name": "labelSelector", + "in": "query", + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "limit", + "in": "query", + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "name": "orphanDependents", + "in": "query", + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "name": "propagationPolicy", + "in": "query", + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "resourceVersion", + "in": "query", + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "resourceVersionMatch", + "in": "query", + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "sendInitialEvents", + "in": "query", + "description": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "name": "timeoutSeconds", + "in": "query", + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "schema": { + "type": "integer", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + } + } + }, + "x-kubernetes-action": "deletecollection", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "description": "object name and auth scope, such as for teams and projects", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "pretty", + "in": "query", + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/shorturl.grafana.app/v1alpha1/namespaces/{namespace}/shorturls/{name}": { + "get": { + "tags": [ + "ShortURL" + ], + "description": "read the specified ShortURL", + "operationId": "getShortURL", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + } + }, + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "put": { + "tags": [ + "ShortURL" + ], + "description": "replace the specified ShortURL", + "operationId": "replaceShortURL", + "parameters": [ + { + "name": "dryRun", + "in": "query", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldManager", + "in": "query", + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldValidation", + "in": "query", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + }, + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + } + }, + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "delete": { + "tags": [ + "ShortURL" + ], + "description": "delete a ShortURL", + "operationId": "deleteShortURL", + "parameters": [ + { + "name": "dryRun", + "in": "query", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "gracePeriodSeconds", + "in": "query", + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "in": "query", + "description": "if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "name": "orphanDependents", + "in": "query", + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "name": "propagationPolicy", + "in": "query", + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + } + }, + "202": { + "description": "Accepted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + } + } + }, + "x-kubernetes-action": "delete", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "patch": { + "tags": [ + "ShortURL" + ], + "description": "partially update the specified ShortURL", + "operationId": "updateShortURL", + "parameters": [ + { + "name": "dryRun", + "in": "query", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldManager", + "in": "query", + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldValidation", + "in": "query", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "force", + "in": "query", + "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/strategic-merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + }, + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + } + }, + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "description": "name of the ShortURL", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "namespace", + "in": "path", + "description": "object name and auth scope, such as for teams and projects", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "pretty", + "in": "query", + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/shorturl.grafana.app/v1alpha1/namespaces/{namespace}/shorturls/{name}/status": { + "get": { + "tags": [ + "ShortURL" + ], + "description": "read status of the specified ShortURL", + "operationId": "getShortURLStatus", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + } + }, + "x-kubernetes-action": "get", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "put": { + "tags": [ + "ShortURL" + ], + "description": "replace status of the specified ShortURL", + "operationId": "replaceShortURLStatus", + "parameters": [ + { + "name": "dryRun", + "in": "query", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldManager", + "in": "query", + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldValidation", + "in": "query", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + }, + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + } + }, + "x-kubernetes-action": "put", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "patch": { + "tags": [ + "ShortURL" + ], + "description": "partially update status of the specified ShortURL", + "operationId": "updateShortURLStatus", + "parameters": [ + { + "name": "dryRun", + "in": "query", + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldManager", + "in": "query", + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "fieldValidation", + "in": "query", + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "force", + "in": "query", + "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/strategic-merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + }, + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/vnd.kubernetes.protobuf": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + } + } + } + }, + "x-kubernetes-action": "patch", + "x-kubernetes-group-version-kind": { + "group": "shorturl.grafana.app", + "version": "v1alpha1", + "kind": "ShortURL" + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "description": "name of the ShortURL", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "namespace", + "in": "path", + "description": "object name and auth scope, such as for teams and projects", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "name": "pretty", + "in": "query", + "description": "If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget).", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + } + }, + "components": { + "schemas": { + "com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL": { + "type": "object", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + } + ] + }, + "spec": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLSpec" + } + ] + }, + "status": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLStatus" + } + ] + } + }, + "x-kubernetes-group-version-kind": [ + { + "group": "shorturl.grafana.app", + "kind": "ShortURL", + "version": "v1alpha1" + } + ] + }, + "com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLList": { + "type": "object", + "required": [ + "metadata", + "items" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "type": "array", + "items": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURL" + } + ] + } + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ] + } + }, + "x-kubernetes-group-version-kind": [ + { + "group": "shorturl.grafana.app", + "kind": "ShortURLList", + "version": "v1alpha1" + } + ] + }, + "com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLSpec": { + "type": "object", + "required": [ + "path" + ], + "properties": { + "path": { + "description": "The original path to where the short url is linking too e.g. https://localhost:3000/eer8i1kictngga/new-dashboard-with-lib-panel", + "type": "string" + } + } + }, + "com.github.grafana.grafana.apps.shorturl.pkg.apis.shorturl.v1alpha1.ShortURLStatus": { + "type": "object", + "required": [ + "lastSeenAt" + ], + "properties": { + "additionalFields": { + "description": "additionalFields is reserved for future use", + "type": "object", + "additionalProperties": true + }, + "lastSeenAt": { + "description": "The last time the short URL was used, 0 is the initial value", + "type": "integer", + "format": "int64" + }, + "operatorStates": { + "description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.", + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "lastEvaluation", + "state" + ], + "properties": { + "descriptiveState": { + "description": "descriptiveState is an optional more descriptive state field which has no requirements on format", + "type": "string" + }, + "details": { + "description": "details contains any extra information that is operator-specific", + "type": "object", + "additionalProperties": true + }, + "lastEvaluation": { + "description": "lastEvaluation is the ResourceVersion last evaluated", + "type": "string" + }, + "state": { + "description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.", + "type": "string", + "enum": [ + "success", + "in_progress", + "failed" + ] + } + } + } + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.APIResource": { + "description": "APIResource specifies the name of a resource and whether it is namespaced.", + "type": "object", + "required": [ + "name", + "singularName", + "namespaced", + "kind", + "verbs" + ], + "properties": { + "categories": { + "description": "categories is a list of the grouped resources this resource belongs to (e.g. 'all')", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "atomic" + }, + "group": { + "description": "group is the preferred group of the resource. Empty implies the group of the containing resource list. For subresources, this may have a different value, for example: Scale\".", + "type": "string" + }, + "kind": { + "description": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')", + "type": "string", + "default": "" + }, + "name": { + "description": "name is the plural name of the resource.", + "type": "string", + "default": "" + }, + "namespaced": { + "description": "namespaced indicates if a resource is namespaced or not.", + "type": "boolean", + "default": false + }, + "shortNames": { + "description": "shortNames is a list of suggested short names of the resource.", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "atomic" + }, + "singularName": { + "description": "singularName is the singular name of the resource. This allows clients to handle plural and singular opaquely. The singularName is more correct for reporting status on a single item and both singular and plural are allowed from the kubectl CLI interface.", + "type": "string", + "default": "" + }, + "storageVersionHash": { + "description": "The hash value of the storage version, the version this resource is converted to when written to the data store. Value must be treated as opaque by clients. Only equality comparison on the value is valid. This is an alpha feature and may change or be removed in the future. The field is populated by the apiserver only if the StorageVersionHash feature gate is enabled. This field will remain optional even if it graduates.", + "type": "string" + }, + "verbs": { + "description": "verbs is a list of supported kube verbs (this includes get, list, watch, create, update, patch, delete, deletecollection, and proxy)", + "type": "array", + "items": { + "type": "string", + "default": "" + } + }, + "version": { + "description": "version is the preferred version of the resource. Empty implies the version of the containing resource list For subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)\".", + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList": { + "description": "APIResourceList is a list of APIResource, it is used to expose the name of the resources supported in a specific group and version, and if the resource is namespaced.", + "type": "object", + "required": [ + "groupVersion", + "resources" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "groupVersion": { + "description": "groupVersion is the group and version this APIResourceList is for.", + "type": "string", + "default": "" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "resources": { + "description": "resources contains the name of the resources and if they are namespaced.", + "type": "array", + "items": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIResource" + } + ] + }, + "x-kubernetes-list-type": "atomic" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions": { + "description": "DeleteOptions may be provided when deleting an API object.", + "type": "object", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "dryRun": { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "atomic" + }, + "gracePeriodSeconds": { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "type": "integer", + "format": "int64" + }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it", + "type": "boolean" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "orphanDependents": { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "type": "boolean" + }, + "preconditions": { + "description": "Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be returned.", + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions" + } + ] + }, + "propagationPolicy": { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1": { + "description": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:\u003cname\u003e', where \u003cname\u003e is the name of a field in a struct, or key in a map 'v:\u003cvalue\u003e', where \u003cvalue\u003e is the exact json formatted value of a list item 'i:\u003cindex\u003e', where \u003cindex\u003e is position of a item in a list 'k:\u003ckeys\u003e', where \u003ckeys\u003e is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta": { + "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", + "type": "object", + "properties": { + "continue": { + "description": "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.", + "type": "string" + }, + "remainingItemCount": { + "description": "remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.", + "type": "integer", + "format": "int64" + }, + "resourceVersion": { + "description": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": { + "description": "ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.", + "type": "object", + "properties": { + "apiVersion": { + "description": "APIVersion defines the version of this resource that this field set applies to. The format is \"group/version\" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.", + "type": "string" + }, + "fieldsType": { + "description": "FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: \"FieldsV1\"", + "type": "string" + }, + "fieldsV1": { + "description": "FieldsV1 holds the first JSON version format as described in the \"FieldsV1\" type.", + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1" + } + ] + }, + "manager": { + "description": "Manager is an identifier of the workflow managing these fields.", + "type": "string" + }, + "operation": { + "description": "Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.", + "type": "string" + }, + "subresource": { + "description": "Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.", + "type": "string" + }, + "time": { + "description": "Time is the timestamp of when the ManagedFields entry was added. The timestamp will also be updated if a field is added, the manager changes any of the owned fields value or removes a field. The timestamp does not update when a field is removed from the entry because another manager took it over.", + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ] + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": { + "description": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", + "type": "object", + "properties": { + "annotations": { + "description": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations", + "type": "object", + "additionalProperties": { + "type": "string", + "default": "" + } + }, + "creationTimestamp": { + "description": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ] + }, + "deletionGracePeriodSeconds": { + "description": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", + "type": "integer", + "format": "int64" + }, + "deletionTimestamp": { + "description": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ] + }, + "finalizers": { + "description": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "set", + "x-kubernetes-patch-strategy": "merge" + }, + "generateName": { + "description": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will return a 409.\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency", + "type": "string" + }, + "generation": { + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", + "type": "integer", + "format": "int64" + }, + "labels": { + "description": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels", + "type": "object", + "additionalProperties": { + "type": "string", + "default": "" + } + }, + "managedFields": { + "description": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.", + "type": "array", + "items": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry" + } + ] + }, + "x-kubernetes-list-type": "atomic" + }, + "name": { + "description": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names", + "type": "string" + }, + "namespace": { + "description": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces", + "type": "string" + }, + "ownerReferences": { + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.", + "type": "array", + "items": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference" + } + ] + }, + "x-kubernetes-list-map-keys": [ + "uid" + ], + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "uid", + "x-kubernetes-patch-strategy": "merge" + }, + "resourceVersion": { + "description": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", + "type": "string" + }, + "uid": { + "description": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": { + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", + "type": "object", + "required": [ + "apiVersion", + "kind", + "name", + "uid" + ], + "properties": { + "apiVersion": { + "description": "API version of the referent.", + "type": "string", + "default": "" + }, + "blockOwnerDeletion": { + "description": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.", + "type": "boolean" + }, + "controller": { + "description": "If true, this reference points to the managing controller.", + "type": "boolean" + }, + "kind": { + "description": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string", + "default": "" + }, + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names", + "type": "string", + "default": "" + }, + "uid": { + "description": "UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", + "type": "string", + "default": "" + } + }, + "x-kubernetes-map-type": "atomic" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Patch": { + "description": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions": { + "description": "Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.", + "type": "object", + "properties": { + "resourceVersion": { + "description": "Specifies the target ResourceVersion", + "type": "string" + }, + "uid": { + "description": "Specifies the target UID.", + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Status": { + "description": "Status is a return value for calls that don't return other objects.", + "type": "object", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "code": { + "description": "Suggested HTTP return code for this status, 0 if not set.", + "type": "integer", + "format": "int32" + }, + "details": { + "description": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.", + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails" + } + ], + "x-kubernetes-list-type": "atomic" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "message": { + "description": "A human-readable description of the status of this operation.", + "type": "string" + }, + "metadata": { + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ] + }, + "reason": { + "description": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.", + "type": "string" + }, + "status": { + "description": "Status of the operation. One of: \"Success\" or \"Failure\". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause": { + "description": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.", + "type": "object", + "properties": { + "field": { + "description": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"", + "type": "string" + }, + "message": { + "description": "A human-readable description of the cause of the error. This field may be presented as-is to a reader.", + "type": "string" + }, + "reason": { + "description": "A machine-readable description of the cause of the error. If this value is empty there is no information available.", + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails": { + "description": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", + "type": "object", + "properties": { + "causes": { + "description": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", + "type": "array", + "items": { + "default": {}, + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause" + } + ] + }, + "x-kubernetes-list-type": "atomic" + }, + "group": { + "description": "The group attribute of the resource associated with the status StatusReason.", + "type": "string" + }, + "kind": { + "description": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "description": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", + "type": "string" + }, + "retryAfterSeconds": { + "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.", + "type": "integer", + "format": "int32" + }, + "uid": { + "description": "UID of the resource. (when there is a single resource which can be described). More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Time": { + "description": "Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.", + "type": "string", + "format": "date-time" + } + } + } +} \ No newline at end of file diff --git a/pkg/tests/apis/openapi_test.go b/pkg/tests/apis/openapi_test.go index f5105589c43..9e3e4886724 100644 --- a/pkg/tests/apis/openapi_test.go +++ b/pkg/tests/apis/openapi_test.go @@ -32,6 +32,7 @@ func TestIntegrationOpenAPIs(t *testing.T) { featuremgmt.FlagGrafanaAdvisor, featuremgmt.FlagKubernetesAlertingRules, featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs, // all datasources + featuremgmt.FlagKubernetesShortURLs, }, }) @@ -98,6 +99,9 @@ func TestIntegrationOpenAPIs(t *testing.T) { }, { Group: "rules.alerting.grafana.app", Version: "v0alpha1", + }, { + Group: "shorturl.grafana.app", + Version: "v1alpha1", }} for _, gv := range groups { VerifyOpenAPISnapshots(t, dir, gv, h) diff --git a/public/app/api/clients/shorturl/v1alpha1/baseAPI.ts b/public/app/api/clients/shorturl/v1alpha1/baseAPI.ts new file mode 100644 index 00000000000..8ded2f34c02 --- /dev/null +++ b/public/app/api/clients/shorturl/v1alpha1/baseAPI.ts @@ -0,0 +1,14 @@ +import { createApi } from '@reduxjs/toolkit/query/react'; + +import { createBaseQuery } from 'app/api/createBaseQuery'; +import { getAPIBaseURL } from 'app/api/utils'; + +export const BASE_URL = getAPIBaseURL('shorturl.grafana.app', 'v1alpha1'); + +export const api = createApi({ + reducerPath: 'shortURLAPIv1alpha1', + baseQuery: createBaseQuery({ + baseURL: BASE_URL, + }), + endpoints: () => ({}), +}); diff --git a/public/app/api/clients/shorturl/v1alpha1/endpoints.gen.ts b/public/app/api/clients/shorturl/v1alpha1/endpoints.gen.ts new file mode 100644 index 00000000000..ad9c2da0884 --- /dev/null +++ b/public/app/api/clients/shorturl/v1alpha1/endpoints.gen.ts @@ -0,0 +1,582 @@ +import { api } from './baseAPI'; +export const addTagTypes = ['API Discovery', 'ShortURL'] as const; +const injectedRtkApi = api + .enhanceEndpoints({ + addTagTypes, + }) + .injectEndpoints({ + endpoints: (build) => ({ + getApiResources: build.query({ + query: () => ({ url: `/apis/shorturl.grafana.app/v1alpha1/` }), + providesTags: ['API Discovery'], + }), + listShortUrl: build.query({ + query: (queryArg) => ({ + url: `/shorturls`, + params: { + pretty: queryArg.pretty, + allowWatchBookmarks: queryArg.allowWatchBookmarks, + continue: queryArg['continue'], + fieldSelector: queryArg.fieldSelector, + labelSelector: queryArg.labelSelector, + limit: queryArg.limit, + resourceVersion: queryArg.resourceVersion, + resourceVersionMatch: queryArg.resourceVersionMatch, + sendInitialEvents: queryArg.sendInitialEvents, + timeoutSeconds: queryArg.timeoutSeconds, + watch: queryArg.watch, + }, + }), + providesTags: ['ShortURL'], + }), + createShortUrl: build.mutation({ + query: (queryArg) => ({ + url: `/shorturls`, + method: 'POST', + body: queryArg.shortUrl, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['ShortURL'], + }), + deletecollectionShortUrl: build.mutation({ + query: (queryArg) => ({ + url: `/shorturls`, + method: 'DELETE', + params: { + pretty: queryArg.pretty, + continue: queryArg['continue'], + dryRun: queryArg.dryRun, + fieldSelector: queryArg.fieldSelector, + gracePeriodSeconds: queryArg.gracePeriodSeconds, + ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, + labelSelector: queryArg.labelSelector, + limit: queryArg.limit, + orphanDependents: queryArg.orphanDependents, + propagationPolicy: queryArg.propagationPolicy, + resourceVersion: queryArg.resourceVersion, + resourceVersionMatch: queryArg.resourceVersionMatch, + sendInitialEvents: queryArg.sendInitialEvents, + timeoutSeconds: queryArg.timeoutSeconds, + }, + }), + invalidatesTags: ['ShortURL'], + }), + getShortUrl: build.query({ + query: (queryArg) => ({ + url: `/shorturls/${queryArg.name}`, + params: { + pretty: queryArg.pretty, + }, + }), + providesTags: ['ShortURL'], + }), + replaceShortUrl: build.mutation({ + query: (queryArg) => ({ + url: `/shorturls/${queryArg.name}`, + method: 'PUT', + body: queryArg.shortUrl, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['ShortURL'], + }), + deleteShortUrl: build.mutation({ + query: (queryArg) => ({ + url: `/shorturls/${queryArg.name}`, + method: 'DELETE', + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + gracePeriodSeconds: queryArg.gracePeriodSeconds, + ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, + orphanDependents: queryArg.orphanDependents, + propagationPolicy: queryArg.propagationPolicy, + }, + }), + invalidatesTags: ['ShortURL'], + }), + updateShortUrl: build.mutation({ + query: (queryArg) => ({ + url: `/shorturls/${queryArg.name}`, + method: 'PATCH', + body: queryArg.patch, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + force: queryArg.force, + }, + }), + invalidatesTags: ['ShortURL'], + }), + getShortUrlStatus: build.query({ + query: (queryArg) => ({ + url: `/shorturls/${queryArg.name}/status`, + params: { + pretty: queryArg.pretty, + }, + }), + providesTags: ['ShortURL'], + }), + replaceShortUrlStatus: build.mutation({ + query: (queryArg) => ({ + url: `/shorturls/${queryArg.name}/status`, + method: 'PUT', + body: queryArg.shortUrl, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['ShortURL'], + }), + updateShortUrlStatus: build.mutation({ + query: (queryArg) => ({ + url: `/shorturls/${queryArg.name}/status`, + method: 'PATCH', + body: queryArg.patch, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + force: queryArg.force, + }, + }), + invalidatesTags: ['ShortURL'], + }), + }), + overrideExisting: false, + }); +export { injectedRtkApi as generatedAPI }; +export type GetApiResourcesApiResponse = /** status 200 OK */ ApiResourceList; +export type GetApiResourcesApiArg = void; +export type ListShortUrlApiResponse = /** status 200 OK */ ShortUrlList; +export type ListShortUrlApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean; + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string; + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string; + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string; + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number; + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string; + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string; + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean; + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number; + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean; +}; +export type CreateShortUrlApiResponse = /** status 200 OK */ + | ShortUrl + | /** status 201 Created */ ShortUrl + | /** status 202 Accepted */ ShortUrl; +export type CreateShortUrlApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + shortUrl: ShortUrl; +}; +export type DeletecollectionShortUrlApiResponse = /** status 200 OK */ Status; +export type DeletecollectionShortUrlApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string; + /** The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. */ + gracePeriodSeconds?: number; + /** if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it */ + ignoreStoreReadErrorWithClusterBreakingPotential?: boolean; + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string; + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number; + /** Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. */ + orphanDependents?: boolean; + /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ + propagationPolicy?: string; + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string; + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string; + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean; + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number; +}; +export type GetShortUrlApiResponse = /** status 200 OK */ ShortUrl; +export type GetShortUrlApiArg = { + /** name of the ShortURL */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; +}; +export type ReplaceShortUrlApiResponse = /** status 200 OK */ ShortUrl | /** status 201 Created */ ShortUrl; +export type ReplaceShortUrlApiArg = { + /** name of the ShortURL */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + shortUrl: ShortUrl; +}; +export type DeleteShortUrlApiResponse = /** status 200 OK */ Status | /** status 202 Accepted */ Status; +export type DeleteShortUrlApiArg = { + /** name of the ShortURL */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. */ + gracePeriodSeconds?: number; + /** if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it */ + ignoreStoreReadErrorWithClusterBreakingPotential?: boolean; + /** Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. */ + orphanDependents?: boolean; + /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ + propagationPolicy?: string; +}; +export type UpdateShortUrlApiResponse = /** status 200 OK */ ShortUrl | /** status 201 Created */ ShortUrl; +export type UpdateShortUrlApiArg = { + /** name of the ShortURL */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ + force?: boolean; + patch: Patch; +}; +export type GetShortUrlStatusApiResponse = /** status 200 OK */ ShortUrl; +export type GetShortUrlStatusApiArg = { + /** name of the ShortURL */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; +}; +export type ReplaceShortUrlStatusApiResponse = /** status 200 OK */ ShortUrl | /** status 201 Created */ ShortUrl; +export type ReplaceShortUrlStatusApiArg = { + /** name of the ShortURL */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + shortUrl: ShortUrl; +}; +export type UpdateShortUrlStatusApiResponse = /** status 200 OK */ ShortUrl | /** status 201 Created */ ShortUrl; +export type UpdateShortUrlStatusApiArg = { + /** name of the ShortURL */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ + force?: boolean; + patch: Patch; +}; +export type ApiResource = { + /** categories is a list of the grouped resources this resource belongs to (e.g. 'all') */ + categories?: string[]; + /** group is the preferred group of the resource. Empty implies the group of the containing resource list. For subresources, this may have a different value, for example: Scale". */ + group?: string; + /** kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo') */ + kind: string; + /** name is the plural name of the resource. */ + name: string; + /** namespaced indicates if a resource is namespaced or not. */ + namespaced: boolean; + /** shortNames is a list of suggested short names of the resource. */ + shortNames?: string[]; + /** singularName is the singular name of the resource. This allows clients to handle plural and singular opaquely. The singularName is more correct for reporting status on a single item and both singular and plural are allowed from the kubectl CLI interface. */ + singularName: string; + /** The hash value of the storage version, the version this resource is converted to when written to the data store. Value must be treated as opaque by clients. Only equality comparison on the value is valid. This is an alpha feature and may change or be removed in the future. The field is populated by the apiserver only if the StorageVersionHash feature gate is enabled. This field will remain optional even if it graduates. */ + storageVersionHash?: string; + /** verbs is a list of supported kube verbs (this includes get, list, watch, create, update, patch, delete, deletecollection, and proxy) */ + verbs: string[]; + /** version is the preferred version of the resource. Empty implies the version of the containing resource list For subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)". */ + version?: string; +}; +export type ApiResourceList = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + /** groupVersion is the group and version this APIResourceList is for. */ + groupVersion: string; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + /** resources contains the name of the resources and if they are namespaced. */ + resources: ApiResource[]; +}; +export type Time = string; +export type FieldsV1 = object; +export type ManagedFieldsEntry = { + /** APIVersion defines the version of this resource that this field set applies to. The format is "group/version" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted. */ + apiVersion?: string; + /** FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: "FieldsV1" */ + fieldsType?: string; + /** FieldsV1 holds the first JSON version format as described in the "FieldsV1" type. */ + fieldsV1?: FieldsV1; + /** Manager is an identifier of the workflow managing these fields. */ + manager?: string; + /** Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'. */ + operation?: string; + /** Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource. */ + subresource?: string; + /** Time is the timestamp of when the ManagedFields entry was added. The timestamp will also be updated if a field is added, the manager changes any of the owned fields value or removes a field. The timestamp does not update when a field is removed from the entry because another manager took it over. */ + time?: Time; +}; +export type OwnerReference = { + /** API version of the referent. */ + apiVersion: string; + /** If true, AND if the owner has the "foregroundDeletion" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned. */ + blockOwnerDeletion?: boolean; + /** If true, this reference points to the managing controller. */ + controller?: boolean; + /** Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind: string; + /** Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names */ + name: string; + /** UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ + uid: string; +}; +export type ObjectMeta = { + /** Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations */ + annotations?: { + [key: string]: string; + }; + /** CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + + Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata */ + creationTimestamp?: Time; + /** Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only. */ + deletionGracePeriodSeconds?: number; + /** DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested. + + Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata */ + deletionTimestamp?: Time; + /** Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list. */ + finalizers?: string[]; + /** GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server. + + If this field is specified and the generated name exists, the server will return a 409. + + Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency */ + generateName?: string; + /** A sequence number representing a specific generation of the desired state. Populated by the system. Read-only. */ + generation?: number; + /** Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels */ + labels?: { + [key: string]: string; + }; + /** ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object. */ + managedFields?: ManagedFieldsEntry[]; + /** Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names */ + name?: string; + /** Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty. + + Must be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces */ + namespace?: string; + /** List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller. */ + ownerReferences?: OwnerReference[]; + /** An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources. + + Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency */ + resourceVersion?: string; + /** Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. */ + selfLink?: string; + /** UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations. + + Populated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ + uid?: string; +}; +export type ShortUrlSpec = { + /** The original path to where the short url is linking too e.g. https://localhost:3000/eer8i1kictngga/new-dashboard-with-lib-panel */ + path: string; +}; +export type ShortUrlStatus = { + /** additionalFields is reserved for future use */ + additionalFields?: { + [key: string]: any; + }; + /** The last time the short URL was used, 0 is the initial value */ + lastSeenAt: number; + /** operatorStates is a map of operator ID to operator state evaluations. + Any operator which consumes this kind SHOULD add its state evaluation information to this field. */ + operatorStates?: { + [key: string]: { + /** descriptiveState is an optional more descriptive state field which has no requirements on format */ + descriptiveState?: string; + /** details contains any extra information that is operator-specific */ + details?: { + [key: string]: any; + }; + /** lastEvaluation is the ResourceVersion last evaluated */ + lastEvaluation: string; + /** state describes the state of the lastEvaluation. + It is limited to three possible states for machine evaluation. */ + state: 'success' | 'in_progress' | 'failed'; + }; + }; +}; +export type ShortUrl = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + metadata?: ObjectMeta; + spec?: ShortUrlSpec; + status?: ShortUrlStatus; +}; +export type ListMeta = { + /** continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message. */ + continue?: string; + /** remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact. */ + remainingItemCount?: number; + /** String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency */ + resourceVersion?: string; + /** Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. */ + selfLink?: string; +}; +export type ShortUrlList = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + items: ShortUrl[]; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + metadata: ListMeta; +}; +export type StatusCause = { + /** The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional. + + Examples: + "name" - the field "name" on the current resource + "items[0].name" - the field "name" on the first array entry in "items" */ + field?: string; + /** A human-readable description of the cause of the error. This field may be presented as-is to a reader. */ + message?: string; + /** A machine-readable description of the cause of the error. If this value is empty there is no information available. */ + reason?: string; +}; +export type StatusDetails = { + /** The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes. */ + causes?: StatusCause[]; + /** The group attribute of the resource associated with the status StatusReason. */ + group?: string; + /** The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + /** The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described). */ + name?: string; + /** If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. */ + retryAfterSeconds?: number; + /** UID of the resource. (when there is a single resource which can be described). More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ + uid?: string; +}; +export type Status = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + /** Suggested HTTP return code for this status, 0 if not set. */ + code?: number; + /** Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type. */ + details?: StatusDetails; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + /** A human-readable description of the status of this operation. */ + message?: string; + /** Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + metadata?: ListMeta; + /** A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it. */ + reason?: string; + /** Status of the operation. One of: "Success" or "Failure". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status */ + status?: string; +}; +export type Patch = object; diff --git a/public/app/api/clients/shorturl/v1alpha1/index.ts b/public/app/api/clients/shorturl/v1alpha1/index.ts new file mode 100644 index 00000000000..415f7a0c474 --- /dev/null +++ b/public/app/api/clients/shorturl/v1alpha1/index.ts @@ -0,0 +1,3 @@ +import { generatedAPI } from './endpoints.gen'; + +export const shortURLAPIv1alpha1 = generatedAPI.enhanceEndpoints({}); diff --git a/public/app/core/reducers/root.ts b/public/app/core/reducers/root.ts index f740febeeae..056c4bb0015 100644 --- a/public/app/core/reducers/root.ts +++ b/public/app/core/reducers/root.ts @@ -4,6 +4,7 @@ import { AnyAction, combineReducers } from 'redux'; import { alertingAPI as alertingPackageAPI } from '@grafana/alerting/unstable'; import { dashboardAPIv0alpha1 } from 'app/api/clients/dashboard/v0alpha1'; import { rulesAPIv0alpha1 } from 'app/api/clients/rules/v0alpha1'; +import { shortURLAPIv1alpha1 } from 'app/api/clients/shorturl/v1alpha1'; import sharedReducers from 'app/core/reducers'; import ldapReducers from 'app/features/admin/state/reducers'; import alertingReducers from 'app/features/alerting/state/reducers'; @@ -75,6 +76,7 @@ const rootReducers = { [advisorAPIv0alpha1.reducerPath]: advisorAPIv0alpha1.reducer, [dashboardAPIv0alpha1.reducerPath]: dashboardAPIv0alpha1.reducer, [rulesAPIv0alpha1.reducerPath]: rulesAPIv0alpha1.reducer, + [shortURLAPIv1alpha1.reducerPath]: shortURLAPIv1alpha1.reducer, // PLOP_INJECT_REDUCER // Used by the API client generator }; diff --git a/public/app/core/utils/shortLinks.test.ts b/public/app/core/utils/shortLinks.test.ts index 406aa73e99f..d07c4940680 100644 --- a/public/app/core/utils/shortLinks.test.ts +++ b/public/app/core/utils/shortLinks.test.ts @@ -2,14 +2,18 @@ import { LogRowModel } from '@grafana/data'; import { config } from '@grafana/runtime'; import { createLogRow } from 'app/features/logs/components/mocks/logRow'; -import { createShortLink, createAndCopyShortLink, getLogsPermalinkRange } from './shortLinks'; +import { ShortURL } from '../../../../apps/shorturl/plugin/src/generated/shorturl/v1alpha1/shorturl_object_gen'; +import { defaultSpec } from '../../../../apps/shorturl/plugin/src/generated/shorturl/v1alpha1/types.spec.gen'; +import { defaultStatus } from '../../../../apps/shorturl/plugin/src/generated/shorturl/v1alpha1/types.status.gen'; + +import { createShortLink, createAndCopyShortLink, getLogsPermalinkRange, buildShortUrl } from './shortLinks'; jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), getBackendSrv: () => { return { post: () => { - return Promise.resolve({ url: 'www.short.com' }); + return Promise.resolve({ url: 'www.test.grafana.com/goto/bewyw48durgu8d?orgId=1' }); }, }; }, @@ -24,12 +28,21 @@ beforeEach(() => { }); document.execCommand = jest.fn(); + config.featureToggles.useKubernetesShortURLsAPI = false; }); describe('createShortLink', () => { it('creates short link', async () => { - const shortUrl = await createShortLink('www.verylonglinkwehavehere.com'); - expect(shortUrl).toBe('www.short.com'); + const shortUrl = await createShortLink('d/edhmipji89b0gb/welcome?orgId=1&from=now-6h&to=now&timezone=browser'); + expect(shortUrl).toBe('www.test.grafana.com/goto/bewyw48durgu8d?orgId=1'); + }); +}); + +describe('createShortLink using k8s API', () => { + it('creates short link', async () => { + config.featureToggles.useKubernetesShortURLsAPI = true; + const shortUrl = await createShortLink('d/edhmipji89b0gb/welcome?orgId=1&from=now-6h&to=now&timezone=browser'); + expect(shortUrl).toBe('www.test.grafana.com/goto/bewyw48durgu8d?orgId=1'); }); }); @@ -41,14 +54,14 @@ describe('createAndCopyShortLink', () => { }, }); document.execCommand = jest.fn(); - await createAndCopyShortLink('www.verylonglinkwehavehere.com'); + await createAndCopyShortLink('www.test.grafana.com'); expect(document.execCommand).toHaveBeenCalledWith('copy'); }); it('copies short link to clipboard via navigator.clipboard.writeText when ClipboardItem is undefined', async () => { window.isSecureContext = true; - await createAndCopyShortLink('www.verylonglinkwehavehere.com'); - expect(navigator.clipboard.writeText).toHaveBeenCalledWith('www.short.com'); + await createAndCopyShortLink('d/edhmipji89b0gb/welcome?orgId=1&from=now-6h&to=now&timezone=browser'); + expect(navigator.clipboard.writeText).toHaveBeenCalledWith('www.test.grafana.com/goto/bewyw48durgu8d?orgId=1'); }); it('copies short link to clipboard via navigator.clipboard.write and ClipboardItem when it is defined', async () => { @@ -59,11 +72,61 @@ describe('createAndCopyShortLink', () => { supports: jest.fn().mockReturnValue(true), // eslint-disable-next-line })) as any; - await createAndCopyShortLink('www.verylonglinkwehavehere.com'); + await createAndCopyShortLink('d/edhmipji89b0gb/welcome?orgId=1&from=now-6h&to=now&timezone=browser'); expect(navigator.clipboard.write).toHaveBeenCalled(); }); }); +describe('buildShortUrl', () => { + // Mock window.location + const mockLocation = { + protocol: 'https:', + host: 'grafana.example.com', + }; + + beforeEach(() => { + Object.defineProperty(window, 'location', { + value: mockLocation, + writable: true, + }); + config.appSubUrl = ''; + }); + + it('builds short URL with metadata name and namespace', () => { + const shortUrl: ShortURL = { + kind: 'ShortURL', + apiVersion: 'shorturl.grafana.app/v1alpha1', + metadata: { + name: 'abc123def', + namespace: 'org-5', + }, + spec: defaultSpec(), + status: defaultStatus(), + }; + + const result = buildShortUrl(shortUrl); + expect(result).toBe('https://grafana.example.com/goto/abc123def?orgId=org-5'); + }); + + it('builds short URL with appSubUrl configured', () => { + config.appSubUrl = '/grafana'; + + const shortUrl: ShortURL = { + kind: 'ShortURL', + apiVersion: 'shorturl.grafana.app/v1alpha1', + metadata: { + name: 'xyz789', + namespace: 'org-1', + }, + spec: defaultSpec(), + status: defaultStatus(), + }; + + const result = buildShortUrl(shortUrl); + expect(result).toBe('https://grafana.example.com/grafana/goto/xyz789?orgId=org-1'); + }); +}); + describe('getLogsPermalinkRange', () => { let row: LogRowModel, rows: LogRowModel[]; beforeEach(() => { diff --git a/public/app/core/utils/shortLinks.ts b/public/app/core/utils/shortLinks.ts index 53ebf12af8b..573cfff2627 100644 --- a/public/app/core/utils/shortLinks.ts +++ b/public/app/core/utils/shortLinks.ts @@ -10,6 +10,8 @@ import { DashboardScene } from 'app/features/dashboard-scene/scene/DashboardScen import { getDashboardUrl } from 'app/features/dashboard-scene/utils/getDashboardUrl'; import { dispatch } from 'app/store/store'; +import { ShortURL } from '../../../../apps/shorturl/plugin/src/generated/shorturl/v1alpha1/shorturl_object_gen'; +import { BASE_URL as k8sShortURLBaseAPI } from '../../api/clients/shorturl/v1alpha1/baseAPI'; import { ShareLinkConfiguration } from '../../features/dashboard-scene/sharing/ShareButton/utils'; import { copyStringToClipboard } from './explore'; @@ -18,6 +20,13 @@ function buildHostUrl() { return `${window.location.protocol}//${window.location.host}${config.appSubUrl}`; } +export function buildShortUrl(k8sShortUrl: ShortURL) { + const key = k8sShortUrl.metadata.name; + const orgId = k8sShortUrl.metadata.namespace; + const hostUrl = buildHostUrl(); + return `${hostUrl}/goto/${key}?orgId=${orgId}`; +} + function getRelativeURLPath(url: string) { let path = url.replace(buildHostUrl(), ''); return path.startsWith('/') ? path.substring(1, path.length) : path; @@ -25,10 +34,23 @@ function getRelativeURLPath(url: string) { export const createShortLink = memoizeOne(async function (path: string) { try { - const shortLink = await getBackendSrv().post(`/api/short-urls`, { - path: getRelativeURLPath(path), - }); - return shortLink.url; + if (config.featureToggles.useKubernetesShortURLsAPI) { + // TODO: this is not ideal, we should use the RTK API but we can't call a hook from here and + // this util function is being called from several places, will require a bigger refactor including some code that + // is deprecated. + const k8sShortUrl: ShortURL = await getBackendSrv().post(`${k8sShortURLBaseAPI}/shorturls`, { + spec: { + path: getRelativeURLPath(path), + }, + }); + return buildShortUrl(k8sShortUrl); + } else { + // Old short URL API + const shortLink = await getBackendSrv().post(`/api/short-urls`, { + path: getRelativeURLPath(path), + }); + return shortLink.url; + } } catch (err) { console.error('Error when creating shortened link: ', err); dispatch(notifyApp(createErrorNotification('Error generating shortened link'))); diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index 0c812f3c90d..0eeb3c0f352 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -5,6 +5,7 @@ import { Middleware } from 'redux'; import { alertingAPI as alertingPackageAPI } from '@grafana/alerting/unstable'; import { dashboardAPIv0alpha1 } from 'app/api/clients/dashboard/v0alpha1'; import { rulesAPIv0alpha1 } from 'app/api/clients/rules/v0alpha1'; +import { shortURLAPIv1alpha1 } from 'app/api/clients/shorturl/v1alpha1'; import { browseDashboardsAPI } from 'app/features/browse-dashboards/api/browseDashboardsAPI'; import { publicDashboardApi } from 'app/features/dashboard/api/publicDashboardApi'; import { cloudMigrationAPI } from 'app/features/migrate-to-cloud/api'; @@ -57,6 +58,7 @@ export function configureStore(initialState?: Partial) { advisorAPIv0alpha1.middleware, dashboardAPIv0alpha1.middleware, rulesAPIv0alpha1.middleware, + shortURLAPIv1alpha1.middleware, // PLOP_INJECT_MIDDLEWARE // Used by the API client generator ...extraMiddleware diff --git a/scripts/generate-rtk-apis.ts b/scripts/generate-rtk-apis.ts index 31e850ee3cd..d5b2529ea19 100644 --- a/scripts/generate-rtk-apis.ts +++ b/scripts/generate-rtk-apis.ts @@ -90,6 +90,11 @@ const config: ConfigFile = { tag: true, }, + '../public/app/api/clients/shorturl/v1alpha1/endpoints.gen.ts': { + apiFile: '../public/app/api/clients/shorturl/v1alpha1/baseAPI.ts', + schemaFile: '../data/openapi/shorturl.grafana.app-v1alpha1.json', + tag: true, + }, '../public/app/api/clients/rules/v0alpha1/endpoints.gen.ts': { apiFile: '../public/app/api/clients/rules/v0alpha1/baseAPI.ts', schemaFile: '../data/openapi/rules.alerting.grafana.app-v0alpha1.json', From a3c95e1375ea1e7cdcc76d8d9bc1e784da036cdf Mon Sep 17 00:00:00 2001 From: "grafana-pr-automation[bot]" <140550294+grafana-pr-automation[bot]@users.noreply.github.com> Date: Sun, 14 Sep 2025 00:30:21 +0000 Subject: [PATCH 48/48] I18n: Download translations from Crowdin (#111052) New Crowdin translations by GitHub Action Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- public/locales/cs-CZ/grafana.json | 54 ++++++++++++++++++++++++----- public/locales/de-DE/grafana.json | 50 +++++++++++++++++++++----- public/locales/es-ES/grafana.json | 50 +++++++++++++++++++++----- public/locales/fr-FR/grafana.json | 50 +++++++++++++++++++++----- public/locales/hu-HU/grafana.json | 50 +++++++++++++++++++++----- public/locales/id-ID/grafana.json | 48 ++++++++++++++++++++----- public/locales/it-IT/grafana.json | 50 +++++++++++++++++++++----- public/locales/ja-JP/grafana.json | 48 ++++++++++++++++++++----- public/locales/ko-KR/grafana.json | 48 ++++++++++++++++++++----- public/locales/nl-NL/grafana.json | 50 +++++++++++++++++++++----- public/locales/pl-PL/grafana.json | 54 ++++++++++++++++++++++++----- public/locales/pt-BR/grafana.json | 50 +++++++++++++++++++++----- public/locales/pt-PT/grafana.json | 50 +++++++++++++++++++++----- public/locales/ru-RU/grafana.json | 54 ++++++++++++++++++++++++----- public/locales/sv-SE/grafana.json | 50 +++++++++++++++++++++----- public/locales/tr-TR/grafana.json | 50 +++++++++++++++++++++----- public/locales/zh-Hans/grafana.json | 48 ++++++++++++++++++++----- public/locales/zh-Hant/grafana.json | 48 ++++++++++++++++++++----- 18 files changed, 758 insertions(+), 144 deletions(-) diff --git a/public/locales/cs-CZ/grafana.json b/public/locales/cs-CZ/grafana.json index 78326412626..6aaa48868de 100644 --- a/public/locales/cs-CZ/grafana.json +++ b/public/locales/cs-CZ/grafana.json @@ -9697,10 +9697,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Deduplikace", - "disable-highlighting": "Zakázat zvýraznění", "disable-prettify-json": "Sbalit protokoly JSON", - "display-level": "Zobrazit úrovně", "display-level-all": "Všechny úrovně", "download": "Stáhnout protokoly", "download-logs": { @@ -9708,18 +9707,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Povolit zvýraznění", "escape-newlines": "Opravit nesprávně uniklé sekvence nového řádku a záložek v řádcích protokolu", - "font-size-default": "Použít malou velikost písma", - "font-size-small": "Použít výchozí velikost písma", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Zavřít vyhledávání", "hide-timestamps": "Skrýt časová razítka", "hide-unique-labels": "Skrýt jedinečné štítky", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Seřazeno od nejnovějších protokolů – kliknutím zobrazíte nejstarší protokoly jako první", "oldest-first": "Seřazeno od nejstarších protokolů – kliknutím zobrazíte nejnovější protokoly jako první", @@ -9735,8 +9755,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Rozbalit řádky", "wrap-lines": "Zalomit řádky" @@ -11433,7 +11463,15 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Vašemu dotazu neodpovídají žádné výsledky", - "placeholder-search": "Hledat" + "placeholder-search": "Hledat", + "all-resources-managed_one": "", + "all-resources-managed_few": "", + "all-resources-managed_many": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_few": "", + "partial-managed_many": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/de-DE/grafana.json b/public/locales/de-DE/grafana.json index 75c5062dcf8..ee2a8d283f3 100644 --- a/public/locales/de-DE/grafana.json +++ b/public/locales/de-DE/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Deduplizierung", - "disable-highlighting": "Markierung deaktivieren", "disable-prettify-json": "JSON-Logs einklappen", - "display-level": "Ebenen anzeigen", "display-level-all": "Alle Ebenen", "download": "Logs herunterladen", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Markierung aktivieren", "escape-newlines": "Falsch dargestellte Zeilenumbrüche und Tab-Sequenzen in Log-Zeilen korrigieren", - "font-size-default": "Kleine Schriftgröße verwenden", - "font-size-small": "Standardschriftgröße verwenden", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Suche schließen", "hide-timestamps": "Zeitstempel ausblenden", "hide-unique-labels": "Eindeutige Labels ausblenden", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Sortiert nach neuesten Logs zuerst – klicken Sie, um die ältesten zuerst anzuzeigen", "oldest-first": "Sortiert nach ältesten Logs zuerst – klicken Sie, um die neuesten zuerst anzuzeigen", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Zeilenumbruch aufheben", "wrap-lines": "Zeilen umbrechen" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Keine passenden Ergebnisse zu Ihrer Abfrage", - "placeholder-search": "Suche" + "placeholder-search": "Suche", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/es-ES/grafana.json b/public/locales/es-ES/grafana.json index 7f10dcdd53c..1d5d25b0449 100644 --- a/public/locales/es-ES/grafana.json +++ b/public/locales/es-ES/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Deduplicación", - "disable-highlighting": "Desactivar resaltado", "disable-prettify-json": "Contraer logs JSON", - "display-level": "Mostrar niveles", "display-level-all": "Todos los niveles", "download": "Descargar registros", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Activar resaltado", "escape-newlines": "Corregir las secuencias de tabulación y de nueva línea que escaparon incorrectamente en las líneas de log", - "font-size-default": "Utilizar tamaño de fuente pequeño", - "font-size-small": "Utilizar tamaño de fuente predeterminado", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Cerrar la búsqueda", "hide-timestamps": "Ocultar marcas de tiempo", "hide-unique-labels": "Ocultar etiquetas únicas", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Ordenado por los logs más nuevos primero: haga clic para mostrar los más antiguos primero", "oldest-first": "Ordenado por los logs más antiguos primero: haga clic para mostrar los más nuevos primero", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Desajustar líneas", "wrap-lines": "Ajustar líneas" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "No hay resultados que coincidan con tu consulta", - "placeholder-search": "Buscar" + "placeholder-search": "Buscar", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/fr-FR/grafana.json b/public/locales/fr-FR/grafana.json index eec2d831c88..87c4f491a33 100644 --- a/public/locales/fr-FR/grafana.json +++ b/public/locales/fr-FR/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Déduplication", - "disable-highlighting": "Désactiver la surbrillance", "disable-prettify-json": "Réduire les journaux JSON", - "display-level": "Afficher les niveaux", "display-level-all": "Tous les niveaux", "download": "Télécharger les journaux", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Activer la surbrillance", "escape-newlines": "Correction des séquences de sauts de ligne et de tabulations incorrectement échappées dans les lignes du journal", - "font-size-default": "Utiliser une petite taille de police", - "font-size-small": "Utiliser la taille de police par défaut", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Fermer la recherche", "hide-timestamps": "Masquer les horodatages", "hide-unique-labels": "Masquer les étiquettes uniques", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Trié par les journaux les plus récents en premier - Cliquez pour afficher les plus anciens en premier", "oldest-first": "Trié par les journaux les plus anciens en premier - Cliquez pour afficher les plus récents en premier", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Dérouler les lignes", "wrap-lines": "Enrouler les lignes" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Aucun résultat ne correspond à votre requête", - "placeholder-search": "Rechercher" + "placeholder-search": "Rechercher", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/hu-HU/grafana.json b/public/locales/hu-HU/grafana.json index bfdb13e2708..291d5967b6e 100644 --- a/public/locales/hu-HU/grafana.json +++ b/public/locales/hu-HU/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Duplikálás megszüntetése", - "disable-highlighting": "Kiemelés letiltása", "disable-prettify-json": "JSON-naplók összecsukása", - "display-level": "Szintek megjelenítése", "display-level-all": "Minden szint", "download": "Naplók letöltése", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Kiemelés engedélyezése", "escape-newlines": "Helytelenül értelmezett újsor- és tabulátorkarakteres szekvenciák javítása a naplósorokban", - "font-size-default": "Kis betűméret használata", - "font-size-small": "Alapértelmezett betűméret használata", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Keresés bezárása", "hide-timestamps": "Időbélyegek elrejtése", "hide-unique-labels": "Egyedi címkék elrejtése", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Rendezés a legújabb naplók szerint – kattintson, hogy a legrégebbi naplók jelenjenek meg elsőként", "oldest-first": "Rendezés a legrégebbi naplók szerint – kattintson, hogy a legújabb naplók jelenjenek meg elsőként", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Sortörés megszüntetése", "wrap-lines": "Sortörés" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Nincs találat a lekérdezésre", - "placeholder-search": "Keresés" + "placeholder-search": "Keresés", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/id-ID/grafana.json b/public/locales/id-ID/grafana.json index f36f2d86a5f..a4d08d24cb8 100644 --- a/public/locales/id-ID/grafana.json +++ b/public/locales/id-ID/grafana.json @@ -9601,10 +9601,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Deduplikasi", - "disable-highlighting": "Nonaktifkan penyorotan", "disable-prettify-json": "Ciutkan log JSON", - "display-level": "Tampilkan level", "display-level-all": "Semua level", "download": "Unduh log", "download-logs": { @@ -9612,18 +9611,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Aktifkan penyorotan", "escape-newlines": "Perbaiki escape sequence baris baru dan tab yang salah di baris log", - "font-size-default": "Gunakan ukuran fon kecil", - "font-size-small": "Gunakan ukuran fon default", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Tutup pencarian", "hide-timestamps": "Sembunyikan stempel waktu", "hide-unique-labels": "Sembunyikan label unik", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Diurutkan berdasarkan log terbaru lebih dulu - Klik untuk menampilkan yang paling lama lebih dulu", "oldest-first": "Diurutkan berdasarkan log paling lama lebih dulu - Klik untuk menampilkan yang terbaru lebih dulu", @@ -9639,8 +9659,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Batal terapkan wrap pada baris", "wrap-lines": "Terapkan wrap pada baris" @@ -11316,7 +11346,9 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Tidak ada hasil yang cocok dengan kueri Anda", - "placeholder-search": "Cari" + "placeholder-search": "Cari", + "all-resources-managed_other": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/it-IT/grafana.json b/public/locales/it-IT/grafana.json index 88b4480c1e7..56fa6d29283 100644 --- a/public/locales/it-IT/grafana.json +++ b/public/locales/it-IT/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Deduplicazione", - "disable-highlighting": "Disabilita evidenziazione", "disable-prettify-json": "Riduci i registri JSON", - "display-level": "Visualizza livelli", "display-level-all": "Tutti i livelli", "download": "Scarica i registri", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Abilita evidenziazione", "escape-newlines": "Correggi le sequenze di nuove righe e tabulazioni non corrette nelle righe del registro", - "font-size-default": "Usa dimensione carattere piccola", - "font-size-small": "Usa dimensione carattere predefinita", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Chiudi ricerca", "hide-timestamps": "Nascondi marca temporale", "hide-unique-labels": "Nascondi etichette univoche", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Ordine: prima i registri più recenti – Fai clic per mostrare prima i meno recenti", "oldest-first": "Ordine: prima i registri meno recenti - Fai clic per mostrare prima i più recenti", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Rimuovi a capo", "wrap-lines": "A capo" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Nessun risultato corrisponde alla tua query", - "placeholder-search": "Cerca" + "placeholder-search": "Cerca", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/ja-JP/grafana.json b/public/locales/ja-JP/grafana.json index a756119bfb5..7038eb7ceb9 100644 --- a/public/locales/ja-JP/grafana.json +++ b/public/locales/ja-JP/grafana.json @@ -9601,10 +9601,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "重複排除", - "disable-highlighting": "ハイライトを無効にする", "disable-prettify-json": "JSONログを折りたたむ", - "display-level": "表示レベル", "display-level-all": "すべてのレベル", "download": "ログをダウンロード", "download-logs": { @@ -9612,18 +9611,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "ハイライトを有効にする", "escape-newlines": "ログ行で誤ってエスケープされた改行とタブシーケンスを修正", - "font-size-default": "小さいフォントサイズを使用", - "font-size-small": "デフォルトのフォントサイズを使用", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "検索を閉じる", "hide-timestamps": "タイムスタンプを非表示", "hide-unique-labels": "一意のラベルを非表示", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "最新のログ順に並び替え - クリックして最も古いログを最初に表示", "oldest-first": "古いログ順に並び替え - クリックして最新のログを最初に表示", @@ -9639,8 +9659,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "行の折り返しを解除", "wrap-lines": "行を折り返す" @@ -11316,7 +11346,9 @@ }, "folder-repository-list": { "no-results-matching-your-query": "クエリに一致する結果なし", - "placeholder-search": "検索" + "placeholder-search": "検索", + "all-resources-managed_other": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/ko-KR/grafana.json b/public/locales/ko-KR/grafana.json index 391c119f6b0..716348775d4 100644 --- a/public/locales/ko-KR/grafana.json +++ b/public/locales/ko-KR/grafana.json @@ -9601,10 +9601,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "중복 제거", - "disable-highlighting": "강조 표시 비활성화", "disable-prettify-json": "JSON 로그 접기", - "display-level": "표시 수준", "display-level-all": "모든 수준", "download": "로그 다운로드", "download-logs": { @@ -9612,18 +9611,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "강조 표시 활성화", "escape-newlines": "로그 줄에서 잘못된 줄 바꿈 및 탭 시퀀스 수정", - "font-size-default": "작은 글꼴 크기 사용", - "font-size-small": "기본 글꼴 크기 사용", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "검색 닫기", "hide-timestamps": "타임스탬프 숨기기", "hide-unique-labels": "고유 라벨 숨기기", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "최신 로그순으로 정렬 - 클릭하여 오래된 로그순으로 표시", "oldest-first": "오래된 로그순으로 정렬 - 클릭하여 최신 로그순으로 표시", @@ -9639,8 +9659,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "줄 바꿈 제거", "wrap-lines": "줄 바꿈" @@ -11316,7 +11346,9 @@ }, "folder-repository-list": { "no-results-matching-your-query": "쿼리와 일치하는 결과가 없습니다", - "placeholder-search": "검색" + "placeholder-search": "검색", + "all-resources-managed_other": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/nl-NL/grafana.json b/public/locales/nl-NL/grafana.json index c546246a335..99c5750c4a0 100644 --- a/public/locales/nl-NL/grafana.json +++ b/public/locales/nl-NL/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Dedupliceren", - "disable-highlighting": "Markeren uitschakelen", "disable-prettify-json": "JSON-logs samenvouwen", - "display-level": "Niveaus weergeven", "display-level-all": "Alle niveaus", "download": "Logs downloaden", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Markeren inschakelen", "escape-newlines": "Corrigeer onjuist escaped nieuwe lijn en tabbladsequenties in logregels", - "font-size-default": "Gebruik kleine lettergrootte", - "font-size-small": "Gebruik standaard lettergrootte", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Zoekopdracht sluiten", "hide-timestamps": "Tijdstempels verbergen", "hide-unique-labels": "Unieke labels verbergen", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Gesorteerd op nieuwste logboeken eerst - klik om oudste eerst weer te geven", "oldest-first": "Gesorteerd op oudste logboeken eerst - klik om nieuwste eerst weer te geven", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Lijnen omsluiten", "wrap-lines": "Lijnen omsluiten" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Geen resultaten die overeenkomen met je query", - "placeholder-search": "Zoeken" + "placeholder-search": "Zoeken", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/pl-PL/grafana.json b/public/locales/pl-PL/grafana.json index f2a4451488a..0bfb3a5f740 100644 --- a/public/locales/pl-PL/grafana.json +++ b/public/locales/pl-PL/grafana.json @@ -9697,10 +9697,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Deduplikacja", - "disable-highlighting": "Wyłącz wyróżnianie", "disable-prettify-json": "Zwiń logi JSON", - "display-level": "Poziomy wyświewtlania", "display-level-all": "Wszystkie poziomy", "download": "Pobierz logi", "download-logs": { @@ -9708,18 +9707,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Włącz wyróżnianie", "escape-newlines": "Napraw nieprawidłowe sekwencje znaków nowego wiersza i tabulacji we wpisach logów", - "font-size-default": "Użyj małego rozmiaru czcionki", - "font-size-small": "Użyj domyślnego rozmiaru czcionki", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Zamknij wyszukiwanie", "hide-timestamps": "Ukryj znaczniki czasu", "hide-unique-labels": "Ukryj unikalne etykiety", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Sortowanie od najnowszych wpisów dziennika – kliknij, aby wyświetlić najpierw najstarsze", "oldest-first": "Sortowanie od najstarszych wpisów dziennika – kliknij, aby wyświetlić najpierw najnowsze", @@ -9735,8 +9755,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Nie zawijaj wierszy", "wrap-lines": "Zawijaj wiersze" @@ -11433,7 +11463,15 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Brak wyników pasujących do zapytania", - "placeholder-search": "Szukaj" + "placeholder-search": "Szukaj", + "all-resources-managed_one": "", + "all-resources-managed_few": "", + "all-resources-managed_many": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_few": "", + "partial-managed_many": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/pt-BR/grafana.json b/public/locales/pt-BR/grafana.json index a5ec46da596..0f038706204 100644 --- a/public/locales/pt-BR/grafana.json +++ b/public/locales/pt-BR/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Desduplicação", - "disable-highlighting": "Desativar destaque", "disable-prettify-json": "Recolher logs JSON", - "display-level": "Exibir níveis", "display-level-all": "Todos os níveis", "download": "Baixar logs", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Ativar destaque", "escape-newlines": "Corrigir sequências de tabulação e quebra de linha adicionadas incorretamente por escape nas linhas de log", - "font-size-default": "Usar tamanho de fonte pequeno", - "font-size-small": "Usar tamanho de fonte padrão", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Fechar busca", "hide-timestamps": "Ocultar data e hora", "hide-unique-labels": "Ocultar rótulos exclusivos", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Organizado por logs mais recentes primeiro: clique para exibir os mais antigos primeiro", "oldest-first": "Organizado por logs mais antigos primeiro: clique para exibir os mais recentes primeiro", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Desfazer quebra de linha", "wrap-lines": "Aplicar quebra de linha" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Nenhum resultado corresponde à sua consulta", - "placeholder-search": "Pesquisar" + "placeholder-search": "Pesquisar", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/pt-PT/grafana.json b/public/locales/pt-PT/grafana.json index 564166fd27e..e923bfe8360 100644 --- a/public/locales/pt-PT/grafana.json +++ b/public/locales/pt-PT/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Desduplicação", - "disable-highlighting": "Desativar destaque", "disable-prettify-json": "Recolher registos JSON", - "display-level": "Níveis de exibição", "display-level-all": "Todos os níveis", "download": "Transferir registos", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Ativar destaque", "escape-newlines": "Corrigir sequências de novas linhas e tabulações ignoradas incorretamente nas linhas de registo", - "font-size-default": "Utilize um tamanho de letra pequeno", - "font-size-small": "Utilize o tamanho de letra predefinido", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Fechar a pesquisa", "hide-timestamps": "Ocultar registos de hora/data", "hide-unique-labels": "Ocultar etiquetas únicas", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Ordenado por registos mais recentes primeiro - Clique para mostrar os mais antigos primeiro", "oldest-first": "Ordenado por registos mais antigos primeiro - Clique para mostrar os mais recentes primeiro", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Revelar linhas", "wrap-lines": "Quebra de linhas" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Não foram encontrados resultados que correspondam à sua consulta", - "placeholder-search": "Pesquisar" + "placeholder-search": "Pesquisar", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/ru-RU/grafana.json b/public/locales/ru-RU/grafana.json index b473fe13523..39470c31c70 100644 --- a/public/locales/ru-RU/grafana.json +++ b/public/locales/ru-RU/grafana.json @@ -9697,10 +9697,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Дедупликация", - "disable-highlighting": "Отключить выделение", "disable-prettify-json": "Свернуть журналы JSON", - "display-level": "Показать уровни", "display-level-all": "Все уровни", "download": "Загрузить журналы", "download-logs": { @@ -9708,18 +9707,39 @@ "json": "JSON", "txt": "TXT" }, - "enable-highlighting": "Включить выделение", "escape-newlines": "Исправить неправильно экранированные последовательности новой строки и табуляции в строках журнала", - "font-size-default": "Использовать мелкий размер шрифта", - "font-size-small": "Использовать размер шрифта по умолчанию", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Закрыть поиск", "hide-timestamps": "Скрыть метки времени", "hide-unique-labels": "Скрыть уникальные метки", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Сначала отображаются самые новые журналы. Нажмите, чтобы показать сначала самые старые", "oldest-first": "Сначала отображаются самые старые журналы. Нажмите, чтобы показать сначала самые новые", @@ -9735,8 +9755,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Не переносить строки", "wrap-lines": "Переносить строки" @@ -11433,7 +11463,15 @@ }, "folder-repository-list": { "no-results-matching-your-query": "По вашему запросу ничего не найдено", - "placeholder-search": "Поиск" + "placeholder-search": "Поиск", + "all-resources-managed_one": "", + "all-resources-managed_few": "", + "all-resources-managed_many": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_few": "", + "partial-managed_many": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/sv-SE/grafana.json b/public/locales/sv-SE/grafana.json index 881f152769a..b46158b344e 100644 --- a/public/locales/sv-SE/grafana.json +++ b/public/locales/sv-SE/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Avduplicering", - "disable-highlighting": "Inaktivera markering", "disable-prettify-json": "Dölj JSON-loggar", - "display-level": "Visa nivåer", "display-level-all": "Alla nivåer", "download": "Ladda ner loggar", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Aktivera markering", "escape-newlines": "Åtgärda felaktiga undantagstecken för radbrytningar och tabbar i loggrader", - "font-size-default": "Använd liten teckenstorlek", - "font-size-small": "Använd standardteckenstorlek", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Stäng sökning", "hide-timestamps": "Dölj tidsstämplar", "hide-unique-labels": "Dölj unika etiketter", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Sorterat efter nyaste loggar först – klicka om du vill visa äldsta först", "oldest-first": "Sorterat efter äldsta loggar först – klicka om du vill visa nyaste först", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Ta bort radbrytningar", "wrap-lines": "Radbryt linjer" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Inga resultat som matchar din fråga", - "placeholder-search": "Sök" + "placeholder-search": "Sök", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/tr-TR/grafana.json b/public/locales/tr-TR/grafana.json index bcb4f372011..f4b26202113 100644 --- a/public/locales/tr-TR/grafana.json +++ b/public/locales/tr-TR/grafana.json @@ -9633,10 +9633,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "Yinelenenleri kaldırma", - "disable-highlighting": "Vurgulamayı devre dışı bırak", "disable-prettify-json": "JSON günlük kayıtlarını daralt", - "display-level": "Seviyeleri göster", "display-level-all": "Tüm seviyeler", "download": "Günlükleri indir", "download-logs": { @@ -9644,18 +9643,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "Vurgulamayı etkinleştir", "escape-newlines": "Günlük kaydı satırlarındaki kaçış karakterli satır sonu ve sekme dizilerini düzelt", - "font-size-default": "Küçük yazı tipi boyutu kullan", - "font-size-small": "Varsayılan yazı tipi boyutunu kullan", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "Aramayı kapat", "hide-timestamps": "Zaman damgalarını gizle", "hide-unique-labels": "Benzersiz etiketleri gizle", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "Günlükler yeniden eskiye sıralandı: En eskileri göstermek için tıklayın", "oldest-first": "Günlükler eskiden yeniye sıralandı: En yenileri göstermek için tıklayın", @@ -9671,8 +9691,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "Satırları çöz", "wrap-lines": "Satırları kaydır" @@ -11355,7 +11385,11 @@ }, "folder-repository-list": { "no-results-matching-your-query": "Sorgunuzla eşleşen sonuç yok", - "placeholder-search": "Ara" + "placeholder-search": "Ara", + "all-resources-managed_one": "", + "all-resources-managed_other": "", + "partial-managed_one": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/zh-Hans/grafana.json b/public/locales/zh-Hans/grafana.json index fb2aa1cb48b..e298bda7761 100644 --- a/public/locales/zh-Hans/grafana.json +++ b/public/locales/zh-Hans/grafana.json @@ -9601,10 +9601,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "去重", - "disable-highlighting": "禁用突出显示", "disable-prettify-json": "收起 JSON 日志", - "display-level": "显示级别", "display-level-all": "所有级别", "download": "下载日志", "download-logs": { @@ -9612,18 +9611,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "启用突出显示", "escape-newlines": "修复日志行中错误转义的换行和制表符序列", - "font-size-default": "使用小字号", - "font-size-small": "使用默认字号", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "关闭搜索", "hide-timestamps": "隐藏时间戳", "hide-unique-labels": "隐藏唯一标签", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "先显示最新日志 - 点击以先显示最旧日志", "oldest-first": "先显示最旧日志 - 点击以先显示最新日志", @@ -9639,8 +9659,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "取消多行显示", "wrap-lines": "多行显示" @@ -11316,7 +11346,9 @@ }, "folder-repository-list": { "no-results-matching-your-query": "没有找到与您的查询匹配的结果", - "placeholder-search": "搜索" + "placeholder-search": "搜索", + "all-resources-managed_other": "", + "partial-managed_other": "" }, "get-default-values": { "title": { diff --git a/public/locales/zh-Hant/grafana.json b/public/locales/zh-Hant/grafana.json index 874b2559929..e0eb86921fc 100644 --- a/public/locales/zh-Hant/grafana.json +++ b/public/locales/zh-Hant/grafana.json @@ -9601,10 +9601,9 @@ } }, "logs-controls": { + "collapse": "", "deduplication": "重複資料", - "disable-highlighting": "停用醒目提示", "disable-prettify-json": "收闔 JSON 紀錄", - "display-level": "顯示層級", "display-level-all": "所有層級", "download": "下載日誌", "download-logs": { @@ -9612,18 +9611,39 @@ "json": "json", "txt": "txt" }, - "enable-highlighting": "啟用醒目提示", "escape-newlines": "修復紀錄行中新行和分頁序列的錯誤轉義", - "font-size-default": "使用較小的字型", - "font-size-small": "使用預設的字型大小", + "expand": "", + "filter-levels": "", + "font-large": "", + "font-small": "", "hide-search": "關閉搜尋", "hide-timestamps": "隱藏時間戳記", "hide-unique-labels": "隱藏唯一標籤", + "label": { + "collapse": "", + "disable-highlighting": "", + "enable-highlighting": "", + "escape-newlines": "", + "expand": "" + }, + "labels": { + "font-large": "", + "font-small": "", + "hide-search": "", + "newest-first": "", + "oldest-first": "", + "show-search": "" + }, "line-wrapping": { "enable": "", "enable-prettify": "", "hide": "", - "label": "" + "state": { + "hide": "", + "json": "", + "wrap": "" + }, + "tooltip": "" }, "newest-first": "按最新紀錄排序 - 按一下以顯示最舊紀錄", "oldest-first": "按最舊紀錄排序 - 按一下以顯示最新紀錄", @@ -9639,8 +9659,18 @@ "timestamp": { "hide": "", "label": "", + "label-hide": "", + "label-ms": "", + "label-ns": "", "milliseconds": "", - "nanoseconds": "" + "nanoseconds": "", + "tooltip": "" + }, + "tooltip": { + "disable-highlighting": "", + "download": "", + "enable-highlighting": "", + "filter-level": "" }, "unwrap-lines": "取消換行", "wrap-lines": "換行" @@ -11316,7 +11346,9 @@ }, "folder-repository-list": { "no-results-matching-your-query": "沒有符合您查詢的結果", - "placeholder-search": "搜尋" + "placeholder-search": "搜尋", + "all-resources-managed_other": "", + "partial-managed_other": "" }, "get-default-values": { "title": {