godns/hosts/hosts.go

118 lines
2.3 KiB
Go
Raw Permalink Normal View History

2020-01-25 17:43:02 +00:00
package hosts
2013-07-26 04:06:16 +00:00
import (
"github.com/miekg/dns"
"time"
2019-09-26 04:43:17 +00:00
)
2013-07-26 04:06:16 +00:00
2021-04-15 04:41:06 +00:00
type HostMap map[string][]Host
type Host struct {
Type uint16 `json:"type"`
TTL time.Duration `json:"ttl"`
Values []string `json:"values"`
}
func (h *Host) TypeString() string {
return dns.TypeToString[h.Type]
}
2020-01-25 17:43:02 +00:00
type ProviderList struct {
providers []Provider
2013-07-26 04:06:16 +00:00
}
2021-04-15 04:41:06 +00:00
// Provider is an interface specifying a host source
// Each source should support AT LEAST List and Get, but can support Writer as well
type Provider interface {
2021-04-15 04:41:06 +00:00
List() (HostMap, error)
Get(queryType uint16, domain string) (*Host, error)
2021-04-15 04:41:06 +00:00
}
// Writer is an interface to modify hosts.
// Examples of this include Redis, Bolt, MySQL, etc.
type Writer interface {
Set(domain string, host *Host) error
2021-04-15 04:41:06 +00:00
Delete(domain string) error
}
type ProviderWriter interface {
Provider
Writer
2018-07-01 03:08:29 +00:00
}
2021-04-15 04:41:06 +00:00
func NewHosts(providers []Provider) *ProviderList {
return &ProviderList{providers}
2013-07-26 10:54:19 +00:00
}
2021-04-15 04:41:06 +00:00
// List returns all results, merged into one HostMap
func (h *ProviderList) List() (HostMap, error) {
hostMap := make(HostMap)
for _, provider := range h.providers {
hosts, err := provider.List()
if err != nil {
continue
}
for k, v := range hosts {
if existing, ok := hostMap[k]; ok {
existing = append(existing, v...)
hostMap[k] = existing
} else {
hostMap[k] = v
}
}
}
return hostMap, nil
}
// Get Matches values to providers, loping each in order
func (h *ProviderList) Get(queryType uint16, domain string) (*Host, error) {
var host *Host
var err error
2015-02-12 06:54:02 +00:00
2018-07-01 03:08:29 +00:00
for _, provider := range h.providers {
host, err = provider.Get(queryType, domain)
2018-07-01 03:08:29 +00:00
if host != nil {
2018-07-01 03:08:29 +00:00
break
2015-02-12 06:54:02 +00:00
}
2013-07-26 10:54:19 +00:00
}
2015-02-03 12:32:18 +00:00
return host, err
2021-04-15 04:41:06 +00:00
}
// Set invokes each provider, setting the host on the first one to return a nil error
func (h *ProviderList) Set(domain string, host *Host) (err error) {
for _, provider := range h.providers {
if writer, ok := provider.(Writer); ok {
err = writer.Set(domain, host)
if err == nil {
return
}
}
}
err = errUnsupportedOperation
return
}
// Delete invokes each provider, removing the host on the first one to return a nil error
func (h *ProviderList) Delete(domain string) (err error) {
for _, provider := range h.providers {
if writer, ok := provider.(Writer); ok {
err = writer.Delete(domain)
if err == nil {
return
}
}
}
err = errUnsupportedOperation
return
2020-01-25 17:43:02 +00:00
}