Merge branch 'master' of github.com:/mfycheng/name-dyndns

This commit is contained in:
Mike Cheng 2015-05-10 17:04:15 -04:00
commit 0056049bf8
6 changed files with 43 additions and 41 deletions

View file

@ -13,24 +13,24 @@ import (
) )
const ( const (
productionUrl = "https://api.name.com/" productionURL = "https://api.name.com/"
devUrl = "https://api.dev.name.com/" devURL = "https://api.dev.name.com/"
) )
// Contains details required to access the Name.com API. // API Contains details required to access the Name.com API.
type API struct { type API struct {
baseUrl string baseURL string
username string username string
token string token string
} }
// A Name.com DNS record. // DNSRecord contains information about a Name.com DNS record.
type DNSRecord struct { type DNSRecord struct {
RecordId string `json:"record_id"` RecordID string `json:"record_id"`
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
Content string `json:"content"` Content string `json:"content"`
Ttl string `json:"ttl"` TTL string `json:"ttl"`
CreateDate string `json:"create_date"` CreateDate string `json:"create_date"`
} }
@ -39,21 +39,21 @@ type resultResponse struct {
Message string `json:"message"` Message string `json:"message"`
} }
// Constructs a new Name.com API. If dev is true, then // NewNameAPI constructs a new Name.com API. If dev is true, then
// the API uses the development API, instead of the production API. // the API uses the development API, instead of the production API.
func NewNameAPI(username, token string, dev bool) API { func NewNameAPI(username, token string, dev bool) API {
a := API{username: username, token: token} a := API{username: username, token: token}
if dev { if dev {
a.baseUrl = devUrl a.baseURL = devURL
} else { } else {
a.baseUrl = productionUrl a.baseURL = productionURL
} }
return a return a
} }
// Constructs a new Name.com API from a configuration. // NewAPIFromConfig constructs a new Name.com API from a configuration.
func NewAPIFromConfig(c Config) API { func NewAPIFromConfig(c Config) API {
return NewNameAPI(c.Username, c.Token, c.Dev) return NewNameAPI(c.Username, c.Token, c.Dev)
} }
@ -77,7 +77,7 @@ func (api API) performRequest(method, url string, body io.Reader) (response []by
return ioutil.ReadAll(resp.Body) return ioutil.ReadAll(resp.Body)
} }
// Create a DNS record for a given domain. The name // CreateDNSRecord creates a DNS record for a given domain. The name
// field in DNSRecord is in the format [hostname].[domainname] // field in DNSRecord is in the format [hostname].[domainname]
func (api API) CreateDNSRecord(domain string, record DNSRecord) error { func (api API) CreateDNSRecord(domain string, record DNSRecord) error {
// We need to transform name -> hostname for JSON. // We need to transform name -> hostname for JSON.
@ -85,13 +85,13 @@ func (api API) CreateDNSRecord(domain string, record DNSRecord) error {
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
Type string `json:"type"` Type string `json:"type"`
Content string `json:"content"` Content string `json:"content"`
Ttl string `json:"ttl"` TTL string `json:"ttl"`
} }
body.Hostname = record.Name body.Hostname = record.Name
body.Type = record.Type body.Type = record.Type
body.Content = record.Content body.Content = record.Content
body.Ttl = record.Ttl body.TTL = record.TTL
b, err := json.Marshal(body) b, err := json.Marshal(body)
if err != nil { if err != nil {
@ -100,7 +100,7 @@ func (api API) CreateDNSRecord(domain string, record DNSRecord) error {
resp, err := api.performRequest( resp, err := api.performRequest(
"POST", "POST",
fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/create/", domain), fmt.Sprintf("%s%s%s", api.baseURL, "api/dns/create/", domain),
bytes.NewBuffer(b), bytes.NewBuffer(b),
) )
if err != nil { if err != nil {
@ -122,13 +122,13 @@ func (api API) CreateDNSRecord(domain string, record DNSRecord) error {
return nil return nil
} }
// Deletes a DNS record for a given domain. The recordId can // DeleteDNSRecord deletes a DNS record for a given domain. The recordID can
// be retreived from GetDNSRecords. // be retreived from GetDNSRecords.
func (api API) DeleteDNSRecord(domain, recordId string) error { func (api API) DeleteDNSRecord(domain, recordID string) error {
var body struct { var body struct {
RecordId string `json:"record_id"` RecordID string `json:"record_id"`
} }
body.RecordId = recordId body.RecordID = recordID
b, err := json.Marshal(body) b, err := json.Marshal(body)
if err != nil { if err != nil {
@ -137,7 +137,7 @@ func (api API) DeleteDNSRecord(domain, recordId string) error {
resp, err := api.performRequest( resp, err := api.performRequest(
"POST", "POST",
fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/delete/", domain), fmt.Sprintf("%s%s%s", api.baseURL, "api/dns/delete/", domain),
bytes.NewBuffer(b), bytes.NewBuffer(b),
) )
if err != nil { if err != nil {
@ -159,11 +159,11 @@ func (api API) DeleteDNSRecord(domain, recordId string) error {
return nil return nil
} }
// Returns a slice of DNS records associated with a given domain. // GetDNSRecords returns a slice of DNS records associated with a given domain.
func (api API) GetDNSRecords(domain string) (records []DNSRecord, err error) { func (api API) GetDNSRecords(domain string) (records []DNSRecord, err error) {
resp, err := api.performRequest( resp, err := api.performRequest(
"GET", "GET",
fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/list/", domain), fmt.Sprintf("%s%s%s", api.baseURL, "api/dns/list/", domain),
nil, nil,
) )

View file

@ -5,11 +5,10 @@ import (
"io/ioutil" "io/ioutil"
) )
// Each configuration should represent a specifc domain. // Config represents the configuration for a
// A domain can have multiple hostnames, and the hostnames // specific domain. Each domain can have multiple
// that should be automaticall updated are in Hostnames. // hostnames, including the root domain, where
// If the root domain is to be managed, an empty hostname // hostname is an empty string.
// should be added to the Hostnames slice.
// //
// The interval is the polling time (in seconds) for // The interval is the polling time (in seconds) for
// daemon mode. // daemon mode.
@ -22,7 +21,7 @@ type Config struct {
Username string `json:"username"` Username string `json:"username"`
} }
// Loads configurations from a file. The configuration // LoadConfigs loads configurations from a file. The configuration
// is stored as an array of JSON serialized Config structs. // is stored as an array of JSON serialized Config structs.
func LoadConfigs(path string) ([]Config, error) { func LoadConfigs(path string) ([]Config, error) {
var configs struct { var configs struct {

View file

@ -9,7 +9,7 @@ var expectedConfigs []Config
func init() { func init() {
expectedConfigs = []Config{ expectedConfigs = []Config{
Config{ {
Username: "dev-account", Username: "dev-account",
Token: "asdasdasdasdasdad", Token: "asdasdasdasdasdad",
Interval: 60, Interval: 60,
@ -17,7 +17,7 @@ func init() {
Domain: "test.com", Domain: "test.com",
Hostnames: []string{"mail", "chat"}, Hostnames: []string{"mail", "chat"},
}, },
Config{ {
Username: "production-account", Username: "production-account",
Token: "123123123123", Token: "123123123123",
Interval: 3600, Interval: 3600,

View file

@ -26,9 +26,9 @@ func contains(c api.Config, val string) bool {
return false return false
} }
func updateDNSRecord(a api.API, domain, recordId string, newRecord api.DNSRecord) error { func updateDNSRecord(a api.API, domain, recordID string, newRecord api.DNSRecord) error {
log.Logger.Printf("Deleting DNS record for %s.\n", newRecord.Name) log.Logger.Printf("Deleting DNS record for %s.\n", newRecord.Name)
err := a.DeleteDNSRecord(domain, newRecord.RecordId) err := a.DeleteDNSRecord(domain, newRecord.RecordID)
if err != nil { if err != nil {
return err return err
} }
@ -90,11 +90,11 @@ func runConfig(c api.Config, daemon bool) {
log.Logger.Printf("Running update check for %s.", r.Name) log.Logger.Printf("Running update check for %s.", r.Name)
if r.Content != ip { if r.Content != ip {
r.Content = ip r.Content = ip
err = updateDNSRecord(a, c.Domain, r.RecordId, r) err = updateDNSRecord(a, c.Domain, r.RecordID, r)
if err != nil { 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) log.Logger.Printf("Failed to update record %s [%s] with IP: %s\n\t%s\n", r.RecordID, r.Name, ip, err)
} else { } else {
log.Logger.Printf("Updated 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)
} }
} }
} }
@ -110,10 +110,13 @@ func runConfig(c api.Config, daemon bool) {
} }
} }
// For each domain, check if the host record matches // Run will process each configuration in configs.
// the current external IP. If it does not, it updates. // If daemon is true, then Run will run forever,
// If daemon is true, then Run will run forever, polling at // processing each configuration at its specified
// an interval specified in each config. // interval.
//
// Each configuration represents a domain with
// multiple hostnames.
func Run(configs []api.Config, daemon bool) { func Run(configs []api.Config, daemon bool) {
for _, config := range configs { for _, config := range configs {
wg.Add(1) wg.Add(1)

View file

@ -28,7 +28,7 @@ func tryMirror(url string) (string, error) {
return string(contents), nil return string(contents), nil
} }
// Retrieves the external facing IP Address. // GetExternalIP retrieves the external facing IP Address.
// If multiple mirrors are provided in Urls, // If multiple mirrors are provided in Urls,
// it will try each one (in order), should // it will try each one (in order), should
// preceding mirrors fail. // preceding mirrors fail.

View file

@ -9,7 +9,7 @@ import (
// Global logger. // Global logger.
var Logger *log.Logger var Logger *log.Logger
// Initialize the logger with a specific io.Writer. // Init intializes the logger with a specific io.Writer.
// This function is generally called near startup. // This function is generally called near startup.
func Init(writer io.Writer) { func Init(writer io.Writer) {
Logger = log.New(writer, "", log.Ldate|log.Ltime) Logger = log.New(writer, "", log.Ldate|log.Ltime)