datasources.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package datasources
  2. import (
  3. "io/ioutil"
  4. "path/filepath"
  5. "github.com/grafana/grafana/pkg/bus"
  6. "github.com/grafana/grafana/pkg/log"
  7. "github.com/grafana/grafana/pkg/models"
  8. yaml "gopkg.in/yaml.v2"
  9. )
  10. type DatasourcesAsConfig struct {
  11. PurgeOtherDatasources bool
  12. Datasources []DataSourceFromConfig
  13. }
  14. func Init(configPath string) error {
  15. dc := NewDatasourceConfiguration()
  16. return dc.applyChanges(configPath)
  17. }
  18. type DatasourceConfigurator struct {
  19. log log.Logger
  20. cfgProvider configProvider
  21. repository datasourceRepository
  22. }
  23. func NewDatasourceConfiguration() DatasourceConfigurator {
  24. return newDatasourceConfiguration(log.New("setting.datasource"), diskConfigReader{}, sqlDatasourceRepository{})
  25. }
  26. func newDatasourceConfiguration(log log.Logger, cfgProvider configProvider, repo datasourceRepository) DatasourceConfigurator {
  27. return DatasourceConfigurator{
  28. log: log.New("setting.datasource"),
  29. repository: repo,
  30. cfgProvider: cfgProvider,
  31. }
  32. }
  33. func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
  34. cfg, err := dc.cfgProvider.readConfig(configPath)
  35. if err != nil {
  36. return err
  37. }
  38. allDatasources, err := dc.repository.loadAllDatasources()
  39. if err != nil {
  40. return err
  41. }
  42. for i := range cfg.Datasources {
  43. if cfg.Datasources[i].OrgId == 0 {
  44. cfg.Datasources[i].OrgId = 1
  45. }
  46. }
  47. if err := dc.deleteDatasourcesNotInConfiguration(cfg, allDatasources); err != nil {
  48. return err
  49. }
  50. for _, ds := range cfg.Datasources {
  51. var dbDatasource *models.DataSource
  52. for _, ddd := range allDatasources {
  53. if ddd.Name == ds.Name && ddd.OrgId == ds.OrgId {
  54. dbDatasource = ddd
  55. break
  56. }
  57. }
  58. if dbDatasource == nil {
  59. dc.log.Info("inserting datasource from configuration ", "name", ds.Name)
  60. insertCmd := createInsertCommand(ds)
  61. err := dc.repository.insert(insertCmd)
  62. if err != nil && err != models.ErrDataSourceNameExists {
  63. return err
  64. }
  65. } else {
  66. dc.log.Info("updating datasource from configuration", "name", ds.Name)
  67. updateCmd := createUpdateCommand(ds, dbDatasource.Id)
  68. if err := dc.repository.update(updateCmd); err != nil {
  69. return err
  70. }
  71. }
  72. }
  73. return nil
  74. }
  75. func (dc *DatasourceConfigurator) deleteDatasourcesNotInConfiguration(cfg *DatasourcesAsConfig, allDatasources []*models.DataSource) error {
  76. if cfg.PurgeOtherDatasources {
  77. for _, dbDS := range allDatasources {
  78. delete := true
  79. for _, cfgDS := range cfg.Datasources {
  80. if dbDS.Name == cfgDS.Name && dbDS.OrgId == cfgDS.OrgId {
  81. delete = false
  82. }
  83. }
  84. if delete {
  85. dc.log.Info("deleting datasource from configuration", "name", dbDS.Name)
  86. cmd := &models.DeleteDataSourceByIdCommand{Id: dbDS.Id, OrgId: dbDS.OrgId}
  87. if err := dc.repository.delete(cmd); err != nil {
  88. return err
  89. }
  90. }
  91. }
  92. }
  93. return nil
  94. }
  95. type datasourceRepository interface {
  96. insert(*models.AddDataSourceCommand) error
  97. update(*models.UpdateDataSourceCommand) error
  98. delete(*models.DeleteDataSourceByIdCommand) error
  99. get(*models.GetDataSourceByNameQuery) error
  100. loadAllDatasources() ([]*models.DataSource, error)
  101. }
  102. type configProvider interface {
  103. readConfig(string) (*DatasourcesAsConfig, error)
  104. }
  105. type sqlDatasourceRepository struct{}
  106. type diskConfigReader struct{}
  107. func (diskConfigReader) readConfig(path string) (*DatasourcesAsConfig, error) {
  108. filename, _ := filepath.Abs(path)
  109. yamlFile, err := ioutil.ReadFile(filename)
  110. if err != nil {
  111. return nil, err
  112. }
  113. var datasources *DatasourcesAsConfig
  114. err = yaml.Unmarshal(yamlFile, &datasources)
  115. if err != nil {
  116. return nil, err
  117. }
  118. return datasources, nil
  119. }
  120. func (sqlDatasourceRepository) delete(cmd *models.DeleteDataSourceByIdCommand) error {
  121. return bus.Dispatch(cmd)
  122. }
  123. func (sqlDatasourceRepository) update(cmd *models.UpdateDataSourceCommand) error {
  124. return bus.Dispatch(cmd)
  125. }
  126. func (sqlDatasourceRepository) insert(cmd *models.AddDataSourceCommand) error {
  127. return bus.Dispatch(cmd)
  128. }
  129. func (sqlDatasourceRepository) get(cmd *models.GetDataSourceByNameQuery) error {
  130. return bus.Dispatch(cmd)
  131. }
  132. func (sqlDatasourceRepository) loadAllDatasources() ([]*models.DataSource, error) {
  133. dss := &models.GetAllDataSourcesQuery{}
  134. if err := bus.Dispatch(dss); err != nil {
  135. return nil, err
  136. }
  137. return dss.Result, nil
  138. }