rewrite most code; removes database to solely rely on config file
This commit is contained in:
parent
32bf03dc07
commit
ef22e29cef
10 changed files with 246 additions and 249 deletions
|
|
@ -1,70 +1,59 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func createQuery(data userData, addr net.IP, deleteRecord bool) string {
|
||||
var query strings.Builder
|
||||
|
||||
query.WriteString(fmt.Sprintf("key %s\n", data.tsigkey))
|
||||
query.WriteString(fmt.Sprintf("server %s\n", data.nameserver))
|
||||
query.WriteString(fmt.Sprintf("zone %s\n", data.zonename))
|
||||
if deleteRecord {
|
||||
query.WriteString(fmt.Sprintf("update delete %s. A\n", data.hostname))
|
||||
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.Hostname)
|
||||
if err != nil {
|
||||
log.Printf("dns lookup failed: %s", err)
|
||||
// enforce update, it's better than not trying at all
|
||||
return true
|
||||
}
|
||||
query.WriteString(fmt.Sprintf("update add %s. A %s\n", data.hostname,
|
||||
addr.String()))
|
||||
query.WriteString("show\n")
|
||||
query.WriteString("send\n")
|
||||
|
||||
return query.String()
|
||||
// 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 queryNameserver(query string) error {
|
||||
var (
|
||||
stdout bytes.Buffer
|
||||
stderr bytes.Buffer
|
||||
)
|
||||
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\n", 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.Hostname, 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)
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
fmt.Printf(stdout.String())
|
||||
fmt.Printf(stderr.String())
|
||||
output, err := cmd.CombinedOutput()
|
||||
// TODO: is outputting stdout+stderr on failure even necessary?
|
||||
if err != nil {
|
||||
log.Printf("executeQuery failed: %s", output)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func updateNameserver(data userData, addr net.IP) (bool, error) {
|
||||
updateRecord := true
|
||||
deleteRecord := true
|
||||
|
||||
addrs, err := net.LookupIP(data.hostname)
|
||||
if err != nil {
|
||||
deleteRecord = false
|
||||
} else {
|
||||
for _, ip := range addrs {
|
||||
if ip.Equal(addr) {
|
||||
updateRecord = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !updateRecord {
|
||||
return false, nil
|
||||
} else {
|
||||
query := createQuery(data, addr, deleteRecord)
|
||||
err = queryNameserver(query)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue