File: record.go

package info (click to toggle)
golang-github-akamai-akamaiopen-edgegrid-golang 1.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 1,408 kB
  • sloc: sh: 532; makefile: 3
file content (226 lines) | stat: -rw-r--r-- 7,595 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
package dnsv2

import (
	"github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1"
	edge "github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"

	"sync"
)

// The record types implemented and their fields are as defined here
// https://developer.akamai.com/api/luna/config-dns/data.html

type RecordBody struct {
	Name       string `json:"name,omitempty"`
	RecordType string `json:"type,omitempty"`
	TTL        int    `json:"ttl,omitempty"`
	// Active field no longer used in v2
	Active bool     `json:"active,omitempty"`
	Target []string `json:"rdata,omitempty"`
	// Remaining Fields are not used in the v2 API
	Subtype             int    `json:"subtype,omitempty"`                //AfsdbRecord
	Flags               int    `json:"flags,omitempty"`                  //DnskeyRecord Nsec3paramRecord
	Protocol            int    `json:"protocol,omitempty"`               //DnskeyRecord
	Algorithm           int    `json:"algorithm,omitempty"`              //DnskeyRecord DsRecord Nsec3paramRecord RrsigRecord SshfpRecord
	Key                 string `json:"key,omitempty"`                    //DnskeyRecord
	Keytag              int    `json:"keytag,omitempty"`                 //DsRecord RrsigRecord
	DigestType          int    `json:"digest_type,omitempty"`            //DsRecord
	Digest              string `json:"digest,omitempty"`                 //DsRecord
	Hardware            string `json:"hardware,omitempty"`               //HinfoRecord
	Software            string `json:"software,omitempty"`               //HinfoRecord
	Priority            int    `json:"priority,omitempty"`               //MxRecord SrvRecord
	Order               uint16 `json:"order,omitempty"`                  //NaptrRecord
	Preference          uint16 `json:"preference,omitempty"`             //NaptrRecord
	FlagsNaptr          string `json:"flags,omitempty"`                  //NaptrRecord
	Service             string `json:"service,omitempty"`                //NaptrRecord
	Regexp              string `json:"regexp,omitempty"`                 //NaptrRecord
	Replacement         string `json:"replacement,omitempty"`            //NaptrRecord
	Iterations          int    `json:"iterations,omitempty"`             //Nsec3Record Nsec3paramRecord
	Salt                string `json:"salt,omitempty"`                   //Nsec3Record Nsec3paramRecord
	NextHashedOwnerName string `json:"next_hashed_owner_name,omitempty"` //Nsec3Record
	TypeBitmaps         string `json:"type_bitmaps,omitempty"`           //Nsec3Record
	Mailbox             string `json:"mailbox,omitempty"`                //RpRecord
	Txt                 string `json:"txt,omitempty"`                    //RpRecord
	TypeCovered         string `json:"type_covered,omitempty"`           //RrsigRecord
	OriginalTTL         int    `json:"original_ttl,omitempty"`           //RrsigRecord
	Expiration          string `json:"expiration,omitempty"`             //RrsigRecord
	Inception           string `json:"inception,omitempty"`              //RrsigRecord
	Signer              string `json:"signer,omitempty"`                 //RrsigRecord
	Signature           string `json:"signature,omitempty"`              //RrsigRecord
	Labels              int    `json:"labels,omitempty"`                 //RrsigRecord
	Weight              uint16 `json:"weight,omitempty"`                 //SrvRecord
	Port                uint16 `json:"port,omitempty"`                   //SrvRecord
	FingerprintType     int    `json:"fingerprint_type,omitempty"`       //SshfpRecord
	Fingerprint         string `json:"fingerprint,omitempty"`            //SshfpRecord
	PriorityIncrement   int    `json:"priority_increment,omitempty"`     //MX priority Increment
}

var (
	zoneRecordWriteLock sync.Mutex
)

func (record *RecordBody) ToMap() map[string]interface{} {
	return map[string]interface{}{
		"name":   record.Name,
		"ttl":    record.TTL,
		"active": record.Active,
		"target": record.Target,
	}
}

func NewRecordBody(params RecordBody) *RecordBody {
	recordbody := &RecordBody{Name: params.Name}
	return recordbody
}

// Eval option lock arg passed into writable endpoints. Default is true, e.g. lock
func localLock(lockArg []bool) bool {

	for _, lock := range lockArg {
		// should only be one entry
		return lock
	}

	return true

}

func (record *RecordBody) 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) {
		zoneRecordWriteLock.Lock()
		defer zoneRecordWriteLock.Unlock()
	}

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

	edge.PrintHttpRequest(req, true)

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

	// Network error
	if err != nil {
		return &RecordError{
			fieldName:        record.Name,
			httpErrorMessage: err.Error(),
			err:              err,
		}
	}

	edge.PrintHttpResponse(res, true)

	// API error
	if client.IsError(res) {
		err := client.NewAPIError(res)
		return &RecordError{fieldName: record.Name, apiErrorMessage: err.Detail, err: err}
	}

	return nil
}

func (record *RecordBody) 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) {
		zoneRecordWriteLock.Lock()
		defer zoneRecordWriteLock.Unlock()
	}

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

	edge.PrintHttpRequest(req, true)

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

	// Network error
	if err != nil {
		return &RecordError{
			fieldName:        record.Name,
			httpErrorMessage: err.Error(),
			err:              err,
		}
	}

	edge.PrintHttpResponse(res, true)

	// API error
	if client.IsError(res) {
		err := client.NewAPIError(res)
		return &RecordError{fieldName: record.Name, apiErrorMessage: err.Detail, err: err}
	}

	return nil
}

func (record *RecordBody) Delete(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) {
		zoneRecordWriteLock.Lock()
		defer zoneRecordWriteLock.Unlock()
	}

	req, err := client.NewJSONRequest(
		Config,
		"DELETE",
		"/config-dns/v2/zones/"+zone+"/names/"+record.Name+"/types/"+record.RecordType,
		nil,
	)
	if err != nil {
		return err
	}

	edge.PrintHttpRequest(req, true)

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

	// Network error
	if err != nil {
		return &RecordError{
			fieldName:        record.Name,
			httpErrorMessage: err.Error(),
			err:              err,
		}
	}

	edge.PrintHttpResponse(res, true)

	// API error
	if client.IsError(res) {
		if res.StatusCode != 404 {
			err := client.NewAPIError(res)
			return &RecordError{fieldName: record.Name, apiErrorMessage: err.Detail, err: err}
		}
	}

	return nil
}