google/cloud/sql/connector/connection_name.py (40 lines of code) (raw):

# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from dataclasses import dataclass import re # Instance connection name is the format <PROJECT>:<REGION>:<INSTANCE_NAME> # Additionally, we have to support legacy "domain-scoped" projects # (e.g. "google.com:PROJECT") CONN_NAME_REGEX = re.compile(("([^:]+(:[^:]+)?):([^:]+):([^:]+)")) # The domain name pattern in accordance with RFC 1035, RFC 1123 and RFC 2181. DOMAIN_NAME_REGEX = re.compile( r"^(?:[_a-z0-9](?:[_a-z0-9-]{0,61}[a-z0-9])?\.)+(?:[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?)?$" ) @dataclass class ConnectionName: """ConnectionName represents a Cloud SQL instance's "instance connection name". Takes the format "<PROJECT>:<REGION>:<INSTANCE_NAME>". """ project: str region: str instance_name: str domain_name: str = "" def __str__(self) -> str: if self.domain_name: return f"{self.domain_name} -> {self.project}:{self.region}:{self.instance_name}" return f"{self.project}:{self.region}:{self.instance_name}" def get_connection_string(self) -> str: """Get the instance connection string for the Cloud SQL instance.""" return f"{self.project}:{self.region}:{self.instance_name}" def _is_valid_domain(domain_name: str) -> bool: if DOMAIN_NAME_REGEX.fullmatch(domain_name) is None: return False return True def _parse_connection_name(connection_name: str) -> ConnectionName: return _parse_connection_name_with_domain_name(connection_name, "") def _parse_connection_name_with_domain_name( connection_name: str, domain_name: str ) -> ConnectionName: if CONN_NAME_REGEX.fullmatch(connection_name) is None: raise ValueError( "Arg `instance_connection_string` must have " "format: PROJECT:REGION:INSTANCE, " f"got {connection_name}." ) connection_name_split = CONN_NAME_REGEX.split(connection_name) return ConnectionName( connection_name_split[1], connection_name_split[3], connection_name_split[4], domain_name, )