mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
datasource as cfg: add support for securedata field
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
76
pkg/setting/datasources/types.go
Normal file
76
pkg/setting/datasources/types.go
Normal 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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user