diff --git a/go.mod b/go.mod index bbc68d42913..cd27554f792 100644 --- a/go.mod +++ b/go.mod @@ -403,7 +403,7 @@ require ( github.com/diegoholiveira/jsonlogic/v3 v3.7.4 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/docker v28.4.0+incompatible // indirect - github.com/docker/go-connections v0.6.0 // @grafana/grafana-app-platform-squad + github.com/docker/go-connections v0.6.0 // indirect; @grafana/grafana-app-platform-squad github.com/docker/go-units v0.5.0 // indirect github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 // indirect github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71 // indirect diff --git a/pkg/extensions/enterprise_imports.go b/pkg/extensions/enterprise_imports.go index 472652cc103..113c2f8e4bb 100644 --- a/pkg/extensions/enterprise_imports.go +++ b/pkg/extensions/enterprise_imports.go @@ -15,7 +15,6 @@ import ( _ "github.com/blugelabs/bluge" _ "github.com/blugelabs/bluge_segment_api" _ "github.com/crewjam/saml" - _ "github.com/docker/go-connections/nat" _ "github.com/go-jose/go-jose/v4" _ "github.com/gobwas/glob" _ "github.com/googleapis/gax-go/v2" @@ -31,7 +30,6 @@ import ( _ "github.com/spf13/cobra" // used by the standalone apiserver cli _ "github.com/spyzhov/ajson" _ "github.com/stretchr/testify/require" - _ "github.com/testcontainers/testcontainers-go" _ "gocloud.dev/secrets/awskms" _ "gocloud.dev/secrets/azurekeyvault" _ "gocloud.dev/secrets/gcpkms" @@ -56,7 +54,9 @@ import ( _ "github.com/grafana/e2e" _ "github.com/grafana/gofpdf" _ "github.com/grafana/gomemcache/memcache" + _ "github.com/grafana/tempo/pkg/traceql" + _ "github.com/grafana/grafana/apps/alerting/alertenrichment/pkg/apis/alertenrichment/v1beta1" _ "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" - _ "github.com/grafana/tempo/pkg/traceql" + _ "github.com/testcontainers/testcontainers-go" ) diff --git a/pkg/registry/apis/dashboard/legacy/sql_dashboards.go b/pkg/registry/apis/dashboard/legacy/sql_dashboards.go index 0fca282fa82..3d157e09489 100644 --- a/pkg/registry/apis/dashboard/legacy/sql_dashboards.go +++ b/pkg/registry/apis/dashboard/legacy/sql_dashboards.go @@ -165,7 +165,7 @@ type rowsWrapper struct { rejected []dashboardRow } -func (a *dashboardSqlAccess) GetResourceStats(ctx context.Context, namespace string, minCount int) ([]resource.ResourceStats, error) { +func (a *dashboardSqlAccess) GetResourceStats(ctx context.Context, nsr resource.NamespacedResource, minCount int) ([]resource.ResourceStats, error) { return nil, fmt.Errorf("not implemented") } diff --git a/pkg/registry/apis/iam/noopstorage/storage_backend.go b/pkg/registry/apis/iam/noopstorage/storage_backend.go index ad0ebbe2335..107ac4e087c 100644 --- a/pkg/registry/apis/iam/noopstorage/storage_backend.go +++ b/pkg/registry/apis/iam/noopstorage/storage_backend.go @@ -23,7 +23,7 @@ func ProvideStorageBackend() *StorageBackendImpl { } // GetResourceStats implements resource.StorageBackend. -func (c *StorageBackendImpl) GetResourceStats(ctx context.Context, namespace string, minCount int) ([]resource.ResourceStats, error) { +func (c *StorageBackendImpl) GetResourceStats(ctx context.Context, nsr resource.NamespacedResource, minCount int) ([]resource.ResourceStats, error) { return []resource.ResourceStats{}, errNoopStorage } diff --git a/pkg/registry/apis/iam/resourcepermission/storage_backend.go b/pkg/registry/apis/iam/resourcepermission/storage_backend.go index 8e2d323ff5c..84015bcf171 100644 --- a/pkg/registry/apis/iam/resourcepermission/storage_backend.go +++ b/pkg/registry/apis/iam/resourcepermission/storage_backend.go @@ -60,7 +60,7 @@ func ProvideStorageBackend(dbProvider legacysql.LegacyDatabaseProvider) *Resourc } } -func (s *ResourcePermSqlBackend) GetResourceStats(ctx context.Context, namespace string, minCount int) ([]resource.ResourceStats, error) { +func (s *ResourcePermSqlBackend) GetResourceStats(ctx context.Context, nsr resource.NamespacedResource, minCount int) ([]resource.ResourceStats, error) { return []resource.ResourceStats{}, errNotImplemented } diff --git a/pkg/storage/unified/resource/search.go b/pkg/storage/unified/resource/search.go index 0f3e9f95912..7b5a6544e5b 100644 --- a/pkg/storage/unified/resource/search.go +++ b/pkg/storage/unified/resource/search.go @@ -245,7 +245,10 @@ func (s *searchSupport) ListManagedObjects(ctx context.Context, req *resourcepb. } rsp := &resourcepb.ListManagedObjectsResponse{} - stats, err := s.storage.GetResourceStats(ctx, req.Namespace, 0) + nsr := NamespacedResource{ + Namespace: req.Namespace, + } + stats, err := s.storage.GetResourceStats(ctx, nsr, 0) if err != nil { rsp.Error = AsErrorResult(err) return rsp, nil @@ -286,7 +289,10 @@ func (s *searchSupport) ListManagedObjects(ctx context.Context, req *resourcepb. func (s *searchSupport) CountManagedObjects(ctx context.Context, req *resourcepb.CountManagedObjectsRequest) (*resourcepb.CountManagedObjectsResponse, error) { rsp := &resourcepb.CountManagedObjectsResponse{} - stats, err := s.storage.GetResourceStats(ctx, req.Namespace, 0) + nsr := NamespacedResource{ + Namespace: req.Namespace, + } + stats, err := s.storage.GetResourceStats(ctx, nsr, 0) if err != nil { rsp.Error = AsErrorResult(err) return rsp, nil @@ -408,7 +414,10 @@ func (s *searchSupport) GetStats(ctx context.Context, req *resourcepb.ResourceSt return rsp, nil } - stats, err := s.storage.GetResourceStats(ctx, req.Namespace, 0) + nsr := NamespacedResource{ + Namespace: req.Namespace, + } + stats, err := s.storage.GetResourceStats(ctx, nsr, 0) if err != nil { return &resourcepb.ResourceStatsResponse{ Error: AsErrorResult(err), @@ -457,7 +466,7 @@ func (s *searchSupport) buildIndexes(ctx context.Context) (int, error) { group := errgroup.Group{} group.SetLimit(s.initWorkers) - stats, err := s.storage.GetResourceStats(ctx, "", s.initMinSize) + stats, err := s.storage.GetResourceStats(ctx, NamespacedResource{}, s.initMinSize) if err != nil { return 0, err } @@ -657,7 +666,12 @@ func (s *searchSupport) rebuildIndex(ctx context.Context, req rebuildRequest) { // Get the correct value of size + RV for building the index. This is important for our Bleve // backend to decide whether to build index in-memory or as file-based. - stats, err := s.storage.GetResourceStats(ctx, req.Namespace, 0) + nsr := NamespacedResource{ + Namespace: req.Namespace, + Group: req.Group, + Resource: req.Resource, + } + stats, err := s.storage.GetResourceStats(ctx, nsr, 0) if err != nil { span.RecordError(fmt.Errorf("failed to get resource stats: %w", err)) l.Error("failed to get resource stats", "error", err) @@ -750,7 +764,10 @@ func (s *searchSupport) getOrCreateIndex(ctx context.Context, key NamespacedReso // Get correct value of size + RV for building the index. This is important for our Bleve // backend to decide whether to build index in-memory or as file-based. - stats, err := s.storage.GetResourceStats(ctx, key.Namespace, 0) + nsr := NamespacedResource{ + Namespace: key.Namespace, + } + stats, err := s.storage.GetResourceStats(ctx, nsr, 0) if err != nil { return nil, fmt.Errorf("failed to get resource stats: %w", err) } diff --git a/pkg/storage/unified/resource/search_test.go b/pkg/storage/unified/resource/search_test.go index 2c3cfe81097..c3f852c837e 100644 --- a/pkg/storage/unified/resource/search_test.go +++ b/pkg/storage/unified/resource/search_test.go @@ -88,7 +88,7 @@ type mockStorageBackend struct { resourceStats []ResourceStats } -func (m *mockStorageBackend) GetResourceStats(ctx context.Context, namespace string, minCount int) ([]ResourceStats, error) { +func (m *mockStorageBackend) GetResourceStats(ctx context.Context, nsr NamespacedResource, minCount int) ([]ResourceStats, error) { var result []ResourceStats for _, stat := range m.resourceStats { // Apply the minCount filter like the real implementation does diff --git a/pkg/storage/unified/resource/server.go b/pkg/storage/unified/resource/server.go index 13bac8a2f6e..bf805cc0a6a 100644 --- a/pkg/storage/unified/resource/server.go +++ b/pkg/storage/unified/resource/server.go @@ -123,7 +123,7 @@ type StorageBackend interface { WatchWriteEvents(ctx context.Context) (<-chan *WrittenEvent, error) // Get resource stats within the storage backend. When namespace is empty, it will apply to all - GetResourceStats(ctx context.Context, namespace string, minCount int) ([]ResourceStats, error) + GetResourceStats(ctx context.Context, nsr NamespacedResource, minCount int) ([]ResourceStats, error) // GetResourceLastImportTimes returns import times for all namespaced resources in the backend. GetResourceLastImportTimes(ctx context.Context) iter.Seq2[ResourceLastImportTime, error] diff --git a/pkg/storage/unified/resource/storage_backend.go b/pkg/storage/unified/resource/storage_backend.go index 3764147508d..838c0814750 100644 --- a/pkg/storage/unified/resource/storage_backend.go +++ b/pkg/storage/unified/resource/storage_backend.go @@ -1223,8 +1223,8 @@ func (k *kvStorageBackend) WatchWriteEvents(ctx context.Context) (<-chan *Writte } // GetResourceStats returns resource stats within the storage backend. -func (k *kvStorageBackend) GetResourceStats(ctx context.Context, namespace string, minCount int) ([]ResourceStats, error) { - return k.dataStore.GetResourceStats(ctx, namespace, minCount) +func (k *kvStorageBackend) GetResourceStats(ctx context.Context, nsr NamespacedResource, minCount int) ([]ResourceStats, error) { + return k.dataStore.GetResourceStats(ctx, nsr.Namespace, minCount) } func (k *kvStorageBackend) GetResourceLastImportTimes(ctx context.Context) iter.Seq2[ResourceLastImportTime, error] { diff --git a/pkg/storage/unified/resource/storage_backend_test.go b/pkg/storage/unified/resource/storage_backend_test.go index 81189fb4545..f8ea2717a1e 100644 --- a/pkg/storage/unified/resource/storage_backend_test.go +++ b/pkg/storage/unified/resource/storage_backend_test.go @@ -1397,7 +1397,7 @@ func TestKvStorageBackend_GetResourceStats_Success(t *testing.T) { } // Get stats for default namespace - stats, err := backend.GetResourceStats(ctx, "default", 0) + stats, err := backend.GetResourceStats(ctx, NamespacedResource{Namespace: "default"}, 0) require.NoError(t, err) require.Len(t, stats, 2) // Should have stats for 2 resource types in default namespace @@ -1413,12 +1413,12 @@ func TestKvStorageBackend_GetResourceStats_Success(t *testing.T) { require.Equal(t, int64(1), resourceTypes["default/core/services"]) // Get stats for all namespaces (empty string) - allStats, err := backend.GetResourceStats(ctx, "", 0) + allStats, err := backend.GetResourceStats(ctx, NamespacedResource{Namespace: ""}, 0) require.NoError(t, err) require.Len(t, allStats, 4) // Should have stats for all 4 resource types across namespaces // Get stats with minCount filter - filteredStats, err := backend.GetResourceStats(ctx, "", 1) + filteredStats, err := backend.GetResourceStats(ctx, NamespacedResource{Namespace: ""}, 1) require.NoError(t, err) require.Len(t, filteredStats, 1) // Only resources in default namespace has count > 1 diff --git a/pkg/storage/unified/sql/backend.go b/pkg/storage/unified/sql/backend.go index 181782eb606..d3dae729fd4 100644 --- a/pkg/storage/unified/sql/backend.go +++ b/pkg/storage/unified/sql/backend.go @@ -262,13 +262,15 @@ func (b *backend) Stop(_ context.Context) error { } // GetResourceStats implements Backend. -func (b *backend) GetResourceStats(ctx context.Context, namespace string, minCount int) ([]resource.ResourceStats, error) { +func (b *backend) GetResourceStats(ctx context.Context, nsr resource.NamespacedResource, minCount int) ([]resource.ResourceStats, error) { ctx, span := b.tracer.Start(ctx, tracePrefix+"GetResourceStats") defer span.End() req := &sqlStatsRequest{ SQLTemplate: sqltemplate.New(b.dialect), - Namespace: namespace, + Namespace: nsr.Namespace, + Group: nsr.Group, + Resource: nsr.Resource, MinCount: minCount, // not used in query... yet? } diff --git a/pkg/storage/unified/testing/storage_backend.go b/pkg/storage/unified/testing/storage_backend.go index 3f8b4b9ed55..b3cc08b57c0 100644 --- a/pkg/storage/unified/testing/storage_backend.go +++ b/pkg/storage/unified/testing/storage_backend.go @@ -262,7 +262,10 @@ func runTestIntegrationBackendGetResourceStats(t *testing.T, backend resource.St require.NoError(t, err) t.Run("Get stats for ns1", func(t *testing.T) { - stats, err := backend.GetResourceStats(ctx, nsPrefix+"-stats-ns1", 0) + nsr := resource.NamespacedResource{ + Namespace: nsPrefix + "-stats-ns1", + } + stats, err := backend.GetResourceStats(ctx, nsr, 0) require.NoError(t, err) require.Len(t, stats, 2) @@ -285,7 +288,10 @@ func runTestIntegrationBackendGetResourceStats(t *testing.T, backend resource.St }) t.Run("Get stats for ns2", func(t *testing.T) { - stats, err := backend.GetResourceStats(ctx, nsPrefix+"-stats-ns2", 0) + nsr := resource.NamespacedResource{ + Namespace: nsPrefix + "-stats-ns2", + } + stats, err := backend.GetResourceStats(ctx, nsr, 0) require.NoError(t, err) require.Len(t, stats, 1) @@ -297,7 +303,10 @@ func runTestIntegrationBackendGetResourceStats(t *testing.T, backend resource.St }) t.Run("Get stats with minimum count", func(t *testing.T) { - stats, err := backend.GetResourceStats(ctx, nsPrefix+"-stats-ns1", 1) + nsr := resource.NamespacedResource{ + Namespace: nsPrefix + "-stats-ns1", + } + stats, err := backend.GetResourceStats(ctx, nsr, 1) require.NoError(t, err) require.Len(t, stats, 1) @@ -308,7 +317,10 @@ func runTestIntegrationBackendGetResourceStats(t *testing.T, backend resource.St }) t.Run("Get stats for non-existent namespace", func(t *testing.T) { - stats, err := backend.GetResourceStats(ctx, "non-existent", 0) + nsr := resource.NamespacedResource{ + Namespace: "non-existent", + } + stats, err := backend.GetResourceStats(ctx, nsr, 0) require.NoError(t, err) require.Empty(t, stats) })