From 685389c83436a19cce0ee4e58d51df958876fe82 Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Fri, 11 Nov 2022 00:07:43 +0000 Subject: [PATCH] Add support for network_firewall_policy_association and region_network_firewall_policy_association (#6796) Co-authored-by: Riley Karson Co-authored-by: Ghaleb Al-habian Signed-off-by: Modular Magician --- .changelog/6796.txt | 6 + google/provider_dcl_resources.go | 64 ++-- ...ute_network_firewall_policy_association.go | 250 ++++++++++++++++ ...ewall_policy_association_generated_test.go | 143 +++++++++ ...ion_network_firewall_policy_association.go | 276 ++++++++++++++++++ ...ewall_policy_association_generated_test.go | 149 ++++++++++ ..._firewall_policy_association.html.markdown | 100 +++++++ ..._firewall_policy_association.html.markdown | 106 +++++++ 8 files changed, 1063 insertions(+), 31 deletions(-) create mode 100644 .changelog/6796.txt create mode 100644 google/resource_compute_network_firewall_policy_association.go create mode 100644 google/resource_compute_network_firewall_policy_association_generated_test.go create mode 100644 google/resource_compute_region_network_firewall_policy_association.go create mode 100644 google/resource_compute_region_network_firewall_policy_association_generated_test.go create mode 100644 website/docs/r/compute_network_firewall_policy_association.html.markdown create mode 100644 website/docs/r/compute_region_network_firewall_policy_association.html.markdown diff --git a/.changelog/6796.txt b/.changelog/6796.txt new file mode 100644 index 00000000000..66aefbaf488 --- /dev/null +++ b/.changelog/6796.txt @@ -0,0 +1,6 @@ +```release-note:new-resource +`google_compute_network_firewall_policy_association` +``` +```release-note:new-resource +`google_compute_region_network_firewall_policy_association` +``` diff --git a/google/provider_dcl_resources.go b/google/provider_dcl_resources.go index 505bb1bfa9d..4fb2bf356fb 100644 --- a/google/provider_dcl_resources.go +++ b/google/provider_dcl_resources.go @@ -20,35 +20,37 @@ import ( ) var dclResources = map[string]*schema.Resource{ - "google_apikeys_key": resourceApikeysKey(), - "google_assured_workloads_workload": resourceAssuredWorkloadsWorkload(), - "google_bigquery_reservation_assignment": resourceBigqueryReservationAssignment(), - "google_cloudbuild_worker_pool": resourceCloudbuildWorkerPool(), - "google_clouddeploy_delivery_pipeline": resourceClouddeployDeliveryPipeline(), - "google_clouddeploy_target": resourceClouddeployTarget(), - "google_compute_firewall_policy": resourceComputeFirewallPolicy(), - "google_compute_firewall_policy_association": resourceComputeFirewallPolicyAssociation(), - "google_compute_firewall_policy_rule": resourceComputeFirewallPolicyRule(), - "google_compute_region_network_firewall_policy": resourceComputeRegionNetworkFirewallPolicy(), - "google_compute_network_firewall_policy": resourceComputeNetworkFirewallPolicy(), - "google_container_aws_cluster": resourceContainerAwsCluster(), - "google_container_aws_node_pool": resourceContainerAwsNodePool(), - "google_container_azure_client": resourceContainerAzureClient(), - "google_container_azure_cluster": resourceContainerAzureCluster(), - "google_container_azure_node_pool": resourceContainerAzureNodePool(), - "google_dataplex_asset": resourceDataplexAsset(), - "google_dataplex_lake": resourceDataplexLake(), - "google_dataplex_zone": resourceDataplexZone(), - "google_dataproc_workflow_template": resourceDataprocWorkflowTemplate(), - "google_eventarc_trigger": resourceEventarcTrigger(), - "google_firebaserules_release": resourceFirebaserulesRelease(), - "google_firebaserules_ruleset": resourceFirebaserulesRuleset(), - "google_logging_log_view": resourceLoggingLogView(), - "google_monitoring_monitored_project": resourceMonitoringMonitoredProject(), - "google_network_connectivity_hub": resourceNetworkConnectivityHub(), - "google_network_connectivity_spoke": resourceNetworkConnectivitySpoke(), - "google_org_policy_policy": resourceOrgPolicyPolicy(), - "google_os_config_os_policy_assignment": resourceOsConfigOsPolicyAssignment(), - "google_privateca_certificate_template": resourcePrivatecaCertificateTemplate(), - "google_recaptcha_enterprise_key": resourceRecaptchaEnterpriseKey(), + "google_apikeys_key": resourceApikeysKey(), + "google_assured_workloads_workload": resourceAssuredWorkloadsWorkload(), + "google_bigquery_reservation_assignment": resourceBigqueryReservationAssignment(), + "google_cloudbuild_worker_pool": resourceCloudbuildWorkerPool(), + "google_clouddeploy_delivery_pipeline": resourceClouddeployDeliveryPipeline(), + "google_clouddeploy_target": resourceClouddeployTarget(), + "google_compute_firewall_policy": resourceComputeFirewallPolicy(), + "google_compute_firewall_policy_association": resourceComputeFirewallPolicyAssociation(), + "google_compute_firewall_policy_rule": resourceComputeFirewallPolicyRule(), + "google_compute_region_network_firewall_policy": resourceComputeRegionNetworkFirewallPolicy(), + "google_compute_network_firewall_policy": resourceComputeNetworkFirewallPolicy(), + "google_compute_network_firewall_policy_association": resourceComputeNetworkFirewallPolicyAssociation(), + "google_compute_region_network_firewall_policy_association": resourceComputeRegionNetworkFirewallPolicyAssociation(), + "google_container_aws_cluster": resourceContainerAwsCluster(), + "google_container_aws_node_pool": resourceContainerAwsNodePool(), + "google_container_azure_client": resourceContainerAzureClient(), + "google_container_azure_cluster": resourceContainerAzureCluster(), + "google_container_azure_node_pool": resourceContainerAzureNodePool(), + "google_dataplex_asset": resourceDataplexAsset(), + "google_dataplex_lake": resourceDataplexLake(), + "google_dataplex_zone": resourceDataplexZone(), + "google_dataproc_workflow_template": resourceDataprocWorkflowTemplate(), + "google_eventarc_trigger": resourceEventarcTrigger(), + "google_firebaserules_release": resourceFirebaserulesRelease(), + "google_firebaserules_ruleset": resourceFirebaserulesRuleset(), + "google_logging_log_view": resourceLoggingLogView(), + "google_monitoring_monitored_project": resourceMonitoringMonitoredProject(), + "google_network_connectivity_hub": resourceNetworkConnectivityHub(), + "google_network_connectivity_spoke": resourceNetworkConnectivitySpoke(), + "google_org_policy_policy": resourceOrgPolicyPolicy(), + "google_os_config_os_policy_assignment": resourceOsConfigOsPolicyAssignment(), + "google_privateca_certificate_template": resourcePrivatecaCertificateTemplate(), + "google_recaptcha_enterprise_key": resourceRecaptchaEnterpriseKey(), } diff --git a/google/resource_compute_network_firewall_policy_association.go b/google/resource_compute_network_firewall_policy_association.go new file mode 100644 index 00000000000..41ebc29a543 --- /dev/null +++ b/google/resource_compute_network_firewall_policy_association.go @@ -0,0 +1,250 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl" + compute "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/compute" +) + +func resourceComputeNetworkFirewallPolicyAssociation() *schema.Resource { + return &schema.Resource{ + Create: resourceComputeNetworkFirewallPolicyAssociationCreate, + Read: resourceComputeNetworkFirewallPolicyAssociationRead, + Delete: resourceComputeNetworkFirewallPolicyAssociationDelete, + + Importer: &schema.ResourceImporter{ + State: resourceComputeNetworkFirewallPolicyAssociationImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "attachment_target": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The target that the firewall policy is attached to.", + }, + + "firewall_policy": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The firewall policy ID of the association.", + }, + + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The name for an association.", + }, + + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The project for the resource", + }, + + "short_name": { + Type: schema.TypeString, + Computed: true, + Description: "The short name of the firewall policy of the association.", + }, + }, + } +} + +func resourceComputeNetworkFirewallPolicyAssociationCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &compute.NetworkFirewallPolicyAssociation{ + AttachmentTarget: dcl.String(d.Get("attachment_target").(string)), + FirewallPolicy: dcl.String(d.Get("firewall_policy").(string)), + Name: dcl.String(d.Get("name").(string)), + Project: dcl.String(project), + } + + id, err := replaceVarsForId(d, config, "projects/{{project}}/global/firewallPolicies/{{firewall_policy}}/associations/{{name}}") + if err != nil { + return fmt.Errorf("error constructing id: %s", err) + } + d.SetId(id) + directive := CreateDirective + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLComputeClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutCreate)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.ApplyNetworkFirewallPolicyAssociation(context.Background(), obj, directive...) + + if _, ok := err.(dcl.DiffAfterApplyError); ok { + log.Printf("[DEBUG] Diff after apply returned from the DCL: %s", err) + } else if err != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error creating NetworkFirewallPolicyAssociation: %s", err) + } + + log.Printf("[DEBUG] Finished creating NetworkFirewallPolicyAssociation %q: %#v", d.Id(), res) + + return resourceComputeNetworkFirewallPolicyAssociationRead(d, meta) +} + +func resourceComputeNetworkFirewallPolicyAssociationRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &compute.NetworkFirewallPolicyAssociation{ + AttachmentTarget: dcl.String(d.Get("attachment_target").(string)), + FirewallPolicy: dcl.String(d.Get("firewall_policy").(string)), + Name: dcl.String(d.Get("name").(string)), + Project: dcl.String(project), + } + + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLComputeClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutRead)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.GetNetworkFirewallPolicyAssociation(context.Background(), obj) + if err != nil { + resourceName := fmt.Sprintf("ComputeNetworkFirewallPolicyAssociation %q", d.Id()) + return handleNotFoundDCLError(err, d, resourceName) + } + + if err = d.Set("attachment_target", res.AttachmentTarget); err != nil { + return fmt.Errorf("error setting attachment_target in state: %s", err) + } + if err = d.Set("firewall_policy", res.FirewallPolicy); err != nil { + return fmt.Errorf("error setting firewall_policy in state: %s", err) + } + if err = d.Set("name", res.Name); err != nil { + return fmt.Errorf("error setting name in state: %s", err) + } + if err = d.Set("project", res.Project); err != nil { + return fmt.Errorf("error setting project in state: %s", err) + } + if err = d.Set("short_name", res.ShortName); err != nil { + return fmt.Errorf("error setting short_name in state: %s", err) + } + + return nil +} + +func resourceComputeNetworkFirewallPolicyAssociationDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := &compute.NetworkFirewallPolicyAssociation{ + AttachmentTarget: dcl.String(d.Get("attachment_target").(string)), + FirewallPolicy: dcl.String(d.Get("firewall_policy").(string)), + Name: dcl.String(d.Get("name").(string)), + Project: dcl.String(project), + } + + log.Printf("[DEBUG] Deleting NetworkFirewallPolicyAssociation %q", d.Id()) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLComputeClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutDelete)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + if err := client.DeleteNetworkFirewallPolicyAssociation(context.Background(), obj); err != nil { + return fmt.Errorf("Error deleting NetworkFirewallPolicyAssociation: %s", err) + } + + log.Printf("[DEBUG] Finished deleting NetworkFirewallPolicyAssociation %q", d.Id()) + return nil +} + +func resourceComputeNetworkFirewallPolicyAssociationImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + + if err := parseImportId([]string{ + "projects/(?P[^/]+)/global/firewallPolicies/(?P[^/]+)/associations/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVarsForId(d, config, "projects/{{project}}/global/firewallPolicies/{{firewall_policy}}/associations/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} diff --git a/google/resource_compute_network_firewall_policy_association_generated_test.go b/google/resource_compute_network_firewall_policy_association_generated_test.go new file mode 100644 index 00000000000..f1eb70a07ac --- /dev/null +++ b/google/resource_compute_network_firewall_policy_association_generated_test.go @@ -0,0 +1,143 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "fmt" + dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl" + compute "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/compute" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "strings" + "testing" +) + +func TestAccComputeNetworkFirewallPolicyAssociation_GlobalHandWritten(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeNetworkFirewallPolicyAssociationDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeNetworkFirewallPolicyAssociation_GlobalHandWritten(context), + }, + { + ResourceName: "google_compute_network_firewall_policy_association.primary", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccComputeNetworkFirewallPolicyAssociation_GlobalHandWrittenUpdate0(context), + }, + { + ResourceName: "google_compute_network_firewall_policy_association.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccComputeNetworkFirewallPolicyAssociation_GlobalHandWritten(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_network_firewall_policy" "network_firewall_policy" { + name = "tf-test-policy%{random_suffix}" + project = "%{project_name}" + description = "Sample global network firewall policy" +} + +resource "google_compute_network" "network" { + name = "tf-test-network%{random_suffix}" +} + +resource "google_compute_network_firewall_policy_association" "primary" { + name = "tf-test-association%{random_suffix}" + attachment_target = google_compute_network.network.id + firewall_policy = google_compute_network_firewall_policy.network_firewall_policy.name + project = "%{project_name}" +} + +`, context) +} + +func testAccComputeNetworkFirewallPolicyAssociation_GlobalHandWrittenUpdate0(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_network_firewall_policy" "network_firewall_policy" { + name = "tf-test-policy%{random_suffix}" + project = "%{project_name}" + description = "Sample global network firewall policy" +} + +resource "google_compute_network" "network" { + name = "tf-test-network%{random_suffix}" +} + +resource "google_compute_network" "network2" { + name = "update-tf-test-network%{random_suffix}" +} + +resource "google_compute_network_firewall_policy_association" "primary" { + name = "tf-test-association%{random_suffix}" + attachment_target = google_compute_network.network2.id + firewall_policy = google_compute_network_firewall_policy.network_firewall_policy.name + project = "%{project_name}" +} + +`, context) +} + +func testAccCheckComputeNetworkFirewallPolicyAssociationDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "rs.google_compute_network_firewall_policy_association" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + billingProject := "" + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + obj := &compute.NetworkFirewallPolicyAssociation{ + AttachmentTarget: dcl.String(rs.Primary.Attributes["attachment_target"]), + FirewallPolicy: dcl.String(rs.Primary.Attributes["firewall_policy"]), + Name: dcl.String(rs.Primary.Attributes["name"]), + Project: dcl.StringOrNil(rs.Primary.Attributes["project"]), + ShortName: dcl.StringOrNil(rs.Primary.Attributes["short_name"]), + } + + client := NewDCLComputeClient(config, config.userAgent, billingProject, 0) + _, err := client.GetNetworkFirewallPolicyAssociation(context.Background(), obj) + if err == nil { + return fmt.Errorf("google_compute_network_firewall_policy_association still exists %v", obj) + } + } + return nil + } +} diff --git a/google/resource_compute_region_network_firewall_policy_association.go b/google/resource_compute_region_network_firewall_policy_association.go new file mode 100644 index 00000000000..243b2aeb869 --- /dev/null +++ b/google/resource_compute_region_network_firewall_policy_association.go @@ -0,0 +1,276 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl" + compute "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/compute" +) + +func resourceComputeRegionNetworkFirewallPolicyAssociation() *schema.Resource { + return &schema.Resource{ + Create: resourceComputeRegionNetworkFirewallPolicyAssociationCreate, + Read: resourceComputeRegionNetworkFirewallPolicyAssociationRead, + Delete: resourceComputeRegionNetworkFirewallPolicyAssociationDelete, + + Importer: &schema.ResourceImporter{ + State: resourceComputeRegionNetworkFirewallPolicyAssociationImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "attachment_target": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The target that the firewall policy is attached to.", + }, + + "firewall_policy": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The firewall policy ID of the association.", + }, + + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The name for an association.", + }, + + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + DiffSuppressFunc: compareSelfLinkOrResourceName, + Description: "The project for the resource", + }, + + "region": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: "The location of this resource.", + }, + + "short_name": { + Type: schema.TypeString, + Computed: true, + Description: "The short name of the firewall policy of the association.", + }, + }, + } +} + +func resourceComputeRegionNetworkFirewallPolicyAssociationCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + region, err := getRegion(d, config) + if err != nil { + return err + } + + obj := &compute.NetworkFirewallPolicyAssociation{ + AttachmentTarget: dcl.String(d.Get("attachment_target").(string)), + FirewallPolicy: dcl.String(d.Get("firewall_policy").(string)), + Name: dcl.String(d.Get("name").(string)), + Project: dcl.String(project), + Location: dcl.String(region), + } + + id, err := replaceVarsForId(d, config, "projects/{{project}}/regions/{{region}}/firewallPolicies/{{firewall_policy}}/associations/{{name}}") + if err != nil { + return fmt.Errorf("error constructing id: %s", err) + } + d.SetId(id) + directive := CreateDirective + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLComputeClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutCreate)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.ApplyNetworkFirewallPolicyAssociation(context.Background(), obj, directive...) + + if _, ok := err.(dcl.DiffAfterApplyError); ok { + log.Printf("[DEBUG] Diff after apply returned from the DCL: %s", err) + } else if err != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error creating NetworkFirewallPolicyAssociation: %s", err) + } + + log.Printf("[DEBUG] Finished creating NetworkFirewallPolicyAssociation %q: %#v", d.Id(), res) + + return resourceComputeRegionNetworkFirewallPolicyAssociationRead(d, meta) +} + +func resourceComputeRegionNetworkFirewallPolicyAssociationRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + region, err := getRegion(d, config) + if err != nil { + return err + } + + obj := &compute.NetworkFirewallPolicyAssociation{ + AttachmentTarget: dcl.String(d.Get("attachment_target").(string)), + FirewallPolicy: dcl.String(d.Get("firewall_policy").(string)), + Name: dcl.String(d.Get("name").(string)), + Project: dcl.String(project), + Location: dcl.String(region), + } + + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLComputeClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutRead)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + res, err := client.GetNetworkFirewallPolicyAssociation(context.Background(), obj) + if err != nil { + resourceName := fmt.Sprintf("ComputeRegionNetworkFirewallPolicyAssociation %q", d.Id()) + return handleNotFoundDCLError(err, d, resourceName) + } + + if err = d.Set("attachment_target", res.AttachmentTarget); err != nil { + return fmt.Errorf("error setting attachment_target in state: %s", err) + } + if err = d.Set("firewall_policy", res.FirewallPolicy); err != nil { + return fmt.Errorf("error setting firewall_policy in state: %s", err) + } + if err = d.Set("name", res.Name); err != nil { + return fmt.Errorf("error setting name in state: %s", err) + } + if err = d.Set("project", res.Project); err != nil { + return fmt.Errorf("error setting project in state: %s", err) + } + if err = d.Set("region", res.Location); err != nil { + return fmt.Errorf("error setting region in state: %s", err) + } + if err = d.Set("short_name", res.ShortName); err != nil { + return fmt.Errorf("error setting short_name in state: %s", err) + } + + return nil +} + +func resourceComputeRegionNetworkFirewallPolicyAssociationDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + project, err := getProject(d, config) + if err != nil { + return err + } + region, err := getRegion(d, config) + if err != nil { + return err + } + + obj := &compute.NetworkFirewallPolicyAssociation{ + AttachmentTarget: dcl.String(d.Get("attachment_target").(string)), + FirewallPolicy: dcl.String(d.Get("firewall_policy").(string)), + Name: dcl.String(d.Get("name").(string)), + Project: dcl.String(project), + Location: dcl.String(region), + } + + log.Printf("[DEBUG] Deleting NetworkFirewallPolicyAssociation %q", d.Id()) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + billingProject := project + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + client := NewDCLComputeClient(config, userAgent, billingProject, d.Timeout(schema.TimeoutDelete)) + if bp, err := replaceVars(d, config, client.Config.BasePath); err != nil { + d.SetId("") + return fmt.Errorf("Could not format %q: %w", client.Config.BasePath, err) + } else { + client.Config.BasePath = bp + } + if err := client.DeleteNetworkFirewallPolicyAssociation(context.Background(), obj); err != nil { + return fmt.Errorf("Error deleting NetworkFirewallPolicyAssociation: %s", err) + } + + log.Printf("[DEBUG] Finished deleting NetworkFirewallPolicyAssociation %q", d.Id()) + return nil +} + +func resourceComputeRegionNetworkFirewallPolicyAssociationImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + + if err := parseImportId([]string{ + "projects/(?P[^/]+)/regions/(?P[^/]+)/firewallPolicies/(?P[^/]+)/associations/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVarsForId(d, config, "projects/{{project}}/regions/{{region}}/firewallPolicies/{{firewall_policy}}/associations/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} diff --git a/google/resource_compute_region_network_firewall_policy_association_generated_test.go b/google/resource_compute_region_network_firewall_policy_association_generated_test.go new file mode 100644 index 00000000000..a40c14160b2 --- /dev/null +++ b/google/resource_compute_region_network_firewall_policy_association_generated_test.go @@ -0,0 +1,149 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: DCL *** +// +// ---------------------------------------------------------------------------- +// +// This file is managed by Magic Modules (https://github.com/GoogleCloudPlatform/magic-modules) +// and is based on the DCL (https://github.com/GoogleCloudPlatform/declarative-resource-client-library). +// Changes will need to be made to the DCL or Magic Modules instead of here. +// +// We are not currently able to accept contributions to this file. If changes +// are required, please file an issue at https://github.com/hashicorp/terraform-provider-google/issues/new/choose +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "context" + "fmt" + dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl" + compute "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/compute" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "strings" + "testing" +) + +func TestAccComputeRegionNetworkFirewallPolicyAssociation_RegionalHandWritten(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project_name": getTestProjectFromEnv(), + "region": getTestRegionFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeRegionNetworkFirewallPolicyAssociationDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeRegionNetworkFirewallPolicyAssociation_RegionalHandWritten(context), + }, + { + ResourceName: "google_compute_region_network_firewall_policy_association.primary", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccComputeRegionNetworkFirewallPolicyAssociation_RegionalHandWrittenUpdate0(context), + }, + { + ResourceName: "google_compute_region_network_firewall_policy_association.primary", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccComputeRegionNetworkFirewallPolicyAssociation_RegionalHandWritten(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_region_network_firewall_policy" "basic_regional_network_firewall_policy" { + name = "tf-test-policy%{random_suffix}" + project = "%{project_name}" + description = "Sample global network firewall policy" + region = "%{region}" +} + +resource "google_compute_network" "basic_network" { + name = "tf-test-network%{random_suffix}" +} + +resource "google_compute_region_network_firewall_policy_association" "primary" { + name = "tf-test-association%{random_suffix}" + attachment_target = google_compute_network.basic_network.id + firewall_policy = google_compute_region_network_firewall_policy.basic_regional_network_firewall_policy.name + project = "%{project_name}" + region = "%{region}" +} + +`, context) +} + +func testAccComputeRegionNetworkFirewallPolicyAssociation_RegionalHandWrittenUpdate0(context map[string]interface{}) string { + return Nprintf(` +resource "google_compute_region_network_firewall_policy" "basic_regional_network_firewall_policy" { + name = "tf-test-policy%{random_suffix}" + project = "%{project_name}" + description = "Sample global network firewall policy" + region = "%{region}" +} + +resource "google_compute_network" "basic_network" { + name = "tf-test-network%{random_suffix}" +} + +resource "google_compute_network" "basic_network2" { + name = "update-tf-test-network%{random_suffix}" +} + +resource "google_compute_region_network_firewall_policy_association" "primary" { + name = "tf-test-association%{random_suffix}" + attachment_target = google_compute_network.basic_network2.id + firewall_policy = google_compute_region_network_firewall_policy.basic_regional_network_firewall_policy.name + project = "%{project_name}" + region = "%{region}" +} + +`, context) +} + +func testAccCheckComputeRegionNetworkFirewallPolicyAssociationDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "rs.google_compute_region_network_firewall_policy_association" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + billingProject := "" + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + obj := &compute.NetworkFirewallPolicyAssociation{ + AttachmentTarget: dcl.String(rs.Primary.Attributes["attachment_target"]), + FirewallPolicy: dcl.String(rs.Primary.Attributes["firewall_policy"]), + Name: dcl.String(rs.Primary.Attributes["name"]), + Project: dcl.StringOrNil(rs.Primary.Attributes["project"]), + Location: dcl.StringOrNil(rs.Primary.Attributes["region"]), + ShortName: dcl.StringOrNil(rs.Primary.Attributes["short_name"]), + } + + client := NewDCLComputeClient(config, config.userAgent, billingProject, 0) + _, err := client.GetNetworkFirewallPolicyAssociation(context.Background(), obj) + if err == nil { + return fmt.Errorf("google_compute_region_network_firewall_policy_association still exists %v", obj) + } + } + return nil + } +} diff --git a/website/docs/r/compute_network_firewall_policy_association.html.markdown b/website/docs/r/compute_network_firewall_policy_association.html.markdown new file mode 100644 index 00000000000..65bd02031d6 --- /dev/null +++ b/website/docs/r/compute_network_firewall_policy_association.html.markdown @@ -0,0 +1,100 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: DCL *** +# +# ---------------------------------------------------------------------------- +# +# This file is managed by Magic Modules (https:#github.com/GoogleCloudPlatform/magic-modules) +# and is based on the DCL (https:#github.com/GoogleCloudPlatform/declarative-resource-client-library). +# Changes will need to be made to the DCL or Magic Modules instead of here. +# +# We are not currently able to accept contributions to this file. If changes +# are required, please file an issue at https:#github.com/hashicorp/terraform-provider-google/issues/new/choose +# +# ---------------------------------------------------------------------------- +subcategory: "Compute Engine" +page_title: "Google: google_compute_network_firewall_policy_association" +description: |- + The Compute NetworkFirewallPolicyAssociation resource +--- + +# google_compute_network_firewall_policy_association + +The Compute NetworkFirewallPolicyAssociation resource + +## Example Usage - global +```hcl +resource "google_compute_network_firewall_policy" "network_firewall_policy" { + name = "policy" + project = "my-project-name" + description = "Sample global network firewall policy" +} + +resource "google_compute_network" "network" { + name = "network" +} + +resource "google_compute_network_firewall_policy_association" "primary" { + name = "association" + attachment_target = google_compute_network.network.id + firewall_policy = google_compute_network_firewall_policy.network_firewall_policy.name + project = "my-project-name" +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `attachment_target` - + (Required) + The target that the firewall policy is attached to. + +* `firewall_policy` - + (Required) + The firewall policy ID of the association. + +* `name` - + (Required) + The name for an association. + + + +- - - + +* `project` - + (Optional) + The project for the resource + + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/global/firewallPolicies/{{firewall_policy}}/associations/{{name}}` + +* `short_name` - + The short name of the firewall policy of the association. + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + +NetworkFirewallPolicyAssociation can be imported using any of these accepted formats: + +``` +$ terraform import google_compute_network_firewall_policy_association.default projects/{{project}}/global/firewallPolicies/{{firewall_policy}}/associations/{{name}} +$ terraform import google_compute_network_firewall_policy_association.default {{project}}/{{firewall_policy}}/{{name}} +``` + + + diff --git a/website/docs/r/compute_region_network_firewall_policy_association.html.markdown b/website/docs/r/compute_region_network_firewall_policy_association.html.markdown new file mode 100644 index 00000000000..17b1b574b22 --- /dev/null +++ b/website/docs/r/compute_region_network_firewall_policy_association.html.markdown @@ -0,0 +1,106 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: DCL *** +# +# ---------------------------------------------------------------------------- +# +# This file is managed by Magic Modules (https:#github.com/GoogleCloudPlatform/magic-modules) +# and is based on the DCL (https:#github.com/GoogleCloudPlatform/declarative-resource-client-library). +# Changes will need to be made to the DCL or Magic Modules instead of here. +# +# We are not currently able to accept contributions to this file. If changes +# are required, please file an issue at https:#github.com/hashicorp/terraform-provider-google/issues/new/choose +# +# ---------------------------------------------------------------------------- +subcategory: "Compute Engine" +page_title: "Google: google_compute_region_network_firewall_policy_association" +description: |- + The Compute NetworkFirewallPolicyAssociation resource +--- + +# google_compute_region_network_firewall_policy_association + +The Compute NetworkFirewallPolicyAssociation resource + +## Example Usage - regional +```hcl +resource "google_compute_region_network_firewall_policy" "basic_regional_network_firewall_policy" { + name = "policy" + project = "my-project-name" + description = "Sample global network firewall policy" + region = "us-west1" +} + +resource "google_compute_network" "basic_network" { + name = "network" +} + +resource "google_compute_region_network_firewall_policy_association" "primary" { + name = "association" + attachment_target = google_compute_network.basic_network.id + firewall_policy = google_compute_region_network_firewall_policy.basic_regional_network_firewall_policy.name + project = "my-project-name" + region = "us-west1" +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `attachment_target` - + (Required) + The target that the firewall policy is attached to. + +* `firewall_policy` - + (Required) + The firewall policy ID of the association. + +* `name` - + (Required) + The name for an association. + + + +- - - + +* `region` - + (Optional) + The location of this resource. + +* `project` - + (Optional) + The project for the resource + + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/regions/{{region}}/firewallPolicies/{{firewall_policy}}/associations/{{name}}` + +* `short_name` - + The short name of the firewall policy of the association. + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + +NetworkFirewallPolicyAssociation can be imported using any of these accepted formats: + +``` +$ terraform import google_compute_region_network_firewall_policy_association.default projects/{{project}}/regions/{{region}}/firewallPolicies/{{firewall_policy}}/associations/{{name}} +$ terraform import google_compute_region_network_firewall_policy_association.default {{project}}/{{region}}/{{firewall_policy}}/{{name}} +``` + + +