Skip to content
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

fix(codepipeline-actions): correctly serialize the userParameters pas… #2537

Merged
merged 1 commit into from
May 30, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export interface LambdaInvokeActionProps extends codepipeline.CommonActionProps
*/
readonly inputs?: codepipeline.Artifact[];

// tslint:enable:max-line-length

/**
* The optional names of the output Artifacts of the Action.
* A Lambda Action can have up to 5 outputs.
Expand All @@ -34,30 +32,14 @@ export interface LambdaInvokeActionProps extends codepipeline.CommonActionProps
readonly outputs?: codepipeline.Artifact[];

/**
* String to be used in the event data parameter passed to the Lambda
* function
*
* See an example JSON event in the CodePipeline documentation.
* A set of key-value pairs that will be accessible to the invoked Lambda
* inside the event that the Pipeline will call it with.
*
* https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html#actions-invoke-lambda-function-json-event-example
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html#actions-invoke-lambda-function-json-event-example
*/
readonly userParameters?: any;
readonly userParameters?: { [key: string]: any };

/**
* Adds the "codepipeline:PutJobSuccessResult" and
* "codepipeline:PutJobFailureResult" for '*' resource to the Lambda
* execution role policy.
*
* NOTE: the reason we can't add the specific pipeline ARN as a resource is
* to avoid a cyclic dependency between the pipeline and the Lambda function
* (the pipeline references) the Lambda and the Lambda needs permissions on
* the pipeline.
*
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html#actions-invoke-lambda-function-create-function
*
* @default true
*/
readonly addPutJobResultPolicy?: boolean;
// tslint:enable:max-line-length

skinny85 marked this conversation as resolved.
Show resolved Hide resolved
/**
* The lambda function to invoke.
Expand Down Expand Up @@ -86,8 +68,8 @@ export class LambdaInvokeAction extends codepipeline.Action {
},
configuration: {
FunctionName: props.lambda.functionName,
UserParameters: props.userParameters
}
UserParameters: props.lambda.node.stringifyJson(props.userParameters),
},
});

this.props = props;
Expand All @@ -104,13 +86,12 @@ export class LambdaInvokeAction extends codepipeline.Action {
.addAction('lambda:InvokeFunction')
.addResource(this.props.lambda.functionArn));

// allow lambda to put job results for this pipeline.
const addToPolicy = this.props.addPutJobResultPolicy !== undefined ? this.props.addPutJobResultPolicy : true;
if (addToPolicy) {
this.props.lambda.addToRolePolicy(new iam.PolicyStatement()
.addAllResources() // to avoid cycles (see docs)
.addAction('codepipeline:PutJobSuccessResult')
.addAction('codepipeline:PutJobFailureResult'));
}
// allow lambda to put job results for this pipeline
// CodePipeline requires this to be granted to '*'
// (the Pipeline ARN will not be enough)
this.props.lambda.addToRolePolicy(new iam.PolicyStatement()
.addAllResources()
.addAction('codepipeline:PutJobSuccessResult')
.addAction('codepipeline:PutJobFailureResult'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { expect, haveResourceLike } from "@aws-cdk/assert";
import codepipeline = require('@aws-cdk/aws-codepipeline');
import lambda = require('@aws-cdk/aws-lambda');
import { Aws, SecretValue, Stack, Token } from "@aws-cdk/cdk";
import { Test } from 'nodeunit';
import cpactions = require('../../lib');

// tslint:disable:object-literal-key-quotes

export = {
'Lambda invoke Action': {
'properly serializes the object passed in userParameters'(test: Test) {
const stack = stackIncludingLambdaInvokeCodePipeline({
key: 1234,
});

expect(stack).to(haveResourceLike('AWS::CodePipeline::Pipeline', {
'Stages': [
{},
{
'Actions': [
{
'Configuration': {
'UserParameters': '{"key":1234}',
},
},
],
},
],
}));

test.done();
},

'properly resolves any Tokens passed in userParameters'(test: Test) {
const stack = stackIncludingLambdaInvokeCodePipeline({
key: new Token(() => Aws.region),
});

expect(stack).to(haveResourceLike('AWS::CodePipeline::Pipeline', {
'Stages': [
{},
{
'Actions': [
{
'Configuration': {
'UserParameters': {
'Fn::Join': [
'',
[
'{"key":"',
{
'Ref': 'AWS::Region',
},
'"}',
],
],
},
},
},
],
},
],
}));

test.done();
},

'properly resolves any stringified Tokens passed in userParameters'(test: Test) {
const stack = stackIncludingLambdaInvokeCodePipeline({
key: new Token(() => null).toString(),
});

expect(stack).to(haveResourceLike('AWS::CodePipeline::Pipeline', {
'Stages': [
{},
{
'Actions': [
{
'Configuration': {
'UserParameters': '{"key":null}',
},
},
],
},
],
}));

test.done();
},
},
};

function stackIncludingLambdaInvokeCodePipeline(userParams: { [key: string]: any }) {
const stack = new Stack();

new codepipeline.Pipeline(stack, 'Pipeline', {
stages: [
{
name: 'Source',
actions: [
new cpactions.GitHubSourceAction({
actionName: 'GitHub',
output: new codepipeline.Artifact(),
oauthToken: SecretValue.plainText('secret'),
owner: 'awslabs',
repo: 'aws-cdk',
}),
],
},
{
name: 'Invoke',
actions: [
new cpactions.LambdaInvokeAction({
actionName: 'Lambda',
lambda: new lambda.Function(stack, 'Lambda', {
code: lambda.Code.cfnParameters(),
handler: 'index.handler',
runtime: lambda.Runtime.NodeJS810,
}),
userParameters: userParams,
}),
],
},
],
});

return stack;
}
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@ export = {
const lambdaAction = new cpactions.LambdaInvokeAction({
actionName: 'InvokeAction',
lambda: lambdaFun,
userParameters: 'foo-bar/42',
inputs: [
source2Output,
source1Output,
Expand Down Expand Up @@ -510,7 +509,6 @@ export = {
"FunctionName": {
"Ref": "Function76856677"
},
"UserParameters": "foo-bar/42"
},
"InputArtifacts": [
{ "Name": "sourceArtifact2" },
Expand Down