mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
datasource as cfg: support globbing
This commit is contained in:
@@ -1,8 +1,3 @@
|
|||||||
# purge data source not listed in configuration.
|
|
||||||
# not recommended in HA setups if config can
|
|
||||||
# can differ between instances.
|
|
||||||
purge_other_datasources: false
|
|
||||||
|
|
||||||
# list of datasources to insert/update depending
|
# list of datasources to insert/update depending
|
||||||
# whats available in the datbase
|
# whats available in the datbase
|
||||||
datasources:
|
datasources:
|
||||||
@@ -42,9 +37,6 @@ datasources:
|
|||||||
# # <bool> allow users to edit datasources from the UI.
|
# # <bool> allow users to edit datasources from the UI.
|
||||||
# editable: true
|
# editable: true
|
||||||
|
|
||||||
|
delete_datasources:
|
||||||
# - name: Prometheus
|
# - name: Graphite
|
||||||
# type: prometheus
|
# org_id: 1
|
||||||
# access: proxy
|
|
||||||
# url: http://localhost:9090
|
|
||||||
|
|
||||||
@@ -12,17 +12,17 @@ instance_name = ${HOSTNAME}
|
|||||||
#################################### Paths ###############################
|
#################################### Paths ###############################
|
||||||
[paths]
|
[paths]
|
||||||
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
|
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
|
||||||
#
|
|
||||||
data = data
|
data = data
|
||||||
#
|
|
||||||
# Directory where grafana can store logs
|
# Directory where grafana can store logs
|
||||||
#
|
|
||||||
logs = data/log
|
logs = data/log
|
||||||
#
|
|
||||||
# Directory where grafana will automatically scan and look for plugins
|
# Directory where grafana will automatically scan and look for plugins
|
||||||
#
|
|
||||||
plugins = data/plugins
|
plugins = data/plugins
|
||||||
|
|
||||||
|
# Config files containing datasources that will be configured at startup
|
||||||
|
datasources = conf/datasources
|
||||||
|
|
||||||
#################################### Server ##############################
|
#################################### Server ##############################
|
||||||
[server]
|
[server]
|
||||||
# Protocol (http, https, socket)
|
# Protocol (http, https, socket)
|
||||||
|
|||||||
@@ -12,18 +12,17 @@
|
|||||||
#################################### Paths ####################################
|
#################################### Paths ####################################
|
||||||
[paths]
|
[paths]
|
||||||
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
|
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
|
||||||
#
|
|
||||||
;data = /var/lib/grafana
|
;data = /var/lib/grafana
|
||||||
#
|
|
||||||
# Directory where grafana can store logs
|
# Directory where grafana can store logs
|
||||||
#
|
|
||||||
;logs = /var/log/grafana
|
;logs = /var/log/grafana
|
||||||
#
|
|
||||||
# Directory where grafana will automatically scan and look for plugins
|
# Directory where grafana will automatically scan and look for plugins
|
||||||
#
|
|
||||||
;plugins = /var/lib/grafana/plugins
|
;plugins = /var/lib/grafana/plugins
|
||||||
|
|
||||||
#
|
# Config files containing datasources that will be configured at startup
|
||||||
|
;datasources = conf/datasources
|
||||||
|
|
||||||
#################################### Server ####################################
|
#################################### Server ####################################
|
||||||
[server]
|
[server]
|
||||||
# Protocol (http, https, socket)
|
# Protocol (http, https, socket)
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ func (g *GrafanaServerImpl) Start() {
|
|||||||
social.NewOAuthService()
|
social.NewOAuthService()
|
||||||
plugins.Init()
|
plugins.Init()
|
||||||
|
|
||||||
if err := provisioning.StartUp(setting.HomePath); err != nil {
|
//if err := provisioning.StartUp(setting.HomePath); err != nil {
|
||||||
|
if err := provisioning.StartUp(setting.DatasourcesPath); err != nil {
|
||||||
logger.Error("Failed to provision Grafana from config", "error", err)
|
logger.Error("Failed to provision Grafana from config", "error", err)
|
||||||
g.Shutdown(1, "Startup failed")
|
g.Shutdown(1, "Startup failed")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -146,11 +146,15 @@ type UpdateDataSourceCommand struct {
|
|||||||
type DeleteDataSourceByIdCommand struct {
|
type DeleteDataSourceByIdCommand struct {
|
||||||
Id int64
|
Id int64
|
||||||
OrgId int64
|
OrgId int64
|
||||||
|
|
||||||
|
DeletedDatasourcesCount int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteDataSourceByNameCommand struct {
|
type DeleteDataSourceByNameCommand struct {
|
||||||
Name string
|
Name string
|
||||||
OrgId int64
|
OrgId int64
|
||||||
|
|
||||||
|
DeletedDatasourcesCount int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
|
||||||
@@ -17,67 +18,36 @@ var (
|
|||||||
ErrInvalidConfigToManyDefault = errors.New("datasource.yaml config is invalid. Only one datasource can be marked as default")
|
ErrInvalidConfigToManyDefault = errors.New("datasource.yaml config is invalid. Only one datasource can be marked as default")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Apply(configPath string) error {
|
func Provision(configDirectory string) error {
|
||||||
dc := NewDatasourceConfiguration()
|
dc := newDatasourceProvisioner(log.New("provisioning.datasources"))
|
||||||
return dc.applyChanges(configPath)
|
return dc.applyChanges(configDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DatasourceConfigurator struct {
|
type DatasourceProvisioner struct {
|
||||||
log log.Logger
|
log log.Logger
|
||||||
cfgProvider configProvider
|
cfgProvider configReader
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatasourceConfiguration() DatasourceConfigurator {
|
func newDatasourceProvisioner(log log.Logger) DatasourceProvisioner {
|
||||||
return newDatasourceConfiguration(log.New("setting.datasource"))
|
return DatasourceProvisioner{
|
||||||
}
|
|
||||||
|
|
||||||
func newDatasourceConfiguration(log log.Logger) DatasourceConfigurator {
|
|
||||||
return DatasourceConfigurator{
|
|
||||||
log: log,
|
log: log,
|
||||||
cfgProvider: configProvider{},
|
cfgProvider: configReader{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
|
func (dc *DatasourceProvisioner) apply(cfg *DatasourcesAsConfig) error {
|
||||||
cfg, err := dc.cfgProvider.readConfig(configPath)
|
if err := dc.deleteDatasources(cfg.DeleteDatasources); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultCount := 0
|
|
||||||
for i := range cfg.Datasources {
|
|
||||||
if cfg.Datasources[i].OrgId == 0 {
|
|
||||||
cfg.Datasources[i].OrgId = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.Datasources[i].IsDefault {
|
|
||||||
defaultCount++
|
|
||||||
if defaultCount > 1 {
|
|
||||||
return ErrInvalidConfigToManyDefault
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := &models.GetAllDataSourcesQuery{}
|
|
||||||
if err = bus.Dispatch(cmd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
allDatasources := cmd.Result
|
|
||||||
|
|
||||||
if err := dc.deleteDatasourcesNotInConfiguration(cfg, allDatasources); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ds := range cfg.Datasources {
|
for _, ds := range cfg.Datasources {
|
||||||
var dbDatasource *models.DataSource
|
cmd := &models.GetDataSourceByNameQuery{OrgId: ds.OrgId, Name: ds.Name}
|
||||||
for _, ddd := range allDatasources {
|
err := bus.Dispatch(cmd)
|
||||||
if ddd.Name == ds.Name && ddd.OrgId == ds.OrgId {
|
if err != nil && err != models.ErrDataSourceNotFound {
|
||||||
dbDatasource = ddd
|
return err
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if dbDatasource == nil {
|
if err == models.ErrDataSourceNotFound {
|
||||||
dc.log.Info("inserting datasource from configuration ", "name", ds.Name)
|
dc.log.Info("inserting datasource from configuration ", "name", ds.Name)
|
||||||
insertCmd := createInsertCommand(ds)
|
insertCmd := createInsertCommand(ds)
|
||||||
if err := bus.Dispatch(insertCmd); err != nil {
|
if err := bus.Dispatch(insertCmd); err != nil {
|
||||||
@@ -85,7 +55,7 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dc.log.Debug("updating datasource from configuration", "name", ds.Name)
|
dc.log.Debug("updating datasource from configuration", "name", ds.Name)
|
||||||
updateCmd := createUpdateCommand(ds, dbDatasource.Id)
|
updateCmd := createUpdateCommand(ds, cmd.Result.Id)
|
||||||
if err := bus.Dispatch(updateCmd); err != nil {
|
if err := bus.Dispatch(updateCmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -95,44 +65,83 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DatasourceConfigurator) deleteDatasourcesNotInConfiguration(cfg *DatasourcesAsConfig, allDatasources []*models.DataSource) error {
|
func (dc *DatasourceProvisioner) applyChanges(configPath string) error {
|
||||||
if cfg.PurgeOtherDatasources {
|
configs, err := dc.cfgProvider.readConfig(configPath)
|
||||||
for _, dbDS := range allDatasources {
|
if err != nil {
|
||||||
delete := true
|
return err
|
||||||
for _, cfgDS := range cfg.Datasources {
|
}
|
||||||
if dbDS.Name == cfgDS.Name && dbDS.OrgId == cfgDS.OrgId {
|
|
||||||
delete = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if delete {
|
for _, cfg := range configs {
|
||||||
dc.log.Info("deleting datasource from configuration", "name", dbDS.Name)
|
if err := dc.apply(cfg); err != nil {
|
||||||
cmd := &models.DeleteDataSourceByIdCommand{Id: dbDS.Id, OrgId: dbDS.OrgId}
|
return err
|
||||||
if err := bus.Dispatch(cmd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type configProvider struct{}
|
func (dc *DatasourceProvisioner) deleteDatasources(dsToDelete []*DeleteDatasourceConfig) error {
|
||||||
|
for _, ds := range dsToDelete {
|
||||||
|
cmd := &models.DeleteDataSourceByNameCommand{OrgId: ds.OrgId, Name: ds.Name}
|
||||||
|
if err := bus.Dispatch(cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (configProvider) readConfig(path string) (*DatasourcesAsConfig, error) {
|
if cmd.DeletedDatasourcesCount > 0 {
|
||||||
filename, _ := filepath.Abs(path)
|
dc.log.Info("deleted datasource based on configuration", "name", ds.Name)
|
||||||
yamlFile, err := ioutil.ReadFile(filename)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type configReader struct{}
|
||||||
|
|
||||||
|
func (configReader) readConfig(path string) ([]*DatasourcesAsConfig, error) {
|
||||||
|
files, err := ioutil.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var datasources *DatasourcesAsConfig
|
var datasources []*DatasourcesAsConfig
|
||||||
|
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)
|
||||||
|
|
||||||
err = yaml.Unmarshal(yamlFile, &datasources)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
}
|
||||||
|
var datasource *DatasourcesAsConfig
|
||||||
|
err = yaml.Unmarshal(yamlFile, &datasource)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
datasources = append(datasources, datasource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultCount := 0
|
||||||
|
for _, cfg := range datasources {
|
||||||
|
for _, ds := range cfg.Datasources {
|
||||||
|
if ds.OrgId == 0 {
|
||||||
|
ds.OrgId = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ds.IsDefault {
|
||||||
|
defaultCount++
|
||||||
|
if defaultCount > 1 {
|
||||||
|
return nil, ErrInvalidConfigToManyDefault
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ds := range cfg.DeleteDatasources {
|
||||||
|
if ds.OrgId == 0 {
|
||||||
|
ds.OrgId = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return datasources, nil
|
return datasources, nil
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ import (
|
|||||||
var (
|
var (
|
||||||
logger log.Logger = log.New("fake.logger")
|
logger log.Logger = log.New("fake.logger")
|
||||||
oneDatasourcesConfig string = ""
|
oneDatasourcesConfig string = ""
|
||||||
twoDatasourcesConfig string = "./test-configs/two-datasources.yaml"
|
twoDatasourcesConfig string = "./test-configs/two-datasources"
|
||||||
twoDatasourcesConfigPurgeOthers string = "./test-configs/two-datasources-purge-others.yaml"
|
twoDatasourcesConfigPurgeOthers string = "./test-configs/insert-two-delete-two"
|
||||||
doubleDatasourcesConfig string = "./test-configs/double-default-datasources.yaml"
|
doubleDatasourcesConfig string = "./test-configs/double-default"
|
||||||
allProperties string = "./test-configs/all-properties.yaml"
|
allProperties string = "./test-configs/all-properties"
|
||||||
|
brokenYaml string = "./test-configs/broken-yaml"
|
||||||
|
|
||||||
fakeRepo *fakeRepository
|
fakeRepo *fakeRepository
|
||||||
)
|
)
|
||||||
@@ -33,7 +34,7 @@ func TestDatasourceAsConfig(t *testing.T) {
|
|||||||
|
|
||||||
Convey("One configured datasource", func() {
|
Convey("One configured datasource", func() {
|
||||||
Convey("no datasource in database", func() {
|
Convey("no datasource in database", func() {
|
||||||
dc := newDatasourceConfiguration(logger)
|
dc := newDatasourceProvisioner(logger)
|
||||||
err := dc.applyChanges(twoDatasourcesConfig)
|
err := dc.applyChanges(twoDatasourcesConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("applyChanges return an error %v", err)
|
t.Fatalf("applyChanges return an error %v", err)
|
||||||
@@ -50,7 +51,7 @@ func TestDatasourceAsConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Convey("should update one datasource", func() {
|
Convey("should update one datasource", func() {
|
||||||
dc := newDatasourceConfiguration(logger)
|
dc := newDatasourceProvisioner(logger)
|
||||||
err := dc.applyChanges(twoDatasourcesConfig)
|
err := dc.applyChanges(twoDatasourcesConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("applyChanges return an error %v", err)
|
t.Fatalf("applyChanges return an error %v", err)
|
||||||
@@ -63,7 +64,7 @@ func TestDatasourceAsConfig(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Two datasources with is_default", func() {
|
Convey("Two datasources with is_default", func() {
|
||||||
dc := newDatasourceConfiguration(logger)
|
dc := newDatasourceProvisioner(logger)
|
||||||
err := dc.applyChanges(doubleDatasourcesConfig)
|
err := dc.applyChanges(doubleDatasourcesConfig)
|
||||||
Convey("should raise error", func() {
|
Convey("should raise error", func() {
|
||||||
So(err, ShouldEqual, ErrInvalidConfigToManyDefault)
|
So(err, ShouldEqual, ErrInvalidConfigToManyDefault)
|
||||||
@@ -79,7 +80,7 @@ func TestDatasourceAsConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Convey("should have two new datasources", func() {
|
Convey("should have two new datasources", func() {
|
||||||
dc := newDatasourceConfiguration(logger)
|
dc := newDatasourceProvisioner(logger)
|
||||||
err := dc.applyChanges(twoDatasourcesConfigPurgeOthers)
|
err := dc.applyChanges(twoDatasourcesConfigPurgeOthers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("applyChanges return an error %v", err)
|
t.Fatalf("applyChanges return an error %v", err)
|
||||||
@@ -100,7 +101,7 @@ func TestDatasourceAsConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Convey("should have two new datasources", func() {
|
Convey("should have two new datasources", func() {
|
||||||
dc := newDatasourceConfiguration(logger)
|
dc := newDatasourceProvisioner(logger)
|
||||||
err := dc.applyChanges(twoDatasourcesConfig)
|
err := dc.applyChanges(twoDatasourcesConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("applyChanges return an error %v", err)
|
t.Fatalf("applyChanges return an error %v", err)
|
||||||
@@ -113,16 +114,22 @@ func TestDatasourceAsConfig(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("can read all properties", func() {
|
Convey("broken yaml should return error", func() {
|
||||||
|
_, err := configReader{}.readConfig(brokenYaml)
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
})
|
||||||
|
|
||||||
cfgProvifer := configProvider{}
|
Convey("can read all properties", func() {
|
||||||
|
cfgProvifer := configReader{}
|
||||||
cfg, err := cfgProvifer.readConfig(allProperties)
|
cfg, err := cfgProvifer.readConfig(allProperties)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("readConfig return an error %v", err)
|
t.Fatalf("readConfig return an error %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
So(cfg.PurgeOtherDatasources, ShouldBeTrue)
|
So(len(cfg), ShouldEqual, 2)
|
||||||
ds := cfg.Datasources[0]
|
|
||||||
|
dsCfg := cfg[0]
|
||||||
|
ds := dsCfg.Datasources[0]
|
||||||
|
|
||||||
So(ds.Name, ShouldEqual, "name")
|
So(ds.Name, ShouldEqual, "name")
|
||||||
So(ds.Type, ShouldEqual, "type")
|
So(ds.Type, ShouldEqual, "type")
|
||||||
@@ -138,19 +145,22 @@ func TestDatasourceAsConfig(t *testing.T) {
|
|||||||
So(ds.WithCredentials, ShouldBeTrue)
|
So(ds.WithCredentials, ShouldBeTrue)
|
||||||
So(ds.IsDefault, ShouldBeTrue)
|
So(ds.IsDefault, ShouldBeTrue)
|
||||||
So(ds.Editable, ShouldBeTrue)
|
So(ds.Editable, ShouldBeTrue)
|
||||||
|
|
||||||
|
dstwo := cfg[1].Datasources[0]
|
||||||
|
So(dstwo.Name, ShouldEqual, "name2")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeRepository struct {
|
type fakeRepository struct {
|
||||||
inserted []*models.AddDataSourceCommand
|
inserted []*models.AddDataSourceCommand
|
||||||
deleted []*models.DeleteDataSourceByIdCommand
|
deleted []*models.DeleteDataSourceByNameCommand
|
||||||
updated []*models.UpdateDataSourceCommand
|
updated []*models.UpdateDataSourceCommand
|
||||||
|
|
||||||
loadAll []*models.DataSource
|
loadAll []*models.DataSource
|
||||||
}
|
}
|
||||||
|
|
||||||
func mockDelete(cmd *models.DeleteDataSourceByIdCommand) error {
|
func mockDelete(cmd *models.DeleteDataSourceByNameCommand) error {
|
||||||
fakeRepo.deleted = append(fakeRepo.deleted, cmd)
|
fakeRepo.deleted = append(fakeRepo.deleted, cmd)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
purge_other_datasources: true
|
|
||||||
datasources:
|
datasources:
|
||||||
- name: name
|
- name: name
|
||||||
type: type
|
type: type
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
purge_other_datasources: true
|
||||||
|
datasources:
|
||||||
|
- name: name2
|
||||||
|
type: type2
|
||||||
|
access: proxy
|
||||||
|
org_id: 2
|
||||||
|
url: url2
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#sfxzgnsxzcvnbzcvn
|
||||||
|
cvbn
|
||||||
|
cvbn
|
||||||
|
c
|
||||||
|
vbn
|
||||||
|
cvbncvbn
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
purge_other_datasources: false
|
|
||||||
datasources:
|
|
||||||
- name: Graphite
|
|
||||||
type: graphite
|
|
||||||
access: proxy
|
|
||||||
url: http://localhost:8080
|
|
||||||
is_default: true
|
|
||||||
- name: Prometheus
|
|
||||||
type: prometheus
|
|
||||||
access: proxy
|
|
||||||
url: http://localhost:9090
|
|
||||||
is_default: true
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
datasources:
|
||||||
|
- name: Graphite
|
||||||
|
type: graphite
|
||||||
|
access: proxy
|
||||||
|
url: http://localhost:8080
|
||||||
|
is_default: true
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
datasources:
|
||||||
|
- name: Graphite
|
||||||
|
type: graphite
|
||||||
|
access: proxy
|
||||||
|
url: http://localhost:8080
|
||||||
|
is_default: true
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
datasources:
|
||||||
|
- name: Prometheus
|
||||||
|
type: prometheus
|
||||||
|
access: proxy
|
||||||
|
url: http://localhost:9090
|
||||||
|
delete_datasources:
|
||||||
|
- name: old-graphite
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
datasources:
|
||||||
|
- name: Graphite
|
||||||
|
type: graphite
|
||||||
|
access: proxy
|
||||||
|
url: http://localhost:8080
|
||||||
|
delete_datasources:
|
||||||
|
- name: old-graphite3
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
purge_other_datasources: true
|
|
||||||
datasources:
|
|
||||||
- name: Graphite
|
|
||||||
type: graphite
|
|
||||||
access: proxy
|
|
||||||
url: http://localhost:8080
|
|
||||||
- name: Prometheus
|
|
||||||
type: prometheus
|
|
||||||
access: proxy
|
|
||||||
url: http://localhost:9090
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
purge_other_datasources: false
|
|
||||||
datasources:
|
datasources:
|
||||||
- name: Graphite
|
- name: Graphite
|
||||||
type: graphite
|
type: graphite
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
purge_other_datasources: false
|
|
||||||
datasources:
|
|
||||||
@@ -4,8 +4,13 @@ import "github.com/grafana/grafana/pkg/models"
|
|||||||
import "github.com/grafana/grafana/pkg/components/simplejson"
|
import "github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
|
|
||||||
type DatasourcesAsConfig struct {
|
type DatasourcesAsConfig struct {
|
||||||
PurgeOtherDatasources bool `json:"purge_other_datasources" yaml:"purge_other_datasources"`
|
Datasources []*DataSourceFromConfig `json:"datasources" yaml:"datasources"`
|
||||||
Datasources []DataSourceFromConfig `json:"datasources" yaml:"datasources"`
|
DeleteDatasources []*DeleteDatasourceConfig `json:"delete_datasources" yaml:"delete_datasources"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteDatasourceConfig struct {
|
||||||
|
OrgId int64 `json:"org_id" yaml:"org_id"`
|
||||||
|
Name string `json:"name" yaml:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DataSourceFromConfig struct {
|
type DataSourceFromConfig struct {
|
||||||
@@ -29,7 +34,7 @@ type DataSourceFromConfig struct {
|
|||||||
Editable bool `json:"editable" yaml:"editable"`
|
Editable bool `json:"editable" yaml:"editable"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createInsertCommand(ds DataSourceFromConfig) *models.AddDataSourceCommand {
|
func createInsertCommand(ds *DataSourceFromConfig) *models.AddDataSourceCommand {
|
||||||
jsonData, err := simplejson.NewJson([]byte(ds.JsonData))
|
jsonData, err := simplejson.NewJson([]byte(ds.JsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
jsonData = simplejson.New()
|
jsonData = simplejson.New()
|
||||||
@@ -55,7 +60,7 @@ func createInsertCommand(ds DataSourceFromConfig) *models.AddDataSourceCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createUpdateCommand(ds DataSourceFromConfig, id int64) *models.UpdateDataSourceCommand {
|
func createUpdateCommand(ds *DataSourceFromConfig, id int64) *models.UpdateDataSourceCommand {
|
||||||
jsonData, err := simplejson.NewJson([]byte(ds.JsonData))
|
jsonData, err := simplejson.NewJson([]byte(ds.JsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
jsonData = simplejson.New()
|
jsonData = simplejson.New()
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package provisioning
|
package provisioning
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/services/provisioning/datasources"
|
"github.com/grafana/grafana/pkg/services/provisioning/datasources"
|
||||||
)
|
)
|
||||||
@@ -11,6 +9,6 @@ var (
|
|||||||
logger log.Logger = log.New("services.provisioning")
|
logger log.Logger = log.New("services.provisioning")
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartUp(homePath string) error {
|
func StartUp(datasourcePath string) error {
|
||||||
return datasources.Apply(filepath.Join(homePath, "conf/datasources.yaml"))
|
return datasources.Provision(datasourcePath)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,9 @@ func GetAllDataSources(query *m.GetAllDataSourcesQuery) error {
|
|||||||
func DeleteDataSourceById(cmd *m.DeleteDataSourceByIdCommand) error {
|
func DeleteDataSourceById(cmd *m.DeleteDataSourceByIdCommand) error {
|
||||||
return inTransaction(func(sess *DBSession) error {
|
return inTransaction(func(sess *DBSession) error {
|
||||||
var rawSql = "DELETE FROM data_source WHERE id=? and org_id=?"
|
var rawSql = "DELETE FROM data_source WHERE id=? and org_id=?"
|
||||||
_, err := sess.Exec(rawSql, cmd.Id, cmd.OrgId)
|
result, err := sess.Exec(rawSql, cmd.Id, cmd.OrgId)
|
||||||
|
affected, _ := result.RowsAffected()
|
||||||
|
cmd.DeletedDatasourcesCount = affected
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -73,7 +75,9 @@ func DeleteDataSourceById(cmd *m.DeleteDataSourceByIdCommand) error {
|
|||||||
func DeleteDataSourceByName(cmd *m.DeleteDataSourceByNameCommand) error {
|
func DeleteDataSourceByName(cmd *m.DeleteDataSourceByNameCommand) error {
|
||||||
return inTransaction(func(sess *DBSession) error {
|
return inTransaction(func(sess *DBSession) error {
|
||||||
var rawSql = "DELETE FROM data_source WHERE name=? and org_id=?"
|
var rawSql = "DELETE FROM data_source WHERE name=? and org_id=?"
|
||||||
_, err := sess.Exec(rawSql, cmd.Name, cmd.OrgId)
|
result, err := sess.Exec(rawSql, cmd.Name, cmd.OrgId)
|
||||||
|
affected, _ := result.RowsAffected()
|
||||||
|
cmd.DeletedDatasourcesCount = affected
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,11 +50,12 @@ var (
|
|||||||
BuildStamp int64
|
BuildStamp int64
|
||||||
|
|
||||||
// Paths
|
// Paths
|
||||||
LogsPath string
|
LogsPath string
|
||||||
HomePath string
|
HomePath string
|
||||||
DataPath string
|
DataPath string
|
||||||
PluginsPath string
|
PluginsPath string
|
||||||
CustomInitPath = "conf/custom.ini"
|
DatasourcesPath string
|
||||||
|
CustomInitPath = "conf/custom.ini"
|
||||||
|
|
||||||
// Log settings.
|
// Log settings.
|
||||||
LogModes []string
|
LogModes []string
|
||||||
@@ -470,6 +471,7 @@ func NewConfigContext(args *CommandLineArgs) error {
|
|||||||
Env = Cfg.Section("").Key("app_mode").MustString("development")
|
Env = Cfg.Section("").Key("app_mode").MustString("development")
|
||||||
InstanceName = Cfg.Section("").Key("instance_name").MustString("unknown_instance_name")
|
InstanceName = Cfg.Section("").Key("instance_name").MustString("unknown_instance_name")
|
||||||
PluginsPath = makeAbsolute(Cfg.Section("paths").Key("plugins").String(), HomePath)
|
PluginsPath = makeAbsolute(Cfg.Section("paths").Key("plugins").String(), HomePath)
|
||||||
|
DatasourcesPath = makeAbsolute(Cfg.Section("paths").Key("datasources").String(), HomePath)
|
||||||
|
|
||||||
server := Cfg.Section("server")
|
server := Cfg.Section("server")
|
||||||
AppUrl, AppSubUrl = parseAppUrlAndSubUrl(server)
|
AppUrl, AppSubUrl = parseAppUrlAndSubUrl(server)
|
||||||
@@ -661,5 +663,6 @@ func LogConfigurationInfo() {
|
|||||||
logger.Info("Path Data", "path", DataPath)
|
logger.Info("Path Data", "path", DataPath)
|
||||||
logger.Info("Path Logs", "path", LogsPath)
|
logger.Info("Path Logs", "path", LogsPath)
|
||||||
logger.Info("Path Plugins", "path", PluginsPath)
|
logger.Info("Path Plugins", "path", PluginsPath)
|
||||||
|
logger.Info("Path Datasources", "path", DatasourcesPath)
|
||||||
logger.Info("App mode " + Env)
|
logger.Info("App mode " + Env)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user