primeiro commit
This commit is contained in:
153
internal/config/config.go
Normal file
153
internal/config/config.go
Normal file
@@ -0,0 +1,153 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/ilyakaznacheev/cleanenv"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Addr string `yaml:"addr" env:"ADDR" env-default:":8080"`
|
||||
PDNSAPIURL string `yaml:"pdns_api_url" env:"PDNS_API_URL" env-default:"http://localhost:8081"`
|
||||
PDNSAPIKey string `yaml:"pdns_api_key" env:"PDNS_API_KEY"`
|
||||
PDNSServerID string `yaml:"pdns_server_id" env:"PDNS_SERVER_ID" env-default:"localhost"`
|
||||
Auth AuthConfig `yaml:"auth"`
|
||||
}
|
||||
|
||||
type AuthConfig struct {
|
||||
Disabled bool `yaml:"disabled" env:"AUTH_DISABLED"`
|
||||
LDAP LDAPConfig `yaml:"ldap"`
|
||||
}
|
||||
|
||||
type LDAPConfig struct {
|
||||
URL string `yaml:"url" env:"AUTH_LDAP_URL"`
|
||||
StartTLS bool `yaml:"start_tls" env:"AUTH_LDAP_START_TLS"`
|
||||
InsecureSkipVerify bool `yaml:"insecure_skip_verify" env:"AUTH_LDAP_INSECURE_SKIP_VERIFY"`
|
||||
BindDN string `yaml:"bind_dn" env:"AUTH_LDAP_BIND_DN"`
|
||||
BindPassword string `yaml:"bind_password" env:"AUTH_LDAP_BIND_PASSWORD"`
|
||||
UserBaseDN string `yaml:"user_base_dn" env:"AUTH_LDAP_USER_BASE_DN"`
|
||||
UsernameAttribute string `yaml:"username_attribute" env:"AUTH_LDAP_USERNAME_ATTRIBUTE" env-default:"uid"`
|
||||
UserFilter string `yaml:"user_filter" env:"AUTH_LDAP_USER_FILTER" env-default:"({username_attribute}={username})"`
|
||||
GroupBaseDN string `yaml:"group_base_dn" env:"AUTH_LDAP_GROUP_BASE_DN"`
|
||||
GroupFilter string `yaml:"group_filter" env:"AUTH_LDAP_GROUP_FILTER"`
|
||||
}
|
||||
|
||||
func Load() (Config, error) {
|
||||
path := strings.TrimSpace(os.Getenv("CONFIG_FILE"))
|
||||
if path == "" {
|
||||
path = defaultConfigPath()
|
||||
}
|
||||
|
||||
return LoadFile(path)
|
||||
}
|
||||
|
||||
func LoadFile(path string) (Config, error) {
|
||||
var cfg Config
|
||||
|
||||
var err error
|
||||
if strings.TrimSpace(path) == "" {
|
||||
err = cleanenv.ReadEnv(&cfg)
|
||||
} else {
|
||||
err = cleanenv.ReadConfig(path, &cfg)
|
||||
}
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
normalize(&cfg)
|
||||
if cfg.PDNSAPIKey == "" {
|
||||
return Config{}, errors.New("PDNS_API_KEY is required")
|
||||
}
|
||||
if err := validateAuth(cfg.Auth); err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func defaultConfigPath() string {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
homeDir = ""
|
||||
}
|
||||
|
||||
return firstExistingConfigPath(configSearchPaths(homeDir, runtime.GOOS))
|
||||
}
|
||||
|
||||
func configSearchPaths(homeDir, goos string) []string {
|
||||
paths := make([]string, 0, 3)
|
||||
if isUnixLike(goos) {
|
||||
paths = append(paths, "/etc/pdns_admin/config.yaml")
|
||||
}
|
||||
if homeDir != "" {
|
||||
paths = append(paths, filepath.Join(homeDir, "config.yaml"))
|
||||
}
|
||||
return append(paths, "config.yaml")
|
||||
}
|
||||
|
||||
func isUnixLike(goos string) bool {
|
||||
switch goos {
|
||||
case "aix", "android", "darwin", "dragonfly", "freebsd", "hurd", "illumos", "ios", "linux", "netbsd", "openbsd", "solaris":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func firstExistingConfigPath(paths []string) string {
|
||||
for _, path := range paths {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return path
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func normalize(cfg *Config) {
|
||||
cfg.Addr = strings.TrimSpace(cfg.Addr)
|
||||
cfg.PDNSAPIURL = strings.TrimSpace(cfg.PDNSAPIURL)
|
||||
cfg.PDNSAPIKey = strings.TrimSpace(cfg.PDNSAPIKey)
|
||||
cfg.PDNSServerID = strings.TrimSpace(cfg.PDNSServerID)
|
||||
cfg.Auth.LDAP.URL = strings.TrimSpace(cfg.Auth.LDAP.URL)
|
||||
cfg.Auth.LDAP.BindDN = strings.TrimSpace(cfg.Auth.LDAP.BindDN)
|
||||
cfg.Auth.LDAP.BindPassword = strings.TrimSpace(cfg.Auth.LDAP.BindPassword)
|
||||
cfg.Auth.LDAP.UserBaseDN = strings.TrimSpace(cfg.Auth.LDAP.UserBaseDN)
|
||||
cfg.Auth.LDAP.UsernameAttribute = strings.TrimSpace(cfg.Auth.LDAP.UsernameAttribute)
|
||||
cfg.Auth.LDAP.UserFilter = strings.TrimSpace(cfg.Auth.LDAP.UserFilter)
|
||||
cfg.Auth.LDAP.GroupBaseDN = strings.TrimSpace(cfg.Auth.LDAP.GroupBaseDN)
|
||||
cfg.Auth.LDAP.GroupFilter = strings.TrimSpace(cfg.Auth.LDAP.GroupFilter)
|
||||
}
|
||||
|
||||
func validateAuth(auth AuthConfig) error {
|
||||
if auth.Disabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
missing := make([]string, 0)
|
||||
for field, value := range map[string]string{
|
||||
"AUTH_LDAP_URL": auth.LDAP.URL,
|
||||
"AUTH_LDAP_BIND_DN": auth.LDAP.BindDN,
|
||||
"AUTH_LDAP_BIND_PASSWORD": auth.LDAP.BindPassword,
|
||||
"AUTH_LDAP_USER_BASE_DN": auth.LDAP.UserBaseDN,
|
||||
"AUTH_LDAP_USERNAME_ATTRIBUTE": auth.LDAP.UsernameAttribute,
|
||||
"AUTH_LDAP_USER_FILTER": auth.LDAP.UserFilter,
|
||||
} {
|
||||
if value == "" {
|
||||
missing = append(missing, field)
|
||||
}
|
||||
}
|
||||
if auth.LDAP.GroupFilter != "" && auth.LDAP.GroupBaseDN == "" {
|
||||
missing = append(missing, "AUTH_LDAP_GROUP_BASE_DN")
|
||||
}
|
||||
if len(missing) > 0 {
|
||||
sort.Strings(missing)
|
||||
return errors.New("LDAP auth is enabled; missing required configuration: " + strings.Join(missing, ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user