Provisioning: Improve validation by validating across all dashboard providers (#26742)
* Provisioning: check sanity across all dashboard readers Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Apply suggestions from code review Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com> Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Refactor of duplicateValidator and fix issues according to commentaries Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Apply suggestions from code review Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove newDuplicateEntries function Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Change folderUid in logs to folderUID Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Restrict write access for readers, which are provisioning duplicate dashboards Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Fix file reader after rebasing onto master Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Apply suggestions from code review Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Format file_reader Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Apply suggestions from code review Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Apply suggestions from code review Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix lint problem Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Apply suggestions from code review Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com> Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com> Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
co-authored by
Emil Tullstedt
Arve Knudsen
Marcus Efraimsson
parent
1efa5f51cf
commit
ec9a587cbe
@@ -0,0 +1,124 @@
|
||||
package dashboards
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
)
|
||||
|
||||
const (
|
||||
dashboardContainingUID = "testdata/test-dashboards/dashboard-with-uid"
|
||||
twoDashboardsWithUID = "testdata/test-dashboards/two-dashboards-with-uid"
|
||||
)
|
||||
|
||||
func TestDuplicatesValidator(t *testing.T) {
|
||||
bus.ClearBusHandlers()
|
||||
fakeService = mockDashboardProvisioningService()
|
||||
|
||||
bus.AddHandler("test", mockGetDashboardQuery)
|
||||
cfg := &config{
|
||||
Name: "Default",
|
||||
Type: "file",
|
||||
OrgID: 1,
|
||||
Folder: "",
|
||||
Options: map[string]interface{}{},
|
||||
}
|
||||
logger := log.New("test.logger")
|
||||
|
||||
t.Run("Duplicates validator should collect info about duplicate UIDs and titles within folders", func(t *testing.T) {
|
||||
const folderName = "duplicates-validator-folder"
|
||||
folderID, err := getOrCreateFolderID(cfg, fakeService, folderName)
|
||||
require.NoError(t, err)
|
||||
|
||||
identity := dashboardIdentity{folderID: folderID, title: "Grafana"}
|
||||
|
||||
cfg1 := &config{
|
||||
Name: "first", Type: "file", OrgID: 1, Folder: folderName,
|
||||
Options: map[string]interface{}{"path": dashboardContainingUID},
|
||||
}
|
||||
cfg2 := &config{
|
||||
Name: "second", Type: "file", OrgID: 1, Folder: folderName,
|
||||
Options: map[string]interface{}{"path": dashboardContainingUID},
|
||||
}
|
||||
|
||||
reader1, err := NewDashboardFileReader(cfg1, logger, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
reader2, err := NewDashboardFileReader(cfg2, logger, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
duplicateValidator := newDuplicateValidator(logger, []*FileReader{reader1, reader2})
|
||||
|
||||
err = reader1.walkDisk()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = reader2.walkDisk()
|
||||
require.NoError(t, err)
|
||||
|
||||
duplicates := duplicateValidator.getDuplicates()
|
||||
|
||||
require.Equal(t, uint8(2), duplicates.UIDs["Z-phNqGmz"].Sum)
|
||||
uidUsageReaders := keysToSlice(duplicates.UIDs["Z-phNqGmz"].InvolvedReaders)
|
||||
sort.Strings(uidUsageReaders)
|
||||
require.Equal(t, []string{"first", "second"}, uidUsageReaders)
|
||||
|
||||
require.Equal(t, uint8(2), duplicates.Titles[identity].Sum)
|
||||
titleUsageReaders := keysToSlice(duplicates.Titles[identity].InvolvedReaders)
|
||||
sort.Strings(titleUsageReaders)
|
||||
require.Equal(t, []string{"first", "second"}, titleUsageReaders)
|
||||
|
||||
duplicateValidator.validate()
|
||||
require.True(t, reader1.isDatabaseAccessRestricted())
|
||||
require.True(t, reader2.isDatabaseAccessRestricted())
|
||||
})
|
||||
|
||||
t.Run("Duplicates validator should restrict write access only for readers with duplicates", func(t *testing.T) {
|
||||
cfg1 := &config{
|
||||
Name: "first", Type: "file", OrgID: 1, Folder: "duplicates-validator-folder",
|
||||
Options: map[string]interface{}{"path": twoDashboardsWithUID},
|
||||
}
|
||||
cfg2 := &config{
|
||||
Name: "second", Type: "file", OrgID: 1, Folder: "root",
|
||||
Options: map[string]interface{}{"path": defaultDashboards},
|
||||
}
|
||||
|
||||
reader1, err := NewDashboardFileReader(cfg1, logger, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
reader2, err := NewDashboardFileReader(cfg2, logger, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
duplicateValidator := newDuplicateValidator(logger, []*FileReader{reader1, reader2})
|
||||
|
||||
err = reader1.walkDisk()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = reader2.walkDisk()
|
||||
require.NoError(t, err)
|
||||
|
||||
duplicates := duplicateValidator.getDuplicates()
|
||||
|
||||
folderID, err := getOrCreateFolderID(cfg, fakeService, cfg1.Folder)
|
||||
require.NoError(t, err)
|
||||
|
||||
identity := dashboardIdentity{folderID: folderID, title: "Grafana"}
|
||||
|
||||
require.Equal(t, uint8(2), duplicates.UIDs["Z-phNqGmz"].Sum)
|
||||
uidUsageReaders := keysToSlice(duplicates.UIDs["Z-phNqGmz"].InvolvedReaders)
|
||||
sort.Strings(uidUsageReaders)
|
||||
require.Equal(t, []string{"first"}, uidUsageReaders)
|
||||
|
||||
require.Equal(t, uint8(2), duplicates.Titles[identity].Sum)
|
||||
titleUsageReaders := keysToSlice(duplicates.Titles[identity].InvolvedReaders)
|
||||
sort.Strings(titleUsageReaders)
|
||||
require.Equal(t, []string{"first"}, titleUsageReaders)
|
||||
|
||||
duplicateValidator.validate()
|
||||
require.True(t, reader1.isDatabaseAccessRestricted())
|
||||
require.False(t, reader2.isDatabaseAccessRestricted())
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user