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

update validation records/errors for custom_hostname and certificate_pack #1424

Merged
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
11 changes: 11 additions & 0 deletions .changelog/1424.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```release-note:enhancement
resource/custom_hostname: validation tokens are now an array (`validation_records`) instead of a top level, but the only top level record that was previously here was for cname validation, txt/http/email were entirely missing.
```

```release-note:enhancement
resource/custom_hostname: also adds missing `validation_errors`, and `certificate_authority`
```

```release-note:enhancement
resource/certificate_pack: adds `validation_errors` and `validation_records` with same format as custom hostnames.
```
25 changes: 25 additions & 0 deletions cloudflare/resource_cloudflare_certificate_pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log"
"reflect"
"strings"

cloudflare "github.com/cloudflare/cloudflare-go"
Expand Down Expand Up @@ -78,6 +79,30 @@ func resourceCloudflareCertificatePackRead(d *schema.ResourceData, meta interfac
d.Set("type", certificatePack.Type)
d.Set("hosts", expandStringListToSet(certificatePack.Hosts))

if !reflect.ValueOf(certificatePack.ValidationErrors).IsNil() {
errors := []map[string]interface{}{}
for _, e := range certificatePack.ValidationErrors {
errors = append(errors, map[string]interface{}{"message": e.Message})
}
d.Set("validation_errors", errors)
}
if !reflect.ValueOf(certificatePack.ValidationRecords).IsNil() {
records := []map[string]interface{}{}
for _, e := range certificatePack.ValidationRecords {
records = append(records,
map[string]interface{}{
"cname_name": e.CnameName,
"cname_target": e.CnameTarget,
"txt_name": e.TxtName,
"txt_value": e.TxtValue,
"http_body": e.HTTPBody,
"http_url": e.HTTPUrl,
"emails": e.Emails,
})
}
d.Set("validation_records", records)
}

return nil
}

Expand Down
58 changes: 40 additions & 18 deletions cloudflare/resource_cloudflare_custom_hostname.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,50 @@ func resourceCloudflareCustomHostnameRead(d *schema.ResourceData, meta interface
var sslConfig []map[string]interface{}

if !reflect.ValueOf(customHostname.SSL).IsNil() {
sslConfig = append(sslConfig, map[string]interface{}{
"type": customHostname.SSL.Type,
"method": customHostname.SSL.Method,
"wildcard": customHostname.SSL.Wildcard,
"status": customHostname.SSL.Status,
"cname_target": customHostname.SSL.CnameTarget,
"cname_name": customHostname.SSL.CnameName,
"custom_certificate": customHostname.SSL.CustomCertificate,
"custom_key": customHostname.SSL.CustomKey,
ssl := map[string]interface{}{
"type": customHostname.SSL.Type,
"method": customHostname.SSL.Method,
"wildcard": customHostname.SSL.Wildcard,
"status": customHostname.SSL.Status,
"certificate_authority": customHostname.SSL.CertificateAuthority,
"custom_certificate": customHostname.SSL.CustomCertificate,
"custom_key": customHostname.SSL.CustomKey,
"settings": []map[string]interface{}{{
"http2": customHostname.SSL.Settings.HTTP2,
"tls13": customHostname.SSL.Settings.TLS13,
"min_tls_version": customHostname.SSL.Settings.MinTLSVersion,
"ciphers": customHostname.SSL.Settings.Ciphers,
"early_hints": customHostname.SSL.Settings.EarlyHints,
}},
})
}
if !reflect.ValueOf(customHostname.SSL.ValidationErrors).IsNil() {
errors := []map[string]interface{}{}
for _, e := range customHostname.SSL.ValidationErrors {
errors = append(errors, map[string]interface{}{"message": e.Message})
}
ssl["validation_errors"] = errors
}
if !reflect.ValueOf(customHostname.SSL.ValidationRecords).IsNil() {
records := []map[string]interface{}{}
for _, e := range customHostname.SSL.ValidationRecords {
records = append(records,
map[string]interface{}{
"cname_name": e.CnameName,
"cname_target": e.CnameTarget,
"txt_name": e.TxtName,
"txt_value": e.TxtValue,
"http_body": e.HTTPBody,
"http_url": e.HTTPUrl,
"emails": e.Emails,
})
}
ssl["validation_records"] = records
}
sslConfig = append(sslConfig, ssl)
}

if err := d.Set("ssl", sslConfig); err != nil {
return fmt.Errorf("failed to see ssl")
return fmt.Errorf("failed to set ssl")
}

ownershipVerificationCfg := map[string]interface{}{
Expand Down Expand Up @@ -153,13 +176,12 @@ func buildCustomHostname(d *schema.ResourceData) cloudflare.CustomHostname {

if _, ok := d.GetOk("ssl"); ok {
ch.SSL = &cloudflare.CustomHostnameSSL{
Method: d.Get("ssl.0.method").(string),
Type: d.Get("ssl.0.type").(string),
Wildcard: &[]bool{d.Get("ssl.0.wildcard").(bool)}[0],
CnameTarget: d.Get("ssl.0.cname_target").(string),
CnameName: d.Get("ssl.0.cname_name").(string),
CustomCertificate: d.Get("ssl.0.custom_certificate").(string),
CustomKey: d.Get("ssl.0.custom_key").(string),
Method: d.Get("ssl.0.method").(string),
Type: d.Get("ssl.0.type").(string),
Wildcard: &[]bool{d.Get("ssl.0.wildcard").(bool)}[0],
CustomCertificate: d.Get("ssl.0.custom_certificate").(string),
CustomKey: d.Get("ssl.0.custom_key").(string),
CertificateAuthority: d.Get("ssl.0.certificate_authority").(string),
Settings: cloudflare.CustomHostnameSSLSettings{
HTTP2: d.Get("ssl.0.settings.0.http2").(string),
TLS13: d.Get("ssl.0.settings.0.tls13").(string),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func resourceCloudflareCustomHostnameFallbackOriginRead(d *schema.ResourceData,

customHostnameFallbackOrigin, err := client.CustomHostnameFallbackOrigin(context.Background(), zoneID)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error reading custom hostname fallback origin %q", zoneID))
return fmt.Errorf("error reading custom hostname fallback origin %q: %w", zoneID, err)
}

d.Set("origin", customHostnameFallbackOrigin.Origin)
Expand All @@ -46,7 +46,7 @@ func resourceCloudflareCustomHostnameFallbackOriginDelete(d *schema.ResourceData

err := client.DeleteCustomHostnameFallbackOrigin(context.Background(), zoneID)
if err != nil {
return errors.Wrap(err, "failed to delete custom hostname fallback origin")
return fmt.Errorf("failed to delete custom hostname fallback origin: %w", err)
}

return nil
Expand All @@ -64,16 +64,18 @@ func resourceCloudflareCustomHostnameFallbackOriginCreate(d *schema.ResourceData
return resource.Retry(d.Timeout(schema.TimeoutDefault), func() *resource.RetryError {
_, err := client.UpdateCustomHostnameFallbackOrigin(context.Background(), zoneID, fallbackOrigin)
if err != nil {
if err.(*cloudflare.APIRequestError).InternalErrorCodeIs(1414) {
//nolint:errorlint
if errors.As(err, &cloudflare.APIRequestError{}) && err.(*cloudflare.APIRequestError).InternalErrorCodeIs(1414) {
return resource.RetryableError(fmt.Errorf("expected custom hostname resource to be ready for modification but is still pending"))
} else {
return resource.NonRetryableError(fmt.Errorf("failed to create custom hostname fallback origin: %w", err))
}
return resource.NonRetryableError(errors.Wrap(err, "failed to create custom hostname fallback origin"))
}

fallbackHostname, err := client.CustomHostnameFallbackOrigin(context.Background(), zoneID)

if err != nil {
return resource.NonRetryableError(fmt.Errorf("failed to fetch custom hostname: %s", err))
return resource.NonRetryableError(fmt.Errorf("failed to fetch custom hostname: %w", err))
}

// Address an eventual consistency issue where deleting a fallback hostname
Expand Down Expand Up @@ -104,10 +106,11 @@ func resourceCloudflareCustomHostnameFallbackOriginUpdate(d *schema.ResourceData
return resource.Retry(d.Timeout(schema.TimeoutDefault), func() *resource.RetryError {
_, err := client.UpdateCustomHostnameFallbackOrigin(context.Background(), zoneID, fallbackOrigin)
if err != nil {
if err.(*cloudflare.APIRequestError).InternalErrorCodeIs(1414) {
//nolint:errorlint
if errors.As(err, &cloudflare.APIRequestError{}) && err.(*cloudflare.APIRequestError).InternalErrorCodeIs(1414) {
return resource.RetryableError(fmt.Errorf("expected custom hostname resource to be ready for modification but is still pending"))
}
return resource.NonRetryableError(errors.Wrap(err, "failed to update custom hostname fallback origin"))
return resource.NonRetryableError(fmt.Errorf("failed to update custom hostname fallback origin: %w", err))
}

resourceCloudflareCustomHostnameFallbackOriginRead(d, meta)
Expand Down
5 changes: 3 additions & 2 deletions cloudflare/resource_cloudflare_custom_hostname_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func TestAccCloudflareCustomHostname_WithCustomSSLSettings(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "ssl.0.settings.0.http2", "off"),
resource.TestCheckResourceAttr(resourceName, "ssl.0.settings.0.min_tls_version", "1.2"),
resource.TestCheckResourceAttr(resourceName, "ssl.0.settings.0.ciphers.#", "2"),
resource.TestCheckResourceAttr(resourceName, "ssl.0.certificate_authority", "digicert"),
resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.value"),
resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.type"),
resource.TestCheckResourceAttrSet(resourceName, "ownership_verification.name"),
Expand Down Expand Up @@ -380,8 +381,8 @@ func TestAccCloudflareCustomHostname_Import(t *testing.T) {
ImportStateVerifyIgnore: []string{
"ssl.#",
"ssl.0.certificate_authority",
"ssl.0.cname_name",
"ssl.0.cname_target",
"ssl.0.validation_records",
"ssl.0.validation_errors",
"ssl.0.custom_certificate",
"ssl.0.custom_key",
"ssl.0.method",
Expand Down
14 changes: 14 additions & 0 deletions cloudflare/schema_cloudflare_certificate_pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,22 @@ func resourceCloudflareCertificatePackSchema() map[string]*schema.Schema {
"certificate_authority": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"digicert", "lets_encrypt"}, false),
Default: nil,
},
"validation_records": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Elem: sslValidationRecordsSchema(),
},
"validation_errors": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Elem: sslValidationErrorsSchema(),
},
"cloudflare_branding": {
Type: schema.TypeBool,
Expand Down
16 changes: 10 additions & 6 deletions cloudflare/schema_cloudflare_custom_hostname.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@ func resourceCloudflareCustomHostnameSchema() map[string]*schema.Schema {
"certificate_authority": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice([]string{"lets_encrypt", "digicert"}, false),
Default: nil,
},
"cname_target": {
Type: schema.TypeString,
Optional: true,
"validation_records": {
Type: schema.TypeList,
Computed: true,
Elem: sslValidationRecordsSchema(),
},
"cname_name": {
Type: schema.TypeString,
Optional: true,
"validation_errors": {
Type: schema.TypeList,
Computed: true,
Elem: sslValidationErrorsSchema(),
},
"wildcard": {
Type: schema.TypeBool,
Expand Down
60 changes: 60 additions & 0 deletions cloudflare/schema_cloudflare_ssl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package cloudflare

import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

func sslValidationErrorsSchema() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Schema: map[string]*schema.Schema{
"message": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func sslValidationRecordsSchema() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Schema: map[string]*schema.Schema{
"cname_target": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"cname_name": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"txt_name": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"txt_value": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"http_url": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"http_body": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"emails": {
Type: schema.TypeList,
Computed: true,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}