Skip to content

Commit 798a621

Browse files
chore: validate region matches instance (#602)
1 parent e546efb commit 798a621

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

google/cloud/sql/connector/instance.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ async def _perform_refresh(self) -> InstanceMetadata:
292292
self._sqladmin_api_endpoint,
293293
self._credentials,
294294
self._project,
295+
self._region,
295296
self._instance,
296297
)
297298
)

google/cloud/sql/connector/refresh_utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ async def _get_metadata(
3939
sqladmin_api_endpoint: str,
4040
credentials: Credentials,
4141
project: str,
42+
region: str,
4243
instance: str,
4344
) -> Dict[str, Any]:
4445
"""Requests metadata from the Cloud SQL Instance
@@ -59,6 +60,9 @@ async def _get_metadata(
5960
:param project:
6061
A string representing the name of the project.
6162
63+
:type region: str
64+
:param region : A string representing the name of the region.
65+
6266
:type instance: str
6367
:param instance: A string representing the name of the instance.
6468
@@ -77,6 +81,8 @@ async def _get_metadata(
7781
)
7882
elif not isinstance(project, str):
7983
raise TypeError(f"project must be of type str, got {type(project)}")
84+
elif not isinstance(region, str):
85+
raise TypeError(f"region must be of type str, got {type(region)}")
8086
elif not isinstance(instance, str):
8187
raise TypeError(f"instance must be of type str, got {type(instance)}")
8288

@@ -95,6 +101,11 @@ async def _get_metadata(
95101
resp = await client_session.get(url, headers=headers, raise_for_status=True)
96102
ret_dict = await resp.json()
97103

104+
if ret_dict["region"] != region:
105+
raise ValueError(
106+
f'[{project}:{region}:{instance}]: Provided region was mismatched - got region {region}, expected {ret_dict["region"]}.'
107+
)
108+
98109
metadata = {
99110
"ip_addresses": {ip["type"]: ip["ipAddress"] for ip in ret_dict["ipAddresses"]},
100111
"server_ca_cert": ret_dict["serverCaCert"]["cert"],

tests/unit/test_refresh_utils.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,12 @@ async def test_get_metadata(
149149
parameters.
150150
"""
151151
project = "my-project"
152+
region = "my-region"
152153
instance = "my-instance"
153154
# mock Cloud SQL Admin API call
154155
with aioresponses() as mocked:
155156
mocked.get(
156-
"https://sqladmin.googleapis.com/sql/v1beta4/projects/my-project/instances/my-instance/connectSettings",
157+
f"https://sqladmin.googleapis.com/sql/v1beta4/projects/{project}/instances/{instance}/connectSettings",
157158
status=200,
158159
body=mock_instance.connect_settings(),
159160
repeat=True,
@@ -165,6 +166,7 @@ async def test_get_metadata(
165166
"https://sqladmin.googleapis.com",
166167
credentials,
167168
project,
169+
region,
168170
instance,
169171
)
170172

@@ -184,6 +186,7 @@ async def test_get_metadata_TypeError(credentials: Credentials) -> None:
184186
"""
185187
client_session = Mock(aiohttp.ClientSession)
186188
project = "my-project"
189+
region = "my-region"
187190
instance = "my-instance"
188191

189192
# incorrect credentials type
@@ -193,6 +196,7 @@ async def test_get_metadata_TypeError(credentials: Credentials) -> None:
193196
sqladmin_api_endpoint="https://sqladmin.googleapis.com",
194197
credentials="bad-credentials",
195198
project=project,
199+
region=region,
196200
instance=instance,
197201
)
198202
# incorrect project type
@@ -202,6 +206,17 @@ async def test_get_metadata_TypeError(credentials: Credentials) -> None:
202206
sqladmin_api_endpoint="https://sqladmin.googleapis.com",
203207
credentials=credentials,
204208
project=12345,
209+
region=region,
210+
instance=instance,
211+
)
212+
# incorrect region type
213+
with pytest.raises(TypeError):
214+
await _get_metadata(
215+
client_session=client_session,
216+
sqladmin_api_endpoint="https://sqladmin.googleapis.com",
217+
credentials=credentials,
218+
project=project,
219+
region=1,
205220
instance=instance,
206221
)
207222
# incorrect instance type
@@ -211,10 +226,46 @@ async def test_get_metadata_TypeError(credentials: Credentials) -> None:
211226
sqladmin_api_endpoint="https://sqladmin.googleapis.com",
212227
credentials=credentials,
213228
project=project,
229+
region=region,
214230
instance=12345,
215231
)
216232

217233

234+
@pytest.mark.asyncio
235+
@no_type_check
236+
async def test_get_metadata_region_mismatch(
237+
mock_instance: FakeCSQLInstance, credentials: Credentials
238+
) -> None:
239+
"""
240+
Test to check whether _get_metadata throws proper ValueError
241+
when given mismatched region.
242+
"""
243+
client_session = Mock(aiohttp.ClientSession)
244+
project = "my-project"
245+
region = "bad-region"
246+
instance = "my-instance"
247+
248+
# mock Cloud SQL Admin API call
249+
with aioresponses() as mocked:
250+
mocked.get(
251+
f"https://sqladmin.googleapis.com/sql/v1beta4/projects/{project}/instances/{instance}/connectSettings",
252+
status=200,
253+
body=mock_instance.connect_settings(),
254+
repeat=True,
255+
)
256+
257+
async with aiohttp.ClientSession() as client_session:
258+
with pytest.raises(ValueError):
259+
await _get_metadata(
260+
client_session=client_session,
261+
sqladmin_api_endpoint="https://sqladmin.googleapis.com",
262+
credentials=credentials,
263+
project=project,
264+
region=region,
265+
instance=instance,
266+
)
267+
268+
218269
@pytest.mark.asyncio
219270
@no_type_check
220271
async def test_is_valid_with_valid_metadata() -> None:

0 commit comments

Comments
 (0)