K8s: Folders: Reduce db calls with /api/folders (#103058)

This commit is contained in:
Stephanie Hingtgen
2025-03-28 17:13:08 -06:00
committed by GitHub
parent 290e5cbe83
commit b67b9e3c5e
4 changed files with 75 additions and 0 deletions
+1
View File
@@ -84,6 +84,7 @@ func (hs *HTTPServer) GetFolders(c *contextmodel.ReqContext) response.Response {
UID: c.Query("parentUid"),
Permission: permission,
SignedInUser: c.SignedInUser,
RefOnly: true, // nolint:staticcheck
}
folders, err := hs.folderService.GetChildren(c.Req.Context(), q)
@@ -15,6 +15,7 @@ import (
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/storage/unified/resource"
"github.com/grafana/grafana/pkg/storage/unified/search"
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
"github.com/grafana/grafana/pkg/infra/log"
@@ -236,6 +237,25 @@ func (ss *FolderUnifiedStoreImpl) GetChildren(ctx context.Context, q folder.GetC
continue
}
// TODO: Remove this once we migrate the alerting use case.
// This is a temporary flag, and will be removed once we migrate the alerting use case to
// expect a folder ref too for children folders.
if q.RefOnly { // nolint:staticcheck
f := &folder.Folder{
ID: item.Field.GetNestedInt64(search.DASHBOARD_LEGACY_ID),
UID: item.Name,
Title: item.Title,
ParentUID: item.Folder,
}
if item.Field.GetNestedString(resource.SEARCH_FIELD_MANAGER_KIND) != "" {
f.ManagedBy = utils.ParseManagerKindString(item.Field.GetNestedString(resource.SEARCH_FIELD_MANAGER_KIND))
}
hits = append(hits, f)
continue
}
// search only returns a subset of info, get all info of the folder
f, err := ss.Get(ctx, folder.GetFolderQuery{UID: &item.Name, OrgID: q.OrgID})
if err != nil {
@@ -388,4 +388,55 @@ func TestGetChildren(t *testing.T) {
require.NoError(t, err)
require.Len(t, result, 1)
})
t.Run("should not do get requests for the children if RefOnly is true", func(t *testing.T) {
mockCli.On("Search", mock.Anything, orgID, &resource.ResourceSearchRequest{
Options: &resource.ListOptions{
Fields: []*resource.Requirement{
{
Key: resource.SEARCH_FIELD_FOLDER,
Operator: string(selection.In),
Values: []string{"folder1"},
},
},
},
Limit: folderSearchLimit, // should default to folderSearchLimit
Offset: 0, // should be set as limit * (page - 1)
Page: 1, // should be set to 1 by default
}).Return(&resource.ResourceSearchResponse{
Results: &resource.ResourceTable{
Columns: []*resource.ResourceTableColumnDefinition{
{Name: "folder", Type: resource.ResourceTableColumnDefinition_STRING},
},
Rows: []*resource.ResourceTableRow{
{
Key: &resource.ResourceKey{Name: "folder2", Resource: "folder"},
Cells: [][]byte{[]byte("folder1")},
},
{
Key: &resource.ResourceKey{Name: "folder3", Resource: "folder"},
Cells: [][]byte{[]byte("folder1")},
},
},
},
TotalHits: 1,
}, nil).Once()
// only get the parent folder in this request
mockCli.On("Get", mock.Anything, "folder1", orgID, mock.Anything, mock.Anything).Return(&unstructured.Unstructured{
Object: map[string]interface{}{
"metadata": map[string]interface{}{"name": "folder1"},
},
}, nil).Once()
// don't set page or limit - should be automatically added
result, err := store.GetChildren(ctx, folder.GetChildrenQuery{
UID: "folder1",
OrgID: orgID,
RefOnly: true, // nolint:staticcheck
})
require.NoError(t, err)
require.Len(t, result, 2)
require.Equal(t, "folder2", result[0].UID)
require.Equal(t, "folder3", result[1].UID)
})
}
+3
View File
@@ -221,6 +221,9 @@ type GetChildrenQuery struct {
// array of folder uids to filter by
FolderUIDs []string `json:"-"`
// Deprecated: this is a temporary flag, and will be removed once we migrate the alerting use case
RefOnly bool
}
type HasEditPermissionInFoldersQuery struct {