From 02d0876bbb196e9fbeb32d977e7cf65229c8559d Mon Sep 17 00:00:00 2001 From: Andreas Sieferlinger Date: Thu, 15 Dec 2022 11:52:06 +0100 Subject: [PATCH] feat(lambda): expose all docker run options to container bundling of all lambda variants (#23318) This continues the work started in #22829 by exposing the underlying docker run options of the container bundling. With that the bundling feature can be used in a wider range of setups that the current defaults can not support out of the box. The removed properties are covered in the same way by the one the interface extends from. ---- ### All Submissions: * [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda-go/README.md | 15 ++ .../@aws-cdk/aws-lambda-go/lib/bundling.ts | 23 ++- packages/@aws-cdk/aws-lambda-go/lib/types.ts | 11 +- .../aws-lambda-go/test/bundling.test.ts | 126 ++++++++++++++++ packages/@aws-cdk/aws-lambda-nodejs/README.md | 14 ++ .../aws-lambda-nodejs/lib/bundling.ts | 16 ++- .../@aws-cdk/aws-lambda-nodejs/lib/types.ts | 11 +- .../aws-lambda-nodejs/test/bundling.test.ts | 134 ++++++++++++++++++ packages/@aws-cdk/aws-lambda-python/README.md | 18 +++ .../aws-lambda-python/lib/bundling.ts | 18 ++- .../@aws-cdk/aws-lambda-python/lib/types.ts | 11 +- .../aws-lambda-python/test/bundling.test.ts | 96 +++++++++++++ 12 files changed, 461 insertions(+), 32 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda-go/README.md b/packages/@aws-cdk/aws-lambda-go/README.md index f79d8c8a862ec..748ab32256ec0 100644 --- a/packages/@aws-cdk/aws-lambda-go/README.md +++ b/packages/@aws-cdk/aws-lambda-go/README.md @@ -183,6 +183,21 @@ new go.GoFunction(this, 'GoFunction', { }); ``` +You can set additional Docker options to configure the build environment: + + ```ts +new go.GoFunction(this, 'GoFunction', { + entry: 'app/cmd/api', + bundling: { + network: 'host', + securityOpt: 'no-new-privileges', + user: 'user:group', + volumesFrom: ['777f7dc92da7'], + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + }, +}); +``` + ## Command hooks It is possible to run additional commands by specifying the `commandHooks` prop: diff --git a/packages/@aws-cdk/aws-lambda-go/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-go/lib/bundling.ts index d30c753df7839..62645d0ae8cc6 100644 --- a/packages/@aws-cdk/aws-lambda-go/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-go/lib/bundling.ts @@ -78,6 +78,13 @@ export class Bundling implements cdk.BundlingOptions { command: bundling.command, environment: bundling.environment, local: bundling.local, + entrypoint: bundling.entrypoint, + volumes: bundling.volumes, + volumesFrom: bundling.volumesFrom, + workingDirectory: bundling.workingDirectory, + user: bundling.user, + securityOpt: bundling.securityOpt, + network: bundling.network, }, }); } @@ -93,6 +100,13 @@ export class Bundling implements cdk.BundlingOptions { public readonly command: string[]; public readonly environment?: { [key: string]: string }; public readonly local?: cdk.ILocalBundling; + public readonly entrypoint?: string[] + public readonly volumes?: cdk.DockerVolume[]; + public readonly volumesFrom?: string[]; + public readonly workingDirectory?: string; + public readonly user?: string; + public readonly securityOpt?: string; + public readonly network?: string; private readonly relativeEntryPath: string; @@ -131,8 +145,15 @@ export class Bundling implements cdk.BundlingOptions { : cdk.DockerImage.fromRegistry('dummy'); // Do not build if we don't need to const bundlingCommand = this.createBundlingCommand(cdk.AssetStaging.BUNDLING_INPUT_DIR, cdk.AssetStaging.BUNDLING_OUTPUT_DIR); - this.command = ['bash', '-c', bundlingCommand]; + this.command = props.command ?? ['bash', '-c', bundlingCommand]; this.environment = environment; + this.entrypoint = props.entrypoint; + this.volumes = props.volumes; + this.volumesFrom = props.volumesFrom; + this.workingDirectory = props.workingDirectory; + this.user = props.user; + this.securityOpt = props.securityOpt; + this.network = props.network; // Local bundling if (!props.forcedDockerBundling) { // only if Docker is not forced diff --git a/packages/@aws-cdk/aws-lambda-go/lib/types.ts b/packages/@aws-cdk/aws-lambda-go/lib/types.ts index c754cbdbcf664..5dc7beb8f886c 100644 --- a/packages/@aws-cdk/aws-lambda-go/lib/types.ts +++ b/packages/@aws-cdk/aws-lambda-go/lib/types.ts @@ -1,16 +1,9 @@ -import { AssetHashType, DockerImage } from '@aws-cdk/core'; +import { AssetHashType, DockerImage, DockerRunOptions } from '@aws-cdk/core'; /** * Bundling options */ -export interface BundlingOptions { - /** - * Environment variables defined when go runs. - * - * @default - no environment variables are defined. - */ - readonly environment?: { [key: string]: string; }; - +export interface BundlingOptions extends DockerRunOptions { /** * Force bundling in a Docker container even if local bundling is * possible. diff --git a/packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts index 73dfec99b45c1..134dd0f51716f 100644 --- a/packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts @@ -335,3 +335,129 @@ test('with command hooks', () => { }), }); }); + +test('Custom bundling entrypoint', () => { + Bundling.bundle({ + entry, + moduleDir, + runtime: Runtime.GO_1_X, + architecture: Architecture.X86_64, + forcedDockerBundling: true, + entrypoint: ['/cool/entrypoint', '--cool-entrypoint-arg'], + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + entrypoint: ['/cool/entrypoint', '--cool-entrypoint-arg'], + }), + }); +}); + +test('Custom bundling volumes', () => { + Bundling.bundle({ + entry, + moduleDir, + runtime: Runtime.GO_1_X, + architecture: Architecture.X86_64, + forcedDockerBundling: true, + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + }), + }); +}); + +test('Custom bundling volumesFrom', () => { + Bundling.bundle({ + entry, + moduleDir, + runtime: Runtime.GO_1_X, + architecture: Architecture.X86_64, + forcedDockerBundling: true, + volumesFrom: ['777f7dc92da7'], + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + volumesFrom: ['777f7dc92da7'], + }), + }); +}); + +test('Custom bundling workingDirectory', () => { + Bundling.bundle({ + entry, + moduleDir, + runtime: Runtime.GO_1_X, + architecture: Architecture.X86_64, + forcedDockerBundling: true, + workingDirectory: '/working-directory', + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + workingDirectory: '/working-directory', + }), + }); +}); + +test('Custom bundling user', () => { + Bundling.bundle({ + entry, + moduleDir, + runtime: Runtime.GO_1_X, + architecture: Architecture.X86_64, + forcedDockerBundling: true, + user: 'user:group', + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + user: 'user:group', + }), + }); +}); + +test('Custom bundling securityOpt', () => { + Bundling.bundle({ + entry, + moduleDir, + runtime: Runtime.GO_1_X, + architecture: Architecture.X86_64, + forcedDockerBundling: true, + securityOpt: 'no-new-privileges', + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + securityOpt: 'no-new-privileges', + }), + }); +}); + +test('Custom bundling network', () => { + Bundling.bundle({ + entry, + moduleDir, + runtime: Runtime.GO_1_X, + architecture: Architecture.X86_64, + forcedDockerBundling: true, + network: 'host', + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + network: 'host', + }), + }); +}); diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index 3953bd225aaca..24d6582d67732 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -307,6 +307,20 @@ should also have `npm`, `yarn` or `pnpm` depending on the lock file you're using Use the [default image provided by `@aws-cdk/aws-lambda-nodejs`](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-lambda-nodejs/lib/Dockerfile) as a source of inspiration. +You can set additional Docker options to configure the build environment: + + ```ts +new nodejs.NodejsFunction(this, 'my-handler', { + bundling: { + network: 'host', + securityOpt: 'no-new-privileges', + user: 'user:group', + volumesFrom: ['777f7dc92da7'], + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + }, +}); +``` + ## Asset hash By default the asset hash will be calculated based on the bundled output (`AssetHashType.OUTPUT`). diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts index 2c16103b0863c..8809166a6e57b 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts @@ -73,9 +73,15 @@ export class Bundling implements cdk.BundlingOptions { // Core bundling options public readonly image: cdk.DockerImage; + public readonly entrypoint?: string[] public readonly command: string[]; + public readonly volumes?: cdk.DockerVolume[]; + public readonly volumesFrom?: string[]; public readonly environment?: { [key: string]: string }; public readonly workingDirectory: string; + public readonly user?: string; + public readonly securityOpt?: string; + public readonly network?: string; public readonly local?: cdk.ILocalBundling; private readonly projectRoot: string; @@ -137,11 +143,17 @@ export class Bundling implements cdk.BundlingOptions { tscRunner: 'tsc', // tsc is installed globally in the docker image osPlatform: 'linux', // linux docker image }); - this.command = ['bash', '-c', bundlingCommand]; + this.command = props.command ?? ['bash', '-c', bundlingCommand]; this.environment = props.environment; // Bundling sets the working directory to cdk.AssetStaging.BUNDLING_INPUT_DIR // and we want to force npx to use the globally installed esbuild. - this.workingDirectory = '/'; + this.workingDirectory = props.workingDirectory ?? '/'; + this.entrypoint = props.entrypoint; + this.volumes = props.volumes; + this.volumesFrom = props.volumesFrom; + this.user = props.user; + this.securityOpt = props.securityOpt; + this.network = props.network; // Local bundling if (!props.forceDockerBundling) { // only if Docker is not forced diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts index c0096404b2511..0d79db703287e 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts @@ -1,9 +1,9 @@ -import { DockerImage } from '@aws-cdk/core'; +import { DockerImage, DockerRunOptions } from '@aws-cdk/core'; /** * Bundling options */ -export interface BundlingOptions { +export interface BundlingOptions extends DockerRunOptions { /** * Whether to minify files when bundling. * @@ -161,13 +161,6 @@ export interface BundlingOptions { */ readonly charset?: Charset; - /** - * Environment variables defined when bundling runs. - * - * @default - no environment variables are defined. - */ - readonly environment?: { [key: string]: string; }; - /** * Replace global identifiers with constant expressions. * diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts index 0259180de8a54..83029ec601590 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -668,3 +668,137 @@ test('with custom hash', () => { assetHashType: AssetHashType.CUSTOM, })); }); + +test('Custom bundling entrypoint', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + architecture: Architecture.X86_64, + forceDockerBundling: true, + entrypoint: ['/cool/entrypoint', '--cool-entrypoint-arg'], + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + entrypoint: ['/cool/entrypoint', '--cool-entrypoint-arg'], + }), + }); +}); + +test('Custom bundling volumes', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + architecture: Architecture.X86_64, + forceDockerBundling: true, + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + }), + }); +}); + +test('Custom bundling volumesFrom', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + architecture: Architecture.X86_64, + forceDockerBundling: true, + volumesFrom: ['777f7dc92da7'], + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + volumesFrom: ['777f7dc92da7'], + }), + }); +}); + + +test('Custom bundling workingDirectory', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + architecture: Architecture.X86_64, + forceDockerBundling: true, + workingDirectory: '/working-directory', + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + workingDirectory: '/working-directory', + }), + }); +}); + +test('Custom bundling user', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + architecture: Architecture.X86_64, + forceDockerBundling: true, + user: 'user:group', + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + user: 'user:group', + }), + }); +}); + +test('Custom bundling securityOpt', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + architecture: Architecture.X86_64, + forceDockerBundling: true, + securityOpt: 'no-new-privileges', + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + securityOpt: 'no-new-privileges', + }), + }); +}); + +test('Custom bundling network', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + architecture: Architecture.X86_64, + forceDockerBundling: true, + network: 'host', + }); + + expect(Code.fromAsset).toHaveBeenCalledWith('/project', { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + network: 'host', + }), + }); +}); diff --git a/packages/@aws-cdk/aws-lambda-python/README.md b/packages/@aws-cdk/aws-lambda-python/README.md index 04f092e5f2875..f7ca29de39e0a 100644 --- a/packages/@aws-cdk/aws-lambda-python/README.md +++ b/packages/@aws-cdk/aws-lambda-python/README.md @@ -145,6 +145,24 @@ new python.PythonFunction(this, 'function', { }); ``` +You can set additional Docker options to configure the build environment: + + ```ts +const entry = '/path/to/function'; + +new python.PythonFunction(this, 'function', { + entry, + runtime: Runtime.PYTHON_3_8, + bundling: { + network: 'host', + securityOpt: 'no-new-privileges', + user: 'user:group', + volumesFrom: ['777f7dc92da7'], + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + }, +}); +``` + ## Custom Bundling with Code Artifact To use a Code Artifact PyPI repo, the `PIP_INDEX_URL` for bundling the function can be customized (requires AWS CLI in the build environment): diff --git a/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts index 5302673a5e296..f83756a334fe8 100644 --- a/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import { Architecture, AssetCode, Code, Runtime } from '@aws-cdk/aws-lambda'; -import { AssetStaging, BundlingOptions as CdkBundlingOptions, DockerImage } from '@aws-cdk/core'; +import { AssetStaging, BundlingOptions as CdkBundlingOptions, DockerImage, DockerVolume } from '@aws-cdk/core'; import { Packaging, DependenciesFile } from './packaging'; import { BundlingOptions, ICommandHooks } from './types'; @@ -57,8 +57,15 @@ export class Bundling implements CdkBundlingOptions { } public readonly image: DockerImage; + public readonly entrypoint?: string[] public readonly command: string[]; + public readonly volumes?: DockerVolume[]; + public readonly volumesFrom?: string[]; public readonly environment?: { [key: string]: string }; + public readonly workingDirectory?: string; + public readonly user?: string; + public readonly securityOpt?: string; + public readonly network?: string; constructor(props: BundlingProps) { const { @@ -88,8 +95,15 @@ export class Bundling implements CdkBundlingOptions { }, platform: architecture.dockerPlatform, }); - this.command = ['bash', '-c', chain(bundlingCommands)]; + this.command = props.command ?? ['bash', '-c', chain(bundlingCommands)]; + this.entrypoint = props.entrypoint; + this.volumes = props.volumes; + this.volumesFrom = props.volumesFrom; this.environment = props.environment; + this.workingDirectory = props.workingDirectory; + this.user = props.user; + this.securityOpt = props.securityOpt; + this.network = props.network; } private createBundlingCommand(options: BundlingCommandOptions): string[] { diff --git a/packages/@aws-cdk/aws-lambda-python/lib/types.ts b/packages/@aws-cdk/aws-lambda-python/lib/types.ts index ff9608b97e2f1..ad0ff6f8ce09d 100644 --- a/packages/@aws-cdk/aws-lambda-python/lib/types.ts +++ b/packages/@aws-cdk/aws-lambda-python/lib/types.ts @@ -1,10 +1,10 @@ -import { AssetHashType, DockerImage } from '@aws-cdk/core'; +import { AssetHashType, DockerImage, DockerRunOptions } from '@aws-cdk/core'; /** * Options for bundling */ -export interface BundlingOptions { +export interface BundlingOptions extends DockerRunOptions { /** * Whether to export Poetry dependencies with hashes. Note that this can cause builds to fail if not all dependencies @@ -40,13 +40,6 @@ export interface BundlingOptions { */ readonly buildArgs?: { [key: string]: string }; - /** - * Environment variables defined when bundling runs. - * - * @default - no environment variables are defined. - */ - readonly environment?: { [key: string]: string; }; - /** * Determines how asset hash is calculated. Assets will get rebuild and * uploaded only if their hash has changed. diff --git a/packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts index 402953c197c1c..d6172ccfb705b 100644 --- a/packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts @@ -278,6 +278,102 @@ test('Bundling with custom environment vars`', () => { })); }); +test('Bundling with volumes from other container', () => { + const entry = path.join(__dirname, 'lambda-handler'); + Bundling.bundle({ + entry: entry, + runtime: Runtime.PYTHON_3_7, + volumesFrom: ['777f7dc92da7'], + + }); + + expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({ + bundling: expect.objectContaining({ + volumesFrom: ['777f7dc92da7'], + }), + })); +}); + +test('Bundling with custom volume paths', () => { + const entry = path.join(__dirname, 'lambda-handler'); + Bundling.bundle({ + entry: entry, + runtime: Runtime.PYTHON_3_7, + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + + }); + + expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({ + bundling: expect.objectContaining({ + volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }], + }), + })); +}); + +test('Bundling with custom working directory', () => { + const entry = path.join(__dirname, 'lambda-handler'); + Bundling.bundle({ + entry: entry, + runtime: Runtime.PYTHON_3_7, + workingDirectory: '/my-dir', + + }); + + expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({ + bundling: expect.objectContaining({ + workingDirectory: '/my-dir', + }), + })); +}); + +test('Bundling with custom user', () => { + const entry = path.join(__dirname, 'lambda-handler'); + Bundling.bundle({ + entry: entry, + runtime: Runtime.PYTHON_3_7, + user: 'user:group', + + }); + + expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({ + bundling: expect.objectContaining({ + user: 'user:group', + }), + })); +}); + +test('Bundling with custom securityOpt', () => { + const entry = path.join(__dirname, 'lambda-handler'); + Bundling.bundle({ + entry: entry, + runtime: Runtime.PYTHON_3_7, + securityOpt: 'no-new-privileges', + + }); + + expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({ + bundling: expect.objectContaining({ + securityOpt: 'no-new-privileges', + }), + })); +}); + +test('Bundling with custom network', () => { + const entry = path.join(__dirname, 'lambda-handler'); + Bundling.bundle({ + entry: entry, + runtime: Runtime.PYTHON_3_7, + network: 'host', + + }); + + expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({ + bundling: expect.objectContaining({ + network: 'host', + }), + })); +}); + test('Do not build docker image when skipping bundling', () => { const entry = path.join(__dirname, 'lambda-handler'); Bundling.bundle({