Skip to content

Commit 7ff23e5

Browse files
authored
feat:eg support subscription (#147)
Co-authored-by: ghm <ghm>
1 parent a05ac76 commit 7ff23e5

File tree

6 files changed

+398
-1
lines changed

6 files changed

+398
-1
lines changed

tools/c7n_huaweicloud/c7n_huaweicloud/client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
ListLoadBalancersRequest,
5555
ListListenersRequest,
5656
)
57+
from huaweicloudsdkeg.v1 import ListSubscriptionsRequest
5758
from huaweicloudsdkeip.v3.region.eip_region import EipRegion
5859
from huaweicloudsdkeip.v3 import EipClient, ListPublicipsRequest
5960
from huaweicloudsdkeip.v2 import EipClient as EipClientV2
@@ -597,5 +598,6 @@ def request(self, service):
597598
request = ListBareMetalServerDetailsRequest()
598599
elif service == 'rds':
599600
request = RdsListInstancesRequest()
600-
601+
elif service == 'eg':
602+
request = ListSubscriptionsRequest()
601603
return request
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Copyright The Cloud Custodian Authors.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import logging
5+
import os
6+
from huaweicloudsdkcore.exceptions import exceptions
7+
from huaweicloudsdktms.v1 import (
8+
ShowResourceTagRequest
9+
)
10+
11+
from c7n_huaweicloud.provider import resources
12+
from c7n_huaweicloud.query import QueryResourceManager, TypeInfo
13+
from c7n.utils import local_session
14+
15+
log = logging.getLogger('custodian.huaweicloud.eg')
16+
17+
18+
@resources.register('eg-subscription')
19+
class Subscription(QueryResourceManager):
20+
"""Huawei Cloud EventGrid subscription Resource Manager.
21+
22+
:example:
23+
24+
.. code-block:: yaml
25+
26+
policies:
27+
- name: event-subscription-tags-autoadd
28+
resource: huaweicloud.eg-subscription
29+
filters:
30+
- type: tag-count
31+
count: 0
32+
op: eq
33+
actions:
34+
- type: tag
35+
key: RequiredTag
36+
value: RequiredValue
37+
38+
policies:
39+
- name: event-subscription-untags
40+
resource: huaweicloud.eg-subscription
41+
filters:
42+
- type: tag-count
43+
count: 0
44+
op: gt
45+
actions:
46+
- type: untag
47+
tag_values:
48+
RequiredTag: RequiredValue
49+
50+
set HUAWEICLOUD_SDK_REGION_EG_SA_BRAZIL_1=https://eg.sa-brazil-1.myhuaweicloud.com
51+
"""
52+
53+
class resource_type(TypeInfo):
54+
service = 'eg'
55+
enum_spec = ('list_subscriptions', 'items', 'offset')
56+
id = 'id'
57+
name = 'name'
58+
filter_name = 'name'
59+
filter_type = 'scalar'
60+
taggable = True
61+
tag_resource_type = 'SUBSCRIPTION'
62+
63+
def augment(self, resources):
64+
"""Augment resources with tag information.
65+
66+
:param resources: List of EventStreaming resource dictionaries.
67+
:return: Augmented list of resources.
68+
"""
69+
if not resources:
70+
return resources
71+
# Attempt to create TMS client to query tags
72+
try:
73+
session = local_session(self.session_factory)
74+
client = session.client('tms')
75+
# Add tags to resource properties
76+
for resource in resources:
77+
try:
78+
request = ShowResourceTagRequest()
79+
request.resource_id = resource['id']
80+
request.resource_type = self.resource_type.tag_resource_type
81+
current_tenant = os.getenv('HUAWEI_PROJECT_ID')
82+
request.project_id = current_tenant
83+
response = client.show_resource_tag(request)
84+
tags = []
85+
if hasattr(response, 'tags'):
86+
tags_raw = response.tags if response.tags is not None else []
87+
for tag in tags_raw:
88+
if hasattr(tag, 'key') and hasattr(tag, 'value'):
89+
tags.append({'key': tag.key, 'value': tag.value})
90+
else:
91+
self.log.warning("Unexpected response structure: 'tags' attribute missing.")
92+
resource['tags'] = tags
93+
except exceptions.ClientRequestException as e:
94+
self.log.warning(
95+
f"Failed to retrieve tags for Subscription {resource['id']}: "
96+
f"{e.error_code} - {e.error_msg}")
97+
# Do not modify the resource or set empty tags on client exception
98+
except Exception as e:
99+
self.log.error(f"Error during tag augmentation: {str(e)}")
100+
# Return original resources if any error occurs during the process
101+
return resources

tools/c7n_huaweicloud/c7n_huaweicloud/resources/resource_map.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,5 @@
5252
"huaweicloud.dc": "c7n_huaweicloud.resources.dc.DC",
5353
"huaweicloud.cc-cloud-connection": "c7n_huaweicloud.resources.cc.CloudConnection",
5454
"huaweicloud.rds": "c7n_huaweicloud.resources.rds.RDS",
55+
"huaweicloud.eg-subscription": "c7n_huaweicloud.resources.eg.Subscription",
5556
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
interactions:
2+
- request:
3+
body: null
4+
headers:
5+
Accept:
6+
- '*/*'
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
Content-Type:
12+
- application/json
13+
Host:
14+
- eg.cn-north-4.myhuaweicloud.com
15+
User-Agent:
16+
- huaweicloud-usdk-python/3.0
17+
X-Project-Id:
18+
- ap-southeat-1
19+
X-Sdk-Date:
20+
- 20250514T063435Z
21+
method: GET
22+
uri: https://eg.cn-north-4.myhuaweicloud.com/v1/ap-southeat-1/subscriptions?limit=100&offset=0
23+
response:
24+
body:
25+
string: '{"size":1,"total":1,"items":[{"id":"63cfd150-65fd-4180-ba32-e9710100d100","created_time":"2025-05-13T10:22:02Z","updated_time":"2025-05-13T10:22:02Z","name":"subscription-ppki","description":"","type":"EVENT","status":"ENABLED","channel_id":"65359a7e-3c46-431d-9629-f2a56a2a0380","channel_name":"test","sources":[{"id":"f2c3c223-dab2-4171-b864-c0ad17268257","created_time":"2025-05-13T10:22:02Z","updated_time":"2025-05-13T10:22:02Z","name":"test","provider_type":"CUSTOM","detail":{},"filter":{"source":[{"op":"StringIn","values":["test"]}]}}],"targets":[{"id":"d1500502-7781-4e39-b1e9-65a5aab661e1","created_time":"2025-05-13T10:22:02Z","updated_time":"2025-05-13T10:22:02Z","name":"HTTPS","provider_type":"CUSTOM","connection_id":"2f1b384d-b643-496f-b9ed-450f741984f3","detail":{"url":"http://1.1.1.1"},"transform":{"type":"ORIGINAL","value":""},"thread_num":20,"retry_times":16}],"used":[],"eps_id":"0"}]}'
26+
headers:
27+
Cache-Control:
28+
- no-cache, no-store, max-age=0, must-revalidate
29+
Connection:
30+
- keep-alive
31+
Content-Length:
32+
- '909'
33+
Content-Type:
34+
- application/json
35+
Date:
36+
- Wed, 14 May 2025 06:34:36 GMT
37+
Server:
38+
- CloudWAF
39+
Set-Cookie:
40+
- HWWAFSESID=e4839732205508c545; path=/
41+
- HWWAFSESTIME=1747204476206; path=/
42+
- HWWAFSESTIME=1747204476207; path=/
43+
- HWWAFSESID=0d9f57376a5e43fd0f; path=/
44+
Strict-Transport-Security:
45+
- max-age=31536000; includeSubdomains;
46+
X-Content-Type-Options:
47+
- nosniff
48+
X-Download-Options:
49+
- noopen
50+
X-Frame-Options:
51+
- SAMEORIGIN
52+
X-Request-Id:
53+
- b9367807496986d3c1cc9d45223d6ad1
54+
X-XSS-Protection:
55+
- 1; mode=block;
56+
status:
57+
code: 200
58+
message: OK
59+
version: 1
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
interactions:
2+
- request:
3+
body: null
4+
headers:
5+
Accept:
6+
- '*/*'
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
Content-Type:
12+
- application/json
13+
Host:
14+
- eg.cn-north-4.myhuaweicloud.com
15+
User-Agent:
16+
- huaweicloud-usdk-python/3.0
17+
X-Project-Id:
18+
- ap-southeat-1
19+
X-Sdk-Date:
20+
- 20250514T062412Z
21+
method: GET
22+
uri: https://eg.cn-north-4.myhuaweicloud.com/v1/ap-southeat-1/subscriptions?limit=100&offset=0
23+
response:
24+
body:
25+
string: '{"size":1,"total":1,"items":[{"id":"63cfd150-65fd-4180-ba32-e9710100d100","created_time":"2025-05-13T10:22:02Z","updated_time":"2025-05-13T10:22:02Z","name":"subscription-ppki","description":"","type":"EVENT","status":"ENABLED","channel_id":"65359a7e-3c46-431d-9629-f2a56a2a0380","channel_name":"test","sources":[{"id":"f2c3c223-dab2-4171-b864-c0ad17268257","created_time":"2025-05-13T10:22:02Z","updated_time":"2025-05-13T10:22:02Z","name":"test","provider_type":"CUSTOM","detail":{},"filter":{"source":[{"op":"StringIn","values":["test"]}]}}],"targets":[{"id":"d1500502-7781-4e39-b1e9-65a5aab661e1","created_time":"2025-05-13T10:22:02Z","updated_time":"2025-05-13T10:22:02Z","name":"HTTPS","provider_type":"CUSTOM","connection_id":"2f1b384d-b643-496f-b9ed-450f741984f3","detail":{"url":"http://1.1.1.1"},"transform":{"type":"ORIGINAL","value":""},"thread_num":20,"retry_times":16}],"used":[],"eps_id":"0"}]}'
26+
headers:
27+
Cache-Control:
28+
- no-cache, no-store, max-age=0, must-revalidate
29+
Connection:
30+
- keep-alive
31+
Content-Length:
32+
- '909'
33+
Content-Type:
34+
- application/json
35+
Date:
36+
- Wed, 14 May 2025 06:24:16 GMT
37+
Server:
38+
- CloudWAF
39+
Set-Cookie:
40+
- HWWAFSESID=fb17573ec020c3646c; path=/
41+
- HWWAFSESTIME=1747203853743; path=/
42+
- HWWAFSESTIME=1747203853748; path=/
43+
- HWWAFSESID=806b173fa9bc29f0be; path=/
44+
Strict-Transport-Security:
45+
- max-age=31536000; includeSubdomains;
46+
X-Content-Type-Options:
47+
- nosniff
48+
X-Download-Options:
49+
- noopen
50+
X-Frame-Options:
51+
- SAMEORIGIN
52+
X-Request-Id:
53+
- b6b75b23de1b3abc1750cf42ce7fa906
54+
X-XSS-Protection:
55+
- 1; mode=block;
56+
status:
57+
code: 200
58+
message: OK
59+
- request:
60+
body: null
61+
headers:
62+
Accept:
63+
- '*/*'
64+
Accept-Encoding:
65+
- gzip, deflate
66+
Connection:
67+
- keep-alive
68+
Host:
69+
- iam.ap-southeast-1.myhuaweicloud.com
70+
User-Agent:
71+
- huaweicloud-usdk-python/3.0
72+
X-Sdk-Date:
73+
- 20250514T062416Z
74+
method: GET
75+
uri: https://iam.ap-southeast-1.myhuaweicloud.com/v3/auth/domains
76+
response:
77+
body:
78+
string: '{"domains":[{"description":"","enabled":true,"id":"e5a81532221b408b85d7b656675d888d","links":{"self":"https://iam.myhuaweicloud.com/v3/domains/e5a81532221b408b85d7b656675d888d"},"name":"hwstaff_intl_a00421997"}],"links":{"self":"https://iam.myhuaweicloud.com/v3/auth/domains"}}'
79+
headers:
80+
Connection:
81+
- keep-alive
82+
Content-Length:
83+
- '277'
84+
Content-Type:
85+
- application/json; charset=UTF-8
86+
Date:
87+
- Wed, 14 May 2025 06:24:16 GMT
88+
Server:
89+
- api-gateway
90+
Strict-Transport-Security:
91+
- max-age=31536000; includeSubdomains;
92+
X-Content-Type-Options:
93+
- nosniff
94+
X-Download-Options:
95+
- noopen
96+
X-Frame-Options:
97+
- SAMEORIGIN
98+
X-IAM-Trace-Id:
99+
- token_ap-southeast-1_null_22b98a7bf124e8859cf5265fd9a1a409
100+
X-Request-Id:
101+
- 22b98a7bf124e8859cf5265fd9a1a409
102+
X-XSS-Protection:
103+
- 1; mode=block;
104+
status:
105+
code: 200
106+
message: ''
107+
- request:
108+
body: null
109+
headers:
110+
Accept:
111+
- '*/*'
112+
Accept-Encoding:
113+
- gzip, deflate
114+
Connection:
115+
- keep-alive
116+
Content-Type:
117+
- application/json
118+
Host:
119+
- tms.ap-southeast-1.myhuaweicloud.com
120+
User-Agent:
121+
- huaweicloud-usdk-python/3.0
122+
X-Domain-Id:
123+
- e5a81532221b408b85d7b656675d888d
124+
X-Sdk-Date:
125+
- 20250514T062416Z
126+
method: GET
127+
uri: https://tms.ap-southeast-1.myhuaweicloud.com/v2.0/resources/63cfd150-65fd-4180-ba32-e9710100d100/tags?project_id=ap-southeat-1&resource_type=SUBSCRIPTION
128+
response:
129+
body:
130+
string: !!binary |
131+
H4sIAAAAAAAAA6tWKklML1ayiq5Wyk6tVLJSCkotLM0sSk0JSUxX0lEqS8wpTUUSDQPza2NrAY4k
132+
B5c4AAAA
133+
headers:
134+
Cache-Control:
135+
- no-cache, no-store, max-age=0, must-revalidate
136+
- no-cache, no-store, must-revalidate
137+
Connection:
138+
- keep-alive
139+
Content-Encoding:
140+
- gzip
141+
Content-Type:
142+
- application/json
143+
Date:
144+
- Wed, 14 May 2025 06:24:18 GMT
145+
Expires:
146+
- '0'
147+
Pragma:
148+
- no-cache
149+
- no-cache
150+
Server:
151+
- api-gateway
152+
Strict-Transport-Security:
153+
- max-age=31536000; includeSubdomains;
154+
Transfer-Encoding:
155+
- chunked
156+
X-Content-Type-Options:
157+
- nosniff
158+
X-Download-Options:
159+
- noopen
160+
X-Frame-Options:
161+
- SAMEORIGIN
162+
X-Request-Id:
163+
- b052c22d0655b08ff5884e454ea2c62a
164+
X-XSS-Protection:
165+
- 1; mode=block;
166+
request_id:
167+
- ap-southeast-1c-TMS-SVR-026150053100.b052c22d0655b08ff5884e454ea2c62a
168+
status:
169+
code: 200
170+
message: ''
171+
version: 1

0 commit comments

Comments
 (0)