Tool to help you manage your Grafana dashboards using Git.

poller.go 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package poller
  2. import (
  3. "time"
  4. "config"
  5. "git"
  6. "grafana"
  7. puller "puller"
  8. "pusher/common"
  9. "github.com/sirupsen/logrus"
  10. )
  11. func Setup(cfg *config.Config, client *grafana.Client, delRemoved bool) error {
  12. r, needsSync, err := git.NewRepository(cfg.Git)
  13. if err != nil {
  14. return err
  15. }
  16. if needsSync {
  17. if err = r.Sync(false); err != nil {
  18. return err
  19. }
  20. }
  21. errs := make(chan error, 1)
  22. go func() {
  23. if err = poller(cfg, r, client, delRemoved); err != nil {
  24. errs <- err
  25. return
  26. }
  27. }()
  28. err = <-errs
  29. return err
  30. }
  31. func poller(
  32. cfg *config.Config, repo *git.Repository, client *grafana.Client,
  33. delRemoved bool,
  34. ) (err error) {
  35. latestCommit, err := repo.GetLatestCommit()
  36. if err != nil {
  37. return
  38. }
  39. filesContents, err := repo.GetFilesContentsAtCommit(latestCommit)
  40. if err != nil {
  41. return
  42. }
  43. previousCommit := latestCommit
  44. previousFilesContents := filesContents
  45. for {
  46. if err = repo.Sync(true); err != nil {
  47. return
  48. }
  49. latestCommit, err = repo.GetLatestCommit()
  50. if err != nil {
  51. return
  52. }
  53. if previousCommit.Hash.String() != latestCommit.Hash.String() {
  54. logrus.WithFields(logrus.Fields{
  55. "previous_hash": previousCommit.Hash.String(),
  56. "new_hash": latestCommit.Hash.String(),
  57. }).Info("New commit(s) detected")
  58. filesContents, err = repo.GetFilesContentsAtCommit(latestCommit)
  59. if err != nil {
  60. return err
  61. }
  62. modified, removed, err := repo.GetModifiedAndRemovedFiles(previousCommit, latestCommit)
  63. if err != nil {
  64. return err
  65. }
  66. mergedContents := mergeContents(modified, removed, filesContents, previousFilesContents)
  67. common.PushFiles(modified, mergedContents, client)
  68. if delRemoved {
  69. common.DeleteDashboards(removed, mergedContents, client)
  70. }
  71. // Grafana will auto-update the version number after we pushed the new
  72. // dashboards, so we use the puller mechanic to pull the updated numbers and
  73. // commit them in the git repo.
  74. if err = puller.PullGrafanaAndCommit(client, cfg); err != nil {
  75. logrus.WithFields(logrus.Fields{
  76. "error": err,
  77. "repo": cfg.Git.User + "@" + cfg.Git.URL,
  78. "clone_path": cfg.Git.ClonePath,
  79. }).Error("Call to puller returned an error")
  80. }
  81. }
  82. previousCommit = latestCommit
  83. previousFilesContents = filesContents
  84. time.Sleep(time.Duration(cfg.Pusher.Config.Interval) * time.Second)
  85. }
  86. }
  87. func mergeContents(
  88. modified []string, removed []string,
  89. filesContents map[string][]byte, previousFilesContents map[string][]byte,
  90. ) (merged map[string][]byte) {
  91. merged = make(map[string][]byte)
  92. for _, modifiedFile := range modified {
  93. merged[modifiedFile] = filesContents[modifiedFile]
  94. }
  95. for _, removedFile := range removed {
  96. merged[removedFile] = previousFilesContents[removedFile]
  97. }
  98. return
  99. }