Skip to content

Commit

Permalink
Add Secret Store API support (#367)
Browse files Browse the repository at this point in the history
Secret Store is currently part of a beta release.

https://developer.fastly.com/reference/api/secret-store/
  • Loading branch information
awilliams-fastly authored Oct 5, 2022
1 parent 70079f1 commit fe76cf1
Show file tree
Hide file tree
Showing 41 changed files with 2,266 additions and 7 deletions.
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)
}
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

0 comments on commit fe76cf1

Please sign in to comment.