-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
191 lines (166 loc) · 4.87 KB
/
config.go
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
* Copyright (c) 2024 Johan Stenstam, johan.stenstam@internetstiftelsen.se
*/
package main
import (
"log"
"time"
"github.com/go-playground/validator/v10"
"github.com/spf13/viper"
"github.com/dnstapir/tapir"
)
type Config struct {
Services ServicesConf
ApiServer ApiserverConf
DnsEngine DnsengineConf
BootstrapServer BootstrapServerConf
KeyStore KeystoreConf
Sources map[string]SourceConf
Policy PolicyConf
Log struct {
File string `validate:"required"`
Verbose *bool `validate:"required"`
Debug *bool `validate:"required"`
}
Loggers struct {
Mqtt *log.Logger
Dnsengine *log.Logger
Policy *log.Logger
}
Internal InternalConf
PopData *PopData
BootTime time.Time
}
type ServicesConf struct {
Rpz struct {
ZoneName string `validate:"required"`
Primary string `validate:"required"` // XXX: must be an address that DnsEngine listens to
SerialCache string `validate:"required"`
}
Reaper struct {
Interval int `validate:"required"`
}
}
type ApiserverConf struct {
Active *bool `validate:"required"`
Name string `validate:"required"`
Key string `validate:"required"`
Addresses []string `validate:"required"`
TlsAddresses []string `validate:"required"`
}
type DnsengineConf struct {
Active *bool `validate:"required"`
Name string `validate:"required"`
Addresses []string `validate:"required"`
Logfile string `validate:"required"`
// Logger *log.Logger
}
type BootstrapServerConf struct {
Active *bool `validate:"required"`
Name string `validate:"required"`
Addresses []string `validate:"required"`
TlsAddresses []string `validate:"required"`
Logfile string
}
type ServerConf struct {
Listen string `validate:"required"`
Port string `validate:"required"`
}
type KeystoreConf struct {
Path string `validate:"required,file"`
}
type SourceConf struct {
Active *bool `validate:"required"`
Name string `validate:"required"`
Description string `validate:"required"`
Type string `validate:"required"`
Format string `validate:"required"`
Source string `validate:"required"`
Immutable bool
Topic string
ValidatorKey string
Bootstrap []string
BootstrapUrl string
BootstrapKey string
Filename string
Upstream string
Zone string
}
type PolicyConf struct {
Logfile string
// Logger *log.Logger
Whitelist struct {
Action string `validate:"required"`
}
Blacklist struct {
Action string `validate:"required"`
}
Greylist GreylistConf
}
type ListConf struct {
}
type GreylistConf struct {
NumSources struct {
Limit int `validate:"required"`
Action string `validate:"required"`
}
NumTapirTags struct {
Limit int `validate:"required"`
Action string `validate:"required"`
}
BlackTapir struct {
Tags []string `validate:"required"`
Action string `validate:"required"`
}
}
type InternalConf struct {
// RefreshZoneCh chan RpzRefresher
// RpzCmdCh chan RpzCmdData
APIStopCh chan struct{}
ComponentStatusCh chan tapir.ComponentStatusUpdate
}
func ValidateConfig(v *viper.Viper, cfgfile string) error {
var config Config
if v == nil {
if err := viper.Unmarshal(&config); err != nil {
POPExiter("ValidateConfig: Unmarshal error: %v", err)
}
} else {
if err := v.Unmarshal(&config); err != nil {
POPExiter("ValidateConfig: Unmarshal error: %v", err)
}
}
var configsections = make(map[string]interface{}, 5)
configsections["log"] = config.Log
configsections["services"] = config.Services
// configsections["server"] = config.Server
configsections["apiserver"] = config.ApiServer
configsections["dnsengine"] = config.DnsEngine
configsections["bootstrapserver"] = config.BootstrapServer
configsections["policy"] = config.Policy
// Cannot validate a map[string]foobar, must validate the individual foobars:
for key, val := range config.Sources {
configsections["sources-"+key] = val
}
// configsections["oldsources"] = config.OldSources
if err := ValidateBySection(&config, configsections, cfgfile); err != nil {
POPExiter("Config \"%s\" is missing required attributes:\n%v\n", cfgfile, err)
}
return nil
}
func ValidateBySection(config *Config, configsections map[string]interface{}, cfgfile string) error {
validate := validator.New()
for k, data := range configsections {
switch data := data.(type) {
case *SourceConf:
log.Printf("%s: Validating config for source %s", data.Name, k)
case *DnsengineConf, *ApiserverConf, *BootstrapServerConf:
// log.Printf("%s: Validating config for service %s", data.Name, k)
}
if err := validate.Struct(data); err != nil {
log.Printf("ValidateBySection: data that caused validation to fail:\n%v\n", data)
POPExiter("ValidateBySection: Config %s, section %s: missing required attributes:\n%v\n", cfgfile, k, err)
}
}
return nil
}