Fix folder parents getter max depth validation (#111568)

* Fix folder parents getter max depth validation

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>

* Move max depth validation out of newParentsGetter

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>

* Add tests

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>

---------

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>
This commit is contained in:
maicon
2025-09-25 10:02:21 +03:00
committed by GitHub
parent df86de78d8
commit 991ac5b72e
3 changed files with 61 additions and 50 deletions
-5
View File
@@ -72,11 +72,6 @@ func newParentsGetter(getter rest.Getter, maxDepth int) parentsGetter {
break
}
if len(info.Items) >= maxDepth {
err = folderLegacy.ErrMaximumDepthReached
break
}
found[parentFolder.Name] = true
folder = parentFolder
}
-15
View File
@@ -111,21 +111,6 @@ func TestParents(t *testing.T) {
},
expectedErr: "cyclic folder references found",
},
{
name: "too deep",
request: input{
name: "test",
folder: "p1",
},
maxDepth: 3,
expectedErr: "[folder.maximum-depth-reached]",
expected: &folders.FolderInfoList{Items: []folders.FolderInfo{
{Name: "test", Parent: "p1"},
{Name: "p1", Parent: "p2"},
{Name: "p2", Parent: "p3"},
{Name: "p3", Parent: "p4"}, // should not try calling p4
}},
},
}
for _, tt := range tests {
+61 -30
View File
@@ -2,6 +2,7 @@ package folders
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/mock"
@@ -57,35 +58,6 @@ func TestFolderAPIBuilder_Validate_Create(t *testing.T) {
name: "valid-name",
},
},
{
name: "should not allow creating a folder in a tree that is too deep",
input: input{
obj: &folders.Folder{
Spec: folders.FolderSpec{
Title: "foo",
},
},
annotations: map[string]string{"grafana.app/folder": "p1"}, // already max depth
name: "valid-name",
},
setupFn: func(m *grafanarest.MockStorage) {
m.On("Get", mock.Anything, "p1", mock.Anything).Return(
&folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "p1",
Annotations: map[string]string{"grafana.app/folder": "p2"},
},
}, nil).Maybe()
m.On("Get", mock.Anything, "p2", mock.Anything).Return(
&folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "p2",
Annotations: map[string]string{"grafana.app/folder": "p3"},
},
}, nil).Maybe()
},
err: folder.ErrMaximumDepthReached,
},
{
name: "should return error when title is empty",
input: input{
@@ -111,6 +83,59 @@ func TestFolderAPIBuilder_Validate_Create(t *testing.T) {
},
err: folder.ErrFolderCannotBeParentOfItself,
},
{
name: "should not allow creating a folder that will become too deep",
input: input{
annotations: map[string]string{utils.AnnoKeyFolder: "p1"},
obj: &folders.Folder{
Spec: folders.FolderSpec{
Title: "title",
},
ObjectMeta: metav1.ObjectMeta{
Name: "p0",
Annotations: map[string]string{"grafana.app/folder": "p1"},
},
},
name: "p0",
},
setupFn: func(m *grafanarest.MockStorage) {
m.On("Get", mock.Anything, "p1", mock.Anything).Return(
&folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "p1",
Annotations: map[string]string{"grafana.app/folder": "p2"},
},
}, nil)
m.On("Get", mock.Anything, "p2", mock.Anything).Return(
&folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "p2",
Annotations: map[string]string{"grafana.app/folder": "p3"},
},
}, nil)
m.On("Get", mock.Anything, "p3", mock.Anything).Return(
&folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "p3",
Annotations: map[string]string{"grafana.app/folder": "p4"},
},
}, nil)
m.On("Get", mock.Anything, "p4", mock.Anything).Return(
&folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "p4",
Annotations: map[string]string{"grafana.app/folder": "p5"},
},
}, nil)
m.On("Get", mock.Anything, "p5", mock.Anything).Return(
&folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "p5",
},
}, nil)
},
err: fmt.Errorf("folder max depth exceeded, max depth is 4"),
},
}
for _, tt := range tests {
@@ -148,7 +173,7 @@ func TestFolderAPIBuilder_Validate_Create(t *testing.T) {
if tt.err == nil {
require.NoError(t, err)
} else {
require.ErrorIs(t, err, tt.err)
require.Contains(t, err.Error(), tt.err.Error())
return
}
})
@@ -336,6 +361,12 @@ func TestFolderAPIBuilder_Validate_Update(t *testing.T) {
Annotations: map[string]string{"grafana.app/folder": "p4"},
},
}, nil)
m.On("Get", mock.Anything, "p4", mock.Anything).Return(
&folders.Folder{
ObjectMeta: metav1.ObjectMeta{
Name: "p4",
},
}, nil)
},
wantErr: true,
},