From 03e10d6f71ca2c0d4046c68b5d220506954673ef Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Fri, 15 Apr 2022 16:43:50 -0700 Subject: [PATCH 1/6] Add secrets to v2 endpoint annotation. --- spec/v2/providers/fixtures.ts | 9 +++++++-- src/v2/core.ts | 2 ++ src/v2/options.ts | 28 +++++++++++++++++++++++++--- src/v2/providers/https.ts | 34 ++++++++++++---------------------- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/spec/v2/providers/fixtures.ts b/spec/v2/providers/fixtures.ts index 53aa852b3..d0c1034c6 100644 --- a/spec/v2/providers/fixtures.ts +++ b/spec/v2/providers/fixtures.ts @@ -1,3 +1,5 @@ +import { ManifestEndpoint } from '../../../src/runtime/manifest'; +import { TriggerAnnotation } from '../../../src/v2/core'; import * as options from '../../../src/v2/options'; export const FULL_OPTIONS: options.GlobalOptions = { @@ -15,9 +17,10 @@ export const FULL_OPTIONS: options.GlobalOptions = { labels: { hello: 'world', }, + secrets: ['MY_SECRET'], }; -export const FULL_TRIGGER = { +export const FULL_TRIGGER: TriggerAnnotation = { platform: 'gcfv2', regions: ['us-west1'], availableMemoryMb: 512, @@ -32,9 +35,10 @@ export const FULL_TRIGGER = { labels: { hello: 'world', }, + secrets: ['MY_SECRET'], }; -export const FULL_ENDPOINT = { +export const FULL_ENDPOINT: ManifestEndpoint = { platform: 'gcfv2', region: ['us-west1'], availableMemoryMb: 512, @@ -52,4 +56,5 @@ export const FULL_ENDPOINT = { labels: { hello: 'world', }, + secretEnvironmentVariables: [{ key: 'MY_SECRET', secret: 'MY_SECRET' }], }; diff --git a/src/v2/core.ts b/src/v2/core.ts index 1160d09ed..76d1e31aa 100644 --- a/src/v2/core.ts +++ b/src/v2/core.ts @@ -24,6 +24,7 @@ import { ManifestEndpoint } from '../runtime/manifest'; /** @internal */ export interface TriggerAnnotation { + platform?: string; concurrency?: number; minInstances?: number; maxInstances?: number; @@ -44,6 +45,7 @@ export interface TriggerAnnotation { vpcConnectorEgressSettings?: string; serviceAccountEmail?: string; ingressSettings?: string; + secrets?: string[]; // TODO: schedule } diff --git a/src/v2/options.ts b/src/v2/options.ts index bfbc3195d..f528dc50c 100644 --- a/src/v2/options.ts +++ b/src/v2/options.ts @@ -215,6 +215,11 @@ export interface GlobalOptions { * Invoker to set access control on https functions. */ invoker?: 'public' | 'private' | string | string[]; + + /* + * Secrets to bind to a functions. + */ + secrets?: string[]; } let globalOptions: GlobalOptions | undefined; @@ -239,6 +244,15 @@ export function getGlobalOptions(): GlobalOptions { return globalOptions || {}; } +/** + * Options that can be set on an individual HTTPS Cloud Function. + */ +export interface HttpsOptions extends Omit { + /* HTTP functions can override and specify more than one regions. */ + region?: SupportedRegion | string | Array; + cors?: string | boolean | RegExp | Array; +} + /** * Options that can be set on an individual event-handling Cloud Function. */ @@ -251,7 +265,7 @@ export interface EventHandlerOptions extends GlobalOptions { * @internal */ export function optionsToTriggerAnnotations( - opts: GlobalOptions | EventHandlerOptions + opts: GlobalOptions | EventHandlerOptions | HttpsOptions ): TriggerAnnotation { const annotation: TriggerAnnotation = {}; copyIfPresent( @@ -263,7 +277,8 @@ export function optionsToTriggerAnnotations( 'ingressSettings', 'labels', 'vpcConnector', - 'vpcConnectorEgressSettings' + 'vpcConnectorEgressSettings', + 'secrets' ); convertIfPresent( annotation, @@ -312,7 +327,7 @@ export function optionsToTriggerAnnotations( * @internal */ export function optionsToEndpoint( - opts: GlobalOptions | EventHandlerOptions + opts: GlobalOptions | EventHandlerOptions | HttpsOptions ): ManifestEndpoint { const endpoint: ManifestEndpoint = {}; copyIfPresent( @@ -350,6 +365,13 @@ export function optionsToEndpoint( } return region; }); + convertIfPresent( + endpoint, + opts, + 'secretEnvironmentVariables', + 'secrets', + (secrets) => secrets.map((secret) => ({ secret, key: secret })) + ); return endpoint; } diff --git a/src/v2/providers/https.ts b/src/v2/providers/https.ts index f6101ba1b..8f84cff6f 100644 --- a/src/v2/providers/https.ts +++ b/src/v2/providers/https.ts @@ -36,14 +36,6 @@ import * as options from '../options'; export { Request, CallableRequest, FunctionsErrorCode, HttpsError }; -export interface HttpsOptions extends Omit { - region?: - | options.SupportedRegion - | string - | Array; - cors?: string | boolean | RegExp | Array; -} - export type HttpsFunction = (( req: Request, res: express.Response @@ -56,7 +48,7 @@ export interface CallableFunction extends HttpsFunction { } export function onRequest( - opts: HttpsOptions, + opts: options.HttpsOptions, handler: ( request: Request, response: express.Response @@ -70,14 +62,14 @@ export function onRequest( ): HttpsFunction; export function onRequest( optsOrHandler: - | HttpsOptions + | options.HttpsOptions | ((request: Request, response: express.Response) => void | Promise), handler?: ( request: Request, response: express.Response ) => void | Promise ): HttpsFunction { - let opts: HttpsOptions; + let opts: options.HttpsOptions; if (arguments.length === 1) { opts = {}; handler = optsOrHandler as ( @@ -85,7 +77,7 @@ export function onRequest( response: express.Response ) => void | Promise; } else { - opts = optsOrHandler as HttpsOptions; + opts = optsOrHandler as options.HttpsOptions; } if ('cors' in opts) { @@ -160,22 +152,24 @@ export function onRequest( } export function onCall>( - opts: HttpsOptions, + opts: options.HttpsOptions, handler: (request: CallableRequest) => Return ): CallableFunction; export function onCall>( handler: (request: CallableRequest) => Return ): CallableFunction; export function onCall>( - optsOrHandler: HttpsOptions | ((request: CallableRequest) => Return), + optsOrHandler: + | options.HttpsOptions + | ((request: CallableRequest) => Return), handler?: (request: CallableRequest) => Return ): CallableFunction { - let opts: HttpsOptions; + let opts: options.HttpsOptions; if (arguments.length == 1) { opts = {}; handler = optsOrHandler as (request: CallableRequest) => Return; } else { - opts = optsOrHandler as HttpsOptions; + opts = optsOrHandler as options.HttpsOptions; } const origin = 'cors' in opts ? opts.cors : true; @@ -195,9 +189,7 @@ export function onCall>( ); // global options calls region a scalar and https allows it to be an array, // but optionsToTriggerAnnotations handles both cases. - const specificOpts = options.optionsToTriggerAnnotations( - opts as options.GlobalOptions - ); + const specificOpts = options.optionsToTriggerAnnotations(opts); return { platform: 'gcfv2', ...baseOpts, @@ -215,9 +207,7 @@ export function onCall>( }); const baseOpts = options.optionsToEndpoint(options.getGlobalOptions()); - // global options calls region a scalar and https allows it to be an array, - // but optionsToManifestEndpoint handles both cases. - const specificOpts = options.optionsToEndpoint(opts as options.GlobalOptions); + const specificOpts = options.optionsToEndpoint(opts); func.__endpoint = { platform: 'gcfv2', ...baseOpts, From b7b0f7ed6fab943ca70eb049b17633e53aae3e1b Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 28 Apr 2022 22:26:20 -0700 Subject: [PATCH 2/6] Move HttpsOptions back to https.ts namespace. --- src/v2/options.ts | 25 ++++++------------------- src/v2/providers/https.ts | 39 +++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/v2/options.ts b/src/v2/options.ts index f528dc50c..f9f9e0082 100644 --- a/src/v2/options.ts +++ b/src/v2/options.ts @@ -20,17 +20,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { - convertIfPresent, - copyIfPresent, - durationFromSeconds, - serviceAccountFromShorthand, -} from '../common/encoding'; +import {convertIfPresent, copyIfPresent, durationFromSeconds, serviceAccountFromShorthand,} from '../common/encoding'; import * as logger from '../logger'; -import { ManifestEndpoint } from '../runtime/manifest'; -import { TriggerAnnotation } from './core'; -import { declaredParams } from './params'; -import { ParamSpec } from './params/types'; +import {ManifestEndpoint} from '../runtime/manifest'; +import {TriggerAnnotation} from './core'; +import {declaredParams} from './params'; +import {ParamSpec} from './params/types'; +import {HttpsOptions} from "./providers/https"; /** * List of all regions supported by Cloud Functions v2 @@ -244,15 +240,6 @@ export function getGlobalOptions(): GlobalOptions { return globalOptions || {}; } -/** - * Options that can be set on an individual HTTPS Cloud Function. - */ -export interface HttpsOptions extends Omit { - /* HTTP functions can override and specify more than one regions. */ - region?: SupportedRegion | string | Array; - cors?: string | boolean | RegExp | Array; -} - /** * Options that can be set on an individual event-handling Cloud Function. */ diff --git a/src/v2/providers/https.ts b/src/v2/providers/https.ts index 8f84cff6f..5e0635a99 100644 --- a/src/v2/providers/https.ts +++ b/src/v2/providers/https.ts @@ -22,20 +22,24 @@ import * as cors from 'cors'; import * as express from 'express'; -import { convertIfPresent, convertInvoker } from '../../common/encoding'; +import {convertIfPresent, convertInvoker} from '../../common/encoding'; -import { - CallableRequest, - FunctionsErrorCode, - HttpsError, - onCallHandler, - Request, -} from '../../common/providers/https'; -import { ManifestEndpoint } from '../../runtime/manifest'; +import {CallableRequest, FunctionsErrorCode, HttpsError, onCallHandler, Request,} from '../../common/providers/https'; +import {ManifestEndpoint} from '../../runtime/manifest'; import * as options from '../options'; +import {GlobalOptions, SupportedRegion} from '../options'; export { Request, CallableRequest, FunctionsErrorCode, HttpsError }; +/** + * Options that can be set on an individual HTTPS Cloud Function. + */ +export interface HttpsOptions extends Omit { + /* HTTP functions can override and specify more than one regions. */ + region?: SupportedRegion | string | Array; + cors?: string | boolean | RegExp | Array; +} + export type HttpsFunction = (( req: Request, res: express.Response @@ -46,9 +50,8 @@ export type HttpsFunction = (( export interface CallableFunction extends HttpsFunction { run(data: CallableRequest): Return; } - export function onRequest( - opts: options.HttpsOptions, + opts: HttpsOptions, handler: ( request: Request, response: express.Response @@ -62,14 +65,14 @@ export function onRequest( ): HttpsFunction; export function onRequest( optsOrHandler: - | options.HttpsOptions + | HttpsOptions | ((request: Request, response: express.Response) => void | Promise), handler?: ( request: Request, response: express.Response ) => void | Promise ): HttpsFunction { - let opts: options.HttpsOptions; + let opts: HttpsOptions; if (arguments.length === 1) { opts = {}; handler = optsOrHandler as ( @@ -77,7 +80,7 @@ export function onRequest( response: express.Response ) => void | Promise; } else { - opts = optsOrHandler as options.HttpsOptions; + opts = optsOrHandler as HttpsOptions; } if ('cors' in opts) { @@ -152,7 +155,7 @@ export function onRequest( } export function onCall>( - opts: options.HttpsOptions, + opts: HttpsOptions, handler: (request: CallableRequest) => Return ): CallableFunction; export function onCall>( @@ -160,16 +163,16 @@ export function onCall>( ): CallableFunction; export function onCall>( optsOrHandler: - | options.HttpsOptions + | HttpsOptions | ((request: CallableRequest) => Return), handler?: (request: CallableRequest) => Return ): CallableFunction { - let opts: options.HttpsOptions; + let opts: HttpsOptions; if (arguments.length == 1) { opts = {}; handler = optsOrHandler as (request: CallableRequest) => Return; } else { - opts = optsOrHandler as options.HttpsOptions; + opts = optsOrHandler as HttpsOptions; } const origin = 'cors' in opts ? opts.cors : true; From 869f99d1184dc13b751e9a5835fb0eb0d552b974 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 28 Apr 2022 22:47:34 -0700 Subject: [PATCH 3/6] Secret option should only set key and not bind secret resource name in container contract. --- spec/v1/cloud-functions.spec.ts | 4 ++-- spec/v2/providers/fixtures.ts | 2 +- src/cloud-functions.ts | 2 +- src/v2/options.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/v1/cloud-functions.spec.ts b/spec/v1/cloud-functions.spec.ts index 5dd0a8941..fec1bd580 100644 --- a/spec/v1/cloud-functions.spec.ts +++ b/spec/v1/cloud-functions.spec.ts @@ -29,7 +29,7 @@ import { EventContext, makeCloudFunction, MakeCloudFunctionArgs, -} from '../../src/cloud-functions'; +} from '../../src'; describe('makeCloudFunction', () => { const cloudFunctionArgs: MakeCloudFunctionArgs = { @@ -124,7 +124,7 @@ describe('makeCloudFunction', () => { }, retry: false, }, - secretEnvironmentVariables: [{ secret: 'MY_SECRET', key: 'MY_SECRET' }], + secretEnvironmentVariables: [{ key: 'MY_SECRET' }], labels: {}, }); }); diff --git a/spec/v2/providers/fixtures.ts b/spec/v2/providers/fixtures.ts index d0c1034c6..7a054572e 100644 --- a/spec/v2/providers/fixtures.ts +++ b/spec/v2/providers/fixtures.ts @@ -56,5 +56,5 @@ export const FULL_ENDPOINT: ManifestEndpoint = { labels: { hello: 'world', }, - secretEnvironmentVariables: [{ key: 'MY_SECRET', secret: 'MY_SECRET' }], + secretEnvironmentVariables: [{ key: 'MY_SECRET' }], }; diff --git a/src/cloud-functions.ts b/src/cloud-functions.ts index ffe94e031..b6153ad3a 100644 --- a/src/cloud-functions.ts +++ b/src/cloud-functions.ts @@ -627,7 +627,7 @@ export function optionsToEndpoint( options, 'secretEnvironmentVariables', 'secrets', - (secrets) => secrets.map((secret) => ({ secret, key: secret })) + (secrets) => secrets.map((secret) => ({ key: secret })) ); if (options?.vpcConnector) { endpoint.vpc = { connector: options.vpcConnector }; diff --git a/src/v2/options.ts b/src/v2/options.ts index f9f9e0082..2b653c23d 100644 --- a/src/v2/options.ts +++ b/src/v2/options.ts @@ -357,7 +357,7 @@ export function optionsToEndpoint( opts, 'secretEnvironmentVariables', 'secrets', - (secrets) => secrets.map((secret) => ({ secret, key: secret })) + (secrets) => secrets.map((secret) => ({ key: secret })) ); return endpoint; From 0080883483d5290e16d2cd325c8a7e3648d02bae Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 28 Apr 2022 22:48:41 -0700 Subject: [PATCH 4/6] Prettier. --- src/v2/options.ts | 17 +++++++++++------ src/v2/providers/https.ts | 18 +++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/v2/options.ts b/src/v2/options.ts index 2b653c23d..42404bfa0 100644 --- a/src/v2/options.ts +++ b/src/v2/options.ts @@ -20,13 +20,18 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import {convertIfPresent, copyIfPresent, durationFromSeconds, serviceAccountFromShorthand,} from '../common/encoding'; +import { + convertIfPresent, + copyIfPresent, + durationFromSeconds, + serviceAccountFromShorthand, +} from '../common/encoding'; import * as logger from '../logger'; -import {ManifestEndpoint} from '../runtime/manifest'; -import {TriggerAnnotation} from './core'; -import {declaredParams} from './params'; -import {ParamSpec} from './params/types'; -import {HttpsOptions} from "./providers/https"; +import { ManifestEndpoint } from '../runtime/manifest'; +import { TriggerAnnotation } from './core'; +import { declaredParams } from './params'; +import { ParamSpec } from './params/types'; +import { HttpsOptions } from './providers/https'; /** * List of all regions supported by Cloud Functions v2 diff --git a/src/v2/providers/https.ts b/src/v2/providers/https.ts index 5e0635a99..51fd7b18b 100644 --- a/src/v2/providers/https.ts +++ b/src/v2/providers/https.ts @@ -22,12 +22,18 @@ import * as cors from 'cors'; import * as express from 'express'; -import {convertIfPresent, convertInvoker} from '../../common/encoding'; +import { convertIfPresent, convertInvoker } from '../../common/encoding'; -import {CallableRequest, FunctionsErrorCode, HttpsError, onCallHandler, Request,} from '../../common/providers/https'; -import {ManifestEndpoint} from '../../runtime/manifest'; +import { + CallableRequest, + FunctionsErrorCode, + HttpsError, + onCallHandler, + Request, +} from '../../common/providers/https'; +import { ManifestEndpoint } from '../../runtime/manifest'; import * as options from '../options'; -import {GlobalOptions, SupportedRegion} from '../options'; +import { GlobalOptions, SupportedRegion } from '../options'; export { Request, CallableRequest, FunctionsErrorCode, HttpsError }; @@ -162,9 +168,7 @@ export function onCall>( handler: (request: CallableRequest) => Return ): CallableFunction; export function onCall>( - optsOrHandler: - | HttpsOptions - | ((request: CallableRequest) => Return), + optsOrHandler: HttpsOptions | ((request: CallableRequest) => Return), handler?: (request: CallableRequest) => Return ): CallableFunction { let opts: HttpsOptions; From e691265165710ec8cc63e21e615f67fe934aa931 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Thu, 28 Apr 2022 22:53:39 -0700 Subject: [PATCH 5/6] Revive unnecessarily removed comment. --- src/v2/providers/https.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/v2/providers/https.ts b/src/v2/providers/https.ts index 51fd7b18b..3cd095e94 100644 --- a/src/v2/providers/https.ts +++ b/src/v2/providers/https.ts @@ -214,6 +214,8 @@ export function onCall>( }); const baseOpts = options.optionsToEndpoint(options.getGlobalOptions()); + // global options calls region a scalar and https allows it to be an array, + // but optionsToEndpoint handles both cases. const specificOpts = options.optionsToEndpoint(opts); func.__endpoint = { platform: 'gcfv2', From 9463b02fed97ff610a5f6bb406fa384e3ae0c4cf Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Fri, 29 Apr 2022 12:33:15 -0700 Subject: [PATCH 6/6] Add changelog entry. --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6008e08a6..ddc0e009c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1,2 @@ -Adds auth blocking triggers to the auth and identity namespaces (1080). +- Adds auth blocking triggers to the auth and identity namespaces (1080). +- Add support for secrets for v2 triggers (#1079).