From 3139eed29018690a7cdc5655f470f7d32ecb053f Mon Sep 17 00:00:00 2001 From: Ivan Ilichev Date: Fri, 1 Mar 2019 11:58:49 -0500 Subject: [PATCH 1/2] CDN: Add support for configuring custom subdomains in Spaces CDN. cc: @sunny-b, @mauricio --- CHANGELOG.md | 4 ++ cdn.go | 45 ++++++++++++----- cdn_test.go | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 170 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 978093d8..db8d1b86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [v1.7.5] - 2019-02-08 + +- #207 Add support for custom subdomains for Spaces CDN [beta] - @xornivore + ## [v1.7.4] - 2019-02-08 - #202 Allow tagging volumes - @mchitten diff --git a/cdn.go b/cdn.go index 217d90e5..2e8f475a 100644 --- a/cdn.go +++ b/cdn.go @@ -14,7 +14,8 @@ type CDNService interface { List(context.Context, *ListOptions) ([]CDN, *Response, error) Get(context.Context, string) (*CDN, *Response, error) Create(context.Context, *CDNCreateRequest) (*CDN, *Response, error) - UpdateTTL(context.Context, string, *CDNUpdateRequest) (*CDN, *Response, error) + UpdateTTL(context.Context, string, *CDNUpdateTTLRequest) (*CDN, *Response, error) + UpdateCustomDomain(context.Context, string, *CDNUpdateCustomDomainRequest) (*CDN, *Response, error) FlushCache(context.Context, string, *CDNFlushCacheRequest) (*Response, error) Delete(context.Context, string) (*Response, error) } @@ -29,11 +30,13 @@ var _ CDNService = &CDNServiceOp{} // CDN represents a DigitalOcean CDN type CDN struct { - ID string `json:"id"` - Origin string `json:"origin"` - Endpoint string `json:"endpoint"` - CreatedAt time.Time `json:"created_at"` - TTL uint32 `json:"ttl"` + ID string `json:"id"` + Origin string `json:"origin"` + Endpoint string `json:"endpoint"` + CreatedAt time.Time `json:"created_at"` + TTL uint32 `json:"ttl"` + CertificateID string `json:"certificate_id,omitempty"` + CustomDomain string `json:"custom_domain,omitempty"` } // CDNRoot represents a response from the DigitalOcean API @@ -48,15 +51,23 @@ type cdnsRoot struct { // CDNCreateRequest represents a request to create a CDN. type CDNCreateRequest struct { - Origin string `json:"origin"` - TTL uint32 `json:"ttl"` + Origin string `json:"origin"` + TTL uint32 `json:"ttl"` + CustomDomain string `json:"custom_domain,omitempty"` + CertificateID string `json:"certificate_id,omitempty"` } -// CDNUpdateRequest represents a request to update the ttl of a CDN. -type CDNUpdateRequest struct { +// CDNUpdateTTLRequest represents a request to update the ttl of a CDN. +type CDNUpdateTTLRequest struct { TTL uint32 `json:"ttl"` } +// CDNUpdateCustomDomainRequest represents a request to update the custom domain of a CDN. +type CDNUpdateCustomDomainRequest struct { + CustomDomain string `json:"custom_domain"` + CertificateID string `json:"certificate_id"` +} + // CDNFlushCacheRequest represents a request to flush cache of a CDN. type CDNFlushCacheRequest struct { Files []string `json:"files"` @@ -128,8 +139,17 @@ func (c CDNServiceOp) Create(ctx context.Context, createRequest *CDNCreateReques return root.Endpoint, resp, err } -// UpdateTTL updates the ttl of individual CDN -func (c CDNServiceOp) UpdateTTL(ctx context.Context, id string, updateRequest *CDNUpdateRequest) (*CDN, *Response, error) { +// UpdateTTL updates the ttl of an individual CDN +func (c CDNServiceOp) UpdateTTL(ctx context.Context, id string, updateRequest *CDNUpdateTTLRequest) (*CDN, *Response, error) { + return c.update(ctx, id, updateRequest) +} + +// UpdateCustomDomain sets or removes the custom domain of an individual CDN +func (c CDNServiceOp) UpdateCustomDomain(ctx context.Context, id string, updateRequest *CDNUpdateCustomDomainRequest) (*CDN, *Response, error) { + return c.update(ctx, id, updateRequest) +} + +func (c CDNServiceOp) update(ctx context.Context, id string, updateRequest interface{}) (*CDN, *Response, error) { if updateRequest == nil { return nil, nil, NewArgError("updateRequest", "cannot be nil") } @@ -137,7 +157,6 @@ func (c CDNServiceOp) UpdateTTL(ctx context.Context, id string, updateRequest *C if len(id) == 0 { return nil, nil, NewArgError("id", "cannot be an empty string") } - path := fmt.Sprintf("%s/%s", cdnBasePath, id) req, err := c.client.NewRequest(ctx, http.MethodPut, path, updateRequest) diff --git a/cdn_test.go b/cdn_test.go index 318962bd..74812aac 100644 --- a/cdn_test.go +++ b/cdn_test.go @@ -221,6 +221,54 @@ func TestCDN_CreateCDN(t *testing.T) { } } +func TestCDN_CreateCustomDomainCDN(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/v2/cdn/endpoints", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPost) + fmt.Fprint( + w, + `{ + "endpoint": { + "id": "12345", + "origin": "my-space.nyc3.digitaloceanspaces.com", + "endpoint": "my-space.nyc3.cdn.digitaloceanspaces.com", + "ttl": 3600, + "created_at": "2012-10-02T15:00:01.05Z", + "custom_domain": "assets.myacmecorp.com", + "certificate_id": "a20489cc-d278-48d2-8e10-45d42a312451" + } + }`, + ) + }) + + req := &CDNCreateRequest{ + Origin: "my-space.nyc3.digitaloceanspaces.com", + TTL: 3600, + CustomDomain: "assets.myacmecorp.com", + CertificateID: "a20489cc-d278-48d2-8e10-45d42a312451", + } + cdn, _, err := client.CDNs.Create(ctx, req) + if err != nil { + t.Errorf("CDNs.Create returned error: %v", err) + } + + expected := &CDN{ + ID: "12345", + Origin: "my-space.nyc3.digitaloceanspaces.com", + Endpoint: "my-space.nyc3.cdn.digitaloceanspaces.com", + TTL: 3600, + CustomDomain: "assets.myacmecorp.com", + CertificateID: "a20489cc-d278-48d2-8e10-45d42a312451", + CreatedAt: time.Date(2012, 10, 02, 15, 00, 01, 50000000, time.UTC), + } + + if !reflect.DeepEqual(cdn, expected) { + t.Errorf("CDNs.Create returned %+v, expected %+v", cdn, expected) + } +} + func TestCDN_DeleteCDN(t *testing.T) { setup() defer teardown() @@ -255,7 +303,7 @@ func TestCDN_UpdateTTLCDN(t *testing.T) { ) }) - req := &CDNUpdateRequest{TTL: 60} + req := &CDNUpdateTTLRequest{TTL: 60} cdn, _, err := client.CDNs.UpdateTTL(ctx, "12345", req) if err != nil { t.Errorf("CDNs.UpdateTTL returned error: %v", err) @@ -274,6 +322,91 @@ func TestCDN_UpdateTTLCDN(t *testing.T) { } } +func TestCDN_UpdateAddCustomDomainCDN(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/v2/cdn/endpoints/12345", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPut) + fmt.Fprint( + w, + `{ + "endpoint": { + "id": "12345", + "origin": "my-space.nyc3.digitaloceanspaces.com", + "endpoint": "my-space.nyc3.cdn.digitaloceanspaces.com", + "ttl": 60, + "created_at": "2012-10-02T15:00:01.05Z", + "custom_domain": "assets.myacmecorp.com", + "certificate_id": "a20489cc-d278-48d2-8e10-45d42a312451" + } + }`, + ) + }) + + req := &CDNUpdateCustomDomainRequest{ + CustomDomain: "assets.myacmecorp.com", + CertificateID: "a20489cc-d278-48d2-8e10-45d42a312451", + } + cdn, _, err := client.CDNs.UpdateCustomDomain(ctx, "12345", req) + if err != nil { + t.Errorf("CDNs.UpdateTTL returned error: %v", err) + } + + expected := &CDN{ + ID: "12345", + Origin: "my-space.nyc3.digitaloceanspaces.com", + Endpoint: "my-space.nyc3.cdn.digitaloceanspaces.com", + CustomDomain: "assets.myacmecorp.com", + CertificateID: "a20489cc-d278-48d2-8e10-45d42a312451", + TTL: 60, + CreatedAt: time.Date(2012, 10, 02, 15, 00, 01, 50000000, time.UTC), + } + + if !reflect.DeepEqual(cdn, expected) { + t.Errorf("CDNs.UpdateTTL returned %+v, expected %+v", cdn, expected) + } +} + +func TestCDN_UpdateRemoveCustomDomainCDN(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/v2/cdn/endpoints/12345", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPut) + fmt.Fprint( + w, + `{ + "endpoint": { + "id": "12345", + "origin": "my-space.nyc3.digitaloceanspaces.com", + "endpoint": "my-space.nyc3.cdn.digitaloceanspaces.com", + "ttl": 60, + "created_at": "2012-10-02T15:00:01.05Z" + } + }`, + ) + }) + + req := &CDNUpdateCustomDomainRequest{} + cdn, _, err := client.CDNs.UpdateCustomDomain(ctx, "12345", req) + if err != nil { + t.Errorf("CDNs.UpdateTTL returned error: %v", err) + } + + expected := &CDN{ + ID: "12345", + Origin: "my-space.nyc3.digitaloceanspaces.com", + Endpoint: "my-space.nyc3.cdn.digitaloceanspaces.com", + TTL: 60, + CreatedAt: time.Date(2012, 10, 02, 15, 00, 01, 50000000, time.UTC), + } + + if !reflect.DeepEqual(cdn, expected) { + t.Errorf("CDNs.UpdateTTL returned %+v, expected %+v", cdn, expected) + } +} + func TestCDN_FluchCacheCDN(t *testing.T) { setup() defer teardown() From 236f43e253a32ec8d5fb3d95b19d9c8bd9d340c8 Mon Sep 17 00:00:00 2001 From: Ivan Ilichev Date: Fri, 1 Mar 2019 16:00:05 -0500 Subject: [PATCH 2/2] Update version to v1.7.5 --- godo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/godo.go b/godo.go index f418a6d4..95e3c7ec 100644 --- a/godo.go +++ b/godo.go @@ -17,7 +17,7 @@ import ( ) const ( - libraryVersion = "1.7.4" + libraryVersion = "1.7.5" defaultBaseURL = "https://api.digitalocean.com/" userAgent = "godo/" + libraryVersion mediaType = "application/json"