This commit separates user credentials from resource record configs to allow user credentials to be used for multiple records instead of one.
59 lines
1.4 KiB
Go
59 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
func requiresRRUpdate(entry *RRConfig, addr net.IP) bool {
|
|
// TODO: use custom resolver to query authoritive nameserver instead of
|
|
// local resolver
|
|
addrs, err := net.LookupIP(entry.Recordname)
|
|
if err != nil {
|
|
log.Printf("dns lookup failed: %s", err)
|
|
// enforce update, it's better than not trying at all
|
|
return true
|
|
}
|
|
|
|
// check if the current ip matches
|
|
for _, ip := range addrs {
|
|
if ip.Equal(addr) {
|
|
// the ip seems to be still up-to-date -> no update required
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func updateRR(entry *RRConfig, addr net.IP) error {
|
|
query := generateQuery(entry, addr)
|
|
return executeQuery(query)
|
|
}
|
|
|
|
func generateQuery(entry *RRConfig, addr net.IP) string {
|
|
var q strings.Builder
|
|
|
|
fmt.Fprintf(&q, "key %s:%s %s\n", entry.Tsigalgo, entry.Tsigid, entry.Tsigkey)
|
|
fmt.Fprintf(&q, "server %s\n", entry.Nameserver)
|
|
fmt.Fprintf(&q, "zone %s\n", entry.Zonename)
|
|
// TODO: check if addr is ipv4 or ipv6 (-> update A or AAAA)
|
|
fmt.Fprintf(&q, "add %s. %d A %s\n", entry.Recordname, entry.Ttl, addr.String())
|
|
fmt.Fprintf(&q, "send\n")
|
|
|
|
return q.String()
|
|
}
|
|
|
|
func executeQuery(query string) error {
|
|
cmd := exec.Command("knsupdate", "-v")
|
|
cmd.Stdin = strings.NewReader(query)
|
|
output, err := cmd.CombinedOutput()
|
|
// TODO: is outputting stdout+stderr on failure even necessary?
|
|
if err != nil {
|
|
log.Printf("executeQuery failed: %s", output)
|
|
}
|
|
|
|
return err
|
|
}
|