Skip to content

Commit

Permalink
Merge branch 'master' into bhargav50/cdk-init-spaces-failure
Browse files Browse the repository at this point in the history
  • Loading branch information
bhargav50 authored Feb 17, 2022
2 parents 9bc45d6 + 3533ea9 commit 6ad8ea6
Show file tree
Hide file tree
Showing 315 changed files with 7,898 additions and 1,455 deletions.
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
},
"devDependencies": {
"@yarnpkg/lockfile": "^1.1.0",
"cdk-generate-synthetic-examples": "^0.1.5",
"cdk-generate-synthetic-examples": "^0.1.6",
"conventional-changelog-cli": "^2.2.2",
"fs-extra": "^9.1.0",
"graceful-fs": "^4.2.9",
"jest-junit": "^13.0.0",
"jsii-diff": "^1.53.0",
"jsii-pacmak": "^1.53.0",
"jsii-reflect": "^1.53.0",
"jsii-rosetta": "^1.53.0",
"jsii-diff": "^1.54.0",
"jsii-pacmak": "^1.54.0",
"jsii-reflect": "^1.54.0",
"jsii-rosetta": "^1.54.0",
"lerna": "^4.0.0",
"patch-package": "^6.4.7",
"standard-version": "^9.3.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/app-delivery/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"@aws-cdk/cdk-integ-tools": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^27.4.0",
"fast-check": "^2.21.0",
"fast-check": "^2.22.0",
"jest": "^27.5.1"
},
"repository": {
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/assertions/lib/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ function constructMessage(type: 'info' | 'warning' | 'error', message: any): {[k
}

function convertArrayToMessagesType(messages: SynthesisMessage[]): Messages {
return messages.reduce((obj, item) => {
return messages.reduce((obj, item, index) => {
return {
...obj,
[item.id]: item,
[index]: item,
};
}, {}) as Messages;
}
Expand Down
11 changes: 8 additions & 3 deletions packages/@aws-cdk/assertions/lib/private/cyclic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,16 @@ function findExpressionDependencies(obj: any): Set<string> {
} else if (keys.length === 1 && keys[0] === 'Fn::Sub') {
const argument = x[keys[0]];
const pattern = Array.isArray(argument) ? argument[0] : argument;
for (const logId of logicalIdsInSubString(pattern)) {
ret.add(logId);

// pattern should always be a string, but we've encountered some cases in which
// it isn't. Better safeguard.
if (typeof pattern === 'string') {
for (const logId of logicalIdsInSubString(pattern)) {
ret.add(logId);
}
}
const contextDict = Array.isArray(argument) ? argument[1] : undefined;
if (contextDict) {
if (contextDict && typeof contextDict === 'object') {
Object.values(contextDict).forEach(recurse);
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/assertions/lib/private/message.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SynthesisMessage } from '@aws-cdk/cx-api';

export type Messages = {
[logicalId: string]: SynthesisMessage;
[key: string]: SynthesisMessage;
}
37 changes: 23 additions & 14 deletions packages/@aws-cdk/assertions/lib/private/messages.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { MatchResult } from '../matcher';
import { SynthesisMessage } from '@aws-cdk/cx-api';
import { Messages } from './message';
import { filterLogicalId, formatFailure, matchSection } from './section';
import { formatFailure, matchSection } from './section';

export function findMessage(messages: Messages, logicalId: string, props: any = {}): { [key: string]: { [key: string]: any } } {
const section: { [key: string]: {} } = messages;
const result = matchSection(filterLogicalId(section, logicalId), props);
export function findMessage(messages: Messages, constructPath: string, props: any = {}): { [key: string]: { [key: string]: any } } {
const section: { [key: string]: SynthesisMessage } = messages;
const result = matchSection(filterPath(section, constructPath), props);

if (!result.match) {
return {};
Expand All @@ -13,9 +13,9 @@ export function findMessage(messages: Messages, logicalId: string, props: any =
return result.matches;
}

export function hasMessage(messages: Messages, logicalId: string, props: any): string | void {
const section: { [key: string]: {} } = messages;
const result = matchSection(filterLogicalId(section, logicalId), props);
export function hasMessage(messages: Messages, constructPath: string, props: any): string | void {
const section: { [key: string]: SynthesisMessage } = messages;
const result = matchSection(filterPath(section, constructPath), props);

if (result.match) {
return;
Expand All @@ -25,17 +25,26 @@ export function hasMessage(messages: Messages, logicalId: string, props: any): s
return 'No messages found in the stack';
}

handleTrace(result.closestResult.target);
return [
`Stack has ${result.analyzedCount} messages, but none match as expected.`,
formatFailure(formatMessage(result.closestResult)),
formatFailure(result.closestResult),
].join('\n');
}

// We redact the stack trace by default because it is unnecessarily long and unintelligible.
// If there is a use case for rendering the trace, we can add it later.
function formatMessage(match: MatchResult, renderTrace: boolean = false): MatchResult {
if (!renderTrace) {
match.target.entry.trace = 'redacted';
}
return match;
function handleTrace(match: any, redact: boolean = true): void {
if (redact && match.entry?.trace !== undefined) {
match.entry.trace = 'redacted';
};
}

function filterPath(section: { [key: string]: SynthesisMessage }, path: string): { [key: string]: SynthesisMessage } {
// default signal for all paths is '*'
if (path === '*') return section;

return Object.entries(section ?? {})
.filter(([_, v]) => v.id === path)
.reduce((agg, [k, v]) => { return { ...agg, [k]: v }; }, {});
}
71 changes: 64 additions & 7 deletions packages/@aws-cdk/assertions/test/annotations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ describe('Messages', () => {
describe('findError', () => {
test('match', () => {
const result = annotations.findError('*', Match.anyValue());
expect(Object.keys(result).length).toEqual(2);
expect(result.length).toEqual(2);
});

test('no match', () => {
const result = annotations.findError('*', 'no message looks like this');
expect(Object.keys(result).length).toEqual(0);
expect(result.length).toEqual(0);
});
});

Expand All @@ -75,12 +75,12 @@ describe('Messages', () => {
describe('findWarning', () => {
test('match', () => {
const result = annotations.findWarning('*', Match.anyValue());
expect(Object.keys(result).length).toEqual(1);
expect(result.length).toEqual(1);
});

test('no match', () => {
const result = annotations.findWarning('*', 'no message looks like this');
expect(Object.keys(result).length).toEqual(0);
expect(result.length).toEqual(0);
});
});

Expand All @@ -97,19 +97,19 @@ describe('Messages', () => {
describe('findInfo', () => {
test('match', () => {
const result = annotations.findInfo('/Default/Qux', 'this is an info');
expect(Object.keys(result).length).toEqual(1);
expect(result.length).toEqual(1);
});

test('no match', () => {
const result = annotations.findInfo('*', 'no message looks like this');
expect(Object.keys(result).length).toEqual(0);
expect(result.length).toEqual(0);
});
});

describe('with matchers', () => {
test('anyValue', () => {
const result = annotations.findError('*', Match.anyValue());
expect(Object.keys(result).length).toEqual(2);
expect(result.length).toEqual(2);
});

test('not', () => {
Expand All @@ -123,6 +123,45 @@ describe('Messages', () => {
});
});

describe('Multiple Messages on the Resource', () => {
let stack: Stack;
let annotations: _Annotations;
beforeAll(() => {
stack = new Stack();
new CfnResource(stack, 'Foo', {
type: 'Foo::Bar',
properties: {
Fred: 'Thud',
},
});

const bar = new CfnResource(stack, 'Bar', {
type: 'Foo::Bar',
properties: {
Baz: 'Qux',
},
});
bar.node.setContext('disable-stack-trace', false);

Aspects.of(stack).add(new MultipleAspectsPerNode());
annotations = _Annotations.fromStack(stack);
});

test('succeeds on hasXxx APIs', () => {
annotations.hasError('/Default/Foo', 'error: this is an error');
annotations.hasError('/Default/Foo', 'error: unsupported type Foo::Bar');
annotations.hasWarning('/Default/Foo', 'warning: Foo::Bar is deprecated');
});

test('succeeds on findXxx APIs', () => {
const result1 = annotations.findError('*', Match.stringLikeRegexp('error:.*'));
expect(result1.length).toEqual(4);
const result2 = annotations.findError('/Default/Bar', Match.stringLikeRegexp('error:.*'));
expect(result2.length).toEqual(2);
const result3 = annotations.findWarning('/Default/Bar', 'warning: Foo::Bar is deprecated');
expect(result3[0].entry.data).toEqual('warning: Foo::Bar is deprecated');
});
});
class MyAspect implements IAspect {
public visit(node: IConstruct): void {
if (node instanceof CfnResource) {
Expand All @@ -147,4 +186,22 @@ class MyAspect implements IAspect {
protected info(node: IConstruct, message: string): void {
Annotations.of(node).addInfo(message);
}
}

class MultipleAspectsPerNode implements IAspect {
public visit(node: IConstruct): void {
if (node instanceof CfnResource) {
this.error(node, 'error: this is an error');
this.error(node, `error: unsupported type ${node.cfnResourceType}`);
this.warn(node, `warning: ${node.cfnResourceType} is deprecated`);
}
}

protected warn(node: IConstruct, message: string): void {
Annotations.of(node).addWarning(message);
}

protected error(node: IConstruct, message: string): void {
Annotations.of(node).addError(message);
}
}
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-applicationautoscaling/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"@aws-cdk/cfn2ts": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^27.4.0",
"fast-check": "^2.21.0",
"fast-check": "^2.22.0",
"jest": "^27.5.1"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-autoscaling-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"@aws-cdk/cdk-integ-tools": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^27.4.0",
"fast-check": "^2.21.0",
"fast-check": "^2.22.0",
"jest": "^27.5.1"
},
"dependencies": {
Expand Down
55 changes: 53 additions & 2 deletions packages/@aws-cdk/aws-codepipeline-actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ directly from a CodeCommit repository, with a manual approval step in between to
See [the AWS documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline.html)
for more details about using CloudFormation in CodePipeline.

#### Actions defined by this package
#### Actions for updating individual CloudFormation Stacks

This package contains the following CloudFormation actions:

Expand All @@ -620,6 +620,57 @@ This package contains the following CloudFormation actions:
changes from the people (or system) applying the changes.
* **CloudFormationExecuteChangeSetAction** - Execute a change set prepared previously.

#### Actions for deploying CloudFormation StackSets to multiple accounts

You can use CloudFormation StackSets to deploy the same CloudFormation template to multiple
accounts in a managed way. If you use AWS Organizations, StackSets can be deployed to
all accounts in a particular Organizational Unit (OU), and even automatically to new
accounts as soon as they are added to a particular OU. For more information, see
the [Working with StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html)
section of the CloudFormation developer guide.

The actions available for updating StackSets are:

* **CloudFormationDeployStackSetAction** - Create or update a CloudFormation StackSet directly from the pipeline, optionally
immediately create and update Stack Instances as well.
* **CloudFormationDeployStackInstancesAction** - Update outdated Stack Instaces using the current version of the StackSet.

Here's an example of using both of these actions:

```ts
declare const pipeline: codepipeline.Pipeline;
declare const sourceOutput: codepipeline.Artifact;

pipeline.addStage({
stageName: 'DeployStackSets',
actions: [
// First, update the StackSet itself with the newest template
new codepipeline_actions.CloudFormationDeployStackSetAction({
actionName: 'UpdateStackSet',
runOrder: 1,
stackSetName: 'MyStackSet',
template: codepipeline_actions.StackSetTemplate.fromArtifactPath(sourceOutput.atPath('template.yaml')),

// Change this to 'StackSetDeploymentModel.organizations()' if you want to deploy to OUs
deploymentModel: codepipeline_actions.StackSetDeploymentModel.selfManaged(),
// This deploys to a set of accounts
stackInstances: codepipeline_actions.StackInstances.inAccounts(['111111111111'], ['us-east-1', 'eu-west-1']),
}),

// Afterwards, update/create additional instances in other accounts
new codepipeline_actions.CloudFormationDeployStackInstancesAction({
actionName: 'AddMoreInstances',
runOrder: 2,
stackSetName: 'MyStackSet',
stackInstances: codepipeline_actions.StackInstances.inAccounts(
['222222222222', '333333333333'],
['us-east-1', 'eu-west-1']
),
}),
],
});
```

#### Lambda deployed through CodePipeline

If you want to deploy your Lambda through CodePipeline,
Expand Down Expand Up @@ -792,7 +843,7 @@ const deployStage = pipeline.addStage({
```

When deploying across accounts, especially in a CDK Pipelines self-mutating pipeline,
it is recommended to provide the `role` property to the `EcsDeployAction`.
it is recommended to provide the `role` property to the `EcsDeployAction`.
The Role will need to have permissions assigned to it for ECS deployment.
See [the CodePipeline documentation](https://docs.aws.amazon.com/codepipeline/latest/userguide/how-to-custom-role.html#how-to-update-role-new-services)
for the permissions needed.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './pipeline-actions';
export * from './stackset-action';
export * from './stackinstances-action';
export * from './stackset-types';
Loading

0 comments on commit 6ad8ea6

Please sign in to comment.