Skip to content

Commit

Permalink
Merge pull request #92 from akamai/dns_maint
Browse files Browse the repository at this point in the history
Add endpoints for recordsets, List zones. Fix issue with parse AKAMAICDN
  • Loading branch information
edglynes authored Jun 9, 2020
2 parents 301cd2a + 4f60c81 commit 9e9c0bd
Show file tree
Hide file tree
Showing 4 changed files with 460 additions and 121 deletions.
118 changes: 0 additions & 118 deletions configdns-v2/record_lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dnsv2

import (
"encoding/hex"
"errors"
"fmt"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1"
edge "github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
Expand All @@ -12,51 +11,6 @@ import (
"strings"
)

// Recordset Query args struct
type RecordsetQueryArgs struct {
Page int
PageSize int
Search string
ShowAll bool
SortBy string
Types string
}

type Recordset struct {
Name string `json:"name"`
Type string `json:"type"`
TTL int `json:"ttl"`
Rdata []string `json:"rdata"`
} //`json:"recordsets"`

type MetadataH struct {
LastPage int `json:"lastPage"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
ShowAll bool `json:"showAll"`
TotalElements int `json:"totalElements"`
} //`json:"metadata"`

type RecordSetResponse struct {
Metadata MetadataH `json:"metadata"`
Recordsets []Recordset `json:"recordsets"`
}

/*
type RecordSetResponse struct {
Metadata struct {
ShowAll bool `json:"showAll"`
TotalElements int `json:"totalElements"`
} `json:"metadata"`
Recordsets []struct {
Name string `json:"name"`
Type string `json:"type"`
TTL int `json:"ttl"`
Rdata []string `json:"rdata"`
} `json:"recordsets"`
}
*/

/*
{
"metadata": {
Expand Down Expand Up @@ -125,75 +79,6 @@ func PadCoordinates(str string) string {

}

func NewRecordSetResponse(name string) *RecordSetResponse {
recordset := &RecordSetResponse{}
return recordset
}

// Get RecordSets with Query Args. No formatting of arg values!
func GetRecordsets(zone string, queryArgs ...RecordsetQueryArgs) (*RecordSetResponse, error) {

recordsetResp := NewRecordSetResponse("")

// construct GET url
getURL := fmt.Sprintf("/config-dns/v2/zones/%s/recordsets", zone)
if len(queryArgs) > 1 {
return nil, errors.New("GetRecordsets QueryArgs invalid.")
}

req, err := client.NewRequest(
Config,
"GET",
getURL,
nil,
)
if err != nil {
return nil, err
}

q := req.URL.Query()
if len(queryArgs) > 0 {
if queryArgs[0].Page > 0 {
q.Add("page", strconv.Itoa(queryArgs[0].Page))
}
if queryArgs[0].PageSize > 0 {
q.Add("pageSize", strconv.Itoa(queryArgs[0].PageSize))
}
if queryArgs[0].Search != "" {
q.Add("search", queryArgs[0].Search)
}
q.Add("showAll", strconv.FormatBool(queryArgs[0].ShowAll))
if queryArgs[0].SortBy != "" {
q.Add("sortBy", queryArgs[0].SortBy)
}
if queryArgs[0].Types != "" {
q.Add("types", queryArgs[0].Types)
}
req.URL.RawQuery = q.Encode()
}

edge.PrintHttpRequest(req, true)

res, err := client.Do(Config, req)
if err != nil {
return nil, err
}

edge.PrintHttpResponse(res, true)

if client.IsError(res) && res.StatusCode != 404 {
return nil, client.NewAPIError(res)
} else if res.StatusCode == 404 {
return nil, &ZoneError{zoneName: zone}
} else {
err = client.BodyJSON(res, recordsetResp)
if err != nil {
return nil, err
}
return recordsetResp, nil
}
}

// Get single Recordset. Following convention for other single record CRUD operations, return a RecordBody.
func GetRecord(zone string, name string, record_type string) (*RecordBody, error) {

Expand Down Expand Up @@ -500,9 +385,6 @@ func ParseRData(rtype string, rdata []string) map[string]interface{} {
break
}

case "AKAMAICDN":
fieldMap["edge_hostname"] = rdata[0]

case "AKAMAITLC":
parts := strings.Split(rdata[0], " ")
fieldMap["answer_type"] = parts[0]
Expand Down
211 changes: 211 additions & 0 deletions configdns-v2/recordsets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package dnsv2

import (
"errors"
"fmt"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1"
edge "github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
"strconv"
"sync"
)

var (
zoneRecordsetsWriteLock sync.Mutex
)

// Recordset Query args struct
type RecordsetQueryArgs struct {
Page int
PageSize int
Search string
ShowAll bool
SortBy string
Types string
}

// Recordsets Struct. Used for Create and Update Recordsets
type Recordsets struct {
Recordsets []Recordset `json:"recordsets"`
}

type Recordset struct {
Name string `json:"name"`
Type string `json:"type"`
TTL int `json:"ttl"`
Rdata []string `json:"rdata"`
} //`json:"recordsets"`

type MetadataH struct {
LastPage int `json:"lastPage"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
ShowAll bool `json:"showAll"`
TotalElements int `json:"totalElements"`
} //`json:"metadata"`

type RecordSetResponse struct {
Metadata MetadataH `json:"metadata"`
Recordsets []Recordset `json:"recordsets"`
}

func NewRecordSetResponse(name string) *RecordSetResponse {
recordset := &RecordSetResponse{}
return recordset
}

// Get RecordSets with Query Args. No formatting of arg values!
func GetRecordsets(zone string, queryArgs ...RecordsetQueryArgs) (*RecordSetResponse, error) {

recordsetResp := NewRecordSetResponse("")

// construct GET url
getURL := fmt.Sprintf("/config-dns/v2/zones/%s/recordsets", zone)
if len(queryArgs) > 1 {
return nil, errors.New("GetRecordsets QueryArgs invalid.")
}

req, err := client.NewRequest(
Config,
"GET",
getURL,
nil,
)
if err != nil {
return nil, err
}

q := req.URL.Query()
if len(queryArgs) > 0 {
if queryArgs[0].Page > 0 {
q.Add("page", strconv.Itoa(queryArgs[0].Page))
}
if queryArgs[0].PageSize > 0 {
q.Add("pageSize", strconv.Itoa(queryArgs[0].PageSize))
}
if queryArgs[0].Search != "" {
q.Add("search", queryArgs[0].Search)
}
q.Add("showAll", strconv.FormatBool(queryArgs[0].ShowAll))
if queryArgs[0].SortBy != "" {
q.Add("sortBy", queryArgs[0].SortBy)
}
if queryArgs[0].Types != "" {
q.Add("types", queryArgs[0].Types)
}
req.URL.RawQuery = q.Encode()
}

edge.PrintHttpRequest(req, true)

res, err := client.Do(Config, req)
if err != nil {
return nil, err
}

edge.PrintHttpResponse(res, true)

if client.IsError(res) && res.StatusCode != 404 {
return nil, client.NewAPIError(res)
} else if res.StatusCode == 404 {
return nil, &ZoneError{zoneName: zone}
} else {
err = client.BodyJSON(res, recordsetResp)
if err != nil {
return nil, err
}
return recordsetResp, nil
}
}

// Create Recordstes
func (recordsets *Recordsets) Save(zone string, recLock ...bool) error {
// This lock will restrict the concurrency of API calls
// to 1 save request at a time. This is needed for the Soa.Serial value which
// is required to be incremented for every subsequent update to a zone
// so we have to save just one request at a time to ensure this is always
// incremented properly

if localLock(recLock) {
zoneRecordsetsWriteLock.Lock()
defer zoneRecordsetsWriteLock.Unlock()
}

req, err := client.NewJSONRequest(
Config,
"POST",
"/config-dns/v2/zones/"+zone+"/recordsets",
recordsets,
)
if err != nil {
return err
}

edge.PrintHttpRequest(req, true)

res, err := client.Do(Config, req)

// Network error
if err != nil {
return &ZoneError{
zoneName: zone,
httpErrorMessage: err.Error(),
err: err,
}
}

edge.PrintHttpResponse(res, true)

// API error
if client.IsError(res) {
err := client.NewAPIError(res)
return &ZoneError{zoneName: zone, apiErrorMessage: err.Detail, err: err}
}

return nil
}

func (recordsets *Recordsets) Update(zone string, recLock ...bool) error {
// This lock will restrict the concurrency of API calls
// to 1 save request at a time. This is needed for the Soa.Serial value which
// is required to be incremented for every subsequent update to a zone
// so we have to save just one request at a time to ensure this is always
// incremented properly

if localLock(recLock) {
zoneRecordsetsWriteLock.Lock()
defer zoneRecordsetsWriteLock.Unlock()
}

req, err := client.NewJSONRequest(
Config,
"PUT",
"/config-dns/v2/zones/"+zone+"/recordsets",
recordsets,
)
if err != nil {
return err
}

edge.PrintHttpRequest(req, true)

res, err := client.Do(Config, req)

// Network error
if err != nil {
return &ZoneError{
zoneName: zone,
httpErrorMessage: err.Error(),
err: err,
}
}

edge.PrintHttpResponse(res, true)

// API error
if client.IsError(res) {
err := client.NewAPIError(res)
return &ZoneError{zoneName: zone, apiErrorMessage: err.Detail, err: err}
}

return nil
}
Loading

0 comments on commit 9e9c0bd

Please sign in to comment.