소스 검색

Adapt configuration to introduce different push modes

Brendan Abolivier 6 년 전
부모
커밋
d10644f3bf
로그인 계정: Brendan Abolivier <contact@brendanabolivier.com> GPG 키 ID: 8EF1500759F70623
2개의 변경된 파일86개의 추가작업 그리고 22개의 파일을 삭제
  1. 30
    12
      config.example.yaml
  2. 56
    10
      src/config/config.go

+ 30
- 12
config.example.yaml 파일 보기

@@ -33,15 +33,33 @@ git:
33 33
         # Author's email.
34 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 파일 보기

@@ -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
+}