From 64c36775987ce39d686f6eb28b1d61b9ebf9c391 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Wed, 21 Aug 2024 06:14:17 +1000 Subject: [PATCH] refactor(cloudflare_record): remove custom validation in favour of `ExactlyOneOf` Previously, the `cloudlare_record` CRUD operations had their own validation for determining which value combinations could be set together. This is already a built in feature that can be applied at the schema level instead through the `ExactlyOneOf` behaviour instead. --- .changelog/3699.txt | 3 +++ docs/resources/record.md | 6 +++--- .../sdkv2provider/resource_cloudflare_record.go | 15 --------------- .../sdkv2provider/schema_cloudflare_record.go | 14 +++++++------- 4 files changed, 13 insertions(+), 25 deletions(-) create mode 100644 .changelog/3699.txt diff --git a/.changelog/3699.txt b/.changelog/3699.txt new file mode 100644 index 0000000000..511f0c19c8 --- /dev/null +++ b/.changelog/3699.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/cloudflare_record: refactor validation to use `ExactlyOneOf` instead of custom logic +``` diff --git a/docs/resources/record.md b/docs/resources/record.md index efd665078a..fe03e3d2f9 100644 --- a/docs/resources/record.md +++ b/docs/resources/record.md @@ -51,14 +51,14 @@ resource "cloudflare_record" "_sip_tls" { - `allow_overwrite` (Boolean) Allow creation of this record in Terraform to overwrite an existing record, if any. This does not affect the ability to update the record in Terraform and does not prevent other resources within Terraform or manual changes outside Terraform from overwriting this record. **This configuration is not recommended for most environments**. Defaults to `false`. - `comment` (String) Comments or notes about the DNS record. This field has no effect on DNS responses. -- `content` (String) The content of the record. Conflicts with `data`. -- `data` (Block List, Max: 1) Map of attributes that constitute the record value. Conflicts with `value`. (see [below for nested schema](#nestedblock--data)) +- `content` (String) The content of the record. Must provide only one of `data`, `content`, `value`. +- `data` (Block List, Max: 1) Map of attributes that constitute the record value. Must provide only one of `data`, `content`, `value`. (see [below for nested schema](#nestedblock--data)) - `priority` (Number) The priority of the record. - `proxied` (Boolean) Whether the record gets Cloudflare's origin protection. - `tags` (Set of String) Custom tags for the DNS record. - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) - `ttl` (Number) The TTL of the record. -- `value` (String, Deprecated) The value of the record. Conflicts with `data`. +- `value` (String, Deprecated) The value of the record. Must provide only one of `data`, `content`, `value`. ### Read-Only diff --git a/internal/sdkv2provider/resource_cloudflare_record.go b/internal/sdkv2provider/resource_cloudflare_record.go index 5f45047a65..5e72d13063 100644 --- a/internal/sdkv2provider/resource_cloudflare_record.go +++ b/internal/sdkv2provider/resource_cloudflare_record.go @@ -71,15 +71,6 @@ func resourceCloudflareRecordCreate(ctx context.Context, d *schema.ResourceData, newRecord.Content = content.(string) } - if contentOk == valueOk { - return diag.FromErr(fmt.Errorf( - "'content' (present: %t) must not be set with 'value' (present: %t)", - contentOk, valueOk)) - } - if valueOk { - contentOk = true - } - data, dataOk := d.GetOk("data") tflog.Debug(ctx, fmt.Sprintf("Data found in config: %#v", data)) @@ -100,12 +91,6 @@ func resourceCloudflareRecordCreate(ctx context.Context, d *schema.ResourceData, newRecord.Data = newDataMap } - if contentOk == dataOk { - return diag.FromErr(fmt.Errorf( - "either 'content' (present: %t) or 'data' (present: %t) must be provided", - contentOk, dataOk)) - } - if priority, ok := d.GetOkExists("priority"); ok { p := uint16(priority.(int)) newRecord.Priority = &p diff --git a/internal/sdkv2provider/schema_cloudflare_record.go b/internal/sdkv2provider/schema_cloudflare_record.go index 0ab4480b74..40fbc8eb8a 100644 --- a/internal/sdkv2provider/schema_cloudflare_record.go +++ b/internal/sdkv2provider/schema_cloudflare_record.go @@ -47,7 +47,7 @@ func resourceCloudflareRecordSchema() map[string]*schema.Schema { Type: schema.TypeString, Optional: true, Computed: true, - ConflictsWith: []string{"data"}, + ExactlyOneOf: []string{"data", "content", "value"}, DiffSuppressFunc: suppressTrailingDots, Description: "The value of the record.", Deprecated: "`value` is deprecated in favour of `content` and will be removed in the next major release.", @@ -57,17 +57,17 @@ func resourceCloudflareRecordSchema() map[string]*schema.Schema { Type: schema.TypeString, Optional: true, Computed: true, - ConflictsWith: []string{"data"}, + ExactlyOneOf: []string{"data", "content", "value"}, DiffSuppressFunc: suppressTrailingDots, Description: "The content of the record.", }, "data": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - ConflictsWith: []string{"value"}, - Description: "Map of attributes that constitute the record value.", + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + ExactlyOneOf: []string{"data", "content", "value"}, + Description: "Map of attributes that constitute the record value.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ // Properties present in several record types