You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
5.5 KiB
229 lines
5.5 KiB
package conf |
|
|
|
import ( |
|
"errors" |
|
"net/url" |
|
"os" |
|
"strconv" |
|
"strings" |
|
"time" |
|
|
|
"github.com/BurntSushi/toml" |
|
|
|
"go-common/library/conf" |
|
"go-common/library/log" |
|
xtime "go-common/library/time" |
|
) |
|
|
|
// ENV Key |
|
const ( |
|
BNSDNSAddr = "BNS_DNS_HOST" |
|
BNSDNSPort = "BNS_DNS_PORT" |
|
BNSHTTPAddr = "BNS_HTTP_ADDR" |
|
BNSHTTPPort = "BNS_HTTP_PORT" |
|
) |
|
|
|
// default value |
|
const ( |
|
defaultBNSDNSAddr = "0.0.0.0" |
|
defaultBNSDNSPort = 15353 |
|
defaultBNSHTTPAddr = "0.0.0.0" |
|
defaultBNSHTTPPort = 15380 |
|
) |
|
|
|
var defaultConfig Config |
|
|
|
func init() { |
|
// default dns config |
|
defaultDNSConfig := DNSConfig{ |
|
TTL: 0, |
|
AllowStale: true, |
|
UDPAnswerLimit: 3, |
|
MaxStale: xtime.Duration(time.Second * 87600), |
|
Domain: "bili.", |
|
RecursorTimeout: xtime.Duration(time.Second), |
|
} |
|
defaultDNSServer := &DNSServer{ |
|
Addr: defaultBNSDNSAddr, |
|
Port: defaultBNSDNSPort, |
|
Config: &defaultDNSConfig, |
|
} |
|
|
|
// default http config |
|
defaultHTTPServer := &HTTPServer{ |
|
Addr: defaultBNSHTTPAddr, |
|
Port: defaultBNSHTTPPort, |
|
} |
|
|
|
defaultBackend := &Backend{ |
|
Backend: "discovery", |
|
Config: map[string]interface{}{ |
|
"url": "http://api.bilibili.co", |
|
}, |
|
} |
|
|
|
defaultConfig = Config{ |
|
Backend: defaultBackend, |
|
HTTP: defaultHTTPServer, |
|
DNS: defaultDNSServer, |
|
} |
|
} |
|
|
|
// LoadConfig from source |
|
func LoadConfig(source string) (*Config, error) { |
|
cfg := defaultConfig |
|
var err error |
|
if strings.HasPrefix(source, "remote://") { |
|
var u *url.URL |
|
if u, err = url.Parse(source); err != nil { |
|
return nil, err |
|
} |
|
err = loadRemoteConfig(u.Path, &cfg) |
|
} else if source != "" { |
|
err = loadLocalConfig(source, &cfg) |
|
} |
|
if err != nil { |
|
return nil, err |
|
} |
|
overwriteByEnv(&cfg) |
|
return &cfg, nil |
|
} |
|
|
|
func loadRemoteConfig(key string, pcfg *Config) error { |
|
client, err := conf.New() |
|
if err != nil { |
|
return err |
|
} |
|
|
|
data, ok := client.Value(key) |
|
if !ok { |
|
return errors.New("load config center error") |
|
} |
|
|
|
if _, err = toml.Decode(data, pcfg); err != nil { |
|
return errors.New("could not decode config") |
|
} |
|
|
|
go func() { |
|
for range client.Event() { |
|
log.Warn("ignore config reload") |
|
} |
|
}() |
|
return nil |
|
} |
|
|
|
func loadLocalConfig(fpath string, pcfg *Config) error { |
|
_, err := toml.DecodeFile(fpath, pcfg) |
|
return err |
|
} |
|
|
|
// Config config struct |
|
type Config struct { |
|
Log *log.Config |
|
Backend *Backend |
|
HTTP *HTTPServer |
|
DNS *DNSServer |
|
} |
|
|
|
// overwrite config from env |
|
func overwriteByEnv(pcfg *Config) { |
|
if addr := os.Getenv(BNSDNSAddr); addr != "" { |
|
pcfg.DNS.Addr = addr |
|
} |
|
if portStr := os.Getenv(BNSDNSPort); portStr != "" { |
|
if port, err := strconv.Atoi(portStr); err != nil { |
|
log.Warn("parse port from env error: %s", err) |
|
} else { |
|
pcfg.DNS.Port = port |
|
} |
|
} |
|
|
|
if addr := os.Getenv(BNSHTTPAddr); addr != "" { |
|
pcfg.HTTP.Addr = addr |
|
} |
|
if portStr := os.Getenv(BNSHTTPPort); portStr != "" { |
|
if port, err := strconv.Atoi(portStr); err != nil { |
|
log.Warn("parse port from env error: %s", err) |
|
} else { |
|
pcfg.HTTP.Port = port |
|
} |
|
} |
|
} |
|
|
|
// Backend Config |
|
type Backend struct { |
|
Backend string |
|
Config map[string]interface{} |
|
} |
|
|
|
// HTTPServer http server config |
|
type HTTPServer struct { |
|
Addr string |
|
Port int |
|
} |
|
|
|
// DNSServer dns server config |
|
type DNSServer struct { |
|
Addr string |
|
Port int |
|
Config *DNSConfig |
|
} |
|
|
|
// DNSConfig dns config |
|
type DNSConfig struct { |
|
// TTL provides the TTL value for a easyns path query for given path. |
|
// The "*" wildcard can be used to set a default to a highlevel path, such as project level path. |
|
TTL xtime.Duration `toml:"ttl"` |
|
|
|
// AllowStale is used to enable lookups with stale |
|
// data. This gives horizontal read scalability since |
|
// any easyns server can service the query instead of |
|
// only the leader. |
|
AllowStale bool |
|
|
|
// EnableTruncate is used to enable setting the truncate |
|
// flag for UDP DNS queries. This allows unmodified |
|
// clients to re-query the easyns server using TCP |
|
// when the total number of records exceeds the number |
|
// returned by default for UDP. |
|
EnableTruncate bool |
|
|
|
// UDPAnswerLimit is used to limit the maximum number of DNS Resource |
|
// Records returned in the ANSWER section of a DNS response. This is |
|
// not normally useful and will be limited based on the querying |
|
// protocol, however systems that implemented §6 Rule 9 in RFC3484 |
|
// may want to set this to `1` in order to subvert §6 Rule 9 and |
|
// re-obtain the effect of randomized resource records (i.e. each |
|
// answer contains only one IP, but the IP changes every request). |
|
// RFC3484 sorts answers in a deterministic order, which defeats the |
|
// purpose of randomized DNS responses. This RFC has been obsoleted |
|
// by RFC6724 and restores the desired behavior of randomized |
|
// responses, however a large number of Linux hosts using glibc(3) |
|
// implemented §6 Rule 9 and may need this option (e.g. CentOS 5-6, |
|
// Debian Squeeze, etc). |
|
UDPAnswerLimit int `toml:"udpAnswerLimit"` |
|
|
|
// MaxStale is used to bound how stale of a result is |
|
// accepted for a DNS lookup. This can be used with |
|
// AllowStale to limit how old of a value is served up. |
|
// If the stale result exceeds this, another non-stale |
|
// stale read is performed. |
|
MaxStale xtime.Duration |
|
|
|
// DisableCompression is used to control whether DNS responses are |
|
// compressed. This was turned on by default and this |
|
// config was added as an opt-out. |
|
DisableCompression bool |
|
|
|
// RecursorTimeout specifies the timeout in seconds |
|
// for Easyns agent's internal dns client used for recursion. |
|
// This value is used for the connection, read and write timeout. |
|
// Default: 2s |
|
RecursorTimeout xtime.Duration |
|
|
|
// Managed domain suffix |
|
Domain string |
|
|
|
// Upstream recursor dns servers |
|
Recursors []string |
|
}
|
|
|