Commit 8880829e by bergquist

avoid infinite loop in the dashboard provisioner

if one dashboard with an uid is refered to by two
provsioners each provsioner overwrite each other.
filling up dashboard_versions quite fast if using
default settings.

ref #12864
parent dc9b8303
...@@ -4,6 +4,6 @@ providers: ...@@ -4,6 +4,6 @@ providers:
- name: 'gdev dashboards' - name: 'gdev dashboards'
folder: 'gdev dashboards' folder: 'gdev dashboards'
type: file type: file
updateIntervalSeconds: 15
options: options:
path: devenv/dev-dashboards path: devenv/dev-dashboards
package dashboards package dashboards
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
...@@ -69,7 +70,7 @@ func (cr *configReader) readConfig() ([]*DashboardsAsConfig, error) { ...@@ -69,7 +70,7 @@ func (cr *configReader) readConfig() ([]*DashboardsAsConfig, error) {
parsedDashboards, err := cr.parseConfigs(file) parsedDashboards, err := cr.parseConfigs(file)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("could not parse provisioning config file: %s error: %v", file.Name(), err)
} }
if len(parsedDashboards) > 0 { if len(parsedDashboards) > 0 {
......
...@@ -118,6 +118,7 @@ func (fr *fileReader) startWalkingDisk() error { ...@@ -118,6 +118,7 @@ func (fr *fileReader) startWalkingDisk() error {
return nil return nil
} }
func (fr *fileReader) deleteDashboardIfFileIsMissing(provisionedDashboardRefs map[string]*models.DashboardProvisioning, filesFoundOnDisk map[string]os.FileInfo) { func (fr *fileReader) deleteDashboardIfFileIsMissing(provisionedDashboardRefs map[string]*models.DashboardProvisioning, filesFoundOnDisk map[string]os.FileInfo) {
if fr.Cfg.DisableDeletion { if fr.Cfg.DisableDeletion {
return return
...@@ -180,7 +181,7 @@ func (fr *fileReader) saveDashboard(path string, folderId int64, fileInfo os.Fil ...@@ -180,7 +181,7 @@ func (fr *fileReader) saveDashboard(path string, folderId int64, fileInfo os.Fil
dash.Dashboard.SetId(provisionedData.DashboardId) dash.Dashboard.SetId(provisionedData.DashboardId)
} }
fr.log.Debug("saving new dashboard", "file", path) fr.log.Debug("saving new dashboard", "provisoner", fr.Cfg.Name, "file", path, "folderId", dash.Dashboard.FolderId)
dp := &models.DashboardProvisioning{ dp := &models.DashboardProvisioning{
ExternalId: path, ExternalId: path,
Name: fr.Cfg.Name, Name: fr.Cfg.Name,
......
...@@ -166,6 +166,36 @@ func TestDashboardFileReader(t *testing.T) { ...@@ -166,6 +166,36 @@ func TestDashboardFileReader(t *testing.T) {
_, err := NewDashboardFileReader(cfg, logger) _, err := NewDashboardFileReader(cfg, logger)
So(err, ShouldBeNil) So(err, ShouldBeNil)
}) })
Convey("Two dashboard providers should be able to provisioned the same dashboard without uid", func() {
cfg1 := &DashboardsAsConfig{Name: "1", Type: "file", OrgId: 1, Folder: "f1", Options: map[string]interface{}{"path": containingId}}
cfg2 := &DashboardsAsConfig{Name: "2", Type: "file", OrgId: 1, Folder: "f2", Options: map[string]interface{}{"path": containingId}}
reader1, err := NewDashboardFileReader(cfg1, logger)
So(err, ShouldBeNil)
err = reader1.startWalkingDisk()
So(err, ShouldBeNil)
reader2, err := NewDashboardFileReader(cfg2, logger)
So(err, ShouldBeNil)
err = reader2.startWalkingDisk()
So(err, ShouldBeNil)
var folderCount int
var dashCount int
for _, o := range fakeService.inserted {
if o.Dashboard.IsFolder {
folderCount++
} else {
dashCount++
}
}
So(folderCount, ShouldEqual, 2)
So(dashCount, ShouldEqual, 2)
})
}) })
Convey("Should not create new folder if folder name is missing", func() { Convey("Should not create new folder if folder name is missing", func() {
...@@ -256,7 +286,9 @@ func (ffi FakeFileInfo) Sys() interface{} { ...@@ -256,7 +286,9 @@ func (ffi FakeFileInfo) Sys() interface{} {
} }
func mockDashboardProvisioningService() *fakeDashboardProvisioningService { func mockDashboardProvisioningService() *fakeDashboardProvisioningService {
mock := fakeDashboardProvisioningService{} mock := fakeDashboardProvisioningService{
provisioned: map[string][]*models.DashboardProvisioning{},
}
dashboards.NewProvisioningService = func() dashboards.DashboardProvisioningService { dashboards.NewProvisioningService = func() dashboards.DashboardProvisioningService {
return &mock return &mock
} }
...@@ -265,17 +297,26 @@ func mockDashboardProvisioningService() *fakeDashboardProvisioningService { ...@@ -265,17 +297,26 @@ func mockDashboardProvisioningService() *fakeDashboardProvisioningService {
type fakeDashboardProvisioningService struct { type fakeDashboardProvisioningService struct {
inserted []*dashboards.SaveDashboardDTO inserted []*dashboards.SaveDashboardDTO
provisioned []*models.DashboardProvisioning provisioned map[string][]*models.DashboardProvisioning
getDashboard []*models.Dashboard getDashboard []*models.Dashboard
} }
func (s *fakeDashboardProvisioningService) GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error) { func (s *fakeDashboardProvisioningService) GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error) {
return s.provisioned, nil if _, ok := s.provisioned[name]; !ok {
s.provisioned[name] = []*models.DashboardProvisioning{}
}
return s.provisioned[name], nil
} }
func (s *fakeDashboardProvisioningService) SaveProvisionedDashboard(dto *dashboards.SaveDashboardDTO, provisioning *models.DashboardProvisioning) (*models.Dashboard, error) { func (s *fakeDashboardProvisioningService) SaveProvisionedDashboard(dto *dashboards.SaveDashboardDTO, provisioning *models.DashboardProvisioning) (*models.Dashboard, error) {
s.inserted = append(s.inserted, dto) s.inserted = append(s.inserted, dto)
s.provisioned = append(s.provisioned, provisioning)
if _, ok := s.provisioned[provisioning.Name]; !ok {
s.provisioned[provisioning.Name] = []*models.DashboardProvisioning{}
}
s.provisioned[provisioning.Name] = append(s.provisioned[provisioning.Name], provisioning)
return dto.Dashboard, nil return dto.Dashboard, nil
} }
......
...@@ -51,7 +51,7 @@ func SaveProvisionedDashboard(cmd *models.SaveProvisionedDashboardCommand) error ...@@ -51,7 +51,7 @@ func SaveProvisionedDashboard(cmd *models.SaveProvisionedDashboardCommand) error
func saveProvionedData(sess *DBSession, cmd *models.DashboardProvisioning, dashboard *models.Dashboard) error { func saveProvionedData(sess *DBSession, cmd *models.DashboardProvisioning, dashboard *models.Dashboard) error {
result := &models.DashboardProvisioning{} result := &models.DashboardProvisioning{}
exist, err := sess.Where("dashboard_id=?", dashboard.Id).Get(result) exist, err := sess.Where("dashboard_id=? AND name = ?", dashboard.Id, cmd.Name).Get(result)
if err != nil { if err != nil {
return err return err
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment