mirror of
https://github.com/serverless/serverless.git
synced 2026-01-25 15:07:39 +00:00
commit
8dde4c7e22
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,3 +1,16 @@
|
||||
# 1.26.0 (29.01.2018)
|
||||
- [AWS Go support](https://github.com/serverless/serverless/pull/4669)
|
||||
- [Support for using an existing ApiGateway and Resources](https://github.com/serverless/serverless/pull/4247)
|
||||
- [Add logRetentionInDays config](https://github.com/serverless/serverless/pull/4591)
|
||||
- [Add support of `serverless.js` configuration file](https://github.com/serverless/serverless/pull/4590)
|
||||
- [Add "did you mean..." CLI suggestions](https://github.com/serverless/serverless/pull/4586)
|
||||
- [Add `--template-path` option to `serverless create`](https://github.com/serverless/serverless/pull/4576)
|
||||
- [Add support POJO input support for Java invoke local](https://github.com/serverless/serverless/pull/4596)
|
||||
|
||||
## Meta
|
||||
- [Comparison since last release](https://github.com/serverless/serverless/compare/v1.25.0...v1.26.0)
|
||||
|
||||
|
||||
# 1.25.0 (20.12.2017)
|
||||
- [Improve Stage and Region Usage](https://github.com/serverless/serverless/pull/4560)
|
||||
- [Add API Gateway endpoint configuration](https://github.com/serverless/serverless/pull/4531)
|
||||
|
||||
@ -132,7 +132,7 @@ The following are services you can instantly install and use by running `serverl
|
||||
|
||||
## <a name="features"></a>Features
|
||||
|
||||
* Supports Node.js, Python, Java, Scala, C#, F#, Groovy, Kotlin, PHP & Swift.
|
||||
* Supports Node.js, Python, Java, Scala, C#, F#, Go, Groovy, Kotlin, PHP & Swift.
|
||||
* Manages the lifecycle of your serverless architecture (build, deploy, update, delete).
|
||||
* Safely deploy functions, events and their required resources together via provider resource managers (e.g., AWS CloudFormation).
|
||||
* Functions can be grouped ("serverless services") for easy management of code, resources & processes, across large projects & teams.
|
||||
@ -158,7 +158,7 @@ This table is generated from https://github.com/serverless/plugins/blob/master/p
|
||||
| **[Raml Serverless](https://github.com/andrewcurioso/raml-serverless)** <br/> Serverless plugin to work with RAML API spec documents | [andrewcurioso](http://github.com/andrewcurioso) |
|
||||
| **[Serverless Alexa Plugin](https://github.com/rajington/serverless-alexa-plugin)** <br/> Serverless plugin to support Alexa Lambda events | [rajington](http://github.com/rajington) |
|
||||
| **[Serverless Api Stage](https://github.com/leftclickben/serverless-api-stage)** <br/> Serverless API Stage plugin, enables stage variables and logging for AWS API Gateway. | [leftclickben](http://github.com/leftclickben) |
|
||||
| **[Serverless Apig S3](https://github.com/sdd/serverless-apig-s3)** <br/> Serve static front-end content from S3 via the API Gatewy and deploy client bundle to S3. | [sdd](http://github.com/sdd) |
|
||||
| **[Serverless Apig S3](https://github.com/sdd/serverless-apig-s3)** <br/> Serve static front-end content from S3 via the API Gateway and deploy client bundle to S3. | [sdd](http://github.com/sdd) |
|
||||
| **[Serverless Apigateway Plugin](https://github.com/GFG/serverless-apigateway-plugin)** <br/> Configure the AWS api gateway: Binary support, Headers and Body template mappings | [GFG](http://github.com/GFG) |
|
||||
| **[Serverless Apigw Binary](https://github.com/maciejtreder/serverless-apigw-binary)** <br/> Plugin to enable binary support in AWS API Gateway. | [maciejtreder](http://github.com/maciejtreder) |
|
||||
| **[Serverless Apigwy Binary](https://github.com/ryanmurakami/serverless-apigwy-binary)** <br/> Serverless plugin for configuring API Gateway to return binary responses | [ryanmurakami](http://github.com/ryanmurakami) |
|
||||
|
||||
@ -63,6 +63,16 @@ services:
|
||||
image: microsoft/dotnet:1.0.4-sdk
|
||||
volumes:
|
||||
- ./tmp/serverless-integration-test-aws-fsharp:/app
|
||||
aws-go:
|
||||
image: golang:1.9
|
||||
volumes:
|
||||
- ./tmp/serverless-integration-test-aws-go:/app
|
||||
- ./tmp/serverless-integration-test-aws-go:/go/src/app
|
||||
aws-go-dep:
|
||||
image: yunspace/golang:1.9
|
||||
volumes:
|
||||
- ./tmp/serverless-integration-test-aws-go-dep:/app
|
||||
- ./tmp/serverless-integration-test-aws-go-dep:/go/src/app
|
||||
aws-nodejs-typescript:
|
||||
image: node:6.10.3
|
||||
volumes:
|
||||
|
||||
@ -14,14 +14,41 @@ layout: Doc
|
||||
|
||||
## Event definition
|
||||
|
||||
This will enable your Lambda function to be called by an Alexa skill kit.
|
||||
This will enable your Lambda function to be called by an Alexa Skill kit.
|
||||
`amzn1.ask.skill.xx-xx-xx-xx-xx` is a skill ID for Alexa Skills kit. You receive a skill ID once you register and create a skill in [Amazon Developer Console](https://developer.amazon.com/).
|
||||
After deploying, add your deployed Lambda function ARN to which this event is attached to the Service Endpoint under Configuration on Amazon Developer Console.
|
||||
|
||||
```yml
|
||||
functions:
|
||||
mySkill:
|
||||
handler: mySkill.handler
|
||||
events:
|
||||
- alexaSkill
|
||||
- alexaSkill: amzn1.ask.skill.xx-xx-xx-xx-xx
|
||||
```
|
||||
|
||||
You can find detailed guides on how to create an Alexa Skill with Serverless using NodeJS [here](https://github.com/serverless/examples/tree/master/aws-node-alexa-skill) as well as in combination with Python [here](https://github.com/serverless/examples/tree/master/aws-python-alexa-skill).
|
||||
|
||||
## Enabling / Disabling
|
||||
|
||||
**Note:** `alexaSkill` events are enabled by default.
|
||||
|
||||
This will create and attach a alexaSkill event for the `mySkill` function which is disabled. If enabled it will call
|
||||
the `mySkill` function by an Alexa Skill.
|
||||
|
||||
```yaml
|
||||
functions:
|
||||
mySkill:
|
||||
handler: mySkill.handler
|
||||
events:
|
||||
- alexaSkill:
|
||||
appId: amzn1.ask.skill.xx-xx-xx-xx
|
||||
enabled: false
|
||||
```
|
||||
|
||||
## Backwards compatability
|
||||
|
||||
Previous syntax of this event didn't require a skill ID as parameter, but according to [Amazon's documentation](https://developer.amazon.com/docs/custom-skills/host-a-custom-skill-as-an-aws-lambda-function.html#configuring-the-alexa-skills-kit-trigger) you should restrict your lambda function to be executed only by your skill.
|
||||
|
||||
Omitting the skill id will make your Lambda function available for the public, allowing any other skill developer to invoke it.
|
||||
|
||||
(This is important, as [opposing to custom HTTPS endpoints](https://developer.amazon.com/docs/custom-skills/handle-requests-sent-by-alexa.html#request-verify), there's no way to validate the request was sent by your skill.)
|
||||
@ -872,7 +872,7 @@ 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 children and grandchildren paths, you also want to break them out into smaller services.
|
||||
|
||||
```yml
|
||||
service: service-a
|
||||
|
||||
@ -14,7 +14,7 @@ layout: Doc
|
||||
|
||||
## Simple event definition
|
||||
|
||||
This will enable your Lambda function to be called by an Log Stream.
|
||||
This will enable your Lambda function to be called by a Log Stream.
|
||||
|
||||
```yml
|
||||
functions:
|
||||
|
||||
@ -17,6 +17,8 @@ Pick your language of choice:
|
||||
|
||||
* [JavaScript](./node)
|
||||
* [Python](./python)
|
||||
* [csharp](./csharp)
|
||||
* [C#](./csharp)
|
||||
* [F#](./fsharp)
|
||||
* [Go](./go)
|
||||
|
||||
[View all examples](https://www.serverless.com/framework/docs/providers/aws/examples/)
|
||||
|
||||
@ -13,13 +13,32 @@ layout: Doc
|
||||
|
||||
Make sure `serverless` is installed. [See installation guide](../../../guide/installation.md).
|
||||
|
||||
Once installed the Serverless CLI can be called with `serverless` or the shorthand `sls` command.
|
||||
|
||||
```
|
||||
$ sls
|
||||
|
||||
Commands
|
||||
* You can run commands with "serverless" or the shortcut "sls"
|
||||
* Pass "--verbose" to this command to get in-depth plugin info
|
||||
* Pass "--no-color" to disable CLI colors
|
||||
* Pass "--help" after any <command> for contextual help
|
||||
```
|
||||
|
||||
## 1. Create a service
|
||||
`serverless create --template aws-csharp --path myService` or `sls create --template aws-csharp --path myService`, where 'myService' is a new folder to be created with template service files. Change directories into this new folder.
|
||||
|
||||
```
|
||||
sls create --template aws-csharp --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-csharp with the `--template` or shorthand `-t` flag.
|
||||
|
||||
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
|
||||
|
||||
```
|
||||
# Linux or OSX
|
||||
# Linux or Mac OS
|
||||
./build.sh
|
||||
```
|
||||
|
||||
@ -29,14 +48,23 @@ Make sure `serverless` is installed. [See installation guide](../../../guide/ins
|
||||
```
|
||||
|
||||
## 3. Deploy
|
||||
`serverless deploy` or `sls deploy`. `sls` is shorthand for the Serverless CLI command
|
||||
|
||||
```
|
||||
sls deploy
|
||||
```
|
||||
|
||||
This will deploy your function to AWS Lambda based on the settings in `serverless.yml`.
|
||||
|
||||
|
||||
## 4. Invoke deployed function
|
||||
`serverless invoke --function hello` or `serverless invoke -f hello`
|
||||
|
||||
`-f` is shorthand for `--function`
|
||||
```
|
||||
sls invoke -f hello
|
||||
```
|
||||
|
||||
In your terminal window you should see the response from AWS Lambda
|
||||
Invoke deployed function with command `invoke` and `--function` or shorthand `-f`.
|
||||
|
||||
In your terminal window you should see the response from AWS Lambda.
|
||||
|
||||
```bash
|
||||
{
|
||||
@ -49,4 +77,4 @@ In your terminal window you should see the response from AWS Lambda
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and run your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -7,31 +7,69 @@ layout: Doc
|
||||
|
||||
# Hello World F# Example
|
||||
|
||||
## Prerequisites
|
||||
Make sure `serverless` is installed. [See installation guide](../../../guide/installation.md).
|
||||
|
||||
* Make sure `serverless` is installed. [See installation guide](../../../guide/installation.md).
|
||||
* [.Net Core 1.0.1 SDK](https://www.microsoft.com/net/download/core)
|
||||
* 1.1 isn't currently supported by AWS Lambda
|
||||
* [NodeJS v4 or higher](https://nodejs.org/en/)
|
||||
* An AWS Account
|
||||
|
||||
## Build and Package
|
||||
|
||||
From the root of this directory, run `build.cmd`, or `build.sh` if on Linux / Mac.
|
||||
|
||||
This will produce your deployment package at `bin/release/netcoreapp1.0/deploy-package.zip`.
|
||||
|
||||
## Deployment and Invocation
|
||||
|
||||
Once packaged, you can follow [these instructions](https://github.com/serverless/serverless#quick-start) to deploy and remotely invoke the function on AWS Lambda.
|
||||
|
||||
In short the commands you will need to run are (from the root of this directory):
|
||||
Once installed the Serverless CLI can be called with `serverless` or the shorthand `sls` command.
|
||||
|
||||
```
|
||||
serverless config credentials --provider aws --key {YourAwsAccessKey} --secret {YourAwsSecret}
|
||||
serverless deploy -v
|
||||
serverless invoke -f hello -l
|
||||
serverless remove
|
||||
$ sls
|
||||
|
||||
Commands
|
||||
* You can run commands with "serverless" or the shortcut "sls"
|
||||
* Pass "--verbose" to this command to get in-depth plugin info
|
||||
* Pass "--no-color" to disable CLI colors
|
||||
* Pass "--help" after any <command> for contextual help
|
||||
```
|
||||
|
||||
By default this template deploys to us-east-1, you can change that in "serverless.yml" under the `region: us-east-1` key.
|
||||
## 1. Create a service
|
||||
|
||||
```
|
||||
sls create --template aws-fsharp --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-fsharp with the `--template` or shorthand `-t` flag.
|
||||
|
||||
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
|
||||
|
||||
```
|
||||
# Linux or Mac OS
|
||||
./build.sh
|
||||
```
|
||||
|
||||
```
|
||||
# Windows PowerShell
|
||||
./build.cmd
|
||||
```
|
||||
|
||||
## 3. Deploy
|
||||
|
||||
```
|
||||
sls deploy
|
||||
```
|
||||
|
||||
This will deploy your function to AWS Lambda based on the settings in `serverless.yml`.
|
||||
|
||||
## 4. Invoke deployed function
|
||||
|
||||
```
|
||||
sls invoke -f hello
|
||||
```
|
||||
|
||||
Invoke deployed function with command `invoke` and `--function` or shorthand `-f`.
|
||||
|
||||
In your terminal window you should see the response from AWS Lambda.
|
||||
|
||||
```bash
|
||||
{
|
||||
"Message": "Go Serverless v1.0! Your function executed successfully!",
|
||||
"Request": {
|
||||
"Key1": null,
|
||||
"Key2": null,
|
||||
"Key3": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -66,7 +66,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
|
||||
116
docs/providers/aws/examples/hello-world/go/README.md
Normal file
116
docs/providers/aws/examples/hello-world/go/README.md
Normal file
@ -0,0 +1,116 @@
|
||||
<!--
|
||||
title: Hello World Go Example
|
||||
menuText: Hello World Go Example
|
||||
description: Create a Go Hello World Lambda function
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
<!-- DOCS-SITE-LINK:START automatically geneated -->
|
||||
### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/examples/hello-world/go/)
|
||||
<!-- DOCS-SITE-LINK:END -->
|
||||
|
||||
# Hello World Go Example
|
||||
|
||||
Make sure `serverless` is installed. [See installation guide](../../../guide/installation.md).
|
||||
|
||||
Once installed the Serverless CLI can be called with `serverless` or the shorthand `sls` command.
|
||||
|
||||
```
|
||||
$ sls
|
||||
|
||||
Commands
|
||||
* You can run commands with "serverless" or the shortcut "sls"
|
||||
* Pass "--verbose" to this command to get in-depth plugin info
|
||||
* Pass "--no-color" to disable CLI colors
|
||||
* Pass "--help" after any <command> for contextual help
|
||||
```
|
||||
|
||||
You should also have [go](https://golang.org/doc/install) and [make](https://www.gnu.org/software/make/)
|
||||
|
||||
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`.
|
||||
|
||||
#### [aws-go](https://github.com/serverless/serverless/tree/master/lib/plugins/create/templates/aws-go)
|
||||
|
||||
`aws-go` fetches dependencies using standard `go get`.
|
||||
|
||||
```
|
||||
sls create --template aws-go --path myService
|
||||
```
|
||||
|
||||
#### [aws-go-dep](https://github.com/serverless/serverless/tree/master/lib/plugins/create/templates/aws-go-dep)
|
||||
|
||||
`aws-go-dep` uses [go dep](https://github.com/golang/dep) and requires your project to be in `$GOPATH/src`
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
The `--path` or shorthand `-p` is the location to be created with the template service files.
|
||||
|
||||
Change directories into 'myService' folder and you can see this project has 2 handler functions: `hello` and `world` split into 2 separate go packages (folders):
|
||||
|
||||
```
|
||||
.
|
||||
├── hello/
|
||||
│ └── main.go
|
||||
├── world/
|
||||
│ └── main.go
|
||||
```
|
||||
|
||||
This because a `main()` function is required as entry point for each handler executable.
|
||||
|
||||
## 2. Build using go build to create static binaries
|
||||
|
||||
Run `make build` to build both functions. Successful build should generate the following binaries:
|
||||
|
||||
```
|
||||
.
|
||||
├── bin/
|
||||
│ |── hello
|
||||
│ └── world
|
||||
```
|
||||
|
||||
## 3. Deploy
|
||||
|
||||
```
|
||||
sls deploy
|
||||
```
|
||||
|
||||
This will deploy your function to AWS Lambda based on the settings in `serverless.yml`.
|
||||
|
||||
## 4. Invoke deployed function
|
||||
|
||||
```
|
||||
sls invoke -f hello
|
||||
```
|
||||
|
||||
```
|
||||
sls invoke -f world
|
||||
```
|
||||
|
||||
Invoke either deployed function with command `invoke` and `--function` or shorthand `-f`.
|
||||
|
||||
In your terminal window you should see the response from AWS Lambda.
|
||||
|
||||
```bash
|
||||
serverless invoke -f hello
|
||||
|
||||
{
|
||||
"message": "Go Serverless v1.0! Your function executed successfully!"
|
||||
}
|
||||
|
||||
serverless invoke -f world
|
||||
|
||||
{
|
||||
"message": "Okay so your other function also executed successfully!"
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
@ -13,18 +13,45 @@ layout: Doc
|
||||
|
||||
Make sure `serverless` is installed. [See installation guide](../../../guide/installation.md).
|
||||
|
||||
Once installed the Serverless CLI can be called with `serverless` or the shorthand `sls` command.
|
||||
|
||||
```
|
||||
$ sls
|
||||
|
||||
Commands
|
||||
* You can run commands with "serverless" or the shortcut "sls"
|
||||
* Pass "--verbose" to this command to get in-depth plugin info
|
||||
* Pass "--no-color" to disable CLI colors
|
||||
* Pass "--help" after any <command> for contextual help
|
||||
```
|
||||
|
||||
## 1. Create a service
|
||||
`serverless create --template aws-nodejs --path myService` or `sls create --template aws-nodejs --path myService`, where 'myService' is a new folder to be created with template service files. Change directories into this new folder.
|
||||
|
||||
```
|
||||
sls create --template aws-nodejs --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.
|
||||
|
||||
The `--path` or shorthand `-p` is the location to be created with the template service files. Change directories into this new folder.
|
||||
|
||||
## 2. Deploy
|
||||
`serverless deploy` or `sls deploy`. `sls` is shorthand for the Serverless CLI command
|
||||
|
||||
```
|
||||
sls deploy
|
||||
```
|
||||
|
||||
This will deploy your function to AWS Lambda based on the settings in `serverless.yml`.
|
||||
|
||||
## 3. Invoke deployed function
|
||||
`serverless invoke --function hello` or `serverless invoke -f hello`
|
||||
|
||||
`-f` is shorthand for `--function`
|
||||
```
|
||||
sls invoke -f hello
|
||||
```
|
||||
|
||||
In your terminal window you should see the response from AWS Lambda
|
||||
Invoke deployed function with command `invoke` and `--function` or shorthand `-f`.
|
||||
|
||||
In your terminal window you should see the response from AWS Lambda.
|
||||
|
||||
```bash
|
||||
{
|
||||
@ -33,4 +60,4 @@ In your terminal window you should see the response from AWS Lambda
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and run your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -13,18 +13,45 @@ layout: Doc
|
||||
|
||||
Make sure `serverless` is installed. [See installation guide](../../../guide/installation.md).
|
||||
|
||||
Once installed the Serverless CLI can be called with `serverless` or the shorthand `sls` command.
|
||||
|
||||
```
|
||||
$ sls
|
||||
|
||||
Commands
|
||||
* You can run commands with "serverless" or the shortcut "sls"
|
||||
* Pass "--verbose" to this command to get in-depth plugin info
|
||||
* Pass "--no-color" to disable CLI colors
|
||||
* Pass "--help" after any <command> for contextual help
|
||||
```
|
||||
|
||||
## 1. Create a service
|
||||
`serverless create --template aws-python --path myService` or `sls create --template aws-python --path myService`, where 'myService' is a new folder to be created with template service files. Change directories into this new folder.
|
||||
|
||||
```
|
||||
sls create --template aws-python --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-python with the `--template` or shorthand `-t` flag.
|
||||
|
||||
The `--path` or shorthand `-p` is the location to be created with the template service files. Change directories into this new folder.
|
||||
|
||||
## 2. Deploy
|
||||
`serverless deploy` or `sls deploy`. `sls` is shorthand for the serverless CLI command
|
||||
|
||||
```
|
||||
sls deploy
|
||||
```
|
||||
|
||||
This will deploy your function to AWS Lambda based on the settings in `serverless.yml`.
|
||||
|
||||
## 3. Invoke deployed function
|
||||
`serverless invoke --function hello` or `serverless invoke -f hello`
|
||||
|
||||
`-f` is shorthand for `--function`
|
||||
```
|
||||
sls invoke -f hello
|
||||
```
|
||||
|
||||
In your terminal window you should see the response from AWS Lambda
|
||||
Invoke deployed function with command `invoke` and `--function` or shorthand `-f`.
|
||||
|
||||
In your terminal window you should see the response from AWS Lambda.
|
||||
|
||||
```bash
|
||||
{
|
||||
@ -33,4 +60,4 @@ In your terminal window you should see the response from AWS Lambda
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and ran your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -37,6 +37,7 @@ functions:
|
||||
runtime: python2.7 # optional overwrite, default is provider runtime
|
||||
memorySize: 512 # optional, in MB, default is 1024
|
||||
timeout: 10 # optional, in seconds, default is 6
|
||||
reservedConcurrency: 5 # optional, reserved concurrency limit for this function. By default, AWS uses account concurrency limit
|
||||
```
|
||||
|
||||
The `handler` property points to the file and module containing the code you want to run in your function.
|
||||
|
||||
@ -159,7 +159,9 @@ functions:
|
||||
batchSize: 100
|
||||
startingPosition: LATEST
|
||||
enabled: false
|
||||
- alexaSkill
|
||||
- alexaSkill:
|
||||
appId: amzn1.ask.skill.xx-xx-xx-xx
|
||||
enabled: true
|
||||
- alexaSmartHome:
|
||||
appId: amzn1.ask.skill.xx-xx-xx-xx
|
||||
enabled: true
|
||||
|
||||
@ -63,6 +63,7 @@ Here are the available runtimes for AWS Lambda:
|
||||
* aws-scala-sbt
|
||||
* aws-csharp
|
||||
* aws-fsharp
|
||||
* aws-go
|
||||
|
||||
Check out the [create command docs](../cli-reference/create) for all the details and options.
|
||||
|
||||
|
||||
@ -39,4 +39,4 @@ In your terminal window you should see the response from azure
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and run your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
56
docs/providers/google/cli-reference/invoke-local.md
Normal file
56
docs/providers/google/cli-reference/invoke-local.md
Normal file
@ -0,0 +1,56 @@
|
||||
<!--
|
||||
title: Serverless Framework Commands - Google Cloud Functions - Invoke Local
|
||||
menuText: invoke local
|
||||
menuOrder: 7
|
||||
description: Emulate an invocation of your Google Cloud function locally using the Serverless Framework
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
<!-- DOCS-SITE-LINK:START automatically generated -->
|
||||
|
||||
### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/google/cli-reference/invoke-local)
|
||||
|
||||
<!-- DOCS-SITE-LINK:END -->
|
||||
|
||||
# Google - Invoke Local
|
||||
|
||||
Invokes deployed function locally. It allows to send event data to the function, read logs and display other important information of the function invocation.
|
||||
|
||||
```bash
|
||||
serverless invoke -f functionName
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
* `--function` or `-f` The name of the function in your service that you want to invoke. **Required**.
|
||||
\_ `--data` or `-d` Data you want to pass into the function
|
||||
* `--path` or `-p` Path to JSON or YAML file holding input data. This path is relative to the root directory of the service.
|
||||
* `--raw` Pass data as a raw string even if it is JSON. If not set, JSON data are parsed and passed as an object.
|
||||
* `--contextPath` or `-x`, The path to a json file holding input context to be passed to the invoked function. This path is relative to the root directory of the service.
|
||||
* `--context` or `-c`, String data to be passed as a context to your function. Same like with `--data`, context included in `--contextPath` will overwrite the context you passed with `--context` flag.
|
||||
|
||||
> Keep in mind that if you pass both `--path` and `--data`, the data included in the `--path` file will overwrite the data you passed with the `--data` flag.
|
||||
|
||||
## Examples
|
||||
|
||||
### Local function invocation
|
||||
|
||||
```bash
|
||||
serverless invoke local -f functionName
|
||||
```
|
||||
|
||||
### Local function invocation with data
|
||||
|
||||
```bash
|
||||
serverless invoke local -f functionName -d '{ "data": "hello world" }'
|
||||
```
|
||||
|
||||
### Local function invocation with data passing
|
||||
|
||||
```bash
|
||||
serverless invoke local -f functionName -p path/to/file.json
|
||||
|
||||
# OR
|
||||
|
||||
serverless invoke local -f functionName -p path/to/file.yaml
|
||||
```
|
||||
@ -31,8 +31,8 @@ Update the `credentials` and your `project` property in the `serverless.yml` fil
|
||||
|
||||
## 5. Invoke deployed function
|
||||
|
||||
`serverless invoke --function helloWorld`
|
||||
`serverless invoke --function first`
|
||||
|
||||
In your terminal window you should see a response from the Google Cloud
|
||||
|
||||
Congrats you have just deployed and run your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -30,6 +30,7 @@ If you have questions, join the [chat in gitter](https://gitter.im/serverless/se
|
||||
<li><a href="./guide/functions.md">Functions</a></li>
|
||||
<li><a href="./guide/events.md">Events</a></li>
|
||||
<li><a href="./guide/deploying.md">Deploying</a></li>
|
||||
<li><a href="./guide/packaging.md">Packaging</a></li>
|
||||
<li><a href="./guide/debugging.md">Debugging</a></li>
|
||||
<li><a href="./guide/workflow.md">Workflow</a></li>
|
||||
</ul>
|
||||
|
||||
@ -25,6 +25,9 @@ service: my-service
|
||||
provider:
|
||||
name: kubeless
|
||||
runtime: python2.7
|
||||
memorySize: 512M # optional, maximum memory
|
||||
timeout: 10 # optional, in seconds, default is 180
|
||||
namespace: funcions # optional, deployment namespace if not specified it uses "default"
|
||||
|
||||
plugins:
|
||||
- serverless-kubeless
|
||||
@ -34,7 +37,12 @@ functions:
|
||||
# and the K8s service object to get a request to call the function
|
||||
hello:
|
||||
# The function to call as a response to the HTTP event
|
||||
handler: handler.hello
|
||||
handler: handler.hello # required, handler set
|
||||
description: Description of what the function does # optional, to set the description as an annotation
|
||||
memorySize: 512M # optional, maximum memory
|
||||
timeout: 10 # optional, in seconds, default is 180
|
||||
namespace: funcions # optional, deployment namespace, if not specified "default" will be used
|
||||
port: 8081 # optional, deploy http-based function with a custom port, default is 8080
|
||||
```
|
||||
|
||||
The `handler` property points to the file and module containing the code you want to run in your function.
|
||||
@ -88,3 +96,139 @@ The Kubeless provider plugin supports the following runtimes.
|
||||
Please see the following repository for sample projects using those runtimes:
|
||||
|
||||
[https://github.com/serverless/serverless-kubeless/tree/master/examples](https://github.com/serverless/serverless-kubeless/tree/master/examples)
|
||||
|
||||
## Installing dependencies
|
||||
|
||||
For installing dependencies the standard dependency file should be placed in the function folder:
|
||||
|
||||
- For Python functions, it will use the file `requirements.txt`
|
||||
- For Nodejs functions, `dependencies` in the `package.json` file will be installed
|
||||
- For Ruby functions, it will use the file `Gemfile.rb`
|
||||
|
||||
If one of the above files is found, the depencies will be installed using a [`Init Container`](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
|
||||
|
||||
## Environment Variables
|
||||
|
||||
You can add environment variable configuration to a specific function in `serverless.yml` by adding an `environment` object property in the function configuration. This object should contain a key/value collection of strings:
|
||||
|
||||
```yml
|
||||
# serverless.yml
|
||||
service: service-name
|
||||
provider: kubeless
|
||||
plugins:
|
||||
- serverless-kubeless
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
environment:
|
||||
TABLE_NAME: tableName
|
||||
```
|
||||
|
||||
Or if you want to apply environment variable configuration to all functions in your service, you can add the configuration to the higher level `provider` object. Environment variables configured at the function level are merged with those at the provider level, so your function with specific environment variables will also have access to the environment variables defined at the provider level. If an environment variable with the same key is defined at both the function and provider levels, the function-specific value overrides the provider-level default value. For example:
|
||||
|
||||
```yml
|
||||
# serverless.yml
|
||||
service: service-name
|
||||
provider:
|
||||
name: kubeless
|
||||
environment:
|
||||
SYSTEM_NAME: mySystem
|
||||
TABLE_NAME: tableName1
|
||||
|
||||
plugins:
|
||||
- serverless-kubeless
|
||||
|
||||
functions:
|
||||
hello:
|
||||
# this function will have SYSTEM_NAME=mySystem and TABLE_NAME=tableName1 from the provider-level environment config above
|
||||
handler: handler.hello
|
||||
users:
|
||||
# this function will have SYSTEM_NAME=mySystem from the provider-level environment config above
|
||||
# but TABLE_NAME will be tableName2 because this more specific config will override the default above
|
||||
handler: handler.users
|
||||
environment:
|
||||
TABLE_NAME: tableName2
|
||||
```
|
||||
|
||||
## Labels
|
||||
|
||||
Using the `labels` configuration makes it possible to add `key` / `value` labels to your functions.
|
||||
|
||||
Those labels will appear in deployments, services and pods and will make it easier to group functions by label or find functions with a common label.
|
||||
|
||||
```yml
|
||||
provider:
|
||||
name: kubeless
|
||||
|
||||
plugins:
|
||||
- serverless-kubeless
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
labels:
|
||||
foo: bar
|
||||
```
|
||||
|
||||
## Custom hostname and path
|
||||
|
||||
It is possible to define a custom hostname and path that will be used to serve a function in a specific endpoint. For doing this, it is necessary to have an [Ingress Controller](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-controllers) available in the cluster.
|
||||
|
||||
```yml
|
||||
provider:
|
||||
name: kubeless
|
||||
hostname: myhostname.io
|
||||
plugins:
|
||||
- serverless-kubeless
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
events:
|
||||
- http:
|
||||
path: /hello
|
||||
```
|
||||
|
||||
In the example above, once the Ingress Rule has been processed by the Ingress controller, you can call the function using as endpoing `myhostname.io/hello`.
|
||||
|
||||
If no hostname is given but a function specifies a `path`, the plugin will use the IP of the cluster followed by a DNS mapping service. By default [nip.io](http://nip.io) will be used but this can be configured with the property `defaultDNSResolution`.
|
||||
|
||||
```yml
|
||||
provider:
|
||||
name: kubeless
|
||||
defaultDNSResolution: 'xip.io'
|
||||
plugins:
|
||||
- serverless-kubeless
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
events:
|
||||
- http:
|
||||
path: /hello
|
||||
```
|
||||
|
||||
The above will result in an endpoint like `1.2.3.4.xip.io/hello` where `1.2.3.4` is the IP of the cluster server.
|
||||
|
||||
The final URL in which the function will be listening can be retrieved executing `serverless info`.
|
||||
|
||||
## Custom images (alpha feature)
|
||||
|
||||
It is possible to skip the Kubeless build system and specify a prebuilt image to run a function. This feature is useful for using Kubeless with languages that are still not supported or if the function package [is over 1MB](./packaging.md#package-maximum-size). To get more information about how to use custom images visit the [upstream documentation](https://github.com/kubeless/kubeless/blob/master/docs/runtimes.md#custom-runtime-alpha).
|
||||
|
||||
```yml
|
||||
service: hello
|
||||
|
||||
provider:
|
||||
name: kubeless
|
||||
runtime: python2.7
|
||||
|
||||
plugins:
|
||||
- serverless-kubeless
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
image: tuna/kubeless-python:0.0.6
|
||||
```
|
||||
|
||||
144
docs/providers/kubeless/guide/packaging.md
Normal file
144
docs/providers/kubeless/guide/packaging.md
Normal file
@ -0,0 +1,144 @@
|
||||
<!--
|
||||
title: Serverless Framework - Kubeless Guide - Packaging
|
||||
menuText: Packaging
|
||||
menuOrder: 10
|
||||
description: How the Serverless Framework packages your Kubeless functions and other available options
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
<!-- DOCS-SITE-LINK:START automatically generated -->
|
||||
### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/kubeless/guide/packaging)
|
||||
<!-- DOCS-SITE-LINK:END -->
|
||||
|
||||
# Kubeless - Packaging
|
||||
|
||||
## Package CLI Command
|
||||
|
||||
Using the Serverless CLI tool, you can package your project without deploying with Kubeless. This is best used with CI / CD workflows to ensure consistent deployable artifacts.
|
||||
|
||||
Running the following command will build and save all of the deployment artifacts in the service's .serverless directory:
|
||||
|
||||
```bash
|
||||
serverless package
|
||||
```
|
||||
|
||||
However, you can also use the --package option to add a destination path and Serverless will store your deployment artifacts there (./my-artifacts in the following case):
|
||||
|
||||
```bash
|
||||
serverless package --package my-artifacts
|
||||
```
|
||||
|
||||
## Package Maximum Size
|
||||
|
||||
Kubeless uses [Kubernetes ConfigMaps](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) to store functions configuration and code. These ConfigMaps have a limitation in size of one MB since they are stored as a single entry in a `etcd` database. Due to this limitation, the maximum possible size for a Kubeless function package is no more than one MB. Note that only code and configuration files should be included in this package, dependencies will be installed during the build process. If your function package size is over one MB please [exclude some directories](#exclude-include) or create a [custom image](./functions#custom-images-alpha-feature) with your function. By default, files under the `node_modules` folder will be excluded.
|
||||
|
||||
## Package Configuration
|
||||
|
||||
Sometimes you might like to have more control over your function artifacts and how they are packaged.
|
||||
|
||||
You can use the `package` and `exclude` configuration for more control over the packaging process.
|
||||
|
||||
### Exclude / include
|
||||
|
||||
Exclude and include allows you to define globs that will be excluded / included from the resulting artifact. If you wish to
|
||||
include files you can use a glob pattern prefixed with `!` such as `!re-include-me/**` in `exclude` or the dedicated `include` config.
|
||||
Serverless will run the glob patterns in order.
|
||||
|
||||
At first it will apply the globs defined in `exclude`. After that it'll add all the globs from `include`. This way you can always re-include
|
||||
previously excluded files and directories.
|
||||
|
||||
### Examples
|
||||
|
||||
Exclude all node_modules but then re-include a specific modules (in this case node-fetch) using `exclude` exclusively
|
||||
|
||||
``` yml
|
||||
package:
|
||||
exclude:
|
||||
- node_modules/**
|
||||
- '!node_modules/node-fetch/**'
|
||||
```
|
||||
|
||||
Exclude all files but `handler.js` using `exclude` and `include`
|
||||
|
||||
``` yml
|
||||
package:
|
||||
exclude:
|
||||
- src/**
|
||||
include:
|
||||
- src/function/handler.js
|
||||
```
|
||||
|
||||
**Note:** Don't forget to use the correct glob syntax if you want to exclude directories
|
||||
|
||||
```
|
||||
exclude:
|
||||
- tmp/**
|
||||
- .git/**
|
||||
```
|
||||
|
||||
### Artifact
|
||||
|
||||
For complete control over the packaging process you can specify your own artifact zip file.
|
||||
Serverless won't zip your service if this is configured and therefore `exclude` and `include` will be ignored. Either you use artifact or include / exclude.
|
||||
|
||||
The artifact option is especially useful in case your development environment allows you to generate a deployable artifact like Maven does for Java.
|
||||
|
||||
### Example
|
||||
|
||||
```yml
|
||||
service: my-service
|
||||
package:
|
||||
artifact: path/to/my-artifact.zip
|
||||
```
|
||||
|
||||
### Packaging functions separately
|
||||
|
||||
If you want even more controls over your functions for deployment you can configure them to be packaged independently. This allows you more control for optimizing your deployment. To enable individual packaging set `individually` to true in the service or function wide packaging settings.
|
||||
|
||||
Then for every function you can use the same `exclude`, `include` or `artifact` config options as you can service wide. The `exclude` and `include` option will be merged with the service wide options to create one `exclude` and `include` config per function during packaging.
|
||||
|
||||
```yml
|
||||
service: my-service
|
||||
package:
|
||||
individually: true
|
||||
exclude:
|
||||
- excluded-by-default.json
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
package:
|
||||
# We're including this file so it will be in the final package of this function only
|
||||
include:
|
||||
- excluded-by-default.json
|
||||
world:
|
||||
handler: handler.hello
|
||||
package:
|
||||
exclude:
|
||||
- some-file.js
|
||||
```
|
||||
|
||||
You can also select which functions to be packaged separately, and have the rest use the service package by setting the `individually` flag at the function level:
|
||||
|
||||
```yml
|
||||
service: my-service
|
||||
functions:
|
||||
hello:
|
||||
handler: handler.hello
|
||||
world:
|
||||
handler: handler.hello
|
||||
package:
|
||||
individually: true
|
||||
```
|
||||
|
||||
### Development dependencies
|
||||
|
||||
Serverless will auto-detect and exclude development dependencies based on the runtime your service is using.
|
||||
|
||||
This ensures that only the production relevant packages and modules are included in your zip file. Doing this drastically reduces the overall size of the deployment package which will be uploaded to the cloud provider.
|
||||
|
||||
You can opt-out of automatic dev dependency exclusion by setting the `excludeDevDependencies` package config to `false`:
|
||||
|
||||
```yml
|
||||
package:
|
||||
excludeDevDependencies: false
|
||||
```
|
||||
@ -35,4 +35,4 @@ In your terminal window you should see the response from Apache OpenWhisk
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and run your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -35,4 +35,4 @@ In your terminal window you should see the response from Apache OpenWhisk
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and run your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -35,4 +35,4 @@ In your terminal window you should see the response from Apache OpenWhisk
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and run your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -35,4 +35,4 @@ In your terminal window you should see the response from Apache OpenWhisk
|
||||
}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and run your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
@ -32,7 +32,7 @@ In your terminal window you should see the response
|
||||
{"hello":"null"}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and ran your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
## Short Hand Guide
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ In your terminal window you should see the response
|
||||
{"hello":"from NodeJS8.3 function"}
|
||||
```
|
||||
|
||||
Congrats you have just deployed and ran your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
## Short Hand Guide
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ In your terminal window you should see the response
|
||||
'{"hello":"from Python2.7 function"}'
|
||||
```
|
||||
|
||||
Congrats you have just deployed and ran your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
## Short Hand Guide
|
||||
|
||||
|
||||
@ -11,21 +11,21 @@ layout: Doc
|
||||
|
||||
# Hello World Ruby Example
|
||||
|
||||
Make sure `serverless` is installed.
|
||||
Make sure `serverless` is installed.
|
||||
|
||||
## 1. Create a service
|
||||
`serverless create --template spotinst-ruby --path serviceName` `serviceName` is going to be a new directory there the Ruby template will be loaded. Once the download is complete change into that directory. Next you will need to install the Spotinst Serverless Functions plugin by running `npm install` in the root directory. You will need to go into the serverless.yml file and add in the environment variable that you want to deploy into.
|
||||
|
||||
|
||||
## 2. Deploy
|
||||
```bash
|
||||
```bash
|
||||
serverless deploy
|
||||
```
|
||||
|
||||
## 3. Invoke deployed function
|
||||
```bash
|
||||
serverless invoke --function hello
|
||||
```
|
||||
```
|
||||
|
||||
In your terminal window you should see the response
|
||||
|
||||
@ -33,14 +33,14 @@ In your terminal window you should see the response
|
||||
'{"hello":"from Ruby2.4.1 function"}'
|
||||
```
|
||||
|
||||
Congrats you have just deployed and ran your Hello World function!
|
||||
Congrats you have deployed and ran your Hello World function!
|
||||
|
||||
## Short Hand Guide
|
||||
|
||||
`sls` is short hand for serverless cli commands
|
||||
`sls` is short hand for serverless cli commands
|
||||
|
||||
`-f` is short hand for `--function`
|
||||
|
||||
`-t` is short hand for `--template`
|
||||
|
||||
`-p` is short hang for `--path`
|
||||
`-p` is short hang for `--path`
|
||||
|
||||
@ -19,7 +19,7 @@ const writeMessage = (messageType, message) => {
|
||||
consoleLog(' ');
|
||||
|
||||
if (message) {
|
||||
consoleLog(chalk.white(` ${message}`));
|
||||
consoleLog(` ${message}`);
|
||||
}
|
||||
|
||||
consoleLog(' ');
|
||||
@ -61,17 +61,16 @@ module.exports.logError = (e) => {
|
||||
consoleLog(' ');
|
||||
}
|
||||
|
||||
const platform = chalk.white(process.platform);
|
||||
const nodeVersion = chalk.white(process.version.replace(/^[v|V]/, ''));
|
||||
const slsVersion = chalk.white(version);
|
||||
const platform = process.platform;
|
||||
const nodeVersion = process.version.replace(/^[v|V]/, '');
|
||||
const slsVersion = version;
|
||||
|
||||
consoleLog(chalk.yellow(' Get Support --------------------------------------------'));
|
||||
consoleLog(`${chalk.yellow(' Docs: ')}${chalk.white('docs.serverless.com')}`);
|
||||
consoleLog(`${chalk.yellow(' Bugs: ')}${chalk
|
||||
.white('github.com/serverless/serverless/issues')}`);
|
||||
consoleLog(`${chalk.yellow(' Forums: ')}${chalk.white('forum.serverless.com')}`);
|
||||
consoleLog(`${chalk.yellow(' Chat: ')}${chalk
|
||||
.white('gitter.im/serverless/serverless')}`);
|
||||
consoleLog(`${chalk.yellow(' Docs: ')}${'docs.serverless.com'}`);
|
||||
consoleLog(`${chalk.yellow(' Bugs: ')}${
|
||||
'github.com/serverless/serverless/issues'}`);
|
||||
consoleLog(`${chalk.yellow(' Forums: ')}${'forum.serverless.com'}`);
|
||||
consoleLog(`${chalk.yellow(' Chat: ')}${'gitter.im/serverless/serverless'}`);
|
||||
|
||||
consoleLog(' ');
|
||||
consoleLog(chalk.yellow(' Your Environment Information -----------------------------'));
|
||||
|
||||
@ -6,7 +6,6 @@ const path = require('path');
|
||||
const AwsProvider = require('../../provider/awsProvider');
|
||||
const AwsDeploy = require('../index');
|
||||
const Serverless = require('../../../../Serverless');
|
||||
const BbPromise = require('bluebird');
|
||||
const testUtils = require('../../../../../tests/utils');
|
||||
|
||||
describe('createStack', () => {
|
||||
@ -98,8 +97,7 @@ describe('createStack', () => {
|
||||
|
||||
it('should set the createLater flag and resolve if deployment bucket is provided', () => {
|
||||
awsDeploy.serverless.service.provider.deploymentBucket = 'serverless';
|
||||
sandbox.stub(awsDeploy.provider, 'request')
|
||||
.returns(BbPromise.reject({ message: 'does not exist' }));
|
||||
sandbox.stub(awsDeploy.provider, 'request').rejects(new Error('does not exist'));
|
||||
|
||||
return awsDeploy.createStack().then(() => {
|
||||
expect(awsDeploy.createLater).to.equal(true);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const chai = require('chai');
|
||||
const sinon = require('sinon');
|
||||
const path = require('path');
|
||||
const AwsProvider = require('../../provider/awsProvider');
|
||||
@ -8,6 +8,10 @@ const AwsDeploy = require('../index');
|
||||
const Serverless = require('../../../../Serverless');
|
||||
const testUtils = require('../../../../../tests/utils');
|
||||
|
||||
chai.use(require('sinon-chai'));
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
describe('extendedValidate', () => {
|
||||
let awsDeploy;
|
||||
const tmpDirPath = testUtils.getTmpDirPath();
|
||||
@ -60,8 +64,8 @@ describe('extendedValidate', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
awsDeploy.serverless.utils.fileExistsSync.restore();
|
||||
awsDeploy.serverless.utils.readFileSync.restore();
|
||||
fileExistsSyncStub.restore();
|
||||
readFileSyncStub.restore();
|
||||
});
|
||||
|
||||
it('should throw error if state file does not exist', () => {
|
||||
|
||||
@ -90,8 +90,8 @@ describe('uploadArtifacts', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
normalizeFiles.normalizeCloudFormationTemplate.restore();
|
||||
awsDeploy.provider.request.restore();
|
||||
normalizeCloudFormationTemplateStub.restore();
|
||||
uploadStub.restore();
|
||||
});
|
||||
|
||||
it('should upload the CloudFormation file to the S3 bucket', () => {
|
||||
@ -159,8 +159,8 @@ describe('uploadArtifacts', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fs.readFileSync.restore();
|
||||
awsDeploy.provider.request.restore();
|
||||
readFileSyncStub.restore();
|
||||
uploadStub.restore();
|
||||
});
|
||||
|
||||
it('should throw for null artifact paths', () => {
|
||||
@ -265,7 +265,7 @@ describe('uploadArtifacts', () => {
|
||||
.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();
|
||||
uploadZipFileStub.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@ -286,7 +286,7 @@ describe('uploadArtifacts', () => {
|
||||
|
||||
const uploadZipFileStub = sinon
|
||||
.stub(awsDeploy, 'uploadZipFile').resolves();
|
||||
sinon.stub(fs, 'statSync').returns({ size: 1024 });
|
||||
const statSyncStub = sinon.stub(fs, 'statSync').returns({ size: 1024 });
|
||||
|
||||
return awsDeploy.uploadFunctions().then(() => {
|
||||
expect(uploadZipFileStub.calledTwice).to.be.equal(true);
|
||||
@ -294,8 +294,9 @@ describe('uploadArtifacts', () => {
|
||||
.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();
|
||||
fs.statSync.restore();
|
||||
}).finally(() => {
|
||||
uploadZipFileStub.restore();
|
||||
statSyncStub.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@ -303,16 +304,16 @@ 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();
|
||||
const statSyncStub = sinon.stub(fs, 'statSync').returns({ size: 1024 });
|
||||
const uploadZipFileStub = 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);
|
||||
|
||||
fs.statSync.restore();
|
||||
awsDeploy.uploadZipFile.restore();
|
||||
}).finally(() => {
|
||||
statSyncStub.restore();
|
||||
uploadZipFileStub.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -83,12 +83,12 @@ class AwsInvoke {
|
||||
}
|
||||
|
||||
log(invocationReply) {
|
||||
const color = !invocationReply.FunctionError ? 'white' : 'red';
|
||||
const color = !invocationReply.FunctionError ? (x => x) : chalk.red;
|
||||
|
||||
if (invocationReply.Payload) {
|
||||
const response = JSON.parse(invocationReply.Payload);
|
||||
|
||||
this.consoleLog(chalk[color](JSON.stringify(response, null, 4)));
|
||||
this.consoleLog(color(JSON.stringify(response, null, 4)));
|
||||
}
|
||||
|
||||
if (invocationReply.LogResult) {
|
||||
|
||||
@ -6,7 +6,6 @@ const path = require('path');
|
||||
const AwsInvoke = require('./index');
|
||||
const AwsProvider = require('../provider/awsProvider');
|
||||
const Serverless = require('../../../Serverless');
|
||||
const chalk = require('chalk');
|
||||
const testUtils = require('../../../../tests/utils');
|
||||
|
||||
describe('AwsInvoke', () => {
|
||||
@ -271,7 +270,7 @@ describe('AwsInvoke', () => {
|
||||
};
|
||||
|
||||
return awsInvoke.log(invocationReplyMock).then(() => {
|
||||
const expectedPayloadMessage = `${chalk.white('{\n "testProp": "testValue"\n}')}`;
|
||||
const expectedPayloadMessage = '{\n "testProp": "testValue"\n}';
|
||||
|
||||
expect(consoleLogStub.calledWith(expectedPayloadMessage)).to.equal(true);
|
||||
});
|
||||
|
||||
@ -282,8 +282,9 @@ module.exports = {
|
||||
getLambdaApiGatewayPermissionLogicalId(functionName) {
|
||||
return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionApiGateway`;
|
||||
},
|
||||
getLambdaAlexaSkillPermissionLogicalId(functionName) {
|
||||
return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionAlexaSkill`;
|
||||
getLambdaAlexaSkillPermissionLogicalId(functionName, alexaSkillIndex) {
|
||||
return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionAlexaSkill${
|
||||
alexaSkillIndex || '0'}`;
|
||||
},
|
||||
getLambdaAlexaSmartHomePermissionLogicalId(functionName, alexaSmartHomeIndex) {
|
||||
return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionAlexaSmartHome${
|
||||
|
||||
@ -464,9 +464,15 @@ describe('#naming()', () => {
|
||||
|
||||
describe('#getLambdaAlexaSkillPermissionLogicalId()', () => {
|
||||
it('should normalize the function name and append the standard suffix',
|
||||
() => {
|
||||
expect(sdk.naming.getLambdaAlexaSkillPermissionLogicalId('functionName', 2))
|
||||
.to.equal('FunctionNameLambdaPermissionAlexaSkill2');
|
||||
});
|
||||
|
||||
it('should normalize the function name and append a default suffix if not defined',
|
||||
() => {
|
||||
expect(sdk.naming.getLambdaAlexaSkillPermissionLogicalId('functionName'))
|
||||
.to.equal('FunctionNameLambdaPermissionAlexaSkill');
|
||||
.to.equal('FunctionNameLambdaPermissionAlexaSkill0');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -15,10 +15,45 @@ class AwsCompileAlexaSkillEvents {
|
||||
compileAlexaSkillEvents() {
|
||||
this.serverless.service.getAllFunctions().forEach((functionName) => {
|
||||
const functionObj = this.serverless.service.getFunction(functionName);
|
||||
let alexaSkillNumberInFunction = 0;
|
||||
|
||||
if (functionObj.events) {
|
||||
functionObj.events.forEach(event => {
|
||||
if (event === 'alexaSkill') {
|
||||
if (event === 'alexaSkill' || event.alexaSkill) {
|
||||
let enabled = true;
|
||||
let appId;
|
||||
if (event === 'alexaSkill') {
|
||||
const warningMessage = [
|
||||
'Warning! You are using an old syntax for alexaSkill which doesn\'t',
|
||||
' restrict the invocation solely to your skill.',
|
||||
' Please refer to the documentation for additional information.',
|
||||
].join('');
|
||||
this.serverless.cli.log(warningMessage);
|
||||
} else if (_.isString(event.alexaSkill)) {
|
||||
appId = event.alexaSkill;
|
||||
} else if (_.isPlainObject(event.alexaSkill)) {
|
||||
if (!_.isString(event.alexaSkill.appId)) {
|
||||
const errorMessage = [
|
||||
`Missing "appId" property for alexaSkill event in function ${functionName}`,
|
||||
' The correct syntax is: appId: amzn1.ask.skill.xx-xx-xx-xx-xx',
|
||||
' OR an object with "appId" property.',
|
||||
' Please check the docs for more info.',
|
||||
].join('');
|
||||
throw new this.serverless.classes.Error(errorMessage);
|
||||
}
|
||||
appId = event.alexaSkill.appId;
|
||||
// Parameter `enabled` is optional, hence the explicit non-equal check for false.
|
||||
enabled = event.alexaSkill.enabled !== false;
|
||||
} else {
|
||||
const errorMessage = [
|
||||
`Alexa Skill event of function "${functionName}" is not an object or string.`,
|
||||
' The correct syntax is: alexaSkill.',
|
||||
' Please check the docs for more info.',
|
||||
].join('');
|
||||
throw new this.serverless.classes.Error(errorMessage);
|
||||
}
|
||||
alexaSkillNumberInFunction++;
|
||||
|
||||
const lambdaLogicalId = this.provider.naming
|
||||
.getLambdaLogicalId(functionName);
|
||||
|
||||
@ -31,13 +66,18 @@ class AwsCompileAlexaSkillEvents {
|
||||
'Arn',
|
||||
],
|
||||
},
|
||||
Action: 'lambda:InvokeFunction',
|
||||
Action: enabled ? 'lambda:InvokeFunction' : 'lambda:DisableInvokeFunction',
|
||||
Principal: 'alexa-appkit.amazon.com',
|
||||
},
|
||||
};
|
||||
|
||||
if (appId) {
|
||||
permissionTemplate.Properties.EventSourceToken = appId.replace(/\\n|\\r/g, '');
|
||||
}
|
||||
|
||||
const lambdaPermissionLogicalId = this.provider.naming
|
||||
.getLambdaAlexaSkillPermissionLogicalId(functionName);
|
||||
.getLambdaAlexaSkillPermissionLogicalId(functionName,
|
||||
alexaSkillNumberInFunction);
|
||||
|
||||
const permissionCloudForamtionResource = {
|
||||
[lambdaPermissionLogicalId]: permissionTemplate,
|
||||
@ -45,13 +85,6 @@ class AwsCompileAlexaSkillEvents {
|
||||
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
|
||||
permissionCloudForamtionResource);
|
||||
} else if (event.alexaSkill) {
|
||||
const errorMessage = [
|
||||
`Alexa Skill event of function "${functionName}" is not an object or string.`,
|
||||
' The correct syntax is: alexaSkill.',
|
||||
' Please check the docs for more info.',
|
||||
].join('');
|
||||
throw new this.serverless.classes.Error(errorMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint-disable no-unused-expressions */
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../../../provider/awsProvider');
|
||||
const AwsCompileAlexaSkillEvents = require('./index');
|
||||
@ -8,11 +10,19 @@ const Serverless = require('../../../../../../Serverless');
|
||||
describe('AwsCompileAlexaSkillEvents', () => {
|
||||
let serverless;
|
||||
let awsCompileAlexaSkillEvents;
|
||||
let consolePrinted;
|
||||
|
||||
beforeEach(() => {
|
||||
serverless = new Serverless();
|
||||
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
|
||||
serverless.setProvider('aws', new AwsProvider(serverless));
|
||||
consolePrinted = '';
|
||||
serverless.cli = {
|
||||
// serverless.cli isn't available in tests, so we will mimic it.
|
||||
log: txt => {
|
||||
consolePrinted += `${txt}\r\n`;
|
||||
},
|
||||
};
|
||||
awsCompileAlexaSkillEvents = new AwsCompileAlexaSkillEvents(serverless);
|
||||
});
|
||||
|
||||
@ -25,7 +35,42 @@ describe('AwsCompileAlexaSkillEvents', () => {
|
||||
});
|
||||
|
||||
describe('#compileAlexaSkillEvents()', () => {
|
||||
it('should throw an error if alexaSkill event is not an string', () => {
|
||||
it('should show a warning if alexaSkill appId is not specified', () => {
|
||||
awsCompileAlexaSkillEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
'alexaSkill',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
awsCompileAlexaSkillEvents.compileAlexaSkillEvents();
|
||||
|
||||
expect(consolePrinted).to.contain.string('old syntax for alexaSkill');
|
||||
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Type
|
||||
).to.equal('AWS::Lambda::Permission');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.FunctionName
|
||||
).to.deep.equal({ 'Fn::GetAtt': ['FirstLambdaFunction', 'Arn'] });
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.Action
|
||||
).to.equal('lambda:InvokeFunction');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.Principal
|
||||
).to.equal('alexa-appkit.amazon.com');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.EventSourceToken
|
||||
).to.be.undefined;
|
||||
});
|
||||
|
||||
it('should throw an error if alexaSkill event is not a string or an object', () => {
|
||||
awsCompileAlexaSkillEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
@ -39,11 +84,36 @@ describe('AwsCompileAlexaSkillEvents', () => {
|
||||
expect(() => awsCompileAlexaSkillEvents.compileAlexaSkillEvents()).to.throw(Error);
|
||||
});
|
||||
|
||||
it('should create corresponding resources when a alexaSkill event is provided', () => {
|
||||
it('should throw an error if alexaSkill event appId is not a string', () => {
|
||||
awsCompileAlexaSkillEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
'alexaSkill',
|
||||
{
|
||||
alexaSkill: {
|
||||
appId: 42,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
expect(() => awsCompileAlexaSkillEvents.compileAlexaSkillEvents()).to.throw(Error);
|
||||
});
|
||||
|
||||
it('should create corresponding resources when multiple alexaSkill events are provided', () => {
|
||||
const skillId1 = 'amzn1.ask.skill.xx-xx-xx-xx';
|
||||
const skillId2 = 'amzn1.ask.skill.yy-yy-yy-yy';
|
||||
awsCompileAlexaSkillEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
{
|
||||
alexaSkill: skillId1,
|
||||
},
|
||||
{
|
||||
alexaSkill: {
|
||||
appId: skillId2,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@ -52,20 +122,84 @@ describe('AwsCompileAlexaSkillEvents', () => {
|
||||
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill.Type
|
||||
.FirstLambdaPermissionAlexaSkill1.Type
|
||||
).to.equal('AWS::Lambda::Permission');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill.Properties.FunctionName
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.FunctionName
|
||||
).to.deep.equal({ 'Fn::GetAtt': ['FirstLambdaFunction', 'Arn'] });
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill.Properties.Action
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.Action
|
||||
).to.equal('lambda:InvokeFunction');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill.Properties.Principal
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.Principal
|
||||
).to.equal('alexa-appkit.amazon.com');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.EventSourceToken
|
||||
).to.equal(skillId1);
|
||||
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill2.Type
|
||||
).to.equal('AWS::Lambda::Permission');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill2.Properties.FunctionName
|
||||
).to.deep.equal({ 'Fn::GetAtt': ['FirstLambdaFunction', 'Arn'] });
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill2.Properties.Action
|
||||
).to.equal('lambda:InvokeFunction');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill2.Properties.Principal
|
||||
).to.equal('alexa-appkit.amazon.com');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill2.Properties.EventSourceToken
|
||||
).to.equal(skillId2);
|
||||
});
|
||||
|
||||
it('should create corresponding resources when a disabled alexaSkill event is provided', () => {
|
||||
const skillId1 = 'amzn1.ask.skill.xx-xx-xx-xx';
|
||||
awsCompileAlexaSkillEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
{
|
||||
alexaSkill: {
|
||||
appId: skillId1,
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
awsCompileAlexaSkillEvents.compileAlexaSkillEvents();
|
||||
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Type
|
||||
).to.equal('AWS::Lambda::Permission');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.FunctionName
|
||||
).to.deep.equal({ 'Fn::GetAtt': ['FirstLambdaFunction', 'Arn'] });
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.Action
|
||||
).to.equal('lambda:DisableInvokeFunction');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.Principal
|
||||
).to.equal('alexa-appkit.amazon.com');
|
||||
expect(awsCompileAlexaSkillEvents.serverless.service
|
||||
.provider.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionAlexaSkill1.Properties.EventSourceToken
|
||||
).to.equal(skillId1);
|
||||
});
|
||||
|
||||
it('should not create corresponding resources when alexaSkill event is not given', () => {
|
||||
@ -82,5 +216,22 @@ describe('AwsCompileAlexaSkillEvents', () => {
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
).to.deep.equal({});
|
||||
});
|
||||
|
||||
it('should not not throw error when other events are present', () => {
|
||||
awsCompileAlexaSkillEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
{
|
||||
http: {
|
||||
method: 'get',
|
||||
path: '/',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
expect(() => awsCompileAlexaSkillEvents.compileAlexaSkillEvents()).to.not.throw();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -20,19 +20,20 @@ class AwsCompileCognitoUserPoolEvents {
|
||||
|
||||
this.hooks = {
|
||||
'package:compileEvents': this.compileCognitoUserPoolEvents.bind(this),
|
||||
'after:package:finalize': this.mergeWithCustomResources.bind(this),
|
||||
};
|
||||
}
|
||||
|
||||
compileCognitoUserPoolEvents() {
|
||||
findUserPoolsAndFunctions() {
|
||||
const userPools = [];
|
||||
const cognitoUserPoolTriggerFunctions = [];
|
||||
|
||||
// Iterate through all functions declared in `serverless.yml`
|
||||
this.serverless.service.getAllFunctions().forEach((functionName) => {
|
||||
_.forEach(this.serverless.service.getAllFunctions(), (functionName) => {
|
||||
const functionObj = this.serverless.service.getFunction(functionName);
|
||||
|
||||
if (functionObj.events) {
|
||||
functionObj.events.forEach(event => {
|
||||
_.forEach(functionObj.events, (event) => {
|
||||
if (event.cognitoUserPool) {
|
||||
// Check event definition for `cognitoUserPool` object
|
||||
if (typeof event.cognitoUserPool === 'object') {
|
||||
@ -80,51 +81,61 @@ class AwsCompileCognitoUserPoolEvents {
|
||||
}
|
||||
});
|
||||
|
||||
// Generate CloudFormation templates for Cognito User Pool changes
|
||||
_.forEach(userPools, (poolName) => {
|
||||
// Create a `LambdaConfig` object for the CloudFormation template
|
||||
const currentPoolTriggerFunctions = _.filter(cognitoUserPoolTriggerFunctions, {
|
||||
poolName,
|
||||
return { cognitoUserPoolTriggerFunctions, userPools };
|
||||
}
|
||||
|
||||
generateTemplateForPool(poolName, currentPoolTriggerFunctions) {
|
||||
const lambdaConfig = _.reduce(currentPoolTriggerFunctions, (result, value) => {
|
||||
const lambdaLogicalId = this.provider.naming.getLambdaLogicalId(value.functionName);
|
||||
|
||||
// Return a new object to avoid lint errors
|
||||
return Object.assign({}, result, {
|
||||
[value.triggerSource]: {
|
||||
'Fn::GetAtt': [
|
||||
lambdaLogicalId,
|
||||
'Arn',
|
||||
],
|
||||
},
|
||||
});
|
||||
}, {});
|
||||
|
||||
const lambdaConfig = _.reduce(currentPoolTriggerFunctions, (result, value) => {
|
||||
const lambdaLogicalId = this.provider.naming.getLambdaLogicalId(value.functionName);
|
||||
const userPoolLogicalId = this.provider.naming.getCognitoUserPoolLogicalId(poolName);
|
||||
|
||||
// Return a new object to avoid lint errors
|
||||
return Object.assign({}, result, {
|
||||
[value.triggerSource]: {
|
||||
'Fn::GetAtt': [
|
||||
lambdaLogicalId,
|
||||
'Arn',
|
||||
],
|
||||
},
|
||||
});
|
||||
}, {});
|
||||
// Attach `DependsOn` for any relevant Lambdas
|
||||
const DependsOn = _.map(currentPoolTriggerFunctions, (value) => this
|
||||
.provider.naming.getLambdaLogicalId(value.functionName));
|
||||
|
||||
const userPoolLogicalId = this.provider.naming.getCognitoUserPoolLogicalId(poolName);
|
||||
|
||||
const DependsOn = _.map(currentPoolTriggerFunctions, (value) => this
|
||||
.provider.naming.getLambdaLogicalId(value.functionName));
|
||||
|
||||
const userPoolTemplate = {
|
||||
return {
|
||||
[userPoolLogicalId]: {
|
||||
Type: 'AWS::Cognito::UserPool',
|
||||
Properties: {
|
||||
UserPoolName: poolName,
|
||||
LambdaConfig: lambdaConfig,
|
||||
},
|
||||
DependsOn,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const userPoolCFResource = {
|
||||
[userPoolLogicalId]: userPoolTemplate,
|
||||
};
|
||||
compileCognitoUserPoolEvents() {
|
||||
const result = this.findUserPoolsAndFunctions();
|
||||
const cognitoUserPoolTriggerFunctions = result.cognitoUserPoolTriggerFunctions;
|
||||
const userPools = result.userPools;
|
||||
|
||||
// Generate CloudFormation templates for Cognito User Pool changes
|
||||
_.forEach(userPools, (poolName) => {
|
||||
const currentPoolTriggerFunctions = _.filter(cognitoUserPoolTriggerFunctions, { poolName });
|
||||
const userPoolCFResource = this.generateTemplateForPool(
|
||||
poolName,
|
||||
currentPoolTriggerFunctions
|
||||
);
|
||||
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
|
||||
userPoolCFResource);
|
||||
});
|
||||
|
||||
// Generate CloudFormation templates for IAM permissions to allow Cognito to trigger Lambda
|
||||
cognitoUserPoolTriggerFunctions.forEach((cognitoUserPoolTriggerFunction) => {
|
||||
_.forEach(cognitoUserPoolTriggerFunctions, (cognitoUserPoolTriggerFunction) => {
|
||||
const userPoolLogicalId = this.provider.naming
|
||||
.getCognitoUserPoolLogicalId(cognitoUserPoolTriggerFunction.poolName);
|
||||
const lambdaLogicalId = this.provider.naming
|
||||
@ -159,6 +170,43 @@ class AwsCompileCognitoUserPoolEvents {
|
||||
permissionCFResource);
|
||||
});
|
||||
}
|
||||
|
||||
mergeWithCustomResources() {
|
||||
const result = this.findUserPoolsAndFunctions();
|
||||
const cognitoUserPoolTriggerFunctions = result.cognitoUserPoolTriggerFunctions;
|
||||
const userPools = result.userPools;
|
||||
|
||||
_.forEach(userPools, (poolName) => {
|
||||
const currentPoolTriggerFunctions = _.filter(cognitoUserPoolTriggerFunctions, { poolName });
|
||||
const userPoolLogicalId = this.provider.naming.getCognitoUserPoolLogicalId(poolName);
|
||||
|
||||
// If overrides exist in `Resources`, merge them in
|
||||
if (_.has(this.serverless.service.resources, userPoolLogicalId)) {
|
||||
const customUserPool = this.serverless.service.resources[userPoolLogicalId];
|
||||
const generatedUserPool = this.generateTemplateForPool(
|
||||
poolName,
|
||||
currentPoolTriggerFunctions
|
||||
)[userPoolLogicalId];
|
||||
|
||||
// Merge `DependsOn` clauses
|
||||
const customUserPoolDependsOn = _.get(customUserPool, 'DependsOn', []);
|
||||
const DependsOn = generatedUserPool.DependsOn.concat(customUserPoolDependsOn);
|
||||
|
||||
// Merge default and custom resources, and `DependsOn` clause
|
||||
const mergedTemplate = Object.assign(
|
||||
{},
|
||||
_.merge(generatedUserPool, customUserPool),
|
||||
{ DependsOn }
|
||||
);
|
||||
|
||||
// Merge resource back into `Resources`
|
||||
_.merge(
|
||||
this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
|
||||
{ [userPoolLogicalId]: mergedTemplate }
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AwsCompileCognitoUserPoolEvents;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../../../provider/awsProvider');
|
||||
const AwsCompileCognitoUserPoolEvents = require('./index');
|
||||
@ -115,9 +116,15 @@ describe('AwsCompileCognitoUserPoolEvents', () => {
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.DependsOn
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.DependsOn
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionCognitoUserPoolMyUserPool1TriggerSourcePreSignUp.Type
|
||||
@ -153,9 +160,15 @@ describe('AwsCompileCognitoUserPoolEvents', () => {
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.DependsOn
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.DependsOn
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionCognitoUserPoolMyUserPool1TriggerSourcePreSignUp.Type
|
||||
@ -195,6 +208,9 @@ describe('AwsCompileCognitoUserPoolEvents', () => {
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1.DependsOn
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool1
|
||||
.Properties.LambdaConfig.PreSignUp['Fn::GetAtt'][0]
|
||||
@ -204,6 +220,9 @@ describe('AwsCompileCognitoUserPoolEvents', () => {
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2.DependsOn
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources.CognitoUserPoolMyUserPool2
|
||||
.Properties.LambdaConfig.PreSignUp['Fn::GetAtt'][0]
|
||||
@ -250,10 +269,14 @@ describe('AwsCompileCognitoUserPoolEvents', () => {
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(Object.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
expect(_.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Properties.LambdaConfig).length
|
||||
).to.equal(2);
|
||||
.CognitoUserPoolMyUserPool.Properties.LambdaConfig)
|
||||
).to.have.lengthOf(2);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.DependsOn
|
||||
).to.have.lengthOf(2);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionCognitoUserPoolMyUserPoolTriggerSourcePreSignUp.Type
|
||||
@ -279,4 +302,145 @@ describe('AwsCompileCognitoUserPoolEvents', () => {
|
||||
).to.deep.equal({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#mergeWithCustomResources()', () => {
|
||||
it('does not merge if no custom resource is found in Resources', () => {
|
||||
awsCompileCognitoUserPoolEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
{
|
||||
cognitoUserPool: {
|
||||
pool: 'MyUserPool',
|
||||
trigger: 'PreSignUp',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
awsCompileCognitoUserPoolEvents.serverless.service.resources = {};
|
||||
|
||||
awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents();
|
||||
awsCompileCognitoUserPoolEvents.mergeWithCustomResources();
|
||||
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(_.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Properties)
|
||||
).to.have.lengthOf(2);
|
||||
expect(_.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Properties.LambdaConfig)
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionCognitoUserPoolMyUserPoolTriggerSourcePreSignUp.Type
|
||||
).to.equal('AWS::Lambda::Permission');
|
||||
});
|
||||
|
||||
it('should merge custom resources found in Resources', () => {
|
||||
awsCompileCognitoUserPoolEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
{
|
||||
cognitoUserPool: {
|
||||
pool: 'MyUserPool',
|
||||
trigger: 'PreSignUp',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
awsCompileCognitoUserPoolEvents.serverless.service.resources = {
|
||||
CognitoUserPoolMyUserPool: {
|
||||
Type: 'AWS::Cognito::UserPool',
|
||||
Properties: {
|
||||
UserPoolName: 'ProdMyUserPool',
|
||||
MfaConfiguration: 'OFF',
|
||||
EmailVerificationSubject: 'Your verification code',
|
||||
EmailVerificationMessage: 'Your verification code is {####}.',
|
||||
SmsVerificationMessage: 'Your verification code is {####}.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents();
|
||||
awsCompileCognitoUserPoolEvents.mergeWithCustomResources();
|
||||
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(_.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Properties)
|
||||
).to.have.lengthOf(6);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.DependsOn
|
||||
).to.have.lengthOf(1);
|
||||
expect(_.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Properties.LambdaConfig)
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionCognitoUserPoolMyUserPoolTriggerSourcePreSignUp.Type
|
||||
).to.equal('AWS::Lambda::Permission');
|
||||
});
|
||||
|
||||
it('should merge `DependsOn` clauses correctly if being overridden from Resources', () => {
|
||||
awsCompileCognitoUserPoolEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
{
|
||||
cognitoUserPool: {
|
||||
pool: 'MyUserPool',
|
||||
trigger: 'PreSignUp',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
awsCompileCognitoUserPoolEvents.serverless.service.resources = {
|
||||
CognitoUserPoolMyUserPool: {
|
||||
DependsOn: ['Something', 'SomethingElse', ['Nothing', 'NothingAtAll']],
|
||||
Type: 'AWS::Cognito::UserPool',
|
||||
Properties: {
|
||||
UserPoolName: 'ProdMyUserPool',
|
||||
MfaConfiguration: 'OFF',
|
||||
EmailVerificationSubject: 'Your verification code',
|
||||
EmailVerificationMessage: 'Your verification code is {####}.',
|
||||
SmsVerificationMessage: 'Your verification code is {####}.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
awsCompileCognitoUserPoolEvents.compileCognitoUserPoolEvents();
|
||||
awsCompileCognitoUserPoolEvents.mergeWithCustomResources();
|
||||
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Type
|
||||
).to.equal('AWS::Cognito::UserPool');
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.DependsOn
|
||||
).to.have.lengthOf(4);
|
||||
expect(_.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Properties)
|
||||
).to.have.lengthOf(6);
|
||||
expect(_.keys(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.CognitoUserPoolMyUserPool.Properties.LambdaConfig)
|
||||
).to.have.lengthOf(1);
|
||||
expect(awsCompileCognitoUserPoolEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources
|
||||
.FirstLambdaPermissionCognitoUserPoolMyUserPoolTriggerSourcePreSignUp.Type
|
||||
).to.equal('AWS::Lambda::Permission');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -279,6 +279,19 @@ class AwsCompileFunctions {
|
||||
delete newFunction.Properties.VpcConfig;
|
||||
}
|
||||
|
||||
if (functionObject.reservedConcurrency) {
|
||||
if (_.isInteger(functionObject.reservedConcurrency)) {
|
||||
newFunction.Properties.ReservedConcurrentExecutions = functionObject.reservedConcurrency;
|
||||
} else {
|
||||
const errorMessage = [
|
||||
'You should use integer as reservedConcurrency value on function: ',
|
||||
`${newFunction.Properties.FunctionName}`,
|
||||
].join('');
|
||||
|
||||
return BbPromise.reject(new this.serverless.classes.Error(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
newFunction.DependsOn = [this.provider.naming.getLogGroupLogicalId(functionName)]
|
||||
.concat(newFunction.DependsOn || []);
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ describe('AwsCompileFunctions', () => {
|
||||
};
|
||||
serverless = new Serverless(options);
|
||||
serverless.setProvider('aws', new AwsProvider(serverless, options));
|
||||
serverless.cli = new serverless.classes.CLI();
|
||||
awsCompileFunctions = new AwsCompileFunctions(serverless, options);
|
||||
awsCompileFunctions.serverless.service.provider.compiledCloudFormationTemplate = {
|
||||
Resources: {},
|
||||
@ -1730,6 +1731,65 @@ describe('AwsCompileFunctions', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should set function declared reserved concurrency limit', () => {
|
||||
const s3Folder = awsCompileFunctions.serverless.service.package.artifactDirectoryName;
|
||||
const s3FileName = awsCompileFunctions.serverless.service.package.artifact
|
||||
.split(path.sep).pop();
|
||||
awsCompileFunctions.serverless.service.functions = {
|
||||
func: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'new-service-dev-func',
|
||||
reservedConcurrency: 5,
|
||||
},
|
||||
};
|
||||
const compiledFunction = {
|
||||
Type: 'AWS::Lambda::Function',
|
||||
DependsOn: [
|
||||
'FuncLogGroup',
|
||||
'IamRoleLambdaExecution',
|
||||
],
|
||||
Properties: {
|
||||
Code: {
|
||||
S3Key: `${s3Folder}/${s3FileName}`,
|
||||
S3Bucket: { Ref: 'ServerlessDeploymentBucket' },
|
||||
},
|
||||
FunctionName: 'new-service-dev-func',
|
||||
Handler: 'func.function.handler',
|
||||
MemorySize: 1024,
|
||||
ReservedConcurrentExecutions: 5,
|
||||
Role: { 'Fn::GetAtt': ['IamRoleLambdaExecution', 'Arn'] },
|
||||
Runtime: 'nodejs4.3',
|
||||
Timeout: 6,
|
||||
},
|
||||
};
|
||||
|
||||
return expect(awsCompileFunctions.compileFunctions()).to.be.fulfilled
|
||||
.then(() => {
|
||||
expect(
|
||||
awsCompileFunctions.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.FuncLambdaFunction
|
||||
).to.deep.equal(compiledFunction);
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an informative error message if non-integer reserved concurrency limit set ' +
|
||||
'on function', () => {
|
||||
awsCompileFunctions.serverless.service.functions = {
|
||||
func: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'new-service-dev-func',
|
||||
reservedConcurrency: '1',
|
||||
},
|
||||
};
|
||||
|
||||
const errorMessage = [
|
||||
'You should use integer as reservedConcurrency value on function: ',
|
||||
'new-service-dev-func',
|
||||
].join('');
|
||||
|
||||
return expect(awsCompileFunctions.compileFunctions()).to.be.rejectedWith(errorMessage);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#compileRole()', () => {
|
||||
|
||||
@ -328,8 +328,6 @@ class AwsProvider {
|
||||
enableS3TransferAcceleration(credentials) {
|
||||
this.serverless.cli.log('Using S3 Transfer Acceleration Endpoint...');
|
||||
credentials.useAccelerateEndpoint = true; // eslint-disable-line no-param-reassign
|
||||
credentials.signatureVersion = 'v2'; // eslint-disable-line no-param-reassign
|
||||
// see https://github.com/aws/aws-sdk-js/issues/281
|
||||
}
|
||||
|
||||
getRegion() {
|
||||
|
||||
@ -34,7 +34,7 @@ module.exports = (msgParam) => {
|
||||
} else if (!isNaN((new Date(splitted[1])).getTime())) {
|
||||
date = splitted[1];
|
||||
reqId = splitted[2];
|
||||
level = `${chalk.white(splitted[0])}\t`;
|
||||
level = `${splitted[0]}\t`;
|
||||
} else {
|
||||
return msg;
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ describe('#formatLambdaLogEvent()', () => {
|
||||
const momentDate = moment('2016-01-01T12:00:00Z').format('YYYY-MM-DD HH:mm:ss.SSS (Z)');
|
||||
expectedLogMessage += `${chalk.green(momentDate)}\t`;
|
||||
expectedLogMessage += `${chalk.yellow('99c30000-b01a-11e5-93f7-b8e85631a00e')}\t`;
|
||||
expectedLogMessage += `${chalk.white('[INFO]')}\t`;
|
||||
expectedLogMessage += `${'[INFO]'}\t`;
|
||||
expectedLogMessage += 'test';
|
||||
|
||||
expect(formatLambdaLogEvent(pythonLoggerLine)).to.equal(expectedLogMessage);
|
||||
|
||||
@ -28,6 +28,8 @@ const validTemplates = [
|
||||
'aws-scala-sbt',
|
||||
'aws-csharp',
|
||||
'aws-fsharp',
|
||||
'aws-go',
|
||||
'aws-go-dep',
|
||||
'azure-nodejs',
|
||||
'google-nodejs',
|
||||
'kubeless-python',
|
||||
|
||||
@ -726,5 +726,39 @@ describe('Create', () => {
|
||||
expect((/service: my-awesome-service/).test(serverlessYmlfileContent)).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate scaffolding for "aws-go" template', () => {
|
||||
process.chdir(tmpDir);
|
||||
create.options.template = 'aws-go';
|
||||
|
||||
return create.create().then(() => {
|
||||
const dirContent = walkDirSync(tmpDir)
|
||||
.map(elem => elem.replace(path.join(tmpDir, path.sep), ''));
|
||||
|
||||
expect(dirContent).to.include('serverless.yml');
|
||||
expect(dirContent).to.include(path.join('hello', 'main.go'));
|
||||
expect(dirContent).to.include(path.join('world', 'main.go'));
|
||||
expect(dirContent).to.include('Makefile');
|
||||
expect(dirContent).to.include('.gitignore');
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate scaffolding for "aws-go-dep" template', () => {
|
||||
process.chdir(tmpDir);
|
||||
create.options.template = 'aws-go-dep';
|
||||
|
||||
return create.create().then(() => {
|
||||
const dirContent = walkDirSync(tmpDir)
|
||||
.map(elem => elem.replace(path.join(tmpDir, path.sep), ''));
|
||||
|
||||
expect(dirContent).to.include('serverless.yml');
|
||||
expect(dirContent).to.include(path.join('hello', 'main.go'));
|
||||
expect(dirContent).to.include(path.join('world', 'main.go'));
|
||||
expect(dirContent).to.include('Gopkg.toml');
|
||||
expect(dirContent).to.include('Gopkg.lock');
|
||||
expect(dirContent).to.include('Makefile');
|
||||
expect(dirContent).to.include('.gitignore');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -67,7 +67,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -67,7 +67,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
19
lib/plugins/create/templates/aws-go-dep/Gopkg.lock
generated
Normal file
19
lib/plugins/create/templates/aws-go-dep/Gopkg.lock
generated
Normal file
@ -0,0 +1,19 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/aws/aws-lambda-go"
|
||||
packages = [
|
||||
"lambda",
|
||||
"lambda/messages",
|
||||
"lambdacontext"
|
||||
]
|
||||
revision = "6e2e37798efbb1dfd8e9c6681702e683a6046517"
|
||||
version = "v1.0.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "85fa166cc59d0fa113a1517ffbb5dee0f1fa4a6795239936afb18c64364af759"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
25
lib/plugins/create/templates/aws-go-dep/Gopkg.toml
Normal file
25
lib/plugins/create/templates/aws-go-dep/Gopkg.toml
Normal file
@ -0,0 +1,25 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/aws/aws-lambda-go"
|
||||
version = "^1.0.1"
|
||||
4
lib/plugins/create/templates/aws-go-dep/Makefile
Normal file
4
lib/plugins/create/templates/aws-go-dep/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
build:
|
||||
dep ensure
|
||||
env GOOS=linux go build -ldflags="-s -w" -o bin/hello hello/main.go
|
||||
env GOOS=linux go build -ldflags="-s -w" -o bin/world world/main.go
|
||||
8
lib/plugins/create/templates/aws-go-dep/gitignore
Normal file
8
lib/plugins/create/templates/aws-go-dep/gitignore
Normal file
@ -0,0 +1,8 @@
|
||||
# Serverless directories
|
||||
.serverless
|
||||
|
||||
# golang output binary directory
|
||||
bin
|
||||
|
||||
# golang vendor (dependencies) directory
|
||||
vendor
|
||||
19
lib/plugins/create/templates/aws-go-dep/hello/main.go
Normal file
19
lib/plugins/create/templates/aws-go-dep/hello/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-lambda-go/lambda"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func Handler() (Response, error) {
|
||||
return Response{
|
||||
Message: "Go Serverless v1.0! Your function executed successfully!",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
lambda.Start(Handler)
|
||||
}
|
||||
104
lib/plugins/create/templates/aws-go-dep/serverless.yml
Normal file
104
lib/plugins/create/templates/aws-go-dep/serverless.yml
Normal file
@ -0,0 +1,104 @@
|
||||
# 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-go-dep # 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: go1.x
|
||||
|
||||
# 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
|
||||
|
||||
package:
|
||||
exclude:
|
||||
- ./**
|
||||
include:
|
||||
- ./bin/**
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: bin/hello
|
||||
world:
|
||||
handler: bin/world
|
||||
|
||||
# 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:
|
||||
# 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
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
# - cloudwatchEvent:
|
||||
# event:
|
||||
# source:
|
||||
# - "aws.ec2"
|
||||
# detail-type:
|
||||
# - "EC2 Instance State-change Notification"
|
||||
# detail:
|
||||
# state:
|
||||
# - pending
|
||||
# - cloudwatchLog: '/aws/lambda/hello'
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
|
||||
# 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"
|
||||
19
lib/plugins/create/templates/aws-go-dep/world/main.go
Normal file
19
lib/plugins/create/templates/aws-go-dep/world/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-lambda-go/lambda"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func Handler() (Response, error) {
|
||||
return Response{
|
||||
Message: "Okay so your other function also executed successfully!",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
lambda.Start(Handler)
|
||||
}
|
||||
4
lib/plugins/create/templates/aws-go/Makefile
Normal file
4
lib/plugins/create/templates/aws-go/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
build:
|
||||
go get github.com/aws/aws-lambda-go/lambda
|
||||
env GOOS=linux go build -ldflags="-s -w" -o bin/hello hello/main.go
|
||||
env GOOS=linux go build -ldflags="-s -w" -o bin/world world/main.go
|
||||
5
lib/plugins/create/templates/aws-go/gitignore
Normal file
5
lib/plugins/create/templates/aws-go/gitignore
Normal file
@ -0,0 +1,5 @@
|
||||
# Serverless directories
|
||||
.serverless
|
||||
|
||||
# golang output binary directory
|
||||
bin
|
||||
19
lib/plugins/create/templates/aws-go/hello/main.go
Normal file
19
lib/plugins/create/templates/aws-go/hello/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-lambda-go/lambda"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func Handler() (Response, error) {
|
||||
return Response{
|
||||
Message: "Go Serverless v1.0! Your function executed successfully!",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
lambda.Start(Handler)
|
||||
}
|
||||
104
lib/plugins/create/templates/aws-go/serverless.yml
Normal file
104
lib/plugins/create/templates/aws-go/serverless.yml
Normal file
@ -0,0 +1,104 @@
|
||||
# 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-go # 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: go1.x
|
||||
|
||||
# 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
|
||||
|
||||
package:
|
||||
exclude:
|
||||
- ./**
|
||||
include:
|
||||
- ./bin/**
|
||||
|
||||
functions:
|
||||
hello:
|
||||
handler: bin/hello
|
||||
world:
|
||||
handler: bin/world
|
||||
|
||||
# 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:
|
||||
# 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
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
# - cloudwatchEvent:
|
||||
# event:
|
||||
# source:
|
||||
# - "aws.ec2"
|
||||
# detail-type:
|
||||
# - "EC2 Instance State-change Notification"
|
||||
# detail:
|
||||
# state:
|
||||
# - pending
|
||||
# - cloudwatchLog: '/aws/lambda/hello'
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
|
||||
# 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"
|
||||
19
lib/plugins/create/templates/aws-go/world/main.go
Normal file
19
lib/plugins/create/templates/aws-go/world/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-lambda-go/lambda"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func Handler() (Response, error) {
|
||||
return Response{
|
||||
Message: "Okay so your other function also executed successfully!",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
lambda.Start(Handler)
|
||||
}
|
||||
@ -64,7 +64,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -64,7 +64,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -64,7 +64,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -64,7 +64,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -64,7 +64,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -60,7 +60,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -3,6 +3,7 @@ const slsw = require('serverless-webpack');
|
||||
|
||||
module.exports = {
|
||||
entry: slsw.lib.entries,
|
||||
devtool: 'source-map',
|
||||
resolve: {
|
||||
extensions: [
|
||||
'.js',
|
||||
|
||||
@ -69,7 +69,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -69,7 +69,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -69,7 +69,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -66,7 +66,7 @@ functions:
|
||||
# - schedule: rate(10 minutes)
|
||||
# - sns: greeter-topic
|
||||
# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000
|
||||
# - alexaSkill
|
||||
# - alexaSkill: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx
|
||||
# - iot:
|
||||
# sql: "SELECT * FROM 'some_topic'"
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"version": "1.0.0",
|
||||
"description": "Example function for serverless kubeless",
|
||||
"dependencies": {
|
||||
"serverless-kubeless": "^0.2.4",
|
||||
"serverless-kubeless": "^0.3.1",
|
||||
"lodash": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"version": "1.0.0",
|
||||
"description": "Sample Kubeless Python serverless framework service.",
|
||||
"dependencies": {
|
||||
"serverless-kubeless": "^0.2.4"
|
||||
"serverless-kubeless": "^0.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
|
||||
250
package-lock.json
generated
250
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "serverless",
|
||||
"version": "1.25.0",
|
||||
"version": "1.26.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -33,9 +33,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz",
|
||||
"integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==",
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz",
|
||||
"integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn-globals": {
|
||||
@ -213,7 +213,7 @@
|
||||
"graphql-anywhere": "3.1.0",
|
||||
"graphql-tag": "2.6.1",
|
||||
"redux": "3.7.2",
|
||||
"symbol-observable": "1.1.0",
|
||||
"symbol-observable": "1.2.0",
|
||||
"whatwg-fetch": "2.0.3"
|
||||
}
|
||||
},
|
||||
@ -367,9 +367,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"assertion-error": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz",
|
||||
"integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
|
||||
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
|
||||
"dev": true
|
||||
},
|
||||
"async": {
|
||||
@ -389,12 +389,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"aws-sdk": {
|
||||
"version": "2.172.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.172.0.tgz",
|
||||
"integrity": "sha1-R9+3mQeXbrvVOFYupaJYNbWz810=",
|
||||
"version": "2.188.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.188.0.tgz",
|
||||
"integrity": "sha1-kGKrx9umOTRZ+i80I89dKU8ARhE=",
|
||||
"requires": {
|
||||
"buffer": "4.9.1",
|
||||
"crypto-browserify": "1.0.9",
|
||||
"events": "1.1.1",
|
||||
"jmespath": "0.15.0",
|
||||
"querystring": "0.2.0",
|
||||
@ -887,7 +886,7 @@
|
||||
"integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assertion-error": "1.0.2",
|
||||
"assertion-error": "1.1.0",
|
||||
"deep-eql": "0.1.3",
|
||||
"type-detect": "1.0.0"
|
||||
}
|
||||
@ -951,13 +950,13 @@
|
||||
}
|
||||
},
|
||||
"cli-usage": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cli-usage/-/cli-usage-0.1.4.tgz",
|
||||
"integrity": "sha1-fAHg3HBsI0s5yTODjI4gshdXduI=",
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/cli-usage/-/cli-usage-0.1.7.tgz",
|
||||
"integrity": "sha512-x/Q52iLSZsRrRb2ePmTsVYXrGcrPQ8G4yRAY7QpMlumxAfPVrnDOH2X6Z5s8qsAX7AA7YuIi8AXFrvH0wWEesA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"marked": "0.3.7",
|
||||
"marked-terminal": "1.7.0"
|
||||
"marked": "0.3.12",
|
||||
"marked-terminal": "2.0.0"
|
||||
}
|
||||
},
|
||||
"cli-width": {
|
||||
@ -1202,11 +1201,6 @@
|
||||
"boom": "2.10.1"
|
||||
}
|
||||
},
|
||||
"crypto-browserify": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-1.0.9.tgz",
|
||||
"integrity": "sha1-zFRJaF37hesRyYKKzHy4erW7/MA="
|
||||
},
|
||||
"crypto-random-string": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
|
||||
@ -1233,7 +1227,7 @@
|
||||
"integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es5-ext": "0.10.37"
|
||||
"es5-ext": "0.10.38"
|
||||
}
|
||||
},
|
||||
"damerau-levenshtein": {
|
||||
@ -1481,9 +1475,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"doctrine": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz",
|
||||
"integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esutils": "2.0.2"
|
||||
@ -1535,9 +1529,9 @@
|
||||
}
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
|
||||
"integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"requires": {
|
||||
"once": "1.4.0"
|
||||
}
|
||||
@ -1585,9 +1579,9 @@
|
||||
}
|
||||
},
|
||||
"es5-ext": {
|
||||
"version": "0.10.37",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz",
|
||||
"integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=",
|
||||
"version": "0.10.38",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.38.tgz",
|
||||
"integrity": "sha512-jCMyePo7AXbUESwbl8Qi01VSH2piY9s/a3rSU/5w/MlTIx8HPL1xn2InGN8ejt/xulcJgnTO7vqNtOAxzYd2Kg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-iterator": "2.0.3",
|
||||
@ -1601,7 +1595,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"d": "1.0.0",
|
||||
"es5-ext": "0.10.37",
|
||||
"es5-ext": "0.10.38",
|
||||
"es6-symbol": "3.1.1"
|
||||
}
|
||||
},
|
||||
@ -1612,7 +1606,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"d": "1.0.0",
|
||||
"es5-ext": "0.10.37",
|
||||
"es5-ext": "0.10.38",
|
||||
"es6-iterator": "2.0.3",
|
||||
"es6-set": "0.1.5",
|
||||
"es6-symbol": "3.1.1",
|
||||
@ -1632,7 +1626,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"d": "1.0.0",
|
||||
"es5-ext": "0.10.37",
|
||||
"es5-ext": "0.10.38",
|
||||
"es6-iterator": "2.0.3",
|
||||
"es6-symbol": "3.1.1",
|
||||
"event-emitter": "0.3.5"
|
||||
@ -1645,7 +1639,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"d": "1.0.0",
|
||||
"es5-ext": "0.10.37"
|
||||
"es5-ext": "0.10.38"
|
||||
}
|
||||
},
|
||||
"es6-weak-map": {
|
||||
@ -1655,7 +1649,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"d": "1.0.0",
|
||||
"es5-ext": "0.10.37",
|
||||
"es5-ext": "0.10.38",
|
||||
"es6-iterator": "2.0.3",
|
||||
"es6-symbol": "3.1.1"
|
||||
}
|
||||
@ -1714,7 +1708,7 @@
|
||||
"chalk": "1.1.3",
|
||||
"concat-stream": "1.6.0",
|
||||
"debug": "2.6.9",
|
||||
"doctrine": "2.0.2",
|
||||
"doctrine": "2.1.0",
|
||||
"escope": "3.6.0",
|
||||
"espree": "3.5.2",
|
||||
"esquery": "1.0.0",
|
||||
@ -1727,7 +1721,7 @@
|
||||
"imurmurhash": "0.1.4",
|
||||
"inquirer": "0.12.0",
|
||||
"is-my-json-valid": "2.17.1",
|
||||
"is-resolvable": "1.0.1",
|
||||
"is-resolvable": "1.1.0",
|
||||
"js-yaml": "3.10.0",
|
||||
"json-stable-stringify": "1.0.1",
|
||||
"levn": "0.3.0",
|
||||
@ -1887,7 +1881,7 @@
|
||||
"doctrine": "1.5.0",
|
||||
"has": "1.0.1",
|
||||
"jsx-ast-utils": "1.4.1",
|
||||
"object.assign": "4.0.4"
|
||||
"object.assign": "4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"doctrine": {
|
||||
@ -1908,7 +1902,7 @@
|
||||
"integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "5.2.1",
|
||||
"acorn": "5.3.0",
|
||||
"acorn-jsx": "3.0.1"
|
||||
}
|
||||
},
|
||||
@ -1955,7 +1949,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"d": "1.0.0",
|
||||
"es5-ext": "0.10.37"
|
||||
"es5-ext": "0.10.38"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
@ -2404,9 +2398,9 @@
|
||||
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
|
||||
},
|
||||
"graphlib": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.1.tgz",
|
||||
"integrity": "sha1-QjUsUrovTQNctWbrkfc5X3bryVE=",
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.5.tgz",
|
||||
"integrity": "sha512-XvtbqCcw+EM5SqQrIetIKKD+uZVNQtDPD1goIg7K73RuRZtVI5rYMdcCVSHm/AS1sCBZ7vt0p5WgXouucHQaOA==",
|
||||
"requires": {
|
||||
"lodash": "4.17.4"
|
||||
}
|
||||
@ -2416,7 +2410,7 @@
|
||||
"resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz",
|
||||
"integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==",
|
||||
"requires": {
|
||||
"iterall": "1.1.3"
|
||||
"iterall": "1.1.4"
|
||||
}
|
||||
},
|
||||
"graphql-anywhere": {
|
||||
@ -2484,7 +2478,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "1.1.3",
|
||||
"commander": "2.12.2",
|
||||
"commander": "2.13.0",
|
||||
"is-my-json-valid": "2.17.1",
|
||||
"pinkie-promise": "2.0.1"
|
||||
},
|
||||
@ -2509,9 +2503,9 @@
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
|
||||
"integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
|
||||
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
@ -2549,6 +2543,12 @@
|
||||
"resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz",
|
||||
"integrity": "sha512-JkaetveU7hFbqnAC1EV1sF4rlojU2D4Usc5CmS69l6NfmPDnpnFUegzFg33eDkkpNCxZ0mQp65HwUDrNFS/8MA=="
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
|
||||
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
|
||||
"dev": true
|
||||
},
|
||||
"has-to-string-tag-x": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
|
||||
@ -2794,9 +2794,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"is-ci": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz",
|
||||
"integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
|
||||
"integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ci-info": "1.1.2"
|
||||
@ -3000,9 +3000,9 @@
|
||||
}
|
||||
},
|
||||
"is-resolvable": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz",
|
||||
"integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
|
||||
"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
|
||||
"dev": true
|
||||
},
|
||||
"is-retry-allowed": {
|
||||
@ -3193,7 +3193,7 @@
|
||||
"babel-types": "6.26.0",
|
||||
"babylon": "6.18.0",
|
||||
"istanbul-lib-coverage": "1.1.1",
|
||||
"semver": "5.4.1"
|
||||
"semver": "5.5.0"
|
||||
}
|
||||
},
|
||||
"istanbul-lib-report": {
|
||||
@ -3274,9 +3274,9 @@
|
||||
}
|
||||
},
|
||||
"iterall": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/iterall/-/iterall-1.1.3.tgz",
|
||||
"integrity": "sha512-Cu/kb+4HiNSejAPhSaN1VukdNTTi/r4/e+yykqjlG/IW+1gZH5b4+Bq3whDX4tvbYugta3r8KTMUiqT3fIGxuQ=="
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/iterall/-/iterall-1.1.4.tgz",
|
||||
"integrity": "sha512-eaDsM/PY8D/X5mYQhecVc5/9xvSHED7yPON+ffQroBeTuqUVm7dfphMkK8NksXuImqZlVRoKtrNfMIVCYIqaUQ=="
|
||||
},
|
||||
"jest-changed-files": {
|
||||
"version": "17.0.2",
|
||||
@ -3294,7 +3294,7 @@
|
||||
"callsites": "2.0.0",
|
||||
"chalk": "1.1.3",
|
||||
"graceful-fs": "4.1.11",
|
||||
"is-ci": "1.0.10",
|
||||
"is-ci": "1.1.0",
|
||||
"istanbul-api": "1.2.1",
|
||||
"istanbul-lib-coverage": "1.1.1",
|
||||
"istanbul-lib-instrument": "1.9.1",
|
||||
@ -3823,8 +3823,8 @@
|
||||
"resolved": "https://registry.npmjs.org/json-refs/-/json-refs-2.1.7.tgz",
|
||||
"integrity": "sha1-uesB/in16j6Sh48VrqEK04taz4k=",
|
||||
"requires": {
|
||||
"commander": "2.12.2",
|
||||
"graphlib": "2.1.1",
|
||||
"commander": "2.13.0",
|
||||
"graphlib": "2.1.5",
|
||||
"js-yaml": "3.10.0",
|
||||
"native-promise-only": "0.8.1",
|
||||
"path-loader": "1.0.4",
|
||||
@ -3833,9 +3833,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
|
||||
"integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA=="
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
|
||||
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4354,12 +4354,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"markdown-magic": {
|
||||
"version": "0.1.19",
|
||||
"resolved": "https://registry.npmjs.org/markdown-magic/-/markdown-magic-0.1.19.tgz",
|
||||
"integrity": "sha1-IKnWWdqgx7DOt64DCVxuLK41KgM=",
|
||||
"version": "0.1.20",
|
||||
"resolved": "https://registry.npmjs.org/markdown-magic/-/markdown-magic-0.1.20.tgz",
|
||||
"integrity": "sha1-Xw73k0L6G0O7pCr+Y9MCMobj7sM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "2.12.2",
|
||||
"commander": "2.13.0",
|
||||
"deepmerge": "1.5.2",
|
||||
"find-up": "2.1.0",
|
||||
"fs-extra": "1.0.0",
|
||||
@ -4370,9 +4370,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
|
||||
"integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
|
||||
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
|
||||
"dev": true
|
||||
},
|
||||
"find-up": {
|
||||
@ -4435,15 +4435,15 @@
|
||||
}
|
||||
},
|
||||
"marked": {
|
||||
"version": "0.3.7",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.7.tgz",
|
||||
"integrity": "sha512-zBEP4qO1YQp5aXHt8S5wTiOv9i2X74V/LQL0zhUNvVaklt6Ywa6lChxIvS+ibYlCGgADwKwZFhjC3+XfpsvQvQ==",
|
||||
"version": "0.3.12",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz",
|
||||
"integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA==",
|
||||
"dev": true
|
||||
},
|
||||
"marked-terminal": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-1.7.0.tgz",
|
||||
"integrity": "sha1-yMRgiBx3LHYEtkNnAH7l938SWQQ=",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-2.0.0.tgz",
|
||||
"integrity": "sha1-Xq9Wi+ZvaGVBr6UqVYKAMQox3i0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cardinal": "1.0.0",
|
||||
@ -4742,11 +4742,11 @@
|
||||
"integrity": "sha1-BW0UJE89zBzq3+aK+c/wxUc6M/M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cli-usage": "0.1.4",
|
||||
"cli-usage": "0.1.7",
|
||||
"growly": "1.3.0",
|
||||
"lodash.clonedeep": "3.0.2",
|
||||
"minimist": "1.2.0",
|
||||
"semver": "5.4.1",
|
||||
"semver": "5.5.0",
|
||||
"shellwords": "0.1.1",
|
||||
"which": "1.3.0"
|
||||
}
|
||||
@ -4768,7 +4768,7 @@
|
||||
"requires": {
|
||||
"hosted-git-info": "2.5.0",
|
||||
"is-builtin-module": "1.0.0",
|
||||
"semver": "5.4.1",
|
||||
"semver": "5.5.0",
|
||||
"validate-npm-package-license": "3.0.1"
|
||||
}
|
||||
},
|
||||
@ -4848,13 +4848,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"object.assign": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz",
|
||||
"integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
|
||||
"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-properties": "1.1.2",
|
||||
"function-bind": "1.1.1",
|
||||
"has-symbols": "1.0.0",
|
||||
"object-keys": "1.0.11"
|
||||
}
|
||||
},
|
||||
@ -4899,9 +4900,9 @@
|
||||
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k="
|
||||
},
|
||||
"opn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz",
|
||||
"integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz",
|
||||
"integrity": "sha512-Jd/GpzPyHF4P2/aNOVmS3lfMSWV9J7cOhCG1s08XCEAsPkB7lp6ddiU0J7XzyQRDUh8BqJ7PchfINjR8jyofRQ==",
|
||||
"requires": {
|
||||
"is-wsl": "1.1.0"
|
||||
}
|
||||
@ -4975,10 +4976,13 @@
|
||||
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
|
||||
"integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=",
|
||||
"dev": true
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
|
||||
"integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-try": "1.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "2.0.0",
|
||||
@ -4986,18 +4990,24 @@
|
||||
"integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-limit": "1.1.0"
|
||||
"p-limit": "1.2.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
|
||||
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
|
||||
"dev": true
|
||||
},
|
||||
"package-json": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
|
||||
"integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
|
||||
"requires": {
|
||||
"got": "6.7.1",
|
||||
"registry-auth-token": "3.3.1",
|
||||
"registry-auth-token": "3.3.2",
|
||||
"registry-url": "3.1.0",
|
||||
"semver": "5.4.1"
|
||||
"semver": "5.5.0"
|
||||
}
|
||||
},
|
||||
"pako": {
|
||||
@ -5197,9 +5207,9 @@
|
||||
}
|
||||
},
|
||||
"promise-queue": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.3.tgz",
|
||||
"integrity": "sha1-hTTXa/RnPDuqOoK7oBvSlcww8U8="
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz",
|
||||
"integrity": "sha1-L29ffA9tCBCelnZZx5uIqe1ek7Q="
|
||||
},
|
||||
"proto-list": {
|
||||
"version": "1.2.4",
|
||||
@ -5322,9 +5332,9 @@
|
||||
}
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz",
|
||||
"integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.4.tgz",
|
||||
"integrity": "sha1-oPYGyq4qO4YrvQ74VILAElsxX6M=",
|
||||
"requires": {
|
||||
"deep-extend": "0.4.2",
|
||||
"ini": "1.3.5",
|
||||
@ -5420,7 +5430,7 @@
|
||||
"lodash": "4.17.4",
|
||||
"lodash-es": "4.17.4",
|
||||
"loose-envify": "1.3.1",
|
||||
"symbol-observable": "1.1.0"
|
||||
"symbol-observable": "1.2.0"
|
||||
}
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
@ -5439,11 +5449,11 @@
|
||||
}
|
||||
},
|
||||
"registry-auth-token": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz",
|
||||
"integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=",
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
|
||||
"integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
|
||||
"requires": {
|
||||
"rc": "1.2.2",
|
||||
"rc": "1.2.4",
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
@ -5452,7 +5462,7 @@
|
||||
"resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
|
||||
"integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
|
||||
"requires": {
|
||||
"rc": "1.2.2"
|
||||
"rc": "1.2.4"
|
||||
}
|
||||
},
|
||||
"remarkable": {
|
||||
@ -5533,7 +5543,7 @@
|
||||
"stringstream": "0.0.5",
|
||||
"tough-cookie": "2.3.3",
|
||||
"tunnel-agent": "0.4.3",
|
||||
"uuid": "3.1.0"
|
||||
"uuid": "3.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"form-data": {
|
||||
@ -5560,9 +5570,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
|
||||
"integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
|
||||
"integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@ -5694,16 +5704,16 @@
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
|
||||
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
|
||||
},
|
||||
"semver-diff": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
|
||||
"integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
|
||||
"requires": {
|
||||
"semver": "5.4.1"
|
||||
"semver": "5.5.0"
|
||||
}
|
||||
},
|
||||
"semver-regex": {
|
||||
@ -6002,9 +6012,9 @@
|
||||
}
|
||||
},
|
||||
"symbol-observable": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.1.0.tgz",
|
||||
"integrity": "sha512-dQoid9tqQ+uotGhuTKEY11X4xhyYePVnqGSoSm3OGKh2E8LZ6RPULp1uXTctk33IeERlrRJYoVSBglsL05F5Uw=="
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
|
||||
},
|
||||
"symbol-tree": {
|
||||
"version": "3.2.2",
|
||||
@ -6118,7 +6128,7 @@
|
||||
"integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
|
||||
"requires": {
|
||||
"bl": "1.2.1",
|
||||
"end-of-stream": "1.4.0",
|
||||
"end-of-stream": "1.4.1",
|
||||
"readable-stream": "2.3.3",
|
||||
"xtend": "4.0.1"
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "serverless",
|
||||
"version": "1.25.0",
|
||||
"version": "1.26.0",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
|
||||
@ -37,5 +37,10 @@ serverless deploy -v
|
||||
echo "Invoking Service"
|
||||
serverless invoke --function hello
|
||||
|
||||
if [ $template == "aws-go" ] || [ $template == "aws-go-dep" ]
|
||||
then
|
||||
serverless invoke --function world
|
||||
fi
|
||||
|
||||
echo "Removing Service"
|
||||
serverless remove -v
|
||||
|
||||
@ -10,6 +10,8 @@ function integration-test {
|
||||
|
||||
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-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-go 'cd /go/src/app && make build'
|
||||
integration-test aws-go-dep 'cd /go/src/app && make build'
|
||||
integration-test aws-groovy-gradle ./gradlew build
|
||||
integration-test aws-java-gradle ./gradlew build
|
||||
integration-test aws-java-maven mvn package
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user