diff --git a/pkg/services/provisioning/dashboards/config_reader.go b/pkg/services/provisioning/dashboards/config_reader.go index d004221a352..50614d3f881 100644 --- a/pkg/services/provisioning/dashboards/config_reader.go +++ b/pkg/services/provisioning/dashboards/config_reader.go @@ -40,7 +40,7 @@ func (cr *configReader) parseConfigs(file os.FileInfo) ([]*DashboardsAsConfig, e } if v1 != nil { - return v1.mapToDashboardAsConfig(), nil + return v1.mapToDashboardsAsConfig() } } else { var v0 []*DashboardsAsConfigV0 @@ -51,7 +51,7 @@ func (cr *configReader) parseConfigs(file os.FileInfo) ([]*DashboardsAsConfig, e if v0 != nil { cr.log.Warn("[Deprecated] the dashboard provisioning config is outdated. please upgrade", "filename", filename) - return mapV0ToDashboardAsConfig(v0), nil + return mapV0ToDashboardsAsConfig(v0) } } diff --git a/pkg/services/provisioning/dashboards/types.go b/pkg/services/provisioning/dashboards/types.go index ef373680e8e..0a259856fca 100644 --- a/pkg/services/provisioning/dashboards/types.go +++ b/pkg/services/provisioning/dashboards/types.go @@ -1,13 +1,13 @@ package dashboards import ( - "github.com/grafana/grafana/pkg/services/provisioning/values" + "fmt" "time" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/services/dashboards" - "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/provisioning/values" ) type DashboardsAsConfig struct { @@ -73,10 +73,16 @@ func createDashboardJson(data *simplejson.Json, lastModified time.Time, cfg *Das return dash, nil } -func mapV0ToDashboardAsConfig(v0 []*DashboardsAsConfigV0) []*DashboardsAsConfig { +func mapV0ToDashboardsAsConfig(v0 []*DashboardsAsConfigV0) ([]*DashboardsAsConfig, error) { var r []*DashboardsAsConfig + seen := make(map[string]bool) for _, v := range v0 { + if _, ok := seen[v.Name]; ok { + return nil, fmt.Errorf("dashboard name %q is not unique", v.Name) + } + seen[v.Name] = true + r = append(r, &DashboardsAsConfig{ Name: v.Name, Type: v.Type, @@ -91,13 +97,19 @@ func mapV0ToDashboardAsConfig(v0 []*DashboardsAsConfigV0) []*DashboardsAsConfig }) } - return r + return r, nil } -func (dc *DashboardAsConfigV1) mapToDashboardAsConfig() []*DashboardsAsConfig { +func (dc *DashboardAsConfigV1) mapToDashboardsAsConfig() ([]*DashboardsAsConfig, error) { var r []*DashboardsAsConfig + seen := make(map[string]bool) for _, v := range dc.Providers { + if _, ok := seen[v.Name.Value()]; ok { + return nil, fmt.Errorf("dashboard name %q is not unique", v.Name.Value()) + } + seen[v.Name.Value()] = true + r = append(r, &DashboardsAsConfig{ Name: v.Name.Value(), Type: v.Type.Value(), @@ -112,5 +124,5 @@ func (dc *DashboardAsConfigV1) mapToDashboardAsConfig() []*DashboardsAsConfig { }) } - return r + return r, nil } diff --git a/pkg/services/provisioning/provisioning.go b/pkg/services/provisioning/provisioning.go index 840ef4944fe..7ca68468577 100644 --- a/pkg/services/provisioning/provisioning.go +++ b/pkg/services/provisioning/provisioning.go @@ -75,6 +75,7 @@ func (ps *provisioningServiceImpl) Run(ctx context.Context) error { err := ps.ProvisionDashboards() if err != nil { ps.log.Error("Failed to provision dashboard", "error", err) + return err } for {