From c1746de8ebf01c0f7035739e15716149302eb7d4 Mon Sep 17 00:00:00 2001 From: Mike Cheng Date: Wed, 6 May 2015 11:08:30 -0400 Subject: [PATCH] Fix bug where any non-empty hostname would not be updated --- api/api.go | 15 ++++++++++++++- dyndns/daemon.go | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/api/api.go b/api/api.go index 7f49ebd..14387a1 100644 --- a/api/api.go +++ b/api/api.go @@ -80,7 +80,20 @@ func (api API) performRequest(method, url string, body io.Reader) (response []by // Create a DNS record for a given domain. The name // field in DNSRecord is in the format [hostname].[domainname] func (api API) CreateDNSRecord(domain string, record DNSRecord) error { - b, err := json.Marshal(record) + // We need to transform name -> hostname for JSON. + var body struct { + Hostname string `json:"hostname"` + Type string `json:"type"` + Content string `json:"content"` + Ttl string `json:"ttl"` + } + + body.Hostname = record.Name + body.Type = record.Type + body.Content = record.Content + body.Ttl = record.Ttl + + b, err := json.Marshal(body) if err != nil { return err } diff --git a/dyndns/daemon.go b/dyndns/daemon.go index ebc42de..1d836cb 100644 --- a/dyndns/daemon.go +++ b/dyndns/daemon.go @@ -3,14 +3,29 @@ package dyndns import ( + "fmt" "github.com/mfycheng/name-dyndns/api" "github.com/mfycheng/name-dyndns/log" + "strings" "sync" "time" ) var wg sync.WaitGroup +func contains(c api.Config, val string) bool { + if val == c.Domain { + return true + } + + for _, v := range c.Hostnames { + if fmt.Sprintf("%s.%s", v, c.Domain) == val { + return true + } + } + return false +} + func updateDNSRecord(a api.API, domain, recordId string, newRecord api.DNSRecord) error { log.Logger.Printf("Deleting DNS record for %s.\n", newRecord.Name) err := a.DeleteDNSRecord(domain, newRecord.RecordId) @@ -19,6 +34,16 @@ func updateDNSRecord(a api.API, domain, recordId string, newRecord api.DNSRecord } log.Logger.Printf("Creating DNS record for %s: %s\n", newRecord.Name, newRecord) + + // Remove the domain from the DNSRecord name. + // This is an unfortunate inconsistency from the API + // implementation (returns full name, but only requires host) + if newRecord.Name == domain { + newRecord.Name = "" + } else { + newRecord.Name = strings.TrimSuffix(newRecord.Name, fmt.Sprintf(".%s", domain)) + } + return a.CreateDNSRecord(domain, newRecord) } @@ -27,7 +52,6 @@ func runConfig(c api.Config, daemon bool) { a := api.NewAPIFromConfig(c) for { - log.Logger.Printf("Running update check for %s.", c.Domain) ip, err := GetExternalIP() if err != nil { log.Logger.Print("Failed to retreive IP: ") @@ -59,13 +83,18 @@ func runConfig(c api.Config, daemon bool) { } for _, r := range records { + if !contains(c, r.Name) { + continue + } + + log.Logger.Printf("Running update check for %s.", r.Name) if r.Content != ip { r.Content = ip err = updateDNSRecord(a, c.Domain, r.RecordId, r) if err != nil { log.Logger.Printf("Failed to update record %s [%s] with IP: %s\n\t%s\n", r.RecordId, r.Name, ip, err) } else { - log.Logger.Printf("Attempting to update record %s [%s] with IP: %s\n", r.RecordId, r.Name, ip) + log.Logger.Printf("Updated record %s [%s] with IP: %s\n", r.RecordId, r.Name, ip) } } }