diff --git a/internal/services/stream/list_data_source_model.go b/internal/services/stream/list_data_source_model.go index e32b569240..0dbf1da0c7 100644 --- a/internal/services/stream/list_data_source_model.go +++ b/internal/services/stream/list_data_source_model.go @@ -7,11 +7,12 @@ import ( "github.com/cloudflare/cloudflare-go/v5" "github.com/cloudflare/cloudflare-go/v5/stream" - "github.com/cloudflare/terraform-provider-cloudflare/internal/customfield" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/cloudflare/terraform-provider-cloudflare/internal/customfield" ) type StreamsResultListDataSourceEnvelope struct { @@ -67,9 +68,9 @@ func (m *StreamsDataSourceModel) toListParams(_ context.Context) (params stream. if !m.Type.IsNull() { params.Type = cloudflare.F(m.Type.ValueString()) } - if !m.VideoName.IsNull() { - params.VideoName = cloudflare.F(m.VideoName.ValueString()) - } + //if !m.VideoName.IsNull() { + // params.VideoName = cloudflare.F(m.VideoName.ValueString()) + //} return } diff --git a/internal/services/zero_trust_access_mtls_hostname_settings/resource.go b/internal/services/zero_trust_access_mtls_hostname_settings/resource.go index 54ecfa24cd..ca631e89c5 100644 --- a/internal/services/zero_trust_access_mtls_hostname_settings/resource.go +++ b/internal/services/zero_trust_access_mtls_hostname_settings/resource.go @@ -7,18 +7,23 @@ import ( "fmt" "io" "net/http" + "time" "github.com/cloudflare/cloudflare-go/v5" "github.com/cloudflare/cloudflare-go/v5/option" "github.com/cloudflare/cloudflare-go/v5/zero_trust" "github.com/cloudflare/terraform-provider-cloudflare/internal/apijson" "github.com/cloudflare/terraform-provider-cloudflare/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" ) // Ensure provider defined types fully satisfy framework interfaces. var _ resource.ResourceWithConfigure = (*ZeroTrustAccessMTLSHostnameSettingsResource)(nil) var _ resource.ResourceWithModifyPlan = (*ZeroTrustAccessMTLSHostnameSettingsResource)(nil) +var _ resource.ResourceWithImportState = (*ZeroTrustAccessMTLSHostnameSettingsResource)(nil) func NewResource() resource.Resource { return &ZeroTrustAccessMTLSHostnameSettingsResource{} @@ -76,13 +81,23 @@ func (r *ZeroTrustAccessMTLSHostnameSettingsResource) Create(ctx context.Context params.ZoneID = cloudflare.F(data.ZoneID.ValueString()) } - _, err = r.client.ZeroTrust.Access.Certificates.Settings.Update( - ctx, - params, - option.WithRequestBody("application/json", dataBytes), - option.WithResponseBodyInto(&res), - option.WithMiddleware(logging.Middleware(ctx)), - ) + err = retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { + _, retryErr := r.client.ZeroTrust.Access.Certificates.Settings.Update( + ctx, + params, + option.WithRequestBody("application/json", dataBytes), + option.WithResponseBodyInto(&res), + option.WithMiddleware(logging.Middleware(ctx)), + ) + if retryErr != nil { + // Check if it's a conflict error that should be retried + if res != nil && res.StatusCode == 409 { + return retry.RetryableError(retryErr) + } + return retry.NonRetryableError(retryErr) + } + return nil + }) if err != nil { resp.Diagnostics.AddError("failed to make http request", err.Error()) return @@ -130,13 +145,23 @@ func (r *ZeroTrustAccessMTLSHostnameSettingsResource) Update(ctx context.Context params.ZoneID = cloudflare.F(data.ZoneID.ValueString()) } - _, err = r.client.ZeroTrust.Access.Certificates.Settings.Update( - ctx, - params, - option.WithRequestBody("application/json", dataBytes), - option.WithResponseBodyInto(&res), - option.WithMiddleware(logging.Middleware(ctx)), - ) + err = retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { + _, retryErr := r.client.ZeroTrust.Access.Certificates.Settings.Update( + ctx, + params, + option.WithRequestBody("application/json", dataBytes), + option.WithResponseBodyInto(&res), + option.WithMiddleware(logging.Middleware(ctx)), + ) + if retryErr != nil { + // Check if it's a conflict error that should be retried + if res != nil && res.StatusCode == 409 { + return retry.RetryableError(retryErr) + } + return retry.NonRetryableError(retryErr) + } + return nil + }) if err != nil { resp.Diagnostics.AddError("failed to make http request", err.Error()) return @@ -201,6 +226,52 @@ func (r *ZeroTrustAccessMTLSHostnameSettingsResource) Delete(ctx context.Context } +func (r *ZeroTrustAccessMTLSHostnameSettingsResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + var data *ZeroTrustAccessMTLSHostnameSettingsModel = new(ZeroTrustAccessMTLSHostnameSettingsModel) + importID := req.ID + + // Check if it's a zone ID or account ID and set the appropriate field + if len(importID) == 32 { + // Account ID + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("account_id"), importID)...) + data.AccountID = types.StringValue(importID) + } else { + // Zone ID + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("zone_id"), importID)...) + data.ZoneID = types.StringValue(importID) + } + + if resp.Diagnostics.HasError() { + return + } + + // Since import just passes the identifier, we need to read the current state + // from the API. We'll do this by creating a mock ReadRequest and calling Read() + var fullData *ZeroTrustAccessMTLSHostnameSettingsModel = new(ZeroTrustAccessMTLSHostnameSettingsModel) + if !data.AccountID.IsNull() { + fullData.AccountID = data.AccountID + } else { + fullData.ZoneID = data.ZoneID + } + + // Set the full data in state first so Read can process it + resp.Diagnostics.Append(resp.State.Set(ctx, fullData)...) + if resp.Diagnostics.HasError() { + return + } + + // Create a Read request and response to fetch the full state + readReq := resource.ReadRequest{State: resp.State} + readResp := &resource.ReadResponse{State: resp.State, Diagnostics: resp.Diagnostics} + + // Call the Read method to populate the full state + r.Read(ctx, readReq, readResp) + + // Copy back the results + resp.State = readResp.State + resp.Diagnostics = readResp.Diagnostics +} + func (r *ZeroTrustAccessMTLSHostnameSettingsResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { if req.State.Raw.IsNull() { resp.Diagnostics.AddWarning( diff --git a/internal/services/zero_trust_access_mtls_hostname_settings/resource_test.go b/internal/services/zero_trust_access_mtls_hostname_settings/resource_test.go index 1c5d4f1d15..6d7640684c 100644 --- a/internal/services/zero_trust_access_mtls_hostname_settings/resource_test.go +++ b/internal/services/zero_trust_access_mtls_hostname_settings/resource_test.go @@ -7,13 +7,14 @@ import ( "testing" cfv1 "github.com/cloudflare/cloudflare-go" - cfv2 "github.com/cloudflare/cloudflare-go/v5" - "github.com/cloudflare/cloudflare-go/v5/zero_trust" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" + "github.com/cloudflare/terraform-provider-cloudflare/internal/acctest" "github.com/cloudflare/terraform-provider-cloudflare/internal/consts" "github.com/cloudflare/terraform-provider-cloudflare/internal/utils" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { @@ -48,7 +49,7 @@ func init() { }) } -func TestAccCloudflareAccessMutualTLSHostnameSettings_Simple(t *testing.T) { +func TestAccCloudflareAccessMutualTLSHostnameSettings_Account(t *testing.T) { // 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. @@ -67,16 +68,15 @@ func TestAccCloudflareAccessMutualTLSHostnameSettings_Simple(t *testing.T) { acctest.TestAccPreCheck_AccountID(t) }, ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories, - CheckDestroy: testAccCheckCloudflareAccessMutualTLSHostnameSettingsDestroy, Steps: []resource.TestStep{ { Config: testAccessMutualTLSHostnameSettingsConfig(rnd, cfv1.AccountIdentifier(accountID), domain), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(name, consts.AccountIDSchemaKey, accountID), - resource.TestCheckResourceAttr(name, "settings.0.hostname", domain), - resource.TestCheckResourceAttr(name, "settings.0.china_network", "false"), - resource.TestCheckResourceAttr(name, "settings.0.client_certificate_forwarding", "true"), - ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("hostname"), knownvalue.StringExact(domain)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(true)), + }, }, { // Ensures no diff on last plan @@ -87,28 +87,253 @@ func TestAccCloudflareAccessMutualTLSHostnameSettings_Simple(t *testing.T) { }) } -func testAccCheckCloudflareAccessMutualTLSHostnameSettingsDestroy(s *terraform.State) error { - client := acctest.SharedClient() +func TestAccCloudflareAccessMutualTLSHostnameSettings_Zone(t *testing.T) { + // 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", "") + } - for _, rs := range s.RootModule().Resources { - if rs.Type != "cloudflare_zero_trust_access_mtls_hostname_settings" { - continue - } + rnd := utils.GenerateRandomResourceName() + name := fmt.Sprintf("cloudflare_zero_trust_access_mtls_hostname_settings.%s", rnd) + domain := os.Getenv("CLOUDFLARE_DOMAIN") + zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") - for _, rs := range s.RootModule().Resources { - certificates, _ := client.ZeroTrust.Access.Certificates.Get(context.Background(), rs.Primary.Attributes["id"], zero_trust.AccessCertificateGetParams{ - AccountID: cfv2.F(rs.Primary.Attributes[consts.AccountIDSchemaKey]), - }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.TestAccPreCheck(t) + acctest.TestAccPreCheck_ZoneID(t) + }, + ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccessMutualTLSHostnameSettingsConfig(rnd, cfv1.ZoneIdentifier(zoneID), domain), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New(consts.ZoneIDSchemaKey), knownvalue.StringExact(zoneID)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("hostname"), knownvalue.StringExact(domain)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(true)), + }, + }, + }, + }) +} - if certificates != nil { - return fmt.Errorf("access_mtls_hostname_settings still exists") - } - } +func TestAccCloudflareAccessMutualTLSHostnameSettings_MultipleHostnames(t *testing.T) { + // 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", "") } - return nil + rnd := utils.GenerateRandomResourceName() + name := fmt.Sprintf("cloudflare_zero_trust_access_mtls_hostname_settings.%s", rnd) + domain := os.Getenv("CLOUDFLARE_DOMAIN") + accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") + secondHostname := fmt.Sprintf("test.%s", domain) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.TestAccPreCheck(t) + acctest.TestAccPreCheck_AccountID(t) + }, + ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccessMutualTLSHostnameSettingsMultipleConfig(rnd, cfv1.AccountIdentifier(accountID), domain, secondHostname), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("hostname"), knownvalue.StringExact(domain)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(true)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(1).AtMapKey("hostname"), knownvalue.StringExact(secondHostname)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(1).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(1).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(false)), + }, + }, + }, + }) +} + +func TestAccCloudflareAccessMutualTLSHostnameSettings_Update(t *testing.T) { + // 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", "") + } + + rnd := utils.GenerateRandomResourceName() + name := fmt.Sprintf("cloudflare_zero_trust_access_mtls_hostname_settings.%s", rnd) + domain := os.Getenv("CLOUDFLARE_DOMAIN") + accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.TestAccPreCheck(t) + acctest.TestAccPreCheck_AccountID(t) + }, + ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccessMutualTLSHostnameSettingsConfig(rnd, cfv1.AccountIdentifier(accountID), domain), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("hostname"), knownvalue.StringExact(domain)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(true)), + }, + }, + { + Config: testAccessMutualTLSHostnameSettingsUpdatedConfig(rnd, cfv1.AccountIdentifier(accountID), domain), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("hostname"), knownvalue.StringExact(domain)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(false)), + }, + }, + }, + }) +} + +func TestAccCloudflareAccessMutualTLSHostnameSettings_BooleanCombinations(t *testing.T) { + // 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", "") + } + + rnd := utils.GenerateRandomResourceName() + name := fmt.Sprintf("cloudflare_zero_trust_access_mtls_hostname_settings.%s", rnd) + domain := os.Getenv("CLOUDFLARE_DOMAIN") + accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.TestAccPreCheck(t) + acctest.TestAccPreCheck_AccountID(t) + }, + ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + // Test all false values + Config: testAccessMutualTLSHostnameSettingsBooleanConfig(rnd, cfv1.AccountIdentifier(accountID), domain, false, false), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(false)), + }, + }, + { + // Test client_certificate_forwarding = true, china_network = false + Config: testAccessMutualTLSHostnameSettingsBooleanConfig(rnd, cfv1.AccountIdentifier(accountID), domain, false, true), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(true)), + }, + }, + { + // Test both false (reset to baseline) + Config: testAccessMutualTLSHostnameSettingsBooleanConfig(rnd, cfv1.AccountIdentifier(accountID), domain, false, false), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(false)), + }, + }, + }, + }) +} + +func TestAccCloudflareAccessMutualTLSHostnameSettings_Import(t *testing.T) { + // 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", "") + } + + rnd := utils.GenerateRandomResourceName() + name := fmt.Sprintf("cloudflare_zero_trust_access_mtls_hostname_settings.%s", rnd) + domain := os.Getenv("CLOUDFLARE_DOMAIN") + accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.TestAccPreCheck(t) + acctest.TestAccPreCheck_AccountID(t) + }, + ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccessMutualTLSHostnameSettingsConfig(rnd, cfv1.AccountIdentifier(accountID), domain), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(name, tfjsonpath.New(consts.AccountIDSchemaKey), knownvalue.StringExact(accountID)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("hostname"), knownvalue.StringExact(domain)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("china_network"), knownvalue.Bool(false)), + statecheck.ExpectKnownValue(name, tfjsonpath.New("settings").AtSliceIndex(0).AtMapKey("client_certificate_forwarding"), knownvalue.Bool(true)), + }, + }, + { + ResourceName: name, + ImportState: true, + ImportStateVerify: true, + ImportStateId: accountID, + ImportStateVerifyIdentifierAttribute: "account_id", + ImportStateVerifyIgnore: []string{"settings"}, + }, + }, + }) } func testAccessMutualTLSHostnameSettingsConfig(rnd string, identifier *cfv1.ResourceContainer, domain string) string { return acctest.LoadTestCase("accessmutualtlshostnamesettingsconfig.tf", rnd, identifier.Type, identifier.Identifier, domain) } + +func testAccessMutualTLSHostnameSettingsMultipleConfig(rnd string, identifier *cfv1.ResourceContainer, domain, secondHostname string) string { + return fmt.Sprintf(` +resource "cloudflare_zero_trust_access_mtls_hostname_settings" "%[1]s" { + %[2]s_id = "%[3]s" + settings = [ + { + hostname = "%[4]s" + client_certificate_forwarding = true + china_network = false + }, + { + hostname = "%[5]s" + client_certificate_forwarding = false + china_network = false + } + ] +} +`, rnd, identifier.Type, identifier.Identifier, domain, secondHostname) +} + +func testAccessMutualTLSHostnameSettingsUpdatedConfig(rnd string, identifier *cfv1.ResourceContainer, domain string) string { + return fmt.Sprintf(` +resource "cloudflare_zero_trust_access_mtls_hostname_settings" "%[1]s" { + %[2]s_id = "%[3]s" + settings = [{ + hostname = "%[4]s" + client_certificate_forwarding = false + china_network = false + }] +} +`, rnd, identifier.Type, identifier.Identifier, domain) +} + +func testAccessMutualTLSHostnameSettingsBooleanConfig(rnd string, identifier *cfv1.ResourceContainer, domain string, chinaNetwork, clientCertForwarding bool) string { + return fmt.Sprintf(` +resource "cloudflare_zero_trust_access_mtls_hostname_settings" "%[1]s" { + %[2]s_id = "%[3]s" + settings = [{ + hostname = "%[4]s" + client_certificate_forwarding = %[5]t + china_network = %[6]t + }] +} +`, rnd, identifier.Type, identifier.Identifier, domain, clientCertForwarding, chinaNetwork) +}