package dns import ( "errors" "strings" "sync" "darvaza.org/core" "darvaza.org/slog" "git.jpi.io/amery/jpictl/pkg/cluster" "golang.org/x/net/publicsuffix" ) // Manager is a DNS Manager instance type Manager struct { mu sync.Mutex domain string suffix string zones map[string]*Zone regions map[string][]string p Provider l slog.Logger } // ManagerOption configures a Manager type ManagerOption func(*Manager) error func newErrorManagerOption(err error, hint string) ManagerOption { return func(*Manager) error { if hint != "" { err = core.Wrap(err, hint) } return err } } // WithProvider attaches a libdns Provider to the Manager func WithProvider(p Provider) ManagerOption { var err error if p == nil { p, err = DefaultDNSProvider() } if err != nil { return newErrorManagerOption(err, "WithProvider") } return func(mgr *Manager) error { mgr.p = p return nil } } // WithLogger attaches a logger to the Manager func WithLogger(log slog.Logger) ManagerOption { if log == nil { log = cluster.DefaultLogger() } return func(mgr *Manager) error { mgr.l = log return nil } } func (mgr *Manager) setDefaults() error { var opts []ManagerOption if mgr.l == nil { opts = append(opts, WithLogger(nil)) } if mgr.domain == "" || mgr.suffix == "" { return errors.New("domain not specified") } mgr.zones = make(map[string]*Zone) mgr.regions = make(map[string][]string) for _, opt := range opts { if err := opt(mgr); err != nil { return err } } return nil } // WithDomain specifies where the manager operates func WithDomain(domain string) ManagerOption { base, err := publicsuffix.EffectiveTLDPlusOne(domain) if err != nil { return newErrorManagerOption(err, "publicsuffix") } suffix := strings.TrimSuffix(domain, base) if suffix != "" { suffix = "." + suffix[:len(suffix)-1] } return func(mgr *Manager) error { mgr.domain = base mgr.suffix = suffix return nil } } // NewManager creates a DNS manager with the func NewManager(opts ...ManagerOption) (*Manager, error) { mgr := new(Manager) for _, opt := range opts { if err := opt(mgr); err != nil { return nil, err } } if err := mgr.setDefaults(); err != nil { return nil, err } return mgr, nil }