2015-05-04 20:20:11 -04:00
|
|
|
// Package api provides a basic interface for dealing
|
|
|
|
// with Name.com DNS API's.
|
2015-04-30 00:18:08 -04:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2015-05-04 14:52:55 -04:00
|
|
|
"bytes"
|
2015-04-30 00:18:08 -04:00
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
productionUrl = "https://api.name.com/"
|
|
|
|
devUrl = "https://api.dev.name.com/"
|
|
|
|
)
|
|
|
|
|
2015-05-04 20:20:11 -04:00
|
|
|
// Contains details required to access the Name.com API.
|
2015-04-30 00:18:08 -04:00
|
|
|
type API struct {
|
|
|
|
baseUrl string
|
|
|
|
username string
|
|
|
|
token string
|
|
|
|
}
|
|
|
|
|
2015-05-04 20:20:11 -04:00
|
|
|
// A Name.com DNS record.
|
2015-04-30 00:18:08 -04:00
|
|
|
type DNSRecord struct {
|
|
|
|
RecordId string `json:"record_id"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Content string `json:"content"`
|
|
|
|
Ttl string `json:"ttl"`
|
|
|
|
CreateDate string `json:"create_date"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type resultResponse struct {
|
|
|
|
Code int `json:"code"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
}
|
|
|
|
|
2015-05-04 20:20:11 -04:00
|
|
|
// Constructs a new Name.com API. If dev is true, then
|
|
|
|
// the API uses the development API, instead of the production API.
|
2015-05-02 21:56:41 -04:00
|
|
|
func NewNameAPI(username, token string, dev bool) API {
|
|
|
|
a := API{username: username, token: token}
|
|
|
|
|
|
|
|
if dev {
|
2015-04-30 00:18:08 -04:00
|
|
|
a.baseUrl = devUrl
|
|
|
|
} else {
|
|
|
|
a.baseUrl = productionUrl
|
|
|
|
}
|
|
|
|
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
2015-05-04 20:20:11 -04:00
|
|
|
// Constructs a new Name.com API from a configuration.
|
2015-05-02 21:56:41 -04:00
|
|
|
func NewAPIFromConfig(c Config) API {
|
|
|
|
return NewNameAPI(c.Username, c.Token, c.Dev)
|
|
|
|
}
|
|
|
|
|
2015-04-30 00:18:08 -04:00
|
|
|
func (api API) performRequest(method, url string, body io.Reader) (response []byte, err error) {
|
|
|
|
var client http.Client
|
|
|
|
req, err := http.NewRequest(method, url, body)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
req.Header.Add("api-username", api.username)
|
|
|
|
req.Header.Add("api-token", api.token)
|
|
|
|
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
return ioutil.ReadAll(resp.Body)
|
|
|
|
}
|
|
|
|
|
2015-05-05 11:07:59 -04:00
|
|
|
// Create a DNS record for a given domain. The name
|
|
|
|
// field in DNSRecord is in the format [hostname].[domainname]
|
2015-05-04 14:52:55 -04:00
|
|
|
func (api API) CreateDNSRecord(domain string, record DNSRecord) error {
|
|
|
|
b, err := json.Marshal(record)
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2015-05-04 20:20:11 -04:00
|
|
|
// Deletes a DNS record for a given domain. The recordId can
|
|
|
|
// be retreived from GetDNSRecords.
|
2015-05-04 14:52:55 -04:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := api.performRequest(
|
|
|
|
"POST",
|
|
|
|
fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/delete/", 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
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns a slice of DNS records associated with a given domain.
|
2015-05-04 20:20:11 -04:00
|
|
|
func (api API) GetDNSRecords(domain string) (records []DNSRecord, err error) {
|
2015-05-04 14:52:55 -04:00
|
|
|
resp, err := api.performRequest(
|
|
|
|
"GET",
|
|
|
|
fmt.Sprintf("%s%s%s", api.baseUrl, "api/dns/list/", domain),
|
|
|
|
nil,
|
|
|
|
)
|
|
|
|
|
2015-04-30 00:18:08 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var result struct {
|
|
|
|
Result resultResponse
|
|
|
|
Records []DNSRecord
|
|
|
|
}
|
|
|
|
|
|
|
|
err = json.Unmarshal(resp, &result)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if result.Result.Code != 100 {
|
|
|
|
return nil, errors.New(result.Result.Message)
|
|
|
|
}
|
|
|
|
|
|
|
|
return result.Records, nil
|
|
|
|
}
|