Skip to content

Commit

Permalink
Ext overrides3 storage headless migrate (#8696)
Browse files Browse the repository at this point in the history
* (fix) s3 cli-ux loop until permission selected

* (fix) storage unit-tests for prompter function change

* (fix) auto-migrate on headless s3 storage api

* (fix) enable migration in headless only if required

* (fix) unit-test failing because of path incorrect

Co-authored-by: Sachin Panemangalore <sachinrp@amazon.com>
  • Loading branch information
sachscode and Sachin Panemangalore committed Nov 11, 2021
1 parent c380332 commit c272973
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import { $TSAny, $TSContext, AmplifySupportedService, stateManager } from 'amplify-cli-core';
import { prompter } from 'amplify-prompts';
import * as uuid from 'uuid';
import { MigrationParams, S3InputState } from '../../../../provider-utils/awscloudformation/service-walkthroughs/s3-user-input-state';
import { AmplifyS3ResourceStackTransform } from '../../../../provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform';
import { addWalkthrough, updateWalkthrough } from '../../../../provider-utils/awscloudformation/service-walkthroughs/s3-walkthrough';
import {
S3AccessType,
S3PermissionType,
S3TriggerFunctionType,
S3UserInputs,
S3UserInputs
} from '../../../../provider-utils/awscloudformation/service-walkthrough-types/s3-user-input-types';
import * as s3AuthAPI from '../../../../provider-utils/awscloudformation/service-walkthroughs/s3-auth-api';
import { S3CLITriggerUpdateMenuOptions, UserPermissionTypeOptions } from '../../../../provider-utils/awscloudformation/service-walkthroughs/s3-questions';
import { MigrationParams, S3InputState } from '../../../../provider-utils/awscloudformation/service-walkthroughs/s3-user-input-state';
import { addWalkthrough, updateWalkthrough } from '../../../../provider-utils/awscloudformation/service-walkthroughs/s3-walkthrough';

jest.mock('amplify-cli-core');
jest.mock('amplify-prompts');
jest.mock('../../../../provider-utils/awscloudformation/service-walkthroughs/s3-user-input-state');
jest.mock('../../../../provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform');
jest.mock('../../../../provider-utils/awscloudformation/service-walkthroughs/s3-auth-api');
jest.mock('uuid');
jest.mock('path');
jest.mock('fs-extra');

describe('add s3 walkthrough tests', () => {
let mockContext: $TSContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,13 @@ export async function askCRUDQuestion(
const message = `What kind of access do you want for ${userRole} users?`;
const choices = possibleCRUDOperations;
const initialIndexes = getIndexArrayByValue(possibleCRUDOperations, roleDefaultValues);
const selectedPermissions = await prompter.pick<'many', string>(message, choices, { returnSize: 'many', initial: initialIndexes });
let selectedPermissions;
do {
selectedPermissions = await prompter.pick<'many', string>(message, choices, { returnSize: 'many', initial: initialIndexes });
if( !selectedPermissions || selectedPermissions.length <= 0 ){
printer.warn('Select at least one option');
}
} while( !selectedPermissions || selectedPermissions.length <= 0 );
return selectedPermissions as Array<S3PermissionType>;
}

Expand Down Expand Up @@ -203,7 +209,7 @@ export async function askUpdateTriggerSelection(
return triggerOperationAnswer as S3CLITriggerUpdateMenuOptions;
}

export async function askAuthPermissionQuestion(context: $TSContext, defaultValues: S3UserInputs) {
export async function askAuthPermissionQuestion(context: $TSContext, defaultValues: S3UserInputs): Promise<S3PermissionType[]> {
const permissions: S3PermissionType[] = await askCRUDQuestion(S3UserAccessRole.AUTH, undefined, context, defaultValues);
return permissions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { $TSContext, AmplifyCategories, AmplifySupportedService, CLISubCommandTy
import { AmplifyS3ResourceStackTransform } from '../cdk-stack-builder/s3-stack-transform';
import { S3UserInputTriggerFunctionParams, S3UserInputs } from '../service-walkthrough-types/s3-user-input-types';
import { S3InputState } from './s3-user-input-state';
import { createNewLambdaAndUpdateCFN } from './s3-walkthrough';
import { createNewLambdaAndUpdateCFN, migrateStorageCategory, isMigrateStorageRequired } from './s3-walkthrough';

/**
* @returns Name of S3 resource or undefined
Expand All @@ -28,7 +28,11 @@ export function s3GetResourceName(): string | undefined {
* @returns
*/
export async function s3GetUserInput(context: $TSContext, s3ResourceName: string): Promise<S3UserInputs> {
const cliInputsState = new S3InputState(s3ResourceName as string, undefined);
//migrate storage and fetch cliInputsState
if ( isMigrateStorageRequired(context, s3ResourceName) ){
await migrateStorageCategory(context, s3ResourceName);
}
let cliInputsState = new S3InputState(s3ResourceName as string, undefined);
return cliInputsState.getUserInput();
}

Expand All @@ -37,7 +41,7 @@ export async function s3GetUserInput(context: $TSContext, s3ResourceName: string
* @param context
* @returns triggerFunction name or undefined
*/
export async function s3GetAdminTriggerFunctionName(context: $TSContext){
export async function s3GetAdminTriggerFunctionName(context: $TSContext) : Promise<string | undefined> {
const s3ResourceName : string|undefined = await s3GetResourceName();
const s3UserInput :S3UserInputs | undefined = (s3ResourceName)?await s3GetUserInput(context , s3ResourceName ):undefined;
return s3UserInput?.adminTriggerFunction?.triggerFunction;
Expand Down Expand Up @@ -194,8 +198,14 @@ export async function addLambdaTrigger(

/** HELPERS */
async function s3APIHelperTransformAndSaveState(context: $TSContext, storageInput: S3UserInputs, phase: CLISubCommandType) {
//migrate storage and fetch cliInputsState
if ( phase != CLISubCommandType.ADD && isMigrateStorageRequired(context, storageInput.resourceName as string) ){
await migrateStorageCategory(context, storageInput.resourceName as string);
}

//Save CLI Inputs payload
let cliInputsState;

if ( phase === CLISubCommandType.ADD ){
cliInputsState = new S3InputState(storageInput.resourceName as string, storageInput);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,27 @@ export class S3InputState {
fs.removeSync(migrationParams.storageParamsFilepath);
}
}
public checkNeedsMigration():boolean{
const backendDir = pathManager.getBackendDirPath();
const oldParametersFilepath = path.join(backendDir, AmplifyCategories.STORAGE, this._resourceName, 'parameters.json');
const oldCFNFilepath = path.join(
backendDir,
AmplifyCategories.STORAGE,
this._resourceName,
`${AmplifySupportedService.S3}-cloudformation-template.json`,
);
if ( fs.existsSync(oldParametersFilepath) && fs.existsSync(oldCFNFilepath) ){
return true;
}else {
return false;
}
}

public async migrate(context: $TSContext) {
//check if migration is possible
if (!this.checkNeedsMigration() ){
return;
}
try {
await migrateAuthDependencyResource(context);
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
CLISubCommandType,
AmplifySupportedService,
$TSMeta,
pathManager,
} from 'amplify-cli-core';
import { S3InputState } from './s3-user-input-state';
import { S3UserInputs, S3TriggerFunctionType } from '../service-walkthrough-types/s3-user-input-types';
Expand Down Expand Up @@ -179,6 +180,22 @@ export async function updateWalkthrough(context: $TSContext) {
}
}

/**
* Check if Storage feature needs migration
* @param context
* @param resourceName - storage resource name
* @returns
*/
export function isMigrateStorageRequired(context : $TSContext, resourceName: string){
const projectBackendDirPath = pathManager.getBackendDirPath();
const cliInputsFilePath = path.resolve(path.join(projectBackendDirPath, AmplifyCategories.STORAGE, resourceName, 'cli-inputs.json'));
if ( !fs.existsSync(cliInputsFilePath) ){
return true;
}else {
return false;
}
}

/**
* Migrate workflow for S3 resource
* - converts old context files into cliInputs and transforms into cloudformation.
Expand Down

0 comments on commit c272973

Please sign in to comment.