Browse Source

Adapt configuration to introduce different push modes

Brendan Abolivier 6 years ago
parent
commit
d10644f3bf
Signed by: Brendan Abolivier <contact@brendanabolivier.com> GPG key ID: 8EF1500759F70623
2 changed files with 86 additions and 22 deletions
  1. 30
    12
      config.example.yaml
  2. 56
    10
      src/config/config.go

+ 30
- 12
config.example.yaml View File

33
         # Author's email.
33
         # Author's email.
34
         email: grafana-dashboard-manager@company.tld
34
         email: grafana-dashboard-manager@company.tld
35
 
35
 
36
-# Settings to configure the Git webhook. Currently only GitLab webhooks are
37
-# supported.
38
-webhook:
39
-    # Interface the webhook will listen on.
40
-    interface: 127.0.0.1
41
-    # Port the webhool will listen on.
42
-    port: 8080
43
-    # Path on which the webhook will live. Full webhook URL will be
44
-    # interface:port/path.
45
-    path: /gitlab-webhook
46
-    # Secret GitLab will use to authenticate the requests.
47
-    secret: mysecret
36
+# Configuration for the Git -> Grafana pusher.
37
+pusher:
38
+    # Mode which will define how the pusher will sync with the Git remote.
39
+    # Currently, only two modes are supported:
40
+    #   webhook:    sets up a webhook which will listen for requests from the
41
+    #               Git remote, and use the content of a request's body to
42
+    #               determine what to push to Grafana. Currently only GitLab
43
+    #               webhooks are supported.
44
+    #   git-pull:   sets up a routine that will pull from the Git remote on a
45
+    #               given interval, and compare the updated Git history with the
46
+    #               previous one to determine what to push to Grafana.
47
+    sync_mode: webhook
48
+    # Configuration for the given sync mode. The current uncommented exemple
49
+    # works for the "webhook" mode. Here's a config example for the "git-pull"
50
+    # mode:
51
+    #
52
+    #   config:
53
+    #       # Interval at which the remote should be pulled, in seconds.
54
+    #       interval: 3600
55
+    #
56
+    config:
57
+        # Interface the webhook will listen on.
58
+        interface: 127.0.0.1
59
+        # Port the webhool will listen on.
60
+        port: 8080
61
+        # Path on which the webhook will live. Full webhook URL will be
62
+        # interface:port/path.
63
+        path: /gitlab-webhook
64
+        # Secret GitLab will use to authenticate the requests.
65
+        secret: mysecret

+ 56
- 10
src/config/config.go View File

1
 package config
1
 package config
2
 
2
 
3
 import (
3
 import (
4
+	"errors"
4
 	"io/ioutil"
5
 	"io/ioutil"
5
 
6
 
6
 	"gopkg.in/yaml.v2"
7
 	"gopkg.in/yaml.v2"
9
 	"github.com/sirupsen/logrus"
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
 // Config is the Go representation of the configuration file. It is filled when
18
 // Config is the Go representation of the configuration file. It is filled when
13
 // parsing the said file.
19
 // parsing the said file.
14
 type Config struct {
20
 type Config struct {
15
 	Grafana GrafanaSettings `yaml:"grafana"`
21
 	Grafana GrafanaSettings `yaml:"grafana"`
16
 	Git     GitSettings     `yaml:"git"`
22
 	Git     GitSettings     `yaml:"git"`
17
-	Webhook WebhookSettings `yaml:"webhook"`
23
+	Pusher  PusherSettings  `yaml:"pusher"`
18
 }
24
 }
19
 
25
 
20
 // GrafanaSettings contains the data required to talk to the Grafana HTTP API.
26
 // GrafanaSettings contains the data required to talk to the Grafana HTTP API.
40
 	Email string `yaml:"email"`
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
 // Load opens a given configuration file and parses it into an instance of the
68
 // Load opens a given configuration file and parses it into an instance of the
64
 	}).Info("Loading configuration")
79
 	}).Info("Loading configuration")
65
 
80
 
66
 	cfg = new(Config)
81
 	cfg = new(Config)
67
-	err = yaml.Unmarshal(rawCfg, cfg)
82
+	if err = yaml.Unmarshal(rawCfg, cfg); err != nil {
83
+		return
84
+	}
68
 	// Since we always compare the prefix against a slug, we need to make sure
85
 	// Since we always compare the prefix against a slug, we need to make sure
69
 	// the prefix is a slug itself.
86
 	// the prefix is a slug itself.
70
 	cfg.Grafana.IgnorePrefix = slug.Make(cfg.Grafana.IgnorePrefix)
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
 	return
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
+}