~gjabell/mfn

ref: eadd6a87a7c825c733dcd197dd0297b10f0d5bd2 mfn/config.go -rw-r--r-- 4.1 KiB
eadd6a87Galen Abell Remove Contributing from README 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package main

import (
	"fmt"
	"reflect"
	"text/template"

	"github.com/BurntSushi/toml"
)

type validator interface {
	validate() error
}

type EmailConfig struct {
	SubjectTemplate    *template.Template `toml:"-"`
	SubjectTemplateStr string             `toml:"subject_template"`
	BodyTemplate       *template.Template `toml:"-"`
	BodyTemplateStr    string             `toml:"body_template"`
	EmailTo            string             `toml:"to"`
	EmailFrom          string             `toml:"from"`
	Username           string             `toml:"username"`
	Password           string             `toml:"password"`
	Server             string             `toml:"server"`
	StartTLS           bool               `toml:"starttls"`
}

func (c *EmailConfig) validate() error {
	for k, v := range map[string]string{
		"subject template": c.SubjectTemplateStr,
		"body template":    c.BodyTemplateStr,
		"\"to\" email":     c.EmailTo,
		"\"from\" email":   c.EmailFrom,
		"username":         c.Username,
		"password":         c.Password,
		"server":           c.Server,
	} {
		if v == "" {
			return fmt.Errorf("you must provide a valid %s", k)
		}
	}

	// parse the templates
	subjTmpl, err := template.New("subject_template").Parse(c.SubjectTemplateStr)
	if err != nil {
		return err
	}
	c.SubjectTemplate = subjTmpl

	bodyTmpl, err := template.New("body_template").Parse(c.BodyTemplateStr)
	if err != nil {
		return err
	}
	c.BodyTemplate = bodyTmpl

	return nil
}

type GotifyConfig struct {
	TitleTemplate      *template.Template `toml:"-"`
	TitleTemplateStr   string             `toml:"title_template"`
	MessageTemplate    *template.Template `toml:"-"`
	MessageTemplateStr string             `toml:"message_template"`
	Server             string             `toml:"server"`
	Token              string             `toml:"token"`
	Priority           int                `toml:"priority"`
}

func (c *GotifyConfig) validate() error {
	for k, v := range map[string]string{
		"title template":   c.TitleTemplateStr,
		"message template": c.MessageTemplateStr,
		"server":           c.Server,
		"token":            c.Token,
	} {
		if v == "" {
			return fmt.Errorf("you must provide a valid %s", k)
		}
	}

	// parse the templates
	titleTmpl, err := template.New("title_template").Parse(c.TitleTemplateStr)
	if err != nil {
		return err
	}
	c.TitleTemplate = titleTmpl

	messageTmpl, err := template.New("message_template").Parse(c.MessageTemplateStr)
	if err != nil {
		return err
	}
	c.MessageTemplate = messageTmpl

	return nil
}

type WebhookConfig struct {
	Template    *template.Template `toml:"-"`
	TemplateStr string             `toml:"template"`
	Endpoint    string             `toml:"endpoint"`
}

func (c *WebhookConfig) validate() error {
	for k, v := range map[string]string{
		"template": c.TemplateStr,
		"endpoint": c.Endpoint,
	} {
		if v == "" {
			return fmt.Errorf("you must provide a valid %s", k)
		}
	}

	// parse the template
	tmpl, err := template.New("webhook").Parse(c.TemplateStr)
	if err != nil {
		return err
	}
	c.Template = tmpl

	return nil
}

type Config struct {
	Server   string `toml:"server"`
	Username string `toml:"username"`
	Password string `toml:"password"`
	DbPath   string `toml:"db_path"`

	EmailConfig   *EmailConfig   `toml:"email"`
	GotifyConfig  *GotifyConfig  `toml:"gotify"`
	WebhookConfig *WebhookConfig `toml:"webhook"`
}

func LoadConfig(configPath string) (*Config, error) {
	var c Config

	if _, err := toml.DecodeFile(configPath, &c); err != nil {
		return nil, err
	}

	if err := c.validate(); err != nil {
		return nil, err
	}

	return &c, nil
}

func (c *Config) validate() error {
	for k, v := range map[string]string{
		"server url":    c.Server,
		"username":      c.Username,
		"password":      c.Password,
		"database path": c.DbPath,
	} {
		if v == "" {
			return fmt.Errorf("you must provide a valid %s", k)
		}
	}

	for k, v := range map[string]validator{
		"email":   c.EmailConfig,
		"gotify":  c.GotifyConfig,
		"webhook": c.WebhookConfig,
	} {
		// interfaces + nil have an interesting interaction...
		if !reflect.ValueOf(v).IsNil() {
			if err := v.validate(); err != nil {
				return fmt.Errorf("invalid %s config: %s", k, err)
			}
		}
	}

	return nil
}