Browse Source

Optimise push workflow

Brendan Abolivier 2 years ago
parent
commit
64b812bb10
Signed by: Brendan Abolivier <contact@brendanabolivier.com> GPG key ID: 8EF1500759F70623
1 changed files with 48 additions and 53 deletions
  1. 48
    53
      src/pusher/webhook.go

+ 48
- 53
src/pusher/webhook.go View File

@@ -57,7 +57,7 @@ func HandlePush(payload interface{}, header webhooks.Header) {
57 57
 	// case a file is successively updated by two commits pushed at the same
58 58
 	// time, it would push the same file several time, which isn't an optimised
59 59
 	// behaviour.
60
-	filesToPush := make(map[string]bool)
60
+	filesToPush := make(map[string][]byte)
61 61
 
62 62
 	// Iterate over the commits descriptions from the payload
63 63
 	for _, commit := range pl.Commits {
@@ -72,56 +72,40 @@ func HandlePush(payload interface{}, header webhooks.Header) {
72 72
 			continue
73 73
 		}
74 74
 
75
-		// Push all added files, except the ones describing a dashboard which
76
-		// name starts with a the prefix specified in the configuration file.
75
+		// Set all added files to be pushed, except the ones describing a
76
+		// dashboard which name starts with a the prefix specified in the
77
+		// configuration file.
77 78
 		for _, addedFile := range commit.Added {
78
-			ignored, err := isIgnored(addedFile)
79
-			if err != nil {
79
+			if err = prepareForPush(addedFile, &filesToPush); err != nil {
80 80
 				logrus.WithFields(logrus.Fields{
81 81
 					"error":    err,
82 82
 					"filename": addedFile,
83
-				}).Error("Failed to check if file is to be ignored")
83
+				}).Error("Failed to prepare file for push")
84 84
 
85 85
 				continue
86 86
 			}
87
-
88
-			if !ignored {
89
-				logrus.WithFields(logrus.Fields{
90
-					"filename": addedFile,
91
-				}).Info("Setting file as file to push to Grafana")
92
-
93
-				filesToPush[addedFile] = true
94
-			}
95 87
 		}
96 88
 
97
-		// Push all modified files, except the ones describing a dashboard which
98
-		// name starts with a the prefix specified in the configuration file.
89
+		// Set all modified files to be pushed, except the ones describing a
90
+		// dashboard which name starts with a the prefix specified in the
91
+		// configuration file.
99 92
 		for _, modifiedFile := range commit.Modified {
100
-			ignored, err := isIgnored(modifiedFile)
101
-			if err != nil {
93
+			if err = prepareForPush(modifiedFile, &filesToPush); err != nil {
102 94
 				logrus.WithFields(logrus.Fields{
103 95
 					"error":    err,
104 96
 					"filename": modifiedFile,
105
-				}).Error("Failed to check if file is to be ignored")
97
+				}).Error("Failed to prepare file for push")
106 98
 
107 99
 				continue
108 100
 			}
109
-
110
-			if !ignored {
111
-				logrus.WithFields(logrus.Fields{
112
-					"filename": modifiedFile,
113
-				}).Info("Setting file as file to push to Grafana")
114
-
115
-				filesToPush[modifiedFile] = true
116
-			}
117 101
 		}
118 102
 
119 103
 		// TODO: Remove a dashboard when its file gets deleted?
120 104
 	}
121 105
 
122 106
 	// Push all files to the Grafana API
123
-	for fileToPush := range filesToPush {
124
-		if err = pushFile(fileToPush); err != nil {
107
+	for fileToPush, fileContent := range filesToPush {
108
+		if err = grafanaClient.CreateOrUpdateDashboard(fileContent); err != nil {
125 109
 			logrus.WithFields(logrus.Fields{
126 110
 				"error":    err,
127 111
 				"filename": fileToPush,
@@ -143,45 +127,56 @@ func HandlePush(payload interface{}, header webhooks.Header) {
143 127
 	}
144 128
 }
145 129
 
146
-// pushFile pushes the content of a given file to the Grafana API in order to
147
-// create or update a dashboard.
148
-// Returns an error if there was an issue reading the file or sending its content
149
-// to the Grafana instance.
150
-func pushFile(filename string) error {
151
-	filePath := cfg.Git.ClonePath + "/" + filename
152
-	fileContent, err := ioutil.ReadFile(filePath)
130
+// prepareForPush reads the file containing the JSON representation of a
131
+// dashboard, checks if the dashboard is set to be ignored, and if not appends
132
+// its content to a map, which will be later iterated over to push the contents
133
+// it contains to the Grafana API.
134
+// Returns an error if there was an issue reading the file or checking if the
135
+// dashboard it represents is to be ignored.
136
+func prepareForPush(
137
+	filename string, filesToPush *map[string][]byte,
138
+) (err error) {
139
+	// Don't set versions.json to be pushed
140
+	if strings.HasSuffix(filename, "versions.json") {
141
+		return
142
+	}
143
+
144
+	// Read the file's content
145
+	fileContent, err := ioutil.ReadFile(filename)
153 146
 	if err != nil {
154
-		return err
147
+		return
155 148
 	}
156 149
 
157
-	return grafanaClient.CreateOrUpdateDashboard(fileContent)
150
+	// Check if dashboard is ignored
151
+	ignored, err := isIgnored(fileContent)
152
+	if err != nil {
153
+		return
154
+	}
155
+
156
+	// Append to the list of contents to push to Grafana
157
+	if !ignored {
158
+		logrus.WithFields(logrus.Fields{
159
+			"filename": filename,
160
+		}).Info("Preparing file to be pushed to Grafana")
161
+
162
+		(*filesToPush)[filename] = fileContent
163
+	}
164
+
165
+	return
158 166
 }
159 167
 
160 168
 // isIgnored checks whether the file must be ignored, by checking if there's an
161 169
 // prefix for ignored files set in the configuration file, and if the dashboard
162 170
 // described in the file has a name that starts with this prefix. Returns an
163 171
 // error if there was an issue reading or decoding the file.
164
-// TODO: Optimise this part of the workflow, as all files get open twice (here
165
-// and in pushFile)
166
-func isIgnored(filename string) (bool, error) {
167
-	// Always ignore versions.json
168
-	if strings.HasSuffix(filename, "versions.json") {
169
-		return true, nil
170
-	}
171
-
172
+func isIgnored(dashboardJSON []byte) (bool, error) {
172 173
 	// If there's no prefix set, no file is ignored
173 174
 	if len(cfg.Grafana.IgnorePrefix) == 0 {
174 175
 		return false, nil
175 176
 	}
176 177
 
177
-	// Read the file's content
178
-	fileContent, err := ioutil.ReadFile(filename)
179
-	if err != nil {
180
-		return false, err
181
-	}
182
-
183 178
 	// Parse the file's content to extract its slug
184
-	slug, err := helpers.GetDashboardSlug(fileContent)
179
+	slug, err := helpers.GetDashboardSlug(dashboardJSON)
185 180
 	if err != nil {
186 181
 		return false, err
187 182
 	}