Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 1840 Add custom_hostname wait_for_active_status #1953

3 changes: 3 additions & 0 deletions .changelog/1953.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/cloudflare_custom_hostname: Add `wait_for_ssl_pending_validation` attribute
```
1 change: 1 addition & 0 deletions docs/resources/custom_hostname.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_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

Expand Down
6 changes: 1 addition & 5 deletions docs/resources/device_posture_rule.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ resource "cloudflare_device_posture_rule" "eaxmple" {
}
}
```

<!-- schema generated by tfplugindocs -->

## Schema

### Required
Expand All @@ -57,7 +55,6 @@ resource "cloudflare_device_posture_rule" "eaxmple" {
- `id` (String) The ID of this resource.

<a id="nestedblock--input"></a>

### Nested Schema for `input`

Optional:
Expand All @@ -78,8 +75,8 @@ Optional:
- `thumbprint` (String) The thumbprint of the file certificate.
- `version` (String) The operating system semantic version.

<a id="nestedblock--match"></a>

<a id="nestedblock--match"></a>
### Nested Schema for `match`

Optional:
Expand All @@ -89,7 +86,6 @@ Optional:
## Import

Import is supported using the following syntax:

```shell
$ terraform import cloudflare_device_posture_rule.example <account_id>/<device_posture_rule_id>
```
21 changes: 21 additions & 0 deletions internal/provider/resource_cloudflare_custom_hostname.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import (
"fmt"
"reflect"
"strings"
"time"

"github.com/MakeNowJust/heredoc/v2"
"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"
)
Expand Down Expand Up @@ -136,6 +138,25 @@ 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_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 ssl status %s", customHostname.SSL.Status))
if err != nil {
return resource.NonRetryableError(errors.Wrap(err, "failed to fetch custom hostname"))
}
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
})
if err != nil {
return diag.FromErr(err)
}
}

d.SetId(newCertificate.Result.ID)

return resourceCloudflareCustomHostnameRead(ctx, d, meta)
Expand Down
42 changes: 42 additions & 0 deletions internal/provider/resource_cloudflare_custom_hostname_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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_ssl_pending_validation", "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_ssl_pending_validation = true
}
`, zoneID, rnd, domain)
}

func TestAccCloudflareCustomHostname_WithCustomOriginServer(t *testing.T) {
t.Parallel()
zoneID := os.Getenv("CLOUDFLARE_ZONE_ID")
Expand Down Expand Up @@ -394,6 +435,7 @@ func TestAccCloudflareCustomHostname_Import(t *testing.T) {
"ssl.0.status",
"ssl.0.type",
"ssl.0.wildcard",
"wait_for_ssl_pending_validation",
},
},
},
Expand Down
7 changes: 7 additions & 0 deletions internal/provider/schema_cloudflare_custom_hostname.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,12 @@ func resourceCloudflareCustomHostnameSchema() map[string]*schema.Schema {
Computed: true,
},
},
"wait_for_ssl_pending_validation": {
Type: schema.TypeBool,
ForceNew: true,
Optional: true,
Default: false,
Description: "Whether to wait for a custom hostname SSL sub-object to reach status `pending_validation` during creation.",
},
}
}