mirror of
https://github.com/mje-nz/zerotier-dns.git
synced 2024-05-11 05:55:15 +00:00
Overhaul config, strip out other subcommands, tidy up, add pre-commit with golangci-lint
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
||||
/.ztdns.toml
|
||||
ztdns.yml
|
||||
ztdns.toml
|
||||
|
||||
.vscode/
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
linters-settings:
|
||||
errcheck:
|
||||
# fmt is default
|
||||
ignore: fmt:.*,github.com/spf13/viper:BindPFlag
|
||||
@@ -0,0 +1,16 @@
|
||||
repos:
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v1.19.1
|
||||
hooks:
|
||||
- id: golangci-lint
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.2.3
|
||||
hooks:
|
||||
- id: check-byte-order-marker
|
||||
- id: check-case-conflict
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-yaml
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
@@ -1,29 +0,0 @@
|
||||
# Configuration file for ztDNS
|
||||
|
||||
suffix = "zt"
|
||||
port = 53
|
||||
interface = "zt0"
|
||||
|
||||
# Number of minutes to wait before updating the DNS database again (Default: 30)
|
||||
DBRefresh = 30
|
||||
|
||||
# This section contains information related to your ZeroTier config
|
||||
[ZT]
|
||||
# API is used to contact the ZeroTier controller API service.
|
||||
API = ""
|
||||
# URL is the url of the ZeroTier controller API
|
||||
URL = "https://my.zerotier.com/api"
|
||||
|
||||
# This section contains one or more ZeroTier networks
|
||||
# Format is: domain = "NetworkID"
|
||||
# Domain does not have to match the configured network name
|
||||
[Networks]
|
||||
|
||||
# Match section contains zero or more match pairs to create Round robin dns
|
||||
# Format is: "regexp to match hosts" = "hostname"
|
||||
# Example 1:
|
||||
# "k8s-node-\w" = "k8s-nodes"
|
||||
# From nodes with names k8s-node-23refw, k8s-node-09sf8g
|
||||
# will create round robin record k8s-nodes
|
||||
[RoundRobin]
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright © 2017 uxbh
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// listinterfacesCmd represents the listinterfaces command
|
||||
var listinterfacesCmd = &cobra.Command{
|
||||
Use: "listinterfaces",
|
||||
Short: "List network interfaces",
|
||||
Long: `List Interfaces (ztdns listinterfaces) lists the available network interfaces
|
||||
to start the server on.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Get a list of interfaces from net
|
||||
ints, err := net.Interfaces()
|
||||
if err != nil {
|
||||
fmt.Printf("error getting interfaces: %s", err)
|
||||
}
|
||||
for i, n := range ints {
|
||||
fmt.Printf("%d: %v\n", i, n.Name)
|
||||
// Get a list of ip address on the interface
|
||||
addrs, _ := n.Addrs()
|
||||
for i, a := range addrs {
|
||||
ip, _, err := net.ParseCIDR(a.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
fmt.Printf("\t%d: %s\n", i, ip)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(listinterfacesCmd)
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
// Copyright © 2017 uxbh
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// mkconfigCmd represents the mkconfig command
|
||||
var mkconfigCmd = &cobra.Command{
|
||||
Use: "mkconfig",
|
||||
Short: "Make a new config file",
|
||||
Long: `mkconfig (ztdns mkconfig) creates a new configuation file.
|
||||
If you do not specify a filename the default is ./.ztdns.toml
|
||||
|
||||
Example: ztdns mkconfig [.filename.toml]`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
filename := "./.ztdns.toml"
|
||||
if len(args) > 0 {
|
||||
filename = args[0]
|
||||
}
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
log.Printf("Creating new config file in %s", filename)
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not create file: %s", err.Error())
|
||||
}
|
||||
defer file.Close()
|
||||
file.WriteString(`# Configuration file for ztDNS
|
||||
|
||||
suffix = "zt"
|
||||
port = 53
|
||||
interface = "zt0"
|
||||
|
||||
# Number of minutes to wait before updating the DNS database again (Default: 30)
|
||||
DBRefresh = 30
|
||||
|
||||
# This section contains information related to your ZeroTier config
|
||||
[ZT]
|
||||
# API is used to contact the ZeroTier controller API service.
|
||||
API = ""
|
||||
# URL is the url of the ZeroTier controller API
|
||||
URL = "https://my.zerotier.com/api"
|
||||
|
||||
# This section contains one or more ZeroTier networks
|
||||
# Format is: domain = "NetworkID"
|
||||
# Domain does not have to match the configured network name
|
||||
[Networks]
|
||||
|
||||
# Match section contains zero or more match pairs to create Round robin dns
|
||||
# Format is: "regexp to match hosts" = "hostname"
|
||||
# Example 1:
|
||||
# "k8s-node-\w" = "k8s-nodes"
|
||||
# From nodes with names k8s-node-23refw, k8s-node-09sf8g
|
||||
# will create round robin record k8s-nodes
|
||||
[RoundRobin]
|
||||
|
||||
`)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(mkconfigCmd)
|
||||
}
|
||||
+12
-13
@@ -1,10 +1,12 @@
|
||||
// Copyright © 2017 uxbh
|
||||
|
||||
// Package cmd implments the ztdns command-line interface.
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
@@ -12,7 +14,6 @@ import (
|
||||
|
||||
var cfgFile string
|
||||
|
||||
// RootCmd represents the base command when called without any subcommands
|
||||
var RootCmd = &cobra.Command{
|
||||
Use: "ztdns",
|
||||
Short: "Zerotier DNS Server",
|
||||
@@ -21,8 +22,6 @@ This application will serve DNS requests for the members of a ZeroTier
|
||||
network for both A (IPv4) and AAAA (IPv6) requests`,
|
||||
}
|
||||
|
||||
// Execute adds all child commands to the root command sets flags appropriately.
|
||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||
func Execute() {
|
||||
if err := RootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -32,28 +31,28 @@ func Execute() {
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
RootCmd.PersistentFlags().Bool("debug", false, "enable debug messages")
|
||||
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ztdns.yml)")
|
||||
viper.BindPFlag("debug", RootCmd.PersistentFlags().Lookup("debug"))
|
||||
|
||||
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ztdns.toml)")
|
||||
|
||||
}
|
||||
|
||||
// initConfig reads in config file and ENV variables if set.
|
||||
func initConfig() {
|
||||
if cfgFile != "" { // enable ability to specify config file via flag
|
||||
if cfgFile != "" {
|
||||
// Use specified config file
|
||||
viper.SetConfigFile(cfgFile)
|
||||
} else {
|
||||
viper.SetConfigName(".ztdns") // name of config file (without extension)
|
||||
viper.AddConfigPath(".") // adding current directory as first search path
|
||||
viper.AddConfigPath("$HOME") // adding home directory as second search path
|
||||
// Find config file in current directory or $HOME
|
||||
viper.SetConfigName("ztdns")
|
||||
viper.AddConfigPath(".")
|
||||
viper.AddConfigPath("$HOME")
|
||||
}
|
||||
|
||||
// Enable setting config values with ZTDNS_KEY environment variables
|
||||
viper.SetEnvPrefix("ztdns")
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
viper.AutomaticEnv()
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
|
||||
// If a config file is found, read it in.
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
fmt.Println("Can't read config:", err)
|
||||
os.Exit(1)
|
||||
|
||||
+55
-44
@@ -20,27 +20,36 @@ import (
|
||||
var serverCmd = &cobra.Command{
|
||||
Use: "server",
|
||||
Short: "Run ztDNS server",
|
||||
Long: `Server (ztdns server) will start the DNS server.append
|
||||
Long: `Server (ztdns server) will start the DNS server.
|
||||
|
||||
Example: ztdns server`,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
// Check config and bail if anything important is missing.
|
||||
if viper.GetBool("debug") {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.Debug("Setting Debug Mode")
|
||||
}
|
||||
if viper.GetString("ZT.API") == "" {
|
||||
return fmt.Errorf("no API key provided")
|
||||
log.Debug("debug: ", viper.GetBool("debug"))
|
||||
log.Debugf("interface: %s", viper.GetString("interface"))
|
||||
log.Debug("port: ", viper.GetInt("port"))
|
||||
log.Debugf("domain: %q", viper.GetString("domain"))
|
||||
log.Debug("refresh: ", viper.GetInt("refresh"))
|
||||
log.Debugf("api-key: %q", viper.GetString("api-key"))
|
||||
log.Debugf("api-url: %q", viper.GetString("api-url"))
|
||||
log.Debugf("network: %q", viper.GetString("network"))
|
||||
log.Debugf("networks: %#v", viper.GetStringMapString("networks"))
|
||||
log.Debugf("round-robin: %#v", viper.GetStringMapString("round-robin"))
|
||||
|
||||
if viper.GetString("api-key") == "" {
|
||||
return fmt.Errorf("No API key provided")
|
||||
}
|
||||
if len(viper.GetStringMapString("Networks")) == 0 {
|
||||
return fmt.Errorf("no Domain / Network ID pairs Provided")
|
||||
|
||||
if viper.GetString("network") == "" && !viper.IsSet("networks") {
|
||||
return fmt.Errorf("No networks configured (specify network or networks)")
|
||||
}
|
||||
if viper.GetString("ZT.URL") == "" {
|
||||
return fmt.Errorf("no URL provided. Run ztdns mkconfig first")
|
||||
}
|
||||
if viper.GetString("suffix") == "" {
|
||||
return fmt.Errorf("no DNS Suffix provided. Run ztdns mkconfig first")
|
||||
if viper.GetString("network") != "" && viper.IsSet("networks") {
|
||||
return fmt.Errorf("Conflicting network configuration (specify one of network or networks)")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
@@ -48,12 +57,9 @@ var serverCmd = &cobra.Command{
|
||||
lastUpdate := updateDNS()
|
||||
req := make(chan string)
|
||||
// Start the DNS server
|
||||
go dnssrv.Start(viper.GetString("interface"), viper.GetInt("port"), viper.GetString("suffix"), req)
|
||||
go dnssrv.Start(viper.GetString("interface"), viper.GetInt("port"), viper.GetString("domain"), req)
|
||||
|
||||
refresh := viper.GetInt("DbRefresh")
|
||||
if refresh == 0 {
|
||||
refresh = 30
|
||||
}
|
||||
refresh := viper.GetInt("refresh")
|
||||
for {
|
||||
// Block until a new request comes in
|
||||
n := <-req
|
||||
@@ -69,49 +75,64 @@ var serverCmd = &cobra.Command{
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(serverCmd)
|
||||
serverCmd.PersistentFlags().String("interface", "", "interface to listen on")
|
||||
viper.BindPFlag("interface", serverCmd.PersistentFlags().Lookup("interface"))
|
||||
serverCmd.Flags().String("interface", "zt0", "network interface to bind to")
|
||||
serverCmd.Flags().Int("port", 53, "port to listen on")
|
||||
serverCmd.Flags().String("domain", "zt", "domain to serve names under")
|
||||
serverCmd.Flags().Int("refresh", 30, "how often to poll the ZeroTier controller in minutes")
|
||||
serverCmd.Flags().String("api-key", "", "ZeroTier API key")
|
||||
serverCmd.Flags().String("api-url", "https://my.zerotier.com/api", "ZeroTier API URL")
|
||||
serverCmd.Flags().String("network", "", "ZeroTier Network ID")
|
||||
viper.BindPFlags(serverCmd.Flags())
|
||||
}
|
||||
|
||||
// TODO: refactor
|
||||
func updateDNS() time.Time {
|
||||
// Get config info
|
||||
API := viper.GetString("ZT.API")
|
||||
URL := viper.GetString("ZT.URL")
|
||||
suffix := viper.GetString("suffix")
|
||||
apiKey := viper.GetString("api-key")
|
||||
apiUrl := viper.GetString("api-url")
|
||||
rootDomain := viper.GetString("domain")
|
||||
|
||||
rrDNSPatterns := make(map[string]*regexp.Regexp)
|
||||
rrDNSRecords := make(map[string][]dnssrv.Records)
|
||||
|
||||
for re, host := range viper.GetStringMapString("RoundRobin") {
|
||||
for re, host := range viper.GetStringMapString("round-robin") {
|
||||
rrDNSPatterns[host] = regexp.MustCompile(re)
|
||||
log.Debugf("Creating match '%s' for %s host", re, host)
|
||||
}
|
||||
|
||||
networks := viper.GetStringMapString("networks")
|
||||
if len(networks) == 0 {
|
||||
networks = map[string]string{"": viper.GetString("network")}
|
||||
}
|
||||
|
||||
// Get all configured networks:
|
||||
for domain, id := range viper.GetStringMapString("Networks") {
|
||||
// Get ZeroTier Network info
|
||||
ztnetwork, err := ztapi.GetNetworkInfo(API, URL, id)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to update DNS entries: %s", err.Error())
|
||||
for domain, networkID := range networks {
|
||||
suffix := "." + rootDomain + "."
|
||||
if domain != "" {
|
||||
suffix = "." + domain + suffix
|
||||
}
|
||||
|
||||
// Get list of members in network
|
||||
log.Infof("Getting Members of Network: %s (%s)", ztnetwork.Config.Name, domain)
|
||||
lst, err := ztapi.GetMemberList(API, URL, ztnetwork.ID)
|
||||
ztnetwork, err := ztapi.GetNetworkInfo(apiKey, apiUrl, networkID)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to update DNS entries: %s", err.Error())
|
||||
log.Fatalf("Unable to get network info: %s", err.Error())
|
||||
}
|
||||
log.Infof("Got %d members", len(*lst))
|
||||
|
||||
log.Infof("Getting members of network: %s (%s)", ztnetwork.Config.Name, suffix)
|
||||
lst, err := ztapi.GetMemberList(apiKey, apiUrl, ztnetwork.ID)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to get member list: %s", err.Error())
|
||||
}
|
||||
log.Debugf("Got %d members", len(*lst))
|
||||
|
||||
for _, n := range *lst {
|
||||
// For all online members
|
||||
if n.Online {
|
||||
// Sanitize name
|
||||
// Sanitize member name
|
||||
name := strings.ToLower(n.Name)
|
||||
name = strings.ReplaceAll(name, " ", "-")
|
||||
re := regexp.MustCompile("[^a-zA-Z0-9-]+")
|
||||
name = re.ReplaceAllString(name, "")
|
||||
record := name + "." + domain + "." + suffix + "."
|
||||
record := name + suffix
|
||||
|
||||
// Clear current DNS records
|
||||
dnssrv.DNSDatabase[record] = dnssrv.Records{}
|
||||
@@ -144,7 +165,6 @@ func updateDNS() time.Time {
|
||||
for host, re := range rrDNSPatterns {
|
||||
log.Debugf("Checking matches for %s host", host)
|
||||
if match := re.FindStringSubmatch(n.Name); match != nil {
|
||||
// prefix := fmt.Sprintf(host, iface(match[1:]))
|
||||
rrRecord := host + "." + domain + "." + suffix + "."
|
||||
|
||||
log.Infof("Adding ips to RR record %-15s IPv4: %-15s IPv6: %s, from host %s", rrRecord, ip4, ip6, n.Name)
|
||||
@@ -169,12 +189,3 @@ func updateDNS() time.Time {
|
||||
// Return the current update time
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
// Convert slice of string to interface for fmt
|
||||
func iface(list []string) []interface{} {
|
||||
vals := make([]interface{}, len(list))
|
||||
for i, v := range list {
|
||||
vals[i] = v
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
+15
-9
@@ -29,7 +29,7 @@ var DNSDatabase = map[string]Records{}
|
||||
var queryChan chan string
|
||||
|
||||
// Start brings up a DNS server for the specified suffix on a given port.
|
||||
func Start(iface string, port int, suffix string, req chan string) error {
|
||||
func Start(iface string, port int, suffix string, req chan string) {
|
||||
queryChan = req
|
||||
|
||||
if port == 0 {
|
||||
@@ -58,12 +58,16 @@ func Start(iface string, port int, suffix string, req chan string) error {
|
||||
log.Printf("Starting server for %s on %s", suffix, server.Addr)
|
||||
err := server.ListenAndServe()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to start DNS server: %s", err.Error())
|
||||
log.Fatalf("Failed to start DNS server: %s", err.Error())
|
||||
}
|
||||
defer server.Shutdown()
|
||||
defer func () {
|
||||
err := server.Shutdown()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to stop DNS server: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
}(suffix, addr, port)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getIfaceAddrs(iface string) []net.IP {
|
||||
@@ -103,7 +107,9 @@ func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
parseQuery(m)
|
||||
}
|
||||
|
||||
w.WriteMsg(m)
|
||||
if err := w.WriteMsg(m); err != nil {
|
||||
log.Errorf("Failed to send response: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// parseQuery reads and creates an answer to a DNS query.
|
||||
@@ -133,15 +139,15 @@ func parseQuery(m *dns.Msg) {
|
||||
|
||||
// shuffle ip addresses for Round Robin dns
|
||||
func shuffle(ips []net.IP) []net.IP {
|
||||
ipsLenght := len(ips)
|
||||
ipsLength := len(ips)
|
||||
|
||||
if ipsLenght < 2 {
|
||||
if ipsLength < 2 {
|
||||
return ips
|
||||
}
|
||||
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
ret := make([]net.IP, ipsLenght)
|
||||
perm := r.Perm(ipsLenght)
|
||||
ret := make([]net.IP, ipsLength)
|
||||
perm := r.Perm(ipsLength)
|
||||
|
||||
for i, randIndex := range perm {
|
||||
ret[i] = ips[randIndex]
|
||||
|
||||
@@ -7,4 +7,5 @@ require (
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/viper v1.4.0
|
||||
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0 // indirect
|
||||
)
|
||||
|
||||
@@ -116,10 +116,13 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -133,7 +136,11 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0 h1:7+F62GGWUowoiJOUDivedlBECd/fTeUDJnCu0JetQO0=
|
||||
golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
||||
+1
-6
@@ -17,10 +17,6 @@ type apiTime struct {
|
||||
|
||||
func (t *apiTime) UnmarshalJSON(b []byte) error {
|
||||
l := len(b)
|
||||
// if string(b) == "0" {
|
||||
// t.time = time.Time{}
|
||||
// return nil
|
||||
// }
|
||||
if l < 3 {
|
||||
n, err := strconv.ParseInt(string(b), 10, 32)
|
||||
if err != nil {
|
||||
@@ -52,8 +48,7 @@ func getJSON(url, APIToken string, target interface{}) error {
|
||||
req.Header.Set("Authorization", "bearer "+APIToken)
|
||||
r, err := c.Do(req)
|
||||
if err != nil {
|
||||
fmt.Errorf("API Error: %q", err)
|
||||
return err
|
||||
return fmt.Errorf("API Error: %s", err.Error())
|
||||
}
|
||||
if r.StatusCode != 200 {
|
||||
return fmt.Errorf("API returned error: %s", r.Status)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# This file contains all available configuration options
|
||||
# with their default values.
|
||||
|
||||
# Network interface to bind to (or "" to bind to). By default, only respond on
|
||||
# the ZeroTier network.
|
||||
interface: "zt0"
|
||||
|
||||
# Port to listen on.
|
||||
port: 53
|
||||
|
||||
# Domain to serve names under. By default, serve members as
|
||||
# "<member name>.<network name>.zt".
|
||||
domain: "zt"
|
||||
|
||||
# How often to poll the ZeroTier controller in minutes.
|
||||
refresh: 30
|
||||
|
||||
# Enable debug messages.
|
||||
debug: false
|
||||
|
||||
# An API key for your ZeroTier account (required).
|
||||
api-key: ""
|
||||
|
||||
# The base API URL for the ZeroTier controller.
|
||||
api-url: "https://my.zerotier.com/api"
|
||||
|
||||
# ID of the ZeroTier network to serve. Only one of "network" and "networks" can
|
||||
# be specified.
|
||||
# E.g., if there is a network with ID "123abc" this would serve its members as
|
||||
# "<member name>.zt".
|
||||
# network: "123abc"
|
||||
network:
|
||||
|
||||
# Mappings between ZeroTier network IDs and domain names. Only one of "network"
|
||||
# and "networks" can be specified.
|
||||
networks:
|
||||
# E.g., if there is a network with ID "123abc" this would serve its members as
|
||||
# "<member name>.home.zt".
|
||||
# home: "123abc"
|
||||
|
||||
# Mappings between round-robin names and regexps to match members. Names are
|
||||
# matched within each network (i.e., if there are members matching a mapping in
|
||||
# multiple networks then the name will be defined separately in each).
|
||||
round-robin:
|
||||
# E.g., if the "home" network defined above had members "k8s-node-23refw" and
|
||||
# "k8s-node-09sf8g" this would create a name "k8s-nodes" returning one of them
|
||||
# at random.
|
||||
# k8s-nodes: "k8s-node-\w"
|
||||
Reference in New Issue
Block a user