Skip to content

Commit

Permalink
Merge pull request #222 from shota/master
Browse files Browse the repository at this point in the history
DescribeExecution as option
  • Loading branch information
theburningmonk authored Jul 8, 2019
2 parents cded38f + 83f55e2 commit 479d003
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 43 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This is the Serverless Framework plugin for AWS Step Functions.
- [Events](#events)
- [API Gateway](#api-gateway)
- [Simple HTTP endpoint](#simple-http-endpoint)
- [Custom Step Functions Action](#custom-step-functions-action)
- [HTTP Endpoint with custom IAM Role](#http-endpoint-with-custom-iam-role)
- [Share API Gateway and API Resources](#share-api-gateway-and-api-resources)
- [Enabling CORS](#enabling-cors)
Expand Down Expand Up @@ -375,6 +376,40 @@ stepFunctions:
definition:
```

#### Custom Step Functions Action

Step Functions have custom actions like DescribeExecution or StopExecution to fetch and control them. You can use custom actions like this:

```yml
stepFunctions:
stateMachines:
start:
events:
- http:
path: action/start
method: POST
definition:
...
status:
events:
- http:
path: action/status
method: POST
action: DescribeExecution
definition:
...
stop:
events:
- http:
path: action/stop
method: POST
action: StopExecution
definition:
...
```

Request template is not used when action is set because there're a bunch of actions. However if you want to use request template you can use [Customizing request body mapping templates](#customizing-request-body-mapping-templates).

#### HTTP Endpoint with custom IAM Role

The plugin would generate an IAM Role for you by default. However, if you wish to use an IAM role that you have provisioned separately, then you can override the IAM Role like this:
Expand Down

This file was deleted.

56 changes: 49 additions & 7 deletions lib/deploy/events/apiGateway/iamRole.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';
const _ = require('lodash');
const BbPromise = require('bluebird');
const path = require('path');

module.exports = {
compileHttpIamRole() {
Expand All @@ -14,15 +13,58 @@ module.exports = {
return BbPromise.resolve();
}

const iamRoleApiGatewayToStepFunctionsTemplate =
JSON.stringify(this.serverless.utils.readFileSync(
path.join(__dirname,
'apigateway-to-stepfunctions-assume-role.json'))
);
const iamRoleApiGatewayToStepFunctionsAction = [
'states:StartExecution',
];

// generate IAM Role action by http.action parameter.
this.pluginhttpValidated.events.forEach((event) => {
if (_.has(event, 'http.action')) {
const actionName = `states:${event.http.action}`;

if (iamRoleApiGatewayToStepFunctionsAction.indexOf(actionName) === -1) {
iamRoleApiGatewayToStepFunctionsAction.push(actionName);
}
}
});

const iamRoleApiGatewayToStepFunctions = {
Type: 'AWS::IAM::Role',
Properties: {
AssumeRolePolicyDocument: {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: {
Service: 'apigateway.amazonaws.com',
},
Action: 'sts:AssumeRole',
},
],
},
Policies: [
{
PolicyName: 'apigatewaytostepfunctions',
PolicyDocument: {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Action: iamRoleApiGatewayToStepFunctionsAction,
Resource: '*',
},
],
},
},
],
},
};


const getApiToStepFunctionsIamRoleLogicalId = this.getApiToStepFunctionsIamRoleLogicalId();
const newIamRoleStateMachineExecutionObject = {
[getApiToStepFunctionsIamRoleLogicalId]: JSON.parse(iamRoleApiGatewayToStepFunctionsTemplate),
[getApiToStepFunctionsIamRoleLogicalId]: iamRoleApiGatewayToStepFunctions,
};

_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
Expand Down
52 changes: 52 additions & 0 deletions lib/deploy/events/apiGateway/iamRole.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,56 @@ describe('#compileHttpIamRole()', () => {
expect(resources).to.not.haveOwnProperty('ApigatewayToStepFunctionsRole');
});
});

it('Should add DescribeExecution action when it is assigned in config', () => {
serverlessStepFunctions.pluginhttpValidated = {
events: [
{
stateMachineName: 'first',
http: {
path: 'foo/bar1',
method: 'post',
},
},
{
stateMachineName: 'first',
http: {
path: 'foo/bar2',
method: 'post',
action: 'DescribeExecution',
},
},
],
};

serverlessStepFunctions
.compileHttpIamRole().then(() => {
const properties = serverlessStepFunctions.serverless.service.provider
.compiledCloudFormationTemplate.Resources.ApigatewayToStepFunctionsRole.Properties;
expect(properties.Policies[0].PolicyDocument.Statement[0].Action)
.to.deep.equal(['states:StartExecution', 'states:DescribeExecution']);
});
});

it('Should not add DescribeExecution action when it is not assigned in config', () => {
serverlessStepFunctions.pluginhttpValidated = {
events: [
{
stateMachineName: 'first',
http: {
path: 'foo/bar1',
method: 'post',
},
},
],
};

serverlessStepFunctions
.compileHttpIamRole().then(() => {
const properties = serverlessStepFunctions.serverless.service.provider
.compiledCloudFormationTemplate.Resources.ApigatewayToStepFunctionsRole.Properties;
expect(properties.Policies[0].PolicyDocument.Statement[0].Action)
.to.deep.equal(['states:StartExecution']);
});
});
});
17 changes: 15 additions & 2 deletions lib/deploy/events/apiGateway/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ module.exports = {
],
};
const iamRole = _.get(http, 'iamRole', defaultIamRole);
let integrationAction = ':states:action/StartExecution';
let passthroughBehavior = 'NEVER';
if (http && http.action) {
integrationAction = `:states:action/${http.action}`;
passthroughBehavior = 'WHEN_NO_TEMPLATES';
}

const integration = {
IntegrationHttpMethod: 'POST',
Type: 'AWS',
Expand All @@ -162,11 +169,11 @@ module.exports = {
{
Ref: 'AWS::Region',
},
':states:action/StartExecution',
integrationAction,
],
],
},
PassthroughBehavior: 'NEVER',
PassthroughBehavior: passthroughBehavior,
RequestTemplates: this.getIntegrationRequestTemplates(
stateMachineName,
stateMachineObj,
Expand Down Expand Up @@ -234,6 +241,12 @@ module.exports = {
http.request.template
);
}

if (_.has(http, 'action')) {
// no template if some action was defined.
return {};
}

// default template
return defaultTemplate;
},
Expand Down
13 changes: 13 additions & 0 deletions lib/deploy/events/apiGateway/methods.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,19 @@ describe('#methods()', () => {
.ResponseParameters['method.response.header.Access-Control-Allow-Origin'])
.to.equal('\'*\'');
});

it('should change passthroughBehavior and action when action is set',
() => {
expect(serverlessStepFunctions.getMethodIntegration('stateMachine', 'custom', {
action: 'DescribeExecution',
}).Properties.Integration.PassthroughBehavior)
.to.equal('WHEN_NO_TEMPLATES');

expect(serverlessStepFunctions.getMethodIntegration('stateMachine', 'custom', {
action: 'DescribeExecution',
}).Properties.Integration.Uri['Fn::Join'][1][2])
.to.equal(':states:action/DescribeExecution');
});
});

describe('#getIntegrationRequestTemplates()', () => {
Expand Down

0 comments on commit 479d003

Please sign in to comment.