From ba9fadd433771bf06e0ebf9058cdb799c8526e4c Mon Sep 17 00:00:00 2001 From: jinyangyang222 Date: Fri, 22 Aug 2025 17:29:31 +0800 Subject: [PATCH 1/2] feat(aad): support `aad_ip_ddos_statistics` data source --- docs/data-sources/aad_ip_ddos_statistics.md | 45 +++++++ huaweicloud/provider.go | 1 + ...urce_huaweicloud_aad_ip_ddos_statistics.go | 123 ++++++++++++++++++ ...huaweicloud_aad_ip_ddos_statistics_test.go | 51 ++++++++ 4 files changed, 220 insertions(+) create mode 100644 docs/data-sources/aad_ip_ddos_statistics.md create mode 100644 huaweicloud/services/aad/data_source_huaweicloud_aad_ip_ddos_statistics.go create mode 100644 huaweicloud/services/acceptance/aad/data_source_huaweicloud_aad_ip_ddos_statistics_test.go diff --git a/docs/data-sources/aad_ip_ddos_statistics.md b/docs/data-sources/aad_ip_ddos_statistics.md new file mode 100644 index 00000000000..40366b68e95 --- /dev/null +++ b/docs/data-sources/aad_ip_ddos_statistics.md @@ -0,0 +1,45 @@ +--- +subcategory: "Advanced Anti-DDoS" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_aad_ip_ddos_statistics" +description: |- + Use this data source to get the Advanced Anti-DDos IP ddos statistics within HuaweiCloud. +--- + +# huaweicloud_aad_ip_ddos_statistics + +Use this data source to get the Advanced Anti-DDos IP ddos statistics within HuaweiCloud. + +## Example Usage + +```hcl +data "huaweicloud_aad_ip_ddos_statistics" "test" {} +``` + +## Argument Reference + +The following arguments are supported: + +* `instance_id` - (Required, String) Specifies the instance ID. + +* `ip` - (Required, String) Specifies the IP address. + +* `start_time` - (Required, String) Specifies the start time, millisecond timestamp. + +* `end_time` - (Required, String) Specifies the end time, millisecond timestamp. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID in UUID format. + +* `attack_kbps_peak` - The attack peak. + +* `in_kbps_peak` - The traffic peak. + +* `ddos_count` - The number of attacks. + +* `timestamp` - The attack peak timestamp. + +* `vip` - The Anti-DDoS IP. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 23a86fed9ce..6689edcf814 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -476,6 +476,7 @@ func Provider() *schema.Provider { "huaweicloud_aad_bandwidth_curve": aad.DataSourceBandwidthCurve(), "huaweicloud_aad_custom_rules": aad.DataSourceCustomRules(), "huaweicloud_aad_frequency_control_rules": aad.DataSourceFrequencyControlRules(), + "huaweicloud_aad_ip_ddos_statistics": aad.DataSourceIpDdosStatistics(), "huaweicloud_antiddos_config_ranges": antiddos.DataSourceConfigRanges(), "huaweicloud_antiddos_weekly_protection_statistics": antiddos.DataSourceWeeklyProtectionStatistics(), diff --git a/huaweicloud/services/aad/data_source_huaweicloud_aad_ip_ddos_statistics.go b/huaweicloud/services/aad/data_source_huaweicloud_aad_ip_ddos_statistics.go new file mode 100644 index 00000000000..db7d6429361 --- /dev/null +++ b/huaweicloud/services/aad/data_source_huaweicloud_aad_ip_ddos_statistics.go @@ -0,0 +1,123 @@ +package aad + +import ( + "context" + "fmt" + "strings" + + "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/chnsz/golangsdk" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +// Due to limited testing conditions, this data source cannot be tested and the API was not successfully called. + +// @API AAD GET /v1/aad/instances/{instance_id}/{ip}/ddos-statistics +func DataSourceIpDdosStatistics() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceIpDdosStatisticsRead, + + Schema: map[string]*schema.Schema{ + "instance_id": { + Type: schema.TypeString, + Required: true, + }, + "ip": { + Type: schema.TypeString, + Required: true, + }, + "start_time": { + Type: schema.TypeString, + Required: true, + }, + "end_time": { + Type: schema.TypeString, + Required: true, + }, + "attack_kbps_peak": { + Type: schema.TypeInt, + Computed: true, + }, + "in_kbps_peak": { + Type: schema.TypeInt, + Computed: true, + }, + "ddos_count": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + "vip": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func buildIpDdosStatisticsQueryParams(d *schema.ResourceData) string { + queryParams := fmt.Sprintf("?start_time=%v", d.Get("start_time")) + queryParams += fmt.Sprintf("&end_time=%v", d.Get("end_time")) + + return queryParams +} + +func dataSourceIpDdosStatisticsRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + product = "aad" + httpUrl = "v1/aad/instances/{instance_id}/{ip}/ddos-statistics" + ) + + client, err := cfg.NewServiceClient(product, region) + if err != nil { + return diag.Errorf("error creating AAD client: %s", err) + } + + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{instance_id}", d.Get("instance_id").(string)) + requestPath = strings.ReplaceAll(requestPath, "{ip}", d.Get("ip").(string)) + requestPath += buildIpDdosStatisticsQueryParams(d) + requestOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + }, + } + + requestResp, err := client.Request("GET", requestPath, &requestOpt) + if err != nil { + return diag.Errorf("error retrieving AAD IP ddos statistics: %s", err) + } + + respBody, err := utils.FlattenResponse(requestResp) + if err != nil { + return diag.FromErr(err) + } + + generateUUID, err := uuid.GenerateUUID() + if err != nil { + return diag.Errorf("unable to generate ID: %s", err) + } + + d.SetId(generateUUID) + + mErr := multierror.Append(nil, + d.Set("attack_kbps_peak", utils.PathSearch("attack_kbps_peak", respBody, nil)), + d.Set("in_kbps_peak", utils.PathSearch("in_kbps_peak", respBody, nil)), + d.Set("ddos_count", utils.PathSearch("ddos_count", respBody, nil)), + d.Set("timestamp", utils.PathSearch("timestamp", respBody, nil)), + ) + + return diag.FromErr(mErr.ErrorOrNil()) +} diff --git a/huaweicloud/services/acceptance/aad/data_source_huaweicloud_aad_ip_ddos_statistics_test.go b/huaweicloud/services/acceptance/aad/data_source_huaweicloud_aad_ip_ddos_statistics_test.go new file mode 100644 index 00000000000..37a0589e93d --- /dev/null +++ b/huaweicloud/services/acceptance/aad/data_source_huaweicloud_aad_ip_ddos_statistics_test.go @@ -0,0 +1,51 @@ +package antiddos + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +// Note: Due to limited test conditions, this test case cannot be executed successfully. +func TestAccIpDdosStatisticsDataSource_basic(t *testing.T) { + var ( + dataSourceName = "data.huaweicloud_aad_ip_ddos_statistics.test" + dc = acceptance.InitDataSourceCheck(dataSourceName) + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + acceptance.TestAccPreCheckAadInstanceID(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testIpDdosStatistics_basic(), + Check: resource.ComposeTestCheckFunc( + dc.CheckResourceExists(), + resource.TestCheckResourceAttrSet(dataSourceName, "attack_kbps_peak"), + resource.TestCheckResourceAttrSet(dataSourceName, "in_kbps_peak"), + resource.TestCheckResourceAttrSet(dataSourceName, "ddos_count"), + resource.TestCheckResourceAttrSet(dataSourceName, "timestamp"), + resource.TestCheckResourceAttrSet(dataSourceName, "vip"), + ), + }, + }, + }) +} + +// Parameter `ip` are mock data. +func testIpDdosStatistics_basic() string { + return fmt.Sprintf(` +data "huaweicloud_aad_ip_ddos_statistics" "test" { + instance_id = "%[1]s" + ip = "12.1.2.117" + start_time = "1755734400" + end_time = "1755820800" +} +`, acceptance.HW_AAD_INSTANCE_ID) +} From 29778d70ff696553833bc22200da7a78d575fb40 Mon Sep 17 00:00:00 2001 From: jinyangyang222 Date: Mon, 25 Aug 2025 11:40:06 +0800 Subject: [PATCH 2/2] feat(aad): support `aad_flow_block` data source --- docs/data-sources/aad_flow_block.md | 47 ++++++ huaweicloud/provider.go | 1 + .../data_source_huaweicloud_aad_flow_block.go | 134 ++++++++++++++++++ ..._source_huaweicloud_aad_flow_block_test.go | 43 ++++++ 4 files changed, 225 insertions(+) create mode 100644 docs/data-sources/aad_flow_block.md create mode 100644 huaweicloud/services/aad/data_source_huaweicloud_aad_flow_block.go create mode 100644 huaweicloud/services/acceptance/aad/data_source_huaweicloud_aad_flow_block_test.go diff --git a/docs/data-sources/aad_flow_block.md b/docs/data-sources/aad_flow_block.md new file mode 100644 index 00000000000..218098b2a31 --- /dev/null +++ b/docs/data-sources/aad_flow_block.md @@ -0,0 +1,47 @@ +--- +subcategory: "Advanced Anti-DDoS" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_aad_flow_block" +description: |- + Use this data source to get the list of Advanced Anti-DDos flow block information within HuaweiCloud. +--- + +# huaweicloud_aad_flow_block + +Use this data source to get the list of Advanced Anti-DDos flow block information within HuaweiCloud. + +## Example Usage + +```hcl +data "huaweicloud_aad_flow_block" "test" {} +``` + +## Argument Reference + +The following arguments are supported: + +* `instance_id` - (Required, String) Specifies the instance ID. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID in UUID format. + +* `ips` - The ips list. + The [ips](#ips_struct) structure is documented below. + + +The `ips` block supports: + +* `ip_id` - The IP ID. + +* `ip` - The IP. + +* `isp` - The isp. + +* `data_center` - The data center. + +* `foreign_switch_status` - The overseas region ban status. `0` represents closed, `1` represents open. + +* `udp_switch_status` - The UDP protocol disabled. `0` represents closed, `1` represents open. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 6689edcf814..8d44306111a 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -477,6 +477,7 @@ func Provider() *schema.Provider { "huaweicloud_aad_custom_rules": aad.DataSourceCustomRules(), "huaweicloud_aad_frequency_control_rules": aad.DataSourceFrequencyControlRules(), "huaweicloud_aad_ip_ddos_statistics": aad.DataSourceIpDdosStatistics(), + "huaweicloud_aad_flow_block": aad.DataSourceFlowBlock(), "huaweicloud_antiddos_config_ranges": antiddos.DataSourceConfigRanges(), "huaweicloud_antiddos_weekly_protection_statistics": antiddos.DataSourceWeeklyProtectionStatistics(), diff --git a/huaweicloud/services/aad/data_source_huaweicloud_aad_flow_block.go b/huaweicloud/services/aad/data_source_huaweicloud_aad_flow_block.go new file mode 100644 index 00000000000..8e4110cc916 --- /dev/null +++ b/huaweicloud/services/aad/data_source_huaweicloud_aad_flow_block.go @@ -0,0 +1,134 @@ +package aad + +import ( + "context" + "fmt" + + "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/chnsz/golangsdk" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +// Due to limited testing conditions, this data source cannot be tested and the API was not successfully called. + +// @API AAD GET /v2/aad/policies/ddos/flow-block +func DataSourceFlowBlock() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceFlowBlockRead, + + Schema: map[string]*schema.Schema{ + "instance_id": { + Type: schema.TypeString, + Required: true, + }, + "ips": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_id": { + Type: schema.TypeString, + Computed: true, + }, + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "isp": { + Type: schema.TypeString, + Computed: true, + }, + "data_center": { + Type: schema.TypeString, + Computed: true, + }, + "foreign_switch_status": { + Type: schema.TypeInt, + Computed: true, + }, + "udp_switch_status": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func buildFlowBlockQueryParams(d *schema.ResourceData) string { + return fmt.Sprintf("?instance_id=%v", d.Get("instance_id")) +} + +func dataSourceFlowBlockRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + product = "aad" + httpUrl = "v2/aad/policies/ddos/flow-block" + ) + + client, err := cfg.NewServiceClient(product, region) + if err != nil { + return diag.Errorf("error creating AAD client: %s", err) + } + + requestPath := client.Endpoint + httpUrl + requestPath += buildFlowBlockQueryParams(d) + requestOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + }, + } + + requestResp, err := client.Request("GET", requestPath, &requestOpt) + if err != nil { + return diag.Errorf("error retrieving AAD flow block information: %s", err) + } + + respBody, err := utils.FlattenResponse(requestResp) + if err != nil { + return diag.FromErr(err) + } + + generateUUID, err := uuid.GenerateUUID() + if err != nil { + return diag.Errorf("unable to generate ID: %s", err) + } + + d.SetId(generateUUID) + + mErr := multierror.Append(nil, + d.Set("ips", flattenFlowBlockIps(utils.PathSearch("ips", respBody, make([]interface{}, 0)).([]interface{}))), + ) + + return diag.FromErr(mErr.ErrorOrNil()) +} + +func flattenFlowBlockIps(resp []interface{}) []interface{} { + if len(resp) == 0 { + return nil + } + + rst := make([]interface{}, 0, len(resp)) + for _, v := range resp { + rst = append(rst, map[string]interface{}{ + "ip_id": utils.PathSearch("ip_id", v, nil), + "ip": utils.PathSearch("ip", v, nil), + "isp": utils.PathSearch("isp", v, nil), + "data_center": utils.PathSearch("data_center", v, nil), + "foreign_switch_status": utils.PathSearch("foreign_switch_status", v, nil), + "udp_switch_status": utils.PathSearch("udp_switch_status", v, nil), + }) + } + + return rst +} diff --git a/huaweicloud/services/acceptance/aad/data_source_huaweicloud_aad_flow_block_test.go b/huaweicloud/services/acceptance/aad/data_source_huaweicloud_aad_flow_block_test.go new file mode 100644 index 00000000000..0b9c12c2746 --- /dev/null +++ b/huaweicloud/services/acceptance/aad/data_source_huaweicloud_aad_flow_block_test.go @@ -0,0 +1,43 @@ +package antiddos + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +// Note: Due to limited test conditions, this test case cannot be executed successfully. +func TestAccDataSourceFlowBlock_basic(t *testing.T) { + var ( + dataSource = "data.huaweicloud_aad_flow_block.test" + dc = acceptance.InitDataSourceCheck(dataSource) + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + acceptance.TestAccPreCheckAadInstanceID(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDataSourceFlowBlock_basic(), + Check: resource.ComposeTestCheckFunc( + dc.CheckResourceExists(), + resource.TestCheckResourceAttrSet(dataSource, "ips.#"), + ), + }, + }, + }) +} + +func testDataSourceFlowBlock_basic() string { + return fmt.Sprintf(` +data "huaweicloud_aad_flow_block" "test" { + instance_id = "%s" +} +`, acceptance.HW_AAD_INSTANCE_ID) +}