Skip to content

Commit 96246d4

Browse files
authored
DXE-3055 Merge pull request #194 from akamai/release/v7.3.0
DXE-3055 Release/v7.3.0
2 parents 0149856 + 2a5def8 commit 96246d4

File tree

9 files changed

+267
-1
lines changed

9 files changed

+267
-1
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# EDGEGRID GOLANG RELEASE NOTES
22

3+
## 7.3.0 (September 19, 2023)
4+
5+
#### FEATURES/ENHANCEMENTS:
6+
7+
* ClientLists
8+
* Updated `GetClientListResponse` and `UpdateClientListResponse` to include `GroupID`
9+
10+
* GTM
11+
* Added custom error `ErrNotFound` that can be used to check if GTM api retuned 404 not found
12+
13+
* HAPI
14+
* Added `GetChangeRequest`
15+
16+
* Updated `yaml.v3` dependency
17+
318
## 7.2.1 (August 25, 2023)
419

520
#### BUG FIXES:

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ COMMIT_SHA=$(shell git rev-parse --short HEAD)
33
VERSION ?= $(shell git describe --tags --always | grep '^v\d' || \
44
echo $(FILEVERSION)-$(COMMIT_SHA))
55
BIN = $(CURDIR)/bin
6-
GOLANGCI_LINT_VERSION = v1.50.1
6+
GOLANGCI_LINT_VERSION = v1.52.2
77
GO = go
88
TIMEOUT = 15
99
V = 0

pkg/clientlists/client_list.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ type (
129129
GetClientListResponse struct {
130130
ListContent
131131
ContractID string `json:"contractId"`
132+
GroupID int64 `json:"groupId"`
132133
GroupName string `json:"groupName"`
133134
Items []ListItemContent `json:"items"`
134135
}
@@ -165,6 +166,7 @@ type (
165166
ListContent
166167
ContractID string `json:"contractId"`
167168
GroupName string `json:"groupName"`
169+
GroupID int64 `json:"groupId"`
168170
}
169171

170172
// UpdateClientListItemsRequest contains request params for UpdateClientListItems method

pkg/clientlists/client_list_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,9 @@ func TestGetClientList(t *testing.T) {
365365
"updateDate": "2023-06-06T15:58:39.225+00:00",
366366
"updatedBy": "ccare2",
367367
"version": 1,
368+
"groupId": 12,
369+
"groupName": "123_ABC",
370+
"contractId" :"12_CO",
368371
"items": [
369372
{
370373
"createDate": "2022-07-12T20:14:29.189+00:00",
@@ -420,6 +423,9 @@ func TestGetClientList(t *testing.T) {
420423
UpdatedBy: "ccare2",
421424
Version: 1,
422425
},
426+
GroupID: 12,
427+
GroupName: "123_ABC",
428+
ContractID: "12_CO",
423429
Items: []ListItemContent{
424430
{
425431
CreateDate: "2022-07-12T20:14:29.189+00:00",
@@ -515,6 +521,7 @@ func TestUpdateClientList(t *testing.T) {
515521
result := UpdateClientListResponse{
516522
ContractID: "M-2CF0QRI",
517523
GroupName: "Kona QA16-M-2CF0QRI",
524+
GroupID: 12,
518525
ListContent: ListContent{
519526
CreateDate: "2023-04-03T15:50:34.074+00:00",
520527
CreatedBy: "ccare2",
@@ -558,6 +565,7 @@ func TestUpdateClientList(t *testing.T) {
558565
"deprecated": false,
559566
"filePrefix": "CL",
560567
"groupName": "Kona QA16-M-2CF0QRI",
568+
"groupId": 12,
561569
"itemsCount": 51,
562570
"listId": "12_12",
563571
"listType": "CL",
@@ -839,6 +847,7 @@ func TestCreateClientLists(t *testing.T) {
839847
},
840848
ContractID: "M-2CF0QRI",
841849
GroupName: "Group A",
850+
GroupID: 12,
842851
Items: []ListItemContent{
843852
{
844853
Value: "1.1.1.1",
@@ -873,6 +882,7 @@ func TestCreateClientLists(t *testing.T) {
873882
],
874883
"contractId": "M-2CF0QRI",
875884
"groupName": "Group A",
885+
"groupId": 12,
876886
"items": [
877887
{
878888
"value": "1.1.1.1",

pkg/gtm/errors.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
var (
1212
// ErrBadRequest is returned when a required parameter is missing
1313
ErrBadRequest = errors.New("missing argument")
14+
// ErrNotFound used when status code is 404 Not Found
15+
ErrNotFound = errors.New("404 Not Found")
1416
)
1517

1618
type (
@@ -62,6 +64,11 @@ func (e *Error) Error() string {
6264

6365
// Is handles error comparisons
6466
func (e *Error) Is(target error) bool {
67+
68+
if errors.Is(target, ErrNotFound) && e.StatusCode == http.StatusNotFound {
69+
return true
70+
}
71+
6572
var t *Error
6673
if !errors.As(target, &t) {
6774
return false

pkg/hapi/change_requests.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package hapi
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"net/http"
8+
)
9+
10+
type (
11+
// ChangeRequests contains operations to query for Change Requests.
12+
ChangeRequests interface {
13+
// GetChangeRequest request status and details specified by the change ID
14+
// that is provided when you make a change request.
15+
//
16+
// See: https://techdocs.akamai.com/edge-hostnames/reference/get-changeid
17+
GetChangeRequest(context.Context, GetChangeRequest) (*ChangeRequest, error)
18+
}
19+
20+
// GetChangeRequest is a request struct
21+
GetChangeRequest struct {
22+
ChangeID int
23+
}
24+
25+
// ChangeRequest represents change response from api
26+
ChangeRequest struct {
27+
Action string `json:"action"`
28+
ChangeID int64 `json:"changeId"`
29+
Comments string `json:"comments"`
30+
EdgeHostnames []EdgeHostname `json:"edgeHostnames"`
31+
Status string `json:"status"`
32+
StatusMessage string `json:"statusMessage"`
33+
StatusUpdateEmail string `json:"statusUpdateEmail"`
34+
StatusUpdateDate string `json:"statusUpdateDate"`
35+
SubmitDate string `json:"submitDate"`
36+
Submitter string `json:"submitter"`
37+
SubmitterEmail string `json:"submitterEmail"`
38+
}
39+
)
40+
41+
// ErrGetChangeRequest returned when get change request fails
42+
var ErrGetChangeRequest = errors.New("get change request")
43+
44+
func (h *hapi) GetChangeRequest(ctx context.Context, prop GetChangeRequest) (*ChangeRequest, error) {
45+
logger := h.Log(ctx)
46+
logger.Debug("GetChangeRequest")
47+
48+
uri := fmt.Sprintf("/hapi/v1/change-requests/%d", prop.ChangeID)
49+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
50+
if err != nil {
51+
return nil, fmt.Errorf("%w: failed to create request: %s", ErrGetChangeRequest, err)
52+
}
53+
54+
var rval ChangeRequest
55+
56+
resp, err := h.Exec(req, &rval)
57+
if err != nil {
58+
return nil, fmt.Errorf("%w: request failed: %s", ErrGetChangeRequest, err)
59+
}
60+
61+
if resp.StatusCode != http.StatusOK {
62+
return nil, fmt.Errorf("%s: %w", ErrGetChangeRequest, h.Error(resp))
63+
}
64+
65+
return &rval, nil
66+
}

pkg/hapi/change_requests_test.go

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package hapi
2+
3+
import (
4+
"context"
5+
"errors"
6+
"net/http"
7+
"net/http/httptest"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func TestGetChangeRequest(t *testing.T) {
15+
tests := map[string]struct {
16+
request GetChangeRequest
17+
responseStatus int
18+
responseBody string
19+
expectedPath string
20+
expectedResponse *ChangeRequest
21+
withError error
22+
}{
23+
"200 OK": {
24+
request: GetChangeRequest{123},
25+
responseStatus: http.StatusOK,
26+
responseBody: `
27+
{
28+
"action": "EDIT",
29+
"changeId": 123,
30+
"edgeHostnames": [
31+
{
32+
"chinaCdn": {
33+
"isChinaCdn": false
34+
},
35+
"dnsZone": "edgekey.net",
36+
"edgeHostnameId": 112233,
37+
"ipVersionBehavior": "IPV6_IPV4_DUALSTACK",
38+
"map": "a;bcd.akamaiedge.net",
39+
"productId": "DSA",
40+
"recordName": "test123",
41+
"securityType": "ENHANCED-TLS",
42+
"serialNumber": 0,
43+
"slotNumber": 1234,
44+
"ttl": 21600,
45+
"useDefaultMap": true,
46+
"useDefaultTtl": true
47+
}
48+
],
49+
"status": "PENDING",
50+
"statusMessage": "File uploaded and awaiting validation",
51+
"statusUpdateDate": "2023-09-04T09:21:38.000+00:00",
52+
"submitDate": "2023-09-04T09:21:38.000+00:00",
53+
"submitter": "nobody",
54+
"submitterEmail": "nobody@nomail-akamai.com"
55+
}
56+
`,
57+
expectedPath: "/hapi/v1/change-requests/123",
58+
expectedResponse: &ChangeRequest{
59+
Action: "EDIT",
60+
ChangeID: 123,
61+
EdgeHostnames: []EdgeHostname{
62+
{
63+
EdgeHostnameID: 112233,
64+
RecordName: "test123",
65+
DNSZone: "edgekey.net",
66+
SecurityType: "ENHANCED-TLS",
67+
UseDefaultTTL: true,
68+
UseDefaultMap: true,
69+
TTL: 21600,
70+
Map: "a;bcd.akamaiedge.net",
71+
SlotNumber: 1234,
72+
IPVersionBehavior: "IPV6_IPV4_DUALSTACK",
73+
Comments: "",
74+
ChinaCDN: ChinaCDN{
75+
IsChinaCDN: false,
76+
},
77+
ProductId: "DSA",
78+
SerialNumber: 0,
79+
},
80+
},
81+
Status: "PENDING",
82+
StatusMessage: "File uploaded and awaiting validation",
83+
StatusUpdateDate: "2023-09-04T09:21:38.000+00:00",
84+
SubmitDate: "2023-09-04T09:21:38.000+00:00",
85+
Submitter: "nobody",
86+
SubmitterEmail: "nobody@nomail-akamai.com",
87+
},
88+
},
89+
"403 Access Denied to Edge Hostname": {
90+
request: GetChangeRequest{234},
91+
responseStatus: http.StatusForbidden,
92+
responseBody: `
93+
{
94+
"type": "/hapi/problems/access-denied-to-edge-hostname",
95+
"title": "Access Denied to Edge Hostname",
96+
"status": 403,
97+
"detail": "You do not have access to this edge hostname",
98+
"instance": "/hapi/error-instances/7a2c1b84-fe90-40f2-8391-aaaaaaaaaa",
99+
"requestInstance": "http://cloud.akamaiapis.net/hapi/open/v1/change-requests/234#aaaaaaa",
100+
"method": "GET",
101+
"requestTime": "2023-09-04T09:26:16.561878149Z",
102+
"errors": []
103+
}`,
104+
expectedPath: "/hapi/v1/change-requests/234",
105+
withError: &Error{
106+
Type: "/hapi/problems/access-denied-to-edge-hostname",
107+
Title: "Access Denied to Edge Hostname",
108+
Status: 403,
109+
Detail: "You do not have access to this edge hostname",
110+
Instance: "/hapi/error-instances/7a2c1b84-fe90-40f2-8391-aaaaaaaaaa",
111+
RequestInstance: "http://cloud.akamaiapis.net/hapi/open/v1/change-requests/234#aaaaaaa",
112+
Method: "GET",
113+
RequestTime: "2023-09-04T09:26:16.561878149Z",
114+
},
115+
},
116+
"500 internal server error": {
117+
request: GetChangeRequest{123},
118+
responseStatus: http.StatusInternalServerError,
119+
responseBody: `
120+
{
121+
"type": "internal_error",
122+
"title": "Internal Server Error",
123+
"detail": "Error deleting activation",
124+
"status": 500
125+
}`,
126+
expectedPath: "/hapi/v1/change-requests/123",
127+
withError: &Error{
128+
Type: "internal_error",
129+
Title: "Internal Server Error",
130+
Detail: "Error deleting activation",
131+
Status: http.StatusInternalServerError,
132+
},
133+
},
134+
}
135+
136+
for name, test := range tests {
137+
t.Run(name, func(t *testing.T) {
138+
mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
139+
assert.Equal(t, test.expectedPath, r.URL.String())
140+
assert.Equal(t, http.MethodGet, r.Method)
141+
w.WriteHeader(test.responseStatus)
142+
_, err := w.Write([]byte(test.responseBody))
143+
assert.NoError(t, err)
144+
}))
145+
client := mockAPIClient(t, mockServer)
146+
result, err := client.GetChangeRequest(context.Background(), test.request)
147+
if test.withError != nil {
148+
assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
149+
return
150+
}
151+
require.NoError(t, err)
152+
assert.Equal(t, test.expectedResponse, result)
153+
})
154+
}
155+
}

pkg/hapi/hapi.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var (
1717
type (
1818
// HAPI is the hapi api interface
1919
HAPI interface {
20+
ChangeRequests
2021
EdgeHostnames
2122
}
2223

pkg/hapi/mocks.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,13 @@ func (m *Mock) UpdateEdgeHostname(ctx context.Context, request UpdateEdgeHostnam
4343

4444
return args.Get(0).(*UpdateEdgeHostnameResponse), nil
4545
}
46+
47+
func (m *Mock) GetChangeRequest(ctx context.Context, req GetChangeRequest) (*ChangeRequest, error) {
48+
args := m.Called(ctx, req)
49+
50+
if args.Error(1) != nil {
51+
return nil, args.Error(1)
52+
}
53+
54+
return args.Get(0).(*ChangeRequest), nil
55+
}

0 commit comments

Comments
 (0)