Skip to content

Commit

Permalink
fix script/test output
Browse files Browse the repository at this point in the history
  • Loading branch information
josephholsten committed Mar 3, 2017
1 parent be73135 commit 7491eef
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 6 deletions.
4 changes: 2 additions & 2 deletions probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (
"net/http"
)

// ProbeType wraps the possible types of a ProbeInfo
// ProbeType is the type value in a ProbeInfo
type ProbeType string

// Here lie all the possible ProbeType values
// ProbeType may have any of these acceptable types
const (
DNSProbeType ProbeType = "DNS"
FTPProbeType ProbeType = "FTP"
Expand Down
4 changes: 2 additions & 2 deletions token_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ func NewConfig(username, password, BaseURL string) *oauthPassword.Config {
return &c
}

// Endpoint returns an oauth2.Endpoint for UltraDNS
// Endpoint takes a BaseURL and creates an oauth2.Endpoint for UltraDNS
func Endpoint(BaseURL string) oauth2.Endpoint {
return oauth2.Endpoint{
TokenURL: TokenURL(BaseURL),
}
}

// TokenURL returns an OAuth2 TokenURL for UltraDNS
// TokenURL takes a BaseURL and returns its OAuth2 TokenURL for UltraDNS
func TokenURL(BaseURL string) string {
return fmt.Sprintf("%s/%s/authorization/token", BaseURL, apiVersion)
}
4 changes: 4 additions & 0 deletions udnssdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ type Client struct {
RRSets *RRSetsService
// Tasks API
Tasks *TasksService
// Zones API
Zones *ZonesService
}

// NewClient returns a new ultradns API client.
Expand All @@ -97,6 +99,7 @@ func NewClient(username, password, baseURL string) (*Client, error) {
c.Probes = &ProbesService{client: c}
c.RRSets = &RRSetsService{client: c}
c.Tasks = &TasksService{client: c}
c.Zones = &ZonesService{client: c}
return c, nil
}

Expand All @@ -120,6 +123,7 @@ func newStubClient(username, password, baseURL, clientID, clientSecret string) (
c.Probes = &ProbesService{client: c}
c.RRSets = &RRSetsService{client: c}
c.Tasks = &TasksService{client: c}
c.Zones = &ZonesService{client: c}
return c, nil
}

Expand Down
2 changes: 1 addition & 1 deletion udnssdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var (
testIPDPoolName = "testipdpool"
testIPDPoolAddress = "127.0.0.1"
testIPDPoolDescr = "A Test IP Directional Pool Group"
testIPAddr = IPAddrRange{Address: "127.0.0.1"}
testIPAddrRange = IPAddrRange{Address: "127.0.0.1"}
testIPDPool = AccountLevelIPDirectionalGroup{Name: "testippool", Description: "An IP Test Pool", IPs: []IPAddrRange{IPAddrRange{Address: "127.0.0.1"}}}
testGeoDPool = AccountLevelGeoDirectionalGroup{Name: "testgeopool", Description: "A test geo pool", Codes: []string{"US, UK"}}
testGeoDPoolName = "testgeodpool"
Expand Down
239 changes: 238 additions & 1 deletion zone.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,142 @@
package udnssdk

import "fmt"
import (
"fmt"
"log"
"net/http"
"time"
)

// ZonesService provides access to the zones resources
type ZonesService struct {
client *Client
}

// Zone wraps a response (or item) from:
// /zone GET
// /zone/{name} GET
// AKA "Zone DTO"
type Zone struct {
Properties ZoneProperties `json:"properties"`
RestrictIPList []ZoneRestrictIP `json:"restrictIPList"`
PrimaryNameServers ZonePrimaryNameServers `json:"primaryNameServers"`
OriginalZoneName string `json:"originalZoneName"`
RegistrarInfo ZoneRegistrarInfo
TSig ZoneTSig `json:"tsig"`
NotifyAddresses []ZoneNotifyAddress `json:"notifyAddresses"`
}

// ZoneCreate wraps a requests to:
// /zone POST
// /zone/{name} PUT
// AKA "Zone Create DTO"
type ZoneCreate struct {
Properties ZoneProperties `json:"properties"`
PrimaryCreate ZonePrimaryCreate `json:"primaryCreateInfo"`
SecondaryCreate ZoneSecondaryCreate `json:"secondaryCreateInfo"`
AliasCreateInfo ZoneAliasCreate `json:"aliasCreateInfo"`
}

// ZoneProperties wraps the properties value of Zone and represents attributes common to all zones
// All values will be ignored if present in a Create or Update
// AKA "Zone Properties DTO"
type ZoneProperties struct {
Name ZoneKey `json:"name"`
AccountName string `json:"accountName"`
Owner string `json:"owner"`
Type string `json:"type"` // "ALIAS", "PRIMARY", "SECONDARY"
RecordCount int `json:"recordCount"`
DNSSecStatus string `json:"dnssecStatus"` // "SIGNED", "UNSIGNED"
LastModifiedDateTime time.Time `json:"lastModifiedDateTime"` // ISO8601/RFC3399
}

// ZonePrimaryCreate wraps the primaryCreateInfo value of the ZoneCreate
// AKA "Primary Zone DTO"
type ZonePrimaryCreate struct {
ForceImport bool `json:"forceImport"`
CreateType string `json:"createType"` // "NEW", "COPY", "TRANSFER", "UPLOAD"
NameServer ZoneNameServerIP `json:"nameServer"`
OriginalZoneName string `json:"originalZoneName"`
RestrictIPList []ZoneRestrictIP `json:"restrictIPList"`
TSig ZoneTSig `json:"tsig"`
NotifyAddresses []ZoneNotifyAddress `json:"notifyAddresses"`
Inheirit string `json:"inheirit"` // "ALL", "NONE", "IP_RANGE", "NOTIFY_IP", "TSIG", joined by ","
}

// ZoneRestrictIP wraps the restrictIPList value of a Zone and ZonePrimaryCreate
// AKA "Restrict IP DTOs"
// cf IPAddrRange
type ZoneRestrictIP struct {
Start string `json:"startIP"`
End string `json:"endIP"`
CIDR string `json:"cidr"`
Address string `json:"singleIP"`
Comment string `json:"comment"`
}

// ZoneSecondaryCreate wraps the secondaryCreateInfo value of ZoneCreate
// AKA "Secondary Zone DTO"
type ZoneSecondaryCreate struct {
PrimaryNameServers ZonePrimaryNameServers `json:"primaryNameServers"`
}

// ZoneAliasCreate wraps the aliasCreateInfo value of ZoneCreate
// AKA "Alias Zone DTO"
type ZoneAliasCreate struct {
OriginalZoneName string `json:"originalZoneName"`
}

// ZonePrimaryNameServers wraps the primaryNameServers value of a Zone and ZoneCreate
// AKA "Name Server IP List DTO"
type ZonePrimaryNameServers struct {
NameServerIPList ZoneNameServerIPList `json:"nameServerIpList"`
}

// ZoneNameServerIPList yes, this is really how the data is specified
type ZoneNameServerIPList struct {
NameServerIP1 ZoneNameServerIP `json:"nameServerIp1"`
NameServerIP2 ZoneNameServerIP `json:"nameServerIp2"`
NameServerIP3 ZoneNameServerIP `json:"nameServerIp3"`
}

// ZoneNameServerIP wraps the nameServerIp* values or ZoneNameServerIPList
type ZoneNameServerIP struct {
IP string `json:"ip"`
TSigKey string `json:"tsigKey"`
TSigKeyValue string `json:"tsigKeyValue"`
}

// ZoneRegistrarInfo wraps the registrarInfo of Zone
// AKA "Registrar Info DTO"
type ZoneRegistrarInfo struct {
Registrar string `json:"registrar"`
WhoisExpiration time.Time `json:"whoisExpiration"`
NameServers ZoneRegistrarNameServers `json:"nameServers"`
}

// ZoneRegistrarNameServers wraps the nameServers value of ZoneRegistrarInfo
type ZoneRegistrarNameServers struct {
Ok []string `json:"ok"`
Unknown []string `json:"unknown"`
Missing []string `json:"missing"`
Incorrect []string `json:"incorrect"`
}

// ZoneTSig was the tsig value of Zone and ZoneCreate
// AKA "TSIG DTO"
type ZoneTSig struct {
KeyName string `json:"tsigKeyName"`
KeyValue string `json:"tsigKeyValue"`
Description string `json:"description"`
Algorithm string `json:"tsigAlgorithm"`
}

// ZoneNotifyAddress wraps the notifyAddress value of Zone and ZonePrimaryCreate
// AKA "Notify Address DTO"
type ZoneNotifyAddress struct {
NotifyAddress string `json:"notifyAddress"`
Description string `json:"description"`
}

// ZoneKey is the key for an UltraDNS zone
type ZoneKey string
Expand All @@ -9,3 +145,104 @@ type ZoneKey string
func (z ZoneKey) URI() string {
return fmt.Sprintf("zones/%s", z)
}

// ZonesQueryURI generates the query URI for the zone collection given a query and offset
func ZonesQueryURI(query string, offset int) string {
sort := "NAME"
limit := 100
reverse := false
if query != "" {
return fmt.Sprintf("zones?q=%v&offset=%d&limit=%d&sort=%v&reverse=%v", query, offset, limit, sort, reverse)
}
return fmt.Sprintf("zones?offset=%d&limit=%d&sort=%v&reverse=%v", offset, limit, sort, reverse)
}

// Select requests all zones, with pagination
func (s *ZonesService) Select(query string) ([]Zone, error) {
// TODO: Sane Configuration for timeouts / retries
maxerrs := 5
waittime := 5 * time.Second

// init accumulators
dtos := []Zone{}
offset := 0
errcnt := 0

for {
reqDtos, ri, res, err := s.SelectWithOffset(query, offset)
if err != nil {
if res != nil && res.StatusCode >= 500 {
errcnt = errcnt + 1
if errcnt < maxerrs {
time.Sleep(waittime)
continue
}
}
return dtos, err
}

log.Printf("[DEBUG] ResultInfo: %+v\n", ri)
for _, d := range reqDtos {
dtos = append(dtos, d)
}
if ri.ReturnedCount+ri.Offset >= ri.TotalCount {
return dtos, nil
}
offset = ri.ReturnedCount + ri.Offset
continue
}
}

// ZoneList wraps a response from:
// /zone?q= GET
// AKA "Zone List DTO"
type ZoneList struct {
Zones []Zone `json:"zones"`
QueryInfo QueryInfo `json:"queryInfo"`
ResultInfo ResultInfo `json:"resultInfo"`
}

// SelectWithOffset request zones by query & offset, list them also returning list metadata, the actual response, or an error
func (s *ZonesService) SelectWithOffset(query string, offset int) ([]Zone, ResultInfo, *http.Response, error) {
var zl ZoneList

uri := ZonesQueryURI(query, offset)
res, err := s.client.get(uri, &zl)

zs := []Zone{}
for _, z := range zl.Zones {
zs = append(zs, z)
}
return zs, zl.ResultInfo, res, err
}

// Find Get the properties of a zone.
func (s *ZonesService) Find(z ZoneKey) (Zone, *http.Response, error) {
var zv Zone
res, err := s.client.get(z.URI(), &zv)
return zv, res, err
}

// Create creates a zone with val
func (s *ZonesService) Create(z ZoneKey, val ZoneCreate) (*http.Response, error) {
var ignored interface{}
return s.client.post(z.URI(), val, &ignored)
}

// Update updates a Zone with the provided val
// Cannot be used to:
// - update an alias
// - specify primary name servers for a primary zone
// - specify IPs, TSig, Notify addresses for a secondary zone
func (s *ZonesService) Update(z ZoneKey, val ZoneCreate) (*http.Response, error) {
var ignored interface{}
return s.client.put(z.URI(), val, &ignored)
}

// Convert: secondary => primary
// Unalias: alias => primary

// Delete requests deletions
func (s *ZonesService) Delete(z ZoneKey) (*http.Response, error) {
return s.client.delete(z.URI(), nil)
}

0 comments on commit 7491eef

Please sign in to comment.