Skip to content
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
5 changes: 1 addition & 4 deletions fastly/custom_tls_activation.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (c *Client) GetTLSActivation(i *GetTLSActivationInput) (*TLSActivation, err
type CreateTLSActivationInput struct {
ID string `jsonapi:"primary,tls_activation"` // ID value does not need to be set.
Certificate *CustomTLSCertificate `jsonapi:"relation,tls_certificate"` // Only ID of CustomTLSCertificate needs to be set.
Configuration *TLSConfiguration `jsonapi:"relation,tls_configuration"`
Configuration *TLSConfiguration `jsonapi:"relation,tls_configuration,omitempty"`
Domain *TLSDomain `jsonapi:"relation,tls_domain"`
}

Expand All @@ -138,9 +138,6 @@ func (c *Client) CreateTLSActivation(i *CreateTLSActivationInput) (*TLSActivatio
if i.Certificate == nil {
return nil, ErrMissingTLSCertificate
}
if i.Configuration == nil {
return nil, ErrMissingTLSConfiguration
}
if i.Domain == nil {
return nil, ErrMissingTLSDomain
}
Expand Down
8 changes: 0 additions & 8 deletions fastly/custom_tls_activation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,6 @@ func TestClient_CreateTLSActivation_validation(t *testing.T) {
t.Errorf("bad error: %s", err)
}

_, err = testClient.CreateTLSActivation(&CreateTLSActivationInput{
Certificate: &CustomTLSCertificate{ID: "CERTIFICATE_ID"},
Domain: &TLSDomain{ID: "DOMAIN_NAME"},
})
if err != ErrMissingTLSConfiguration {
t.Errorf("bad error: %s", err)
}

_, err = testClient.CreateTLSActivation(&CreateTLSActivationInput{
Certificate: &CustomTLSCertificate{ID: "CERTIFICATE_ID"},
Configuration: &TLSConfiguration{ID: "CONFIGURATION_ID"},
Expand Down
15 changes: 4 additions & 11 deletions fastly/custom_tls_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ type CustomTLSCertificate struct {
Replace bool `jsonapi:"attr,replace"`
SerialNumber string `jsonapi:"attr,serial_number"`
SignatureAlgorithm string `jsonapi:"attr,signature_algorithm"`
TLSDomains []*TLSDomain `jsonapi:"relation,tls_domains"`
Domains []*TLSDomain `jsonapi:"relation,tls_domains"`
CreatedAt *time.Time `jsonapi:"attr,created_at,iso8601"`
UpdatedAt *time.Time `jsonapi:"attr,updated_at,iso8601"`
}

// ListCustomTLSCertificatesInput is used as input to the ListCustomTLSCertificatesInput function.
// ListCustomTLSCertificatesInput is used as input to the Client.ListCustomTLSCertificates function.
type ListCustomTLSCertificatesInput struct {
FilterNotAfter string // Limit the returned certificates to those that expire prior to the specified date in UTC. Accepts parameters: lte (e.g., filter[not_after][lte]=2020-05-05).
FilterTLSDomainsID string // Limit the returned certificates to those that include the specific domain.
Expand Down Expand Up @@ -124,17 +124,14 @@ func (c *Client) GetCustomTLSCertificate(i *GetCustomTLSCertificateInput) (*Cust
type CreateCustomTLSCertificateInput struct {
ID string `jsonapi:"primary,tls_certificate"` // ID value does not need to be set.
CertBlob string `jsonapi:"attr,cert_blob"`
Name string `jsonapi:"attr,name"`
Name string `jsonapi:"attr,name,omitempty"`
}

// CreateCustomTLSCertificate creates a custom TLS certificate.
func (c *Client) CreateCustomTLSCertificate(i *CreateCustomTLSCertificateInput) (*CustomTLSCertificate, error) {
if i.CertBlob == "" {
return nil, ErrMissingCertBlob
}
if i.Name == "" {
return nil, ErrMissingName
}

p := "/tls/certificates"

Expand All @@ -155,7 +152,7 @@ func (c *Client) CreateCustomTLSCertificate(i *CreateCustomTLSCertificateInput)
type UpdateCustomTLSCertificateInput struct {
ID string `jsonapi:"primary,tls_certificate"`
CertBlob string `jsonapi:"attr,cert_blob"`
Name string `jsonapi:"attr,name"`
Name string `jsonapi:"attr,name,omitempty"`
}

// UpdateCustomTLSCertificate replace a certificate with a newly reissued certificate.
Expand All @@ -171,10 +168,6 @@ func (c *Client) UpdateCustomTLSCertificate(i *UpdateCustomTLSCertificateInput)
return nil, ErrMissingCertBlob
}

if i.Name == "" {
return nil, ErrMissingName
}

path := fmt.Sprintf("/tls/certificates/%s", i.ID)
resp, err := c.PatchJSONAPI(path, i, nil)
if err != nil {
Expand Down
27 changes: 6 additions & 21 deletions fastly/custom_tls_certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ func TestClient_CustomTLSCertificate(t *testing.T) {
if cc.ID != gcc.ID {
t.Errorf("bad ID: %q (%q)", cc.ID, gcc.ID)
}
if gcc.TLSDomains == nil {
t.Errorf("TLSDomains should not be nil: %v", cc.TLSDomains)
if gcc.Domains == nil {
t.Errorf("Domains should not be nil: %v", cc.Domains)
}
if len(gcc.TLSDomains) < 1 {
t.Errorf("TLSDomains should not be an empty slice: %v", cc.TLSDomains)
if len(gcc.Domains) < 1 {
t.Errorf("Domains should not be an empty slice: %v", cc.Domains)
}
if cc.TLSDomains[0].ID != gcc.TLSDomains[0].ID {
t.Errorf("bad Domain ID: %q (%q)", cc.TLSDomains[0].ID, gcc.TLSDomains[0].ID)
if cc.Domains[0].ID != gcc.Domains[0].ID {
t.Errorf("bad Domain ID: %q (%q)", cc.Domains[0].ID, gcc.Domains[0].ID)
}

// Update
Expand Down Expand Up @@ -107,13 +107,6 @@ func TestClient_CreateCustomTLSCertificate_validation(t *testing.T) {
t.Fatal(err)
}

_, err = testClient.CreateCustomTLSCertificate(&CreateCustomTLSCertificateInput{
CertBlob: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n",
})
if err != ErrMissingName {
t.Errorf("bad error: %s", err)
}

_, err = testClient.CreateCustomTLSCertificate(&CreateCustomTLSCertificateInput{
Name: "My certificate",
})
Expand Down Expand Up @@ -202,12 +195,4 @@ func TestClient_UpdateCustomTLSCertificate_validation(t *testing.T) {
if err != ErrMissingCertBlob {
t.Errorf("bad error: %s", err)
}

_, err = testClient.UpdateCustomTLSCertificate(&UpdateCustomTLSCertificateInput{
ID: "CERTIFICATE_ID",
CertBlob: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n",
})
if err != ErrMissingName {
t.Errorf("bad error: %s", err)
}
}
92 changes: 92 additions & 0 deletions fastly/custom_tls_domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package fastly

import (
"fmt"
"reflect"
"strconv"

"github.com/google/jsonapi"
)

// ListTLSDomainsInput is used as input to Client.ListTLSDomains.
type ListTLSDomainsInput struct {
// Limit the returned domains to those currently using Fastly to terminate TLS with SNI (that is, domains considered "in use")
FilterInUse *bool
// Limit the returned domains to those listed in the given TLS certificate's SAN list
FilterTLSCertificateID string
// Limit the returned domains to those for a given TLS subscription
FilterTLSSubscriptionID string
// Include related objects
Include string
// Current page
PageNumber int
// Number of records per page
PageSize int
// The order in which to list the results by creation date
Sort string
}

// formatFilters converts user input into query parameters for filtering.
func (l *ListTLSDomainsInput) formatFilters() map[string]string {
result := map[string]string{}
pairings := map[string]interface{}{
"filter[in_use]": l.FilterInUse,
"filter[tls_certificate.id]": l.FilterTLSCertificateID,
"filter[tls_subscriptions.id]": l.FilterTLSSubscriptionID,
"include": l.Include,
"page[number]": l.PageNumber,
"page[size]": l.PageSize,
"sort": l.Sort,
}

for key, value := range pairings {
switch t := value.(type) {
case string:
if t != "" {
result[key] = t
}
case int:
if t != 0 {
result[key] = strconv.Itoa(t)
}
case *bool:
if t != nil {
result[key] = strconv.FormatBool(*t)
}
}
}

return result
}

// ListTLSDomains retrieves a page of TLS domains.
func (c *Client) ListTLSDomains(i *ListTLSDomainsInput) ([]*TLSDomain, error) {
p := "/tls/domains"
filters := &RequestOptions{
Params: i.formatFilters(),
Headers: map[string]string{
"Accept": "application/vnd.api+json", // this is required otherwise the filters don't work
},
}

r, err := c.Get(p, filters)
if err != nil {
return nil, err
}

data, err := jsonapi.UnmarshalManyPayload(r.Body, reflect.TypeOf(new(TLSDomain)))
if err != nil {
return nil, err
}

a := make([]*TLSDomain, len(data))
for i := range data {
typed, ok := data[i].(*TLSDomain)
if !ok {
return nil, fmt.Errorf("unexpected response type: %T", data[i])
}
a[i] = typed
}

return a, nil
}
28 changes: 28 additions & 0 deletions fastly/custom_tls_domain_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package fastly

import (
"testing"
)

func TestClient_ListTLSDomains(t *testing.T) {
t.Parallel()

fixtureBase := "custom_tls_domain/"

var err error

// List
var ldom []*TLSDomain
record(t, fixtureBase+"list", func(c *Client) {
ldom, err = c.ListTLSDomains(&ListTLSDomainsInput{
PageSize: 10,
})
})
if err != nil {
t.Fatal(err)
}
if len(ldom) < 1 {
t.Errorf("bad tls domains: %v", ldom)
}

}
4 changes: 4 additions & 0 deletions fastly/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ var ErrMissingTLSConfiguration = NewFieldError("TLSConfiguration")
// requires a "TLSDomain" key, but one was not set.
var ErrMissingTLSDomain = NewFieldError("TLSDomain")

// ErrCommonNameNotInDomains is an error that is returned when an input struct
// requires that the domain in "CommonName" is also in "Domains"
var ErrCommonNameNotInDomains = NewFieldError("CommonName").Message("CommonName must be in Domains")

// ErrMissingTo is an error that is returned when an input struct
// requires a "To" key, but one was not set.
var ErrMissingTo = NewFieldError("To")
Expand Down
43 changes: 43 additions & 0 deletions fastly/fixtures/custom_tls_domain/list.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
version: 1
interactions:
- request:
body: ""
form: {}
headers:
Accept:
- application/vnd.api+json
User-Agent:
- FastlyGo/2.1.0 (+github.com/fastly/go-fastly; go1.15.4)
url: https://api.fastly.com/tls/domains?page%5Bsize%5D=10
method: GET
response:
body: '{"data":[{"id":"a-real-tld.example","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"6RltCYkOfFfzPVitOyLCnV","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"along-with.localhost","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"64JrNBzdRRzkefaHXLvg3e","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"also-real.invalid","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"2TMKp6R51PW2VMJKiWW3eO","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"and-this-is-real.test","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"1f44cer2CdblNR2WVgfGnU","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"dummy.test","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"1jBkBddyG0bcMlaLp6i1Ur","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"first.example","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"5tjYkVLnZKc4yscdDQ4lzz","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"hello-world.example","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"4RWSfyNCwPAfUIWqtTKg2N","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"pagination-pad1.test","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"7d34I8GLEja5zVq4gCq294","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"pagination-pad2.test","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"77MQa3kQ1Ke3BodIuEdr3Y","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}},{"id":"pagination-pad3.test","type":"tls_domain","relationships":{"tls_activations":{"data":[]},"tls_certificates":{"data":[{"id":"7eQZD0jAsebDtWAWphdu3p","type":"tls_certificate"}]},"tls_subscriptions":{"data":[]}}}],"links":{"self":"https://api.fastly.com/tls/domains?page%5Bnumber%5D=1\u0026page%5Bsize%5D=10","first":"https://api.fastly.com/tls/domains?page%5Bnumber%5D=1\u0026page%5Bsize%5D=10","prev":null,"next":"https://api.fastly.com/tls/domains?page%5Bnumber%5D=2\u0026page%5Bsize%5D=10","last":"https://api.fastly.com/tls/domains?page%5Bnumber%5D=2\u0026page%5Bsize%5D=10"},"meta":{"record_count":12,"current_page":1,"per_page":10,"total_pages":2}}'
headers:
Accept-Ranges:
- bytes
Content-Length:
- "2599"
Content-Type:
- application/vnd.api+json
Date:
- Mon, 25 Jan 2021 15:02:43 GMT
Status:
- 200 OK
Strict-Transport-Security:
- max-age=31536000
Via:
- 1.1 varnish, 1.1 varnish
X-Cache:
- MISS, MISS
X-Cache-Hits:
- 0, 0
X-Content-Type-Options:
- nosniff
X-Served-By:
- cache-control-slwdc9035-CONTROL-SLWDC, cache-lcy19235-LCY
X-Timer:
- S1611586963.753130,VS0,VE572
status: 200 OK
code: 200
duration: ""
37 changes: 37 additions & 0 deletions fastly/fixtures/tls_subscription/cleanup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
version: 1
interactions:
- request:
body: ""
form: {}
headers:
User-Agent:
- FastlyGo/2.1.0 (+github.com/fastly/go-fastly; go1.15.6)
url: https://api.fastly.com/tls/subscriptions/SUBSCRIPTION_ID
method: DELETE
response:
body: ""
headers:
Accept-Ranges:
- bytes
Date:
- Mon, 25 Jan 2021 18:00:06 GMT
Status:
- 204 No Content
Strict-Transport-Security:
- max-age=31536000
Via:
- 1.1 varnish, 1.1 varnish
X-Cache:
- MISS, MISS
X-Cache-Hits:
- 0, 0
X-Content-Type-Options:
- nosniff
X-Served-By:
- cache-control-slwdc9037-CONTROL-SLWDC, cache-lcy19251-LCY
X-Timer:
- S1611597606.927024,VS0,VE145
status: 204 No Content
code: 204
duration: ""
46 changes: 46 additions & 0 deletions fastly/fixtures/tls_subscription/create.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
version: 1
interactions:
- request:
body: |
{"data":{"type":"tls_subscription","relationships":{"tls_domain":{"data":[{"type":"tls_domain"}]}}},"included":[{"type":"tls_domain","attributes":{"type":""}}]}
form: {}
headers:
Accept:
- application/vnd.api+json
Content-Type:
- application/vnd.api+json
User-Agent:
- FastlyGo/2.1.0 (+github.com/fastly/go-fastly; go1.15.6)
url: https://api.fastly.com/tls/subscriptions
method: POST
response:
body: '{"data":{"id":"SUBSCRIPTION_ID","type":"tls_subscription","attributes":{"certificate_authority":"lets-encrypt","created_at":"2021-01-25T17:11:41.000Z","state":"pending","updated_at":"2021-01-25T17:11:41.000Z"},"relationships":{"tls_authorizations":{"data":[{"id":"AUTHORIZATION_ID","type":"tls_authorization"}]},"tls_certificates":{"data":[]},"tls_domains":{"data":[{"id":"DOMAIN_NAME","type":"tls_domain"}]},"common_name":{"data":{"id":"DOMAIN_NAME","type":"tls_domain"}},"tls_configuration":{"data":{"id":"CONFIGURATION_ID","type":"tls_configuration"}}}},"included":[{"id":"AUTHORIZATION_ID","type":"tls_authorization","attributes":{"challenges":[{"type":"managed-dns","record_type":"CNAME","record_name":"CNAME_CHALLENGE_DOMAIN_NAME","values":["CNAME_CHALLENGE_DOMAIN_NAME_TARGET"]},{"type":"managed-http-cname","record_type":"CNAME","record_name":"DOMAIN_NAME","values":["j.sni.global.fastly.net"]},{"type":"managed-http-a","record_type":"A","record_name":"DOMAIN_NAME","values":["151.101.2.132","151.101.66.132","151.101.130.132","151.101.194.132"]}],"created_at":"2021-01-25T17:11:41.000Z","state":"pending","updated_at":"2021-01-25T17:11:41.000Z","warnings":null},"relationships":{"tls_domain":{"data":{"id":"DOMAIN_NAME","type":"tls_domain"}}}}]}'
headers:
Accept-Ranges:
- bytes
Content-Length:
- "1322"
Content-Type:
- application/vnd.api+json
Date:
- Mon, 25 Jan 2021 17:11:41 GMT
Status:
- 201 Created
Strict-Transport-Security:
- max-age=31536000
Via:
- 1.1 varnish, 1.1 varnish
X-Cache:
- MISS, MISS
X-Cache-Hits:
- 0, 0
X-Content-Type-Options:
- nosniff
X-Served-By:
- cache-control-slwdc9035-CONTROL-SLWDC, cache-lcy19271-LCY
X-Timer:
- S1611594701.776296,VS0,VE800
status: 201 Created
code: 201
duration: ""
Loading