-
Notifications
You must be signed in to change notification settings - Fork 822
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: undo refactor changes in merge from dev
- Loading branch information
rjabhi
committed
Feb 7, 2025
1 parent
13d3842
commit 9907c5c
Showing
4 changed files
with
120 additions
and
56 deletions.
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
packages/amplify-migration-template-gen/src/cfn-stack-refactor-updater.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { | ||
CloudFormationClient, | ||
CreateStackRefactorCommand, | ||
CreateStackRefactorCommandInput, | ||
DescribeStackRefactorCommand, | ||
DescribeStackRefactorCommandOutput, | ||
ExecuteStackRefactorCommand, | ||
StackRefactorExecutionStatus, | ||
StackRefactorStatus, | ||
} from '@aws-sdk/client-cloudformation'; | ||
import assert from 'node:assert'; | ||
import { FailedRefactorResponse } from './types'; | ||
|
||
const POLL_ATTEMPTS = 30; | ||
const POLL_INTERVAL_MS = 1500; | ||
const COMPLETION_STATE = '_COMPLETE'; | ||
const FAILED_STATE = '_FAILED'; | ||
export const UPDATE_COMPLETE = 'UPDATE_COMPLETE'; | ||
/** | ||
* Refactors a stack with given source and destination template. | ||
* @param cfnClient | ||
* @param createStackRefactorCommandInput | ||
* @param attempts number of attempts to poll CFN stack for update completion state. The interval between the polls is 1.5 seconds. | ||
* @returns a tuple containing the success/failed state and the reason if any. | ||
*/ | ||
export async function tryRefactorStack( | ||
cfnClient: CloudFormationClient, | ||
createStackRefactorCommandInput: CreateStackRefactorCommandInput, | ||
attempts = POLL_ATTEMPTS, | ||
): Promise<[boolean, FailedRefactorResponse | undefined]> { | ||
const { StackRefactorId } = await cfnClient.send(new CreateStackRefactorCommand(createStackRefactorCommandInput)); | ||
assert(StackRefactorId); | ||
let describeStackRefactorResponse = await pollStackRefactorForCompletionState( | ||
cfnClient, | ||
StackRefactorId, | ||
(_describeStackRefactorResponse: DescribeStackRefactorCommandOutput) => { | ||
assert(_describeStackRefactorResponse.Status); | ||
return ( | ||
_describeStackRefactorResponse.Status.endsWith(COMPLETION_STATE) || _describeStackRefactorResponse.Status.endsWith(FAILED_STATE) | ||
); | ||
}, | ||
attempts, | ||
); | ||
if (describeStackRefactorResponse.Status !== StackRefactorStatus.CREATE_COMPLETE) { | ||
return [false, { | ||
status: describeStackRefactorResponse.Status, | ||
reason: describeStackRefactorResponse.StatusReason, | ||
stackRefactorId: StackRefactorId, | ||
}]; | ||
} | ||
// assert(describeStackRefactorResponse.Status === StackRefactorStatus.CREATE_COMPLETE); | ||
await cfnClient.send( | ||
new ExecuteStackRefactorCommand({ | ||
StackRefactorId, | ||
}), | ||
); | ||
describeStackRefactorResponse = await pollStackRefactorForCompletionState( | ||
cfnClient, | ||
StackRefactorId, | ||
(describeStackRefactorResponse: DescribeStackRefactorCommandOutput) => { | ||
assert(describeStackRefactorResponse.ExecutionStatus); | ||
return ( | ||
describeStackRefactorResponse.ExecutionStatus.endsWith(COMPLETION_STATE) || | ||
describeStackRefactorResponse.ExecutionStatus.endsWith(FAILED_STATE) | ||
); | ||
}, | ||
attempts, | ||
); | ||
if (describeStackRefactorResponse.ExecutionStatus !== StackRefactorExecutionStatus.EXECUTE_COMPLETE) { | ||
return [false, { | ||
status: describeStackRefactorResponse.ExecutionStatus, | ||
stackRefactorId: StackRefactorId, | ||
reason: describeStackRefactorResponse.ExecutionStatusReason, | ||
}]; | ||
} | ||
return [true, undefined]; | ||
|
||
// assert(describeStackRefactorResponse.ExecutionStatus === StackRefactorExecutionStatus.EXECUTE_COMPLETE); | ||
} | ||
|
||
/** | ||
* Polls a stack refactor operation for completion state | ||
* @param cfnClient | ||
* @param stackRefactorId | ||
* @param exitCondition a function that determines if the stack refactor operation has reached a completion state. | ||
* @param attempts number of attempts to poll for completion. | ||
* @returns the stack status | ||
*/ | ||
async function pollStackRefactorForCompletionState( | ||
cfnClient: CloudFormationClient, | ||
stackRefactorId: string, | ||
exitCondition: (describeStackRefactorResponse: DescribeStackRefactorCommandOutput) => boolean, | ||
attempts: number, | ||
): Promise<DescribeStackRefactorCommandOutput> { | ||
do { | ||
const describeStackRefactorResponse = await cfnClient.send( | ||
new DescribeStackRefactorCommand({ | ||
StackRefactorId: stackRefactorId, | ||
}), | ||
); | ||
if (exitCondition(describeStackRefactorResponse)) { | ||
return describeStackRefactorResponse; | ||
} | ||
await new Promise((res) => setTimeout(() => res(''), POLL_INTERVAL_MS)); | ||
attempts--; | ||
} while (attempts > 0); | ||
throw new Error(`Stack refactor ${stackRefactorId} did not reach a completion state within the given time period.`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters