Skip to content

Commit 5df779d

Browse files
jialuootswast
andauthored
feat: Support VPC egress setting in remote function (#2059)
Co-authored-by: Tim Sweña (Swast) <swast@google.com>
1 parent 8804ada commit 5df779d

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed

bigframes/functions/_function_client.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@
5151
}
5252
)
5353

54+
# https://cloud.google.com/functions/docs/reference/rest/v2/projects.locations.functions#vpconnectoregresssettings
55+
_VPC_EGRESS_SETTINGS_MAP = types.MappingProxyType(
56+
{
57+
"all": functions_v2.ServiceConfig.VpcConnectorEgressSettings.ALL_TRAFFIC,
58+
"private-ranges-only": functions_v2.ServiceConfig.VpcConnectorEgressSettings.PRIVATE_RANGES_ONLY,
59+
"unspecified": functions_v2.ServiceConfig.VpcConnectorEgressSettings.VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED,
60+
}
61+
)
62+
5463
# BQ managed functions (@udf) currently only support Python 3.11.
5564
_MANAGED_FUNC_PYTHON_VERSION = "python-3.11"
5665

@@ -375,6 +384,7 @@ def create_cloud_function(
375384
max_instance_count=None,
376385
is_row_processor=False,
377386
vpc_connector=None,
387+
vpc_connector_egress_settings="private-ranges-only",
378388
memory_mib=1024,
379389
ingress_settings="internal-only",
380390
):
@@ -472,6 +482,15 @@ def create_cloud_function(
472482
function.service_config.max_instance_count = max_instance_count
473483
if vpc_connector is not None:
474484
function.service_config.vpc_connector = vpc_connector
485+
if vpc_connector_egress_settings not in _VPC_EGRESS_SETTINGS_MAP:
486+
raise bf_formatting.create_exception_with_feedback_link(
487+
ValueError,
488+
f"'{vpc_connector_egress_settings}' not one of the supported vpc egress settings values: {list(_VPC_EGRESS_SETTINGS_MAP)}",
489+
)
490+
function.service_config.vpc_connector_egress_settings = cast(
491+
functions_v2.ServiceConfig.VpcConnectorEgressSettings,
492+
_VPC_EGRESS_SETTINGS_MAP[vpc_connector_egress_settings],
493+
)
475494
function.service_config.service_account_email = (
476495
self._cloud_function_service_account
477496
)
@@ -532,6 +551,7 @@ def provision_bq_remote_function(
532551
cloud_function_max_instance_count,
533552
is_row_processor,
534553
cloud_function_vpc_connector,
554+
cloud_function_vpc_connector_egress_settings,
535555
cloud_function_memory_mib,
536556
cloud_function_ingress_settings,
537557
bq_metadata,
@@ -580,6 +600,7 @@ def provision_bq_remote_function(
580600
max_instance_count=cloud_function_max_instance_count,
581601
is_row_processor=is_row_processor,
582602
vpc_connector=cloud_function_vpc_connector,
603+
vpc_connector_egress_settings=cloud_function_vpc_connector_egress_settings,
583604
memory_mib=cloud_function_memory_mib,
584605
ingress_settings=cloud_function_ingress_settings,
585606
)

bigframes/functions/_function_session.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ def remote_function(
245245
cloud_function_timeout: Optional[int] = 600,
246246
cloud_function_max_instances: Optional[int] = None,
247247
cloud_function_vpc_connector: Optional[str] = None,
248+
cloud_function_vpc_connector_egress_settings: Literal[
249+
"all", "private-ranges-only", "unspecified"
250+
] = "private-ranges-only",
248251
cloud_function_memory_mib: Optional[int] = 1024,
249252
cloud_function_ingress_settings: Literal[
250253
"all", "internal-only", "internal-and-gclb"
@@ -425,6 +428,13 @@ def remote_function(
425428
function. This is useful if your code needs access to data or
426429
service(s) that are on a VPC network. See for more details
427430
https://cloud.google.com/functions/docs/networking/connecting-vpc.
431+
cloud_function_vpc_connector_egress_settings (str, Optional):
432+
Egress settings for the VPC connector, controlling what outbound
433+
traffic is routed through the VPC connector.
434+
Options are: `all`, `private-ranges-only`, or `unspecified`.
435+
If not specified, `private-ranges-only` is used by default.
436+
See for more details
437+
https://cloud.google.com/run/docs/configuring/vpc-connectors#egress-job.
428438
cloud_function_memory_mib (int, Optional):
429439
The amounts of memory (in mebibytes) to allocate for the cloud
430440
function (2nd gen) created. This also dictates a corresponding
@@ -616,6 +626,7 @@ def wrapper(func):
616626
cloud_function_max_instance_count=cloud_function_max_instances,
617627
is_row_processor=is_row_processor,
618628
cloud_function_vpc_connector=cloud_function_vpc_connector,
629+
cloud_function_vpc_connector_egress_settings=cloud_function_vpc_connector_egress_settings,
619630
cloud_function_memory_mib=cloud_function_memory_mib,
620631
cloud_function_ingress_settings=cloud_function_ingress_settings,
621632
bq_metadata=bqrf_metadata,

bigframes/pandas/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ def remote_function(
8787
cloud_function_timeout: Optional[int] = 600,
8888
cloud_function_max_instances: Optional[int] = None,
8989
cloud_function_vpc_connector: Optional[str] = None,
90+
cloud_function_vpc_connector_egress_settings: Literal[
91+
"all", "private-ranges-only", "unspecified"
92+
] = "private-ranges-only",
9093
cloud_function_memory_mib: Optional[int] = 1024,
9194
cloud_function_ingress_settings: Literal[
9295
"all", "internal-only", "internal-and-gclb"
@@ -109,6 +112,7 @@ def remote_function(
109112
cloud_function_timeout=cloud_function_timeout,
110113
cloud_function_max_instances=cloud_function_max_instances,
111114
cloud_function_vpc_connector=cloud_function_vpc_connector,
115+
cloud_function_vpc_connector_egress_settings=cloud_function_vpc_connector_egress_settings,
112116
cloud_function_memory_mib=cloud_function_memory_mib,
113117
cloud_function_ingress_settings=cloud_function_ingress_settings,
114118
cloud_build_service_account=cloud_build_service_account,

bigframes/session/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,6 +1510,9 @@ def remote_function(
15101510
cloud_function_timeout: Optional[int] = 600,
15111511
cloud_function_max_instances: Optional[int] = None,
15121512
cloud_function_vpc_connector: Optional[str] = None,
1513+
cloud_function_vpc_connector_egress_settings: Literal[
1514+
"all", "private-ranges-only", "unspecified"
1515+
] = "private-ranges-only",
15131516
cloud_function_memory_mib: Optional[int] = 1024,
15141517
cloud_function_ingress_settings: Literal[
15151518
"all", "internal-only", "internal-and-gclb"
@@ -1675,6 +1678,13 @@ def remote_function(
16751678
function. This is useful if your code needs access to data or
16761679
service(s) that are on a VPC network. See for more details
16771680
https://cloud.google.com/functions/docs/networking/connecting-vpc.
1681+
cloud_function_vpc_connector_egress_settings (str, Optional):
1682+
Egress settings for the VPC connector, controlling what outbound
1683+
traffic is routed through the VPC connector.
1684+
Options are: `all`, `private-ranges-only`, or `unspecified`.
1685+
If not specified, `private-ranges-only` is used by default.
1686+
See for more details
1687+
https://cloud.google.com/run/docs/configuring/vpc-connectors#egress-job.
16781688
cloud_function_memory_mib (int, Optional):
16791689
The amounts of memory (in mebibytes) to allocate for the cloud
16801690
function (2nd gen) created. This also dictates a corresponding
@@ -1732,6 +1742,7 @@ def remote_function(
17321742
cloud_function_timeout=cloud_function_timeout,
17331743
cloud_function_max_instances=cloud_function_max_instances,
17341744
cloud_function_vpc_connector=cloud_function_vpc_connector,
1745+
cloud_function_vpc_connector_egress_settings=cloud_function_vpc_connector_egress_settings,
17351746
cloud_function_memory_mib=cloud_function_memory_mib,
17361747
cloud_function_ingress_settings=cloud_function_ingress_settings,
17371748
cloud_build_service_account=cloud_build_service_account,

tests/system/large/functions/test_remote_function.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1478,14 +1478,20 @@ def square_num(x):
14781478
reuse=False,
14791479
cloud_function_service_account="default",
14801480
cloud_function_vpc_connector=gcf_vpc_connector,
1481+
cloud_function_vpc_connector_egress_settings="all",
14811482
cloud_function_ingress_settings="all",
14821483
)(square_num)
14831484

1484-
# assert that the GCF is created with the intended vpc connector
14851485
gcf = rf_session.cloudfunctionsclient.get_function(
14861486
name=square_num_remote.bigframes_cloud_function
14871487
)
1488+
1489+
# assert that the GCF is created with the intended vpc connector and
1490+
# egress settings.
14881491
assert gcf.service_config.vpc_connector == gcf_vpc_connector
1492+
# The value is <VpcConnectorEgressSettings.ALL_TRAFFIC: 2> since we set
1493+
# cloud_function_vpc_connector_egress_settings="all" earlier.
1494+
assert gcf.service_config.vpc_connector_egress_settings == 2
14891495

14901496
# assert that the function works as expected on data
14911497
scalars_df, scalars_pandas_df = scalars_dfs

0 commit comments

Comments
 (0)