Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Secret Store API support #367

Merged
merged 2 commits into from
Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions fastly/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package fastly

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"

"github.com/google/jsonapi"
)
Expand Down Expand Up @@ -165,6 +167,10 @@ var ErrMissingNumber = NewFieldError("Number")
// requires a "PoolID" key, but one was not set.
var ErrMissingPoolID = NewFieldError("PoolID")

// ErrMissingSecret is an error that is returned when an input struct
// requires a "Secret" key, but one was not set.
var ErrMissingSecret = NewFieldError("Secret")

// ErrMissingServer is an error that is returned when an input struct
// requires a "Server" key, but one was not set.
var ErrMissingServer = NewFieldError("Server")
Expand Down Expand Up @@ -318,12 +324,31 @@ func NewHTTPError(resp *http.Response) *HTTPError {
return &e
}

// If this is a jsonapi response, decode it accordingly
if resp.Header.Get("Content-Type") == jsonapi.MediaType {
switch resp.Header.Get("Content-Type") {
case jsonapi.MediaType:
// If this is a jsonapi response, decode it accordingly
if err := decodeBodyMap(resp.Body, &e); err != nil {
panic(err)
}
} else {

case "application/problem+json":
// Response is a "problem detail" as defined in RFC 7807.
var problemDetail struct {
URL string `json:"type,omitempty"` // URL to a human-readable document describing this specific error condition
Title string `json:"title,omitempty"` // A short name for the error type, which remains constant from occurrence to occurrence
Status int `json:"status"` // HTTP status code
Detail string `json:"detail,omitempty"` // A human-readable description of the specific error, aiming to help the user correct the problem
}
if err := json.NewDecoder(resp.Body).Decode(&problemDetail); err != nil {
panic(err)
dgryski marked this conversation as resolved.
Show resolved Hide resolved
}
e.Errors = append(e.Errors, &ErrorObject{
Title: problemDetail.Title,
Detail: problemDetail.Detail,
Status: strconv.Itoa(problemDetail.Status),
})

default:
var lerr *legacyError
decodeBodyMap(resp.Body, &lerr)
if lerr != nil {
Expand Down
40 changes: 36 additions & 4 deletions fastly/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ func TestNewHTTPError(t *testing.T) {
Detail: nope
`)
if e.Error() != expected {
t.Errorf("expected \n\n%s\n\n to be \n\n%s\n\n", e.Error(), expected)
t.Errorf("expected \n\n%q\n\n to be \n\n%q\n\n", e.Error(), expected)
}
if e.String() != expected {
t.Errorf("expected \n\n%s\n\n to be \n\n%s\n\n", e.String(), expected)
t.Errorf("expected \n\n%q\n\n to be \n\n%q\n\n", e.String(), expected)
}

if !e.IsNotFound() {
Expand Down Expand Up @@ -64,10 +64,42 @@ func TestNewHTTPError(t *testing.T) {
Detail: That resource does not exist
`)
if e.Error() != expected {
t.Errorf("expected \n\n%s\n\n to be \n\n%s\n\n", e.Error(), expected)
t.Errorf("expected \n\n%q\n\n to be \n\n%q\n\n", e.Error(), expected)
}
if e.String() != expected {
t.Errorf("expected \n\n%s\n\n to be \n\n%s\n\n", e.String(), expected)
t.Errorf("expected \n\n%q\n\n to be \n\n%q\n\n", e.String(), expected)
}

if !e.IsNotFound() {
t.Error("not not found")
}
})

t.Run("problem detail", func(t *testing.T) {
resp := &http.Response{
StatusCode: 404,
Header: http.Header(map[string][]string{"Content-Type": {"application/problem+json"}}),
Body: io.NopCloser(bytes.NewBufferString(
`{"title": "Error", "detail": "this was an error", "status": 404}`,
)),
}
e := NewHTTPError(resp)

if e.StatusCode != 404 {
t.Errorf("expected %d to be %d", e.StatusCode, 404)
}

expected := strings.TrimSpace(`
404 - Not Found:

Title: Error
Detail: this was an error
`)
if e.Error() != expected {
t.Errorf("expected \n\n%q\n\n to be \n\n%q\n\n", e.Error(), expected)
}
if e.String() != expected {
t.Errorf("expected \n\n%q\n\n to be \n\n%q\n\n", e.String(), expected)
}

if !e.IsNotFound() {
Expand Down
40 changes: 40 additions & 0 deletions fastly/fixtures/secret_store/TestClient_CreateSecret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
version: 1
interactions:
- request:
body: |
{"name":"TestClient_CreateSecret","secret":"c2VjcmV0dW0gc2VydmFyZQ=="}
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- FastlyGo/6.5.2 (+github.com/fastly/go-fastly; go1.19.1)
url: https://api.fastly.com/resources/stores/secret/YsFsqmjSDvg52GhvBeIbqw/secrets
method: POST
response:
body: |
{
"name": "TestClient_CreateSecret",
"digest": "NLdzRaW6NfFy6RS3yPUVk7ZtK2oiIeCRQVN0sXR2564="
}
headers:
Access-Control-Allow-Headers:
- Content-Type, Fastly-Key
Access-Control-Allow-Methods:
- PUT, POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:
- '*'
Content-Length:
- "100"
Content-Type:
- application/json
Date:
- Fri, 23 Sep 2022 16:09:02 GMT
Fastly-Trace-Id:
- 73bYYj5weXQGItmRssm4Qm
status: 200 OK
code: 200
duration: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
version: 1
interactions:
- request:
body: |
{"name":"TestClient_CreateSecret-00"}
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- FastlyGo/6.5.2 (+github.com/fastly/go-fastly; go1.19.1)
url: https://api.fastly.com/resources/stores/secret
method: POST
response:
body: |
{
"id": "YsFsqmjSDvg52GhvBeIbqw",
"name": "TestClient_CreateSecret-00"
}
headers:
Access-Control-Allow-Headers:
- Content-Type, Fastly-Key
Access-Control-Allow-Methods:
- PUT, POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:
- '*'
Content-Length:
- "77"
Content-Type:
- application/json
Date:
- Fri, 23 Sep 2022 16:09:02 GMT
Fastly-Trace-Id:
- lubT76EDRYTxymsIx3TJGg
status: 201 Created
code: 201
duration: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
version: 1
interactions:
- request:
body: ""
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- FastlyGo/6.5.2 (+github.com/fastly/go-fastly; go1.19.1)
url: https://api.fastly.com/resources/stores/secret/YsFsqmjSDvg52GhvBeIbqw
method: DELETE
response:
body: ""
headers:
Access-Control-Allow-Headers:
- Content-Type, Fastly-Key
Access-Control-Allow-Methods:
- PUT, POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:
- '*'
Date:
- Fri, 23 Sep 2022 16:09:02 GMT
Fastly-Trace-Id:
- eProXX1wiDOdHLjqcvCxSq
status: 204 No Content
code: 204
duration: ""
40 changes: 40 additions & 0 deletions fastly/fixtures/secret_store/TestClient_CreateSecretStore.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
version: 1
interactions:
- request:
body: |
{"name":"TestClient_CreateSecretStore"}
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- FastlyGo/6.5.2 (+github.com/fastly/go-fastly; go1.19.1)
url: https://api.fastly.com/resources/stores/secret
method: POST
response:
body: |
{
"id": "qIbYRt3b3mzvSTFVONM2uo",
"name": "TestClient_CreateSecretStore"
}
headers:
Access-Control-Allow-Headers:
- Content-Type, Fastly-Key
Access-Control-Allow-Methods:
- PUT, POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:
- '*'
Content-Length:
- "79"
Content-Type:
- application/json
Date:
- Fri, 23 Sep 2022 16:09:02 GMT
Fastly-Trace-Id:
- AFNpFkYCDNQu7cj4AJCEzL
status: 201 Created
code: 201
duration: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
version: 1
interactions:
- request:
body: ""
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- FastlyGo/6.5.2 (+github.com/fastly/go-fastly; go1.19.1)
url: https://api.fastly.com/resources/stores/secret/qIbYRt3b3mzvSTFVONM2uo
method: DELETE
response:
body: ""
headers:
Access-Control-Allow-Headers:
- Content-Type, Fastly-Key
Access-Control-Allow-Methods:
- PUT, POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:
- '*'
Date:
- Fri, 23 Sep 2022 16:09:02 GMT
Fastly-Trace-Id:
- ZbnCNVaCnA5VNvYp49wS5y
status: 204 No Content
code: 204
duration: ""
31 changes: 31 additions & 0 deletions fastly/fixtures/secret_store/TestClient_DeleteSecret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
version: 1
interactions:
- request:
body: ""
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- FastlyGo/6.5.2 (+github.com/fastly/go-fastly; go1.19.1)
url: https://api.fastly.com/resources/stores/secret/DwDUfumJxzsKYVBhXNUT4m/secrets/TestClient_DeleteSecret
method: DELETE
response:
body: ""
headers:
Access-Control-Allow-Headers:
- Content-Type, Fastly-Key
Access-Control-Allow-Methods:
- PUT, POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:
- '*'
Date:
- Fri, 23 Sep 2022 16:09:02 GMT
Fastly-Trace-Id:
- IGREzUCNGXsWnFKbh38kCk
status: 204 No Content
code: 204
duration: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
version: 1
interactions:
- request:
body: |
{"name":"TestClient_DeleteSecret","secret":"c2VjcmV0dW0gc2VydmFyZQ=="}
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- FastlyGo/6.5.2 (+github.com/fastly/go-fastly; go1.19.1)
url: https://api.fastly.com/resources/stores/secret/DwDUfumJxzsKYVBhXNUT4m/secrets
method: POST
response:
body: |
{
"name": "TestClient_DeleteSecret",
"digest": "EjvFk6TSfhAMXrLFzCLsAJYqLs8BwBM5PSMa7rJCNBk="
}
headers:
Access-Control-Allow-Headers:
- Content-Type, Fastly-Key
Access-Control-Allow-Methods:
- PUT, POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:
- '*'
Content-Length:
- "100"
Content-Type:
- application/json
Date:
- Fri, 23 Sep 2022 16:09:02 GMT
Fastly-Trace-Id:
- diMVjRZ4rKGIheD64pCLd2
status: 200 OK
code: 200
duration: ""
Loading