Skip to content

Commit 18e3d42

Browse files
feat: check that database version is supported (#44)
* add request to get db version
1 parent 6a7c3d2 commit 18e3d42

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

app.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
grant_iam_group_role,
2626
UserService,
2727
)
28-
from iam_groups_authn.sql_admin import get_instance_users, add_missing_db_users
28+
from iam_groups_authn.sql_admin import (
29+
get_instance_users,
30+
add_missing_db_users,
31+
InstanceConnectionName,
32+
)
2933
from iam_groups_authn.iam_admin import get_iam_users
3034
from iam_groups_authn.mysql import init_connection_engine, RoleService, mysql_username
3135

@@ -34,6 +38,8 @@
3438
"https://www.googleapis.com/auth/admin.directory.group.member.readonly",
3539
"https://www.googleapis.com/auth/sqlservice.admin",
3640
]
41+
# supported database types
42+
SUPPORTED_DATABASES = ["MYSQL_8_0"]
3743

3844
app = Quart(__name__)
3945

@@ -110,15 +116,31 @@ async def run_groups_authn():
110116

111117
for instance in sql_instances:
112118
instance_task = asyncio.create_task(get_instance_users(user_service, instance))
113-
instance_tasks[instance] = instance_task
119+
database_version_task = asyncio.create_task(
120+
user_service.get_database_version(
121+
InstanceConnectionName(*instance.split(":"))
122+
)
123+
)
124+
instance_tasks[instance] = (instance_task, database_version_task)
114125

115126
# create pairings of iam groups and instances
116127
for group in iam_groups:
117128
for instance in sql_instances:
129+
130+
# get database version of instance and check if supported
131+
database_version = await instance_tasks[instance][1]
132+
if database_version not in SUPPORTED_DATABASES:
133+
raise ValueError(
134+
f"Unsupported database version for instance `{instance}`. Current supported versions are: {SUPPORTED_DATABASES}"
135+
)
136+
118137
# add missing IAM group members to database
119138
add_users_task = asyncio.create_task(
120139
add_missing_db_users(
121-
user_service, group_tasks[group], instance_tasks[instance], instance
140+
user_service,
141+
group_tasks[group],
142+
instance_tasks[instance][0],
143+
instance,
122144
)
123145
)
124146

iam_groups_authn/sync.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import json
2323
from aiohttp import ClientSession
2424
from enum import Enum
25+
import logging
2526

2627
# URI for OAuth2 credentials
2728
TOKEN_URI = "https://accounts.google.com/o/oauth2/token"
@@ -130,6 +131,40 @@ async def insert_db_user(self, user_email, instance_connection_name):
130131
f"Error: Failed to add IAM user `{user_email}` to Cloud SQL database instance `{instance_connection_name.instance}`."
131132
) from e
132133

134+
async def get_database_version(self, instance_connection_name):
135+
"""Get database version of a Cloud SQL instance.
136+
137+
Args:
138+
instance_connection_name: InstanceConnectionName namedTuple.
139+
(e.g. InstanceConnectionName(project='my-project', region='my-region',
140+
instance='my-instance'))
141+
142+
Returns:
143+
database_version: Database version of given Cloud SQL instance.
144+
"""
145+
# build request to SQL Admin API
146+
project = instance_connection_name.project
147+
region = instance_connection_name.region
148+
instance = instance_connection_name.instance
149+
url = f"https://sqladmin.googleapis.com/sql/v1beta4/projects/{project}/instances/{instance}"
150+
151+
try:
152+
# call the SQL Admin API
153+
resp = await authenticated_request(
154+
self.creds, url, self.client_session, RequestType.get
155+
)
156+
results = json.loads(await resp.text())
157+
database_version = results.get("databaseVersion")
158+
logging.debug(
159+
"[%s:%s:%s] Database version found: %s"
160+
% (project, region, instance, database_version)
161+
)
162+
return database_version
163+
except Exception as e:
164+
raise Exception(
165+
f"Error: Failed to get the database version for `{instance_connection_name}`. Verify instance connection name and instance details."
166+
) from e
167+
133168
def __del__(self):
134169
"""Deconstructor for UserService to close ClientSession and have
135170
graceful exit.

0 commit comments

Comments
 (0)