Skip to content

Commit

Permalink
Added support for adaptive protection to google_compute_security_poli…
Browse files Browse the repository at this point in the history
…cy (#4846) (#3322)

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored Jun 9, 2021
1 parent c2f5742 commit 37c17dd
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .changelog/4846.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
compute: Added field `adaptive_protection_config` to `google_compute_security_policy` (beta)
```
121 changes: 113 additions & 8 deletions google-beta/resource_compute_security_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"google.golang.org/api/compute/v1"
compute "google.golang.org/api/compute/v0.beta"
)

func resourceComputeSecurityPolicy() *schema.Resource {
Expand Down Expand Up @@ -165,7 +165,41 @@ func resourceComputeSecurityPolicy() *schema.Resource {
Computed: true,
Description: `The URI of the created resource.`,
},

"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".`,
},
},
},
},
},
},
},
},

UseJSONNumber: true,
}
}
Expand Down Expand Up @@ -207,9 +241,15 @@ func resourceComputeSecurityPolicyCreate(d *schema.ResourceData, meta interface{
securityPolicy.Rules = expandSecurityPolicyRules(v.(*schema.Set).List())
}

if v, ok := d.GetOk("adaptive_protection_config"); ok {
securityPolicy.AdaptiveProtectionConfig = expandSecurityPolicyAdaptiveProtectionConfig(v.([]interface{}))
}

log.Printf("[DEBUG] SecurityPolicy insert request: %#v", securityPolicy)

op, err := config.NewComputeClient(userAgent).SecurityPolicies.Insert(project, securityPolicy).Do()
client := config.NewComputeBetaClient(userAgent)

op, err := client.SecurityPolicies.Insert(project, securityPolicy).Do()

if err != nil {
return errwrap.Wrapf("Error creating SecurityPolicy: {{err}}", err)
Expand Down Expand Up @@ -242,7 +282,10 @@ func resourceComputeSecurityPolicyRead(d *schema.ResourceData, meta interface{})
}

sp := d.Get("name").(string)
securityPolicy, err := config.NewComputeClient(userAgent).SecurityPolicies.Get(project, sp).Do()

client := config.NewComputeBetaClient(userAgent)

securityPolicy, err := client.SecurityPolicies.Get(project, sp).Do()
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("SecurityPolicy %q", d.Id()))
}
Expand All @@ -265,6 +308,9 @@ 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)
}
if err := d.Set("adaptive_protection_config", flattenSecurityPolicyAdaptiveProtectionConfig(securityPolicy.AdaptiveProtectionConfig)); err != nil {
return fmt.Errorf("Error setting adaptive_protection_config: %s", err)
}

return nil
}
Expand All @@ -289,7 +335,10 @@ 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()

client := config.NewComputeBetaClient(userAgent)

op, err := client.SecurityPolicies.Patch(project, sp, securityPolicy).Do()

if err != nil {
return errwrap.Wrapf(fmt.Sprintf("Error updating SecurityPolicy %q: {{err}}", sp), err)
Expand All @@ -316,8 +365,10 @@ func resourceComputeSecurityPolicyUpdate(d *schema.ResourceData, meta interface{
priority := int64(rule.(map[string]interface{})["priority"].(int))
nPriorities[priority] = true
if !oPriorities[priority] {
client := config.NewComputeBetaClient(userAgent)

// 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)
Expand All @@ -328,8 +379,10 @@ func resourceComputeSecurityPolicyUpdate(d *schema.ResourceData, meta interface{
return err
}
} else if !oSet.Contains(rule) {
client := config.NewComputeBetaClient(userAgent)

// 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)
Expand All @@ -345,8 +398,10 @@ func resourceComputeSecurityPolicyUpdate(d *schema.ResourceData, meta interface{
for _, rule := range oSet.List() {
priority := int64(rule.(map[string]interface{})["priority"].(int))
if !nPriorities[priority] {
client := config.NewComputeBetaClient(userAgent)

// 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)
Expand Down Expand Up @@ -375,8 +430,10 @@ func resourceComputeSecurityPolicyDelete(d *schema.ResourceData, meta interface{
return err
}

client := config.NewComputeBetaClient(userAgent)

// 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)
}
Expand Down Expand Up @@ -507,6 +564,54 @@ func flattenMatchExpr(match *compute.SecurityPolicyRuleMatcher) []map[string]int
return []map[string]interface{}{data}
}

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}
}

func resourceSecurityPolicyStateImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*Config)
if err := parseImportId([]string{"projects/(?P<project>[^/]+)/global/securityPolicies/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config); err != nil {
Expand Down
38 changes: 38 additions & 0 deletions google-beta/resource_compute_security_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,28 @@ func TestAccComputeSecurityPolicy_update(t *testing.T) {
})
}

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,
},
},
})
}

func testAccCheckComputeSecurityPolicyDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
config := googleProviderConfig(t)
Expand Down Expand Up @@ -309,3 +331,19 @@ resource "google_compute_security_policy" "policy" {
}
`, spName)
}

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)
}
12 changes: 12 additions & 0 deletions website/docs/r/compute_security_policy.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 37c17dd

Please sign in to comment.