package main import ( "fmt" "github.com/pelletier/go-toml" "os" ) 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 { Recordname string `toml:"recordname"` Zonename string `toml:"zonename"` 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"` } func LoadConfig(path string) (*Config, error) { var cfg Config f, err := os.Open(path) if err != nil { return nil, err } decoder := toml.NewDecoder(f).Strict(true) err = decoder.Decode(&cfg) if err != nil { return nil, err } return prepareConfig(&cfg) } func prepareConfig(cfg *Config) (*Config, error) { // 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) } // 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 }