Update appears to work, roughly

This commit is contained in:
Mike Cheng 2015-05-04 14:52:55 -04:00
parent 9faf101631
commit be38e512b3
3 changed files with 124 additions and 22 deletions

View file

@ -1,6 +1,7 @@
package api package api
import ( import (
"bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -74,9 +75,83 @@ func (api API) performRequest(method, url string, body io.Reader) (response []by
return ioutil.ReadAll(resp.Body) return ioutil.ReadAll(resp.Body)
} }
// Returns a slice of DNS records associated with a given hostname. func (api API) CreateDNSRecord(domain string, record DNSRecord) error {
func (api API) GetRecords(hostname string) (records []DNSRecord, err error) { b, err := json.Marshal(record)
resp, err := api.performRequest("GET", fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/list/", hostname), nil) if err != nil {
return err
}
resp, err := api.performRequest(
"POST",
fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/create/", domain),
bytes.NewBuffer(b),
)
if err != nil {
return err
}
var result struct {
Result resultResponse
}
err = json.Unmarshal(resp, &result)
if err != nil {
return err
}
if result.Result.Code != 100 {
return errors.New(result.Result.Message)
}
return nil
}
func (api API) DeleteDNSRecord(domain, recordId string) error {
var body struct {
RecordId string `json:"record_id"`
}
body.RecordId = recordId
b, err := json.Marshal(body)
if err != nil {
return err
}
fmt.Println("Body:", string(b))
resp, err := api.performRequest(
"POST",
fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/delete/", domain),
bytes.NewBuffer(b),
)
if err != nil {
return err
}
fmt.Println("Response:", string(resp))
var result struct {
Result resultResponse
}
err = json.Unmarshal(resp, &result)
if err != nil {
return err
}
if result.Result.Code != 100 {
return errors.New(result.Result.Message)
}
return nil
}
// Returns a slice of DNS records associated with a given domain.
func (api API) GetRecords(domain string) (records []DNSRecord, err error) {
resp, err := api.performRequest(
"GET",
fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/list/", domain),
nil,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -90,8 +165,6 @@ func (api API) GetRecords(hostname string) (records []DNSRecord, err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Make sure the API call was successful
if result.Result.Code != 100 { if result.Result.Code != 100 {
return nil, errors.New(result.Result.Message) return nil, errors.New(result.Result.Message)
} }

View file

@ -9,23 +9,16 @@ import (
var wg sync.WaitGroup var wg sync.WaitGroup
func updateDomain(a api.API, currentIP, domain string) error { func updateDNSRecord(a api.API, domain, recordId string, newRecord api.DNSRecord) error {
records, err := a.GetRecords(domain) fmt.Println("Deleting record...")
err := a.DeleteDNSRecord(domain, newRecord.RecordId)
if err != nil { if err != nil {
return err return err
} }
if len(records) == 0 { // Does a /create/ overwrite? or do we have to delete first?
return nil fmt.Println("Creating record")
} return a.CreateDNSRecord(domain, newRecord)
for _, record := range records {
if record.Content != currentIP {
// TODO: Update
}
}
return nil
} }
func runConfig(c api.Config, daemon bool) { func runConfig(c api.Config, daemon bool) {
@ -35,7 +28,7 @@ func runConfig(c api.Config, daemon bool) {
for { for {
ip, err := GetExternalIP() ip, err := GetExternalIP()
if err != nil { if err != nil {
fmt.Print("Failed to retreive IP: ") fmt.Print("Fail to retreive IP: ")
if daemon { if daemon {
fmt.Println("Will retry...") fmt.Println("Will retry...")
continue continue
@ -45,8 +38,31 @@ func runConfig(c api.Config, daemon bool) {
} }
} }
for _, domain := range c.Domains { // GetRecords retrieves a list of DNSRecords,
updateDomain(a, ip, domain) // 1 per hostname with the associated domain.
// If the content is not the current IP, then
// update it.
records, err := a.GetRecords(c.Domain)
if err != nil {
fmt.Print("Failed to retreive records for:%s\n", c.Domain)
if daemon {
fmt.Println("Will retry...")
continue
} else {
fmt.Println("Giving up.")
break
}
}
for _, r := range records {
if r.Content != ip {
fmt.Printf("Updating record %s for %s\n", r.RecordId, c.Domain)
r.Content = ip
err = updateDNSRecord(a, c.Domain, r.RecordId, r)
if err != nil {
fmt.Println("Failed to update record.", err)
}
}
} }
if !daemon { if !daemon {

15
main.go
View file

@ -8,9 +8,20 @@ import (
"os" "os"
) )
func filterConfigs(configs []api.Config, dev bool) []api.Config {
for i := 0; i < len(configs); i++ {
if configs[i].Dev != dev {
configs = append(configs[:i], configs[i+1:]...)
}
}
return configs
}
func main() { func main() {
configPath := flag.String("config", "./config.json", "Specify the configuration file") configPath := flag.String("config", "./config.json", "Specify the configuration file")
daemon := flag.Bool("daemon", false, "operate in daemon mode") daemon := flag.Bool("daemon", false, "Operate in daemon mode.")
dev := flag.Bool("dev", false, "Use development configurations instead.")
flag.Parse() flag.Parse()
configs, err := api.LoadConfigs(*configPath) configs, err := api.LoadConfigs(*configPath)
@ -20,6 +31,8 @@ func main() {
return return
} }
configs = filterConfigs(configs, *dev)
fmt.Printf("Successfully loaded %d configs\n", len(configs)) fmt.Printf("Successfully loaded %d configs\n", len(configs))
dyndns.Run(configs, *daemon) dyndns.Run(configs, *daemon)
} }