Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .projenrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ const tmpToolkitHelpers = configureProject(
'fast-check',
],
deps: [
cloudAssemblySchema.name,
'archiver',
'glob',
'semver',
Expand Down
4 changes: 4 additions & 0 deletions packages/@aws-cdk/tmp-toolkit-helpers/.projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/@aws-cdk/tmp-toolkit-helpers/.projen/tasks.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/@aws-cdk/tmp-toolkit-helpers/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { MetadataEntry } from '@aws-cdk/cloud-assembly-schema';
import type { CloudFormationStackArtifact } from '@aws-cdk/cx-api';
import type { StackEvent } from '@aws-sdk/client-cloudformation';
import type { StackProgress } from './progress';
import type { ResourceMetadata } from '../../resource-metadata/resource-metadata';

/**
* Payload when stack monitoring is starting or stopping for a given stack deployment.
Expand Down Expand Up @@ -48,6 +48,9 @@ export interface StackActivity {

/**
* Additional resource metadata
*
* This information is only available if the information is available in the current cloud assembly.
* I.e. no `metadata` will not be available for resource deletion events.
*/
readonly metadata?: ResourceMetadata;

Expand All @@ -56,8 +59,3 @@ export interface StackActivity {
*/
readonly progress: StackProgress;
}

export interface ResourceMetadata {
entry: MetadataEntry;
constructPath: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type { FileWatchEvent, WatchSettings } from '../payloads/watch';
* - X900-X999 are reserved for results
*/
export const IO = {
// Defaults
// Defaults (0000)
DEFAULT_TOOLKIT_INFO: make.info({
code: 'CDK_TOOLKIT_I0000',
description: 'Default info messages emitted from the Toolkit',
Expand All @@ -35,7 +35,7 @@ export const IO = {
description: 'Default warning messages emitted from the Toolkit',
}),

// 1: Synth
// 1: Synth (1xxx)
CDK_TOOLKIT_I1000: make.info<Duration>({
code: 'CDK_TOOLKIT_I1000',
description: 'Provides synthesis times.',
Expand All @@ -57,7 +57,7 @@ export const IO = {
interface: 'AssemblyData',
}),

// 2: List
// 2: List (2xxx)
CDK_TOOLKIT_I2901: make.result<StackDetailsPayload>({
code: 'CDK_TOOLKIT_I2901',
description: 'Provides details on the selected stacks and their dependencies',
Expand All @@ -70,9 +70,9 @@ export const IO = {
description: 'Resource import failed',
}),

// 4: Diff
// 4: Diff (4xxx)

// 5: Deploy & Watch
// 5: Deploy & Watch (5xxx)
CDK_TOOLKIT_I5000: make.info<Duration>({
code: 'CDK_TOOLKIT_I5000',
description: 'Provides deployment times',
Expand Down Expand Up @@ -129,14 +129,13 @@ export const IO = {
description: 'Confirm deploy security sensitive changes',
interface: 'DeployConfirmationRequest',
}),

CDK_TOOLKIT_I5100: make.info<StackDeployProgress>({
code: 'CDK_TOOLKIT_I5100',
description: 'Stack deploy progress',
interface: 'StackDeployProgress',
}),

// Assets
// Assets (52xx)
CDK_TOOLKIT_I5210: make.trace<BuildAsset>({
code: 'CDK_TOOLKIT_I5210',
description: 'Started building a specific asset',
Expand All @@ -147,7 +146,6 @@ export const IO = {
description: 'Building the asset has completed',
interface: 'Duration',
}),

CDK_TOOLKIT_I5220: make.trace<PublishAsset>({
code: 'CDK_TOOLKIT_I5220',
description: 'Started publishing a specific asset',
Expand All @@ -159,7 +157,7 @@ export const IO = {
interface: 'Duration',
}),

// Watch
// Watch (53xx)
CDK_TOOLKIT_I5310: make.debug<WatchSettings>({
code: 'CDK_TOOLKIT_I5310',
description: 'The computed settings used for file watching',
Expand Down Expand Up @@ -189,7 +187,9 @@ export const IO = {
description: 'Queued watch deployment started',
}),

// Stack Monitor
// Hotswap (54xx)

// Stack Monitor (55xx)
CDK_TOOLKIT_I5501: make.info<StackMonitoringControlEvent>({
code: 'CDK_TOOLKIT_I5501',
description: 'Stack Monitoring: Start monitoring of a single stack',
Expand All @@ -206,7 +206,7 @@ export const IO = {
interface: 'StackMonitoringControlEvent',
}),

// Success
// Success (59xx)
CDK_TOOLKIT_I5900: make.result<SuccessfulDeployStackResult>({
code: 'CDK_TOOLKIT_I5900',
description: 'Deployment results on success',
Expand All @@ -232,7 +232,7 @@ export const IO = {
interface: 'ErrorPayload',
}),

// 6: Rollback
// 6: Rollback (6xxx)
CDK_TOOLKIT_I6000: make.info<Duration>({
code: 'CDK_TOOLKIT_I6000',
description: 'Provides rollback times',
Expand All @@ -254,7 +254,7 @@ export const IO = {
interface: 'ErrorPayload',
}),

// 7: Destroy
// 7: Destroy (7xxx)
CDK_TOOLKIT_I7000: make.info<Duration>({
code: 'CDK_TOOLKIT_I7000',
description: 'Provides destroy times',
Expand Down Expand Up @@ -297,7 +297,7 @@ export const IO = {
interface: 'ErrorPayload',
}),

// 9: Bootstrap
// 9: Bootstrap (9xxx)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i assume by the way you are "enforcing" this that these are not meant to be strongly enforced at all, and will rely on our attention to detail to ensure we follow.

i feel like we are getting to the point where these rules may be hard to get right when we eventually introduce new message codes.

CDK_TOOLKIT_I9000: make.info<Duration>({
code: 'CDK_TOOLKIT_I9000',
description: 'Provides bootstrap times',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ArtifactMetadataEntryType, type MetadataEntry } from '@aws-cdk/cloud-assembly-schema';
import type { CloudFormationStackArtifact } from '@aws-cdk/cx-api';

/**
* Metadata entry for a resource within a CloudFormation stack
*/
export interface ResourceMetadata {
/**
* The resource's metadata as declared in the cloud assembly
*/
readonly entry: MetadataEntry;
/**
* The construct path of the resource
*/
readonly constructPath: string;
}

/**
* Attempts to read metadata for resources from a CloudFormation stack artifact
*
* @param stack The CloudFormation stack to read from
* @param logicalId The logical ID of the resource to read
*
* @returns The resource metadata, or undefined if the resource was not found
*/
export function resourceMetadata(stack: CloudFormationStackArtifact, logicalId: string): ResourceMetadata | undefined {
const metadata = stack.manifest?.metadata;
if (!metadata) {
return undefined;
}

for (const path of Object.keys(metadata)) {
const entry = metadata[path]
.filter((e) => e.type === ArtifactMetadataEntryType.LOGICAL_ID)
.find((e) => e.data === logicalId);
if (entry) {
return {
entry,
constructPath: simplifyConstructPath(path, stack.stackName),
};
}
}
return undefined;
}

function simplifyConstructPath(path: string, stackName: string) {
path = path.replace(/\/Resource$/, '');
path = path.replace(/^\//, ''); // remove "/" prefix

// remove "<stack-name>/" prefix
if (stackName) {
if (path.startsWith(stackName + '/')) {
path = path.slice(stackName.length + 1);
}
}
return path;
}
3 changes: 1 addition & 2 deletions packages/aws-cdk/lib/api/deployments/hotswap-deployments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ export async function tryHotswapDeployment(
const currentTemplate = await loadCurrentTemplateWithNestedStacks(stackArtifact, sdk);

const evaluateCfnTemplate = new EvaluateCloudFormationTemplate({
stackName: stackArtifact.stackName,
template: stackArtifact.template,
stackArtifact,
parameters: assetParams,
account: resolvedEnv.account,
region: resolvedEnv.region,
Expand Down
19 changes: 15 additions & 4 deletions packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { CloudFormationStackArtifact } from '@aws-cdk/cx-api';
import type { Export, ListExportsCommandOutput, StackResourceSummary } from '@aws-sdk/client-cloudformation';
import type { SDK } from './aws-auth';
import type { NestedStackTemplates } from './deployments';
import { resourceMetadata } from '../../../@aws-cdk/tmp-toolkit-helpers/src/api/resource-metadata/resource-metadata';
import type { ResourceMetadata } from '../../../@aws-cdk/tmp-toolkit-helpers/src/api/resource-metadata/resource-metadata';
import { ToolkitError } from '../toolkit/error';

export interface ListStackResources {
Expand Down Expand Up @@ -85,8 +88,9 @@ export interface ResourceDefinition {
}

export interface EvaluateCloudFormationTemplateProps {
readonly stackName: string;
readonly template: Template;
readonly stackArtifact: CloudFormationStackArtifact;
readonly stackName?: string;
readonly template?: Template;
readonly parameters: { [parameterName: string]: string };
readonly account: string;
readonly region: string;
Expand All @@ -98,6 +102,7 @@ export interface EvaluateCloudFormationTemplateProps {
}

export class EvaluateCloudFormationTemplate {
public readonly stackArtifact: CloudFormationStackArtifact;
private readonly stackName: string;
private readonly template: Template;
private readonly context: { [k: string]: any };
Expand All @@ -114,8 +119,9 @@ export class EvaluateCloudFormationTemplate {
private cachedUrlSuffix: string | undefined;

constructor(props: EvaluateCloudFormationTemplateProps) {
this.stackName = props.stackName;
this.template = props.template;
this.stackArtifact = props.stackArtifact;
this.stackName = props.stackName ?? props.stackArtifact.stackName;
this.template = props.template ?? props.stackArtifact.template;
this.context = {
'AWS::AccountId': props.account,
'AWS::Region': props.region,
Expand Down Expand Up @@ -147,6 +153,7 @@ export class EvaluateCloudFormationTemplate {
) {
const evaluatedParams = await this.evaluateCfnExpression(nestedStackParameters);
return new EvaluateCloudFormationTemplate({
stackArtifact: this.stackArtifact,
stackName,
template: nestedTemplate,
parameters: evaluatedParams,
Expand Down Expand Up @@ -312,6 +319,10 @@ export class EvaluateCloudFormationTemplate {
return this.template.Resources?.[logicalId]?.Properties?.[propertyName];
}

public metadataFor(logicalId: string): ResourceMetadata | undefined {
return resourceMetadata(this.stackArtifact, logicalId);
}

private references(logicalId: string, templateElement: any): boolean {
if (typeof templateElement === 'string') {
return logicalId === templateElement;
Expand Down
3 changes: 1 addition & 2 deletions packages/aws-cdk/lib/api/logs/find-cloudwatch-logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ export async function findCloudWatchLogGroups(

const listStackResources = new LazyListStackResources(sdk, stackArtifact.stackName);
const evaluateCfnTemplate = new EvaluateCloudFormationTemplate({
stackName: stackArtifact.stackName,
template: stackArtifact.template,
stackArtifact,
parameters: {},
account: resolvedEnv.account,
region: resolvedEnv.region,
Expand Down
30 changes: 4 additions & 26 deletions packages/aws-cdk/lib/api/stack-events/stack-activity-monitor.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

import * as util from 'util';
import { ArtifactMetadataEntryType } from '@aws-cdk/cloud-assembly-schema';
import type { CloudFormationStackArtifact } from '@aws-cdk/cx-api';
import type { ResourceMetadata, StackActivity, StackMonitoringControlEvent } from '@aws-cdk/tmp-toolkit-helpers';
import type { StackActivity, StackMonitoringControlEvent } from '@aws-cdk/tmp-toolkit-helpers';
import * as uuid from 'uuid';
import { StackEventPoller } from './stack-event-poller';
import { resourceMetadata } from '../../../../@aws-cdk/tmp-toolkit-helpers/src/api/resource-metadata/resource-metadata';
import { debug, error, info } from '../../cli/messages';
import { stackEventHasErrorMessage } from '../../util';
import type { ICloudFormationClient } from '../aws-auth';
Expand Down Expand Up @@ -181,23 +181,12 @@ export class StackActivityMonitor {
this.scheduleNextTick();
}

private findMetadataFor(logicalId: string | undefined): ResourceMetadata | undefined {
private findMetadataFor(logicalId: string | undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why delete this? seems like we are still returning the same type

const metadata = this.stack.manifest?.metadata;
if (!logicalId || !metadata) {
return undefined;
}
for (const path of Object.keys(metadata)) {
const entry = metadata[path]
.filter((e) => e.type === ArtifactMetadataEntryType.LOGICAL_ID)
.find((e) => e.data === logicalId);
if (entry) {
return {
entry,
constructPath: this.simplifyConstructPath(path),
};
}
}
return undefined;
return resourceMetadata(this.stack, logicalId);
}

/**
Expand Down Expand Up @@ -278,15 +267,4 @@ export class StackActivityMonitor {
}
}
}

private simplifyConstructPath(path: string) {
path = path.replace(/\/Resource$/, '');
path = path.replace(/^\//, ''); // remove "/" prefix

// remove "<stack-name>/" prefix
if (path.startsWith(this.stackName + '/')) {
path = path.slice(this.stackName.length + 1);
}
return path;
}
}
Loading