From ce6e0df276529da489dff167bbd2e26f34ef212a Mon Sep 17 00:00:00 2001 From: horike37 Date: Fri, 12 Jan 2018 09:52:33 +0900 Subject: [PATCH 01/29] improve apigw doc --- docs/providers/aws/events/apigateway.md | 92 ++++++++++++------------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/docs/providers/aws/events/apigateway.md b/docs/providers/aws/events/apigateway.md index cd281ac7b..8dfeb5572 100644 --- a/docs/providers/aws/events/apigateway.md +++ b/docs/providers/aws/events/apigateway.md @@ -12,6 +12,32 @@ layout: Doc # API Gateway +- [Lambda Proxy Integration](#lambda-proxy-integration) + - [Simple HTTP Endpoint](#simple-http-endpoint) + - [Example "LAMBDA-PROXY" event (default)](#example-lambda-proxy-event-default) + - [HTTP Endpoint with Extended Options](#http-endpoint-with-extended-options) + - [Enabling CORS](#enabling-cors) + - [HTTP Endpoints with `AWS_IAM` Authorizers](#http-endpoints-with-awsiam-authorizers) + - [HTTP Endpoints with Custom Authorizers](#http-endpoints-with-custom-authorizers) + - [Catching Exceptions In Your Lambda Function](#catching-exceptions-in-your-lambda-function) + - [Setting API keys for your Rest API](#setting-api-keys-for-your-rest-api) + - [Request Parameters](#request-parameters) +- [Lambda Integration](#lambda-integration) + - [Example "LAMBDA" event (before customization)](#example-lambda-event-before-customization) + - [Request templates](#request-templates) + - [Default Request Templates](#default-request-templates) + - [Custom Request Templates](#custom-request-templates) + - [Pass Through Behavior](#pass-through-behavior) + - [Responses](#responses) + - [Custom Response Headers](#custom-response-headers) + - [Custom Response Templates](#custom-response-templates) + - [Status codes](#status-codes) + - [Available Status Codes](#available-status-codes) + - [Using Status Codes](#using-status-codes) + - [Custom Status Codes](#custom-status-codes) +- [Setting an HTTP Proxy on API Gateway](#setting-an-http-proxy-on-api-gateway) +- [Share API Gateway and API Resources](#share-api-gateway-and-api-resources) + _Are you looking for tutorials on using API Gateway? Check out the following resources:_ > - [Add a custom domain for your API Gateway](https://serverless.com/blog/serverless-api-gateway-domain/) @@ -633,39 +659,7 @@ See the [api gateway documentation](https://docs.aws.amazon.com/apigateway/lates **Notes:** - A missing/empty request Content-Type is considered to be the API Gateway default (`application/json`) - - [[Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/apigateway)](#read-this-on-the-main-serverless-docs-sitehttpswwwserverlesscomframeworkdocsprovidersawseventsapigateway) - - [[Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/apigateway)](#read-this-on-the-main-serverless-docs-sitehttpswwwserverlesscomframeworkdocsprovidersawseventsapigateway) - - [[Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/apigateway)](#read-this-on-the-main-serverless-docs-sitehttpswwwserverlesscomframeworkdocsprovidersawseventsapigateway) - - [[Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/apigateway)](#read-this-on-the-main-serverless-docs-sitehttpswwwserverlesscomframeworkdocsprovidersawseventsapigateway) - - [[Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/apigateway)](#read-this-on-the-main-serverless-docs-sitehttpswwwserverlesscomframeworkdocsprovidersawseventsapigateway) - - [[Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/apigateway)](#read-this-on-the-main-serverless-docs-sitehttpswwwserverlesscomframeworkdocsprovidersawseventsapigateway) - - [[Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/apigateway)](#read-this-on-the-main-serverless-docs-sitehttpswwwserverlesscomframeworkdocsprovidersawseventsapigateway) -- [API Gateway](#api-gateway) - - [Lambda Proxy Integration](#lambda-proxy-integration) - - [Simple HTTP Endpoint](#simple-http-endpoint) - - [Example "LAMBDA-PROXY" event (default)](#example-lambda-proxy-event-default) - - [HTTP Endpoint with Extended Options](#http-endpoint-with-extended-options) - - [Enabling CORS](#enabling-cors) - - [HTTP Endpoints with `AWS_IAM` Authorizers](#http-endpoints-with-awsiam-authorizers) - - [HTTP Endpoints with Custom Authorizers](#http-endpoints-with-custom-authorizers) - - [Catching Exceptions In Your Lambda Function](#catching-exceptions-in-your-lambda-function) - - [Setting API keys for your Rest API](#setting-api-keys-for-your-rest-api) - - [Request Parameters](#request-parameters) - - [Lambda Integration](#lambda-integration) - - [Example "LAMBDA" event (before customization)](#example-lambda-event-before-customization) - - [Request templates](#request-templates) - - [Default Request Templates](#default-request-templates) - - [Custom Request Templates](#custom-request-templates) - - [Pass Through Behavior](#pass-through-behavior) - - [Responses](#responses) - - [Custom Response Headers](#custom-response-headers) - - [Custom Response Templates](#custom-response-templates) - - [Status codes](#status-codes) - - [Available Status Codes](#available-status-codes) - - [Using Status Codes](#using-status-codes) - - [Custom Status Codes](#custom-status-codes) - - [Setting an HTTP Proxy on API Gateway](#setting-an-http-proxy-on-api-gateway) - - [Share API Gateway and API Resources](#share-api-gateway-and-api-resources) +- API Gateway docs refer to "WHEN_NO_TEMPLATE" (singular), but this will fail during creation as the actual value should be "WHEN_NO_TEMPLATES" (plural) ### Responses @@ -867,7 +861,7 @@ As you application grows, you will have idea to break it out into multiple servi ```yml service: service-name -provider: +provider: name: aws apiGateway: restApiId: xxxxxxxxxx # REST API resource ID. Default is generated by the framework @@ -878,13 +872,13 @@ functions: ``` -In case the application has many chilren and grandchildren paths, you also want to break them out into smaller services. +In case the application has many chilren and grandchildren paths, you also want to break them out into smaller services. ```yml service: service-a -provider: +provider: apiGateway: - restApiId: xxxxxxxxxx + restApiId: xxxxxxxxxx restApiRootResourceId: xxxxxxxxxx functions: @@ -898,10 +892,10 @@ functions: ```yml service: service-b -provider: +provider: apiGateway: - restApiId: xxxxxxxxxx - restApiRootResourceId: xxxxxxxxxx + restApiId: xxxxxxxxxx + restApiRootResourceId: xxxxxxxxxx functions: create: @@ -916,13 +910,13 @@ They reference the same parent path `/posts`. Cloudformation will throw error if ```yml service: service-a -provider: +provider: apiGateway: - restApiId: xxxxxxxxxx + restApiId: xxxxxxxxxx restApiRootResourceId: xxxxxxxxxx restApiResources: /posts: xxxxxxxxxx - + functions: ... @@ -930,10 +924,10 @@ functions: ```yml service: service-b -provider: +provider: apiGateway: - restApiId: xxxxxxxxxx - restApiRootResourceId: xxxxxxxxxx + restApiId: xxxxxxxxxx + restApiRootResourceId: xxxxxxxxxx restApiResources: /posts: xxxxxxxxxx @@ -946,14 +940,14 @@ You can define more than one path resource. Otherwise, serverless will generate ```yml service: service-a -provider: +provider: apiGateway: - restApiId: xxxxxxxxxx + restApiId: xxxxxxxxxx # restApiRootResourceId: xxxxxxxxxx # Optional restApiResources: /posts: xxxxxxxxxx /categories: xxxxxxxxx - + functions: listPosts: From f981c1c7701ef5387203021bc2f9116d21b134ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Mon, 22 Jan 2018 13:16:43 -0200 Subject: [PATCH 02/29] WIP --- lib/plugins/aws/deploy/lib/uploadArtifacts.js | 54 ++++++++++--------- .../aws/deploy/lib/uploadArtifacts.test.js | 46 +++++++++++++--- 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.js index a6b21e770..2c9baa953 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.js @@ -2,6 +2,7 @@ /* eslint-disable no-use-before-define */ +const _ = require('lodash'); const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); @@ -80,36 +81,37 @@ module.exports = { }, uploadFunctions() { - let shouldUploadService = false; this.serverless.cli.log('Uploading artifacts...'); + const functionNames = this.serverless.service.getAllFunctions(); - return BbPromise.map(functionNames, (name) => { - const functionArtifactFileName = this.provider.naming.getFunctionArtifactName(name); - const functionObject = this.serverless.service.getFunction(name); - functionObject.package = functionObject.package || {}; - let artifactFilePath = functionObject.package.artifact || - this.serverless.service.package.artifact; - if (!artifactFilePath || - (this.serverless.service.artifact && !functionObject.package.artifact)) { - if (this.serverless.service.package.individually || functionObject.package.individually) { - const artifactFileName = functionArtifactFileName; - artifactFilePath = path.join(this.packagePath, artifactFileName); - return this.uploadZipFile(artifactFilePath); + const artifactFilePaths = _.uniq( + _.map(functionNames, (name) => { + const functionArtifactFileName = this.provider.naming.getFunctionArtifactName(name); + const functionObject = this.serverless.service.getFunction(name); + functionObject.package = functionObject.package || {}; + const artifact = functionObject.package.artifact || + this.serverless.service.package.artifact; + console.log(`artifactFilePath ${JSON.stringify(artifact, null, 2)}`) + if (!artifact || + (this.serverless.service.artifact && !functionObject.package.artifact)) { + if (this.serverless.service.package.individually || functionObject.package.individually) { + const artifactFileName = functionArtifactFileName; + return path.join(this.packagePath, artifactFileName); + } + return this.provider.naming.getServiceArtifactName(); } - shouldUploadService = true; - return BbPromise.resolve(); - } + return artifact; + }) + ); + + console.log(`artifactFileNames ${JSON.stringify(artifactFilePaths, null, 2)}`) + + return BbPromise.map(artifactFilePaths, (artifactFilePath) => { + const stats = fs.statSync(artifactFilePath); + this.serverless.cli.log(`Uploading service .zip file to S3 (${filesize(stats.size)})...`); return this.uploadZipFile(artifactFilePath); - }, { concurrency: 3 }).then(() => { - if (shouldUploadService) { - const artifactFileName = this.provider.naming.getServiceArtifactName(); - const artifactFilePath = path.join(this.packagePath, artifactFileName); - const stats = fs.statSync(artifactFilePath); - this.serverless.cli.log(`Uploading service .zip file to S3 (${filesize(stats.size)})...`); - return this.uploadZipFile(artifactFilePath); - } - return BbPromise.resolve(); - }); + }, { concurrency: 3 } + ); }, }; diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js index 7af45d186..9cd72e81e 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js @@ -230,23 +230,57 @@ describe('uploadArtifacts', () => { }); }); - describe('#uploadFunctions()', () => { + describe.only('#uploadFunctions()', () => { + beforeEach(() => { + sinon.stub(fs, 'statSync').returns({ size: 1024 }); + }); + + afterEach(() => { + fs.statSync.restore(); + }); + it('should upload the service artifact file to the S3 bucket', () => { awsDeploy.serverless.config.servicePath = 'some/path'; awsDeploy.serverless.service.service = 'new-service'; - sinon.stub(fs, 'statSync').returns({ size: 0 }); - const uploadZipFileStub = sinon .stub(awsDeploy, 'uploadZipFile').resolves(); return awsDeploy.uploadFunctions().then(() => { expect(uploadZipFileStub.calledOnce).to.be.equal(true); - fs.statSync.restore(); awsDeploy.uploadZipFile.restore(); }); }); + // it.only('should upload a single .zip file to the S3 bucket', () => { + // awsDeploy.serverless.config.servicePath = 'some/path'; + // awsDeploy.serverless.service.service = 'new-service'; + // awsDeploy.serverless.service.functions = { + // first: { + // handler: 'first-handler', + // }, + // second: { + // handler: 'second-handler', + // }, + + // }; + + // sinon.stub(fs, 'statSync').returns({ size: 0 }); + + // const uploadZipFileStub = sinon + // .stub(awsDeploy, 'uploadZipFile').resolves(); + + // return awsDeploy.uploadFunctions().then(() => { + // expect(uploadZipFileStub.calledOnce).to.be.equal(true); + // console.log(`uploadZipFileStub.args ${JSON.stringify(uploadZipFileStub.args, null, 2)}`) + // expect(uploadZipFileStub.args[0][0]) + // .to.be.equal(awsDeploy.serverless.service.functions.first.package.artifact); + // expect(uploadZipFileStub.args[1][0]) + // .to.be.equal(awsDeploy.serverless.service.functions.second.package.artifact); + // awsDeploy.uploadZipFile.restore(); + // }); + // }); + it('should upload the function .zip files to the S3 bucket', () => { awsDeploy.serverless.service.package.individually = true; awsDeploy.serverless.service.functions = { @@ -292,7 +326,6 @@ describe('uploadArtifacts', () => { const uploadZipFileStub = sinon .stub(awsDeploy, 'uploadZipFile').resolves(); - sinon.stub(fs, 'statSync').returns({ size: 1024 }); return awsDeploy.uploadFunctions().then(() => { expect(uploadZipFileStub.calledTwice).to.be.equal(true); @@ -301,7 +334,6 @@ describe('uploadArtifacts', () => { expect(uploadZipFileStub.args[1][0]) .to.be.equal(awsDeploy.serverless.service.package.artifact); awsDeploy.uploadZipFile.restore(); - fs.statSync.restore(); }); }); @@ -309,7 +341,6 @@ describe('uploadArtifacts', () => { awsDeploy.serverless.config.servicePath = 'some/path'; awsDeploy.serverless.service.service = 'new-service'; - sinon.stub(fs, 'statSync').returns({ size: 1024 }); sinon.stub(awsDeploy, 'uploadZipFile').resolves(); sinon.spy(awsDeploy.serverless.cli, 'log'); @@ -317,7 +348,6 @@ describe('uploadArtifacts', () => { const expected = 'Uploading service .zip file to S3 (1 KB)...'; expect(awsDeploy.serverless.cli.log.calledWithExactly(expected)).to.be.equal(true); - fs.statSync.restore(); awsDeploy.uploadZipFile.restore(); }); }); From 3e7f736abcb02ec5effc6f0938c194c82c3b0354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Mon, 22 Jan 2018 14:58:34 -0200 Subject: [PATCH 03/29] Fix concurrency upload --- lib/plugins/aws/deploy/lib/uploadArtifacts.js | 5 +-- .../aws/deploy/lib/uploadArtifacts.test.js | 45 +++++++++---------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.js index 2c9baa953..e2ce3e4d1 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.js @@ -91,7 +91,7 @@ module.exports = { functionObject.package = functionObject.package || {}; const artifact = functionObject.package.artifact || this.serverless.service.package.artifact; - console.log(`artifactFilePath ${JSON.stringify(artifact, null, 2)}`) + if (!artifact || (this.serverless.service.artifact && !functionObject.package.artifact)) { if (this.serverless.service.package.individually || functionObject.package.individually) { @@ -100,12 +100,11 @@ module.exports = { } return this.provider.naming.getServiceArtifactName(); } + return artifact; }) ); - console.log(`artifactFileNames ${JSON.stringify(artifactFilePaths, null, 2)}`) - return BbPromise.map(artifactFilePaths, (artifactFilePath) => { const stats = fs.statSync(artifactFilePath); this.serverless.cli.log(`Uploading service .zip file to S3 (${filesize(stats.size)})...`); diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js index 9cd72e81e..9f50614a0 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js @@ -252,34 +252,29 @@ describe('uploadArtifacts', () => { }); }); - // it.only('should upload a single .zip file to the S3 bucket', () => { - // awsDeploy.serverless.config.servicePath = 'some/path'; - // awsDeploy.serverless.service.service = 'new-service'; - // awsDeploy.serverless.service.functions = { - // first: { - // handler: 'first-handler', - // }, - // second: { - // handler: 'second-handler', - // }, + it('should upload a single .zip file to the S3 bucket', () => { + awsDeploy.serverless.config.servicePath = 'some/path'; + awsDeploy.serverless.service.service = 'new-service'; + awsDeploy.serverless.service.functions = { + first: { + handler: 'first-handler', + }, + second: { + handler: 'second-handler', + }, - // }; + }; - // sinon.stub(fs, 'statSync').returns({ size: 0 }); + const uploadZipFileStub = sinon + .stub(awsDeploy, 'uploadZipFile').resolves(); - // const uploadZipFileStub = sinon - // .stub(awsDeploy, 'uploadZipFile').resolves(); - - // return awsDeploy.uploadFunctions().then(() => { - // expect(uploadZipFileStub.calledOnce).to.be.equal(true); - // console.log(`uploadZipFileStub.args ${JSON.stringify(uploadZipFileStub.args, null, 2)}`) - // expect(uploadZipFileStub.args[0][0]) - // .to.be.equal(awsDeploy.serverless.service.functions.first.package.artifact); - // expect(uploadZipFileStub.args[1][0]) - // .to.be.equal(awsDeploy.serverless.service.functions.second.package.artifact); - // awsDeploy.uploadZipFile.restore(); - // }); - // }); + return awsDeploy.uploadFunctions().then(() => { + expect(uploadZipFileStub.calledOnce).to.be.equal(true); + expect(uploadZipFileStub.args[0][0]) + .to.be.equal(`${awsDeploy.serverless.service.service}.zip`); + awsDeploy.uploadZipFile.restore(); + }); + }); it('should upload the function .zip files to the S3 bucket', () => { awsDeploy.serverless.service.package.individually = true; From d059a3c448cc7d3fdf8f4477a064fc4754cac613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Mon, 22 Jan 2018 14:59:35 -0200 Subject: [PATCH 04/29] Improve spec description --- lib/plugins/aws/deploy/lib/uploadArtifacts.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js index 9f50614a0..5d25bc71c 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js @@ -252,7 +252,7 @@ describe('uploadArtifacts', () => { }); }); - it('should upload a single .zip file to the S3 bucket', () => { + it('should upload a single .zip file to the S3 bucket when not packaging individually', () => { awsDeploy.serverless.config.servicePath = 'some/path'; awsDeploy.serverless.service.service = 'new-service'; awsDeploy.serverless.service.functions = { From 29e13014db6f489f00d44992bf6375e2342da410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Mon, 22 Jan 2018 15:32:02 -0200 Subject: [PATCH 05/29] artifactFilePath makes more sense --- lib/plugins/aws/deploy/lib/uploadArtifacts.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.js index e2ce3e4d1..1d2a59862 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.js @@ -89,10 +89,10 @@ module.exports = { const functionArtifactFileName = this.provider.naming.getFunctionArtifactName(name); const functionObject = this.serverless.service.getFunction(name); functionObject.package = functionObject.package || {}; - const artifact = functionObject.package.artifact || + const artifactFilePath = functionObject.package.artifact || this.serverless.service.package.artifact; - if (!artifact || + if (!artifactFilePath || (this.serverless.service.artifact && !functionObject.package.artifact)) { if (this.serverless.service.package.individually || functionObject.package.individually) { const artifactFileName = functionArtifactFileName; @@ -101,7 +101,7 @@ module.exports = { return this.provider.naming.getServiceArtifactName(); } - return artifact; + return artifactFilePath; }) ); From cc0fee96b7909a0ffc1edfa6dc8be2b2bf10aba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Mon, 22 Jan 2018 22:15:57 -0200 Subject: [PATCH 06/29] Adding spec to test that duplicates uploads --- .../aws/deploy/lib/uploadArtifacts.test.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js index 5d25bc71c..8c3f0eb70 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js @@ -230,7 +230,7 @@ describe('uploadArtifacts', () => { }); }); - describe.only('#uploadFunctions()', () => { + describe('#uploadFunctions()', () => { beforeEach(() => { sinon.stub(fs, 'statSync').returns({ size: 1024 }); }); @@ -253,16 +253,17 @@ describe('uploadArtifacts', () => { }); it('should upload a single .zip file to the S3 bucket when not packaging individually', () => { - awsDeploy.serverless.config.servicePath = 'some/path'; - awsDeploy.serverless.service.service = 'new-service'; awsDeploy.serverless.service.functions = { first: { - handler: 'first-handler', + package: { + artifact: 'artifact.zip', + }, }, second: { - handler: 'second-handler', + package: { + artifact: 'artifact.zip', + }, }, - }; const uploadZipFileStub = sinon @@ -270,8 +271,7 @@ describe('uploadArtifacts', () => { return awsDeploy.uploadFunctions().then(() => { expect(uploadZipFileStub.calledOnce).to.be.equal(true); - expect(uploadZipFileStub.args[0][0]) - .to.be.equal(`${awsDeploy.serverless.service.service}.zip`); + expect(uploadZipFileStub.args[0][0]).to.be.equal('artifact.zip'); awsDeploy.uploadZipFile.restore(); }); }); From ede4824c97329af0bc5607960453bebb9d1d1bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Mon, 22 Jan 2018 22:30:53 -0200 Subject: [PATCH 07/29] Improve tests --- .../aws/deploy/lib/uploadArtifacts.test.js | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js index 8c3f0eb70..b743a0db1 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js @@ -231,24 +231,24 @@ describe('uploadArtifacts', () => { }); describe('#uploadFunctions()', () => { + let uploadZipFileStub; + beforeEach(() => { sinon.stub(fs, 'statSync').returns({ size: 1024 }); + uploadZipFileStub = sinon.stub(awsDeploy, 'uploadZipFile').resolves(); }); afterEach(() => { fs.statSync.restore(); + uploadZipFileStub.restore(); }); it('should upload the service artifact file to the S3 bucket', () => { awsDeploy.serverless.config.servicePath = 'some/path'; awsDeploy.serverless.service.service = 'new-service'; - const uploadZipFileStub = sinon - .stub(awsDeploy, 'uploadZipFile').resolves(); - return awsDeploy.uploadFunctions().then(() => { expect(uploadZipFileStub.calledOnce).to.be.equal(true); - awsDeploy.uploadZipFile.restore(); }); }); @@ -266,13 +266,9 @@ describe('uploadArtifacts', () => { }, }; - const uploadZipFileStub = sinon - .stub(awsDeploy, 'uploadZipFile').resolves(); - return awsDeploy.uploadFunctions().then(() => { expect(uploadZipFileStub.calledOnce).to.be.equal(true); expect(uploadZipFileStub.args[0][0]).to.be.equal('artifact.zip'); - awsDeploy.uploadZipFile.restore(); }); }); @@ -291,16 +287,12 @@ describe('uploadArtifacts', () => { }, }; - const uploadZipFileStub = sinon - .stub(awsDeploy, 'uploadZipFile').resolves(); - return awsDeploy.uploadFunctions().then(() => { expect(uploadZipFileStub.calledTwice).to.be.equal(true); expect(uploadZipFileStub.args[0][0]) .to.be.equal(awsDeploy.serverless.service.functions.first.package.artifact); expect(uploadZipFileStub.args[1][0]) .to.be.equal(awsDeploy.serverless.service.functions.second.package.artifact); - awsDeploy.uploadZipFile.restore(); }); }); @@ -319,16 +311,12 @@ describe('uploadArtifacts', () => { }, }; - const uploadZipFileStub = sinon - .stub(awsDeploy, 'uploadZipFile').resolves(); - return awsDeploy.uploadFunctions().then(() => { expect(uploadZipFileStub.calledTwice).to.be.equal(true); expect(uploadZipFileStub.args[0][0]) .to.be.equal(awsDeploy.serverless.service.functions.first.package.artifact); expect(uploadZipFileStub.args[1][0]) .to.be.equal(awsDeploy.serverless.service.package.artifact); - awsDeploy.uploadZipFile.restore(); }); }); @@ -336,14 +324,11 @@ describe('uploadArtifacts', () => { awsDeploy.serverless.config.servicePath = 'some/path'; awsDeploy.serverless.service.service = 'new-service'; - sinon.stub(awsDeploy, 'uploadZipFile').resolves(); sinon.spy(awsDeploy.serverless.cli, 'log'); return awsDeploy.uploadFunctions().then(() => { const expected = 'Uploading service .zip file to S3 (1 KB)...'; expect(awsDeploy.serverless.cli.log.calledWithExactly(expected)).to.be.equal(true); - - awsDeploy.uploadZipFile.restore(); }); }); }); From 0fe3efefe9bd2554a4ac2b4514ddca582476f06a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Tue, 23 Jan 2018 08:55:55 -0200 Subject: [PATCH 08/29] Adding verification to expected file name --- lib/plugins/aws/deploy/lib/uploadArtifacts.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js index b881a1298..306610af5 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.test.js @@ -243,6 +243,7 @@ describe('uploadArtifacts', () => { return awsDeploy.uploadFunctions().then(() => { expect(uploadZipFileStub.calledOnce).to.be.equal(true); + expect(uploadZipFileStub.args[0][0]).to.be.equal('new-service.zip'); }); }); From 35ec7251dc6f5cb250973c2164201aa739b1bff4 Mon Sep 17 00:00:00 2001 From: Stuart Lang Date: Tue, 16 Jan 2018 00:52:40 +0000 Subject: [PATCH 09/29] Uprade aws-csharp to .NET Core 2.0 --- .gitignore | 4 ++++ docker-compose.yml | 4 ++-- .../examples/hello-world/csharp/csharp.csproj | 7 ++++--- .../examples/hello-world/csharp/serverless.yml | 4 ++-- lib/plugins/create/create.test.js | 1 - .../templates/aws-csharp/.vs/aws-csharp/v15/.suo | Bin 4608 -> 0 bytes .../templates/aws-csharp/aws-csharp.csproj | 5 +++-- .../create/templates/aws-csharp/build.cmd | 3 +-- lib/plugins/create/templates/aws-csharp/build.sh | 9 +-------- .../create/templates/aws-csharp/global.json | 5 ----- .../create/templates/aws-csharp/serverless.yml | 4 ++-- tests/templates/test_all_templates | 2 +- 12 files changed, 20 insertions(+), 28 deletions(-) delete mode 100644 lib/plugins/create/templates/aws-csharp/.vs/aws-csharp/v15/.suo delete mode 100644 lib/plugins/create/templates/aws-csharp/global.json diff --git a/.gitignore b/.gitignore index 4d98e9617..750b1d90b 100755 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,7 @@ jest # VIM *.swp + +# DotNet +bin/ +obj/ diff --git a/docker-compose.yml b/docker-compose.yml index f9ae71b3e..162efc044 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -56,7 +56,7 @@ services: volumes: - ./tmp/serverless-integration-test-aws-scala-sbt:/app aws-csharp: - image: microsoft/dotnet:1.0.4-sdk + image: microsoft/dotnet:2.0.5-sdk-2.1.4 volumes: - ./tmp/serverless-integration-test-aws-csharp:/app aws-fsharp: @@ -89,7 +89,7 @@ services: - ./tmp/serverless-integration-test-spotinst-ruby:/app spotinst-java8: image: maven:3-jdk-8 - volumes: + volumes: - ./tmp/serverless-integration-test-spotinst-java8:/app webtasks-nodejs: image: node:6.10.3 diff --git a/docs/providers/aws/examples/hello-world/csharp/csharp.csproj b/docs/providers/aws/examples/hello-world/csharp/csharp.csproj index c0d2e4c69..9cedd48b6 100644 --- a/docs/providers/aws/examples/hello-world/csharp/csharp.csproj +++ b/docs/providers/aws/examples/hello-world/csharp/csharp.csproj @@ -1,9 +1,10 @@  - netcoreapp1.0 + netcoreapp2.0 + true CsharpHandlers - csharp + aws-csharp @@ -12,7 +13,7 @@ - + diff --git a/docs/providers/aws/examples/hello-world/csharp/serverless.yml b/docs/providers/aws/examples/hello-world/csharp/serverless.yml index 3e622e1f5..298ded8e2 100644 --- a/docs/providers/aws/examples/hello-world/csharp/serverless.yml +++ b/docs/providers/aws/examples/hello-world/csharp/serverless.yml @@ -19,7 +19,7 @@ service: aws-csharp # NOTE: update this with your service name provider: name: aws - runtime: dotnetcore1.0 + runtime: dotnetcore2.0 # you can overwrite defaults here # stage: dev @@ -47,7 +47,7 @@ provider: # you can add packaging information here package: - artifact: bin/release/netcoreapp1.0/deploy-package.zip + artifact: bin/release/netcoreapp2.0/deploy-package.zip # exclude: # - exclude-me.js # - exclude-me-dir/** diff --git a/lib/plugins/create/create.test.js b/lib/plugins/create/create.test.js index 3bba193fa..dd4107729 100644 --- a/lib/plugins/create/create.test.js +++ b/lib/plugins/create/create.test.js @@ -143,7 +143,6 @@ describe('Create', () => { expect(dirContent).to.include('aws-csharp.csproj'); expect(dirContent).to.include('build.cmd'); expect(dirContent).to.include('build.sh'); - expect(dirContent).to.include('global.json'); }); }); diff --git a/lib/plugins/create/templates/aws-csharp/.vs/aws-csharp/v15/.suo b/lib/plugins/create/templates/aws-csharp/.vs/aws-csharp/v15/.suo deleted file mode 100644 index 9c228fb45c0cd90da38bf0643fa46764ffba39a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4608 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*3aa1_1`J97ycn|Ns9%QXn>vISPhQ2m~?Y z17Qh+0)s0<9*{0#s02kN(LjuW6&~kI1avjbw?10@{1PKOP~8D&VhRA-n9q>K;0d%n z4ajn3s32epsI;Bogo;=PXyvruv?6w z>Tppi3`~q5uP_5KvG#+^+5{qifROzr5M?+?p#3EKALQ08P!mCU_bD26~~4~WKTIg$h@{ZldjlbruRPJ!irBxjM$ z1o;~VNHqke4^|G0=6hI(j0_r-4MBNlG~P!>e53oahtZkAiXny}9@z591h#rIfbF3q zAio&c{wZQ81Cu#GvKR*SV*W%Cp1S-wYT?`UKfV-d7 z81*M@ir@WKO-J!7w+ljMltoMkAm@J;paxLgJX#i@r@7(FAL{wPZ_t!q$qc!`a%}ga da_-3mhvH^ - netcoreapp1.0 + netcoreapp2.0 + true CsharpHandlers aws-csharp @@ -12,7 +13,7 @@ - + diff --git a/lib/plugins/create/templates/aws-csharp/build.cmd b/lib/plugins/create/templates/aws-csharp/build.cmd index f33ae0254..daf426e15 100644 --- a/lib/plugins/create/templates/aws-csharp/build.cmd +++ b/lib/plugins/create/templates/aws-csharp/build.cmd @@ -1,2 +1 @@ -dotnet restore -dotnet lambda package --configuration release --framework netcoreapp1.0 --output-package bin/release/netcoreapp1.0/deploy-package.zip \ No newline at end of file +dotnet lambda package --configuration release --framework netcoreapp2.0 --output-package bin/release/netcoreapp2.0/deploy-package.zip diff --git a/lib/plugins/create/templates/aws-csharp/build.sh b/lib/plugins/create/templates/aws-csharp/build.sh index 892b0f289..ea638246b 100755 --- a/lib/plugins/create/templates/aws-csharp/build.sh +++ b/lib/plugins/create/templates/aws-csharp/build.sh @@ -1,10 +1,3 @@ #!/bin/bash -#install zip -apt-get -qq update -apt-get -qq -y install zip - -dotnet restore - -#create deployment package -dotnet lambda package --configuration release --framework netcoreapp1.0 --output-package bin/release/netcoreapp1.0/deploy-package.zip +dotnet lambda package --configuration release --framework netcoreapp2.0 --output-package bin/release/netcoreapp2.0/deploy-package.zip diff --git a/lib/plugins/create/templates/aws-csharp/global.json b/lib/plugins/create/templates/aws-csharp/global.json deleted file mode 100644 index 8af244a46..000000000 --- a/lib/plugins/create/templates/aws-csharp/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "1.0.4" - } -} diff --git a/lib/plugins/create/templates/aws-csharp/serverless.yml b/lib/plugins/create/templates/aws-csharp/serverless.yml index fb55c7aac..fcecbd634 100644 --- a/lib/plugins/create/templates/aws-csharp/serverless.yml +++ b/lib/plugins/create/templates/aws-csharp/serverless.yml @@ -19,7 +19,7 @@ service: aws-csharp # NOTE: update this with your service name provider: name: aws - runtime: dotnetcore1.0 + runtime: dotnetcore2.0 # you can overwrite defaults here # stage: dev @@ -47,7 +47,7 @@ provider: # you can add packaging information here package: - artifact: bin/release/netcoreapp1.0/deploy-package.zip + artifact: bin/release/netcoreapp2.0/deploy-package.zip # exclude: # - exclude-me.js # - exclude-me-dir/** diff --git a/tests/templates/test_all_templates b/tests/templates/test_all_templates index 79bbebd55..63a7a0902 100755 --- a/tests/templates/test_all_templates +++ b/tests/templates/test_all_templates @@ -8,7 +8,7 @@ function integration-test { $DIR/integration-test-template $@ } -integration-test aws-csharp 'apt-get -qq update && apt-get -qq -y install zip && dotnet restore && dotnet lambda package --configuration release --framework netcoreapp1.0 --output-package bin/release/netcoreapp1.0/deploy-package.zip' +integration-test aws-csharp 'dotnet lambda package --configuration release --framework netcoreapp2.0 --output-package bin/release/netcoreapp2.0/deploy-package.zip' integration-test aws-fsharp 'apt-get -qq update && apt-get -qq -y install zip && dotnet restore && dotnet lambda package --configuration release --framework netcoreapp1.0 --output-package bin/release/netcoreapp1.0/deploy-package.zip' integration-test aws-groovy-gradle ./gradlew build integration-test aws-java-gradle ./gradlew build From e6692aa1fd2b1cc57fee47af18451caf9b55d8df Mon Sep 17 00:00:00 2001 From: Kamesh Sampath Date: Thu, 22 Feb 2018 00:40:22 +0530 Subject: [PATCH 10/29] Resolving #4491 , adding support for java maven templates for OpenWhisk Signed-off-by: Kamesh Sampath --- lib/plugins/create/create.js | 1 + lib/plugins/create/create.test.js | 85 +++++++++++-------- .../templates/openwhisk-java-maven/.gitignore | 8 ++ .../templates/openwhisk-java-maven/pom.xml | 47 ++++++++++ .../openwhisk-java-maven/serverless.yml | 49 +++++++++++ .../main/java/com/example/FunctionApp.java | 31 +++++++ .../java/com/example/FunctionAppTest.java | 39 +++++++++ 7 files changed, 226 insertions(+), 34 deletions(-) create mode 100644 lib/plugins/create/templates/openwhisk-java-maven/.gitignore create mode 100644 lib/plugins/create/templates/openwhisk-java-maven/pom.xml create mode 100644 lib/plugins/create/templates/openwhisk-java-maven/serverless.yml create mode 100644 lib/plugins/create/templates/openwhisk-java-maven/src/main/java/com/example/FunctionApp.java create mode 100644 lib/plugins/create/templates/openwhisk-java-maven/src/test/java/com/example/FunctionAppTest.java diff --git a/lib/plugins/create/create.js b/lib/plugins/create/create.js index 84368002a..a5d60a8ba 100644 --- a/lib/plugins/create/create.js +++ b/lib/plugins/create/create.js @@ -34,6 +34,7 @@ const validTemplates = [ 'google-nodejs', 'kubeless-python', 'kubeless-nodejs', + 'openwhisk-java-maven', 'openwhisk-nodejs', 'openwhisk-php', 'openwhisk-python', diff --git a/lib/plugins/create/create.test.js b/lib/plugins/create/create.test.js index c0bf9d726..664578d02 100644 --- a/lib/plugins/create/create.test.js +++ b/lib/plugins/create/create.test.js @@ -264,9 +264,9 @@ describe('Create', () => { expect(dirContent).to.include('gradlew.bat'); expect(dirContent).to.include('package.json'); expect(dirContent).to.include(path.join('gradle', 'wrapper', - 'gradle-wrapper.jar')); + 'gradle-wrapper.jar')); expect(dirContent).to.include(path.join('gradle', 'wrapper', - 'gradle-wrapper.properties')); + 'gradle-wrapper.properties')); expect(dirContent).to.include(path.join('src', 'main', 'kotlin', 'com', 'serverless', 'Handler.kt')); expect(dirContent).to.include(path.join('src', 'main', 'kotlin', 'com', 'serverless', @@ -291,17 +291,17 @@ describe('Create', () => { expect(dirContent).to.include('gradlew'); expect(dirContent).to.include('gradlew.bat'); expect(dirContent).to.include(path.join('gradle', 'wrapper', - 'gradle-wrapper.jar')); + 'gradle-wrapper.jar')); expect(dirContent).to.include(path.join('gradle', 'wrapper', - 'gradle-wrapper.properties')); + 'gradle-wrapper.properties')); expect(dirContent).to.include(path.join('src', 'main', 'resources', - 'log4j.properties')); + 'log4j.properties')); expect(dirContent).to.include(path.join('src', 'main', 'java', - 'com', 'serverless', 'Handler.java')); + 'com', 'serverless', 'Handler.java')); expect(dirContent).to.include(path.join('src', 'main', 'java', - 'com', 'serverless', 'ApiGatewayResponse.java')); + 'com', 'serverless', 'ApiGatewayResponse.java')); expect(dirContent).to.include(path.join('src', 'main', 'java', - 'com', 'serverless', 'Response.java')); + 'com', 'serverless', 'Response.java')); expect(dirContent).to.include(path.join('.gitignore')); }); }); @@ -319,17 +319,17 @@ describe('Create', () => { expect(dirContent).to.include('gradlew'); expect(dirContent).to.include('gradlew.bat'); expect(dirContent).to.include(path.join('gradle', 'wrapper', - 'gradle-wrapper.jar')); + 'gradle-wrapper.jar')); expect(dirContent).to.include(path.join('gradle', 'wrapper', - 'gradle-wrapper.properties')); + 'gradle-wrapper.properties')); expect(dirContent).to.include(path.join('src', 'main', 'resources', - 'log4j.properties')); + 'log4j.properties')); expect(dirContent).to.include(path.join('src', 'main', 'groovy', - 'com', 'serverless', 'Handler.groovy')); + 'com', 'serverless', 'Handler.groovy')); expect(dirContent).to.include(path.join('src', 'main', 'groovy', - 'com', 'serverless', 'ApiGatewayResponse.groovy')); + 'com', 'serverless', 'ApiGatewayResponse.groovy')); expect(dirContent).to.include(path.join('src', 'main', 'groovy', - 'com', 'serverless', 'Response.groovy')); + 'com', 'serverless', 'Response.groovy')); expect(dirContent).to.include('.gitignore'); }); }); @@ -354,6 +354,23 @@ describe('Create', () => { }); }); + it('should generate scaffolding for "openwhisk-java-maven" template', () => { + process.chdir(tmpDir); + create.options.template = 'openwhisk-java-maven'; + + return create.create().then(() => { + const dirContent = walkDirSync(tmpDir) + .map(elem => elem.replace(path.join(tmpDir, path.sep), '')); + expect(dirContent).to.include('pom.xml'); + expect(dirContent).to.include(path.join('src', 'main', 'java', + 'com', 'example', 'FunctionApp.java')); + expect(dirContent).to.include(path.join('src', 'test', 'java', + 'com', 'example', 'FunctionAppTest.java')); + expect(dirContent).to.include('.gitignore'); + expect(dirContent).to.include('serverless.yml'); + }); + }); + it('should generate scaffolding for "openwhisk-nodejs" template', () => { process.chdir(tmpDir); create.options.template = 'openwhisk-nodejs'; @@ -509,7 +526,7 @@ describe('Create', () => { expect(dirContent).to.include('serverless.yml'); expect(dirContent).to.include('pom.xml'); expect(dirContent).to.include(path.join('src', 'main', 'java', - 'com', 'serverless', 'Handler.java')); + 'com', 'serverless', 'Handler.java')); expect(dirContent).to.include('.gitignore'); }); }); @@ -608,30 +625,30 @@ describe('Create', () => { }); it('should create a custom renamed service in the directory if using ' + - 'the "path" and "name" option', () => { - process.chdir(tmpDir); + 'the "path" and "name" option', () => { + process.chdir(tmpDir); - create.options.path = 'my-new-service'; - create.options.name = 'my-custom-new-service'; + create.options.path = 'my-new-service'; + create.options.name = 'my-custom-new-service'; - // using the nodejs template (this test is completely be independent from the template) - create.options.template = 'aws-nodejs'; + // using the nodejs template (this test is completely be independent from the template) + create.options.template = 'aws-nodejs'; - return create.create().then(() => { - const serviceDir = path.join(tmpDir, create.options.path); - const dirContent = fs.readdirSync(serviceDir); + return create.create().then(() => { + const serviceDir = path.join(tmpDir, create.options.path); + const dirContent = fs.readdirSync(serviceDir); - // check if files are created in the correct directory - expect(dirContent).to.include('serverless.yml'); - expect(dirContent).to.include('handler.js'); + // check if files are created in the correct directory + expect(dirContent).to.include('serverless.yml'); + expect(dirContent).to.include('handler.js'); - // check if the service was renamed - const serverlessYmlfileContent = fse - .readFileSync(path.join(serviceDir, 'serverless.yml')).toString(); + // check if the service was renamed + const serverlessYmlfileContent = fse + .readFileSync(path.join(serviceDir, 'serverless.yml')).toString(); - expect((/service: my-custom-new-service/).test(serverlessYmlfileContent)).to.equal(true); + expect((/service: my-custom-new-service/).test(serverlessYmlfileContent)).to.equal(true); + }); }); - }); it('should throw error if there are existing template files in cwd', () => { process.chdir(tmpDir); @@ -640,7 +657,7 @@ describe('Create', () => { create.options.template = 'aws-nodejs'; create.options.path = ''; create.serverless.utils.copyDirContentsSync(path.join(create.serverless.config.serverlessPath, - 'plugins', 'create', 'templates', create.options.template), tmpDir); + 'plugins', 'create', 'templates', create.options.template), tmpDir); const dirContent = fs.readdirSync(tmpDir); @@ -749,7 +766,7 @@ describe('Create', () => { return create.create().then(() => { const dirContent = walkDirSync(tmpDir) - .map(elem => elem.replace(path.join(tmpDir, path.sep), '')); + .map(elem => elem.replace(path.join(tmpDir, path.sep), '')); expect(dirContent).to.include('serverless.yml'); expect(dirContent).to.include(path.join('hello', 'main.go')); diff --git a/lib/plugins/create/templates/openwhisk-java-maven/.gitignore b/lib/plugins/create/templates/openwhisk-java-maven/.gitignore new file mode 100644 index 000000000..186e57ceb --- /dev/null +++ b/lib/plugins/create/templates/openwhisk-java-maven/.gitignore @@ -0,0 +1,8 @@ +target +.vscode +.sts4-cache +.project +.classpath +.settings +*.iml +.idea diff --git a/lib/plugins/create/templates/openwhisk-java-maven/pom.xml b/lib/plugins/create/templates/openwhisk-java-maven/pom.xml new file mode 100644 index 000000000..95c0ac0ff --- /dev/null +++ b/lib/plugins/create/templates/openwhisk-java-maven/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + com.example + demo-function + 1.0-SNAPSHOT + https://openwhisk.apache.org/ + + UTF-8 + 1.8 + 1.8 + 2.8.2 + + + + com.google.code.gson + gson + ${gson.version} + + + junit + junit + 4.12 + test + + + + demo-function + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + + + + + diff --git a/lib/plugins/create/templates/openwhisk-java-maven/serverless.yml b/lib/plugins/create/templates/openwhisk-java-maven/serverless.yml new file mode 100644 index 000000000..e0ba29ac0 --- /dev/null +++ b/lib/plugins/create/templates/openwhisk-java-maven/serverless.yml @@ -0,0 +1,49 @@ +# Welcome to Serverless! +# +# This file is the main config file for your service. +# It's very minimal at this point and uses default values. +# You can always add more config options for more control. +# We've included some commented out config examples here. +# Just uncomment any of them to get that config option. +# +# For full config options, check the docs: +# docs.serverless.com +# +# Happy Coding! + +service: openwhisk-java-maven # NOTE: update this with your service name + +# Please ensure the serverless-openwhisk provider plugin is installed globally. +# $ npm install -g serverless-openwhisk +# ...before installing project dependencies to register this provider. +# $ npm install +provider: + name: openwhisk + runtime: java8 + +# you can add packaging information here +package: + artifact: target/demo-function.jar + +functions: + demo: + handler: com.example.FunctionApp + +# extend the framework using plugins listed here: +# https://github.com/serverless/plugins +plugins: + - "serverless-openwhisk" + +# you can define custom triggers and trigger feeds using the resources section. +# +#resources: +# triggers: +# my_trigger: +# parameters: +# hello: world +# alarm_trigger: +# parameters: +# hello: world +# feed: /whisk.system/alarms/alarm +# feed_parameters: +# cron: '*/8 * * * * *' diff --git a/lib/plugins/create/templates/openwhisk-java-maven/src/main/java/com/example/FunctionApp.java b/lib/plugins/create/templates/openwhisk-java-maven/src/main/java/com/example/FunctionApp.java new file mode 100644 index 000000000..f216f79c9 --- /dev/null +++ b/lib/plugins/create/templates/openwhisk-java-maven/src/main/java/com/example/FunctionApp.java @@ -0,0 +1,31 @@ +package com.example; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.google.gson.JsonObject; + +/** + * Hello FunctionApp + */ +public class FunctionApp { + public static JsonObject main(JsonObject args) { + JsonObject response = new JsonObject(); + response.addProperty("greetings", "Hello! Welcome to OpenWhisk"); + return response; + } +} diff --git a/lib/plugins/create/templates/openwhisk-java-maven/src/test/java/com/example/FunctionAppTest.java b/lib/plugins/create/templates/openwhisk-java-maven/src/test/java/com/example/FunctionAppTest.java new file mode 100644 index 000000000..20229769e --- /dev/null +++ b/lib/plugins/create/templates/openwhisk-java-maven/src/test/java/com/example/FunctionAppTest.java @@ -0,0 +1,39 @@ +package com.example; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import static org.junit.Assert.*; + +import com.google.gson.JsonObject; + +import org.junit.Test; + +/** + * Unit test for simple function. + */ +public class FunctionAppTest { + @Test + public void testFunction() { + JsonObject args = new JsonObject(); + JsonObject response = FunctionApp.main(args); + assertNotNull(response); + String greetings = response.getAsJsonPrimitive("greetings").getAsString(); + assertNotNull(greetings); + assertEquals("Hello! Welcome to OpenWhisk", greetings); + } +} From 67cbabc4c97741b1c1be2c18da63e305f56663e9 Mon Sep 17 00:00:00 2001 From: Yunspace Date: Tue, 27 Feb 2018 22:23:59 +1100 Subject: [PATCH 11/29] removed redudant code from docs. --- docker-compose.yml | 2 +- .../examples/hello-world/csharp/Handler.cs | 39 --------- .../aws/examples/hello-world/csharp/README.md | 2 +- .../examples/hello-world/csharp/csharp.csproj | 19 ----- .../hello-world/csharp/serverless.yml | 85 ------------------- .../create/templates/aws-csharp/build.cmd | 1 + .../create/templates/aws-csharp/build.sh | 1 + 7 files changed, 4 insertions(+), 145 deletions(-) delete mode 100644 docs/providers/aws/examples/hello-world/csharp/Handler.cs delete mode 100644 docs/providers/aws/examples/hello-world/csharp/csharp.csproj delete mode 100644 docs/providers/aws/examples/hello-world/csharp/serverless.yml diff --git a/docker-compose.yml b/docker-compose.yml index af78404f4..cbc760b01 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -56,7 +56,7 @@ services: volumes: - ./tmp/serverless-integration-test-aws-scala-sbt:/app aws-csharp: - image: microsoft/dotnet:2.0.5-sdk-2.1.4 + image: microsoft/dotnet:2.0-sdk volumes: - ./tmp/serverless-integration-test-aws-csharp:/app aws-fsharp: diff --git a/docs/providers/aws/examples/hello-world/csharp/Handler.cs b/docs/providers/aws/examples/hello-world/csharp/Handler.cs deleted file mode 100644 index cf4ff9549..000000000 --- a/docs/providers/aws/examples/hello-world/csharp/Handler.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Amazon.Lambda.Core; -using System; - -[assembly:LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))] - -namespace AwsDotnetCsharp -{ - public class Handler - { - public Response Hello(Request request) - { - return new Response("Go Serverless v1.0! Your function executed successfully!", request); - } - } - - public class Response - { - public string Message {get; set;} - public Request Request {get; set;} - - public Response(string message, Request request){ - Message = message; - Request = request; - } - } - - public class Request - { - public string Key1 {get; set;} - public string Key2 {get; set;} - public string Key3 {get; set;} - - public Request(string key1, string key2, string key3){ - Key1 = key1; - Key2 = key2; - Key3 = key3; - } - } -} diff --git a/docs/providers/aws/examples/hello-world/csharp/README.md b/docs/providers/aws/examples/hello-world/csharp/README.md index f230f7f88..371c7dc36 100644 --- a/docs/providers/aws/examples/hello-world/csharp/README.md +++ b/docs/providers/aws/examples/hello-world/csharp/README.md @@ -35,7 +35,7 @@ Using the `create` command we can specify one of the available [templates](https The `--path` or shorthand `-p` is the location to be created with the template service files. Change directories into this new folder. -## 2. Build using .NET CLI tools and create zip package +## 2. Build using .NET Core 2.X CLI tools and create zip package ``` # Linux or Mac OS diff --git a/docs/providers/aws/examples/hello-world/csharp/csharp.csproj b/docs/providers/aws/examples/hello-world/csharp/csharp.csproj deleted file mode 100644 index 9cedd48b6..000000000 --- a/docs/providers/aws/examples/hello-world/csharp/csharp.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - netcoreapp2.0 - true - CsharpHandlers - aws-csharp - - - - - - - - - - - - diff --git a/docs/providers/aws/examples/hello-world/csharp/serverless.yml b/docs/providers/aws/examples/hello-world/csharp/serverless.yml deleted file mode 100644 index 298ded8e2..000000000 --- a/docs/providers/aws/examples/hello-world/csharp/serverless.yml +++ /dev/null @@ -1,85 +0,0 @@ -# Welcome to Serverless! -# -# This file is the main config file for your service. -# It's very minimal at this point and uses default values. -# You can always add more config options for more control. -# We've included some commented out config examples here. -# Just uncomment any of them to get that config option. -# -# For full config options, check the docs: -# docs.serverless.com -# -# Happy Coding! - -service: aws-csharp # NOTE: update this with your service name - -# You can pin your service to only deploy with a specific Serverless version -# Check out our docs for more details -# frameworkVersion: "=X.X.X" - -provider: - name: aws - runtime: dotnetcore2.0 - -# you can overwrite defaults here -# stage: dev -# region: us-east-1 - -# you can add statements to the Lambda function's IAM Role here -# iamRoleStatements: -# - Effect: "Allow" -# Action: -# - "s3:ListBucket" -# Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] } -# - Effect: "Allow" -# Action: -# - "s3:PutObject" -# Resource: -# Fn::Join: -# - "" -# - - "arn:aws:s3:::" -# - "Ref" : "ServerlessDeploymentBucket" -# - "/*" - -# you can define service wide environment variables here -# environment: -# variable1: value1 - -# you can add packaging information here -package: - artifact: bin/release/netcoreapp2.0/deploy-package.zip -# exclude: -# - exclude-me.js -# - exclude-me-dir/** - -functions: - hello: - handler: CsharpHandlers::AwsDotnetCsharp.Handler::Hello - -# The following are a few example events you can configure -# NOTE: Please make sure to change your handler code to work with those events -# Check the event documentation for details -# events: -# - http: -# path: users/create -# method: get -# - s3: ${env:BUCKET} -# - schedule: rate(10 minutes) -# - sns: greeter-topic -# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000 - -# Define function environment variables here -# environment: -# variable2: value2 - -# you can add CloudFormation resource templates here -#resources: -# Resources: -# NewResource: -# Type: AWS::S3::Bucket -# Properties: -# BucketName: my-new-bucket -# Outputs: -# NewOutput: -# Description: "Description for the output" -# Value: "Some output value" diff --git a/lib/plugins/create/templates/aws-csharp/build.cmd b/lib/plugins/create/templates/aws-csharp/build.cmd index daf426e15..9bd8efb21 100644 --- a/lib/plugins/create/templates/aws-csharp/build.cmd +++ b/lib/plugins/create/templates/aws-csharp/build.cmd @@ -1 +1,2 @@ +dotnet restore dotnet lambda package --configuration release --framework netcoreapp2.0 --output-package bin/release/netcoreapp2.0/deploy-package.zip diff --git a/lib/plugins/create/templates/aws-csharp/build.sh b/lib/plugins/create/templates/aws-csharp/build.sh index ea638246b..51e84dbfa 100755 --- a/lib/plugins/create/templates/aws-csharp/build.sh +++ b/lib/plugins/create/templates/aws-csharp/build.sh @@ -1,3 +1,4 @@ #!/bin/bash +dotnet restore dotnet lambda package --configuration release --framework netcoreapp2.0 --output-package bin/release/netcoreapp2.0/deploy-package.zip From 9c94e0838f50413ecb460b48526dace85aa5229b Mon Sep 17 00:00:00 2001 From: Yunspace Date: Wed, 28 Feb 2018 00:26:20 +1100 Subject: [PATCH 12/29] consistent README and zip installation for both aws-csharp and aws-fsharp --- .../aws/examples/hello-world/fsharp/README.md | 4 ++++ lib/plugins/create/templates/aws-csharp/build.sh | 7 +++++++ lib/plugins/create/templates/aws-fsharp/build.sh | 12 ++++-------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/docs/providers/aws/examples/hello-world/fsharp/README.md b/docs/providers/aws/examples/hello-world/fsharp/README.md index b973a9c46..f1e14c97d 100644 --- a/docs/providers/aws/examples/hello-world/fsharp/README.md +++ b/docs/providers/aws/examples/hello-world/fsharp/README.md @@ -5,6 +5,10 @@ description: Create a F# Hello World Lambda function layout: Doc --> + +### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/examples/hello-world/fsharp/) + + # Hello World F# Example Make sure `serverless` is installed. [See installation guide](../../../guide/installation.md). diff --git a/lib/plugins/create/templates/aws-csharp/build.sh b/lib/plugins/create/templates/aws-csharp/build.sh index 51e84dbfa..f05233ca5 100755 --- a/lib/plugins/create/templates/aws-csharp/build.sh +++ b/lib/plugins/create/templates/aws-csharp/build.sh @@ -1,4 +1,11 @@ #!/bin/bash +#install zip on debian OS, since microsoft/dotnet container doesn't have zip by default +if [ -f /etc/debian_version ] +then + apt -qq update + apt -qq -y install zip +fi + dotnet restore dotnet lambda package --configuration release --framework netcoreapp2.0 --output-package bin/release/netcoreapp2.0/deploy-package.zip diff --git a/lib/plugins/create/templates/aws-fsharp/build.sh b/lib/plugins/create/templates/aws-fsharp/build.sh index 3f92f87ce..f05233ca5 100644 --- a/lib/plugins/create/templates/aws-fsharp/build.sh +++ b/lib/plugins/create/templates/aws-fsharp/build.sh @@ -1,15 +1,11 @@ #!/bin/bash -isMacOs=`uname -a | grep Darwin` - -#install zip -if [ -z "$isMacOs" ] +#install zip on debian OS, since microsoft/dotnet container doesn't have zip by default +if [ -f /etc/debian_version ] then - apt-get -qq update - apt-get -qq -y install zip + apt -qq update + apt -qq -y install zip fi dotnet restore - -#create deployment package dotnet lambda package --configuration release --framework netcoreapp2.0 --output-package bin/release/netcoreapp2.0/deploy-package.zip From 11de3e63ee282e6f80db662025e6e8b4a6160088 Mon Sep 17 00:00:00 2001 From: Kamesh Sampath Date: Wed, 28 Feb 2018 17:01:05 +0530 Subject: [PATCH 13/29] Fixing lint issues on the test class Signed-off-by: Kamesh Sampath --- lib/plugins/create/create.test.js | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/plugins/create/create.test.js b/lib/plugins/create/create.test.js index 664578d02..2b8b5c0a4 100644 --- a/lib/plugins/create/create.test.js +++ b/lib/plugins/create/create.test.js @@ -626,29 +626,29 @@ describe('Create', () => { it('should create a custom renamed service in the directory if using ' + 'the "path" and "name" option', () => { - process.chdir(tmpDir); + process.chdir(tmpDir); - create.options.path = 'my-new-service'; - create.options.name = 'my-custom-new-service'; + create.options.path = 'my-new-service'; + create.options.name = 'my-custom-new-service'; - // using the nodejs template (this test is completely be independent from the template) - create.options.template = 'aws-nodejs'; + // using the nodejs template (this test is completely be independent from the template) + create.options.template = 'aws-nodejs'; - return create.create().then(() => { - const serviceDir = path.join(tmpDir, create.options.path); - const dirContent = fs.readdirSync(serviceDir); + return create.create().then(() => { + const serviceDir = path.join(tmpDir, create.options.path); + const dirContent = fs.readdirSync(serviceDir); - // check if files are created in the correct directory - expect(dirContent).to.include('serverless.yml'); - expect(dirContent).to.include('handler.js'); + // check if files are created in the correct directory + expect(dirContent).to.include('serverless.yml'); + expect(dirContent).to.include('handler.js'); - // check if the service was renamed - const serverlessYmlfileContent = fse - .readFileSync(path.join(serviceDir, 'serverless.yml')).toString(); + // check if the service was renamed + const serverlessYmlfileContent = fse + .readFileSync(path.join(serviceDir, 'serverless.yml')).toString(); - expect((/service: my-custom-new-service/).test(serverlessYmlfileContent)).to.equal(true); - }); + expect((/service: my-custom-new-service/).test(serverlessYmlfileContent)).to.equal(true); }); + }); it('should throw error if there are existing template files in cwd', () => { process.chdir(tmpDir); From 3aeb1c533a130a35158c477a85f0555a91ccdf35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Wed, 28 Feb 2018 09:56:43 -0300 Subject: [PATCH 14/29] Retry travis From 5ed408aedc558999c9e21229cdebec4fd0fd20c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Wed, 28 Feb 2018 10:28:49 -0300 Subject: [PATCH 15/29] Retry travis From e492e744a9f4a0108155d8a6d1c73c3df48ece9a Mon Sep 17 00:00:00 2001 From: bobjamin Date: Fri, 2 Mar 2018 10:33:35 +0000 Subject: [PATCH 16/29] added iam managed policies to aws provider closes #3751 --- .../aws/package/lib/mergeIamTemplates.js | 25 +++++++++++++++++++ .../aws/package/lib/mergeIamTemplates.test.js | 21 ++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/lib/plugins/aws/package/lib/mergeIamTemplates.js b/lib/plugins/aws/package/lib/mergeIamTemplates.js index a17e2dffd..fdf075962 100644 --- a/lib/plugins/aws/package/lib/mergeIamTemplates.js +++ b/lib/plugins/aws/package/lib/mergeIamTemplates.js @@ -7,6 +7,7 @@ const path = require('path'); module.exports = { mergeIamTemplates() { this.validateStatements(this.serverless.service.provider.iamRoleStatements); + this.validateManagedPolicies(this.serverless.service.provider.iamManagedPolicies); return this.merge(); }, @@ -120,6 +121,20 @@ module.exports = { .Statement.concat(this.serverless.service.provider.iamRoleStatements); } + if (this.serverless.service.provider.iamManagedPolicies) { + // add iam managed policies + const iamManagedPolicies = this.serverless.service.provider.iamManagedPolicies; + const resource = this.serverless.service.provider.compiledCloudFormationTemplate + .Resources[this.provider.naming.getRoleLogicalId()]; + if (iamManagedPolicies.length > 0) { + if (!resource.ManagedPolicyArns) { + resource.ManagedPolicyArns = []; + } + resource.ManagedPolicyArns = resource.ManagedPolicyArns + .concat(iamManagedPolicies) + } + } + // check if one of the functions contains vpc configuration const vpcConfigProvided = []; this.serverless.service.getAllFunctions().forEach((functionName) => { @@ -173,4 +188,14 @@ module.exports = { throw new this.serverless.classes.Error(errorMessage); } }, + + validateManagedPolicies(iamManagedPolicies) { + // Verify that iamManagedPolicies (if present) is an array + if (!iamManagedPolicies) { + return; + } + if (!(iamManagedPolicies instanceof Array)) { + throw new this.serverless.classes.Error('iamManagedPolicies should be an array of arns') + } + }, }; diff --git a/lib/plugins/aws/package/lib/mergeIamTemplates.test.js b/lib/plugins/aws/package/lib/mergeIamTemplates.test.js index 140798925..7e12d2be9 100644 --- a/lib/plugins/aws/package/lib/mergeIamTemplates.test.js +++ b/lib/plugins/aws/package/lib/mergeIamTemplates.test.js @@ -155,6 +155,21 @@ describe('#mergeIamTemplates()', () => { }); }); + it('should add managed policy arns', () => { + awsPackage.serverless.service.provider.iamManagedPolicies = [ + 'some:aws:arn:xxx:*:*', + 'someOther:aws:arn:xxx:*:*', + { 'Fn::Join': [':', ['arn:aws:iam:', { Ref: 'AWSAccountId' }, 'some/path']] }, + ]; + return awsPackage.mergeIamTemplates() + .then(() => { + expect(awsPackage.serverless.service.provider.compiledCloudFormationTemplate + .Resources[awsPackage.provider.naming.getRoleLogicalId()] + .ManagedPolicyArns + ).to.deep.equal(awsPackage.serverless.service.provider.iamManagedPolicies); + }); + }); + it('should throw error if custom IAM policy statements is not an array', () => { awsPackage.serverless.service.provider.iamRoleStatements = { policy: 'some_value', @@ -222,6 +237,12 @@ describe('#mergeIamTemplates()', () => { .to.throw(/statement 0 is missing.*Resource; statement 2 is missing.*Effect, Action/); }); + it('should throw error if managed policies is not an array', () => { + awsPackage.serverless.service.provider.iamManagedPolicies = 'a string'; + expect(() => awsPackage.mergeIamTemplates()) + .to.throw('iamManagedPolicies should be an array of arns'); + }); + it('should add a CloudWatch LogGroup resource', () => { const normalizedName = awsPackage.provider.naming.getLogGroupLogicalId(functionName); return awsPackage.mergeIamTemplates().then(() => { From d9f745433940bf9896921926b730f68043ecb446 Mon Sep 17 00:00:00 2001 From: bobjamin Date: Fri, 2 Mar 2018 10:49:46 +0000 Subject: [PATCH 17/29] adding semicolons for linter --- lib/plugins/aws/package/lib/mergeIamTemplates.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/aws/package/lib/mergeIamTemplates.js b/lib/plugins/aws/package/lib/mergeIamTemplates.js index fdf075962..abc21bea6 100644 --- a/lib/plugins/aws/package/lib/mergeIamTemplates.js +++ b/lib/plugins/aws/package/lib/mergeIamTemplates.js @@ -131,7 +131,7 @@ module.exports = { resource.ManagedPolicyArns = []; } resource.ManagedPolicyArns = resource.ManagedPolicyArns - .concat(iamManagedPolicies) + .concat(iamManagedPolicies); } } @@ -195,7 +195,7 @@ module.exports = { return; } if (!(iamManagedPolicies instanceof Array)) { - throw new this.serverless.classes.Error('iamManagedPolicies should be an array of arns') + throw new this.serverless.classes.Error('iamManagedPolicies should be an array of arns'); } }, }; From 81328fccb366765143d3a11dc2372439a7a15da3 Mon Sep 17 00:00:00 2001 From: Kamesh Sampath Date: Mon, 5 Mar 2018 09:58:50 +0530 Subject: [PATCH 18/29] renaming the java runtime name in serverless.yaml Signed-off-by: Kamesh Sampath --- .../create/templates/openwhisk-java-maven/serverless.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/create/templates/openwhisk-java-maven/serverless.yml b/lib/plugins/create/templates/openwhisk-java-maven/serverless.yml index e0ba29ac0..d3541cdf8 100644 --- a/lib/plugins/create/templates/openwhisk-java-maven/serverless.yml +++ b/lib/plugins/create/templates/openwhisk-java-maven/serverless.yml @@ -19,7 +19,7 @@ service: openwhisk-java-maven # NOTE: update this with your service name # $ npm install provider: name: openwhisk - runtime: java8 + runtime: java # you can add packaging information here package: From 4bbc56c78a01968ef419adbe971ec1ba996fc590 Mon Sep 17 00:00:00 2001 From: jpstrikesback Date: Wed, 7 Mar 2018 07:29:49 -0500 Subject: [PATCH 19/29] Update Stack Policy Deny action --- docs/providers/aws/guide/services.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/providers/aws/guide/services.md b/docs/providers/aws/guide/services.md index 24d33dab1..57e2975e9 100644 --- a/docs/providers/aws/guide/services.md +++ b/docs/providers/aws/guide/services.md @@ -116,6 +116,7 @@ provider: Action: - Update:Replace - Update:Delete + Resource: "*" Condition: StringEquals: ResourceType: From 0f72638f4e0b2310dd4a47ac0a177d063e5837ea Mon Sep 17 00:00:00 2001 From: Rupak Ganguly Date: Wed, 7 Mar 2018 20:16:54 -0500 Subject: [PATCH 20/29] Http methods should be lowercase for them to work --- docs/providers/azure/guide/intro.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/providers/azure/guide/intro.md b/docs/providers/azure/guide/intro.md index f212424a9..f33a846c7 100644 --- a/docs/providers/azure/guide/intro.md +++ b/docs/providers/azure/guide/intro.md @@ -78,7 +78,7 @@ functions: # Your "Functions" x-azure-settings: name: req methods: - - POST + - post route: /users/create usersDelete: events: @@ -86,7 +86,7 @@ functions: # Your "Functions" x-azure-settings: name: req methods: - - DELETE + - delete route: /users/delete ``` From 02d54356a3b7a66887b87c5775585f021550bbd4 Mon Sep 17 00:00:00 2001 From: Walery Strauch Date: Thu, 8 Mar 2018 09:28:07 +0100 Subject: [PATCH 21/29] Add package.artifact on severless.yml reference docs. --- docs/providers/aws/guide/serverless.yml.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/providers/aws/guide/serverless.yml.md b/docs/providers/aws/guide/serverless.yml.md index a10c2767d..eafa123b9 100644 --- a/docs/providers/aws/guide/serverless.yml.md +++ b/docs/providers/aws/guide/serverless.yml.md @@ -103,6 +103,7 @@ package: # Optional deployment packaging configuration - .git/** - .travis.yml excludeDevDependencies: false # Config if Serverless should automatically exclude dev dependencies in the deployment package. Defaults to true + artifact: path/to/my-artifact.zip # Own package that should be used. You must provide this file. functions: From 3daf840abb85582b0909f55630c75d71f0ba71c0 Mon Sep 17 00:00:00 2001 From: Walery Strauch Date: Thu, 8 Mar 2018 09:41:19 +0100 Subject: [PATCH 22/29] Add individually package on severless.yml reference docs. --- docs/providers/aws/guide/serverless.yml.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/providers/aws/guide/serverless.yml.md b/docs/providers/aws/guide/serverless.yml.md index eafa123b9..c128e9e6b 100644 --- a/docs/providers/aws/guide/serverless.yml.md +++ b/docs/providers/aws/guide/serverless.yml.md @@ -104,6 +104,7 @@ package: # Optional deployment packaging configuration - .travis.yml excludeDevDependencies: false # Config if Serverless should automatically exclude dev dependencies in the deployment package. Defaults to true artifact: path/to/my-artifact.zip # Own package that should be used. You must provide this file. + individually: true # Enables individual packaging for each function. If true you must provide package for each function. Defaults to false functions: @@ -128,6 +129,15 @@ functions: subnetIds: - subnetId1 - subnetId2 + package: + include: # Specify the directories and files which should be included in the deployment package for this specific function. + - src/** + - handler.js + exclude: # Specify the directories and files which should be excluded in the deployment package for this specific function. + - .git/** + - .travis.yml + artifact: path/to/my-artifact.zip # Own package that should be use for this specific function. You must provide this file. + individually: true # Enables individual packaging for specific function. If true you must provide package for each function. Defaults to false events: # The Events that trigger this Function - http: # This creates an API Gateway HTTP endpoint which can be used to trigger this function. Learn more in "events/apigateway" path: users/create # Path for this endpoint From 6f31908d2d2498c05fb819043c24b8f5987b85ba Mon Sep 17 00:00:00 2001 From: chrisbarbour Date: Sat, 10 Mar 2018 13:53:15 +0000 Subject: [PATCH 23/29] added documentations for iamManagedPolicies --- docs/providers/aws/guide/iam.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/providers/aws/guide/iam.md b/docs/providers/aws/guide/iam.md index 19aacd6f3..9a0164cce 100644 --- a/docs/providers/aws/guide/iam.md +++ b/docs/providers/aws/guide/iam.md @@ -45,7 +45,17 @@ provider: - "/*" ``` +Alongside `provider.iamRoleStatements` managed policies can also be added to this service-wide Role, define managed policies in `provider.iamManagedPolicies`. These will also be merged into the generated IAM Role so you can use `Join`, `Ref` or any other CloudFormation method or feature here too. +```yml +service: new-service +provider: + name: aws + iamManagedPolicies: + - 'some:aws:arn:xxx:*:*' + - 'someOther:aws:arn:xxx:*:*' + - { 'Fn::Join': [':', ['arn:aws:iam:', { Ref: 'AWSAccountId' }, 'some/path']] } +``` ## Custom IAM Roles **WARNING:** You need to take care of the overall role setup as soon as you define custom roles. From 2d9f4a27d399293912e85eede0d99238bcb99ff9 Mon Sep 17 00:00:00 2001 From: chrisbarbour Date: Tue, 13 Mar 2018 08:22:20 +0000 Subject: [PATCH 24/29] updating to use lodash --- lib/plugins/aws/package/lib/mergeIamTemplates.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/aws/package/lib/mergeIamTemplates.js b/lib/plugins/aws/package/lib/mergeIamTemplates.js index abc21bea6..4f268fb08 100644 --- a/lib/plugins/aws/package/lib/mergeIamTemplates.js +++ b/lib/plugins/aws/package/lib/mergeIamTemplates.js @@ -127,7 +127,7 @@ module.exports = { const resource = this.serverless.service.provider.compiledCloudFormationTemplate .Resources[this.provider.naming.getRoleLogicalId()]; if (iamManagedPolicies.length > 0) { - if (!resource.ManagedPolicyArns) { + if (!_.has(resource, 'ManagedPolicyArns') || _.isEmpty(resource.ManagedPolicyArns)) { resource.ManagedPolicyArns = []; } resource.ManagedPolicyArns = resource.ManagedPolicyArns @@ -194,7 +194,7 @@ module.exports = { if (!iamManagedPolicies) { return; } - if (!(iamManagedPolicies instanceof Array)) { + if (!_.isArray(iamManagedPolicies)) { throw new this.serverless.classes.Error('iamManagedPolicies should be an array of arns'); } }, From c86bad256254c6c80109e1378839f90098bb50de Mon Sep 17 00:00:00 2001 From: Haoliang Yu Date: Wed, 14 Mar 2018 13:56:01 -0400 Subject: [PATCH 25/29] Fix a broken link --- docs/providers/kubeless/events/pubsub.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/providers/kubeless/events/pubsub.md b/docs/providers/kubeless/events/pubsub.md index d3ef2065b..cd2f707ae 100644 --- a/docs/providers/kubeless/events/pubsub.md +++ b/docs/providers/kubeless/events/pubsub.md @@ -49,4 +49,4 @@ serverless logs -f hello hello world! ``` -You can install the Kubeless CLI tool following the [../guide/installation](installation guide). +You can install the Kubeless CLI tool following the [installation guide](../guide/installation.md). From 435f88e3346bcb5603e6efc075b070a274e63e62 Mon Sep 17 00:00:00 2001 From: Loren Siebert Date: Thu, 15 Mar 2018 10:08:14 -0700 Subject: [PATCH 26/29] Update README.md - Remove duplicate sentence - Change Node template to Go template --- docs/providers/aws/examples/hello-world/go/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/providers/aws/examples/hello-world/go/README.md b/docs/providers/aws/examples/hello-world/go/README.md index 1720c009b..05a233a33 100644 --- a/docs/providers/aws/examples/hello-world/go/README.md +++ b/docs/providers/aws/examples/hello-world/go/README.md @@ -30,7 +30,6 @@ You should also have [go](https://golang.org/doc/install) and [make](https://www It is always good practice to organize your `go` projects within [GOPATH](https://golang.org/doc/code.html#GOPATH), to maximize the benefits of go tooling. ## 1. Create a service -There are two templates for `go`: The Serverless Framework includes starter templates for various languages and providers. There are two templates for `go`. @@ -50,7 +49,7 @@ sls create --template aws-go --path myService sls create --template aws-go-dep --path myService ``` -Using the `create` command we can specify one of the available [templates](https://serverless.com/framework/docs/providers/aws/cli-reference/create#available-templates). For this example use aws-nodejs with the `--template` or shorthand `-t` flag. +Using the `create` command we can specify one of the available [templates](https://serverless.com/framework/docs/providers/aws/cli-reference/create#available-templates). For this example use aws-go-dep with the `--template` or shorthand `-t` flag. The `--path` or shorthand `-p` is the location to be created with the template service files. From 005b6bdcdde1c788c894773e5ca362c69baadfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Guimar=C3=A3es?= Date: Mon, 19 Mar 2018 10:27:11 -0300 Subject: [PATCH 27/29] Adding NUM_CONCURRENT_UPLOADS constant --- lib/plugins/aws/deploy/lib/uploadArtifacts.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.js index 20fc8e42c..8d6c94556 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.js @@ -10,6 +10,8 @@ const BbPromise = require('bluebird'); const filesize = require('filesize'); const normalizeFiles = require('../../lib/normalizeFiles'); +const NUM_CONCURRENT_UPLOADS = 3; + module.exports = { uploadArtifacts() { return BbPromise.bind(this) @@ -105,7 +107,7 @@ module.exports = { const stats = fs.statSync(artifactFilePath); this.serverless.cli.log(`Uploading service .zip file to S3 (${filesize(stats.size)})...`); return this.uploadZipFile(artifactFilePath); - }, { concurrency: 3 } + }, { concurrency: NUM_CONCURRENT_UPLOADS } ); }, }; From 0c8a5699688fc0834cfab793bde7622a0420c5e6 Mon Sep 17 00:00:00 2001 From: CHRIS BARBOUR Date: Wed, 21 Mar 2018 21:51:35 +0000 Subject: [PATCH 28/29] fixing location of ManagedPolicyArns to be under Properties --- lib/plugins/aws/package/lib/mergeIamTemplates.js | 2 +- lib/plugins/aws/package/lib/mergeIamTemplates.test.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/plugins/aws/package/lib/mergeIamTemplates.js b/lib/plugins/aws/package/lib/mergeIamTemplates.js index 4f268fb08..12508e3d1 100644 --- a/lib/plugins/aws/package/lib/mergeIamTemplates.js +++ b/lib/plugins/aws/package/lib/mergeIamTemplates.js @@ -125,7 +125,7 @@ module.exports = { // add iam managed policies const iamManagedPolicies = this.serverless.service.provider.iamManagedPolicies; const resource = this.serverless.service.provider.compiledCloudFormationTemplate - .Resources[this.provider.naming.getRoleLogicalId()]; + .Resources[this.provider.naming.getRoleLogicalId()].Properties; if (iamManagedPolicies.length > 0) { if (!_.has(resource, 'ManagedPolicyArns') || _.isEmpty(resource.ManagedPolicyArns)) { resource.ManagedPolicyArns = []; diff --git a/lib/plugins/aws/package/lib/mergeIamTemplates.test.js b/lib/plugins/aws/package/lib/mergeIamTemplates.test.js index 7e12d2be9..373f0aa32 100644 --- a/lib/plugins/aws/package/lib/mergeIamTemplates.test.js +++ b/lib/plugins/aws/package/lib/mergeIamTemplates.test.js @@ -165,6 +165,7 @@ describe('#mergeIamTemplates()', () => { .then(() => { expect(awsPackage.serverless.service.provider.compiledCloudFormationTemplate .Resources[awsPackage.provider.naming.getRoleLogicalId()] + .Properties .ManagedPolicyArns ).to.deep.equal(awsPackage.serverless.service.provider.iamManagedPolicies); }); From 92378bd414f2dffa48dc4c8dbed0851ccea92712 Mon Sep 17 00:00:00 2001 From: horike37 Date: Fri, 23 Mar 2018 02:35:54 +0900 Subject: [PATCH 29/29] add this to serverless.yml.md --- docs/providers/aws/guide/serverless.yml.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/providers/aws/guide/serverless.yml.md b/docs/providers/aws/guide/serverless.yml.md index d06f4803e..138924184 100644 --- a/docs/providers/aws/guide/serverless.yml.md +++ b/docs/providers/aws/guide/serverless.yml.md @@ -62,6 +62,8 @@ provider: rateLimit: 100 stackTags: # Optional CF stack tags key: value + iamManagedPolicies: # Optional IAM Managed Policies, which allows to include the policies into IAM Role + - arn:aws:iam:*****:policy/some-managed-policy iamRoleStatements: # IAM role statements so that services can be accessed in the AWS account - Effect: 'Allow' Action: