|  | @@ -1,6 +1,7 @@
 | 
	
		
			
			| 1 | 1 |  package config
 | 
	
		
			
			| 2 | 2 |  
 | 
	
		
			
			| 3 | 3 |  import (
 | 
	
		
			
			|  | 4 | +	"errors"
 | 
	
		
			
			| 4 | 5 |  	"io/ioutil"
 | 
	
		
			
			| 5 | 6 |  
 | 
	
		
			
			| 6 | 7 |  	"gopkg.in/yaml.v2"
 | 
	
	
		
			
			|  | @@ -9,12 +10,17 @@ import (
 | 
	
		
			
			| 9 | 10 |  	"github.com/sirupsen/logrus"
 | 
	
		
			
			| 10 | 11 |  )
 | 
	
		
			
			| 11 | 12 |  
 | 
	
		
			
			|  | 13 | +var (
 | 
	
		
			
			|  | 14 | +	ErrPusherInvalidSyncMode   = errors.New("Invalid sync mode in the pusher settings")
 | 
	
		
			
			|  | 15 | +	ErrPusherConfigNotMatching = errors.New("The pusher config doesn't match with the one expected from the pusher sync mode")
 | 
	
		
			
			|  | 16 | +)
 | 
	
		
			
			|  | 17 | +
 | 
	
		
			
			| 12 | 18 |  // Config is the Go representation of the configuration file. It is filled when
 | 
	
		
			
			| 13 | 19 |  // parsing the said file.
 | 
	
		
			
			| 14 | 20 |  type Config struct {
 | 
	
		
			
			| 15 | 21 |  	Grafana GrafanaSettings `yaml:"grafana"`
 | 
	
		
			
			| 16 | 22 |  	Git     GitSettings     `yaml:"git"`
 | 
	
		
			
			| 17 |  | -	Webhook WebhookSettings `yaml:"webhook"`
 | 
	
		
			
			|  | 23 | +	Pusher  PusherSettings  `yaml:"pusher"`
 | 
	
		
			
			| 18 | 24 |  }
 | 
	
		
			
			| 19 | 25 |  
 | 
	
		
			
			| 20 | 26 |  // GrafanaSettings contains the data required to talk to the Grafana HTTP API.
 | 
	
	
		
			
			|  | @@ -40,14 +46,23 @@ type CommitsAuthorConfig struct {
 | 
	
		
			
			| 40 | 46 |  	Email string `yaml:"email"`
 | 
	
		
			
			| 41 | 47 |  }
 | 
	
		
			
			| 42 | 48 |  
 | 
	
		
			
			| 43 |  | -// WebhookSettings contains the data required to setup the GitLab webhook.
 | 
	
		
			
			| 44 |  | -// We declare the port as a string because, although it's a number, it's only
 | 
	
		
			
			| 45 |  | -// used in a string concatenation when creating the webhook.
 | 
	
		
			
			| 46 |  | -type WebhookSettings struct {
 | 
	
		
			
			| 47 |  | -	Interface string `yaml:"interface"`
 | 
	
		
			
			| 48 |  | -	Port      string `yaml:"port"`
 | 
	
		
			
			| 49 |  | -	Path      string `yaml:"path"`
 | 
	
		
			
			| 50 |  | -	Secret    string `yaml:"secret"`
 | 
	
		
			
			|  | 49 | +// PusherConfig contains the data required to setup either the GitLab webhook or
 | 
	
		
			
			|  | 50 | +// the poller.
 | 
	
		
			
			|  | 51 | +// When using the GitLab webhook, we declare the port as a string because,
 | 
	
		
			
			|  | 52 | +// although it's a number, it's only used in a string concatenation when
 | 
	
		
			
			|  | 53 | +// creating the webhook.
 | 
	
		
			
			|  | 54 | +type PusherConfig struct {
 | 
	
		
			
			|  | 55 | +	Interface string `yaml:"interface,omitempty"`
 | 
	
		
			
			|  | 56 | +	Port      string `yaml:"port,omitempty"`
 | 
	
		
			
			|  | 57 | +	Path      string `yaml:"path,omitempty"`
 | 
	
		
			
			|  | 58 | +	Secret    string `yaml:"secret,omitempty"`
 | 
	
		
			
			|  | 59 | +	Interval  int64  `yaml:"interval,omitempty"`
 | 
	
		
			
			|  | 60 | +}
 | 
	
		
			
			|  | 61 | +
 | 
	
		
			
			|  | 62 | +// PusherSettings contains the settings to configure the Git->Grafana pusher.
 | 
	
		
			
			|  | 63 | +type PusherSettings struct {
 | 
	
		
			
			|  | 64 | +	Mode   string       `yaml:"sync_mode"`
 | 
	
		
			
			|  | 65 | +	Config PusherConfig `yaml:"config"`
 | 
	
		
			
			| 51 | 66 |  }
 | 
	
		
			
			| 52 | 67 |  
 | 
	
		
			
			| 53 | 68 |  // Load opens a given configuration file and parses it into an instance of the
 | 
	
	
		
			
			|  | @@ -64,9 +79,40 @@ func Load(filename string) (cfg *Config, err error) {
 | 
	
		
			
			| 64 | 79 |  	}).Info("Loading configuration")
 | 
	
		
			
			| 65 | 80 |  
 | 
	
		
			
			| 66 | 81 |  	cfg = new(Config)
 | 
	
		
			
			| 67 |  | -	err = yaml.Unmarshal(rawCfg, cfg)
 | 
	
		
			
			|  | 82 | +	if err = yaml.Unmarshal(rawCfg, cfg); err != nil {
 | 
	
		
			
			|  | 83 | +		return
 | 
	
		
			
			|  | 84 | +	}
 | 
	
		
			
			| 68 | 85 |  	// Since we always compare the prefix against a slug, we need to make sure
 | 
	
		
			
			| 69 | 86 |  	// the prefix is a slug itself.
 | 
	
		
			
			| 70 | 87 |  	cfg.Grafana.IgnorePrefix = slug.Make(cfg.Grafana.IgnorePrefix)
 | 
	
		
			
			|  | 88 | +	// Make sure the pusher's config is valid, as the parser can't do it.
 | 
	
		
			
			|  | 89 | +	err = validatePusherSettings(cfg.Pusher)
 | 
	
		
			
			| 71 | 90 |  	return
 | 
	
		
			
			| 72 | 91 |  }
 | 
	
		
			
			|  | 92 | +
 | 
	
		
			
			|  | 93 | +// validatePusherSettings checks the pusher config against the one expected from
 | 
	
		
			
			|  | 94 | +// looking at its sync mode.
 | 
	
		
			
			|  | 95 | +// Returns an error if the sync mode isn't in the allowed modes, or if at least
 | 
	
		
			
			|  | 96 | +// one of the fields expected to hold a non-zero-value holds the zero-value for
 | 
	
		
			
			|  | 97 | +// its type.
 | 
	
		
			
			|  | 98 | +func validatePusherSettings(cfg PusherSettings) error {
 | 
	
		
			
			|  | 99 | +	config := cfg.Config
 | 
	
		
			
			|  | 100 | +	var configValid bool
 | 
	
		
			
			|  | 101 | +	switch cfg.Mode {
 | 
	
		
			
			|  | 102 | +	case "webhook":
 | 
	
		
			
			|  | 103 | +		configValid = len(config.Interface) > 0 && len(config.Port) > 0 &&
 | 
	
		
			
			|  | 104 | +			len(config.Path) > 0 && len(config.Secret) > 0
 | 
	
		
			
			|  | 105 | +		break
 | 
	
		
			
			|  | 106 | +	case "git-pull":
 | 
	
		
			
			|  | 107 | +		configValid = config.Interval > 0
 | 
	
		
			
			|  | 108 | +		break
 | 
	
		
			
			|  | 109 | +	default:
 | 
	
		
			
			|  | 110 | +		return ErrPusherInvalidSyncMode
 | 
	
		
			
			|  | 111 | +	}
 | 
	
		
			
			|  | 112 | +
 | 
	
		
			
			|  | 113 | +	if !configValid {
 | 
	
		
			
			|  | 114 | +		return ErrPusherConfigNotMatching
 | 
	
		
			
			|  | 115 | +	}
 | 
	
		
			
			|  | 116 | +
 | 
	
		
			
			|  | 117 | +	return nil
 | 
	
		
			
			|  | 118 | +}
 |