From b60bee5811dea10f3a958d54ccd27ba7c7969a92 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Wed, 2 Oct 2024 12:11:01 -0700 Subject: [PATCH] fix settings the Locations field for client_certificate_v2 posture rules --- .changelog/4168.txt | 3 + ...resource_cloudflare_device_posture_rule.go | 15 +++- ...rce_cloudflare_device_posture_rule_test.go | 76 +++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 .changelog/4168.txt diff --git a/.changelog/4168.txt b/.changelog/4168.txt new file mode 100644 index 0000000000..cb2b6dff5e --- /dev/null +++ b/.changelog/4168.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/cloudflare_device_posture_rule: fix bug where locations were not parsed correctly for client_certificate_v2 posture rules +``` \ No newline at end of file diff --git a/internal/sdkv2provider/resource_cloudflare_device_posture_rule.go b/internal/sdkv2provider/resource_cloudflare_device_posture_rule.go index 075606aa08..23e2440113 100644 --- a/internal/sdkv2provider/resource_cloudflare_device_posture_rule.go +++ b/internal/sdkv2provider/resource_cloudflare_device_posture_rule.go @@ -290,8 +290,19 @@ func setDevicePostureRuleInput(rule *cloudflare.DevicePostureRule, d *schema.Res input.ExtendedKeyUsage = append(input.ExtendedKeyUsage, value.(string)) } } - if locations, ok := d.GetOk("input.0.locations"); ok { - input.Locations = locations.(cloudflare.CertificateLocations) + if _, ok := d.GetOk("input.0.locations"); ok { + if paths, ok := d.GetOk("input.0.locations.0.paths"); ok { + values := paths.(*schema.Set).List() + for _, value := range values { + input.Locations.Paths = append(input.Locations.Paths, value.(string)) + } + } + if trustStores, ok := d.GetOk("input.0.locations.0.trust_stores"); ok { + values := trustStores.(*schema.Set).List() + for _, value := range values { + input.Locations.TrustStores = append(input.Locations.TrustStores, value.(string)) + } + } } if score, ok := d.GetOk("input.0.score"); ok { input.Score = score.(int) diff --git a/internal/sdkv2provider/resource_cloudflare_device_posture_rule_test.go b/internal/sdkv2provider/resource_cloudflare_device_posture_rule_test.go index 72908a8af5..81221a5daa 100644 --- a/internal/sdkv2provider/resource_cloudflare_device_posture_rule_test.go +++ b/internal/sdkv2provider/resource_cloudflare_device_posture_rule_test.go @@ -289,6 +289,53 @@ func TestAccCloudflareDevicePostureRule_DiskEncryption_CheckDisks(t *testing.T) }) } +func TestAccCloudflareDevicePostureRule_ClientCertificateV2(t *testing.T) { + skipForDefaultAccount(t, "Assertion requires an active certificate configured") + + // Temporarily unset CLOUDFLARE_API_TOKEN if it is set as the Access + // service does not yet support the API tokens and it results in + // misleading state error messages. + if os.Getenv("CLOUDFLARE_API_TOKEN") != "" { + t.Setenv("CLOUDFLARE_API_TOKEN", "") + } + + if v := os.Getenv("CLOUDFLARE_DEVICE_POSTURE_CERTIFICATE_ID"); v == "" { + t.Fatal("CLOUDFLARE_DEVICE_POSTURE_CERTIFICATE_ID must be set for this acceptance test") + } + + certificateID := os.Getenv("CLOUDFLARE_DEVICE_POSTURE_CERTIFICATE_ID") + + rnd := generateRandomResourceName() + name := fmt.Sprintf("cloudflare_zero_trust_device_posture_rule.%s", rnd) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + ProviderFactories: providerFactories, + CheckDestroy: testAccCheckCloudflareDevicePostureRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCloudflareDevicePostureRuleConfigClientCertificateV2(rnd, accountID, certificateID), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, consts.AccountIDSchemaKey, accountID), + resource.TestCheckResourceAttr(name, "name", rnd), + resource.TestCheckResourceAttr(name, "type", "client_certificate_v2"), + resource.TestCheckResourceAttr(name, "description", "My description"), + resource.TestCheckResourceAttr(name, "schedule", "24h"), + resource.TestCheckResourceAttr(name, "expiration", "24h"), + resource.TestCheckResourceAttr(name, "match.0.platform", "linux"), + resource.TestCheckResourceAttr(name, "input.0.certificate_id", certificateID), + resource.TestCheckResourceAttr(name, "input.0.check_private_key", "true"), + resource.TestCheckResourceAttr(name, "input.0.extended_key_usage.0", "clientAuth"), + resource.TestCheckResourceAttr(name, "input.0.locations.0.trust_stores.0", "system"), + resource.TestCheckResourceAttr(name, "input.0.locations.0.paths.0", "/path/to/file"), + ), + }, + }, + }) +} + func TestAccCloudflareDevicePostureRule_Intune(t *testing.T) { skipForDefaultAccount(t, "Assertion requires active Intune license.") @@ -471,6 +518,35 @@ resource "cloudflare_zero_trust_device_posture_rule" "%[1]s" { `, rnd, accountID) } +func testAccCloudflareDevicePostureRuleConfigClientCertificateV2(rnd, accountID, certificateID string) string { + return fmt.Sprintf(` +resource "cloudflare_zero_trust_device_posture_rule" "%[1]s" { + account_id = "%[2]s" + name = "%[1]s" + type = "client_certificate_v2" + description = "My description" + schedule = "24h" + expiration = "24h" + match { + platform = "linux" + } + input { + certificate_id = "%[3]s" + check_private_key = true + extended_key_usage = ["clientAuth"] + locations { + paths = [ + "/path/to/file" + ] + trust_stores = [ + "system" + ] + } + } +} +`, rnd, accountID, certificateID) +} + func testAccCloudflareDevicePostureRuleConfigFirewall(rnd, accountID string) string { return fmt.Sprintf(` resource "cloudflare_zero_trust_device_posture_rule" "%[1]s" {