Commit 59104118 by bergquist

datasource as cfg: add support for securedata field

parent 930da631
...@@ -11,13 +11,9 @@ import ( ...@@ -11,13 +11,9 @@ import (
yaml "gopkg.in/yaml.v2" 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 { type DatasourcesAsConfig struct {
PurgeOtherDatasources bool PurgeOtherDatasources bool
Datasources []models.DataSource Datasources []DataSourceFromConfig
} }
func Init(configPath string) error { func Init(configPath string) error {
...@@ -49,50 +45,39 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error { ...@@ -49,50 +45,39 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
return err return err
} }
all, err := dc.repository.loadAllDatasources() allDatasources, err := dc.repository.loadAllDatasources()
if err != nil { if err != nil {
return err return err
} }
for i, _ := range cfg.Datasources { for i := range cfg.Datasources {
if cfg.Datasources[i].OrgId == 0 { if cfg.Datasources[i].OrgId == 0 {
cfg.Datasources[i].OrgId = 1 cfg.Datasources[i].OrgId = 1
} }
} }
if cfg.PurgeOtherDatasources { if err := dc.deleteDatasourcesNotInConfiguration(cfg, allDatasources); err != nil {
for _, dbDatasource := range all { return err
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})
}
}
} }
for _, ds := range cfg.Datasources { for _, ds := range cfg.Datasources {
var dbDatasource *models.DataSource
query := &models.GetDataSourceByNameQuery{Name: ds.Name, OrgId: ds.OrgId} for _, ddd := range allDatasources {
err := dc.repository.get(query) if ddd.Name == ds.Name && ddd.OrgId == ds.OrgId {
if err != nil && err != models.ErrDataSourceNotFound { dbDatasource = ddd
return err break
}
} }
if query.Result == nil { if dbDatasource == nil {
dc.log.Info("inserting ", "name", ds.Name) dc.log.Info("inserting datasource from configuration ", "name", ds.Name)
insertCmd := createInsertCommand(ds) insertCmd := createInsertCommand(ds)
if err := dc.repository.insert(insertCmd); err != nil { if err := dc.repository.insert(insertCmd); err != nil {
return err return err
} }
} else { } else {
dc.log.Info("updating", "name", ds.Name) dc.log.Info("updating datasource from configuration", "name", ds.Name)
updateCmd := createUpdateCommand(ds, query.Result.Id) updateCmd := createUpdateCommand(ds, dbDatasource.Id)
if err := dc.repository.update(updateCmd); err != nil { if err := dc.repository.update(updateCmd); err != nil {
return err return err
} }
...@@ -102,43 +87,27 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error { ...@@ -102,43 +87,27 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
return nil return nil
} }
func createInsertCommand(ds models.DataSource) *models.AddDataSourceCommand { func (dc *DatasourceConfigurator) deleteDatasourcesNotInConfiguration(cfg *DatasourcesAsConfig, allDatasources []*models.DataSource) error {
return &models.AddDataSourceCommand{ if cfg.PurgeOtherDatasources {
OrgId: ds.OrgId, for _, dbDS := range allDatasources {
Name: ds.Name, delete := true
Type: ds.Type, for _, cfgDS := range cfg.Datasources {
Access: ds.Access, if dbDS.Name == cfgDS.Name && dbDS.OrgId == cfgDS.OrgId {
Url: ds.Url, delete = false
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 createUpdateCommand(ds models.DataSource, id int64) *models.UpdateDataSourceCommand { if delete {
return &models.UpdateDataSourceCommand{ dc.log.Info("deleting datasource from configuration", "name", dbDS.Name)
Id: id, cmd := &models.DeleteDataSourceByIdCommand{Id: dbDS.Id, OrgId: dbDS.OrgId}
OrgId: ds.OrgId, if err := dc.repository.delete(cmd); err != nil {
Name: ds.Name, return err
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,
} }
return nil
} }
type datasourceRepository interface { type datasourceRepository interface {
......
...@@ -19,8 +19,8 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -19,8 +19,8 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("One configured datasource", func() { Convey("One configured datasource", func() {
fakeCfg.cfg = &DatasourcesAsConfig{ fakeCfg.cfg = &DatasourcesAsConfig{
PurgeOtherDatasources: false, PurgeOtherDatasources: false,
Datasources: []models.DataSource{ Datasources: []DataSourceFromConfig{
models.DataSource{Name: "graphite", OrgId: 1}, {Name: "graphite", OrgId: 1},
}, },
} }
...@@ -38,7 +38,7 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -38,7 +38,7 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("One datasource in database with same name", func() { Convey("One datasource in database with same name", func() {
fakeRepo.loadAll = []*models.DataSource{ fakeRepo.loadAll = []*models.DataSource{
&models.DataSource{Name: "graphite", OrgId: 1, Id: 1}, {Name: "graphite", OrgId: 1, Id: 1},
} }
Convey("should update one datasource", func() { Convey("should update one datasource", func() {
...@@ -56,7 +56,7 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -56,7 +56,7 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("One datasource in database with new name", func() { Convey("One datasource in database with new name", func() {
fakeRepo.loadAll = []*models.DataSource{ 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() { Convey("should update one datasource", func() {
...@@ -76,16 +76,16 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -76,16 +76,16 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("Two configured datasource and purge others ", func() { Convey("Two configured datasource and purge others ", func() {
fakeCfg.cfg = &DatasourcesAsConfig{ fakeCfg.cfg = &DatasourcesAsConfig{
PurgeOtherDatasources: true, PurgeOtherDatasources: true,
Datasources: []models.DataSource{ Datasources: []DataSourceFromConfig{
models.DataSource{Name: "graphite", OrgId: 1}, {Name: "graphite", OrgId: 1},
models.DataSource{Name: "prometheus", OrgId: 1}, {Name: "prometheus", OrgId: 1},
}, },
} }
Convey("two other datasources in database", func() { Convey("two other datasources in database", func() {
fakeRepo.loadAll = []*models.DataSource{ fakeRepo.loadAll = []*models.DataSource{
&models.DataSource{Name: "old-graphite", OrgId: 1, Id: 1}, {Name: "old-graphite", OrgId: 1, Id: 1},
&models.DataSource{Name: "old-graphite2", OrgId: 1, Id: 2}, {Name: "old-graphite2", OrgId: 1, Id: 2},
} }
Convey("should have two new datasources", func() { Convey("should have two new datasources", func() {
...@@ -100,22 +100,21 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -100,22 +100,21 @@ func TestDatasourceAsConfig(t *testing.T) {
So(len(fakeRepo.updated), ShouldEqual, 0) So(len(fakeRepo.updated), ShouldEqual, 0)
}) })
}) })
}) })
Convey("Two configured datasource and purge others = false", func() { Convey("Two configured datasource and purge others = false", func() {
fakeCfg.cfg = &DatasourcesAsConfig{ fakeCfg.cfg = &DatasourcesAsConfig{
PurgeOtherDatasources: false, PurgeOtherDatasources: false,
Datasources: []models.DataSource{ Datasources: []DataSourceFromConfig{
models.DataSource{Name: "graphite", OrgId: 1}, {Name: "graphite", OrgId: 1},
models.DataSource{Name: "prometheus", OrgId: 1}, {Name: "prometheus", OrgId: 1},
}, },
} }
Convey("two other datasources in database", func() { Convey("two other datasources in database", func() {
fakeRepo.loadAll = []*models.DataSource{ fakeRepo.loadAll = []*models.DataSource{
&models.DataSource{Name: "old-graphite", OrgId: 1, Id: 1}, {Name: "graphite", OrgId: 1, Id: 1},
&models.DataSource{Name: "old-graphite2", OrgId: 1, Id: 2}, {Name: "old-graphite2", OrgId: 1, Id: 2},
} }
Convey("should have two new datasources", func() { Convey("should have two new datasources", func() {
...@@ -126,11 +125,10 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -126,11 +125,10 @@ func TestDatasourceAsConfig(t *testing.T) {
} }
So(len(fakeRepo.deleted), ShouldEqual, 0) So(len(fakeRepo.deleted), ShouldEqual, 0)
So(len(fakeRepo.inserted), ShouldEqual, 2) So(len(fakeRepo.inserted), ShouldEqual, 1)
So(len(fakeRepo.updated), ShouldEqual, 0) So(len(fakeRepo.updated), ShouldEqual, 1)
}) })
}) })
}) })
}) })
} }
......
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,
}
}
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