-
Notifications
You must be signed in to change notification settings - Fork 4.3k
refactor(cli): resource-import uses IoHost #33412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. some minor refactoring to make the code more human readable |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,71 @@ | ||
| import { DeployOptions } from '@aws-cdk/cloud-assembly-schema'; | ||
| import { format } from 'util'; | ||
| import * as cfnDiff from '@aws-cdk/cloudformation-diff'; | ||
| import { ResourceDifference } from '@aws-cdk/cloudformation-diff'; | ||
| import * as cxapi from '@aws-cdk/cx-api'; | ||
| import * as chalk from 'chalk'; | ||
| import * as fs from 'fs-extra'; | ||
| import * as promptly from 'promptly'; | ||
| import { assertIsSuccessfulDeployStackResult, Deployments, DeploymentMethod, ResourceIdentifierProperties, ResourcesToImport } from './api/deployments'; | ||
| import { Tag } from './api/tags'; | ||
| import { StackActivityProgress } from './api/util/cloudformation/stack-activity-monitor'; | ||
| import { error, info, success, warning } from './logging'; | ||
| import { ToolkitError } from './toolkit/error'; | ||
|
|
||
| export interface ImportDeploymentOptions extends DeployOptions { | ||
| deploymentMethod?: DeploymentMethod; | ||
| progress?: StackActivityProgress; | ||
| tags?: Tag[]; | ||
| import { error, info, warn } from '../../cli/messages'; | ||
| import { IIoHost, ToolkitAction } from '../../toolkit/cli-io-host'; | ||
| import { ToolkitError } from '../../toolkit/error'; | ||
| import { assertIsSuccessfulDeployStackResult, Deployments, DeploymentMethod, ResourceIdentifierProperties, ResourcesToImport } from '../deployments'; | ||
| import { Tag } from '../tags'; | ||
| import { StackActivityProgress } from '../util/cloudformation/stack-activity-monitor'; | ||
|
|
||
| export interface ResourceImporterProps { | ||
| deployments: Deployments; | ||
| ioHost: IIoHost; | ||
| action: ToolkitAction; | ||
| } | ||
|
|
||
| export interface ImportDeploymentOptions { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Made this an explicit copy to limit the interface to a small subset of expected options. |
||
| /** | ||
| * Name of the toolkit stack to use/deploy | ||
| * | ||
| * @default CDKToolkit | ||
| */ | ||
| readonly toolkitStackName: string; | ||
|
||
|
|
||
| /** | ||
| * Role to pass to CloudFormation for deployment | ||
| * | ||
| * @default - Default stack role | ||
| */ | ||
| readonly roleArn?: string; | ||
|
|
||
| /** | ||
| * Deployment method | ||
| */ | ||
| readonly deploymentMethod?: DeploymentMethod; | ||
mrgrain marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
| * Stack tags (pass through to CloudFormation) | ||
| */ | ||
| readonly tags?: Tag[]; | ||
|
|
||
| /** | ||
| * Use previous values for unspecified parameters | ||
| * | ||
| * If not set, all parameters must be specified for every deployment. | ||
| * | ||
| * @default true | ||
| */ | ||
| readonly usePreviousParameters?: boolean; | ||
|
|
||
| /** | ||
| * Display mode for stack deployment progress. | ||
| * | ||
| * @default - StackActivityProgress.Bar - stack events will be displayed for | ||
| * the resource currently being deployed. | ||
| */ | ||
| readonly progress?: StackActivityProgress; | ||
|
|
||
| /** | ||
| * Rollback failed deployments | ||
| * | ||
| * @default true | ||
| */ | ||
| readonly rollback?: boolean; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -61,9 +112,20 @@ | |
| export class ResourceImporter { | ||
| private _currentTemplate: any; | ||
|
|
||
| private readonly stack: cxapi.CloudFormationStackArtifact; | ||
| private readonly cfn: Deployments; | ||
| private readonly ioHost: IIoHost; | ||
| private readonly action: ToolkitAction; | ||
|
|
||
| constructor( | ||
| private readonly stack: cxapi.CloudFormationStackArtifact, | ||
| private readonly cfn: Deployments) { } | ||
| stack: cxapi.CloudFormationStackArtifact, | ||
| props: ResourceImporterProps, | ||
| ) { | ||
| this.stack = stack; | ||
| this.cfn = props.deployments; | ||
| this.ioHost = props.ioHost; | ||
| this.action = props.action; | ||
| } | ||
|
|
||
| /** | ||
| * Ask the user for resources to import | ||
|
|
@@ -96,19 +158,19 @@ | |
| const descr = this.describeResource(resource.logicalId); | ||
| const idProps = contents[resource.logicalId]; | ||
| if (idProps) { | ||
| info('%s: importing using %s', chalk.blue(descr), chalk.blue(fmtdict(idProps))); | ||
| await this.ioHost.notify(info(this.action, format('%s: importing using %s', chalk.blue(descr), chalk.blue(fmtdict(idProps))))); | ||
|
|
||
| ret.importResources.push(resource); | ||
| ret.resourceMap[resource.logicalId] = idProps; | ||
| delete contents[resource.logicalId]; | ||
| } else { | ||
| info('%s: skipping', chalk.blue(descr)); | ||
| await this.ioHost.notify(info(this.action, format('%s: skipping', chalk.blue(descr)))); | ||
| } | ||
| } | ||
|
|
||
| const unknown = Object.keys(contents); | ||
| if (unknown.length > 0) { | ||
| warning(`Unrecognized resource identifiers in mapping file: ${unknown.join(', ')}`); | ||
| await this.ioHost.notify(warn(this.action, `Unrecognized resource identifiers in mapping file: ${unknown.join(', ')}`)); | ||
| } | ||
|
|
||
| return ret; | ||
|
|
@@ -158,9 +220,9 @@ | |
| ? ' ✅ %s (no changes)' | ||
| : ' ✅ %s'; | ||
|
|
||
| success('\n' + message, this.stack.displayName); | ||
| await this.ioHost.notify(info(this.action, '\n' + chalk.green(format(message, this.stack.displayName)))); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why did we do away with the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Getting rid of all helpers with implicit formatting. |
||
| } catch (e) { | ||
| error('\n ❌ %s failed: %s', chalk.bold(this.stack.displayName), e); | ||
| await this.ioHost.notify(error(this.action, format('\n ❌ %s failed: %s', chalk.bold(this.stack.displayName), e), 'CDK_TOOLKIT_E3900')); | ||
| throw e; | ||
| } | ||
| } | ||
|
|
@@ -189,7 +251,7 @@ | |
| const offendingResources = nonAdditions.map(([logId, _]) => this.describeResource(logId)); | ||
|
|
||
| if (allowNonAdditions) { | ||
| warning(`Ignoring updated/deleted resources (--force): ${offendingResources.join(', ')}`); | ||
| await this.ioHost.notify(warn(this.action, `Ignoring updated/deleted resources (--force): ${offendingResources.join(', ')}`)); | ||
| } else { | ||
| throw new ToolkitError('No resource updates or deletes are allowed on import operation. Make sure to resolve pending changes ' + | ||
| `to existing resources, before attempting an import. Updated/deleted resources: ${offendingResources.join(', ')} (--force to override)`); | ||
|
|
@@ -277,7 +339,7 @@ | |
| // Skip resources that do not support importing | ||
| const resourceType = chg.resourceDiff.newResourceType; | ||
| if (resourceType === undefined || !(resourceType in resourceIdentifiers)) { | ||
| warning(`${resourceName}: unsupported resource type ${resourceType}, skipping import.`); | ||
| await this.ioHost.notify(warn(this.action, `${resourceName}: unsupported resource type ${resourceType}, skipping import.`)); | ||
| return undefined; | ||
| } | ||
|
|
||
|
|
@@ -303,7 +365,7 @@ | |
|
|
||
| // If we got here and the user rejected any available identifiers, then apparently they don't want the resource at all | ||
| if (satisfiedPropSets.length > 0) { | ||
| info(chalk.grey(`Skipping import of ${resourceName}`)); | ||
| await this.ioHost.notify(info(this.action, chalk.grey(`Skipping import of ${resourceName}`))); | ||
| return undefined; | ||
| } | ||
|
|
||
|
|
@@ -321,7 +383,7 @@ | |
|
|
||
| // Do the input loop here | ||
| if (preamble) { | ||
| info(preamble); | ||
| await this.ioHost.notify(info(this.action, preamble)); | ||
| } | ||
| for (const idProps of idPropSets) { | ||
| const input: Record<string, string> = {}; | ||
|
|
@@ -356,7 +418,7 @@ | |
| } | ||
| } | ||
|
|
||
| info(chalk.grey(`Skipping import of ${resourceName}`)); | ||
| await this.ioHost.notify(info(this.action, chalk.grey(`Skipping import of ${resourceName}`))); | ||
| return undefined; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| export * from './importer'; | ||
| export * from './migrator'; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sort of a meta question -- is there a way to block us from importing directly from the file itself when we have an i want to disawllow
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could write an eslint rule for it, might need a plugin. There can be good reasons to import directly though. My current concern is that anything outside of |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed in favor of the same option on the Toolkit.