diff --git a/mmv1/third_party/terraform/resources/resource_compute_security_policy.go.erb b/mmv1/third_party/terraform/resources/resource_compute_security_policy.go.erb index bfd1151e139e..079b4ae5348a 100644 --- a/mmv1/third_party/terraform/resources/resource_compute_security_policy.go.erb +++ b/mmv1/third_party/terraform/resources/resource_compute_security_policy.go.erb @@ -11,7 +11,11 @@ import ( "github.com/hashicorp/errwrap" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +<% if version == 'ga' -%> "google.golang.org/api/compute/v1" +<% else -%> + "google.golang.org/api/compute/v0.beta" +<% end -%> ) func resourceComputeSecurityPolicy() *schema.Resource { @@ -166,7 +170,43 @@ func resourceComputeSecurityPolicy() *schema.Resource { Computed: true, Description: `The URI of the created resource.`, }, + + <% unless version == 'ga' -%> + "adaptive_protection_config": { + Type: schema.TypeList, + Optional: true, + Description: `Adaptive Protection Config of this security policy.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "layer_7_ddos_defense_config": { + Type: schema.TypeList, + Description: `Layer 7 DDoS Defense Config of this security policy`, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enable": { + Type: schema.TypeBool, + Optional: true, + Description: `If set to true, enables CAAP for L7 DDoS detection.`, + }, + "rule_visibility": { + Type: schema.TypeString, + Optional: true, + Default: "STANDARD", + ValidateFunc: validation.StringInSlice([]string{"STANDARD", "PREMIUM"}, false), + Description: `Rule visibility. Supported values include: "STANDARD", "PREMIUM".`, + }, + }, + }, + }, + }, + }, + }, + <% end -%> }, + UseJSONNumber: true, } } @@ -208,9 +248,21 @@ func resourceComputeSecurityPolicyCreate(d *schema.ResourceData, meta interface{ securityPolicy.Rules = expandSecurityPolicyRules(v.(*schema.Set).List()) } +<% unless version == 'ga' -%> + if v, ok := d.GetOk("adaptive_protection_config"); ok{ + securityPolicy.AdaptiveProtectionConfig = expandSecurityPolicyAdaptiveProtectionConfig(v.([]interface{})) + } +<% end -%> + log.Printf("[DEBUG] SecurityPolicy insert request: %#v", securityPolicy) - op, err := config.NewComputeClient(userAgent).SecurityPolicies.Insert(project, securityPolicy).Do() +<% if version == 'ga' -%> + client := config.NewComputeClient(userAgent) +<% else -%> + client := config.NewComputeBetaClient(userAgent) +<% end -%> + + op, err := client.SecurityPolicies.Insert(project, securityPolicy).Do() if err != nil { return errwrap.Wrapf("Error creating SecurityPolicy: {{err}}", err) @@ -243,7 +295,14 @@ func resourceComputeSecurityPolicyRead(d *schema.ResourceData, meta interface{}) } sp := d.Get("name").(string) - securityPolicy, err := config.NewComputeClient(userAgent).SecurityPolicies.Get(project, sp).Do() + +<% if version == 'ga' -%> + client := config.NewComputeClient(userAgent) +<% else -%> + client := config.NewComputeBetaClient(userAgent) +<% end -%> + + securityPolicy, err := client.SecurityPolicies.Get(project, sp).Do() if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("SecurityPolicy %q", d.Id())) } @@ -266,6 +325,11 @@ func resourceComputeSecurityPolicyRead(d *schema.ResourceData, meta interface{}) if err := d.Set("self_link", ConvertSelfLinkToV1(securityPolicy.SelfLink)); err != nil { return fmt.Errorf("Error setting self_link: %s", err) } +<% unless version == 'ga' -%> + if err := d.Set("adaptive_protection_config", flattenSecurityPolicyAdaptiveProtectionConfig(securityPolicy.AdaptiveProtectionConfig)); err != nil { + return fmt.Errorf("Error setting adaptive_protection_config: %s", err) + } +<% end -%> return nil } @@ -290,7 +354,14 @@ func resourceComputeSecurityPolicyUpdate(d *schema.ResourceData, meta interface{ Fingerprint: d.Get("fingerprint").(string), ForceSendFields: []string{"Description"}, } - op, err := config.NewComputeClient(userAgent).SecurityPolicies.Patch(project, sp, securityPolicy).Do() + + <% if version == 'ga' -%> + client := config.NewComputeClient(userAgent) + <% else -%> + client := config.NewComputeBetaClient(userAgent) + <% end -%> + + op, err := client.SecurityPolicies.Patch(project, sp, securityPolicy).Do() if err != nil { return errwrap.Wrapf(fmt.Sprintf("Error updating SecurityPolicy %q: {{err}}", sp), err) @@ -317,8 +388,14 @@ func resourceComputeSecurityPolicyUpdate(d *schema.ResourceData, meta interface{ priority := int64(rule.(map[string]interface{})["priority"].(int)) nPriorities[priority] = true if !oPriorities[priority] { + <% if version == 'ga' -%> + client := config.NewComputeClient(userAgent) + <% else -%> + client := config.NewComputeBetaClient(userAgent) + <% end -%> + // If the rule is in new and its priority does not exist in old, then add it. - op, err := config.NewComputeClient(userAgent).SecurityPolicies.AddRule(project, sp, expandSecurityPolicyRule(rule)).Do() + op, err := client.SecurityPolicies.AddRule(project, sp, expandSecurityPolicyRule(rule)).Do() if err != nil { return errwrap.Wrapf(fmt.Sprintf("Error updating SecurityPolicy %q: {{err}}", sp), err) @@ -329,8 +406,14 @@ func resourceComputeSecurityPolicyUpdate(d *schema.ResourceData, meta interface{ return err } } else if !oSet.Contains(rule) { + <% if version == 'ga' -%> + client := config.NewComputeClient(userAgent) + <% else -%> + client := config.NewComputeBetaClient(userAgent) + <% end -%> + // If the rule is in new, and its priority is in old, but its hash is different than the one in old, update it. - op, err := config.NewComputeClient(userAgent).SecurityPolicies.PatchRule(project, sp, expandSecurityPolicyRule(rule)).Priority(priority).Do() + op, err := client.SecurityPolicies.PatchRule(project, sp, expandSecurityPolicyRule(rule)).Priority(priority).Do() if err != nil { return errwrap.Wrapf(fmt.Sprintf("Error updating SecurityPolicy %q: {{err}}", sp), err) @@ -346,8 +429,14 @@ func resourceComputeSecurityPolicyUpdate(d *schema.ResourceData, meta interface{ for _, rule := range oSet.List() { priority := int64(rule.(map[string]interface{})["priority"].(int)) if !nPriorities[priority] { + <% if version == 'ga' -%> + client := config.NewComputeClient(userAgent) + <% else -%> + client := config.NewComputeBetaClient(userAgent) + <% end -%> + // If the rule's priority is in old but not new, remove it. - op, err := config.NewComputeClient(userAgent).SecurityPolicies.RemoveRule(project, sp).Priority(priority).Do() + op, err := client.SecurityPolicies.RemoveRule(project, sp).Priority(priority).Do() if err != nil { return errwrap.Wrapf(fmt.Sprintf("Error updating SecurityPolicy %q: {{err}}", sp), err) @@ -376,8 +465,14 @@ func resourceComputeSecurityPolicyDelete(d *schema.ResourceData, meta interface{ return err } +<% if version == 'ga' -%> + client := config.NewComputeClient(userAgent) +<% else -%> + client := config.NewComputeBetaClient(userAgent) +<% end -%> + // Delete the SecurityPolicy - op, err := config.NewComputeClient(userAgent).SecurityPolicies.Delete(project, d.Get("name").(string)).Do() + op, err := client.SecurityPolicies.Delete(project, d.Get("name").(string)).Do() if err != nil { return errwrap.Wrapf("Error deleting SecurityPolicy: {{err}}", err) } @@ -508,6 +603,56 @@ func flattenMatchExpr(match *compute.SecurityPolicyRuleMatcher) []map[string]int return []map[string]interface{}{data} } +<% unless version == 'ga' -%> +func expandSecurityPolicyAdaptiveProtectionConfig(configured []interface{}) *compute.SecurityPolicyAdaptiveProtectionConfig { + if len(configured) == 0 || configured[0] == nil { + return nil + } + + data := configured[0].(map[string]interface{}) + return &compute.SecurityPolicyAdaptiveProtectionConfig{ + Layer7DdosDefenseConfig: expandLayer7DdosDefenseConfig(data["layer_7_ddos_defense_config"].([]interface{})), + } +} + +func expandLayer7DdosDefenseConfig(configured []interface{}) *compute.SecurityPolicyAdaptiveProtectionConfigLayer7DdosDefenseConfig { + if len(configured) == 0 || configured[0] == nil { + return nil + } + + data := configured[0].(map[string]interface{}) + return &compute.SecurityPolicyAdaptiveProtectionConfigLayer7DdosDefenseConfig{ + Enable: data["enable"].(bool), + RuleVisibility: data["rule_visibility"].(string), + } +} + +func flattenSecurityPolicyAdaptiveProtectionConfig(conf *compute.SecurityPolicyAdaptiveProtectionConfig) []map[string]interface{} { + if conf == nil { + return nil + } + + data := map[string]interface{}{ + "layer_7_ddos_defense_config": flattenLayer7DdosDefenseConfig(conf.Layer7DdosDefenseConfig), + } + + return []map[string]interface{}{data} +} + +func flattenLayer7DdosDefenseConfig(conf *compute.SecurityPolicyAdaptiveProtectionConfigLayer7DdosDefenseConfig) []map[string]interface{} { + if conf == nil { + return nil + } + + data := map[string]interface{}{ + "enable": conf.Enable, + "rule_visibility": conf.RuleVisibility, + } + + return []map[string]interface{}{data} +} +<% end -%> + func resourceSecurityPolicyStateImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { config := meta.(*Config) if err := parseImportId([]string{"projects/(?P[^/]+)/global/securityPolicies/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config); err != nil { diff --git a/mmv1/third_party/terraform/tests/resource_compute_security_policy_test.go.erb b/mmv1/third_party/terraform/tests/resource_compute_security_policy_test.go.erb index ebefc342f8e5..fd85cd0aec93 100644 --- a/mmv1/third_party/terraform/tests/resource_compute_security_policy_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_compute_security_policy_test.go.erb @@ -122,6 +122,30 @@ func TestAccComputeSecurityPolicy_update(t *testing.T) { }) } +<% unless version == 'ga' -%> +func TestAccComputeSecurityPolicy_withAdaptiveProtection(t *testing.T) { + t.Parallel() + + spName := fmt.Sprintf("tf-test-%s", randString(t, 10)) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeSecurityPolicyDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeSecurityPolicy_withAdaptiveProtection(spName), + }, + { + ResourceName: "google_compute_security_policy.policy", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +<% end -%> + func testAccCheckComputeSecurityPolicyDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { config := googleProviderConfig(t) @@ -313,3 +337,21 @@ resource "google_compute_security_policy" "policy" { `, spName) } <% end -%> + +<% unless version == 'ga' -%> +func testAccComputeSecurityPolicy_withAdaptiveProtection(spName string) string { + return fmt.Sprintf(` +resource "google_compute_security_policy" "policy" { + name = "%s" + description = "updated description" + + adaptive_protection_config { + layer_7_ddos_defense_config { + enable = true + rule_visibility = "STANDARD" + } + } +} +`, spName) +} +<% end -%> diff --git a/mmv1/third_party/terraform/website/docs/r/compute_security_policy.html.markdown b/mmv1/third_party/terraform/website/docs/r/compute_security_policy.html.markdown index 31cab8c8c2f7..55a5a650b741 100644 --- a/mmv1/third_party/terraform/website/docs/r/compute_security_policy.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/compute_security_policy.html.markdown @@ -64,6 +64,8 @@ The following arguments are supported: rule (rule with priority 2147483647 and match "\*"). If no rules are provided when creating a security policy, a default rule with action "allow" will be added. Structure is documented below. +* `adaptive_protection_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Configuration for [Google Cloud Armor Adaptive Protection](https://cloud.google.com/armor/docs/adaptive-protection-overview?hl=en). Structure is documented below. + The `rule` block supports: * `action` - (Required) Action to take when `match` matches the request. Valid values: @@ -106,6 +108,16 @@ The `expr` block supports: * `expression` - (Required) Textual representation of an expression in Common Expression Language syntax. The application context of the containing message determines which well-known feature set of CEL is supported. +The `adaptive_protection_config` block supports: + +* `layer_7_ddos_defense_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Configuration for [Google Cloud Armor Adaptive Protection Layer 7 DDoS Defense](https://cloud.google.com/armor/docs/adaptive-protection-overview?hl=en). Structure is documented below. + +The `layer_7_ddos_defense_config` block supports: + +* `enable` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) If set to true, enables CAAP for L7 DDoS detection. + +* `rule_visibility` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Rule visibility can be one of the following: STANDARD - opaque rules. (default) PREMIUM - transparent rules. + ## Attributes Reference In addition to the arguments listed above, the following computed attributes are