Сопоставление ресурсов
Код: Выделить всё
project_a
- sa_project_a
Код: Выделить всё
project_b
- sa_project_b
- Облако Экземпляр SQL
Код: Выделить всё
project_c
- Кластер воздушного потока на K8s
Код: Выделить всё
BigQuery Data Viewer
BigQuery Job User
Cloud SQL Client
Secret Manager Secret Accessor
Код: Выделить всё
def bigquery_to_df(self, query: str) -> None:
"""Query the data from BigQuery with SQL and convert to Pandas DataFrame
Args:
query (str): SQL query string
"""
client = bigquery.Client()
query_job = client.query(query)
rows = query_job.result()
data = [dict(row) for row in rows]
self.df = pd.DataFrame(data=data)
Код: Выделить всё
def create_connect(
self,
connection_name: str,
db_user: str,
db_pass: str,
db_name: str,
database: str,
lib: str,
) -> None:
"""Create the connect cursor to database in Cloud SQL
Args:
connection_name (str): Connection's name of Cloud SQL instance
db_user (str): User id
db_pass (str): Password
db_name (str): Database name on Cloud SQL instance
database (str, optional): Database software that host on Cloud SQL.
lib (str, optional): Database library to connect the database.
"""
ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC
connector = Connector(ip_type)
def _get_conn() -> pymysql.connections.Connection:
"""Create the pymysql connection to database on Cloud SQL
Returns:
pymysql.connections.Connection: the pymysql connection
"""
conn = connector.connect(
instance_connection_string=connection_name,
driver=lib,
user=db_user,
password=db_pass,
db=db_name,
)
return conn
self.db_name = db_name
self._pool = sqlalchemy.create_engine(
f"{database}+{lib}://",
creator=_get_conn,
).connect()
logging.info(" --> Start the connection!")
Код: Выделить всё
aiohttp.client_exceptions.ClientResponseError: 403, message="Forbidden: Authenticated IAM principal does not seeem authorized to make API request. Verify 'Cloud SQL Admin API' is enabled within your GCP project and 'Cloud SQL Client' role has been granted to IAM principal.", url='https://sqladmin.googleapis.com/sql/v1beta4/projects/{project_id}/instances/{instand_id}/connectSettings'
Чтобы быстро решить проблему, я создал новую учетную запись службы sa_project_b в project_b (тот же проект как экземпляр Cloud SQL) с теми же ролями, что и sa_project_a. Я сохранил учетные данные в Secret Manager и извлек их перед созданием соединения.
Код: Выделить всё
ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{self.project_id}/secrets/{self.secret_id}/versions/latest"
request = client.access_secret_version(request={"name": name})
response = json.loads(request.payload.data.decode("UTF-8"))
credentials = service_account.Credentials.from_service_account_info(response)
connector = Connector(ip_type=ip_type, credentials=credentials)
Я подозреваю, что sa_project_a может не иметь разрешения на использование облака SQL Admin API, потому что я использовал тот же сценарий, но изменил только учетную запись службы, которая была создана в том же проекте, что и экземпляр Cloud SQL. sa_project_b может автоматически получить доступ к API администратора Cloud SQL, поскольку он был создан в том же проекте.
Подробнее здесь: https://stackoverflow.com/questions/790 ... e-api-requ