Dashboard Provisioning: Add duplicate cleanup for modes 0-2 (#113336)
This commit is contained in:
@@ -876,6 +876,12 @@ func (dr *DashboardServiceImpl) waitForSearchQuery(ctx context.Context, query *d
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *dashboards.DeleteOrphanedProvisionedDashboardsCommand) error {
|
||||
// cleanup duplicate provisioned dashboards first (this will have the same name and external_id)
|
||||
// note: only works in modes 1-3
|
||||
if err := dr.DeleteDuplicateProvisionedDashboards(ctx); err != nil {
|
||||
dr.log.Error("Failed to delete duplicate provisioned dashboards", "error", err)
|
||||
}
|
||||
|
||||
// check each org for orphaned provisioned dashboards
|
||||
orgs, err := dr.orgService.Search(ctx, &org.SearchOrgsQuery{})
|
||||
if err != nil {
|
||||
@@ -914,6 +920,34 @@ func (dr *DashboardServiceImpl) DeleteOrphanedProvisionedDashboards(ctx context.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) DeleteDuplicateProvisionedDashboards(ctx context.Context) error {
|
||||
duplicates, err := dr.dashboardStore.GetDuplicateProvisionedDashboards(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type provisioningKey struct {
|
||||
name string
|
||||
externalID string
|
||||
}
|
||||
|
||||
groups := make(map[provisioningKey][]*dashboards.DashboardProvisioningSearchResults)
|
||||
for _, dash := range duplicates {
|
||||
key := provisioningKey{
|
||||
name: dash.Provisioner,
|
||||
externalID: dash.ExternalID,
|
||||
}
|
||||
if _, exists := groups[key]; exists {
|
||||
if err = dr.deleteDashboard(ctx, dash.ID, dash.UID, dash.OrgID, false); err != nil {
|
||||
dr.log.Error("Failed to delete duplicate provisioned dashboard", "error", err, "dashboardUID", dash.UID, "dashboardID", dash.ID)
|
||||
}
|
||||
}
|
||||
groups[key] = append(groups[key], dash)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) ValidateDashboardRefreshInterval(minRefreshInterval string, targetRefreshInterval string) error {
|
||||
if minRefreshInterval == "" {
|
||||
return nil
|
||||
|
||||
@@ -629,16 +629,19 @@ func TestGetProvisionedDashboardDataByDashboardUID(t *testing.T) {
|
||||
|
||||
func TestDeleteOrphanedProvisionedDashboards(t *testing.T) {
|
||||
fakePublicDashboardService := publicdashboards.NewFakePublicDashboardServiceWrapper(t)
|
||||
fakeDashboardStore := &dashboards.FakeDashboardStore{}
|
||||
service := &DashboardServiceImpl{
|
||||
cfg: setting.NewCfg(),
|
||||
orgService: &orgtest.FakeOrgService{
|
||||
ExpectedOrgs: []*org.OrgDTO{{ID: 1}, {ID: 2}},
|
||||
},
|
||||
publicDashboardService: fakePublicDashboardService,
|
||||
dashboardStore: fakeDashboardStore,
|
||||
log: log.NewNopLogger(),
|
||||
}
|
||||
|
||||
t.Run("Should delete across all orgs, but only delete file based provisioned dashboards", func(t *testing.T) {
|
||||
fakeDashboardStore.On("GetDuplicateProvisionedDashboards", mock.Anything).Return([]*dashboards.DashboardProvisioningSearchResults{}, nil)
|
||||
_, k8sCliMock := setupK8sDashboardTests(service)
|
||||
k8sCliMock.On("GetNamespace", mock.Anything, mock.Anything).Return("default")
|
||||
k8sCliMock.On("Delete", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
@@ -783,6 +786,7 @@ func TestDeleteOrphanedProvisionedDashboards(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Should retry until deleted dashboard not found in search", func(t *testing.T) {
|
||||
fakeDashboardStore.On("GetDuplicateProvisionedDashboards", mock.Anything).Return([]*dashboards.DashboardProvisioningSearchResults{}, nil)
|
||||
repo := "test"
|
||||
singleOrgService := &DashboardServiceImpl{
|
||||
cfg: setting.NewCfg(),
|
||||
@@ -790,6 +794,7 @@ func TestDeleteOrphanedProvisionedDashboards(t *testing.T) {
|
||||
ExpectedOrgs: []*org.OrgDTO{{ID: 1}},
|
||||
},
|
||||
publicDashboardService: fakePublicDashboardService,
|
||||
dashboardStore: fakeDashboardStore,
|
||||
log: log.NewNopLogger(),
|
||||
}
|
||||
ctx, k8sCliMock := setupK8sDashboardTests(singleOrgService)
|
||||
@@ -876,6 +881,7 @@ func TestDeleteOrphanedProvisionedDashboards(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Will not wait for indexer when no dashboards were deleted", func(t *testing.T) {
|
||||
fakeDashboardStore.On("GetDuplicateProvisionedDashboards", mock.Anything).Return([]*dashboards.DashboardProvisioningSearchResults{}, nil)
|
||||
repo := "test"
|
||||
singleOrgService := &DashboardServiceImpl{
|
||||
cfg: setting.NewCfg(),
|
||||
@@ -883,6 +889,7 @@ func TestDeleteOrphanedProvisionedDashboards(t *testing.T) {
|
||||
ExpectedOrgs: []*org.OrgDTO{{ID: 1}},
|
||||
},
|
||||
publicDashboardService: fakePublicDashboardService,
|
||||
dashboardStore: fakeDashboardStore,
|
||||
log: log.NewNopLogger(),
|
||||
}
|
||||
ctx, k8sCliMock := setupK8sDashboardTests(singleOrgService)
|
||||
|
||||
Reference in New Issue
Block a user