bilibili-backup/app/service/main/bns/conf/conf.go
2019-04-22 02:59:20 +00:00

230 lines
5.5 KiB
Go

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
}