mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
provisioning: support camelcase for dashboards configs
This commit is contained in:
parent
4a35244cb9
commit
b010e4df93
@ -1,5 +1,9 @@
|
||||
# # config file version
|
||||
# apiVersion: 1
|
||||
|
||||
#providers:
|
||||
# - name: 'default'
|
||||
# org_id: 1
|
||||
# orgId: 1
|
||||
# folder: ''
|
||||
# type: file
|
||||
# options:
|
||||
|
@ -177,8 +177,11 @@ It's possible to manage dashboards in Grafana by adding one or more yaml config
|
||||
The dashboard provider config file looks somewhat like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: 'default'
|
||||
org_id: 1
|
||||
orgId: 1
|
||||
folder: ''
|
||||
type: file
|
||||
options:
|
||||
|
@ -14,6 +14,37 @@ type configReader struct {
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func parseConfigs(yamlFile []byte) ([]*DashboardsAsConfig, error) {
|
||||
apiVersion := &ConfigVersion{ApiVersion: 0}
|
||||
yaml.Unmarshal(yamlFile, &apiVersion)
|
||||
|
||||
if apiVersion.ApiVersion > 0 {
|
||||
|
||||
v1 := &DashboardAsConfigV1{}
|
||||
err := yaml.Unmarshal(yamlFile, &v1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if v1 != nil {
|
||||
return v1.mapToDashboardAsConfig(), nil
|
||||
}
|
||||
|
||||
} else {
|
||||
var v0 []*DashboardsAsConfigV0
|
||||
err := yaml.Unmarshal(yamlFile, &v0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if v0 != nil {
|
||||
return convertv0ToDashboardAsConfig(v0), nil
|
||||
}
|
||||
}
|
||||
|
||||
return []*DashboardsAsConfig{}, nil
|
||||
}
|
||||
|
||||
func (cr *configReader) readConfig() ([]*DashboardsAsConfig, error) {
|
||||
var dashboards []*DashboardsAsConfig
|
||||
|
||||
@ -35,13 +66,14 @@ func (cr *configReader) readConfig() ([]*DashboardsAsConfig, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var dashCfg []*DashboardsAsConfig
|
||||
err = yaml.Unmarshal(yamlFile, &dashCfg)
|
||||
parsedDashboards, err := parseConfigs(yamlFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
}
|
||||
|
||||
dashboards = append(dashboards, dashCfg...)
|
||||
if len(parsedDashboards) > 0 {
|
||||
dashboards = append(dashboards, parsedDashboards...)
|
||||
}
|
||||
}
|
||||
|
||||
for i := range dashboards {
|
||||
|
@ -9,48 +9,33 @@ import (
|
||||
|
||||
var (
|
||||
simpleDashboardConfig string = "./test-configs/dashboards-from-disk"
|
||||
oldVersion string = "./test-configs/version-0"
|
||||
brokenConfigs string = "./test-configs/broken-configs"
|
||||
)
|
||||
|
||||
func TestDashboardsAsConfig(t *testing.T) {
|
||||
Convey("Dashboards as configuration", t, func() {
|
||||
logger := log.New("test-logger")
|
||||
|
||||
Convey("Can read config file", func() {
|
||||
|
||||
cfgProvider := configReader{path: simpleDashboardConfig, log: log.New("test-logger")}
|
||||
Convey("Can read config file version 1 format", func() {
|
||||
cfgProvider := configReader{path: simpleDashboardConfig, log: logger}
|
||||
cfg, err := cfgProvider.readConfig()
|
||||
if err != nil {
|
||||
t.Fatalf("readConfig return an error %v", err)
|
||||
}
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(cfg), ShouldEqual, 2)
|
||||
validateDashboardAsConfig(cfg)
|
||||
})
|
||||
|
||||
ds := cfg[0]
|
||||
Convey("Can read config file in version 0 format", func() {
|
||||
cfgProvider := configReader{path: oldVersion, log: logger}
|
||||
cfg, err := cfgProvider.readConfig()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(ds.Name, ShouldEqual, "general dashboards")
|
||||
So(ds.Type, ShouldEqual, "file")
|
||||
So(ds.OrgId, ShouldEqual, 2)
|
||||
So(ds.Folder, ShouldEqual, "developers")
|
||||
So(ds.Editable, ShouldBeTrue)
|
||||
|
||||
So(len(ds.Options), ShouldEqual, 1)
|
||||
So(ds.Options["path"], ShouldEqual, "/var/lib/grafana/dashboards")
|
||||
|
||||
ds2 := cfg[1]
|
||||
|
||||
So(ds2.Name, ShouldEqual, "default")
|
||||
So(ds2.Type, ShouldEqual, "file")
|
||||
So(ds2.OrgId, ShouldEqual, 1)
|
||||
So(ds2.Folder, ShouldEqual, "")
|
||||
So(ds2.Editable, ShouldBeFalse)
|
||||
|
||||
So(len(ds2.Options), ShouldEqual, 1)
|
||||
So(ds2.Options["path"], ShouldEqual, "/var/lib/grafana/dashboards")
|
||||
validateDashboardAsConfig(cfg)
|
||||
})
|
||||
|
||||
Convey("Should skip invalid path", func() {
|
||||
|
||||
cfgProvider := configReader{path: "/invalid-directory", log: log.New("test-logger")}
|
||||
cfgProvider := configReader{path: "/invalid-directory", log: logger}
|
||||
cfg, err := cfgProvider.readConfig()
|
||||
if err != nil {
|
||||
t.Fatalf("readConfig return an error %v", err)
|
||||
@ -61,7 +46,7 @@ func TestDashboardsAsConfig(t *testing.T) {
|
||||
|
||||
Convey("Should skip broken config files", func() {
|
||||
|
||||
cfgProvider := configReader{path: brokenConfigs, log: log.New("test-logger")}
|
||||
cfgProvider := configReader{path: brokenConfigs, log: logger}
|
||||
cfg, err := cfgProvider.readConfig()
|
||||
if err != nil {
|
||||
t.Fatalf("readConfig return an error %v", err)
|
||||
@ -71,3 +56,23 @@ func TestDashboardsAsConfig(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
func validateDashboardAsConfig(cfg []*DashboardsAsConfig) {
|
||||
So(len(cfg), ShouldEqual, 2)
|
||||
|
||||
ds := cfg[0]
|
||||
So(ds.Name, ShouldEqual, "general dashboards")
|
||||
So(ds.Type, ShouldEqual, "file")
|
||||
So(ds.OrgId, ShouldEqual, 2)
|
||||
So(ds.Folder, ShouldEqual, "developers")
|
||||
So(ds.Editable, ShouldBeTrue)
|
||||
So(len(ds.Options), ShouldEqual, 1)
|
||||
So(ds.Options["path"], ShouldEqual, "/var/lib/grafana/dashboards")
|
||||
ds2 := cfg[1]
|
||||
So(ds2.Name, ShouldEqual, "default")
|
||||
So(ds2.Type, ShouldEqual, "file")
|
||||
So(ds2.OrgId, ShouldEqual, 1)
|
||||
So(ds2.Folder, ShouldEqual, "")
|
||||
So(ds2.Editable, ShouldBeFalse)
|
||||
So(len(ds2.Options), ShouldEqual, 1)
|
||||
So(ds2.Options["path"], ShouldEqual, "/var/lib/grafana/dashboards")
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: 'general dashboards'
|
||||
org_id: 2
|
||||
orgId: 2
|
||||
folder: 'developers'
|
||||
editable: true
|
||||
type: file
|
||||
|
@ -0,0 +1,12 @@
|
||||
- name: 'general dashboards'
|
||||
org_id: 2
|
||||
folder: 'developers'
|
||||
editable: true
|
||||
type: file
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards
|
||||
|
||||
- name: 'default'
|
||||
type: file
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards
|
@ -10,6 +10,15 @@ import (
|
||||
)
|
||||
|
||||
type DashboardsAsConfig struct {
|
||||
Name string
|
||||
Type string
|
||||
OrgId int64
|
||||
Folder string
|
||||
Editable bool
|
||||
Options map[string]interface{}
|
||||
}
|
||||
|
||||
type DashboardsAsConfigV0 struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Type string `json:"type" yaml:"type"`
|
||||
OrgId int64 `json:"org_id" yaml:"org_id"`
|
||||
@ -18,6 +27,59 @@ type DashboardsAsConfig struct {
|
||||
Options map[string]interface{} `json:"options" yaml:"options"`
|
||||
}
|
||||
|
||||
func convertv0ToDashboardAsConfig(v0 []*DashboardsAsConfigV0) []*DashboardsAsConfig {
|
||||
var r []*DashboardsAsConfig
|
||||
|
||||
for _, v := range v0 {
|
||||
r = append(r, &DashboardsAsConfig{
|
||||
Name: v.Name,
|
||||
Type: v.Type,
|
||||
OrgId: v.OrgId,
|
||||
Folder: v.Folder,
|
||||
Editable: v.Editable,
|
||||
Options: v.Options,
|
||||
})
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
type ConfigVersion struct {
|
||||
ApiVersion int64 `json:"apiVersion" yaml:"apiVersion"`
|
||||
}
|
||||
|
||||
type DashboardAsConfigV1 struct {
|
||||
ApiVersion int64 `json:"apiVersion" yaml:"apiVersion"`
|
||||
|
||||
Providers []*DashboardSource `json:"providers" yaml:"providers"`
|
||||
}
|
||||
|
||||
func (dc *DashboardAsConfigV1) mapToDashboardAsConfig() []*DashboardsAsConfig {
|
||||
var r []*DashboardsAsConfig
|
||||
|
||||
for _, v := range dc.Providers {
|
||||
r = append(r, &DashboardsAsConfig{
|
||||
Name: v.Name,
|
||||
Type: v.Type,
|
||||
OrgId: v.OrgId,
|
||||
Folder: v.Folder,
|
||||
Editable: v.Editable,
|
||||
Options: v.Options,
|
||||
})
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
type DashboardSource struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Type string `json:"type" yaml:"type"`
|
||||
OrgId int64 `json:"orgId" yaml:"orgId"`
|
||||
Folder string `json:"folder" yaml:"folder"`
|
||||
Editable bool `json:"editable" yaml:"editable"`
|
||||
Options map[string]interface{} `json:"options" yaml:"options"`
|
||||
}
|
||||
|
||||
func createDashboardJson(data *simplejson.Json, lastModified time.Time, cfg *DashboardsAsConfig, folderId int64) (*dashboards.SaveDashboardDTO, error) {
|
||||
dash := &dashboards.SaveDashboardDTO{}
|
||||
dash.Dashboard = models.NewDashboardFromJson(data)
|
||||
|
Loading…
Reference in New Issue
Block a user