| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- package config2
-
- import (
- "bytes"
- "context"
- "encoding/json"
- "net"
- "strconv"
- "sync"
- "time"
-
- "github.com/juju/errors"
- statsd "gopkg.in/alexcesaro/statsd.v2"
- )
-
- type SecretType byte
-
- func (s SecretType) String() string {
- switch s {
- case SecretTypeMain:
- return "main"
- case SecretTypeSecured:
- return "secured"
- default:
- return "tls"
- }
- }
-
- const (
- SecretTypeMain = 1 << iota
- SecretTypeSecured
- SecretTypeTLS
- )
-
- const (
- FlagDebug = "debug"
- FlagVerbose = "verbose"
-
- FlagBindIP = "bind-ip"
- FlagBindPort = "bind-port"
- FlagPublicIPv4 = "public-ipv4"
- FlagPublicIPv4Port = "public-ipv4-port"
- FlagPublicIPv6 = "public-ipv6"
- FlagPublicIPv6Port = "public-ipv6-port"
- FlagStatsIP = "stats-ip"
- FlagStatsPort = "stats-port"
-
- FlagStatsdIP = "statsd-ip"
- FlagStatsdPort = "statsd-port"
- FlagStatsdNetwork = "statsd-network"
- FlagStatsdPrefix = "statsd-prefix"
- FlagStatsdTagsFormat = "statsd-tags-format"
- FlagStatsdTags = "statsd-tags"
-
- FlagPrometheusPrefix = "prometheus-prefix"
-
- FlagWriteBufferSize = "write-buffer"
- FlagReadBufferSize = "read-buffer"
-
- FlagSecureOnly = "secure-only"
-
- FlagAntiReplayMaxSize = "anti-replay-max-size"
- FlagAntiReplayEvictionTime = "anti-replay-eviction-time"
-
- FlagSecret = "secret"
- FlagAdtag = "adtag"
- )
-
- type BufferSize struct {
- Read int `json:"read"`
- Write int `json:"write"`
- }
-
- type AntiReplay struct {
- MaxSize int `json:"max_size"`
- EvictionTime time.Duration `json:"duration"`
- }
-
- type Stats struct {
- Prefix string `json:"prefix"`
- Enabled bool `json:"enabled"`
- }
-
- type StatsdStats struct {
- Stats
-
- Addr Addr `json:"addr"`
- Tags map[string]string `json:"tags"`
- TagsFormat statsd.TagFormat `json:"format"`
- }
-
- type PrometheusStats struct {
- Stats
- }
-
- type Addr struct {
- IP net.IP `json:"ip"`
- Port int `json:"port"`
- net string
- }
-
- func (a Addr) Network() string {
- if a.net == "" {
- return "tcp"
- }
- return a.net
- }
-
- func (a Addr) String() string {
- return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port))
- }
-
- func (a Addr) MarshalJSON() ([]byte, error) {
- data := map[string]string{
- "network": a.Network(),
- "addr": a.String(),
- }
- return json.Marshal(data)
- }
-
- type Config struct {
- BufferSize BufferSize `json:"buffer_size"`
- AntiReplay AntiReplay `json:"anti_replay"`
-
- ListenAddr Addr `json:"listen_addr"`
- PublicIPv4Addr Addr `json:"public_ipv4_addr"`
- PublicIPv6Addr Addr `json:"public_ipv6_addr"`
- StatsAddr Addr `json:"stats_addr"`
-
- StatsdStats StatsdStats `json:"stats_statsd"`
- PrometheusStats PrometheusStats `json:"stats_prometheus"`
-
- Debug bool `json:"debug"`
- Verbose bool `json:"verbose"`
- SecureOnly bool `json:"secure_only"`
- SecretType SecretType `json:"secret_type"`
- Secret []byte `json:"secret"`
- AdTag []byte `json:"adtag"`
- }
-
- func (c Config) String() string {
- data, _ := json.Marshal(c)
- return string(data)
- }
-
- type ConfigOpt struct {
- Name string
- Value interface{}
- }
-
- var C = Config{}
-
- func Init(options ...ConfigOpt) error { // nolint: gocyclo
- for _, opt := range options {
- switch opt.Name {
- case FlagDebug:
- C.Debug = opt.Value.(bool)
- case FlagVerbose:
- C.Verbose = opt.Value.(bool)
- case FlagBindIP:
- C.ListenAddr.IP = opt.Value.(net.IP)
- case FlagBindPort:
- C.ListenAddr.Port = opt.Value.(int)
- case FlagPublicIPv4:
- C.PublicIPv4Addr.IP = opt.Value.(net.IP)
- case FlagPublicIPv4Port:
- C.PublicIPv4Addr.Port = opt.Value.(int)
- case FlagPublicIPv6:
- C.PublicIPv6Addr.IP = opt.Value.(net.IP)
- case FlagPublicIPv6Port:
- C.PublicIPv6Addr.Port = opt.Value.(int)
- case FlagStatsIP:
- C.StatsAddr.IP = opt.Value.(net.IP)
- case FlagStatsPort:
- C.StatsAddr.Port = opt.Value.(int)
- case FlagStatsdIP:
- C.StatsdStats.Addr.IP = opt.Value.(net.IP)
- case FlagStatsdPort:
- C.StatsdStats.Addr.Port = opt.Value.(int)
- case FlagStatsdNetwork:
- C.StatsdStats.Addr.net = opt.Value.(string)
- case FlagStatsdPrefix:
- C.StatsdStats.Prefix = opt.Value.(string)
- case FlagStatsdTagsFormat:
- value := opt.Value.(string)
- switch value {
- case "datadog":
- C.StatsdStats.TagsFormat = statsd.Datadog
- case "influxdb":
- C.StatsdStats.TagsFormat = statsd.InfluxDB
- default:
- return errors.Errorf("Incorrect statsd tag %s", value)
- }
- case FlagStatsdTags:
- C.StatsdStats.Tags = opt.Value.(map[string]string)
- case FlagPrometheusPrefix:
- C.PrometheusStats.Prefix = opt.Value.(string)
- case FlagWriteBufferSize:
- C.BufferSize.Write = opt.Value.(int)
- case FlagReadBufferSize:
- C.BufferSize.Read = opt.Value.(int)
- case FlagAntiReplayMaxSize:
- C.AntiReplay.MaxSize = opt.Value.(int)
- case FlagAntiReplayEvictionTime:
- C.AntiReplay.EvictionTime = opt.Value.(time.Duration)
- case FlagSecureOnly:
- C.SecureOnly = opt.Value.(bool)
- case FlagSecret:
- C.Secret = opt.Value.([]byte)
- case FlagAdtag:
- C.AdTag = opt.Value.([]byte)
- }
- }
-
- var defaultStatsdTags statsd.TagFormat
- if C.StatsdStats.TagsFormat == defaultStatsdTags {
- C.StatsdStats.TagsFormat = statsd.Datadog
- }
- if C.StatsdStats.Addr.net == "" {
- C.StatsdStats.Addr.net = "udp"
- }
-
- switch {
- case len(C.Secret) == 17 && bytes.HasPrefix(C.Secret, []byte{0xdd}):
- C.SecretType = SecretTypeSecured
- C.Secret = bytes.TrimPrefix(C.Secret, []byte{0xdd})
- case len(C.Secret) == 16:
- C.SecretType = SecretTypeMain
- default:
- return errors.New("Incorrect secret")
- }
-
- return nil
- }
-
- func InitPublicAddress() error {
- if C.PublicIPv4Addr.Port == 0 {
- C.PublicIPv4Addr.Port = C.ListenAddr.Port
- }
- if C.PublicIPv6Addr.Port == 0 {
- C.PublicIPv6Addr.Port = C.ListenAddr.Port
- }
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- wg := &sync.WaitGroup{}
- done := make(chan struct{})
-
- if C.PublicIPv4Addr.IP == nil {
- wg.Add(1)
- go func() {
- getGlobalIPv4(ctx, cancel)
- wg.Done()
- }()
- }
- if C.PublicIPv6Addr.IP == nil {
- wg.Add(1)
- go func() {
- getGlobalIPv6(ctx, cancel)
- wg.Done()
-
- }()
- }
- go func() {
- wg.Wait()
- close(done)
- }()
-
- select {
- case <-done:
- return nil
- case <-ctx.Done():
- return ctx.Err()
- }
- }
|