From 7182296da5c22800107bd2b07670214f0ae3c696 Mon Sep 17 00:00:00 2001 From: Kaustav Ghosh Date: Fri, 5 Nov 2021 13:28:50 -0700 Subject: [PATCH] feat: overrides uniformity accross all the categories (#8695) * feat: overrides uniformity accross all the categories * chore: remove unneeded dependency * fix: apply override unformity to root-stack Co-authored-by: Ghosh --- .../resources/overrides-resource/override.ts | 4 +- .../resources/overrides-resource/package.json | 2 - .../auth-stack-transform.ts | 6 +-- .../user-pool-group-stack-transform.ts | 3 +- .../amplify-category-storage/package.json | 3 +- .../overrides-resource/DynamoDB/override.ts | 4 +- .../overrides-resource/DynamoDB/package.json | 4 +- .../overrides-resource/S3/override.ts | 4 +- .../overrides-resource/S3/package.json | 4 +- .../cdk-stack-builder/ddb-stack-transform.ts | 43 ++++++++++++------- .../cdk-stack-builder/s3-stack-transform.ts | 40 ++++++++++++----- .../override-skeleton-generator.ts | 2 +- packages/amplify-cli/amplify-plugin.json | 2 +- .../{build-override.test.ts => build.test.ts} | 10 ++--- .../commands/{build-override.ts => build.ts} | 2 +- packages/amplify-cli/src/commands/export.ts | 2 +- .../src/categories/storage.ts | 2 +- .../resources/overrides-resource/override.ts | 4 +- .../resources/overrides-resource/package.json | 4 +- .../root-stack-transform.ts | 3 +- 20 files changed, 81 insertions(+), 67 deletions(-) rename packages/amplify-cli/src/__tests__/commands/{build-override.test.ts => build.test.ts} (92%) rename packages/amplify-cli/src/commands/{build-override.ts => build.ts} (98%) diff --git a/packages/amplify-category-auth/resources/overrides-resource/override.ts b/packages/amplify-category-auth/resources/overrides-resource/override.ts index e5ba67d19cc..76000340d77 100644 --- a/packages/amplify-category-auth/resources/overrides-resource/override.ts +++ b/packages/amplify-category-auth/resources/overrides-resource/override.ts @@ -1,5 +1,3 @@ import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-overrides-helper'; -export function overrideProps(props: AmplifyAuthCognitoStackTemplate) { - return props; -} +export function override(resources: AmplifyAuthCognitoStackTemplate) {} diff --git a/packages/amplify-category-auth/resources/overrides-resource/package.json b/packages/amplify-category-auth/resources/overrides-resource/package.json index ac0fb81b3ce..35910a5f41c 100644 --- a/packages/amplify-category-auth/resources/overrides-resource/package.json +++ b/packages/amplify-category-auth/resources/overrides-resource/package.json @@ -8,8 +8,6 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "@types/fs-extra": "^9.0.11", - "fs-extra": "^9.1.0", "@aws-amplify/cli-overrides-helper": "1.1.0-ext11.0" }, "devDependencies": { diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/auth-stack-transform.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/auth-stack-transform.ts index 302b79c6598..81eb15bf299 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/auth-stack-transform.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/auth-stack-transform.ts @@ -110,7 +110,7 @@ export class AmplifyAuthTransform extends AmplifyCategoryTransform { formatter.list(['No override File Found', `To override ${this.resourceName} run amplify override auth`]); return ''; }); - const cognitoStackTemplateObj = this._authTemplateObj as AmplifyAuthCognitoStack & AmplifyStackTemplate; + const sandboxNode = new vm.NodeVM({ console: 'inherit', timeout: 5000, @@ -122,9 +122,9 @@ export class AmplifyAuthTransform extends AmplifyCategoryTransform { }, }); try { - this._authTemplateObj = await sandboxNode + await sandboxNode .run(overrideCode, path.join(overrideDir, 'build', 'override.js')) - .overrideProps(cognitoStackTemplateObj); + .override(this._authTemplateObj as AmplifyAuthCognitoStack & AmplifyStackTemplate); } catch (err: $TSAny) { const error = new Error(`Skipping override due to ${err}${os.EOL}`); printer.error(`${error}`); diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/user-pool-group-stack-transform.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/user-pool-group-stack-transform.ts index af65d86debb..70da715cfa6 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/user-pool-group-stack-transform.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/user-pool-group-stack-transform.ts @@ -183,14 +183,13 @@ export class AmplifyUserPoolGroupTransform extends AmplifyCategoryTransform { formatter.list(['No override File Found', `To override ${this._resourceName} run amplify override auth`]); return ''; }); - const cognitoStackTemplateObj = this._userPoolGroupTemplateObj as AmplifyUserPoolGroupStack & AmplifyStackTemplate; const sandboxNode = new vm.NodeVM({ console: 'inherit', timeout: 5000, sandbox: {}, }); try { - this._userPoolGroupTemplateObj = sandboxNode.run(overrideCode).overrideProps(cognitoStackTemplateObj); + sandboxNode.run(overrideCode).override(this._userPoolGroupTemplateObj as AmplifyUserPoolGroupStack & AmplifyStackTemplate); } catch (err: $TSAny) { const error = new Error(`Skipping override due to ${err}${os.EOL}`); printer.error(`${error}`); diff --git a/packages/amplify-category-storage/package.json b/packages/amplify-category-storage/package.json index 4b64004d9c8..779c11e7578 100644 --- a/packages/amplify-category-storage/package.json +++ b/packages/amplify-category-storage/package.json @@ -40,7 +40,8 @@ "inquirer": "^7.3.3", "lodash": "^4.17.21", "promise-sequential": "^1.1.1", - "uuid": "^8.3.2" + "uuid": "^8.3.2", + "vm2": "^3.9.3" }, "devDependencies": { "aws-sdk": "^2.963.0", diff --git a/packages/amplify-category-storage/resources/overrides-resource/DynamoDB/override.ts b/packages/amplify-category-storage/resources/overrides-resource/DynamoDB/override.ts index e893913538a..b2de7ccdba9 100644 --- a/packages/amplify-category-storage/resources/overrides-resource/DynamoDB/override.ts +++ b/packages/amplify-category-storage/resources/overrides-resource/DynamoDB/override.ts @@ -1,5 +1,3 @@ import { AmplifyDDBResourceTemplate } from '@aws-amplify/cli-overrides-helper'; -export function overrideProps(props: AmplifyDDBResourceTemplate) { - return props; -} +export function override(resources: AmplifyDDBResourceTemplate) {} diff --git a/packages/amplify-category-storage/resources/overrides-resource/DynamoDB/package.json b/packages/amplify-category-storage/resources/overrides-resource/DynamoDB/package.json index f376bdfbd12..7b484b7b809 100644 --- a/packages/amplify-category-storage/resources/overrides-resource/DynamoDB/package.json +++ b/packages/amplify-category-storage/resources/overrides-resource/DynamoDB/package.json @@ -1,5 +1,5 @@ { - "name": "overrides-for-root-stack", + "name": "overrides-dependencies", "version": "1.0.0", "description": "", "scripts": { @@ -8,8 +8,6 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "@types/fs-extra": "^9.0.11", - "fs-extra": "^9.1.0", "@aws-amplify/cli-overrides-helper": "1.1.0-ext11.0" }, diff --git a/packages/amplify-category-storage/resources/overrides-resource/S3/override.ts b/packages/amplify-category-storage/resources/overrides-resource/S3/override.ts index f6de84d4c8d..c018e0819d3 100644 --- a/packages/amplify-category-storage/resources/overrides-resource/S3/override.ts +++ b/packages/amplify-category-storage/resources/overrides-resource/S3/override.ts @@ -1,5 +1,3 @@ import { AmplifyS3ResourceTemplate } from '@aws-amplify/cli-overrides-helper'; -export function overrideProps(props: AmplifyS3ResourceTemplate) { - return props; -} +export function override(resources: AmplifyS3ResourceTemplate) {} diff --git a/packages/amplify-category-storage/resources/overrides-resource/S3/package.json b/packages/amplify-category-storage/resources/overrides-resource/S3/package.json index 56273555a15..deef309eb16 100644 --- a/packages/amplify-category-storage/resources/overrides-resource/S3/package.json +++ b/packages/amplify-category-storage/resources/overrides-resource/S3/package.json @@ -1,5 +1,5 @@ { - "name": "overrides-for-root-stack", + "name": "overrides-dependencies", "version": "1.0.0", "description": "", "scripts": { @@ -8,8 +8,6 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "@types/fs-extra": "^9.0.11", - "fs-extra": "^9.1.0", "@aws-amplify/cli-overrides-helper": "1.1.0-ext11.0" }, "devDependencies": { diff --git a/packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/ddb-stack-transform.ts b/packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/ddb-stack-transform.ts index a09f654f09d..22ac57b02a0 100644 --- a/packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/ddb-stack-transform.ts +++ b/packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/ddb-stack-transform.ts @@ -8,6 +8,8 @@ import * as fs from 'fs-extra'; import { JSONUtilities, pathManager, buildOverrideDir, $TSAny } from 'amplify-cli-core'; import * as path from 'path'; import { formatter, printer } from 'amplify-prompts'; +import * as vm from 'vm2'; +import os from 'os'; export class DDBStackTransform { app: App; @@ -168,32 +170,43 @@ export class DDBStackTransform { async applyOverrides() { const backendDir = pathManager.getBackendDirPath(); - const overrideFilePath = pathManager.getResourceDirectoryPath(undefined, 'storage', this._resourceName); + const resourceDirPath = pathManager.getResourceDirectoryPath(undefined, 'storage', this._resourceName); + const overrideJSFilePath = path.resolve(path.join(resourceDirPath, 'build', 'override.js')); - const isBuild = await buildOverrideDir(backendDir, overrideFilePath).catch(error => { + const isBuild = await buildOverrideDir(backendDir, resourceDirPath).catch(error => { printer.debug(`Skipping build as ${error.message}`); return false; }); // skip if packageManager or override.ts not found if (isBuild) { - const { overrideProps } = await import(path.join(overrideFilePath, 'build', 'override.js')).catch(error => { + const { override } = await import(overrideJSFilePath).catch(error => { formatter.list(['No override File Found', `To override ${this._resourceName} run amplify override auth ${this._resourceName} `]); return undefined; }); - // pass stack object - const ddbStackTemplateObj = this._resourceTemplateObj as AmplifyDDBResourceTemplate; - //TODO: Check Script Options - if (typeof overrideProps === 'function' && overrideProps) { + if (typeof override === 'function' && override) { + const overrideCode: string = await fs.readFile(overrideJSFilePath, 'utf-8').catch(() => { + formatter.list(['No override File Found', `To override ${this._resourceName} run amplify override auth`]); + return ''; + }); + + const sandboxNode = new vm.NodeVM({ + console: 'inherit', + timeout: 5000, + sandbox: {}, + require: { + context: 'sandbox', + builtin: ['path'], + external: true, + }, + }); try { - this._resourceTemplateObj = overrideProps(this._resourceTemplateObj as AmplifyDDBResourceTemplate); - - //The vm module enables compiling and running code within V8 Virtual Machine contexts. The vm module is not a security mechanism. Do not use it to run untrusted code. - // const script = new vm.Script(overrideCode); - // script.runInContext(vm.createContext(cognitoStackTemplateObj)); - return; - } catch (error: $TSAny) { - throw new Error(error); + await sandboxNode.run(overrideCode, overrideJSFilePath).override(this._resourceTemplateObj as AmplifyDDBResourceTemplate); + } catch (err: $TSAny) { + const error = new Error(`Skipping override due to ${err}${os.EOL}`); + printer.error(`${error}`); + error.stack = undefined; + throw error; } } } diff --git a/packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform.ts b/packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform.ts index 25cdaa89946..785c4d2bf09 100644 --- a/packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform.ts +++ b/packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform.ts @@ -13,6 +13,8 @@ import { import { formatter, printer } from 'amplify-prompts'; import * as fs from 'fs-extra'; import * as path from 'path'; +import * as vm from 'vm2'; +import os from 'os'; import { S3PermissionType, S3UserInputs } from '../service-walkthrough-types/s3-user-input-types'; import { canResourceBeTransformed, S3CFNDependsOn, S3CFNPermissionType, S3InputState } from '../service-walkthroughs/s3-user-input-state'; import { AmplifyS3ResourceCfnStack } from './s3-stack-builder'; @@ -167,27 +169,43 @@ export class AmplifyS3ResourceStackTransform { // Modify cloudformation files based on overrides async applyOverrides() { const backendDir = pathManager.getBackendDirPath(); - const overrideFilePath = pathManager.getResourceDirectoryPath(undefined, AmplifyCategories.STORAGE, this.resourceName); - const isBuild = await buildOverrideDir(backendDir, overrideFilePath).catch(error => { + const resourceDirPath = pathManager.getResourceDirectoryPath(undefined, AmplifyCategories.STORAGE, this.resourceName); + const overrideJSFilePath = path.resolve(path.join(resourceDirPath, 'build', 'override.js')); + + const isBuild = await buildOverrideDir(backendDir, resourceDirPath).catch(error => { printer.debug(`Skipping build as ${error.message}`); return false; }); //Skip if packageManager or override.ts not found if (isBuild) { - const { overrideProps } = await import(path.join(overrideFilePath, 'build', 'override.js')).catch(error => { + const { override } = await import(overrideJSFilePath).catch(error => { formatter.list(['No override File Found', `To override ${this.resourceName} run amplify override auth ${this.resourceName} `]); return undefined; }); // Pass stack object - if (overrideProps && typeof overrideProps === 'function') { + if (override && typeof override === 'function') { + const overrideCode: string = await fs.readFile(overrideJSFilePath, 'utf-8').catch(() => { + formatter.list(['No override File Found', `To override ${this.resourceName} run amplify override auth`]); + return ''; + }); + + const sandboxNode = new vm.NodeVM({ + console: 'inherit', + timeout: 5000, + sandbox: {}, + require: { + context: 'sandbox', + builtin: ['path'], + external: true, + }, + }); try { - this.resourceTemplateObj = overrideProps(this.resourceTemplateObj as AmplifyS3ResourceTemplate); - //The vm module enables compiling and running code within V8 Virtual Machine contexts. The vm module is not a security mechanism. Do not use it to run untrusted code. - // const script = new vm.Script(overrideCode); - // script.runInContext(vm.createContext(cognitoStackTemplateObj)); - return; - } catch (error: $TSAny) { - throw new Error(error); + await sandboxNode.run(overrideCode, overrideJSFilePath).override(this.resourceTemplateObj as AmplifyS3ResourceTemplate); + } catch (err: $TSAny) { + const error = new Error(`Skipping override due to ${err}${os.EOL}`); + printer.error(`${error}`); + error.stack = undefined; + throw error; } } } diff --git a/packages/amplify-cli-core/src/overrides-manager/override-skeleton-generator.ts b/packages/amplify-cli-core/src/overrides-manager/override-skeleton-generator.ts index 001ff1ca8db..453147e2c2d 100644 --- a/packages/amplify-cli-core/src/overrides-manager/override-skeleton-generator.ts +++ b/packages/amplify-cli-core/src/overrides-manager/override-skeleton-generator.ts @@ -25,7 +25,7 @@ export const generateOverrideSkeleton = async (context: $TSContext, srcResourceD await buildOverrideDir(backendDir, destDirPath); printer.success(`Successfully generated "override.ts" folder at ${destDirPath}`); - const isOpen = await prompter.confirmContinue('Do you want to edit override.ts file now?'); + const isOpen = await prompter.yesOrNo('Do you want to edit override.ts file now?', true); if (isOpen) { await context.amplify.openEditor(context, overrideFile); } diff --git a/packages/amplify-cli/amplify-plugin.json b/packages/amplify-cli/amplify-plugin.json index 1b62a73db38..73a66129337 100644 --- a/packages/amplify-cli/amplify-plugin.json +++ b/packages/amplify-cli/amplify-plugin.json @@ -21,7 +21,7 @@ "uninstall", "upgrade", "version", - "build-override" + "build" ], "commandAliases": { "h": "help", diff --git a/packages/amplify-cli/src/__tests__/commands/build-override.test.ts b/packages/amplify-cli/src/__tests__/commands/build.test.ts similarity index 92% rename from packages/amplify-cli/src/__tests__/commands/build-override.test.ts rename to packages/amplify-cli/src/__tests__/commands/build.test.ts index 666ad6d2824..ece7fe34e65 100644 --- a/packages/amplify-cli/src/__tests__/commands/build-override.test.ts +++ b/packages/amplify-cli/src/__tests__/commands/build.test.ts @@ -1,11 +1,11 @@ -import { run } from '../../commands/build-override'; +import { run } from '../../commands/build'; import { $TSContext } from 'amplify-cli-core'; jest.mock('amplify-cli-core'); jest.mock('amplify-provider-awscloudformation'); -describe('run build-override command', () => { - it('runs override command for only a resource', async () => { +describe('run build command', () => { + it('runs build command for only a resource', async () => { const context_stub = { amplify: { getResourceStatus: jest.fn().mockResolvedValue({ @@ -48,7 +48,7 @@ describe('run build-override command', () => { expect(context_stub_typed.amplify.invokePluginMethod).toBeCalledTimes(1); }); - it('runs override command for only all resources in a category', async () => { + it('runs build command for only all resources in a category', async () => { const context_stub = { amplify: { getResourceStatus: jest.fn().mockResolvedValue({ @@ -91,7 +91,7 @@ describe('run build-override command', () => { expect(context_stub_typed.amplify.invokePluginMethod).toBeCalledTimes(3); }); - it('runs override command successfully for all resources in all categories', async () => { + it('runs build command successfully for all resources in all categories', async () => { const context_stub = { amplify: { getResourceStatus: jest.fn().mockResolvedValue({ diff --git a/packages/amplify-cli/src/commands/build-override.ts b/packages/amplify-cli/src/commands/build.ts similarity index 98% rename from packages/amplify-cli/src/commands/build-override.ts rename to packages/amplify-cli/src/commands/build.ts index 96975b9a8b6..5b529676a6f 100644 --- a/packages/amplify-cli/src/commands/build-override.ts +++ b/packages/amplify-cli/src/commands/build.ts @@ -3,7 +3,7 @@ import { printer } from 'amplify-prompts'; /** * Command to transform CFN with overrides */ -const subcommand = 'build-override'; +const subcommand = 'build'; export const run = async (context: $TSContext) => { const categoryName = context?.input?.subCommands?.[0]; diff --git a/packages/amplify-cli/src/commands/export.ts b/packages/amplify-cli/src/commands/export.ts index 53dd595586f..eafaa508ad7 100644 --- a/packages/amplify-cli/src/commands/export.ts +++ b/packages/amplify-cli/src/commands/export.ts @@ -10,7 +10,7 @@ import { printer } from 'amplify-prompts'; import chalk from 'chalk'; import { getResourceOutputs } from '../extensions/amplify-helpers/get-resource-outputs'; import Ora from 'ora'; -import { getResources } from './build-override'; +import { getResources } from './build'; import * as _ from 'lodash'; export const run = async (context: $TSContext) => { diff --git a/packages/amplify-e2e-core/src/categories/storage.ts b/packages/amplify-e2e-core/src/categories/storage.ts index ac60309a62f..c37050512db 100644 --- a/packages/amplify-e2e-core/src/categories/storage.ts +++ b/packages/amplify-e2e-core/src/categories/storage.ts @@ -244,7 +244,7 @@ export function overrideDDB(cwd: string, settings: {}) { export function buildOverrideStorage(cwd: string, settings: {}) { return new Promise((resolve, reject) => { // Add 'storage' as a category param once implemented - const args = ['build-override']; + const args = ['build']; spawn(getCLIPath(), args, { cwd, stripColors: true }) .sendEof() diff --git a/packages/amplify-provider-awscloudformation/resources/overrides-resource/override.ts b/packages/amplify-provider-awscloudformation/resources/overrides-resource/override.ts index a7b26b93c3f..2832816feaf 100644 --- a/packages/amplify-provider-awscloudformation/resources/overrides-resource/override.ts +++ b/packages/amplify-provider-awscloudformation/resources/overrides-resource/override.ts @@ -1,5 +1,3 @@ import { AmplifyRootStackTemplate } from '@aws-amplify/cli-overrides-helper'; -export function overrideProps(props: AmplifyRootStackTemplate) { - return props; -} +export function override(resources: AmplifyRootStackTemplate) {} diff --git a/packages/amplify-provider-awscloudformation/resources/overrides-resource/package.json b/packages/amplify-provider-awscloudformation/resources/overrides-resource/package.json index 56273555a15..deef309eb16 100644 --- a/packages/amplify-provider-awscloudformation/resources/overrides-resource/package.json +++ b/packages/amplify-provider-awscloudformation/resources/overrides-resource/package.json @@ -1,5 +1,5 @@ { - "name": "overrides-for-root-stack", + "name": "overrides-dependencies", "version": "1.0.0", "description": "", "scripts": { @@ -8,8 +8,6 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "@types/fs-extra": "^9.0.11", - "fs-extra": "^9.1.0", "@aws-amplify/cli-overrides-helper": "1.1.0-ext11.0" }, "devDependencies": { diff --git a/packages/amplify-provider-awscloudformation/src/root-stack-builder/root-stack-transform.ts b/packages/amplify-provider-awscloudformation/src/root-stack-builder/root-stack-transform.ts index 2011de5963f..9453ac47cd5 100644 --- a/packages/amplify-provider-awscloudformation/src/root-stack-builder/root-stack-transform.ts +++ b/packages/amplify-provider-awscloudformation/src/root-stack-builder/root-stack-transform.ts @@ -60,14 +60,13 @@ export class AmplifyRootStackTransform { amplifyPrinter.formatter.list(['No override File Found', `To override ${this._resourceName} run amplify override auth`]); return ''; }); - const rootStackTemplateObj = this._rootTemplateObj as AmplifyRootStackTemplate; const sandboxNode = new vm.NodeVM({ console: 'inherit', timeout: 5000, sandbox: {}, }); try { - this._rootTemplateObj = sandboxNode.run(overrideCode).overrideProps(rootStackTemplateObj); + sandboxNode.run(overrideCode).overrideProps(this._rootTemplateObj); } catch (err: $TSAny) { const error = new Error(`Skipping override due to ${err}${os.EOL}`); printer.error(`${error}`);