datasource as cfg: add support for securedata field

This commit is contained in:
bergquist
2017-10-11 21:44:23 +02:00
parent 930da63173
commit 5910411845
3 changed files with 126 additions and 83 deletions

View File

@@ -11,13 +11,9 @@ import (
yaml "gopkg.in/yaml.v2"
)
// TODO: secure jsonData
// TODO: auto reload on file changes
// TODO: remove get method since all datasources is in memory
type DatasourcesAsConfig struct {
PurgeOtherDatasources bool
Datasources []models.DataSource
Datasources []DataSourceFromConfig
}
func Init(configPath string) error {
@@ -49,50 +45,39 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
return err
}
all, err := dc.repository.loadAllDatasources()
allDatasources, err := dc.repository.loadAllDatasources()
if err != nil {
return err
}
for i, _ := range cfg.Datasources {
for i := range cfg.Datasources {
if cfg.Datasources[i].OrgId == 0 {
cfg.Datasources[i].OrgId = 1
}
}
if cfg.PurgeOtherDatasources {
for _, dbDatasource := range all {
delete := true
for _, cfgDatasource := range cfg.Datasources {
if dbDatasource.Name == cfgDatasource.Name && dbDatasource.OrgId == cfgDatasource.OrgId {
delete = false
}
}
if delete {
dc.log.Info("deleting datasource since PurgeOtherDatasource is enabled", "name", dbDatasource.Name)
dc.repository.delete(&models.DeleteDataSourceByIdCommand{Id: dbDatasource.Id, OrgId: dbDatasource.OrgId})
}
}
if err := dc.deleteDatasourcesNotInConfiguration(cfg, allDatasources); err != nil {
return err
}
for _, ds := range cfg.Datasources {
query := &models.GetDataSourceByNameQuery{Name: ds.Name, OrgId: ds.OrgId}
err := dc.repository.get(query)
if err != nil && err != models.ErrDataSourceNotFound {
return err
var dbDatasource *models.DataSource
for _, ddd := range allDatasources {
if ddd.Name == ds.Name && ddd.OrgId == ds.OrgId {
dbDatasource = ddd
break
}
}
if query.Result == nil {
dc.log.Info("inserting ", "name", ds.Name)
if dbDatasource == nil {
dc.log.Info("inserting datasource from configuration ", "name", ds.Name)
insertCmd := createInsertCommand(ds)
if err := dc.repository.insert(insertCmd); err != nil {
return err
}
} else {
dc.log.Info("updating", "name", ds.Name)
updateCmd := createUpdateCommand(ds, query.Result.Id)
dc.log.Info("updating datasource from configuration", "name", ds.Name)
updateCmd := createUpdateCommand(ds, dbDatasource.Id)
if err := dc.repository.update(updateCmd); err != nil {
return err
}
@@ -102,43 +87,27 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
return nil
}
func createInsertCommand(ds models.DataSource) *models.AddDataSourceCommand {
return &models.AddDataSourceCommand{
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,
}
}
func (dc *DatasourceConfigurator) deleteDatasourcesNotInConfiguration(cfg *DatasourcesAsConfig, allDatasources []*models.DataSource) error {
if cfg.PurgeOtherDatasources {
for _, dbDS := range allDatasources {
delete := true
for _, cfgDS := range cfg.Datasources {
if dbDS.Name == cfgDS.Name && dbDS.OrgId == cfgDS.OrgId {
delete = false
}
}
func createUpdateCommand(ds models.DataSource, id int64) *models.UpdateDataSourceCommand {
return &models.UpdateDataSourceCommand{
Id: id,
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,
if delete {
dc.log.Info("deleting datasource from configuration", "name", dbDS.Name)
cmd := &models.DeleteDataSourceByIdCommand{Id: dbDS.Id, OrgId: dbDS.OrgId}
if err := dc.repository.delete(cmd); err != nil {
return err
}
}
}
}
return nil
}
type datasourceRepository interface {

View File

@@ -19,8 +19,8 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("One configured datasource", func() {
fakeCfg.cfg = &DatasourcesAsConfig{
PurgeOtherDatasources: false,
Datasources: []models.DataSource{
models.DataSource{Name: "graphite", OrgId: 1},
Datasources: []DataSourceFromConfig{
{Name: "graphite", OrgId: 1},
},
}
@@ -38,7 +38,7 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("One datasource in database with same name", func() {
fakeRepo.loadAll = []*models.DataSource{
&models.DataSource{Name: "graphite", OrgId: 1, Id: 1},
{Name: "graphite", OrgId: 1, Id: 1},
}
Convey("should update one datasource", func() {
@@ -56,7 +56,7 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("One datasource in database with new name", func() {
fakeRepo.loadAll = []*models.DataSource{
&models.DataSource{Name: "old-graphite", OrgId: 1, Id: 1},
{Name: "old-graphite", OrgId: 1, Id: 1},
}
Convey("should update one datasource", func() {
@@ -76,16 +76,16 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("Two configured datasource and purge others ", func() {
fakeCfg.cfg = &DatasourcesAsConfig{
PurgeOtherDatasources: true,
Datasources: []models.DataSource{
models.DataSource{Name: "graphite", OrgId: 1},
models.DataSource{Name: "prometheus", OrgId: 1},
Datasources: []DataSourceFromConfig{
{Name: "graphite", OrgId: 1},
{Name: "prometheus", OrgId: 1},
},
}
Convey("two other datasources in database", func() {
fakeRepo.loadAll = []*models.DataSource{
&models.DataSource{Name: "old-graphite", OrgId: 1, Id: 1},
&models.DataSource{Name: "old-graphite2", OrgId: 1, Id: 2},
{Name: "old-graphite", OrgId: 1, Id: 1},
{Name: "old-graphite2", OrgId: 1, Id: 2},
}
Convey("should have two new datasources", func() {
@@ -100,22 +100,21 @@ func TestDatasourceAsConfig(t *testing.T) {
So(len(fakeRepo.updated), ShouldEqual, 0)
})
})
})
Convey("Two configured datasource and purge others = false", func() {
fakeCfg.cfg = &DatasourcesAsConfig{
PurgeOtherDatasources: false,
Datasources: []models.DataSource{
models.DataSource{Name: "graphite", OrgId: 1},
models.DataSource{Name: "prometheus", OrgId: 1},
Datasources: []DataSourceFromConfig{
{Name: "graphite", OrgId: 1},
{Name: "prometheus", OrgId: 1},
},
}
Convey("two other datasources in database", func() {
fakeRepo.loadAll = []*models.DataSource{
&models.DataSource{Name: "old-graphite", OrgId: 1, Id: 1},
&models.DataSource{Name: "old-graphite2", OrgId: 1, Id: 2},
{Name: "graphite", OrgId: 1, Id: 1},
{Name: "old-graphite2", OrgId: 1, Id: 2},
}
Convey("should have two new datasources", func() {
@@ -126,11 +125,10 @@ func TestDatasourceAsConfig(t *testing.T) {
}
So(len(fakeRepo.deleted), ShouldEqual, 0)
So(len(fakeRepo.inserted), ShouldEqual, 2)
So(len(fakeRepo.updated), ShouldEqual, 0)
So(len(fakeRepo.inserted), ShouldEqual, 1)
So(len(fakeRepo.updated), ShouldEqual, 1)
})
})
})
})
}

View File

@@ -0,0 +1,76 @@
package datasources
import "github.com/grafana/grafana/pkg/models"
import "github.com/grafana/grafana/pkg/components/simplejson"
type DataSourceFromConfig struct {
Id int64
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 string
SecureJsonData map[string]string
}
func createInsertCommand(ds DataSourceFromConfig) *models.AddDataSourceCommand {
jsonData, err := simplejson.NewJson([]byte(ds.JsonData))
if err != nil {
jsonData = simplejson.New()
}
return &models.AddDataSourceCommand{
OrgId: ds.OrgId,
Name: ds.Name,
Type: ds.Type,
Access: models.DsAccess(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: jsonData,
SecureJsonData: ds.SecureJsonData,
}
}
func createUpdateCommand(ds DataSourceFromConfig, id int64) *models.UpdateDataSourceCommand {
jsonData, err := simplejson.NewJson([]byte(ds.JsonData))
if err != nil {
jsonData = simplejson.New()
}
return &models.UpdateDataSourceCommand{
Id: id,
OrgId: ds.OrgId,
Name: ds.Name,
Type: ds.Type,
Access: models.DsAccess(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: jsonData,
SecureJsonData: ds.SecureJsonData,
}
}