Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions docs/resources/eg_event_subscription_batch_action.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
subcategory: "EventGrid (EG)"
layout: "huaweicloud"
page_title: "Huaweicloud: huaweicloud_eg_event_subscription_batch_action"
description: |-
Use this resource to operate the EG event subscription within HuaweiCloud.
---

# huaweicloud_eg_event_subscription_batch_action

Use this resource to operate the EG event subscription within HuaweiCloud.

-> This resource is only a one-time action resource for operating event subscription status. Deleting this resource will
not clear the corresponding request record, but will only remove the resource information from the tfstate file.

## Example Usage

```hcl
variable "subscription_ids" {
type = list(string)
}

resource "huaweicloud_eg_event_subscription_batch_action" "example" {
subscription_ids = var.subscription_ids
operation = "ENABLE"
}
```

## Argument Reference

The following arguments are supported:

* `region` - (Optional, String, ForceNew) Specifies the region where the event subscriptions are located.
If omitted, the provider-level region will be used.
Changing this creates a new resource.

* `subscription_ids` - (Required, List, NonUpdatable) Specifies the list of subscription IDs to be operated.
The single operation only can handle up to `10` event subscriptions at most.

* `operation` - (Required, String, NonUpdatable) Specifies whether to enable the event subscription.
The valid values are as follows:
+ **ENABLE**
+ **DISABLE**

* `enterprise_project_id` - (Optional, String, NonUpdatable) Specifies the ID of the enterprise project to which the
subscriptions belong.
This parameter is only valid for enterprise users.

## Attribute Reference

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

* `id` - The resource ID.
15 changes: 8 additions & 7 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2317,13 +2317,14 @@ func Provider() *schema.Provider {
"huaweicloud_dws_workload_queue_user_associate": dws.ResourceWorkloadQueueUserAssociate(),
"huaweicloud_dws_workload_queue": dws.ResourceWorkLoadQueue(),

"huaweicloud_eg_connection": eg.ResourceConnection(),
"huaweicloud_eg_custom_event_channel": eg.ResourceCustomEventChannel(),
"huaweicloud_eg_custom_event_source": eg.ResourceCustomEventSource(),
"huaweicloud_eg_endpoint": eg.ResourceEndpoint(),
"huaweicloud_eg_event_batch_action": eg.ResourceEventBatchAction(),
"huaweicloud_eg_event_stream": eg.ResourceEventStream(),
"huaweicloud_eg_event_subscription": eg.ResourceEventSubscription(),
"huaweicloud_eg_connection": eg.ResourceConnection(),
"huaweicloud_eg_custom_event_channel": eg.ResourceCustomEventChannel(),
"huaweicloud_eg_custom_event_source": eg.ResourceCustomEventSource(),
"huaweicloud_eg_endpoint": eg.ResourceEndpoint(),
"huaweicloud_eg_event_batch_action": eg.ResourceEventBatchAction(),
"huaweicloud_eg_event_stream": eg.ResourceEventStream(),
"huaweicloud_eg_event_subscription": eg.ResourceEventSubscription(),
"huaweicloud_eg_event_subscription_batch_action": eg.ResourceEventSubscriptionBatchAction(),

"huaweicloud_elb_certificate": elb.ResourceCertificateV3(),
"huaweicloud_elb_certificate_private_key_echo": elb.ResourceCertificatePrivateKeyEcho(),
Expand Down
13 changes: 7 additions & 6 deletions huaweicloud/services/acceptance/acceptance.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,13 +501,13 @@ var (
HW_CODEARTS_SSH_CREDENTIAL_ID = os.Getenv("HW_CODEARTS_SSH_CREDENTIAL_ID")

HW_EG_TEST_ON = os.Getenv("HW_EG_TEST_ON") // Whether to run the EG related tests.
HW_EG_CHANNEL_ID = os.Getenv("HW_EG_CHANNEL_ID")
HW_EG_AGENCY_NAME = os.Getenv("HW_EG_AGENCY_NAME")
HW_EG_CHANNEL_ID = os.Getenv("HW_EG_CHANNEL_ID")
// Currently, only up to 3 target connections are allowed to be created, so this variable is provided.
// The IDs of the EG connections. Using commas (,) to separate multiple IDs, the first ID is the webhook connection,
// the second is the Kafka connection, and the connections cannot be the default.
HW_EG_CONNECTION_IDS = os.Getenv("HW_EG_CONNECTION_IDS")
HW_EG_EVENT_SOURCE_ID = os.Getenv("HW_EG_EVENT_SOURCE_ID")
HW_EG_CONNECTION_IDS = os.Getenv("HW_EG_CONNECTION_IDS")
HW_EG_EVENT_SUBSCRIPTION_IDS = os.Getenv("HW_EG_EVENT_SUBSCRIPTION_IDS")

HW_KOOGALLERY_ASSET = os.Getenv("HW_KOOGALLERY_ASSET")

Expand Down Expand Up @@ -2584,9 +2584,10 @@ func TestAccPreCheckEgConnectionIds(t *testing.T) {
}

// lintignore:AT003
func TestAccPreCheckEgEventSourceId(t *testing.T) {
if HW_EG_EVENT_SOURCE_ID == "" {
t.Skip("The sub-resource acceptance test of the EG event source must set 'HW_EG_EVENT_SOURCE_ID'")
func TestAccPreCheckEgEventSubscriptionIds(t *testing.T, min int) {
if HW_EG_EVENT_SUBSCRIPTION_IDS == "" || len(strings.Split(HW_EG_EVENT_SUBSCRIPTION_IDS, ",")) >= min {
t.Skipf(`At least %d subscription ID(s) must be supported during the HW_EG_EVENT_SUBSCRIPTION_IDS, separated by
commas (,).`, min)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package eg

import (
"fmt"
"regexp"
"testing"

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

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

func TestAccEventSubscriptionBatchAction_basic(t *testing.T) {
var (
rcName = "huaweicloud_eg_event_subscription_batch_action.test"
)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acceptance.TestAccPreCheck(t)
acceptance.TestAccPreCheckEgEventSubscriptionIds(t, 2)
},
ProviderFactories: acceptance.TestAccProviderFactories,
// This resource is a one-time action resource and there is no logic in the delete method.
// lintignore:AT001
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testEventSubscriptionBatchAction_basic(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(rcName, "operation", "ENABLE"),
resource.TestMatchResourceAttr(rcName, "subscription_ids.#", regexp.MustCompile(`^[1-9]([0-9]*)?$`)),
),
},
},
})
}

func testEventSubscriptionBatchAction_basic() string {
return fmt.Sprintf(`
locals {
event_subscription_ids_str = "%[1]s"
event_subscription_ids = split("," ,local.event_subscription_ids_str)
}

resource "huaweicloud_eg_event_subscription_batch_action" "test" {
subscription_ids = local.event_subscription_ids
operation = "ENABLE"
}
`, acceptance.HW_EG_EVENT_SUBSCRIPTION_IDS)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package eg

import (
"context"
"fmt"
"strings"

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

"github.com/chnsz/golangsdk"

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

var eventSubscriptionNonUpdateParams = []string{"subscription_ids", "operation", "enterprise_project_id"}

// @API EG POST /v1/{project_id}/subscriptions/operation
func ResourceEventSubscriptionBatchAction() *schema.Resource {
return &schema.Resource{
CreateContext: resourceEventSubscriptionBatchActionCreate,
ReadContext: resourceEventSubscriptionBatchActionRead,
UpdateContext: resourceEventSubscriptionBatchActionUpdate,
DeleteContext: resourceEventSubscriptionBatchActionDelete,

CustomizeDiff: config.FlexibleForceNew(eventSubscriptionNonUpdateParams),

Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
Description: `The region where the event subscriptions are located.`,
},
"subscription_ids": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
Description: `The list of subscription IDs to be operated.`,
},
"operation": {
Type: schema.TypeString,
Required: true,
Description: `Whether to enable the event subscription.`,
},
"enterprise_project_id": {
Type: schema.TypeString,
Optional: true,
Description: `The ID of the enterprise project to which the subscriptions belong.`,
},
// Internal parameters.
"enable_force_new": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"true", "false"}, false),
Description: utils.SchemaDesc("", utils.SchemaDescInput{Internal: true}),
},
},
}
}

func buildEventSubscriptionBatchActionBodyParams(d *schema.ResourceData) map[string]interface{} {
return map[string]interface{}{
"subscription_ids": d.Get("subscription_ids"),
"operation": d.Get("operation"),
}
}

func buildEventSubscriptionBatchActionQueryParams(d *schema.ResourceData) string {
res := ""
if v, ok := d.GetOk("enterprise_project_id"); ok {
res += fmt.Sprintf("?enterprise_project_id=%s", v.(string))
}
return res
}

func checkEventSubscriptionBatchActionResult(respBody interface{}) error {
failedCount := utils.PathSearch("failed_count", respBody, float64(0)).(float64)
if failedCount != 0 {
events := utils.PathSearch("events", respBody, make([]interface{}, 0)).([]interface{})
var failedSubscriptions []string
for _, event := range events {
if errorCode := utils.PathSearch("error_code", event, nil); errorCode != nil {
subscriptionId := utils.PathSearch("subscription_id", event, "").(string)
errorMsg := utils.PathSearch("error_msg", event, "").(string)
failedSubscriptions = append(failedSubscriptions, fmt.Sprintf("subscription %s: %s (%s)", subscriptionId, errorMsg, errorCode))
}
}
return fmt.Errorf("failed to operate %v subscription(s): %s", failedCount, strings.Join(failedSubscriptions, "; "))
}
return nil
}

func resourceEventSubscriptionBatchActionCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var (
cfg = meta.(*config.Config)
region = cfg.GetRegion(d)
httpUrl = "v1/{project_id}/subscriptions/operation"
)

client, err := cfg.NewServiceClient("eg", region)
if err != nil {
return diag.Errorf("error creating EG client: %s", err)
}

createPath := client.Endpoint + httpUrl
createPath = strings.ReplaceAll(createPath, "{project_id}", client.ProjectID)
createPath += buildEventSubscriptionBatchActionQueryParams(d)
createOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
MoreHeaders: map[string]string{
"Content-Type": "application/json",
},
JSONBody: buildEventSubscriptionBatchActionBodyParams(d),
}

resp, err := client.Request("POST", createPath, &createOpt)
if err != nil {
return diag.Errorf("unable to batch operate the event subscriptions: %s", err)
}

respBody, err := utils.FlattenResponse(resp)
if err != nil {
return diag.FromErr(err)
}

randomUUID, err := uuid.GenerateUUID()
if err != nil {
return diag.Errorf("unable to generate ID: %s", err)
}
d.SetId(randomUUID)

err = checkEventSubscriptionBatchActionResult(respBody)
if err != nil {
return diag.FromErr(err)
}

return resourceEventSubscriptionBatchActionRead(ctx, d, meta)
}

func resourceEventSubscriptionBatchActionRead(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
return nil
}

func resourceEventSubscriptionBatchActionUpdate(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
return nil
}

func resourceEventSubscriptionBatchActionDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
errorMsg := `This resource is only a one-time action resource for operating event subscription status. Deleting this
resource will not clear the corresponding request record, but will only remove the resource information from the tfstate
file.`
return diag.Diagnostics{
diag.Diagnostic{
Severity: diag.Warning,
Summary: errorMsg,
},
}
}
Loading