Skip to content

Commit

Permalink
feat(anti-ddos): support new datasource to query antiddos eip defense…
Browse files Browse the repository at this point in the history
… statuses (#5644)
  • Loading branch information
deer-hang authored Oct 8, 2024
1 parent af61fc9 commit e8dc045
Show file tree
Hide file tree
Showing 4 changed files with 343 additions and 0 deletions.
61 changes: 61 additions & 0 deletions docs/data-sources/antiddos_eip_defense_statuses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
subcategory: "Anti-DDoS"
layout: "huaweicloud"
page_title: "HuaweiCloud: huaweicloud_antiddos_eip_defense_statuses"
description: |-
Use this data source to query the list of defense statuses of EIPs within HuaweiCloud.
---

# huaweicloud_antiddos_eip_defense_statuses

Use this data source to query the list of defense statuses of EIPs within HuaweiCloud.

## Example Usage

```hcl
data "huaweicloud_antiddos_eip_defense_statuses" "test" {}
```

## Argument Reference

The following arguments are supported:

* `region` - (Optional, String) Specifies the region in which to query the resource.
If omitted, the provider-level region will be used.

* `status` - (Optional, String) Specifies the defense status. Valid values are **normal**, **configging**, **notConfig**,
**packetcleaning**, and **packetdropping**. Query all by default.

* `ip` - (Optional, String) Specifies the IP address. Both IPv4 and IPv6 addresses are supported. For example, if you
enter **?ip=192.168**, the defense status of EIPs corresponding to **192.168.111.1** and **10.192.168.8** is returned.

## Attribute Reference

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

* `id` - The data source ID.

* `ddos_status` - The list of Anti-DDos statuses.

The [ddos_status](#ddos_status_struct) structure is documented below.

<a name="ddos_status_struct"></a>
The `ddos_status` block supports:

* `blackhole_endtime` - The end time of black hole.

* `protect_type` - The protect type.

* `traffic_threshold` - The traffic cleaning threshold in Mbps.

* `http_threshold` - The threshold of http traffic.

* `eip_id` - The ID of an EIP.

* `public_ip` - The public address of the EIP.

* `network_type` - The EIP type. Valid values are:
+ **EIP**: EIP bound or not bound to ECS.
+ **ELB**: EIP bound to ELB.

* `status` - The defense status.
1 change: 1 addition & 0 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ func Provider() *schema.Provider {
DataSourcesMap: map[string]*schema.Resource{
"huaweicloud_antiddos_config_ranges": antiddos.DataSourceConfigRanges(),
"huaweicloud_antiddos_weekly_protection_statistics": antiddos.DataSourceWeeklyProtectionStatistics(),
"huaweicloud_antiddos_eip_defense_statuses": antiddos.DataSourceEipDefenseStatuses(),

"huaweicloud_aom_alarm_action_rules": aom.DataSourceAomAlarmActionRules(),
"huaweicloud_aom_alarm_group_rules": aom.DataSourceAlarmGroupRules(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package antiddos

import (
"fmt"
"testing"

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

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

func TestAccDataSourceEipDefenseStatuses_basic(t *testing.T) {
dataSource := "data.huaweicloud_antiddos_eip_defense_statuses.test"
rName := acceptance.RandomAccResourceName()
dc := acceptance.InitDataSourceCheck(dataSource)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acceptance.TestAccPreCheck(t)
},
ProviderFactories: acceptance.TestAccProviderFactories,
Steps: []resource.TestStep{
{
Config: testDataSourceEipDefenseStatuses_basic(rName),
Check: resource.ComposeTestCheckFunc(
dc.CheckResourceExists(),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.#"),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.0.blackhole_endtime"),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.0.protect_type"),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.0.traffic_threshold"),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.0.http_threshold"),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.0.eip_id"),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.0.public_ip"),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.0.network_type"),
resource.TestCheckResourceAttrSet(dataSource, "ddos_status.0.status"),

resource.TestCheckOutput("is_status_filter_useful", "true"),
resource.TestCheckOutput("is_public_ip_filter_useful", "true"),
),
},
},
})
}

func testDataSourceEipDefenseStatuses_base(name string) string {
return fmt.Sprintf(`
resource "huaweicloud_vpc_eip" "test" {
name = "%[1]s"
publicip {
type = "5_bgp"
ip_version = 4
}
bandwidth {
share_type = "PER"
name = "%[1]s"
size = 5
charge_mode = "traffic"
}
tags = {
foo = "bar"
key = "value"
}
}
`, name)
}

func testDataSourceEipDefenseStatuses_basic(name string) string {
return fmt.Sprintf(`
%s
data "huaweicloud_antiddos_eip_defense_statuses" "test" {
depends_on = [huaweicloud_vpc_eip.test]
}
locals {
status = data.huaweicloud_antiddos_eip_defense_statuses.test.ddos_status[0].status
public_ip = data.huaweicloud_antiddos_eip_defense_statuses.test.ddos_status[0].public_ip
}
data "huaweicloud_antiddos_eip_defense_statuses" "filter_by_status" {
status = local.status
}
data "huaweicloud_antiddos_eip_defense_statuses" "filter_by_public_ip" {
ip = local.public_ip
}
locals {
list_by_status = data.huaweicloud_antiddos_eip_defense_statuses.filter_by_status.ddos_status
list_by_public_ip = data.huaweicloud_antiddos_eip_defense_statuses.filter_by_public_ip.ddos_status
}
output "is_status_filter_useful" {
value = length(local.list_by_status) > 0 && alltrue(
[for v in local.list_by_status[*].status : v == local.status]
)
}
output "is_public_ip_filter_useful" {
value = length(local.list_by_public_ip) > 0 && alltrue(
[for v in local.list_by_public_ip[*].public_ip : v == local.public_ip]
)
}
`, testDataSourceEipDefenseStatuses_base(name))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Generated by PMS #372
package antiddos

import (
"context"

"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/tidwall/gjson"

"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/httphelper"
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/schemas"
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
)

func DataSourceEipDefenseStatuses() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceEipDefenseStatusesRead,

Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: `Specifies the region in which to query the resource. If omitted, the provider-level region will be used.`,
},
"status": {
Type: schema.TypeString,
Optional: true,
Description: `Specifies the defense status.`,
},
"ip": {
Type: schema.TypeString,
Optional: true,
Description: `Specifies the IP address. Both IPv4 and IPv6 addresses are supported.`,
},
"ddos_status": {
Type: schema.TypeList,
Computed: true,
Description: `The Anti-DDos statuses.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
// Because this field has no response value and its unit cannot be determined, it remains a numeric type.
"blackhole_endtime": {
Type: schema.TypeInt,
Computed: true,
Description: `The end time of blackhole.`,
},
"protect_type": {
Type: schema.TypeString,
Computed: true,
Description: `The protect type.`,
},
"traffic_threshold": {
Type: schema.TypeInt,
Computed: true,
Description: `The traffic cleaning threshold in Mbps.`,
},
"http_threshold": {
Type: schema.TypeInt,
Computed: true,
Description: `The threshold of http traffic.`,
},
"eip_id": {
Type: schema.TypeString,
Computed: true,
Description: `The ID of an EIP.`,
},
"public_ip": {
Type: schema.TypeString,
Computed: true,
Description: `The public address of the EIP.`,
},
"network_type": {
Type: schema.TypeString,
Computed: true,
Description: `The EIP type.`,
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: `The defense status.`,
},
},
},
},
},
}
}

type EipDefenseStatusesDSWrapper struct {
*schemas.ResourceDataWrapper
Config *config.Config
}

func newEipDefenseStatusesDSWrapper(d *schema.ResourceData, meta interface{}) *EipDefenseStatusesDSWrapper {
return &EipDefenseStatusesDSWrapper{
ResourceDataWrapper: schemas.NewSchemaWrapper(d),
Config: meta.(*config.Config),
}
}

func dataSourceEipDefenseStatusesRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
wrapper := newEipDefenseStatusesDSWrapper(d, meta)
listDDosStatusRst, err := wrapper.ListDDosStatus()
if err != nil {
return diag.FromErr(err)
}

id, err := uuid.GenerateUUID()
if err != nil {
return diag.FromErr(err)
}
d.SetId(id)

err = wrapper.listDDosStatusToSchema(listDDosStatusRst)
if err != nil {
return diag.FromErr(err)
}

return nil
}

// @API ANTI-DDOS GET /v1/{project_id}/antiddos
func (w *EipDefenseStatusesDSWrapper) ListDDosStatus() (*gjson.Result, error) {
client, err := w.NewClient(w.Config, "anti-ddos")
if err != nil {
return nil, err
}

uri := "/v1/{project_id}/antiddos"
params := map[string]any{
"status": w.Get("status"),
"ip": w.Get("ip"),
}
params = utils.RemoveNil(params)
return httphelper.New(client).
Method("GET").
URI(uri).
Query(params).
OffsetPager("ddosStatus", "offset", "limit", 0).
Request().
Result()
}

func (w *EipDefenseStatusesDSWrapper) listDDosStatusToSchema(body *gjson.Result) error {
d := w.ResourceData
mErr := multierror.Append(nil,
d.Set("region", w.Config.GetRegion(w.ResourceData)),
d.Set("ddos_status", schemas.SliceToList(body.Get("ddosStatus"),
func(ddosStatus gjson.Result) any {
return map[string]any{
"blackhole_endtime": ddosStatus.Get("blackhole_endtime").Value(),
"protect_type": ddosStatus.Get("protect_type").Value(),
"traffic_threshold": w.setTrafficThreshold(ddosStatus),
"http_threshold": ddosStatus.Get("http_threshold").Value(),
"eip_id": ddosStatus.Get("floating_ip_id").Value(),
"public_ip": ddosStatus.Get("floating_ip_address").Value(),
"network_type": ddosStatus.Get("network_type").Value(),
"status": ddosStatus.Get("status").Value(),
}
},
)),
)
return mErr.ErrorOrNil()
}

func (*EipDefenseStatusesDSWrapper) setTrafficThreshold(ddosStatus gjson.Result) any {
return getTrafficThresholdBandwidth(int(ddosStatus.Get("traffic_threshold").Int()))
}

0 comments on commit e8dc045

Please sign in to comment.