Commit 3091697a by Carl Bergquist Committed by GitHub

Merge pull request #10896 from bergquist/provisioning_cfg_camelCase

Change naming format to camelCase for provisioning configs
parents 8dd4d505 84de76ff
# # config file version
# apiVersion: 1
#providers:
# - name: 'default'
# org_id: 1
# orgId: 1
# folder: ''
# type: file
# options:
......
# # config file version
# apiVersion: 1
# # list of datasources that should be deleted from the database
#delete_datasources:
#deleteDatasources:
# - name: Graphite
# org_id: 1
# orgId: 1
# # list of datasources to insert/update depending
# # on what's available in the datbase
......@@ -12,8 +15,8 @@
# type: graphite
# # <string, required> access mode. direct or proxy. Required
# access: proxy
# # <int> org id. will default to org_id 1 if not specified
# org_id: 1
# # <int> org id. will default to orgId 1 if not specified
# orgId: 1
# # <string> url
# url: http://localhost:8080
# # <string> database password, if used
......@@ -23,22 +26,22 @@
# # <string> database name, if used
# database:
# # <bool> enable/disable basic auth
# basic_auth:
# basicAuth:
# # <string> basic auth username
# basic_auth_user:
# basicAuthUser:
# # <string> basic auth password
# basic_auth_password:
# basicAuthPassword:
# # <bool> enable/disable with credentials headers
# with_credentials:
# withCredentials:
# # <bool> mark as default datasource. Max one per org
# is_default:
# isDefault:
# # <map> fields that will be converted to json and stored in json_data
# json_data:
# jsonData:
# graphiteVersion: "1.1"
# tlsAuth: true
# tlsAuthWithCACert: true
# # <string> json object of data that will be encrypted.
# secure_json_data:
# secureJsonData:
# tlsCACert: "..."
# tlsClientCert: "..."
# tlsClientKey: "..."
......
......@@ -81,13 +81,16 @@ If you are running multiple instances of Grafana you might run into problems if
### Example datasource config file
```yaml
# config file version
apiVersion: 1
# list of datasources that should be deleted from the database
delete_datasources:
deleteDatasources:
- name: Graphite
org_id: 1
orgId: 1
# list of datasources to insert/update depending
# whats available in the datbase
# whats available in the database
datasources:
# <string, required> name of the datasource. Required
- name: Graphite
......@@ -95,8 +98,8 @@ datasources:
type: graphite
# <string, required> access mode. direct or proxy. Required
access: proxy
# <int> org id. will default to org_id 1 if not specified
org_id: 1
# <int> org id. will default to orgId 1 if not specified
orgId: 1
# <string> url
url: http://localhost:8080
# <string> database password, if used
......@@ -106,22 +109,22 @@ datasources:
# <string> database name, if used
database:
# <bool> enable/disable basic auth
basic_auth:
basicAuth:
# <string> basic auth username
basic_auth_user:
basicAuthUser:
# <string> basic auth password
basic_auth_password:
basicAuthPassword:
# <bool> enable/disable with credentials headers
with_credentials:
withCredentials:
# <bool> mark as default datasource. Max one per org
is_default:
isDefault:
# <map> fields that will be converted to json and stored in json_data
json_data:
jsonData:
graphiteVersion: "1.1"
tlsAuth: true
tlsAuthWithCACert: true
# <string> json object of data that will be encrypted.
secure_json_data:
secureJsonData:
tlsCACert: "..."
tlsClientCert: "..."
tlsClientKey: "..."
......@@ -174,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:
......
......@@ -2,6 +2,7 @@ package dashboards
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
......@@ -14,11 +15,48 @@ type configReader struct {
log log.Logger
}
func (cr *configReader) parseConfigs(file os.FileInfo) ([]*DashboardsAsConfig, error) {
filename, _ := filepath.Abs(filepath.Join(cr.path, file.Name()))
yamlFile, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
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 {
cr.log.Warn("[Deprecated] the dashboard provisioning config is outdated. please upgrade", "filename", filename)
return mapV0ToDashboardAsConfig(v0), nil
}
}
return []*DashboardsAsConfig{}, nil
}
func (cr *configReader) readConfig() ([]*DashboardsAsConfig, error) {
var dashboards []*DashboardsAsConfig
files, err := ioutil.ReadDir(cr.path)
if err != nil {
cr.log.Error("cant read dashboard provisioning files from directory", "path", cr.path)
return dashboards, nil
......@@ -29,19 +67,14 @@ func (cr *configReader) readConfig() ([]*DashboardsAsConfig, error) {
continue
}
filename, _ := filepath.Abs(filepath.Join(cr.path, file.Name()))
yamlFile, err := ioutil.ReadFile(filename)
parsedDashboards, err := cr.parseConfigs(file)
if err != nil {
return nil, err
}
var dashCfg []*DashboardsAsConfig
err = yaml.Unmarshal(yamlFile, &dashCfg)
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(len(cfg), ShouldEqual, 2)
ds := cfg[0]
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]
validateDashboardAsConfig(cfg)
})
So(ds2.Name, ShouldEqual, "default")
So(ds2.Type, ShouldEqual, "file")
So(ds2.OrgId, ShouldEqual, 1)
So(ds2.Folder, ShouldEqual, "")
So(ds2.Editable, ShouldBeFalse)
Convey("Can read config file in version 0 format", func() {
cfgProvider := configReader{path: oldVersion, log: logger}
cfg, err := cfgProvider.readConfig()
So(err, ShouldBeNil)
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")
}
apiVersion: 1
providers:
- name: 'general dashboards'
org_id: 2
orgId: 2
folder: 'developers'
editable: true
type: file
......
- 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,23 @@ type DashboardsAsConfig struct {
Options map[string]interface{} `json:"options" yaml:"options"`
}
type ConfigVersion struct {
ApiVersion int64 `json:"apiVersion" yaml:"apiVersion"`
}
type DashboardAsConfigV1 struct {
Providers []*DashboardProviderConfigs `json:"providers" yaml:"providers"`
}
type DashboardProviderConfigs 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)
......@@ -36,3 +62,37 @@ func createDashboardJson(data *simplejson.Json, lastModified time.Time, cfg *Das
return dash, nil
}
func mapV0ToDashboardAsConfig(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
}
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
}
package datasources
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/grafana/grafana/pkg/log"
"gopkg.in/yaml.v2"
)
type configReader struct {
log log.Logger
}
func (cr *configReader) readConfig(path string) ([]*DatasourcesAsConfig, error) {
var datasources []*DatasourcesAsConfig
files, err := ioutil.ReadDir(path)
if err != nil {
cr.log.Error("cant read datasource provisioning files from directory", "path", path)
return datasources, nil
}
for _, file := range files {
if strings.HasSuffix(file.Name(), ".yaml") || strings.HasSuffix(file.Name(), ".yml") {
datasource, err := cr.parseDatasourceConfig(path, file)
if err != nil {
return nil, err
}
if datasource != nil {
datasources = append(datasources, datasource)
}
}
}
err = validateDefaultUniqueness(datasources)
if err != nil {
return nil, err
}
return datasources, nil
}
func (cr *configReader) parseDatasourceConfig(path string, file os.FileInfo) (*DatasourcesAsConfig, error) {
filename, _ := filepath.Abs(filepath.Join(path, file.Name()))
yamlFile, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
var apiVersion *ConfigVersion
err = yaml.Unmarshal(yamlFile, &apiVersion)
if err != nil {
return nil, err
}
if apiVersion.ApiVersion > 0 {
var v1 *DatasourcesAsConfigV1
err = yaml.Unmarshal(yamlFile, &v1)
if err != nil {
return nil, err
}
return v1.mapToDatasourceFromConfig(apiVersion.ApiVersion), nil
}
var v0 *DatasourcesAsConfigV0
err = yaml.Unmarshal(yamlFile, &v0)
if err != nil {
return nil, err
}
cr.log.Warn("[Deprecated] the datasource provisioning config is outdated. please upgrade", "filename", filename)
return v0.mapToDatasourceFromConfig(apiVersion.ApiVersion), nil
}
func validateDefaultUniqueness(datasources []*DatasourcesAsConfig) error {
defaultCount := 0
for i := range datasources {
if datasources[i].Datasources == nil {
continue
}
for _, ds := range datasources[i].Datasources {
if ds.OrgId == 0 {
ds.OrgId = 1
}
if ds.IsDefault {
defaultCount++
if defaultCount > 1 {
return ErrInvalidConfigToManyDefault
}
}
}
for _, ds := range datasources[i].DeleteDatasources {
if ds.OrgId == 0 {
ds.OrgId = 1
}
}
}
return nil
}
......@@ -17,6 +17,7 @@ var (
twoDatasourcesConfigPurgeOthers string = "./test-configs/insert-two-delete-two"
doubleDatasourcesConfig string = "./test-configs/double-default"
allProperties string = "./test-configs/all-properties"
versionZero string = "./test-configs/version-0"
brokenYaml string = "./test-configs/broken-yaml"
fakeRepo *fakeRepository
......@@ -130,7 +131,7 @@ func TestDatasourceAsConfig(t *testing.T) {
So(len(cfg), ShouldEqual, 0)
})
Convey("can read all properties", func() {
Convey("can read all properties from version 1", func() {
cfgProvifer := &configReader{log: log.New("test logger")}
cfg, err := cfgProvifer.readConfig(allProperties)
if err != nil {
......@@ -140,38 +141,65 @@ func TestDatasourceAsConfig(t *testing.T) {
So(len(cfg), ShouldEqual, 2)
dsCfg := cfg[0]
ds := dsCfg.Datasources[0]
So(ds.Name, ShouldEqual, "name")
So(ds.Type, ShouldEqual, "type")
So(ds.Access, ShouldEqual, models.DS_ACCESS_PROXY)
So(ds.OrgId, ShouldEqual, 2)
So(ds.Url, ShouldEqual, "url")
So(ds.User, ShouldEqual, "user")
So(ds.Password, ShouldEqual, "password")
So(ds.Database, ShouldEqual, "database")
So(ds.BasicAuth, ShouldBeTrue)
So(ds.BasicAuthUser, ShouldEqual, "basic_auth_user")
So(ds.BasicAuthPassword, ShouldEqual, "basic_auth_password")
So(ds.WithCredentials, ShouldBeTrue)
So(ds.IsDefault, ShouldBeTrue)
So(ds.Editable, ShouldBeTrue)
So(len(ds.JsonData), ShouldBeGreaterThan, 2)
So(ds.JsonData["graphiteVersion"], ShouldEqual, "1.1")
So(ds.JsonData["tlsAuth"], ShouldEqual, true)
So(ds.JsonData["tlsAuthWithCACert"], ShouldEqual, true)
So(len(ds.SecureJsonData), ShouldBeGreaterThan, 2)
So(ds.SecureJsonData["tlsCACert"], ShouldEqual, "MjNOcW9RdkbUDHZmpco2HCYzVq9dE+i6Yi+gmUJotq5CDA==")
So(ds.SecureJsonData["tlsClientCert"], ShouldEqual, "ckN0dGlyMXN503YNfjTcf9CV+GGQneN+xmAclQ==")
So(ds.SecureJsonData["tlsClientKey"], ShouldEqual, "ZkN4aG1aNkja/gKAB1wlnKFIsy2SRDq4slrM0A==")
dstwo := cfg[1].Datasources[0]
So(dstwo.Name, ShouldEqual, "name2")
So(dsCfg.ApiVersion, ShouldEqual, 1)
validateDatasource(dsCfg)
validateDeleteDatasources(dsCfg)
})
Convey("can read all properties from version 0", func() {
cfgProvifer := &configReader{log: log.New("test logger")}
cfg, err := cfgProvifer.readConfig(versionZero)
if err != nil {
t.Fatalf("readConfig return an error %v", err)
}
So(len(cfg), ShouldEqual, 1)
dsCfg := cfg[0]
So(dsCfg.ApiVersion, ShouldEqual, 0)
validateDatasource(dsCfg)
validateDeleteDatasources(dsCfg)
})
})
}
func validateDeleteDatasources(dsCfg *DatasourcesAsConfig) {
So(len(dsCfg.DeleteDatasources), ShouldEqual, 1)
deleteDs := dsCfg.DeleteDatasources[0]
So(deleteDs.Name, ShouldEqual, "old-graphite3")
So(deleteDs.OrgId, ShouldEqual, 2)
}
func validateDatasource(dsCfg *DatasourcesAsConfig) {
ds := dsCfg.Datasources[0]
So(ds.Name, ShouldEqual, "name")
So(ds.Type, ShouldEqual, "type")
So(ds.Access, ShouldEqual, models.DS_ACCESS_PROXY)
So(ds.OrgId, ShouldEqual, 2)
So(ds.Url, ShouldEqual, "url")
So(ds.User, ShouldEqual, "user")
So(ds.Password, ShouldEqual, "password")
So(ds.Database, ShouldEqual, "database")
So(ds.BasicAuth, ShouldBeTrue)
So(ds.BasicAuthUser, ShouldEqual, "basic_auth_user")
So(ds.BasicAuthPassword, ShouldEqual, "basic_auth_password")
So(ds.WithCredentials, ShouldBeTrue)
So(ds.IsDefault, ShouldBeTrue)
So(ds.Editable, ShouldBeTrue)
So(ds.Version, ShouldEqual, 10)
So(len(ds.JsonData), ShouldBeGreaterThan, 2)
So(ds.JsonData["graphiteVersion"], ShouldEqual, "1.1")
So(ds.JsonData["tlsAuth"], ShouldEqual, true)
So(ds.JsonData["tlsAuthWithCACert"], ShouldEqual, true)
So(len(ds.SecureJsonData), ShouldBeGreaterThan, 2)
So(ds.SecureJsonData["tlsCACert"], ShouldEqual, "MjNOcW9RdkbUDHZmpco2HCYzVq9dE+i6Yi+gmUJotq5CDA==")
So(ds.SecureJsonData["tlsClientCert"], ShouldEqual, "ckN0dGlyMXN503YNfjTcf9CV+GGQneN+xmAclQ==")
So(ds.SecureJsonData["tlsClientKey"], ShouldEqual, "ZkN4aG1aNkja/gKAB1wlnKFIsy2SRDq4slrM0A==")
}
type fakeRepository struct {
inserted []*models.AddDataSourceCommand
......
......@@ -2,16 +2,12 @@ package datasources
import (
"errors"
"io/ioutil"
"path/filepath"
"strings"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models"
yaml "gopkg.in/yaml.v2"
)
var (
......@@ -94,65 +90,3 @@ func (dc *DatasourceProvisioner) deleteDatasources(dsToDelete []*DeleteDatasourc
return nil
}
type configReader struct {
log log.Logger
}
func (cr *configReader) readConfig(path string) ([]*DatasourcesAsConfig, error) {
var datasources []*DatasourcesAsConfig
files, err := ioutil.ReadDir(path)
if err != nil {
cr.log.Error("cant read datasource provisioning files from directory", "path", path)
return datasources, nil
}
for _, file := range files {
if strings.HasSuffix(file.Name(), ".yaml") || strings.HasSuffix(file.Name(), ".yml") {
filename, _ := filepath.Abs(filepath.Join(path, file.Name()))
yamlFile, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
var datasource *DatasourcesAsConfig
err = yaml.Unmarshal(yamlFile, &datasource)
if err != nil {
return nil, err
}
if datasource != nil {
datasources = append(datasources, datasource)
}
}
}
defaultCount := 0
for i := range datasources {
if datasources[i].Datasources == nil {
continue
}
for _, ds := range datasources[i].Datasources {
if ds.OrgId == 0 {
ds.OrgId = 1
}
if ds.IsDefault {
defaultCount++
if defaultCount > 1 {
return nil, ErrInvalidConfigToManyDefault
}
}
}
for _, ds := range datasources[i].DeleteDatasources {
if ds.OrgId == 0 {
ds.OrgId = 1
}
}
}
return datasources, nil
}
apiVersion: 1
datasources:
- name: name
type: type
access: proxy
org_id: 2
orgId: 2
url: url
password: password
user: user
database: database
basic_auth: true
basic_auth_user: basic_auth_user
basic_auth_password: basic_auth_password
with_credentials: true
is_default: true
json_data:
basicAuth: true
basicAuthUser: basic_auth_user
basicAuthPassword: basic_auth_password
withCredentials: true
isDefault: true
jsonData:
graphiteVersion: "1.1"
tlsAuth: true
tlsAuthWithCACert: true
secure_json_data:
secureJsonData:
tlsCACert: "MjNOcW9RdkbUDHZmpco2HCYzVq9dE+i6Yi+gmUJotq5CDA=="
tlsClientCert: "ckN0dGlyMXN503YNfjTcf9CV+GGQneN+xmAclQ=="
tlsClientKey: "ZkN4aG1aNkja/gKAB1wlnKFIsy2SRDq4slrM0A=="
editable: true
version: 10
deleteDatasources:
- name: old-graphite3
orgId: 2
......@@ -3,5 +3,5 @@ datasources:
- name: name2
type: type2
access: proxy
org_id: 2
orgId: 2
url: url2
datasources:
- name: name
type: type
access: proxy
org_id: 2
url: url
password: password
user: user
database: database
basic_auth: true
basic_auth_user: basic_auth_user
basic_auth_password: basic_auth_password
with_credentials: true
is_default: true
json_data:
graphiteVersion: "1.1"
tlsAuth: true
tlsAuthWithCACert: true
secure_json_data:
tlsCACert: "MjNOcW9RdkbUDHZmpco2HCYzVq9dE+i6Yi+gmUJotq5CDA=="
tlsClientCert: "ckN0dGlyMXN503YNfjTcf9CV+GGQneN+xmAclQ=="
tlsClientKey: "ZkN4aG1aNkja/gKAB1wlnKFIsy2SRDq4slrM0A=="
editable: true
version: 10
delete_datasources:
- name: old-graphite3
org_id: 2
package datasources
import "github.com/grafana/grafana/pkg/models"
import (
"github.com/grafana/grafana/pkg/models"
)
import "github.com/grafana/grafana/pkg/components/simplejson"
type ConfigVersion struct {
ApiVersion int64 `json:"apiVersion" yaml:"apiVersion"`
}
type DatasourcesAsConfig struct {
Datasources []*DataSourceFromConfig `json:"datasources" yaml:"datasources"`
DeleteDatasources []*DeleteDatasourceConfig `json:"delete_datasources" yaml:"delete_datasources"`
ApiVersion int64
Datasources []*DataSourceFromConfig
DeleteDatasources []*DeleteDatasourceConfig
}
type DeleteDatasourceConfig struct {
OrgId int64
Name string
}
type DataSourceFromConfig struct {
OrgId int64
Version int
Name string
Type string
Access string
Url string
Password string
User string
Database string
BasicAuth bool
BasicAuthUser string
BasicAuthPassword string
WithCredentials bool
IsDefault bool
JsonData map[string]interface{}
SecureJsonData map[string]string
Editable bool
}
type DatasourcesAsConfigV0 struct {
ConfigVersion
Datasources []*DataSourceFromConfigV0 `json:"datasources" yaml:"datasources"`
DeleteDatasources []*DeleteDatasourceConfigV0 `json:"delete_datasources" yaml:"delete_datasources"`
}
type DatasourcesAsConfigV1 struct {
ConfigVersion
Datasources []*DataSourceFromConfigV1 `json:"datasources" yaml:"datasources"`
DeleteDatasources []*DeleteDatasourceConfigV1 `json:"deleteDatasources" yaml:"deleteDatasources"`
}
type DeleteDatasourceConfigV0 struct {
OrgId int64 `json:"org_id" yaml:"org_id"`
Name string `json:"name" yaml:"name"`
}
type DataSourceFromConfig struct {
OrgId int64 `json:"org_id" yaml:"org_id"`
Version int `json:"version" yaml:"version"`
type DeleteDatasourceConfigV1 struct {
OrgId int64 `json:"orgId" yaml:"orgId"`
Name string `json:"name" yaml:"name"`
}
type DataSourceFromConfigV0 struct {
OrgId int64 `json:"org_id" yaml:"org_id"`
Version int `json:"version" yaml:"version"`
Name string `json:"name" yaml:"name"`
Type string `json:"type" yaml:"type"`
Access string `json:"access" yaml:"access"`
......@@ -34,6 +86,100 @@ type DataSourceFromConfig struct {
Editable bool `json:"editable" yaml:"editable"`
}
type DataSourceFromConfigV1 struct {
OrgId int64 `json:"orgId" yaml:"orgId"`
Version int `json:"version" yaml:"version"`
Name string `json:"name" yaml:"name"`
Type string `json:"type" yaml:"type"`
Access string `json:"access" yaml:"access"`
Url string `json:"url" yaml:"url"`
Password string `json:"password" yaml:"password"`
User string `json:"user" yaml:"user"`
Database string `json:"database" yaml:"database"`
BasicAuth bool `json:"basicAuth" yaml:"basicAuth"`
BasicAuthUser string `json:"basicAuthUser" yaml:"basicAuthUser"`
BasicAuthPassword string `json:"basicAuthPassword" yaml:"basicAuthPassword"`
WithCredentials bool `json:"withCredentials" yaml:"withCredentials"`
IsDefault bool `json:"isDefault" yaml:"isDefault"`
JsonData map[string]interface{} `json:"jsonData" yaml:"jsonData"`
SecureJsonData map[string]string `json:"secureJsonData" yaml:"secureJsonData"`
Editable bool `json:"editable" yaml:"editable"`
}
func (cfg *DatasourcesAsConfigV1) mapToDatasourceFromConfig(apiVersion int64) *DatasourcesAsConfig {
r := &DatasourcesAsConfig{}
r.ApiVersion = apiVersion
for _, ds := range cfg.Datasources {
r.Datasources = append(r.Datasources, &DataSourceFromConfig{
OrgId: ds.OrgId,
Name: ds.Name,
Type: ds.Type,
Access: ds.Access,
Url: ds.Url,
Password: ds.Password,
User: ds.User,
Database: ds.Database,
BasicAuth: ds.BasicAuth,
BasicAuthUser: ds.BasicAuthUser,
BasicAuthPassword: ds.BasicAuthPassword,
WithCredentials: ds.WithCredentials,
IsDefault: ds.IsDefault,
JsonData: ds.JsonData,
SecureJsonData: ds.SecureJsonData,
Editable: ds.Editable,
Version: ds.Version,
})
}
for _, ds := range cfg.DeleteDatasources {
r.DeleteDatasources = append(r.DeleteDatasources, &DeleteDatasourceConfig{
OrgId: ds.OrgId,
Name: ds.Name,
})
}
return r
}
func (cfg *DatasourcesAsConfigV0) mapToDatasourceFromConfig(apiVersion int64) *DatasourcesAsConfig {
r := &DatasourcesAsConfig{}
r.ApiVersion = apiVersion
for _, ds := range cfg.Datasources {
r.Datasources = append(r.Datasources, &DataSourceFromConfig{
OrgId: ds.OrgId,
Name: ds.Name,
Type: ds.Type,
Access: ds.Access,
Url: ds.Url,
Password: ds.Password,
User: ds.User,
Database: ds.Database,
BasicAuth: ds.BasicAuth,
BasicAuthUser: ds.BasicAuthUser,
BasicAuthPassword: ds.BasicAuthPassword,
WithCredentials: ds.WithCredentials,
IsDefault: ds.IsDefault,
JsonData: ds.JsonData,
SecureJsonData: ds.SecureJsonData,
Editable: ds.Editable,
Version: ds.Version,
})
}
for _, ds := range cfg.DeleteDatasources {
r.DeleteDatasources = append(r.DeleteDatasources, &DeleteDatasourceConfig{
OrgId: ds.OrgId,
Name: ds.Name,
})
}
return r
}
func createInsertCommand(ds *DataSourceFromConfig) *models.AddDataSourceCommand {
jsonData := simplejson.New()
if len(ds.JsonData) > 0 {
......
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