mirror of
https://github.com/mje-nz/zerotier-dns.git
synced 2024-05-11 05:55:15 +00:00
Add roundrobin record via mtaches (#4)
This commit is contained in:
committed by
Ihor Borodin
parent
861793b69f
commit
80bd0116b9
@ -17,3 +17,5 @@ Dockerfile
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
.DS_Store
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,3 +15,5 @@
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
.DS_Store
|
||||
|
@ -19,3 +19,11 @@ URL = "https://my.zerotier.com/api"
|
||||
# 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]
|
||||
|
||||
|
@ -51,6 +51,13 @@ URL = "https://my.zerotier.com/api"
|
||||
# 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]
|
||||
|
||||
`)
|
||||
}
|
||||
|
13
cmd/root.go
13
cmd/root.go
@ -43,17 +43,20 @@ func init() {
|
||||
|
||||
// initConfig reads in config file and ENV variables if set.
|
||||
func initConfig() {
|
||||
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
|
||||
|
||||
if cfgFile != "" { // enable ability to specify config file via flag
|
||||
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
|
||||
}
|
||||
|
||||
viper.SetEnvPrefix("ztdns")
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
|
||||
// If a config file is found, read it in.
|
||||
viper.ReadInConfig()
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
fmt.Println("Can't read config:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@ -78,6 +79,14 @@ func updateDNS() time.Time {
|
||||
URL := viper.GetString("ZT.URL")
|
||||
suffix := viper.GetString("suffix")
|
||||
|
||||
rrDNSPatterns := make(map[string]*regexp.Regexp)
|
||||
rrDNSRecords := make(map[string][]dnssrv.Records)
|
||||
|
||||
for re, host := range viper.GetStringMapString("RoundRobin") {
|
||||
rrDNSPatterns[host] = regexp.MustCompile(re)
|
||||
log.Debugf("Creating match '%s' for %s host", re, host)
|
||||
}
|
||||
|
||||
// Get all configured networks:
|
||||
for domain, id := range viper.GetStringMapString("Networks") {
|
||||
// Get ZeroTier Network info
|
||||
@ -115,16 +124,51 @@ func updateDNS() time.Time {
|
||||
for _, a := range n.Config.IPAssignments {
|
||||
ip4 = append(ip4, net.ParseIP(a))
|
||||
}
|
||||
// Add the record to the database
|
||||
log.Infof("Updating %-15s IPv4: %-15s IPv6: %s", record, ip4, ip6)
|
||||
dnssrv.DNSDatabase[record] = dnssrv.Records{
|
||||
|
||||
dnsRecord := dnssrv.Records{
|
||||
A: ip4,
|
||||
AAAA: ip6,
|
||||
}
|
||||
|
||||
// Add the record to the database
|
||||
log.Infof("Updating %-15s IPv4: %-15s IPv6: %s", record, ip4, ip6)
|
||||
dnssrv.DNSDatabase[record] = dnsRecord
|
||||
|
||||
// Finding matches for RoundRobin dns
|
||||
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)
|
||||
rrDNSRecords[rrRecord] = append(rrDNSRecords[rrRecord], dnsRecord)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for rrRecord, dnsRecords := range rrDNSRecords {
|
||||
rrRecordIps := dnssrv.Records{}
|
||||
for _, ips := range dnsRecords {
|
||||
rrRecordIps.A = append(rrRecordIps.A, ips.A...)
|
||||
rrRecordIps.AAAA = append(rrRecordIps.AAAA, ips.AAAA...)
|
||||
}
|
||||
|
||||
log.Infof("Updating %-15s IPv4: %-15s IPv6: %s", rrRecord, rrRecordIps.A, rrRecordIps.AAAA)
|
||||
dnssrv.DNSDatabase[rrRecord] = rrRecordIps
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ package dnssrv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
@ -112,14 +113,14 @@ func parseQuery(m *dns.Msg) {
|
||||
if rec, ok := DNSDatabase[q.Name]; ok {
|
||||
switch q.Qtype {
|
||||
case dns.TypeA:
|
||||
for _, ip := range rec.A {
|
||||
for _, ip := range shuffle(rec.A) {
|
||||
rr, err := dns.NewRR(fmt.Sprintf("%s A %s", q.Name, ip.String()))
|
||||
if err == nil {
|
||||
m.Answer = append(m.Answer, rr)
|
||||
}
|
||||
}
|
||||
case dns.TypeAAAA:
|
||||
for _, ip := range rec.AAAA {
|
||||
for _, ip := range shuffle(rec.AAAA) {
|
||||
rr, err := dns.NewRR(fmt.Sprintf("%s AAAA %s", q.Name, ip.String()))
|
||||
if err == nil {
|
||||
m.Answer = append(m.Answer, rr)
|
||||
@ -129,3 +130,16 @@ func parseQuery(m *dns.Msg) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shuffle ip addresses for Round Robin dns
|
||||
func shuffle(ips []net.IP) []net.IP {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
ret := make([]net.IP, len(ips))
|
||||
perm := r.Perm(len(ips))
|
||||
|
||||
for i, randIndex := range perm {
|
||||
ret[i] = ips[randIndex]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
Reference in New Issue
Block a user