|
@@ -1,6 +1,9 @@
|
1
|
1
|
package webhook
|
2
|
2
|
|
3
|
3
|
import (
|
|
4
|
+ "io/ioutil"
|
|
5
|
+ "path/filepath"
|
|
6
|
+
|
4
|
7
|
"config"
|
5
|
8
|
"git"
|
6
|
9
|
"grafana"
|
|
@@ -49,6 +52,13 @@ func Setup(conf *config.Config, client *grafana.Client, delRemoved bool) (err er
|
49
|
52
|
func HandlePush(payload interface{}, header webhooks.Header) {
|
50
|
53
|
var err error
|
51
|
54
|
|
|
55
|
+ var (
|
|
56
|
+ added = make([]string, 0)
|
|
57
|
+ modified = make([]string, 0)
|
|
58
|
+ removed = make([]string, 0)
|
|
59
|
+ contents = make(map[string][]byte)
|
|
60
|
+ )
|
|
61
|
+
|
52
|
62
|
// Process the payload using the right structure
|
53
|
63
|
pl := payload.(gitlab.PushEventPayload)
|
54
|
64
|
|
|
@@ -57,25 +67,6 @@ func HandlePush(payload interface{}, header webhooks.Header) {
|
57
|
67
|
return
|
58
|
68
|
}
|
59
|
69
|
|
60
|
|
- // Clone or pull the repository
|
61
|
|
- if err = repo.Sync(false); err != nil {
|
62
|
|
- logrus.WithFields(logrus.Fields{
|
63
|
|
- "error": err,
|
64
|
|
- "repo": cfg.Git.User + "@" + cfg.Git.URL,
|
65
|
|
- "clone_path": cfg.Git.ClonePath,
|
66
|
|
- }).Error("Failed to synchronise the Git repository with the remote")
|
67
|
|
-
|
68
|
|
- return
|
69
|
|
- }
|
70
|
|
-
|
71
|
|
- // Files to push and their contents are stored in a map before being pushed
|
72
|
|
- // to the Grafana API. We don't push them in the loop iterating over commits
|
73
|
|
- // because, in the case a file is successively updated by two commits pushed
|
74
|
|
- // at the same time, it would push the same file several time, which isn't
|
75
|
|
- // an optimised behaviour.
|
76
|
|
- filesToPush := make(map[string][]byte)
|
77
|
|
-
|
78
|
|
- // Iterate over the commits descriptions from the payload
|
79
|
70
|
for _, commit := range pl.Commits {
|
80
|
71
|
// We don't want to process commits made by the puller
|
81
|
72
|
if commit.Author.Email == cfg.Git.CommitsAuthor.Email {
|
|
@@ -88,56 +79,52 @@ func HandlePush(payload interface{}, header webhooks.Header) {
|
88
|
79
|
continue
|
89
|
80
|
}
|
90
|
81
|
|
91
|
|
- // Set all added files to be pushed, except the ones describing a
|
92
|
|
- // dashboard which name starts with a the prefix specified in the
|
93
|
|
- // configuration file.
|
94
|
82
|
for _, addedFile := range commit.Added {
|
95
|
|
- if err = common.PrepareForPush(
|
96
|
|
- addedFile, &filesToPush, cfg,
|
97
|
|
- ); err != nil {
|
98
|
|
- logrus.WithFields(logrus.Fields{
|
99
|
|
- "error": err,
|
100
|
|
- "filename": addedFile,
|
101
|
|
- }).Error("Failed to prepare file for push")
|
102
|
|
-
|
103
|
|
- continue
|
104
|
|
- }
|
|
83
|
+ added = append(added, addedFile)
|
105
|
84
|
}
|
106
|
85
|
|
107
|
|
- // Set all modified files to be pushed, except the ones describing a
|
108
|
|
- // dashboard which name starts with a the prefix specified in the
|
109
|
|
- // configuration file.
|
110
|
86
|
for _, modifiedFile := range commit.Modified {
|
111
|
|
- if err = common.PrepareForPush(
|
112
|
|
- modifiedFile, &filesToPush, cfg,
|
113
|
|
- ); err != nil {
|
114
|
|
- logrus.WithFields(logrus.Fields{
|
115
|
|
- "error": err,
|
116
|
|
- "filename": modifiedFile,
|
117
|
|
- }).Error("Failed to prepare file for push")
|
118
|
|
-
|
119
|
|
- continue
|
120
|
|
- }
|
|
87
|
+ modified = append(modified, modifiedFile)
|
121
|
88
|
}
|
122
|
89
|
|
123
|
|
- // If a file describing a dashboard gets removed from the Git repository,
|
124
|
|
- // delete the corresponding dashboard on Grafana, but only if the user
|
125
|
|
- // mentionned they want to do so with the correct command line flag.
|
126
|
|
- if deleteRemoved {
|
127
|
|
- for _, removedFile := range commit.Removed {
|
128
|
|
- if err = common.DeleteDashboard(
|
129
|
|
- removedFile, grafanaClient, cfg,
|
130
|
|
- ); err != nil {
|
131
|
|
- logrus.WithFields(logrus.Fields{
|
132
|
|
- "error": err,
|
133
|
|
- "filename": removedFile,
|
134
|
|
- }).Error("Failed to delete the dashboard")
|
135
|
|
- }
|
136
|
|
- }
|
|
90
|
+ for _, removedFile := range commit.Removed {
|
|
91
|
+ removed = append(removed, removedFile)
|
137
|
92
|
}
|
138
|
93
|
}
|
139
|
94
|
|
140
|
|
- common.PushFiles(filesToPush, grafanaClient)
|
|
95
|
+ if err = getFilesContents(removed, &contents, cfg); err != nil {
|
|
96
|
+ return
|
|
97
|
+ }
|
|
98
|
+
|
|
99
|
+ // Clone or pull the repository
|
|
100
|
+ if err = repo.Sync(false); err != nil {
|
|
101
|
+ logrus.WithFields(logrus.Fields{
|
|
102
|
+ "error": err,
|
|
103
|
+ "repo": cfg.Git.User + "@" + cfg.Git.URL,
|
|
104
|
+ "clone_path": cfg.Git.ClonePath,
|
|
105
|
+ }).Error("Failed to synchronise the Git repository with the remote")
|
|
106
|
+
|
|
107
|
+ return
|
|
108
|
+ }
|
|
109
|
+
|
|
110
|
+ if err = getFilesContents(added, &contents, cfg); err != nil {
|
|
111
|
+ return
|
|
112
|
+ }
|
|
113
|
+
|
|
114
|
+ if err = getFilesContents(modified, &contents, cfg); err != nil {
|
|
115
|
+ return
|
|
116
|
+ }
|
|
117
|
+
|
|
118
|
+ if err = common.FilterIgnored(&contents, cfg); err != nil {
|
|
119
|
+ return
|
|
120
|
+ }
|
|
121
|
+
|
|
122
|
+ common.PushFiles(added, contents, grafanaClient)
|
|
123
|
+ common.PushFiles(modified, contents, grafanaClient)
|
|
124
|
+
|
|
125
|
+ if deleteRemoved {
|
|
126
|
+ common.DeleteDashboards(removed, contents, grafanaClient)
|
|
127
|
+ }
|
141
|
128
|
|
142
|
129
|
// Grafana will auto-update the version number after we pushed the new
|
143
|
130
|
// dashboards, so we use the puller mechanic to pull the updated numbers and
|
|
@@ -150,3 +137,20 @@ func HandlePush(payload interface{}, header webhooks.Header) {
|
150
|
137
|
}).Error("Call to puller returned an error")
|
151
|
138
|
}
|
152
|
139
|
}
|
|
140
|
+
|
|
141
|
+func getFilesContents(
|
|
142
|
+ filenames []string, contents *map[string][]byte, cfg *config.Config,
|
|
143
|
+) (err error) {
|
|
144
|
+ for _, filename := range filenames {
|
|
145
|
+ // Read the file's content
|
|
146
|
+ filePath := filepath.Join(cfg.Git.ClonePath, filename)
|
|
147
|
+ fileContent, err := ioutil.ReadFile(filePath)
|
|
148
|
+ if err != nil {
|
|
149
|
+ return err
|
|
150
|
+ }
|
|
151
|
+
|
|
152
|
+ (*contents)[filename] = fileContent
|
|
153
|
+ }
|
|
154
|
+
|
|
155
|
+ return
|
|
156
|
+}
|