chore(unified-storage): add tracing for unified storage folder implementation (#105601)
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/services/user/usertest"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
)
|
||||
|
||||
func TestFolderConversions(t *testing.T) {
|
||||
@@ -48,6 +49,7 @@ func TestFolderConversions(t *testing.T) {
|
||||
created = created.Local()
|
||||
require.NoError(t, err)
|
||||
|
||||
tracer := noop.NewTracerProvider().Tracer("TestFolderConversions")
|
||||
fake := usertest.NewUserServiceFake()
|
||||
fake.ExpectedListUsersByIdOrUid = []*user.User{
|
||||
{
|
||||
@@ -60,7 +62,7 @@ func TestFolderConversions(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
fs := ProvideUnifiedStore(nil, fake)
|
||||
fs := ProvideUnifiedStore(nil, fake, tracer)
|
||||
|
||||
converted, err := fs.UnstructuredToLegacyFolder(context.Background(), input)
|
||||
require.NoError(t, err)
|
||||
@@ -239,6 +241,7 @@ func TestFolderListConversions(t *testing.T) {
|
||||
created = created.Local()
|
||||
require.NoError(t, err)
|
||||
|
||||
tracer := noop.NewTracerProvider().Tracer("TestFolderListConversions")
|
||||
fake := usertest.NewUserServiceFake()
|
||||
fake.ExpectedListUsersByIdOrUid = []*user.User{
|
||||
{
|
||||
@@ -267,7 +270,7 @@ func TestFolderListConversions(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
fs := ProvideUnifiedStore(nil, fake)
|
||||
fs := ProvideUnifiedStore(nil, fake, tracer)
|
||||
|
||||
converted, err := fs.UnstructuredToLegacyFolderList(context.Background(), input)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/client"
|
||||
@@ -70,7 +69,7 @@ type Service struct {
|
||||
mutex sync.RWMutex
|
||||
registry map[string]folder.RegistryService
|
||||
metrics *foldersMetrics
|
||||
tracer tracing.Tracer
|
||||
tracer trace.Tracer
|
||||
}
|
||||
|
||||
func ProvideService(
|
||||
@@ -86,7 +85,7 @@ func ProvideService(
|
||||
publicDashboardService publicdashboards.ServiceWrapper,
|
||||
cfg *setting.Cfg,
|
||||
r prometheus.Registerer,
|
||||
tracer tracing.Tracer,
|
||||
tracer trace.Tracer,
|
||||
resourceClient resource.ResourceClient,
|
||||
dual dualwrite.Service,
|
||||
sorter sort.Service,
|
||||
@@ -125,7 +124,7 @@ func ProvideService(
|
||||
sorter,
|
||||
)
|
||||
|
||||
unifiedStore := ProvideUnifiedStore(k8sHandler, userService)
|
||||
unifiedStore := ProvideUnifiedStore(k8sHandler, userService, tracer)
|
||||
|
||||
srv.unifiedStore = unifiedStore
|
||||
srv.k8sclient = k8sHandler
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@@ -69,9 +70,10 @@ func TestIntegrationProvideFolderService(t *testing.T) {
|
||||
ac := acmock.New()
|
||||
db, cfg := db.InitTestDBWithCfg(t)
|
||||
store := ProvideStore(db)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestIntegrationProvideFolderService")
|
||||
ProvideService(
|
||||
store, ac, bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
nil, nil, nil, db, featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest(), nil, dualwrite.ProvideTestService(), sort.ProvideService(),
|
||||
nil, nil, nil, db, featuremgmt.WithFeatures(), supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracer, nil, dualwrite.ProvideTestService(), sort.ProvideService(),
|
||||
apiserver.WithoutRestConfig)
|
||||
|
||||
require.Len(t, ac.Calls.RegisterAttributeScopeResolver, 2)
|
||||
@@ -90,6 +92,7 @@ func TestIntegrationFolderService(t *testing.T) {
|
||||
folderStore := foldertest.NewFakeFolderStore(t)
|
||||
publicDashboardService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
features := featuremgmt.WithFeatures()
|
||||
tracer := noop.NewTracerProvider().Tracer("TestIntegrationFolderService")
|
||||
|
||||
alertingStore := ngstore.DBstore{
|
||||
SQLStore: db,
|
||||
@@ -110,7 +113,7 @@ func TestIntegrationFolderService(t *testing.T) {
|
||||
accessControl: actest.FakeAccessControl{ExpectedEvaluate: true},
|
||||
metrics: newFoldersMetrics(nil),
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
require.NoError(t, service.RegisterService(alertingStore))
|
||||
@@ -369,6 +372,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
publicDashboardFakeService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestIntegrationNestedFolderService")
|
||||
|
||||
b := bus.ProvideBus(tracing.InitializeTracerForTest())
|
||||
ac := actest.FakeAccessControl{ExpectedEvaluate: true}
|
||||
@@ -384,7 +388,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
accessControl: ac,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
publicDashboardService: publicDashboardFakeService,
|
||||
}
|
||||
|
||||
@@ -497,7 +501,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
publicDashboardService: publicDashboardFakeService,
|
||||
}
|
||||
|
||||
@@ -572,7 +576,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
|
||||
db: db,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
publicDashboardService: publicDashboardFakeService,
|
||||
accessControl: actest.FakeAccessControl{ExpectedEvaluate: true},
|
||||
}
|
||||
@@ -730,6 +734,7 @@ func TestNestedFolderServiceFeatureToggle(t *testing.T) {
|
||||
dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{}, nil)
|
||||
|
||||
dashboardFolderStore := foldertest.NewFakeFolderStore(t)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestNestedFolderServiceFeatureToggle")
|
||||
|
||||
db, _ := sqlstore.InitTestDB(t)
|
||||
folderService := &Service{
|
||||
@@ -741,7 +746,7 @@ func TestNestedFolderServiceFeatureToggle(t *testing.T) {
|
||||
features: featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders),
|
||||
accessControl: actest.FakeAccessControl{ExpectedEvaluate: true},
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
}
|
||||
t.Run("create folder", func(t *testing.T) {
|
||||
nestedFolderStore.ExpectedFolder = &folder.Folder{ParentUID: util.GenerateShortUID()}
|
||||
@@ -762,6 +767,7 @@ func TestFolderServiceDualWrite(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
dashboardFolderStore := ProvideDashboardFolderStore(db)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestFolderServiceDualWrite")
|
||||
|
||||
folderService := &Service{
|
||||
store: nestedFolderStore,
|
||||
@@ -772,7 +778,7 @@ func TestFolderServiceDualWrite(t *testing.T) {
|
||||
features: featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders),
|
||||
accessControl: actest.FakeAccessControl{ExpectedEvaluate: true},
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
bus: bus.ProvideBus(tracing.InitializeTracerForTest()),
|
||||
}
|
||||
|
||||
@@ -1296,6 +1302,7 @@ func TestIntegrationNestedFolderSharedWithMe(t *testing.T) {
|
||||
dashStore, err := database.ProvideDashboardStore(db, cfg, featuresFlagOn, tagimpl.ProvideService(db))
|
||||
require.NoError(t, err)
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestIntegrationNestedFolderSharedWithMe")
|
||||
|
||||
b := bus.ProvideBus(tracing.InitializeTracerForTest())
|
||||
ac := acimpl.ProvideAccessControl(featuresFlagOn)
|
||||
@@ -1311,7 +1318,7 @@ func TestIntegrationNestedFolderSharedWithMe(t *testing.T) {
|
||||
accessControl: ac,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
dashboardPermissions := acmock.NewMockedPermissionsService()
|
||||
@@ -1703,6 +1710,7 @@ func TestFolderServiceGetFolder(t *testing.T) {
|
||||
dashStore, err := database.ProvideDashboardStore(db, cfg, featuresFlagOff, tagimpl.ProvideService(db))
|
||||
require.NoError(t, err)
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestFolderServiceGetFolder")
|
||||
|
||||
b := bus.ProvideBus(tracing.InitializeTracerForTest())
|
||||
ac := acimpl.ProvideAccessControl(featuresFlagOff)
|
||||
@@ -1718,7 +1726,7 @@ func TestFolderServiceGetFolder(t *testing.T) {
|
||||
accessControl: ac,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
tracer: tracer,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1801,6 +1809,7 @@ func TestFolderServiceGetFolders(t *testing.T) {
|
||||
dashStore, err := database.ProvideDashboardStore(db, cfg, featuresFlagOff, tagimpl.ProvideService(db))
|
||||
require.NoError(t, err)
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestFolderServiceGetFolders")
|
||||
|
||||
b := bus.ProvideBus(tracing.InitializeTracerForTest())
|
||||
ac := acimpl.ProvideAccessControl(featuresFlagOff)
|
||||
@@ -1816,7 +1825,7 @@ func TestFolderServiceGetFolders(t *testing.T) {
|
||||
accessControl: ac,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
signedInAdminUser := user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{
|
||||
@@ -1880,6 +1889,7 @@ func TestGetChildrenFilterByPermission(t *testing.T) {
|
||||
dashStore, err := database.ProvideDashboardStore(db, cfg, featuresFlagOff, tagimpl.ProvideService(db))
|
||||
require.NoError(t, err)
|
||||
nestedFolderStore := ProvideStore(db)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestGetChildrenFilterByPermission")
|
||||
|
||||
b := bus.ProvideBus(tracing.InitializeTracerForTest())
|
||||
ac := acimpl.ProvideAccessControl(featuresFlagOff)
|
||||
@@ -1897,7 +1907,7 @@ func TestGetChildrenFilterByPermission(t *testing.T) {
|
||||
accessControl: ac,
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
viewer := user.SignedInUser{UserID: 1, OrgID: orgID, Permissions: map[int64]map[string][]string{
|
||||
@@ -2343,7 +2353,7 @@ func setup(t *testing.T, dashStore dashboards.Store, dashboardFolderStore folder
|
||||
accessControl: ac,
|
||||
db: db,
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: noop.NewTracerProvider().Tracer("setup"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
)
|
||||
|
||||
const folderSearchLimit = 100000
|
||||
const folderListLimit = 100
|
||||
const folderListLimit = 10000
|
||||
|
||||
func (s *Service) getFoldersFromApiServer(ctx context.Context, q folder.GetFoldersQuery) ([]*folder.Folder, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "folder.getFoldersFromApiServer")
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
clientrest "k8s.io/client-go/rest"
|
||||
|
||||
@@ -196,9 +197,10 @@ func TestIntegrationFolderServiceViaUnifiedStorage(t *testing.T) {
|
||||
featuremgmt.FlagKubernetesClientDashboardsFolders}
|
||||
features := featuremgmt.WithFeatures(featuresArr...)
|
||||
|
||||
tracer := noop.NewTracerProvider().Tracer("TestIntegrationFolderServiceViaUnifiedStorage")
|
||||
dashboardStore := dashboards.NewFakeDashboardStore(t)
|
||||
k8sCli := client.NewK8sHandler(dualwrite.ProvideTestService(), request.GetNamespaceMapper(cfg), folderv1.FolderResourceInfo.GroupVersionResource(), restCfgProvider.GetRestConfig, dashboardStore, userService, nil, sort.ProvideService())
|
||||
unifiedStore := ProvideUnifiedStore(k8sCli, userService)
|
||||
unifiedStore := ProvideUnifiedStore(k8sCli, userService, tracer)
|
||||
|
||||
ctx := context.Background()
|
||||
usr := &user.SignedInUser{UserID: 1, OrgID: 1, Permissions: map[int64]map[string][]string{
|
||||
@@ -231,7 +233,7 @@ func TestIntegrationFolderServiceViaUnifiedStorage(t *testing.T) {
|
||||
accessControl: acimpl.ProvideAccessControl(features),
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
metrics: newFoldersMetrics(nil),
|
||||
tracer: tracing.InitializeTracerForTest(),
|
||||
tracer: tracer,
|
||||
k8sclient: k8sCli,
|
||||
dashboardK8sClient: fakeK8sClient,
|
||||
publicDashboardService: publicDashboardService,
|
||||
@@ -516,11 +518,12 @@ func TestSearchFoldersFromApiServer(t *testing.T) {
|
||||
ID: 2,
|
||||
Title: "parent title",
|
||||
}
|
||||
tracer := noop.NewTracerProvider().Tracer("TestSearchFoldersFromApiServer")
|
||||
service := Service{
|
||||
k8sclient: fakeK8sClient,
|
||||
features: featuremgmt.WithFeatures(featuremgmt.FlagKubernetesClientDashboardsFolders),
|
||||
unifiedStore: folderStore,
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
tracer: tracer,
|
||||
accessControl: actest.FakeAccessControl{ExpectedEvaluate: true},
|
||||
}
|
||||
user := &user.SignedInUser{OrgID: 1}
|
||||
@@ -758,12 +761,13 @@ func TestGetFoldersFromApiServer(t *testing.T) {
|
||||
ID: 2,
|
||||
Title: "parent title",
|
||||
}
|
||||
tracer := noop.NewTracerProvider().Tracer("TestGetFoldersFromApiServer")
|
||||
service := Service{
|
||||
k8sclient: fakeK8sClient,
|
||||
features: featuremgmt.WithFeatures(featuremgmt.FlagKubernetesClientDashboardsFolders),
|
||||
unifiedStore: folderStore,
|
||||
accessControl: actest.FakeAccessControl{ExpectedEvaluate: true},
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
tracer: tracer,
|
||||
}
|
||||
user := &user.SignedInUser{OrgID: 1}
|
||||
ctx := identity.WithRequester(context.Background(), user)
|
||||
@@ -845,6 +849,7 @@ func TestDeleteFoldersFromApiServer(t *testing.T) {
|
||||
fakeFolderStore := folder.NewFakeStore()
|
||||
dashboardStore := dashboards.NewFakeDashboardStore(t)
|
||||
publicDashboardFakeService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestDeleteFoldersFromApiServer")
|
||||
service := Service{
|
||||
k8sclient: fakeK8sClient,
|
||||
dashboardK8sClient: dashboardK8sclient,
|
||||
@@ -854,7 +859,7 @@ func TestDeleteFoldersFromApiServer(t *testing.T) {
|
||||
accessControl: actest.FakeAccessControl{ExpectedEvaluate: true},
|
||||
registry: make(map[string]folder.RegistryService),
|
||||
features: featuremgmt.WithFeatures(featuremgmt.FlagKubernetesClientDashboardsFolders),
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
tracer: tracer,
|
||||
}
|
||||
user := &user.SignedInUser{OrgID: 1}
|
||||
ctx := identity.WithRequester(context.Background(), user)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
@@ -28,24 +29,31 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
const tracePrefix = "folder.unifiedstore."
|
||||
|
||||
type FolderUnifiedStoreImpl struct {
|
||||
log log.Logger
|
||||
k8sclient client.K8sHandler
|
||||
userService user.Service
|
||||
tracer trace.Tracer
|
||||
}
|
||||
|
||||
// sqlStore implements the store interface.
|
||||
var _ folder.Store = (*FolderUnifiedStoreImpl)(nil)
|
||||
|
||||
func ProvideUnifiedStore(k8sHandler client.K8sHandler, userService user.Service) *FolderUnifiedStoreImpl {
|
||||
func ProvideUnifiedStore(k8sHandler client.K8sHandler, userService user.Service, tracer trace.Tracer) *FolderUnifiedStoreImpl {
|
||||
return &FolderUnifiedStoreImpl{
|
||||
k8sclient: k8sHandler,
|
||||
log: log.New("folder-store"),
|
||||
userService: userService,
|
||||
tracer: tracer,
|
||||
}
|
||||
}
|
||||
|
||||
func (ss *FolderUnifiedStoreImpl) Create(ctx context.Context, cmd folder.CreateFolderCommand) (*folder.Folder, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"Create")
|
||||
defer span.End()
|
||||
|
||||
obj, err := internalfolders.LegacyCreateCommandToUnstructured(&cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -65,6 +73,9 @@ func (ss *FolderUnifiedStoreImpl) Create(ctx context.Context, cmd folder.CreateF
|
||||
}
|
||||
|
||||
func (ss *FolderUnifiedStoreImpl) Delete(ctx context.Context, UIDs []string, orgID int64) error {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"Delete")
|
||||
defer span.End()
|
||||
|
||||
for _, uid := range UIDs {
|
||||
err := ss.k8sclient.Delete(ctx, uid, orgID, v1.DeleteOptions{})
|
||||
if err != nil {
|
||||
@@ -76,6 +87,9 @@ func (ss *FolderUnifiedStoreImpl) Delete(ctx context.Context, UIDs []string, org
|
||||
}
|
||||
|
||||
func (ss *FolderUnifiedStoreImpl) Update(ctx context.Context, cmd folder.UpdateFolderCommand) (*folder.Folder, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"Update")
|
||||
defer span.End()
|
||||
|
||||
obj, err := ss.k8sclient.Get(ctx, cmd.UID, cmd.OrgID, v1.GetOptions{})
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
@@ -140,6 +154,9 @@ func (ss *FolderUnifiedStoreImpl) Update(ctx context.Context, cmd folder.UpdateF
|
||||
//
|
||||
// The full path of C is "A/B\/C".
|
||||
func (ss *FolderUnifiedStoreImpl) Get(ctx context.Context, q folder.GetFolderQuery) (*folder.Folder, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"Get")
|
||||
defer span.End()
|
||||
|
||||
out, err := ss.k8sclient.Get(ctx, *q.UID, q.OrgID, v1.GetOptions{})
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
@@ -151,6 +168,9 @@ func (ss *FolderUnifiedStoreImpl) Get(ctx context.Context, q folder.GetFolderQue
|
||||
}
|
||||
|
||||
func (ss *FolderUnifiedStoreImpl) GetParents(ctx context.Context, q folder.GetParentsQuery) ([]*folder.Folder, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"GetParents")
|
||||
defer span.End()
|
||||
|
||||
hits := []*folder.Folder{}
|
||||
|
||||
parentUID := q.UID
|
||||
@@ -177,6 +197,9 @@ func (ss *FolderUnifiedStoreImpl) GetParents(ctx context.Context, q folder.GetPa
|
||||
}
|
||||
|
||||
func (ss *FolderUnifiedStoreImpl) GetChildren(ctx context.Context, q folder.GetChildrenQuery) ([]*folder.FolderReference, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"GetChildren")
|
||||
defer span.End()
|
||||
|
||||
// the general folder is saved as an empty string in the database
|
||||
if q.UID == folder.GeneralFolderUID {
|
||||
q.UID = ""
|
||||
@@ -261,6 +284,9 @@ func (ss *FolderUnifiedStoreImpl) GetChildren(ctx context.Context, q folder.GetC
|
||||
|
||||
// TODO use a single query to get the height of a folder
|
||||
func (ss *FolderUnifiedStoreImpl) GetHeight(ctx context.Context, foldrUID string, orgID int64, parentUID *string) (int, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"GetHeight")
|
||||
defer span.End()
|
||||
|
||||
height := -1
|
||||
queue := []string{foldrUID}
|
||||
for len(queue) > 0 && height <= folder.MaxNestedFolderDepth {
|
||||
@@ -319,6 +345,9 @@ func (ss *FolderUnifiedStoreImpl) GetHeight(ctx context.Context, foldrUID string
|
||||
// The full path UIDs of B is "uid1/uid2".
|
||||
// The full path UIDs of A is "uid1".
|
||||
func (ss *FolderUnifiedStoreImpl) GetFolders(ctx context.Context, q folder.GetFoldersFromStoreQuery) ([]*folder.Folder, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"GetFolders")
|
||||
defer span.End()
|
||||
|
||||
opts := v1.ListOptions{}
|
||||
if q.WithFullpath || q.WithFullpathUIDs {
|
||||
// only supported in modes 0-2, to keep the alerting queries from causing tons of get folder requests
|
||||
@@ -371,6 +400,9 @@ func (ss *FolderUnifiedStoreImpl) GetFolders(ctx context.Context, q folder.GetFo
|
||||
}
|
||||
|
||||
func (ss *FolderUnifiedStoreImpl) GetDescendants(ctx context.Context, orgID int64, ancestor_uid string) ([]*folder.Folder, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"GetDescendants")
|
||||
defer span.End()
|
||||
|
||||
out, err := ss.list(ctx, orgID, v1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -421,6 +453,9 @@ func getDescendants(nodes map[string]*folder.Folder, tree map[string]map[string]
|
||||
}
|
||||
|
||||
func (ss *FolderUnifiedStoreImpl) CountFolderContent(ctx context.Context, orgID int64, ancestor_uid string) (folder.DescendantCounts, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"CountFolderContent")
|
||||
defer span.End()
|
||||
|
||||
counts, err := ss.k8sclient.Get(ctx, ancestor_uid, orgID, v1.GetOptions{}, "counts")
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
@@ -448,6 +483,9 @@ func (ss *FolderUnifiedStoreImpl) CountInOrg(ctx context.Context, orgID int64) (
|
||||
}
|
||||
|
||||
func (ss *FolderUnifiedStoreImpl) list(ctx context.Context, orgID int64, opts v1.ListOptions) (*unstructured.UnstructuredList, error) {
|
||||
ctx, span := ss.tracer.Start(ctx, tracePrefix+"list")
|
||||
defer span.End()
|
||||
|
||||
var allItems []unstructured.Unstructured
|
||||
|
||||
listOpts := opts.DeepCopy()
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
@@ -96,9 +97,11 @@ func TestComputeFullPath(t *testing.T) {
|
||||
|
||||
func TestGetParents(t *testing.T) {
|
||||
mockCli := new(client.MockK8sHandler)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestGetParents")
|
||||
store := FolderUnifiedStoreImpl{
|
||||
k8sclient: mockCli,
|
||||
userService: usertest.NewUserServiceFake(),
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
@@ -192,9 +195,11 @@ func TestGetParents(t *testing.T) {
|
||||
|
||||
func TestGetChildren(t *testing.T) {
|
||||
mockCli := new(client.MockK8sHandler)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestGetChildren")
|
||||
store := FolderUnifiedStoreImpl{
|
||||
k8sclient: mockCli,
|
||||
userService: usertest.NewUserServiceFake(),
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
@@ -739,9 +744,11 @@ func TestGetFolders(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockCLI := new(client.MockK8sHandler)
|
||||
tt.mock(mockCLI)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestGetFolders")
|
||||
ss := &FolderUnifiedStoreImpl{
|
||||
k8sclient: mockCLI,
|
||||
userService: usertest.NewUserServiceFake(),
|
||||
tracer: tracer,
|
||||
}
|
||||
got, err := ss.GetFolders(tt.args.ctx, tt.args.q)
|
||||
require.Equal(t, tt.wantErr, err != nil, "GetFolders() error = %v, wantErr %v", err, tt.wantErr)
|
||||
@@ -1099,9 +1106,11 @@ func TestList(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockCLI := new(client.MockK8sHandler)
|
||||
tt.mock(mockCLI)
|
||||
tracer := noop.NewTracerProvider().Tracer("TestList")
|
||||
ss := &FolderUnifiedStoreImpl{
|
||||
k8sclient: mockCLI,
|
||||
userService: usertest.NewUserServiceFake(),
|
||||
tracer: tracer,
|
||||
}
|
||||
got, err := ss.list(tt.args.ctx, tt.args.orgID, tt.args.opts)
|
||||
if tt.wantErr {
|
||||
|
||||
Reference in New Issue
Block a user