Skip to content

Commit e4f53d7

Browse files
committed
fix: support both types of cn endpoint patterns
1 parent 2d097c4 commit e4f53d7

File tree

2 files changed

+129
-58
lines changed

2 files changed

+129
-58
lines changed

aws_advanced_python_wrapper/utils/rdsutils.py

Lines changed: 91 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from re import search, sub
16-
from typing import Optional
15+
from re import search, sub, Match
16+
from typing import Optional, Dict
1717

1818
from aws_advanced_python_wrapper.utils.rds_url_type import RdsUrlType
1919

@@ -81,84 +81,101 @@ class RdsUtils:
8181
r"(?P<dns>proxy-|cluster-|cluster-ro-|cluster-custom-)?" \
8282
r"(?P<domain>[a-zA-Z0-9]+\." \
8383
r"(?P<region>[a-zA-Z0-9\-]+)\.rds\.amazonaws\.com\.cn)"
84-
AURORA_CHINA_INSTANCE_PATTERN = r"(?P<instance>.+)\." \
85-
r"(?P<domain>[a-zA-Z0-9]+\." \
86-
r"(?P<region>[a-zA-Z0-9\-]+)\.rds\.amazonaws\.com\.cn)"
84+
AURORA_OLD_CHINA_DNS_PATTERN = r"(?P<instance>.+)\." \
85+
r"(?P<dns>proxy-|cluster-|cluster-ro-|cluster-custom-)?" \
86+
r"(?P<domain>[a-zA-Z0-9]+\." \
87+
r"rds\.(?P<region>[a-zA-Z0-9\-]+)\.amazonaws\.com\.cn)"
8788
AURORA_CHINA_CLUSTER_PATTERN = r"(?P<instance>.+)\." \
8889
r"(?P<dns>cluster-|cluster-ro-)+" \
8990
r"(?P<domain>[a-zA-Z0-9]+\." \
9091
r"(?P<region>[a-zA-Z0-9\-]+)\.rds\.amazonaws\.com\.cn)"
91-
AURORA_CHINA_CUSTOM_CLUSTER_PATTERN = r"(?P<instance>.+)\." \
92-
r"(?P<dns>cluster-custom-)+" \
93-
r"(?P<domain>[a-zA-Z0-9]+\." \
94-
r"(?P<region>[a-zA-Z0-9\-]+)\.rds\.amazonaws\.com\.cn)"
95-
AURORA_CHINA_PROXY_DNS_PATTERN = r"(?P<instance>.+)\." \
96-
r"(?P<dns>proxy-)+" \
97-
r"(?P<domain>[a-zA-Z0-9]+\." \
98-
r"(?P<region>[a-zA-Z0-9\-])+\.rds\.amazonaws\.com\.cn)"
92+
AURORA_OLD_CHINA_CLUSTER_PATTERN = r"(?P<instance>.+)\." \
93+
r"(?P<dns>cluster-|cluster-ro-)+" \
94+
r"(?P<domain>[a-zA-Z0-9]+\." \
95+
r"rds\.(?P<region>[a-zA-Z0-9\-]+)\.amazonaws\.com\.cn)"
96+
AURORA_GOV_DNS_PATTERN = r"^(?P<instance>.+)\." \
97+
r"(?P<dns>proxy-|cluster-|cluster-ro-|cluster-custom-|limitless-)?" \
98+
r"(?P<domain>[a-zA-Z0-9]+\.rds\.(?P<region>[a-zA-Z0-9\-]+)" \
99+
r"\.(amazonaws\.com|c2s\.ic\.gov|sc2s\.sgov\.gov))"
100+
AURORA_GOV_CLUSTER_PATTERN = r"^(?P<instance>.+)\." \
101+
r"(?P<dns>cluster-|cluster-ro-)+" \
102+
r"(?P<domain>[a-zA-Z0-9]+\.rds\.(?P<region>[a-zA-Z0-9\-]+)" \
103+
r"\.(amazonaws\.com|c2s\.ic\.gov|sc2s\.sgov\.gov))"
104+
ELB_PATTERN = r"^(?<instance>.+)\.elb\.((?<region>[a-zA-Z0-9\-]+)\.amazonaws\.com)"
99105

100106
IP_V4 = r"^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){1}" \
101-
r"(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
107+
r"(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
102108
IP_V6 = r"^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}$"
103-
IP_V6_COMPRESSED = r"^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)$"
109+
IP_V6_COMPRESSED = r"^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)"
104110

105111
DNS_GROUP = "dns"
106112
DOMAIN_GROUP = "domain"
107113
INSTANCE_GROUP = "instance"
108114
REGION_GROUP = "region"
109115

116+
CACHE_DNS_PATTERNS: Dict[str, Match[str]] = {}
117+
CACHE_PATTERNS: Dict[str, str] = {}
118+
110119
def is_rds_cluster_dns(self, host: str) -> bool:
111-
return self._contains(host, [self.AURORA_CLUSTER_PATTERN, self.AURORA_CHINA_CLUSTER_PATTERN])
120+
dns_group = self._get_dns_group(host)
121+
return dns_group is not None and dns_group.casefold() in ["cluster-", "cluster-ro-"]
112122

113123
def is_rds_custom_cluster_dns(self, host: str) -> bool:
114-
return self._contains(host, [self.AURORA_CUSTOM_CLUSTER_PATTERN, self.AURORA_CHINA_CUSTOM_CLUSTER_PATTERN])
124+
dns_group = self._get_dns_group(host)
125+
return dns_group is not None and dns_group.casefold() == "cluster-custom-"
115126

116127
def is_rds_dns(self, host: str) -> bool:
117-
return self._contains(host, [self.AURORA_DNS_PATTERN, self.AURORA_CHINA_DNS_PATTERN])
128+
if not host or not host.strip():
129+
return False
130+
131+
pattern = self._find(host, [RdsUtils.AURORA_DNS_PATTERN,
132+
RdsUtils.AURORA_CHINA_DNS_PATTERN,
133+
RdsUtils.AURORA_OLD_CHINA_DNS_PATTERN,
134+
RdsUtils.AURORA_GOV_DNS_PATTERN])
135+
group = self._get_regex_group(pattern, RdsUtils.DNS_GROUP)
136+
137+
if group:
138+
RdsUtils.CACHE_PATTERNS[host] = group
139+
140+
return pattern is not None
118141

119142
def is_rds_instance(self, host: str) -> bool:
120-
return (self._contains(host, [self.AURORA_INSTANCE_PATTERN, self.AURORA_CHINA_INSTANCE_PATTERN])
121-
and self.is_rds_dns(host))
143+
return self._get_dns_group(host) is None and self.is_rds_dns(host)
122144

123145
def is_rds_proxy_dns(self, host: str) -> bool:
124-
return self._contains(host, [self.AURORA_PROXY_DNS_PATTERN, self.AURORA_CHINA_PROXY_DNS_PATTERN])
146+
dns_group = self._get_dns_group(host)
147+
return dns_group is not None and dns_group.casefold() == "proxy-"
125148

126149
def get_rds_instance_host_pattern(self, host: str) -> str:
127150
if not host or not host.strip():
128151
return "?"
129152

130-
match = self._find(host, [self.AURORA_DNS_PATTERN, self.AURORA_CHINA_DNS_PATTERN])
153+
match = self._get_group(host, RdsUtils.DOMAIN_GROUP)
131154
if match:
132-
return f"?.{match.group(self.DOMAIN_GROUP)}"
155+
return f"?.{match}"
133156

134157
return "?"
135158

136159
def get_rds_region(self, host: Optional[str]):
137160
if not host or not host.strip():
138161
return None
139162

140-
match = self._find(host, [self.AURORA_DNS_PATTERN, self.AURORA_CHINA_DNS_PATTERN])
141-
if match:
142-
return match.group(self.REGION_GROUP)
163+
group = self._get_group(host, RdsUtils.REGION_GROUP)
164+
if group:
165+
return group
143166

167+
elb_matcher = search(RdsUtils.ELB_PATTERN, host)
168+
if elb_matcher:
169+
return elb_matcher.group(RdsUtils.REGION_GROUP)
144170
return None
145171

146172
def is_writer_cluster_dns(self, host: str) -> bool:
147-
if not host or not host.strip():
148-
return False
149-
150-
match = self._find(host, [self.AURORA_CLUSTER_PATTERN, self.AURORA_CHINA_CLUSTER_PATTERN])
151-
if match:
152-
return "cluster-".casefold() == match.group(self.DNS_GROUP).casefold()
153-
154-
return False
173+
dns_group = self._get_dns_group(host)
174+
return dns_group is not None and dns_group.casefold() == "cluster-"
155175

156176
def is_reader_cluster_dns(self, host: str) -> bool:
157-
match = self._find(host, [self.AURORA_CLUSTER_PATTERN, self.AURORA_CHINA_CLUSTER_PATTERN])
158-
if match:
159-
return "cluster-ro-".casefold() == match.group(self.DNS_GROUP).casefold()
160-
161-
return False
177+
dns_group = self._get_dns_group(host)
178+
return dns_group is not None and dns_group.casefold() == "cluster-ro-"
162179

163180
def get_rds_cluster_host_url(self, host: str):
164181
if not host or not host.strip():
@@ -173,20 +190,20 @@ def get_rds_cluster_host_url(self, host: str):
173190
return None
174191

175192
def get_instance_id(self, host: str) -> Optional[str]:
176-
if not host or not host.strip():
177-
return None
178-
179-
match = self._find(host, [self.AURORA_INSTANCE_PATTERN, self.AURORA_CHINA_INSTANCE_PATTERN])
180-
if match:
181-
return match.group(self.INSTANCE_GROUP)
193+
if self._get_dns_group(host) is None:
194+
return self._get_group(host, self.INSTANCE_GROUP)
182195

183196
return None
184197

185198
def is_ipv4(self, host: str) -> bool:
186-
return self._contains(host, [self.IP_V4])
199+
if host is None or not host.strip():
200+
return False
201+
return search(RdsUtils.IP_V4, host) is not None
187202

188203
def is_ipv6(self, host: str) -> bool:
189-
return self._contains(host, [self.IP_V6, self.IP_V6_COMPRESSED])
204+
if host is None or not host.strip():
205+
return False
206+
return search(RdsUtils.IP_V6_COMPRESSED, host) is not None and search(RdsUtils.IP_V6, host) is not None
190207

191208
def is_dns_pattern_valid(self, host: str) -> bool:
192209
return "?" in host
@@ -210,17 +227,38 @@ def identify_rds_type(self, host: Optional[str]) -> RdsUrlType:
210227

211228
return RdsUrlType.OTHER
212229

213-
def _contains(self, host: str, patterns: list) -> bool:
214-
if not host or not host.strip():
215-
return False
216-
217-
return len([pattern for pattern in patterns if search(pattern, host)]) > 0
218-
219230
def _find(self, host: str, patterns: list):
220231
if not host or not host.strip():
221232
return None
222233

223234
for pattern in patterns:
235+
match = RdsUtils.CACHE_DNS_PATTERNS.get(host)
236+
if match:
237+
return match
238+
224239
match = search(pattern, host)
225240
if match:
241+
RdsUtils.CACHE_DNS_PATTERNS[host] = match
226242
return match
243+
244+
return None
245+
246+
def _get_regex_group(self, pattern: Match[str], group_name: str):
247+
return pattern.group(group_name)
248+
249+
def _get_group(self, host: str, group: str):
250+
if not host or not host.strip():
251+
return None
252+
253+
pattern = self._find(host, [RdsUtils.AURORA_DNS_PATTERN,
254+
RdsUtils.AURORA_CHINA_DNS_PATTERN,
255+
RdsUtils.AURORA_OLD_CHINA_DNS_PATTERN,
256+
RdsUtils.AURORA_GOV_DNS_PATTERN])
257+
return self._get_regex_group(pattern, group)
258+
259+
def _get_dns_group(self, host: str):
260+
return self._get_group(host, RdsUtils.DNS_GROUP)
261+
262+
@staticmethod
263+
def clear_cache():
264+
RdsUtils.CACHE_PATTERNS.clear()

tests/unit/test_rds_utils.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,24 @@
2222
us_east_region_proxy = "proxy-test-name.proxy-XYZ.us-east-2.rds.amazonaws.com"
2323
us_east_region_custom_domain = "custom-test-name.cluster-custom-XYZ.us-east-2.rds.amazonaws.com"
2424
china_region_cluster = "database-test-name.cluster-XYZ.cn-northwest-1.rds.amazonaws.com.cn"
25+
china_alt_region_cluster = "database-test-name.cluster-XYZ.rds.cn-northwest-1.amazonaws.com.cn"
2526
china_region_cluster_read_only = "database-test-name.cluster-ro-XYZ.cn-northwest-1.rds.amazonaws.com.cn"
27+
china_alt_region_cluster_read_only = "database-test-name.cluster-ro-XYZ.rds.cn-northwest-1.amazonaws.com.cn"
2628
china_region_instance = "instance-test-name.XYZ.cn-northwest-1.rds.amazonaws.com.cn"
29+
china_alt_region_instance = "instance-test-name.XYZ.rds.cn-northwest-1.amazonaws.com.cn"
2730
china_region_proxy = "proxy-test-name.proxy-XYZ.cn-northwest-1.rds.amazonaws.com.cn"
31+
china_alt_region_proxy = "proxy-test-name.proxy-XYZ.rds.cn-northwest-1.amazonaws.com.cn"
2832
china_region_custom_domain = "custom-test-name.cluster-custom-XYZ.cn-northwest-1.rds.amazonaws.com.cn"
33+
china_alt_region_custom_domain = "custom-test-name.cluster-custom-XYZ.rds.cn-northwest-1.amazonaws.com.cn"
2934

3035

3136
@pytest.mark.parametrize("test_value", [
3237
us_east_region_cluster,
3338
us_east_region_cluster_read_only,
3439
china_region_cluster,
40+
china_alt_region_cluster,
3541
china_region_cluster_read_only,
42+
china_alt_region_cluster_read_only
3643
])
3744
def test_is_rds_cluster_dns(test_value):
3845
target = RdsUtils()
@@ -46,7 +53,10 @@ def test_is_rds_cluster_dns(test_value):
4653
us_east_region_custom_domain,
4754
china_region_instance,
4855
china_region_proxy,
49-
china_region_custom_domain
56+
china_region_custom_domain,
57+
china_alt_region_instance,
58+
china_alt_region_proxy,
59+
china_alt_region_custom_domain
5060
])
5161
def test_is_not_rds_cluster_dns(test_value):
5262
target = RdsUtils()
@@ -64,7 +74,12 @@ def test_is_not_rds_cluster_dns(test_value):
6474
china_region_cluster_read_only,
6575
china_region_instance,
6676
china_region_proxy,
67-
china_region_custom_domain
77+
china_region_custom_domain,
78+
china_alt_region_cluster,
79+
china_alt_region_cluster_read_only,
80+
china_alt_region_instance,
81+
china_alt_region_proxy,
82+
china_alt_region_custom_domain
6883
])
6984
def test_is_rds_dns(test_value):
7085
target = RdsUtils()
@@ -81,7 +96,12 @@ def test_is_rds_dns(test_value):
8196
("?.XYZ.cn-northwest-1.rds.amazonaws.com.cn", china_region_cluster_read_only),
8297
("?.XYZ.cn-northwest-1.rds.amazonaws.com.cn", china_region_instance),
8398
("?.XYZ.cn-northwest-1.rds.amazonaws.com.cn", china_region_proxy),
84-
("?.XYZ.cn-northwest-1.rds.amazonaws.com.cn", china_region_custom_domain)
99+
("?.XYZ.cn-northwest-1.rds.amazonaws.com.cn", china_region_custom_domain),
100+
("?.XYZ.rds.cn-northwest-1.amazonaws.com.cn", china_alt_region_cluster),
101+
("?.XYZ.rds.cn-northwest-1.amazonaws.com.cn", china_alt_region_cluster_read_only),
102+
("?.XYZ.rds.cn-northwest-1.amazonaws.com.cn", china_alt_region_instance),
103+
("?.XYZ.rds.cn-northwest-1.amazonaws.com.cn", china_alt_region_proxy),
104+
("?.XYZ.rds.cn-northwest-1.amazonaws.com.cn", china_alt_region_custom_domain)
85105
])
86106
def test_get_rds_instance_host_pattern(expected, test_value):
87107
target = RdsUtils()
@@ -98,7 +118,12 @@ def test_get_rds_instance_host_pattern(expected, test_value):
98118
("cn-northwest-1", china_region_cluster_read_only),
99119
("cn-northwest-1", china_region_instance),
100120
("cn-northwest-1", china_region_proxy),
101-
("cn-northwest-1", china_region_custom_domain)
121+
("cn-northwest-1", china_region_custom_domain),
122+
("cn-northwest-1", china_alt_region_cluster),
123+
("cn-northwest-1", china_alt_region_cluster_read_only),
124+
("cn-northwest-1", china_alt_region_instance),
125+
("cn-northwest-1", china_alt_region_proxy),
126+
("cn-northwest-1", china_alt_region_custom_domain)
102127
])
103128
def test_get_rds_region(expected, test_value):
104129
target = RdsUtils()
@@ -123,7 +148,11 @@ def test_is_writer_cluster_dns(test_value):
123148
china_region_cluster_read_only,
124149
china_region_instance,
125150
china_region_proxy,
126-
china_region_custom_domain
151+
china_region_custom_domain,
152+
china_alt_region_cluster_read_only,
153+
china_alt_region_instance,
154+
china_alt_region_proxy,
155+
china_alt_region_custom_domain
127156
])
128157
def test_is_not_writer_cluster_dns(test_value):
129158
target = RdsUtils()
@@ -149,6 +178,10 @@ def test_is_reader_cluster_dns(test_value):
149178
china_region_cluster,
150179
china_region_instance,
151180
china_region_proxy,
181+
china_region_custom_domain,
182+
china_region_cluster,
183+
china_region_instance,
184+
china_region_proxy,
152185
china_region_custom_domain
153186
])
154187
def test_is_not_reader_cluster_dns(test_value):

0 commit comments

Comments
 (0)