~gjabell/mfn

ref: 7eaf9032bc8817241052b6ce09ffe131f2b9f21d mfn/config.go -rw-r--r-- 4.0 KiB
7eaf9032Galen Abell Fix null-pointer exception 1 year, 6 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"

	"github.com/BurntSushi/toml"
)

type validator interface {
	validate() error
}

type EmailConfig struct {
	SubjectTemplate    *Template `toml:"-"`
	SubjectTemplateStr string    `toml:"subject_template"`
	BodyTemplate       *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"`
	HTML               bool      `toml:"html"`
}

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 := NewTemplate("subject_template", c.HTML).Parse(c.SubjectTemplateStr)
	if err != nil {
		return err
	}
	c.SubjectTemplate = subjTmpl

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

	return nil
}

type GotifyConfig struct {
	TitleTemplate      *Template `toml:"-"`
	TitleTemplateStr   string    `toml:"title_template"`
	MessageTemplate    *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 := NewTemplate("title_template", false).Parse(c.TitleTemplateStr)
	if err != nil {
		return err
	}
	c.TitleTemplate = titleTmpl

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

	return nil
}

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

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 := NewTemplate("webhook", c.HTML).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
}