|  | @@ -52,11 +52,11 @@ func HandlePush(payload interface{}, header webhooks.Header) {
 | 
	
		
			
			| 52 | 52 |  		return
 | 
	
		
			
			| 53 | 53 |  	}
 | 
	
		
			
			| 54 | 54 |  
 | 
	
		
			
			| 55 |  | -	// Files to push are stored in a map before being pushed to the Grafana API.
 | 
	
		
			
			| 56 |  | -	// We don't push them in the loop iterating over commits because, in the
 | 
	
		
			
			| 57 |  | -	// case a file is successively updated by two commits pushed at the same
 | 
	
		
			
			| 58 |  | -	// time, it would push the same file several time, which isn't an optimised
 | 
	
		
			
			| 59 |  | -	// behaviour.
 | 
	
		
			
			|  | 55 | +	// Files to push and their contents are stored in a map before being pushed
 | 
	
		
			
			|  | 56 | +	// to the Grafana API. We don't push them in the loop iterating over commits
 | 
	
		
			
			|  | 57 | +	// because, in the case a file is successively updated by two commits pushed
 | 
	
		
			
			|  | 58 | +	// at the same time, it would push the same file several time, which isn't
 | 
	
		
			
			|  | 59 | +	// an optimised behaviour.
 | 
	
		
			
			| 60 | 60 |  	filesToPush := make(map[string][]byte)
 | 
	
		
			
			| 61 | 61 |  
 | 
	
		
			
			| 62 | 62 |  	// Iterate over the commits descriptions from the payload
 | 
	
	
		
			
			|  | @@ -100,7 +100,21 @@ func HandlePush(payload interface{}, header webhooks.Header) {
 | 
	
		
			
			| 100 | 100 |  			}
 | 
	
		
			
			| 101 | 101 |  		}
 | 
	
		
			
			| 102 | 102 |  
 | 
	
		
			
			| 103 |  | -		// TODO: Remove a dashboard when its file gets deleted?
 | 
	
		
			
			|  | 103 | +		// If a file describing a dashboard gets removed from the Git repository,
 | 
	
		
			
			|  | 104 | +		// delete the corresponding dashboard on Grafana, but only if the user
 | 
	
		
			
			|  | 105 | +		// mentionned they want to do so with the correct command line flag.
 | 
	
		
			
			|  | 106 | +		if *deleteRemoved {
 | 
	
		
			
			|  | 107 | +			for _, removedFile := range commit.Removed {
 | 
	
		
			
			|  | 108 | +				if err = deleteDashboard(removedFile); err != nil {
 | 
	
		
			
			|  | 109 | +					logrus.WithFields(logrus.Fields{
 | 
	
		
			
			|  | 110 | +						"error":    err,
 | 
	
		
			
			|  | 111 | +						"filename": removedFile,
 | 
	
		
			
			|  | 112 | +					}).Error("Failed to delete the dashboard")
 | 
	
		
			
			|  | 113 | +				}
 | 
	
		
			
			|  | 114 | +
 | 
	
		
			
			|  | 115 | +				continue
 | 
	
		
			
			|  | 116 | +			}
 | 
	
		
			
			|  | 117 | +		}
 | 
	
		
			
			| 104 | 118 |  	}
 | 
	
		
			
			| 105 | 119 |  
 | 
	
		
			
			| 106 | 120 |  	// Push all files to the Grafana API
 | 
	
	
		
			
			|  | @@ -165,6 +179,44 @@ func prepareForPush(
 | 
	
		
			
			| 165 | 179 |  	return
 | 
	
		
			
			| 166 | 180 |  }
 | 
	
		
			
			| 167 | 181 |  
 | 
	
		
			
			|  | 182 | +// deleteDashboard reads the dashboard described in a given file and, if the file
 | 
	
		
			
			|  | 183 | +// isn't set to be ignored, delete the corresponding dashboard from Grafana.
 | 
	
		
			
			|  | 184 | +// Returns an error if there was an issue reading the file's content, checking
 | 
	
		
			
			|  | 185 | +// if the dashboard is to be ignored, computing its slug or deleting it from
 | 
	
		
			
			|  | 186 | +// Grafana.
 | 
	
		
			
			|  | 187 | +func deleteDashboard(filename string) (err error) {
 | 
	
		
			
			|  | 188 | +	// Don't delete versions.json
 | 
	
		
			
			|  | 189 | +	if strings.HasSuffix(filename, "versions.json") {
 | 
	
		
			
			|  | 190 | +		return
 | 
	
		
			
			|  | 191 | +	}
 | 
	
		
			
			|  | 192 | +
 | 
	
		
			
			|  | 193 | +	// Read the file's content
 | 
	
		
			
			|  | 194 | +	fileContent, err := ioutil.ReadFile(filename)
 | 
	
		
			
			|  | 195 | +	if err != nil {
 | 
	
		
			
			|  | 196 | +		return
 | 
	
		
			
			|  | 197 | +	}
 | 
	
		
			
			|  | 198 | +
 | 
	
		
			
			|  | 199 | +	// Check if dashboard is ignored
 | 
	
		
			
			|  | 200 | +	ignored, err := isIgnored(fileContent)
 | 
	
		
			
			|  | 201 | +	if err != nil {
 | 
	
		
			
			|  | 202 | +		return
 | 
	
		
			
			|  | 203 | +	}
 | 
	
		
			
			|  | 204 | +
 | 
	
		
			
			|  | 205 | +	if !ignored {
 | 
	
		
			
			|  | 206 | +		// Retrieve dashboard slug because we need it in the deletion request.
 | 
	
		
			
			|  | 207 | +		var slug string
 | 
	
		
			
			|  | 208 | +		slug, err = helpers.GetDashboardSlug(fileContent)
 | 
	
		
			
			|  | 209 | +		if err != nil {
 | 
	
		
			
			|  | 210 | +			return
 | 
	
		
			
			|  | 211 | +		}
 | 
	
		
			
			|  | 212 | +
 | 
	
		
			
			|  | 213 | +		// Delete the dashboard
 | 
	
		
			
			|  | 214 | +		err = grafanaClient.DeleteDashboard(slug)
 | 
	
		
			
			|  | 215 | +	}
 | 
	
		
			
			|  | 216 | +
 | 
	
		
			
			|  | 217 | +	return
 | 
	
		
			
			|  | 218 | +}
 | 
	
		
			
			|  | 219 | +
 | 
	
		
			
			| 168 | 220 |  // isIgnored checks whether the file must be ignored, by checking if there's an
 | 
	
		
			
			| 169 | 221 |  // prefix for ignored files set in the configuration file, and if the dashboard
 | 
	
		
			
			| 170 | 222 |  // described in the file has a name that starts with this prefix. Returns an
 |