-
Notifications
You must be signed in to change notification settings - Fork 221
Add support for VPC direct connect #1823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
8566bd9
1d81733
854affd
7d7a161
57a4d0b
dfe810f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Add support for VPC direct connect (network interfaces) (#1823) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -107,6 +107,35 @@ export type VpcEgressSetting = "PRIVATE_RANGES_ONLY" | "ALL_TRAFFIC"; | |
| */ | ||
| export type IngressSetting = "ALLOW_ALL" | "ALLOW_INTERNAL_ONLY" | "ALLOW_INTERNAL_AND_GCLB"; | ||
|
|
||
| /** | ||
| * Interface for a direct VPC network connection. | ||
| * At least one of network or subnetwork must be specified. | ||
| */ | ||
| export interface NetworkInterface { | ||
| /** | ||
| * Network to use for VPC direct connect. | ||
| * network or subnetwork must be specified to use VPC direct connect, though | ||
| * both can be specified as well. "default" is an acceptable value. | ||
| * Mutually exclusive with vpcConnector. | ||
| */ | ||
| network?: string | Expression<string> | ResetValue; | ||
|
|
||
| /** | ||
| * Subnetwork to use for VPC direct connect. | ||
| * network or subnetwork must be specified to use VPC direct connect, though | ||
| * both can be specified as well. "default" is an acceptable value. | ||
| * Mutually exclusive with vpcConnector. | ||
| */ | ||
| subnetwork?: string | Expression<string> | ResetValue; | ||
|
|
||
| /** | ||
| * Tags for VPC traffic. | ||
| * An optional field for VPC direct connect | ||
| * mutually exclusive with vpcConnector. | ||
| */ | ||
| tags?: string | string[] | Expression<string> | Expression<string[]> | ResetValue; | ||
| } | ||
|
|
||
| /** | ||
| * `GlobalOptions` are options that can be set across an entire project. | ||
| * These options are common to HTTPS and event handling functions. | ||
|
|
@@ -179,6 +208,7 @@ export interface GlobalOptions { | |
|
|
||
| /** | ||
| * Connect a function to a specified VPC connector. | ||
| * Mutually exclusive with networkInterface | ||
| */ | ||
| vpcConnector?: string | Expression<string> | ResetValue; | ||
|
|
||
|
|
@@ -187,6 +217,16 @@ export interface GlobalOptions { | |
| */ | ||
| vpcConnectorEgressSettings?: VpcEgressSetting | ResetValue; | ||
|
|
||
| /** | ||
| * An alias for vpcConnectorEgressSettings. | ||
| */ | ||
| vpcEgress?: VpcEgressSetting | ResetValue; | ||
|
|
||
| /** | ||
| * Network Interface to use with VPC Direct Connect | ||
| */ | ||
| networkInterface?: NetworkInterface | ResetValue; | ||
|
|
||
| /** | ||
| * Specific service account for the function to run as. | ||
| */ | ||
|
|
@@ -311,9 +351,18 @@ export function optionsToTriggerAnnotations( | |
| "ingressSettings", | ||
| "labels", | ||
| "vpcConnector", | ||
| "vpcConnectorEgressSettings", | ||
| "secrets" | ||
| ); | ||
|
|
||
| const vpcEgress = opts.vpcEgress ?? opts.vpcConnectorEgressSettings; | ||
| if (vpcEgress !== undefined) { | ||
| if (vpcEgress === null || vpcEgress instanceof ResetValue) { | ||
| annotation.vpcConnectorEgressSettings = null; | ||
| } else { | ||
| annotation.vpcConnectorEgressSettings = vpcEgress; | ||
| } | ||
| } | ||
|
|
||
| convertIfPresent(annotation, opts, "availableMemoryMb", "memory", (mem: MemoryOption) => { | ||
| return MemoryOptionToMB[mem]; | ||
| }); | ||
|
|
@@ -333,7 +382,7 @@ export function optionsToTriggerAnnotations( | |
| convertIfPresent(annotation, opts, "timeout", "timeoutSeconds", durationFromSeconds); | ||
| convertIfPresent( | ||
| annotation, | ||
| opts as any as EventHandlerOptions, | ||
| opts as EventHandlerOptions, | ||
| "failurePolicy", | ||
| "retry", | ||
| (retry: boolean) => { | ||
|
|
@@ -365,12 +414,37 @@ export function optionsToEndpoint( | |
| "cpu" | ||
| ); | ||
| convertIfPresent(endpoint, opts, "serviceAccountEmail", "serviceAccount"); | ||
| if (opts.vpcConnector !== undefined) { | ||
| if (opts.vpcConnector === null || opts.vpcConnector instanceof ResetValue) { | ||
| const vpcEgress = opts.vpcEgress ?? opts.vpcConnectorEgressSettings; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. iiuc, it looks like we are silently prioritizing vpcEgress if both that and vpcConnectorEgressSettings are provided. Was curious if we want to log a warning if a user accidentally supplies both, or is the alias behavior intended to be a silent override?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That seems pretty reasonable. |
||
| const connector = opts.vpcConnector; | ||
| const networkInterface = opts.networkInterface; | ||
inlined marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (connector !== undefined || vpcEgress !== undefined || networkInterface !== undefined) { | ||
| const resetConnector = connector === null || connector instanceof ResetValue; | ||
| const hasConnector = !!connector; | ||
| const resetNetwork = networkInterface === null || networkInterface instanceof ResetValue; | ||
| const hasNetwork = !!networkInterface && !resetNetwork; | ||
inlined marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (hasNetwork) { | ||
| if (!networkInterface.network && !networkInterface.subnetwork) { | ||
| throw new Error( | ||
| "At least one of network or subnetwork must be specified in networkInterface." | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| // It's OK to reset one and set the other, that's just being pedantic while switching types. | ||
| // But if you only use a reset value, that means you don't want VPC at all. | ||
| if (hasNetwork && hasConnector) { | ||
| throw new Error("Cannot set both vpcConnector and networkInterface"); | ||
| } else if ((resetConnector && !hasNetwork) || (resetNetwork && !hasConnector)) { | ||
| endpoint.vpc = RESET_VALUE; | ||
| } else { | ||
| const vpc: ManifestEndpoint["vpc"] = { connector: opts.vpcConnector }; | ||
| convertIfPresent(vpc, opts, "egressSettings", "vpcConnectorEgressSettings"); | ||
| const vpc: ManifestEndpoint["vpc"] = {}; | ||
| convertIfPresent(vpc, opts, "connector", "vpcConnector"); | ||
| if (vpcEgress !== undefined) { | ||
| vpc.egressSettings = vpcEgress; | ||
| } | ||
| convertIfPresent(vpc, opts, "networkInterfaces", "networkInterface", (a) => [a]); | ||
| endpoint.vpc = vpc; | ||
inlined marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that in manifest.ts, we support an array of network interfaces. But here we only expose a singular object. Is it something that was intentional or do we plan on something like networkInterfaces?: NetworkInterface | NetworkInterface[] in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great question, and yes. The Google API is a plural but only supports arrays of size one. To support ergonomics, we will currently only accept a singular in our API and eventually support a plural if GCF ever supports one, but our wire format will always be plural to avoid mistakes.
This is part of the predictability principle that you should be forgiving in what you accept (e.g. singular or plural) but strict in what you produce (plural)