1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15- from re import search , sub
15+ from re import search , sub , Match
1616from typing import Optional
1717
1818from aws_advanced_python_wrapper .utils .rds_url_type import RdsUrlType
@@ -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+ "(?P<dns>proxy-|cluster-|cluster-ro-|cluster-custom-|limitless-)?" \
98+ "(?P<domain>[a-zA-Z0-9]+\.rds\.(?P<region>[a-zA-Z0-9\-]+)" \
99+ "\.(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 None
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,34 @@ 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 :
224- match = search ( pattern , host )
235+ match = RdsUtils . CACHE_DNS_PATTERNS . get ( host )
225236 if match :
226237 return match
238+ else :
239+ match = search (pattern , host )
240+ RdsUtils .CACHE_DNS_PATTERNS [host ] = match
241+
242+ def _get_regex_group (self , pattern : Match [str ], group_name : str ):
243+ return pattern .group (group_name )
244+
245+ def _get_group (self , host : str , group : str ):
246+ if not host or not host .strip ():
247+ return None
248+
249+ pattern = self ._find (host , [RdsUtils .AURORA_DNS_PATTERN ,
250+ RdsUtils .AURORA_CHINA_DNS_PATTERN ,
251+ RdsUtils .AURORA_OLD_CHINA_DNS_PATTERN ,
252+ RdsUtils .AURORA_GOV_DNS_PATTERN ])
253+ return self ._get_regex_group (pattern , group )
254+
255+ def _get_dns_group (self , host : str ):
256+ return self ._get_group (host , RdsUtils .DNS_GROUP )
257+
258+ @staticmethod
259+ def clear_cache ():
260+ RdsUtils .CACHE_PATTERNS .clear ()
0 commit comments