restructure config to allow user credentials to update multiple records

This commit separates user credentials from resource record configs to
allow user credentials to be used for multiple records instead of one.
This commit is contained in:
Thomas Preisner 2021-09-08 14:55:04 +02:00
parent 7f1500d53d
commit 451776bde0
4 changed files with 116 additions and 38 deletions

View file

@ -8,18 +8,28 @@ import (
type Config struct {
ServerPort uint16 `toml:"port"`
Users []User `toml:"user"`
RRConfigs []RRConfig `toml:"rrconfig"`
users map[string]*User
rrconfigs map[string]*RRConfig
}
type User struct {
Username string `toml:"username"`
Password string `toml:"password"`
Records []string `toml:"records"`
records map[string]bool
}
type RRConfig struct {
Username string `toml:"username"`
Password string `toml:"password"`
Nameserver string `toml:"nameserver"`
Recordname string `toml:"recordname"`
Zonename string `toml:"zonename"`
Hostname string `toml:"hostname"`
Tsigkey string `toml:"tsigkey"`
Nameserver string `toml:"nameserver"`
Tsigalgo string `toml:"tsig_algo"`
Tsigid string `toml:"tsig_id"`
Tsigkey string `toml:"tsig_key"`
Ttl int `toml:"ttl" default:"60"`
}
@ -37,12 +47,43 @@ func LoadConfig(path string) (*Config, error) {
return nil, err
}
cfg.rrconfigs = map[string]*RRConfig{}
for _, entry := range cfg.RRConfigs {
if _, ok := cfg.rrconfigs[entry.Username]; ok {
return nil, fmt.Errorf("Duplicate username detected")
// temporary map for preventing duplicate records between users
records := make(map[string]bool)
// populate user map
cfg.users = map[string]*User{}
for _, user := range cfg.Users {
if _, ok := cfg.users[user.Username]; ok {
return nil, fmt.Errorf("Duplicate username detected: %s", user.Username)
}
cfg.rrconfigs[entry.Username] = &entry
// initialize and populate user.records map
user.records = make(map[string]bool)
if len(user.Records) <= 0 {
return nil, fmt.Errorf("User without records detected: %s", user.Username)
}
for _, record := range user.Records {
// check for duplicate records
if records[record] {
return nil, fmt.Errorf("Record associated with multiple users detected: %s", record)
}
// memorize record both in the user as well as in the temporary map
user.records[record] = true
records[record] = true
}
cfg.users[user.Username] = &user
}
// populate record map
cfg.rrconfigs = map[string]*RRConfig{}
for _, record := range cfg.RRConfigs {
if !records[record.Recordname] {
return nil, fmt.Errorf("Record without associated user detected: %s", record.Recordname)
}
if _, ok := cfg.rrconfigs[record.Recordname]; ok {
return nil, fmt.Errorf("Duplicate record detected: %s", record.Recordname)
}
cfg.rrconfigs[record.Recordname] = &record
}
return &cfg, nil
}