wesher/config.go

72 lines
2.8 KiB
Go
Raw Normal View History

2019-03-25 01:02:10 +01:00
package main
import (
"fmt"
"net"
"github.com/hashicorp/go-sockaddr"
2019-03-25 01:02:10 +01:00
"github.com/stevenroose/gonfig"
)
const clusterKeyLen = 32
type config struct {
2019-03-25 23:31:32 +01:00
ClusterKey []byte `id:"cluster-key" desc:"shared key for cluster membership; must be 32 bytes base64 encoded; will be generated if not provided"`
Join []string `desc:"comma separated list of hostnames or IP addresses to existing cluster members; if not provided, will attempt resuming any known state or otherwise wait for further members."`
2019-03-27 00:47:23 +01:00
BindAddr string `id:"bind-addr" desc:"IP address to bind to for cluster membership"`
2019-03-25 23:31:32 +01:00
ClusterPort int `id:"cluster-port" desc:"port used for membership gossip traffic (both TCP and UDP); must be the same across cluster" default:"7946"`
WireguardPort int `id:"wireguard-port" desc:"port used for wireguard traffic (UDP); must be the same across cluster" default:"51820"`
OverlayNet *network `id:"overlay-net" desc:"the network in which to allocate addresses for the overlay mesh network (CIDR format); smaller networks increase the chance of IP collision" default:"10.0.0.0/8"`
Interface string `desc:"name of the wireguard interface to create and manage" default:"wgoverlay"`
2019-03-26 23:26:29 +01:00
NoEtcHosts bool `id:"no-etc-hosts" desc:"disable writing of entries to /etc/hosts"`
2019-03-25 23:31:32 +01:00
LogLevel string `id:"log-level" desc:"set the verbosity (debug/info/warn/error)" default:"warn"`
2019-03-26 23:26:54 +01:00
Version bool `desc:"display current version and exit"`
2019-03-25 01:02:10 +01:00
2019-03-26 23:26:54 +01:00
// for easier local testing; will break etchosts entry
UseIPAsName bool `id:"ip-as-name" default:"false" opts:"hidden"`
2019-03-25 01:02:10 +01:00
}
func loadConfig() (*config, error) {
var config config
err := gonfig.Load(&config, gonfig.Conf{EnvPrefix: "WESHER_"})
if err != nil {
return nil, err
}
// perform some validation
if len(config.ClusterKey) != 0 && len(config.ClusterKey) != clusterKeyLen {
return nil, fmt.Errorf("unsupported cluster key length; expected %d, got %d", clusterKeyLen, len(config.ClusterKey))
}
if bits, _ := ((*net.IPNet)(config.OverlayNet)).Mask.Size(); bits%8 != 0 {
return nil, fmt.Errorf("unsupported overlay network size; net mask must be multiple of 8, got %d", bits)
}
// FIXME: this is a work around for memberlist refusing to listen on public IPs
2019-03-27 00:47:23 +01:00
if config.BindAddr == "" {
detectedBindAddr, err := sockaddr.GetPublicIP()
if err != nil {
return nil, err
}
// if we cannot find a public IP, let memberlist do its thing
2019-03-27 00:47:23 +01:00
if detectedBindAddr != "" {
config.BindAddr = detectedBindAddr
}
}
2019-03-25 01:02:10 +01:00
return &config, nil
}
type network net.IPNet
// UnmarshalText parses the provided byte array into the network receiver
func (n *network) UnmarshalText(data []byte) error {
_, ipnet, err := net.ParseCIDR(string(data))
if err != nil {
return err
}
*n = network(*ipnet)
return nil
}