Skip to content

Commit 1dca42d

Browse files
bvliucopybara-github
authored andcommitted
Connect using private IPs for Cloud SQL.
PiperOrigin-RevId: 715950195
1 parent 45b5717 commit 1dca42d

File tree

3 files changed

+67
-20
lines changed

3 files changed

+67
-20
lines changed

perfkitbenchmarker/providers/gcp/gcp_alloy_db.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ def GetResourceMetadata(self) -> Dict[str, Any]:
108108
})
109109
return metadata
110110

111+
def _CreateDependencies(self):
112+
util.SetupPrivateServicesAccess(
113+
self.client_vm.network.network_resource.name, self.project
114+
)
115+
111116
def _Create(self) -> None:
112117
"""Creates the Cloud SQL instance and authorizes traffic from anywhere.
113118

perfkitbenchmarker/providers/gcp/gcp_relational_db.py

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,15 @@ class GCPOmniPostgresIAASRelationalDb(
165165
omni_postgres_iaas_relational_db.OmniPostgresIAASRelationalDb
166166
):
167167
"""A GCP Omni Postgres IAAS database resource."""
168+
168169
CLOUD = provider_info.GCP
169170

170171

171172
class GCPTimescaleDbPostgresIAASRelationalDb(
172173
timescaledb_iaas_relational_db.TimescaleDbIAASRelationalDb
173174
):
174175
"""A TimescaleDB Postgres IAAS database resource."""
176+
175177
CLOUD = provider_info.GCP
176178

177179

@@ -191,24 +193,15 @@ def __init__(self, relational_db_spec):
191193
super().__init__(relational_db_spec)
192194
self.project = FLAGS.project or util.GetDefaultProject()
193195

194-
def _GetAuthorizedNetworks(self, vms):
195-
"""Get CIDR connections for list of VM specs that need to access the db."""
196-
for vm in vms:
197-
if not vm.HasIpAddress:
198-
raise RuntimeError(
199-
'Client vm needs to be initialized before database can '
200-
'discover authorized network.'
201-
)
202-
# create the CIDR of the client VM that is configured to access
203-
# the database
204-
return ','.join('{}/32'.format(vm.ip_address) for vm in vms)
196+
def _CreateDependencies(self):
197+
util.SetupPrivateServicesAccess(
198+
self.client_vm.network.network_resource.name, self.project
199+
)
205200

206201
def _CreateGcloudSqlInstance(self):
207202
storage_size = self.spec.db_disk_spec.disk_size
208203
instance_zone = self.spec.db_spec.zone
209204

210-
authorized_network = self._GetAuthorizedNetworks([self.client_vm])
211-
212205
database_version_string = self._GetEngineVersionString(
213206
self.spec.engine, self.spec.engine_version
214207
)
@@ -222,8 +215,9 @@ def _CreateGcloudSqlInstance(self):
222215
'--quiet',
223216
'--format=json',
224217
'--activation-policy=ALWAYS',
225-
'--assign-ip',
226-
'--authorized-networks=%s' % authorized_network,
218+
'--no-assign-ip',
219+
'--network=%s' % self.client_vm.network.network_resource.name,
220+
'--allocated-ip-range-name=google-service-range',
227221
'--zone=%s' % instance_zone,
228222
'--database-version=%s' % database_version_string,
229223
'--storage-size=%d' % storage_size,
@@ -584,8 +578,9 @@ def _GetEngineVersionString(engine, version):
584578
if engine not in GCP_DATABASE_VERSION_MAPPING:
585579
valid_databases = ', '.join(GCP_DATABASE_VERSION_MAPPING.keys())
586580
raise NotImplementedError(
587-
'Database {} is not supported,supported '
588-
'databases include {}'.format(engine, valid_databases)
581+
'Database {} is not supported,supported databases include {}'.format(
582+
engine, valid_databases
583+
)
589584
)
590585

591586
version_mapping = GCP_DATABASE_VERSION_MAPPING[engine]

perfkitbenchmarker/providers/gcp/util.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -543,9 +543,7 @@ def FormatTags(tags_dict: dict[str, str]):
543543
Returns:
544544
A string contains formatted tags
545545
"""
546-
return ','.join(
547-
'{}={}'.format(k, v) for k, v in sorted(tags_dict.items())
548-
)
546+
return ','.join('{}={}'.format(k, v) for k, v in sorted(tags_dict.items()))
549547

550548

551549
def SplitTags(tags: str):
@@ -604,3 +602,52 @@ def GetAccessToken(application_default: bool = True) -> str:
604602
cmd.append('print-access-token')
605603
stdout, _, _ = vm_util.IssueCommand(cmd)
606604
return stdout.strip()
605+
606+
607+
def SetupPrivateServicesAccess(network: str, project: str) -> None:
608+
"""Setup private services access for the network.
609+
610+
Private services access is used by several GCP services and enables VMs to
611+
connect to service producers using internal IP addressses. See
612+
https://cloud.google.com/vpc/docs/configure-private-services-access for more
613+
info.
614+
615+
Args:
616+
network: The network (VPC) name to setup private services access for.
617+
project: The project to setup private services access for.
618+
"""
619+
cmd = GcloudCommand(
620+
None,
621+
'compute',
622+
'addresses',
623+
'create',
624+
'google-service-range',
625+
)
626+
cmd.flags['global'] = True
627+
cmd.flags['prefix-length'] = 16
628+
cmd.flags['purpose'] = 'VPC_PEERING'
629+
cmd.flags['network'] = network
630+
cmd.flags['project'] = project
631+
cmd.Issue(raise_on_failure=False)
632+
633+
cmd = GcloudCommand(None, 'services', 'vpc-peerings', 'connect')
634+
cmd.flags['service'] = 'servicenetworking.googleapis.com'
635+
cmd.flags['network'] = network
636+
cmd.flags['ranges'] = 'google-service-range'
637+
cmd.flags['project'] = project
638+
_, stderr, _ = cmd.Issue(raise_on_failure=False)
639+
640+
# There are create errors when creating the connection for a second time.
641+
# The workaround is to update the connection:
642+
if 'Please use UpdateConnection' in stderr:
643+
cmd = GcloudCommand(
644+
None,
645+
'services',
646+
'vpc-peerings',
647+
'update',
648+
)
649+
cmd.flags['network'] = network
650+
cmd.flags['project'] = project
651+
cmd.flags['ranges'] = 'google-service-range'
652+
cmd.flags['force'] = True
653+
cmd.Issue(raise_on_failure=False)

0 commit comments

Comments
 (0)