Skip to content

Commit

Permalink
Merge branch 'master' into parameterize_bootstrap_stack_version
Browse files Browse the repository at this point in the history
  • Loading branch information
rix0rrr authored Jun 7, 2021
2 parents ebf61e2 + 775a0c9 commit 388f0e8
Show file tree
Hide file tree
Showing 39 changed files with 490 additions and 270 deletions.
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
"fs-extra": "^9.1.0",
"graceful-fs": "^4.2.6",
"jest-junit": "^12.1.0",
"jsii-diff": "^1.29.0",
"jsii-pacmak": "^1.29.0",
"jsii-reflect": "^1.29.0",
"jsii-rosetta": "^1.29.0",
"jsii-diff": "^1.30.0",
"jsii-pacmak": "^1.30.0",
"jsii-reflect": "^1.30.0",
"jsii-rosetta": "^1.30.0",
"lerna": "^4.0.0",
"patch-package": "^6.4.7",
"standard-version": "^9.3.0",
Expand Down Expand Up @@ -97,6 +97,8 @@
"@aws-cdk/core/minimatch/**",
"@aws-cdk/cx-api/semver",
"@aws-cdk/cx-api/semver/**",
"@aws-cdk/aws-events-targets/aws-sdk",
"@aws-cdk/aws-events-targets/aws-sdk/**",
"@aws-cdk/yaml-cfn/yaml",
"@aws-cdk/yaml-cfn/yaml/**",
"aws-cdk-lib/@balena/dockerignore",
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 @@ -62,7 +62,7 @@
"@types/nodeunit": "^0.0.31",
"cdk-build-tools": "0.0.0",
"cdk-integ-tools": "0.0.0",
"fast-check": "^2.14.0",
"fast-check": "^2.16.0",
"nodeunit": "^0.11.3",
"pkglint": "0.0.0",
"@aws-cdk/assert-internal": "0.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"license": "Apache-2.0",
"devDependencies": {
"@types/jest": "^26.0.23",
"@types/aws-lambda": "^8.10.76",
"@types/aws-lambda": "^8.10.77",
"@aws-cdk/aws-apigatewayv2-integrations": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"cdk-build-tools": "0.0.0",
Expand Down
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 @@ -73,7 +73,7 @@
"@types/nodeunit": "^0.0.31",
"cdk-build-tools": "0.0.0",
"cfn2ts": "0.0.0",
"fast-check": "^2.14.0",
"fast-check": "^2.16.0",
"nodeunit": "^0.11.3",
"pkglint": "0.0.0",
"@aws-cdk/assert-internal": "0.0.0"
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 @@ -65,7 +65,7 @@
"@types/nodeunit": "^0.0.31",
"cdk-build-tools": "0.0.0",
"cdk-integ-tools": "0.0.0",
"fast-check": "^2.14.0",
"fast-check": "^2.16.0",
"nodeunit": "^0.11.3",
"pkglint": "0.0.0",
"@aws-cdk/assert-internal": "0.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,21 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@types/aws-lambda": "^8.10.76",
"@types/aws-lambda": "^8.10.77",
"@types/sinon": "^9.0.11",
"cdk-build-tools": "0.0.0",
"aws-sdk": "^2.596.0",
"aws-sdk-mock": "^5.1.0",
"eslint": "^7.27.0",
"eslint": "^7.28.0",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.23.3",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-standard": "^4.1.0",
"jest": "^26.6.3",
"lambda-tester": "^3.6.0",
"sinon": "^9.2.4",
"nock": "^13.0.11",
"nock": "^13.1.0",
"ts-jest": "^26.5.6"
}
}
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-cloudformation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"@aws-cdk/aws-sns-subscriptions": "0.0.0",
"@aws-cdk/aws-sqs": "0.0.0",
"@aws-cdk/aws-ssm": "0.0.0",
"@types/aws-lambda": "^8.10.76",
"@types/aws-lambda": "^8.10.77",
"@types/nodeunit": "^0.0.31",
"cdk-build-tools": "0.0.0",
"cdk-integ-tools": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
"devDependencies": {
"aws-sdk": "^2.596.0",
"aws-sdk-mock": "^5.1.0",
"eslint": "^7.27.0",
"eslint": "^7.28.0",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.23.3",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-standard": "^4.1.0",
"jest": "^26.6.3",
"lambda-tester": "^3.6.0",
"nock": "^13.0.11"
"nock": "^13.1.0"
}
}
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-dynamodb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@types/aws-lambda": "^8.10.76",
"@types/aws-lambda": "^8.10.77",
"@types/jest": "^26.0.23",
"@types/sinon": "^9.0.11",
"aws-sdk": "^2.848.0",
Expand Down
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-ec2/lib/security-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,9 @@ export class SecurityGroup extends SecurityGroupBase {
// In the case of "allowAllOutbound", we don't add any more rules. There
// is only one rule which allows all traffic and that subsumes any other
// rule.
Annotations.of(this).addWarning('Ignoring Egress rule since \'allowAllOutbound\' is set to true; To add customize rules, set allowAllOutbound=false on the SecurityGroup');
if (!remoteRule) { // Warn only if addEgressRule() was explicitely called
Annotations.of(this).addWarning('Ignoring Egress rule since \'allowAllOutbound\' is set to true; To add customize rules, set allowAllOutbound=false on the SecurityGroup');
}
return;
} else {
// Otherwise, if the bogus rule exists we can now remove it because the
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-ec2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@types/aws-lambda": "^8.10.76",
"@types/aws-lambda": "^8.10.77",
"@types/jest": "^26.0.23",
"@aws-cdk/cx-api": "0.0.0",
"cdk-build-tools": "0.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-eks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@types/aws-lambda": "^8.10.76",
"@types/aws-lambda": "^8.10.77",
"@types/sinon": "^9.0.11",
"@types/nodeunit": "^0.0.31",
"@types/yaml": "1.9.6",
Expand Down
15 changes: 15 additions & 0 deletions packages/@aws-cdk/aws-events-targets/lib/aws-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import * as lambda from '@aws-cdk/aws-lambda';
import { Annotations } from '@aws-cdk/core';
import { metadata } from './sdk-api-metadata.generated';
import { addLambdaPermission } from './util';

Expand Down Expand Up @@ -89,6 +90,8 @@ export class AwsApi implements events.IRuleTarget {
lambdaPurpose: 'AWS',
});

checkServiceExists(this.props.service, handler);

if (this.props.policyStatement) {
handler.addToRolePolicy(this.props.policyStatement);
} else {
Expand Down Expand Up @@ -117,6 +120,18 @@ export class AwsApi implements events.IRuleTarget {
}
}

/**
* Check if the given service exists in the AWS SDK. If not, a warning will be raised.
* @param service Service name
*/
function checkServiceExists(service: string, handler: lambda.SingletonFunction) {
const sdkService = awsSdkMetadata[service.toLowerCase()];
if (!sdkService) {
Annotations.of(handler).addWarning(`Service ${service} does not exist in the AWS SDK. Check the list of available \
services and actions from https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html`);
}
}

/**
* Transform SDK service/action to IAM action using metadata from aws-sdk module.
*/
Expand Down
38 changes: 32 additions & 6 deletions packages/@aws-cdk/aws-events-targets/test/aws-api/aws-api.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { countResources, expect, haveResource } from '@aws-cdk/assert-internal';
import { countResources, expect as cdkExpect, haveResource, SynthUtils } from '@aws-cdk/assert-internal';
import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import { Stack } from '@aws-cdk/core';
Expand Down Expand Up @@ -32,7 +32,7 @@ test('use AwsApi as an event rule target', () => {
}));

// THEN
expect(stack).to(haveResource('AWS::Events::Rule', {
cdkExpect(stack).to(haveResource('AWS::Events::Rule', {
Targets: [
{
Arn: {
Expand Down Expand Up @@ -73,9 +73,9 @@ test('use AwsApi as an event rule target', () => {
}));

// Uses a singleton function
expect(stack).to(countResources('AWS::Lambda::Function', 1));
cdkExpect(stack).to(countResources('AWS::Lambda::Function', 1));

expect(stack).to(haveResource('AWS::IAM::Policy', {
cdkExpect(stack).to(haveResource('AWS::IAM::Policy', {
PolicyDocument: {
Statement: [
{
Expand Down Expand Up @@ -112,7 +112,7 @@ test('with policy statement', () => {
}));

// THEN
expect(stack).to(haveResource('AWS::Events::Rule', {
cdkExpect(stack).to(haveResource('AWS::Events::Rule', {
Targets: [
{
Arn: {
Expand All @@ -130,7 +130,7 @@ test('with policy statement', () => {
],
}));

expect(stack).to(haveResource('AWS::IAM::Policy', {
cdkExpect(stack).to(haveResource('AWS::IAM::Policy', {
PolicyDocument: {
Statement: [
{
Expand All @@ -143,3 +143,29 @@ test('with policy statement', () => {
},
}));
});

test('with service not in AWS SDK', () => {
// GIVEN
const stack = new Stack();
const rule = new events.Rule(stack, 'Rule', {
schedule: events.Schedule.expression('rate(15 minutes)'),
});
const awsApi = new targets.AwsApi({
service: 'no-such-service',
action: 'no-such-action',
policyStatement: new iam.PolicyStatement({
actions: ['s3:GetObject'],
resources: ['resource'],
}),
});

// WHEN
rule.addTarget(awsApi);

// THEN
const assembly = SynthUtils.synthesize(stack);
expect(assembly.messages.length).toBe(1);
const message = assembly.messages[0];
expect(message.entry.type).toBe('aws:cdk:warning');
expect(message.entry.data).toBe('Service no-such-service does not exist in the AWS SDK. Check the list of available services and actions from https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html');
});
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-events/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ onCommitRule.addTarget(new targets.SnsTopic(topic, {
}));
```

Or using an Object:

```ts
onCommitRule.addTarget(new targets.SnsTopic(topic, {
message: events.RuleTargetInput.fromObject(
{
DataType: `custom_${events.EventField.fromPath('$.detail-type')}`
}
)
}));
```

## Scheduling

You can configure a Rule to run on a schedule (cron or rate).
Expand Down
44 changes: 13 additions & 31 deletions packages/@aws-cdk/aws-events/lib/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,6 @@ class FieldAwareEventInput extends RuleTargetInput {
return key;
}

const self = this;

class EventFieldReplacer extends DefaultTokenResolver {
constructor() {
super(new StringConcat());
Expand All @@ -167,7 +165,7 @@ class FieldAwareEventInput extends RuleTargetInput {
}
inputPathsMap[key] = t.path;

return self.keyPlaceholder(key);
return `<${key}>`;
}
}

Expand All @@ -188,35 +186,32 @@ class FieldAwareEventInput extends RuleTargetInput {
}));
}

if (Object.keys(inputPathsMap).length === 0) {
const keys = Object.keys(inputPathsMap);

if (keys.length === 0) {
// Nothing special, just return 'input'
return { input: resolved };
}

return {
inputTemplate: this.unquoteKeyPlaceholders(resolved),
inputTemplate: this.unquoteKeyPlaceholders(resolved, keys),
inputPathsMap,
};
}

/**
* Return a template placeholder for the given key
*
* In object scope we'll need to get rid of surrounding quotes later on, so
* return a bracing that's unlikely to occur naturally (like tokens).
*/
private keyPlaceholder(key: string) {
if (this.inputType !== InputType.Object) { return `<${key}>`; }
return UNLIKELY_OPENING_STRING + key + UNLIKELY_CLOSING_STRING;
}

/**
* Removing surrounding quotes from any object placeholders
* when key is the lone value.
*
* Those have been put there by JSON.stringify(), but we need to
* remove them.
*
* Do not remove quotes when the key is part of a larger string.
*
* Valid: { "data": "Some string with \"quotes\"<key>" } // key will be string
* Valid: { "data": <key> } // Key could be number, bool, obj, or string
*/
private unquoteKeyPlaceholders(sub: string) {
private unquoteKeyPlaceholders(sub: string, keys: string[]) {
if (this.inputType !== InputType.Object) { return sub; }

return Lazy.uncachedString({ produce: (ctx: IResolveContext) => Token.asString(deepUnquote(ctx.resolve(sub))) });
Expand All @@ -230,19 +225,13 @@ class FieldAwareEventInput extends RuleTargetInput {
}
return resolved;
} else if (typeof(resolved) === 'string') {
return resolved.replace(OPENING_STRING_REGEX, '<').replace(CLOSING_STRING_REGEX, '>');
return keys.reduce((r, key) => r.replace(new RegExp(`(?<!\\\\)\"\<${key}\>\"`, 'g'), `<${key}>`), resolved);
}
return resolved;
}
}
}

const UNLIKELY_OPENING_STRING = '<<${';
const UNLIKELY_CLOSING_STRING = '}>>';

const OPENING_STRING_REGEX = new RegExp(regexQuote('"' + UNLIKELY_OPENING_STRING), 'g');
const CLOSING_STRING_REGEX = new RegExp(regexQuote(UNLIKELY_CLOSING_STRING + '"'), 'g');

/**
* Represents a field in the event pattern
*/
Expand Down Expand Up @@ -339,10 +328,3 @@ function isEventField(x: any): x is EventField {
}

const EVENT_FIELD_SYMBOL = Symbol.for('@aws-cdk/aws-events.EventField');

/**
* Quote a string for use in a regex
*/
function regexQuote(s: string) {
return s.replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&');
}
Loading

0 comments on commit 388f0e8

Please sign in to comment.