package main import ( "fmt" "os" "sync" "git.xbudex.com/buddy/update-dns/dns" "git.xbudex.com/buddy/update-dns/ip" "github.com/pkg/errors" "github.com/urfave/cli" ) func main() { app := cli.NewApp() app.Name = "update-dns" app.Usage = "update dnsimple with public ip address" app.Version = "0.2.0-dev" app.Action = action app.Flags = []cli.Flag{ cli.StringFlag{ Name: "url", Value: "https://whatismyipv6.buddy.wtf/json", Usage: "url to use to get public ip address", }, cli.StringFlag{ EnvVar: "DNSIMPLE_TOKEN", Name: "dnsimple-token", Usage: "dnsimple token", }, } app.Run(os.Args) } type runtimeError string func (e runtimeError) Error() string { return string(e) } func action(context *cli.Context) error { var wg sync.WaitGroup if context.NArg() < 1 { return runtimeError("requires host argument") } host := context.Args().Get(0) wg.Add(1) ipClient := &ip.Client{ URLv4: "https://whatismyipv4.buddy.wtf/json", URLv6: "https://whatismyipv6.buddy.wtf/json", } var getIPError error var ip string go func() { defer wg.Done() if result, err := ipClient.GetIPv6(); err != nil { getIPError = errors.Wrap(err, "could not get IP address") } else { ip = result } }() client := dns.New(context.String("dnsimple-token")) records := []dns.Record{} var getRecordsError error wg.Add(1) go func() { defer wg.Done() fmt.Println("Getting records") if results, err := client.GetRecords(host, "AAAA"); err != nil { getRecordsError = errors.Wrap(err, "could not get records for host") } else { records = results } }() wg.Wait() if getIPError != nil { return errors.Wrap(getIPError, "could no get ip address") } if getRecordsError != nil { return errors.Wrap(getRecordsError, "could no get record") } if len(records) == 1 && records[0].Content == ip { fmt.Printf("%s record for %s already set as %s\n", "AAAA", host, ip) return nil } if err := client.CreateRecord(host, dns.Record{Type: "AAAA", Content: ip}); err != nil { return errors.Wrap(err, "could not create record") } fmt.Printf("%s record created for %s as %s\n", "AAAA", host, ip) var deleteWG sync.WaitGroup for _, record := range records { deleteWG.Add(1) go func(r dns.Record) { defer deleteWG.Done() fmt.Printf("%s record for %s being deleting %s\n", r.Type, host, r.Content) client.DeleteRecord(r) }(record) } deleteWG.Wait() return nil }