From 604dfe19ae64089cd7d564b7a5bb9eacddeddbfa Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Fri, 7 Oct 2022 10:14:07 -0400 Subject: [PATCH 01/11] Issue 1840 Add custom_hostname wait_for_active_status --- .../resource_cloudflare_custom_hostname.go | 23 +++++++++++ ...esource_cloudflare_custom_hostname_test.go | 41 +++++++++++++++++++ .../schema_cloudflare_custom_hostname.go | 7 ++++ 3 files changed, 71 insertions(+) diff --git a/internal/provider/resource_cloudflare_custom_hostname.go b/internal/provider/resource_cloudflare_custom_hostname.go index b1ee7a0a9d..5fd06b2cbe 100644 --- a/internal/provider/resource_cloudflare_custom_hostname.go +++ b/internal/provider/resource_cloudflare_custom_hostname.go @@ -3,8 +3,10 @@ package provider import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "reflect" "strings" + "time" "github.com/MakeNowJust/heredoc/v2" "github.com/cloudflare/cloudflare-go" @@ -136,6 +138,27 @@ func resourceCloudflareCustomHostnameCreate(ctx context.Context, d *schema.Resou return diag.FromErr(errors.Wrap(err, "failed to create custom hostname certificate")) } + hostnameID := newCertificate.Result.ID + + if d.Get("wait_for_active_status").(bool) { + tflog.Info(ctx, fmt.Sprintf("enter wait_for_active_status")) + err := resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate)-time.Minute, func() *resource.RetryError { + customHostname, err := client.CustomHostname(ctx, zoneID, hostnameID) + tflog.Info(ctx, fmt.Sprintf("got customHostname status %s", customHostname.Status)) + if err != nil { + return resource.NonRetryableError(errors.Wrap(err, "failed to fetch custom hostname")) + } + if customHostname.Status != "active" { + return resource.RetryableError(fmt.Errorf("hostname is not in active status")) + } + return nil + }) + tflog.Info(ctx, fmt.Sprintf("exit wait_for_active_status")) + if err != nil { + return diag.FromErr(err) + } + } + d.SetId(newCertificate.Result.ID) return resourceCloudflareCustomHostnameRead(ctx, d, meta) diff --git a/internal/provider/resource_cloudflare_custom_hostname_test.go b/internal/provider/resource_cloudflare_custom_hostname_test.go index 2a14438542..423f771deb 100644 --- a/internal/provider/resource_cloudflare_custom_hostname_test.go +++ b/internal/provider/resource_cloudflare_custom_hostname_test.go @@ -95,6 +95,47 @@ resource "cloudflare_custom_hostname" "%[2]s" { `, zoneID, rnd, domain) } +func TestAccCloudflareCustomHostname_WaitForActive(t *testing.T) { + t.Parallel() + zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") + domain := os.Getenv("CLOUDFLARE_DOMAIN") + rnd := generateRandomResourceName() + resourceName := "cloudflare_custom_hostname." + rnd + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: testAccCheckCloudflareCustomHostnameWaitForActive(zoneID, rnd, domain), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "zone_id", zoneID), + resource.TestCheckResourceAttr(resourceName, "hostname", fmt.Sprintf("%s.%s", rnd, domain)), + resource.TestCheckResourceAttr(resourceName, "ssl.0.method", "txt"), + resource.TestCheckResourceAttr(resourceName, "wait_for_active_status", "true"), + resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.value"), + resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.type"), + resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.name"), + resource.TestCheckResourceAttrSet(resourceName, "ownership_verification_http.http_url"), + resource.TestCheckResourceAttrSet(resourceName, "ownership_verification_http.http_body"), + ), + }, + }, + }) +} + +func testAccCheckCloudflareCustomHostnameWaitForActive(zoneID, rnd, domain string) string { + return fmt.Sprintf(` +resource "cloudflare_custom_hostname" "%[2]s" { + zone_id = "%[1]s" + hostname = "%[2]s.%[3]s" + ssl { + method = "txt" + } + wait_for_active_status = true +} +`, zoneID, rnd, domain) +} + func TestAccCloudflareCustomHostname_WithCustomOriginServer(t *testing.T) { t.Parallel() zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") diff --git a/internal/provider/schema_cloudflare_custom_hostname.go b/internal/provider/schema_cloudflare_custom_hostname.go index 7aad01db45..e0d2672965 100644 --- a/internal/provider/schema_cloudflare_custom_hostname.go +++ b/internal/provider/schema_cloudflare_custom_hostname.go @@ -155,5 +155,12 @@ func resourceCloudflareCustomHostnameSchema() map[string]*schema.Schema { Computed: true, }, }, + "wait_for_active_status": { + Type: schema.TypeBool, + ForceNew: true, + Optional: true, + Default: false, + Description: "Whether or not to wait for a custom hostname to reach status `active` during creation.", + }, } } From ec7c64ad697b3583377b614faeabc17203f10a17 Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Fri, 7 Oct 2022 10:23:27 -0400 Subject: [PATCH 02/11] Add release note --- .changelog/1953.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/1953.txt diff --git a/.changelog/1953.txt b/.changelog/1953.txt new file mode 100644 index 0000000000..8cb66aa17b --- /dev/null +++ b/.changelog/1953.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/cloudflare_custom_hostname: Add `wait_for_active_status` attribute +``` \ No newline at end of file From cbfb3e8d89cd85d6c700731194b8ca75e20d4b60 Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Fri, 7 Oct 2022 10:31:35 -0400 Subject: [PATCH 03/11] Adjust logging --- internal/provider/resource_cloudflare_custom_hostname.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/provider/resource_cloudflare_custom_hostname.go b/internal/provider/resource_cloudflare_custom_hostname.go index 5fd06b2cbe..0fa33cd2d2 100644 --- a/internal/provider/resource_cloudflare_custom_hostname.go +++ b/internal/provider/resource_cloudflare_custom_hostname.go @@ -141,10 +141,9 @@ func resourceCloudflareCustomHostnameCreate(ctx context.Context, d *schema.Resou hostnameID := newCertificate.Result.ID if d.Get("wait_for_active_status").(bool) { - tflog.Info(ctx, fmt.Sprintf("enter wait_for_active_status")) err := resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate)-time.Minute, func() *resource.RetryError { customHostname, err := client.CustomHostname(ctx, zoneID, hostnameID) - tflog.Info(ctx, fmt.Sprintf("got customHostname status %s", customHostname.Status)) + tflog.Debug(ctx, fmt.Sprintf("got customHostname status %s", customHostname.Status)) if err != nil { return resource.NonRetryableError(errors.Wrap(err, "failed to fetch custom hostname")) } @@ -153,7 +152,6 @@ func resourceCloudflareCustomHostnameCreate(ctx context.Context, d *schema.Resou } return nil }) - tflog.Info(ctx, fmt.Sprintf("exit wait_for_active_status")) if err != nil { return diag.FromErr(err) } From 9ed891a183043f771cb71e8cf0643497f2c1535e Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Mon, 10 Oct 2022 09:49:12 -0400 Subject: [PATCH 04/11] Update internal/provider/resource_cloudflare_custom_hostname.go Co-authored-by: Jacob Bednarz --- internal/provider/resource_cloudflare_custom_hostname.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/provider/resource_cloudflare_custom_hostname.go b/internal/provider/resource_cloudflare_custom_hostname.go index 0fa33cd2d2..0db627da41 100644 --- a/internal/provider/resource_cloudflare_custom_hostname.go +++ b/internal/provider/resource_cloudflare_custom_hostname.go @@ -148,7 +148,7 @@ func resourceCloudflareCustomHostnameCreate(ctx context.Context, d *schema.Resou return resource.NonRetryableError(errors.Wrap(err, "failed to fetch custom hostname")) } if customHostname.Status != "active" { - return resource.RetryableError(fmt.Errorf("hostname is not in active status")) + return resource.RetryableError(fmt.Errorf("hostname is not yet in active status")) } return nil }) From c1e7dcec16ce929f1199dbe8d8b9bffa9dd3cd3b Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Mon, 10 Oct 2022 09:49:19 -0400 Subject: [PATCH 05/11] Update internal/provider/resource_cloudflare_custom_hostname.go Co-authored-by: Jacob Bednarz --- internal/provider/resource_cloudflare_custom_hostname.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/provider/resource_cloudflare_custom_hostname.go b/internal/provider/resource_cloudflare_custom_hostname.go index 0db627da41..310f0ea6ab 100644 --- a/internal/provider/resource_cloudflare_custom_hostname.go +++ b/internal/provider/resource_cloudflare_custom_hostname.go @@ -143,7 +143,7 @@ func resourceCloudflareCustomHostnameCreate(ctx context.Context, d *schema.Resou if d.Get("wait_for_active_status").(bool) { err := resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate)-time.Minute, func() *resource.RetryError { customHostname, err := client.CustomHostname(ctx, zoneID, hostnameID) - tflog.Debug(ctx, fmt.Sprintf("got customHostname status %s", customHostname.Status)) + tflog.Debug(ctx, fmt.Sprintf("custom hostname status %s", customHostname.Status)) if err != nil { return resource.NonRetryableError(errors.Wrap(err, "failed to fetch custom hostname")) } From c407916c087665e7f7691761d20ce5ea637979f7 Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Mon, 10 Oct 2022 09:49:24 -0400 Subject: [PATCH 06/11] Update internal/provider/schema_cloudflare_custom_hostname.go Co-authored-by: Jacob Bednarz --- internal/provider/schema_cloudflare_custom_hostname.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/provider/schema_cloudflare_custom_hostname.go b/internal/provider/schema_cloudflare_custom_hostname.go index e0d2672965..41297034fd 100644 --- a/internal/provider/schema_cloudflare_custom_hostname.go +++ b/internal/provider/schema_cloudflare_custom_hostname.go @@ -160,7 +160,7 @@ func resourceCloudflareCustomHostnameSchema() map[string]*schema.Schema { ForceNew: true, Optional: true, Default: false, - Description: "Whether or not to wait for a custom hostname to reach status `active` during creation.", + Description: "Whether to wait for a custom hostname to reach `active` state during creation.", }, } } From df235a80d8c561afa2f632f63e14c23bfda087b2 Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Mon, 10 Oct 2022 09:51:42 -0400 Subject: [PATCH 07/11] update docs --- docs/resources/custom_hostname.md | 1 + docs/resources/device_posture_rule.md | 6 +----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/resources/custom_hostname.md b/docs/resources/custom_hostname.md index 8ab37d694d..c8546cca5e 100644 --- a/docs/resources/custom_hostname.md +++ b/docs/resources/custom_hostname.md @@ -33,6 +33,7 @@ resource "cloudflare_custom_hostname" "example" { - `custom_origin_server` (String) The custom origin server used for certificates. - `custom_origin_sni` (String) The [custom origin SNI](https://developers.cloudflare.com/ssl/ssl-for-saas/hostname-specific-behavior/custom-origin) used for certificates. - `ssl` (Block List) SSL configuration of the certificate. (see [below for nested schema](#nestedblock--ssl)) +- `wait_for_active_status` (Boolean) Whether to wait for a custom hostname to reach `active` state during creation. Defaults to `false`. ### Read-Only diff --git a/docs/resources/device_posture_rule.md b/docs/resources/device_posture_rule.md index 3aefddfe19..6812aac17b 100644 --- a/docs/resources/device_posture_rule.md +++ b/docs/resources/device_posture_rule.md @@ -33,9 +33,7 @@ resource "cloudflare_device_posture_rule" "eaxmple" { } } ``` - - ## Schema ### Required @@ -57,7 +55,6 @@ resource "cloudflare_device_posture_rule" "eaxmple" { - `id` (String) The ID of this resource. - ### Nested Schema for `input` Optional: @@ -78,8 +75,8 @@ Optional: - `thumbprint` (String) The thumbprint of the file certificate. - `version` (String) The operating system semantic version. - + ### Nested Schema for `match` Optional: @@ -89,7 +86,6 @@ Optional: ## Import Import is supported using the following syntax: - ```shell $ terraform import cloudflare_device_posture_rule.example / ``` From fd1121160f9bc6ddaaa25157215055e700e04923 Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Wed, 12 Oct 2022 09:18:08 -0400 Subject: [PATCH 08/11] update to ssl pending verification check --- .changelog/1953.txt | 2 +- docs/resources/custom_hostname.md | 2 +- internal/provider/resource_cloudflare_custom_hostname.go | 8 ++++---- .../provider/resource_cloudflare_custom_hostname_test.go | 4 ++-- internal/provider/schema_cloudflare_custom_hostname.go | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.changelog/1953.txt b/.changelog/1953.txt index 8cb66aa17b..cb5fd7ad1e 100644 --- a/.changelog/1953.txt +++ b/.changelog/1953.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/cloudflare_custom_hostname: Add `wait_for_active_status` attribute +resource/cloudflare_custom_hostname: Add `wait_for_ssl_pending_validation` attribute ``` \ No newline at end of file diff --git a/docs/resources/custom_hostname.md b/docs/resources/custom_hostname.md index c8546cca5e..8fc8ce121e 100644 --- a/docs/resources/custom_hostname.md +++ b/docs/resources/custom_hostname.md @@ -33,7 +33,7 @@ resource "cloudflare_custom_hostname" "example" { - `custom_origin_server` (String) The custom origin server used for certificates. - `custom_origin_sni` (String) The [custom origin SNI](https://developers.cloudflare.com/ssl/ssl-for-saas/hostname-specific-behavior/custom-origin) used for certificates. - `ssl` (Block List) SSL configuration of the certificate. (see [below for nested schema](#nestedblock--ssl)) -- `wait_for_active_status` (Boolean) Whether to wait for a custom hostname to reach `active` state during creation. Defaults to `false`. +- `wait_for_ssl_pending_validation` (Boolean) Whether or not to wait for a custom hostname SSL sub-object to reach status `pending_validation` during creation. Defaults to `false`. ### Read-Only diff --git a/internal/provider/resource_cloudflare_custom_hostname.go b/internal/provider/resource_cloudflare_custom_hostname.go index 310f0ea6ab..7f241296e7 100644 --- a/internal/provider/resource_cloudflare_custom_hostname.go +++ b/internal/provider/resource_cloudflare_custom_hostname.go @@ -140,15 +140,15 @@ func resourceCloudflareCustomHostnameCreate(ctx context.Context, d *schema.Resou hostnameID := newCertificate.Result.ID - if d.Get("wait_for_active_status").(bool) { + if d.Get("wait_for_ssl_pending_validation").(bool) { err := resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate)-time.Minute, func() *resource.RetryError { customHostname, err := client.CustomHostname(ctx, zoneID, hostnameID) - tflog.Debug(ctx, fmt.Sprintf("custom hostname status %s", customHostname.Status)) + tflog.Debug(ctx, fmt.Sprintf("custom hostname ssl status %s", customHostname.SSL.Status)) if err != nil { return resource.NonRetryableError(errors.Wrap(err, "failed to fetch custom hostname")) } - if customHostname.Status != "active" { - return resource.RetryableError(fmt.Errorf("hostname is not yet in active status")) + if customHostname.SSL.Status != "pending_validation" { + return resource.RetryableError(fmt.Errorf("hostname ssl sub-object is not yet in pending_validation status")) } return nil }) diff --git a/internal/provider/resource_cloudflare_custom_hostname_test.go b/internal/provider/resource_cloudflare_custom_hostname_test.go index 423f771deb..26ae1afff5 100644 --- a/internal/provider/resource_cloudflare_custom_hostname_test.go +++ b/internal/provider/resource_cloudflare_custom_hostname_test.go @@ -111,7 +111,7 @@ func TestAccCloudflareCustomHostname_WaitForActive(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "zone_id", zoneID), resource.TestCheckResourceAttr(resourceName, "hostname", fmt.Sprintf("%s.%s", rnd, domain)), resource.TestCheckResourceAttr(resourceName, "ssl.0.method", "txt"), - resource.TestCheckResourceAttr(resourceName, "wait_for_active_status", "true"), + resource.TestCheckResourceAttr(resourceName, "wait_for_ssl_pending_validation", "true"), resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.value"), resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.type"), resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.name"), @@ -131,7 +131,7 @@ resource "cloudflare_custom_hostname" "%[2]s" { ssl { method = "txt" } - wait_for_active_status = true + wait_for_ssl_pending_validation = true } `, zoneID, rnd, domain) } diff --git a/internal/provider/schema_cloudflare_custom_hostname.go b/internal/provider/schema_cloudflare_custom_hostname.go index 41297034fd..c2883313d1 100644 --- a/internal/provider/schema_cloudflare_custom_hostname.go +++ b/internal/provider/schema_cloudflare_custom_hostname.go @@ -155,12 +155,12 @@ func resourceCloudflareCustomHostnameSchema() map[string]*schema.Schema { Computed: true, }, }, - "wait_for_active_status": { + "wait_for_ssl_pending_validation": { Type: schema.TypeBool, ForceNew: true, Optional: true, Default: false, - Description: "Whether to wait for a custom hostname to reach `active` state during creation.", + Description: "Whether or not to wait for a custom hostname SSL sub-object to reach status `pending_validation` during creation.", }, } } From b9a8e8de02385bd70473acfefc4b39d36f912545 Mon Sep 17 00:00:00 2001 From: Will Bluem Date: Fri, 14 Oct 2022 10:33:52 -0400 Subject: [PATCH 09/11] Update internal/provider/schema_cloudflare_custom_hostname.go Co-authored-by: Jacob Bednarz --- internal/provider/schema_cloudflare_custom_hostname.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/provider/schema_cloudflare_custom_hostname.go b/internal/provider/schema_cloudflare_custom_hostname.go index c2883313d1..073f897970 100644 --- a/internal/provider/schema_cloudflare_custom_hostname.go +++ b/internal/provider/schema_cloudflare_custom_hostname.go @@ -160,7 +160,7 @@ func resourceCloudflareCustomHostnameSchema() map[string]*schema.Schema { ForceNew: true, Optional: true, Default: false, - Description: "Whether or not to wait for a custom hostname SSL sub-object to reach status `pending_validation` during creation.", + Description: "Whether to wait for a custom hostname SSL sub-object to reach status `pending_validation` during creation.", }, } } From 1682768510cb07a340fb17676f6264829374f453 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Mon, 17 Oct 2022 10:43:42 +1100 Subject: [PATCH 10/11] fix nil check before using customHostname.SSL --- docs/resources/custom_hostname.md | 2 +- internal/provider/resource_cloudflare_custom_hostname.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/resources/custom_hostname.md b/docs/resources/custom_hostname.md index 8fc8ce121e..9edd5e0a77 100644 --- a/docs/resources/custom_hostname.md +++ b/docs/resources/custom_hostname.md @@ -33,7 +33,7 @@ resource "cloudflare_custom_hostname" "example" { - `custom_origin_server` (String) The custom origin server used for certificates. - `custom_origin_sni` (String) The [custom origin SNI](https://developers.cloudflare.com/ssl/ssl-for-saas/hostname-specific-behavior/custom-origin) used for certificates. - `ssl` (Block List) SSL configuration of the certificate. (see [below for nested schema](#nestedblock--ssl)) -- `wait_for_ssl_pending_validation` (Boolean) Whether or not to wait for a custom hostname SSL sub-object to reach status `pending_validation` during creation. Defaults to `false`. +- `wait_for_ssl_pending_validation` (Boolean) Whether to wait for a custom hostname SSL sub-object to reach status `pending_validation` during creation. Defaults to `false`. ### Read-Only diff --git a/internal/provider/resource_cloudflare_custom_hostname.go b/internal/provider/resource_cloudflare_custom_hostname.go index 7f241296e7..5eb89ba360 100644 --- a/internal/provider/resource_cloudflare_custom_hostname.go +++ b/internal/provider/resource_cloudflare_custom_hostname.go @@ -3,7 +3,6 @@ package provider import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "reflect" "strings" "time" @@ -12,6 +11,7 @@ import ( "github.com/cloudflare/cloudflare-go" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/pkg/errors" ) @@ -147,7 +147,7 @@ func resourceCloudflareCustomHostnameCreate(ctx context.Context, d *schema.Resou if err != nil { return resource.NonRetryableError(errors.Wrap(err, "failed to fetch custom hostname")) } - if customHostname.SSL.Status != "pending_validation" { + if customHostname.SSL != nil && customHostname.SSL.Status != "pending_validation" { return resource.RetryableError(fmt.Errorf("hostname ssl sub-object is not yet in pending_validation status")) } return nil From 02cf33f788bccae675e6397a83b164e1f03894c6 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Mon, 17 Oct 2022 12:14:15 +1100 Subject: [PATCH 11/11] ignore state import for ssl validation check --- internal/provider/resource_cloudflare_custom_hostname_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/provider/resource_cloudflare_custom_hostname_test.go b/internal/provider/resource_cloudflare_custom_hostname_test.go index 26ae1afff5..9112b34841 100644 --- a/internal/provider/resource_cloudflare_custom_hostname_test.go +++ b/internal/provider/resource_cloudflare_custom_hostname_test.go @@ -435,6 +435,7 @@ func TestAccCloudflareCustomHostname_Import(t *testing.T) { "ssl.0.status", "ssl.0.type", "ssl.0.wildcard", + "wait_for_ssl_pending_validation", }, }, },