Skip to content

Commit 932717e

Browse files
author
greyworld
committed
feat(eg): add new operation resource for event subscription
1 parent 8974fe6 commit 932717e

File tree

5 files changed

+291
-8
lines changed

5 files changed

+291
-8
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
subcategory: "EventGrid (EG)"
3+
layout: "huaweicloud"
4+
page_title: "Huaweicloud: huaweicloud_eg_event_subscription_action"
5+
description: |-
6+
Manages an EG event subscription action resource within HuaweiCloud.
7+
---
8+
9+
# huaweicloud_eg_event_subscription_action
10+
11+
Manages an EG event subscription action resource within HuaweiCloud.
12+
13+
## Example Usage
14+
15+
### Enable event subscription
16+
17+
```hcl
18+
variable "subscription_ids" {
19+
type = list(string)
20+
}
21+
22+
resource "huaweicloud_eg_event_subscription_action" "enable" {
23+
subscription_ids = var.subscription_ids
24+
operation = "ENABLE"
25+
}
26+
```
27+
28+
### Disable event subscription
29+
30+
```hcl
31+
variable "subscription_ids" {
32+
type = list(string)
33+
}
34+
35+
resource "huaweicloud_eg_event_subscription_action" "disable" {
36+
subscription_ids = var.subscription_ids
37+
operation = "DISABLE"
38+
}
39+
```
40+
41+
## Argument Reference
42+
43+
The following arguments are supported:
44+
45+
* `region` - (Optional, String, ForceNew) The region where the event subscriptions are located.
46+
If omitted, the provider-level region will be used.
47+
Changing this creates a new resource.
48+
49+
* `subscription_ids` - (Required, List, ForceNew) Specifies the list of subscription IDs to be operated.
50+
Changing this creates a new resource.
51+
52+
* `operation` - (Required, String, ForceNew) Specifies whether to enable the event subscription.
53+
Changing this creates a new resource.
54+
The valid values are as follows:
55+
+ **ENABLE**
56+
+ **DISABLE**
57+
58+
* `enterprise_project_id` - (Optional, String, ForceNew) Specifies the ID of the enterprise project.
59+
Changing this creates a new resource.
60+
61+
## Attribute Reference
62+
63+
In addition to all arguments above, the following attributes are exported:
64+
65+
* `id` - The resource ID.

huaweicloud/provider.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2288,12 +2288,13 @@ func Provider() *schema.Provider {
22882288
"huaweicloud_dws_workload_queue_user_associate": dws.ResourceWorkloadQueueUserAssociate(),
22892289
"huaweicloud_dws_workload_queue": dws.ResourceWorkLoadQueue(),
22902290

2291-
"huaweicloud_eg_connection": eg.ResourceConnection(),
2292-
"huaweicloud_eg_custom_event_channel": eg.ResourceCustomEventChannel(),
2293-
"huaweicloud_eg_custom_event_source": eg.ResourceCustomEventSource(),
2294-
"huaweicloud_eg_endpoint": eg.ResourceEndpoint(),
2295-
"huaweicloud_eg_event_stream": eg.ResourceEventStream(),
2296-
"huaweicloud_eg_event_subscription": eg.ResourceEventSubscription(),
2291+
"huaweicloud_eg_connection": eg.ResourceConnection(),
2292+
"huaweicloud_eg_custom_event_channel": eg.ResourceCustomEventChannel(),
2293+
"huaweicloud_eg_custom_event_source": eg.ResourceCustomEventSource(),
2294+
"huaweicloud_eg_endpoint": eg.ResourceEndpoint(),
2295+
"huaweicloud_eg_event_stream": eg.ResourceEventStream(),
2296+
"huaweicloud_eg_event_subscription": eg.ResourceEventSubscription(),
2297+
"huaweicloud_eg_event_subscription_action": eg.ResourceEventSubscriptionAction(),
22972298

22982299
"huaweicloud_elb_certificate": elb.ResourceCertificateV3(),
22992300
"huaweicloud_elb_certificate_private_key_echo": elb.ResourceCertificatePrivateKeyEcho(),

huaweicloud/services/acceptance/acceptance.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,12 +501,13 @@ var (
501501
HW_CODEARTS_SSH_CREDENTIAL_ID = os.Getenv("HW_CODEARTS_SSH_CREDENTIAL_ID")
502502

503503
HW_EG_TEST_ON = os.Getenv("HW_EG_TEST_ON") // Whether to run the EG related tests.
504-
HW_EG_CHANNEL_ID = os.Getenv("HW_EG_CHANNEL_ID")
505504
HW_EG_AGENCY_NAME = os.Getenv("HW_EG_AGENCY_NAME")
505+
HW_EG_CHANNEL_ID = os.Getenv("HW_EG_CHANNEL_ID")
506506
// Currently, only up to 3 target connections are allowed to be created, so this variable is provided.
507507
// The IDs of the EG connections. Using commas (,) to separate multiple IDs, the first ID is the webhook connection,
508508
// the second is the Kafka connection, and the connections cannot be the default.
509-
HW_EG_CONNECTION_IDS = os.Getenv("HW_EG_CONNECTION_IDS")
509+
HW_EG_CONNECTION_IDS = os.Getenv("HW_EG_CONNECTION_IDS")
510+
HW_EG_EVENT_SUBSCRIPTION_ID = os.Getenv("HW_EG_EVENT_SUBSCRIPTION_ID")
510511

511512
HW_KOOGALLERY_ASSET = os.Getenv("HW_KOOGALLERY_ASSET")
512513

@@ -2591,6 +2592,13 @@ func TestAccPreCheckEgConnectionIds(t *testing.T) {
25912592
}
25922593
}
25932594

2595+
// lintignore:AT003
2596+
func TestAccPreCheckEgEventSubscriptionId(t *testing.T) {
2597+
if HW_EG_EVENT_SUBSCRIPTION_ID == "" {
2598+
t.Skip("The sub-resource acceptance test of the EG event subscription must set 'HW_EG_EVENT_SUBSCRIPTION_ID'")
2599+
}
2600+
}
2601+
25942602
// lintignore:AT003
25952603
func TestAccPreCheckLtsAomAccess(t *testing.T) {
25962604
if HW_LTS_CLUSTER_ID == "" || HW_LTS_CLUSTER_NAME == "" {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package eg
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
9+
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"
10+
)
11+
12+
func TestAccEventSubscriptionAction_basic(t *testing.T) {
13+
var (
14+
rcName = "huaweicloud_eg_event_subscription_action.test"
15+
)
16+
17+
resource.ParallelTest(t, resource.TestCase{
18+
PreCheck: func() {
19+
acceptance.TestAccPreCheck(t)
20+
acceptance.TestAccPreCheckEgEventSubscriptionId(t)
21+
},
22+
ProviderFactories: acceptance.TestAccProviderFactories,
23+
// This resource is a one-time action resource and there is no logic in the delete method.
24+
// lintignore:AT001
25+
CheckDestroy: nil,
26+
Steps: []resource.TestStep{
27+
{
28+
Config: testEventSubscriptionAction_basic(),
29+
Check: resource.ComposeTestCheckFunc(
30+
resource.TestCheckResourceAttr(rcName, "operation", "ENABLE"),
31+
resource.TestCheckResourceAttr(rcName, "subscription_ids.#", "1"),
32+
),
33+
},
34+
},
35+
})
36+
}
37+
38+
func testEventSubscriptionAction_basic() string {
39+
return fmt.Sprintf(`
40+
resource "huaweicloud_eg_event_subscription_action" "test" {
41+
subscription_ids = ["%[1]s"]
42+
operation = "ENABLE"
43+
}
44+
`, acceptance.HW_EG_EVENT_SUBSCRIPTION_ID)
45+
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package eg
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/hashicorp/go-uuid"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
12+
13+
"github.com/chnsz/golangsdk"
14+
15+
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
16+
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
17+
)
18+
19+
var eventSubscriptionNonUpdateParams = []string{"subscription_ids", "operation", "enterprise_project_id"}
20+
21+
// @API EG POST /v1/{project_id}/subscriptions/operation
22+
func ResourceEventSubscriptionAction() *schema.Resource {
23+
return &schema.Resource{
24+
CreateContext: resourceEventSubscriptionActionCreate,
25+
ReadContext: resourceEventSubscriptionActionRead,
26+
UpdateContext: resourceEventSubscriptionActionUpdate,
27+
DeleteContext: resourceEventSubscriptionActionDelete,
28+
29+
CustomizeDiff: config.FlexibleForceNew(eventSubscriptionNonUpdateParams),
30+
31+
Schema: map[string]*schema.Schema{
32+
"region": {
33+
Type: schema.TypeString,
34+
Optional: true,
35+
Computed: true,
36+
ForceNew: true,
37+
Description: `The region where the event subscriptions are located.`,
38+
},
39+
"subscription_ids": {
40+
Type: schema.TypeList,
41+
Required: true,
42+
ForceNew: true,
43+
Elem: &schema.Schema{Type: schema.TypeString},
44+
Description: `The list of subscription IDs to be operated.`,
45+
},
46+
"operation": {
47+
Type: schema.TypeString,
48+
Required: true,
49+
Description: `Whether to enable the event subscription.`,
50+
},
51+
"enterprise_project_id": {
52+
Type: schema.TypeString,
53+
Optional: true,
54+
Description: `The ID of the enterprise project.`,
55+
},
56+
// Internal parameters.
57+
"enable_force_new": {
58+
Type: schema.TypeString,
59+
Optional: true,
60+
ValidateFunc: validation.StringInSlice([]string{"true", "false"}, false),
61+
Description: utils.SchemaDesc("", utils.SchemaDescInput{Internal: true}),
62+
},
63+
},
64+
}
65+
}
66+
67+
func buildEventSubscriptionActionBodyParams(d *schema.ResourceData) map[string]interface{} {
68+
return map[string]interface{}{
69+
"subscription_ids": d.Get("subscription_ids"),
70+
"operation": d.Get("operation"),
71+
}
72+
}
73+
74+
func buildEventSubscriptionActionQueryParams(d *schema.ResourceData) string {
75+
res := ""
76+
if v, ok := d.GetOk("enterprise_project_id"); ok {
77+
res += fmt.Sprintf("?enterprise_project_id=%s", v.(string))
78+
}
79+
return res
80+
}
81+
82+
func checkEventSubscriptionActionResult(respBody interface{}) error {
83+
failedCount := utils.PathSearch("failed_count", respBody, 0).(float64)
84+
if failedCount != 0 {
85+
events := utils.PathSearch("events", respBody, make([]interface{}, 0)).([]interface{})
86+
var failedSubscriptions []string
87+
for _, event := range events {
88+
if errorCode := utils.PathSearch("error_code", event, nil); errorCode != nil {
89+
subscriptionId := utils.PathSearch("subscription_id", event, "").(string)
90+
errorMsg := utils.PathSearch("error_msg", event, "").(string)
91+
failedSubscriptions = append(failedSubscriptions, fmt.Sprintf("subscription %s: %s (%s)", subscriptionId, errorMsg, errorCode))
92+
}
93+
}
94+
return fmt.Errorf("failed to operate %f subscription(s): %s", failedCount, strings.Join(failedSubscriptions, "; "))
95+
}
96+
return nil
97+
}
98+
99+
func resourceEventSubscriptionActionCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
100+
var (
101+
cfg = meta.(*config.Config)
102+
region = cfg.GetRegion(d)
103+
httpUrl = "v1/{project_id}/subscriptions/operation"
104+
)
105+
106+
client, err := cfg.NewServiceClient("eg", region)
107+
if err != nil {
108+
return diag.Errorf("error creating EG client: %s", err)
109+
}
110+
111+
createPath := client.Endpoint + httpUrl
112+
createPath = strings.ReplaceAll(createPath, "{project_id}", client.ProjectID)
113+
createPath += buildEventSubscriptionActionQueryParams(d)
114+
createOpt := golangsdk.RequestOpts{
115+
KeepResponseBody: true,
116+
MoreHeaders: map[string]string{
117+
"Content-Type": "application/json",
118+
},
119+
JSONBody: buildEventSubscriptionActionBodyParams(d),
120+
}
121+
122+
resp, err := client.Request("POST", createPath, &createOpt)
123+
if err != nil {
124+
return diag.Errorf("error creating EG event subscription action: %s", err)
125+
}
126+
127+
respBody, err := utils.FlattenResponse(resp)
128+
if err != nil {
129+
return diag.FromErr(err)
130+
}
131+
132+
// Check if there are any failed operations
133+
err = checkEventSubscriptionActionResult(respBody)
134+
if err != nil {
135+
return diag.FromErr(err)
136+
}
137+
138+
randomUUID, err := uuid.GenerateUUID()
139+
if err != nil {
140+
return diag.Errorf("unable to generate ID: %s", err)
141+
}
142+
d.SetId(randomUUID)
143+
144+
return resourceEventSubscriptionActionRead(ctx, d, meta)
145+
}
146+
147+
func resourceEventSubscriptionActionRead(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
148+
return nil
149+
}
150+
151+
func resourceEventSubscriptionActionUpdate(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
152+
return nil
153+
}
154+
155+
func resourceEventSubscriptionActionDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
156+
errorMsg := `This resource is a one-time action resource using to operate event subscription status. Deleting this resource will
157+
not clear the corresponding request record, but will only remove the resource information from the tfstate file.`
158+
return diag.Diagnostics{
159+
diag.Diagnostic{
160+
Severity: diag.Warning,
161+
Summary: errorMsg,
162+
},
163+
}
164+
}

0 commit comments

Comments
 (0)