Skip to content

Commit

Permalink
Add WAF policy rule management supports #1280
Browse files Browse the repository at this point in the history
  • Loading branch information
chengxiangdong committed Jul 20, 2021
1 parent f971b21 commit 89189c5
Show file tree
Hide file tree
Showing 8 changed files with 579 additions and 0 deletions.
63 changes: 63 additions & 0 deletions docs/resources/waf_rule_data_masking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
subcategory: "Web Application Firewall (WAF)"
---

# huaweicloud_waf_rule_data_masking

Manages a WAF Data Masking Rule resource within HuaweiCloud.

## Example Usage

```hcl
resource "huaweicloud_waf_policy" "policy_1" {
name = "policy_1"
}
resource "huaweicloud_waf_rule_data_masking" "rule_1" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login"
field = "params"
subfield = "password"
}
```

## Argument Reference

The following arguments are supported:
* `region` - (Optional, String, ForceNew) The region in which to create the WAF Data Masking rule resource.
If omitted, the provider-level region will be used. Changing this setting will create a new rule.

* `policy_id` - (Required, String, ForceNew) Specifies the WAF policy ID. Changing this creates a new rule.

* `path` - (Required, String) Specifies the URL to which the data masking rule applies (exact match by default).

* `field` - (Required, String) The position where the masked field stored.
Valid values are:
* `params`: The field in the parameter.
* `header`: The field in the header.
* `form`: The field in the form.
* `cookie`: The field in the cookie.

* `subfield` - (Required, String) Specifies the name of the masked field, e.g.: password.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

* `id` - The rule ID in UUID format.

## Timeouts

This resource provides the following timeouts configuration options:
- `create` - Default is 10 minute.
- `update` - Default is 10 minute.
- `delete` - Default is 5 minute.

## Import

Data Masking Rules can be imported using the policy ID and rule ID
separated by a slash, e.g.:

```sh
terraform import huaweicloud_waf_rule_data_masking.rule_1 d78b439fd5e54ea08886e5f63ee7b3f5/ac01a092d50e4e6ba3cd622c1128ba2c
```
1 change: 1 addition & 0 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ func Provider() terraform.ResourceProvider {
"huaweicloud_waf_domain": waf.ResourceWafDomainV1(),
"huaweicloud_waf_policy": waf.ResourceWafPolicyV1(),
"huaweicloud_waf_rule_blacklist": waf.ResourceWafRuleBlackListV1(),
"huaweicloud_waf_rule_data_masking": waf.ResourceWafRuleDataMaskingV1(),

// Legacy
"huaweicloud_compute_instance_v2": ResourceComputeInstanceV2(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/*
Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
*/

package waf

import (
"fmt"
"testing"

"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"

rules "github.com/huaweicloud/golangsdk/openstack/waf_hw/v1/datamasking_rules"
)

func TestAccWafRuleDataMasking_basic(t *testing.T) {
var rule rules.DataMasking
policyName := "policy-" + acctest.RandString(5)
resourceName1 := "huaweicloud_waf_rule_data_masking.rule_1"
resourceName2 := "huaweicloud_waf_rule_data_masking.rule_1"
resourceName3 := "huaweicloud_waf_rule_data_masking.rule_1"
resourceName4 := "huaweicloud_waf_rule_data_masking.rule_1"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.TestAccPreCheck(t) },
Providers: acceptance.TestAccProviders,
CheckDestroy: testAccCheckWafRuleDataMaskingDestroy,
Steps: []resource.TestStep{
{
Config: testAccWafRuleDataMasking_basic(policyName),
Check: resource.ComposeTestCheckFunc(
testAccCheckWafRuleDataMaskingExists(resourceName1, &rule),
resource.TestCheckResourceAttr(resourceName1, "path", "/login"),
resource.TestCheckResourceAttr(resourceName1, "field", "params"),
resource.TestCheckResourceAttr(resourceName1, "subfield", "password"),
resource.TestCheckResourceAttr(resourceName2, "subfield", "password"),
resource.TestCheckResourceAttr(resourceName3, "subfield", "password"),
resource.TestCheckResourceAttr(resourceName4, "subfield", "password"),
),
},
{
Config: testAccWafRuleDataMasking_update(policyName),
Check: resource.ComposeTestCheckFunc(
testAccCheckWafRuleDataMaskingExists(resourceName1, &rule),
resource.TestCheckResourceAttr(resourceName1, "path", "/login_new"),
resource.TestCheckResourceAttr(resourceName1, "field", "params"),
resource.TestCheckResourceAttr(resourceName1, "subfield", "secret"),
resource.TestCheckResourceAttr(resourceName2, "subfield", "secret"),
resource.TestCheckResourceAttr(resourceName3, "subfield", "secret"),
resource.TestCheckResourceAttr(resourceName4, "subfield", "secret"),
),
},
{
ResourceName: resourceName1,
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: testAccWafRuleImportStateIdFunc(resourceName1),
},
},
})
}

func testAccCheckWafRuleDataMaskingDestroy(s *terraform.State) error {
config := acceptance.TestAccProvider.Meta().(*config.Config)
wafClient, err := config.WafV1Client(acceptance.HW_REGION_NAME)
if err != nil {
return fmt.Errorf("error creating HuaweiCloud WAF client: %s", err)
}
for _, rs := range s.RootModule().Resources {
if rs.Type != "huaweicloud_waf_rule_data_masking" {
continue
}

policyID := rs.Primary.Attributes["policy_id"]
_, err := rules.Get(wafClient, policyID, rs.Primary.ID).Extract()
if err == nil {
return fmt.Errorf("WAF data masking rule still exists")
}
}

return nil
}

func testAccCheckWafRuleDataMaskingExists(n string, rule *rules.DataMasking) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}

config := acceptance.TestAccProvider.Meta().(*config.Config)
wafClient, err := config.WafV1Client(acceptance.HW_REGION_NAME)
if err != nil {
return fmt.Errorf("error creating HuaweiCloud WAF client: %s", err)
}

policyID := rs.Primary.Attributes["policy_id"]
found, err := rules.Get(wafClient, policyID, rs.Primary.ID).Extract()
if err != nil {
return err
}

if found.Id != rs.Primary.ID {
return fmt.Errorf("WAF data masking rule not found")
}

*rule = *found

return nil
}
}

func testAccWafRuleDataMasking_basic(name string) string {
return fmt.Sprintf(`
resource "huaweicloud_waf_policy" "policy_1" {
name = "%s"
}
resource "huaweicloud_waf_rule_data_masking" "rule_1" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login"
field = "params"
subfield = "password"
}
resource "huaweicloud_waf_rule_data_masking" "rule_2" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login"
field = "header"
subfield = "password"
}
resource "huaweicloud_waf_rule_data_masking" "rule_3" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login"
field = "form"
subfield = "password"
}
resource "huaweicloud_waf_rule_data_masking" "rule_4" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login"
field = "cookie"
subfield = "password"
}
`, name)
}

func testAccWafRuleDataMasking_update(name string) string {
return fmt.Sprintf(`
resource "huaweicloud_waf_policy" "policy_1" {
name = "%s"
}
resource "huaweicloud_waf_rule_data_masking" "rule_1" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login_new"
field = "params"
subfield = "secret"
}
resource "huaweicloud_waf_rule_data_masking" "rule_2" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login"
field = "header"
subfield = "secret"
}
resource "huaweicloud_waf_rule_data_masking" "rule_3" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login"
field = "form"
subfield = "secret"
}
resource "huaweicloud_waf_rule_data_masking" "rule_4" {
policy_id = huaweicloud_waf_policy.policy_1.id
path = "/login"
field = "cookie"
subfield = "secret"
}
`, name)
}
Loading

0 comments on commit 89189c5

Please sign in to comment.