From eb2f4b20aa7028abc1e8bbc8b8b1223f8d38b207 Mon Sep 17 00:00:00 2001 From: Trent Rosenbaum Date: Thu, 11 Apr 2019 16:02:18 +0100 Subject: [PATCH] issues/204 - Updates the cdn and cdn_tests to allow cdn creation with origin and ttl. --- digitalocean/resource_digitalocean_cdn.go | 88 ++++++++++- .../resource_digitalocean_cdn_test.go | 139 +++++++++++++++++- 2 files changed, 224 insertions(+), 3 deletions(-) diff --git a/digitalocean/resource_digitalocean_cdn.go b/digitalocean/resource_digitalocean_cdn.go index 8b6eb9fc..b07f548f 100644 --- a/digitalocean/resource_digitalocean_cdn.go +++ b/digitalocean/resource_digitalocean_cdn.go @@ -1,6 +1,11 @@ package digitalocean import ( + "context" + "fmt" + "log" + + "github.com/digitalocean/godo" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" ) @@ -26,6 +31,7 @@ func resourceDigitalOceanCDN() *schema.Resource { "ttl": { Type: schema.TypeInt, Optional: true, + Computed: true, Description: "The amount of time the content is cached in the CDN", }, "certificate_id": { @@ -55,23 +61,101 @@ func resourceDigitalOceanCDN() *schema.Resource { func resourceDigitalOceanCDNCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*CombinedConfig).godoClient() - return nil + cdnRequest := &godo.CDNCreateRequest{ + Origin: d.Get("origin").(string), + } + + if v, ok := d.GetOk("ttl"); ok { + cdnRequest.TTL = uint32(v.(int)) + } + + if v, ok := d.GetOk("custom_domain"); ok { + cdnRequest.CustomDomain = v.(string) + } + + if v, ok := d.GetOk("certificate_id"); ok { + cdnRequest.CertificateID = v.(string) + } + + cdn, _, err := client.CDNs.Create(context.Background(), cdnRequest) + if err != nil { + return fmt.Errorf("Error creating CDN: %s", err) + } + + d.SetId(cdn.ID) + log.Printf("CDN created with ID: %s", d.Id()) + + log.Printf("The state of CDN: %+v", cdn) + + return resourceDigitalOceanCDNRead(d, meta) } func resourceDigitalOceanCDNRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*CombinedConfig).godoClient() + cdn, resp, err := client.CDNs.Get(context.Background(), d.Id()) + + if err != nil { + if resp != nil && resp.StatusCode == 404 { + d.SetId("") + } + return fmt.Errorf("Error reading CDN: %s", err) + } + + d.SetId(cdn.ID) + d.Set("origin", cdn.Origin) + d.Set("ttl", cdn.TTL) + d.Set("endpoint", cdn.Endpoint) + d.Set("created_at", cdn.CreatedAt) + d.Set("custom_domain", cdn.CustomDomain) + d.Set("certificate_id", cdn.CertificateID) return nil } func resourceDigitalOceanCDNUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*CombinedConfig).godoClient() - return nil + d.Partial(true) + + if d.HasChange("ttl") { + d.SetPartial("ttl") + ttlUpdateRequest := &godo.CDNUpdateTTLRequest{ + TTL: uint32(d.Get("ttl").(int)), + } + _, _, err := client.CDNs.UpdateTTL(context.Background(), d.Id(), ttlUpdateRequest) + + if err != nil { + return fmt.Errorf("Error updating CDN TTL: %s", err) + } + } + + if d.HasChange("certificate_id") || d.HasChange("custom_domain") { + d.SetPartial("custom_domain_and_certificate_id") + cdUpdateRequest := &godo.CDNUpdateCustomDomainRequest{ + CustomDomain: d.Get("certificate_id").(string), + CertificateID: d.Get("custom_domain").(string), + } + + _, _, err := client.CDNs.UpdateCustomDomain(context.Background(), d.Id(), cdUpdateRequest) + + if err != nil { + return fmt.Errorf("Error updating CDN custom domain: %s", err) + } + } + + d.Partial(false) + return resourceDigitalOceanCDNRead(d, meta) } func resourceDigitalOceanCDNDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*CombinedConfig).godoClient() + _, err := client.CDNs.Delete(context.Background(), d.Id()) + if err != nil { + return fmt.Errorf("Error deleting CDN: %s", err) + } + + d.SetId("") + return nil } diff --git a/digitalocean/resource_digitalocean_cdn_test.go b/digitalocean/resource_digitalocean_cdn_test.go index 477e43ee..dcf79a79 100644 --- a/digitalocean/resource_digitalocean_cdn_test.go +++ b/digitalocean/resource_digitalocean_cdn_test.go @@ -1,6 +1,7 @@ package digitalocean import ( + "context" "fmt" "testing" @@ -9,8 +10,16 @@ import ( "github.com/hashicorp/terraform/terraform" ) +// func init() { +// resource.AddTestSweepers("digitalocean_cdn", &resource.Sweeper{ +// Name: "digitalocean_cdn", +// F: testSweepCertificate, +// }) + +// } + func TestAccDigitalOceanCDN_Basic(t *testing.T) { - digitalOceanBucketName := fmt.Sprintf("tf-test-bucket-%d", acctest.RandInt()) + digitalOceanBucketName := fmt.Sprintf("tf-cdn-test-bucket-%d", acctest.RandInt()) cdnConfig := fmt.Sprintf(testAccCheckDigitalOceanCDNConfig_basic, digitalOceanBucketName) resource.Test(t, resource.TestCase{ @@ -31,14 +40,97 @@ func TestAccDigitalOceanCDN_Basic(t *testing.T) { }) } +func TestAccDigitalOceanCDN_withTTL(t *testing.T) { + digitalOceanBucketName := fmt.Sprintf("tf-cdn-test-bucket-%d", acctest.RandInt()) + cdnConfig := fmt.Sprintf(testAccCheckDigitalOceanCDNConfig_withTTL, digitalOceanBucketName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDigitalOceanCDNDestroy, + Steps: []resource.TestStep{ + { + Config: cdnConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanCDNExists("digitalocean_cdn.foobar"), + resource.TestCheckResourceAttr( + "digitalocean_cdn.foobar", "origin", digitalOceanBucketName+".ams3.digitaloceanspaces.com"), + resource.TestCheckResourceAttr("digitalocean_cdn.foobar", "ttl", "1800"), + ), + }, + }, + }) +} + +// func TestAccDigitalOceanCDN_withCustomDomain(t *testing.T) { + +// rInt := acctest.RandInt() +// privateKeyMaterial, leafCertMaterial, certChainMaterial := generateTestCertMaterial(t) +// //domainName := fmt.Sprintf("trenttest%d.com", rInt) +// domainName := "trenttest1.com" +// bucketName := fmt.Sprintf("tf-cdn-test-bucket-%d", rInt) + +// cdnConfig := testAccCheckDigitalOceanCDNConfig_withDomain(rInt, privateKeyMaterial, leafCertMaterial, certChainMaterial, domainName, bucketName) + +// resource.Test(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// Providers: testAccProviders, +// CheckDestroy: testAccCheckDigitalOceanCDNDestroy, +// Steps: []resource.TestStep{ +// { +// Config: cdnConfig, +// Check: resource.ComposeTestCheckFunc( +// testAccCheckDigitalOceanCDNExists("digitalocean_cdn.mycdn"), +// resource.TestCheckResourceAttr( +// "digitalocean_cdn.mycdn", "origin", bucketName+".ams3.digitaloceanspaces.com"), +// resource.TestCheckResourceAttr("digitalocean_cdn.mycdn", "ttl", "3600"), +// ), +// }, +// }, +// }) +// } + func testAccCheckDigitalOceanCDNDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*CombinedConfig).godoClient() + for _, rs := range s.RootModule().Resources { + + if rs.Type != "digitalocean_cdn" { + continue + } + + _, _, err := client.CDNs.Get(context.Background(), rs.Primary.ID) + if err == nil { + return fmt.Errorf("CDN resource still exists") + } + } + return nil } func testAccCheckDigitalOceanCDNExists(resource string) resource.TestCheckFunc { return func(s *terraform.State) error { + client := testAccProvider.Meta().(*CombinedConfig).godoClient() + + rs, ok := s.RootModule().Resources[resource] + + if !ok { + return fmt.Errorf("Not found: %s", resource) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID set for resource: %s", resource) + } + + foundCDN, _, err := client.CDNs.Get(context.Background(), rs.Primary.ID) + + if err != nil { + return err + } + + if foundCDN.ID != rs.Primary.ID { + return fmt.Errorf("Resource not found: %s : %s", resource, rs.Primary.ID) + } return nil } @@ -54,3 +146,48 @@ resource "digitalocean_spaces_bucket" "bucket" { resource "digitalocean_cdn" "foobar" { origin = "${digitalocean_spaces_bucket.bucket.bucket_domain_name}" }` + +const testAccCheckDigitalOceanCDNConfig_withTTL = ` +resource "digitalocean_spaces_bucket" "bucket" { + name = "%s" + region = "ams3" + acl = "public-read" +} + +resource "digitalocean_cdn" "foobar" { + origin = "${digitalocean_spaces_bucket.bucket.bucket_domain_name}" + ttl = 1800 +}` + +// func testAccCheckDigitalOceanCDNConfig_withDomain(rInt int, privateKeyMaterial, leafCert, certChain, domainName, bucketName string) string { + +// return fmt.Sprintf(` +// resource "digitalocean_certificate" "mycert" { +// name = "certificate-%d" +// private_key = <