Skip to content

[Runtimes] Update documentation and examples to support new exported … #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 27 additions & 27 deletions deploy/scalewayDeploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,54 +17,54 @@ class ScalewayDeploy {
this.provider = this.serverless.getProvider('scaleway');

Object.assign(
this,
validate,
setUpDeployment,
createNamespace,
createFunctions,
createContainers,
pushContainers,
uploadCode,
deployFunctions,
deployContainers,
namespaceUtils,
this,
validate,
setUpDeployment,
createNamespace,
createFunctions,
createContainers,
pushContainers,
uploadCode,
deployFunctions,
deployContainers,
namespaceUtils,
);

function chainContainers() {
if (this.provider.serverless.service.custom &&
this.provider.serverless.service.custom.containers &&
Object.keys(this.provider.serverless.service.custom.containers).length !== 0) {
if (this.provider.serverless.service.custom
&& this.provider.serverless.service.custom.containers
&& Object.keys(this.provider.serverless.service.custom.containers).length !== 0) {
return this.createContainers()
.then(this.pushContainers)
.then(this.deployContainers)
.then(this.pushContainers)
.then(this.deployContainers);
}
};
}

function chainFunctions() {
if (this.provider.serverless.service.functions &&
Object.keys(this.provider.serverless.service.functions).length !== 0) {
if (this.provider.serverless.service.functions
&& Object.keys(this.provider.serverless.service.functions).length !== 0) {
return this.createFunctions()
.then(this.uploadCode)
.then(this.deployFunctions)
.then(this.uploadCode)
.then(this.deployFunctions);
}
};
}

this.hooks = {
// Validate serverless.yml, set up default values, configure deployment...
'before:deploy:deploy': () => BbPromise.bind(this)
.then(this.provider.initialize(this.serverless, this.options))
.then(this.validate)
.then(this.setUpDeployment),
.then(this.setUpDeployment)
.then(this.validate),
// Every tasks related to functions deployment:
// - Create a namespace if it does not exist
// - Create each functions in API if it does not exist
// - Zip code - zip each function
// - Get Presigned URL and Push code for each function to S3
// - Deploy each function / container
'deploy:deploy': () => BbPromise.bind(this)
.then(this.createNamespace)
.then(chainContainers)
.then(chainFunctions)
.then(this.createNamespace)
.then(chainContainers)
.then(chainFunctions),
};
}
}
Expand Down
120 changes: 60 additions & 60 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,67 +164,67 @@ Available runtimes are:
#### Functions Handler

Based on the chosen runtime, the `handler` variable on function might vary:
- `node` (8 or 10): Path to your handler file (from serverless.yml), omit `./`, `../`.
```
- src
- handlers
- firstHandler.js
- secondHandler.js
- serverless.yml
```
Inside serverless.yml:
```yml
provider:
# ...
runtime: node8 # or node10
functions:
first:
handler: src/handlers/firstHandler.js
second:
handler: src/handlers/secondHandler.js
```
- `python` (2.7 and 3.7): Similar to `node`, path to handler file `src/testing/handler.py`:
```
- src
- handlers
- firstHandler.py
- secondHandler.py
- serverless.yml
```
Inside serverless.yml:
```yml
provider:
# ...
runtime: python3 # or python for python 2.7
functions:
first:
handler: src/handlers/firstHandler.py
second:
handler: src/handlers/secondHandler.py
```
- `node` (8 or 10): Path to your handler file (from serverless.yml), omit `./`, `../`, suffixed by the exported function to use (example: `myFunction.handle` => file `myFunction.js` exports a function `handle`).
```
- src
- handlers
- firstHandler.js => module.exports.myFirstHandler
- secondHandler.js => module.exports.mySecondHandler
- serverless.yml
```
Inside serverless.yml:
```yml
provider:
# ...
runtime: node8 # or node10
functions:
first:
handler: src/handlers/firstHandler.myFirstHandler
second:
handler: src/handlers/secondHandler.mySecondHandler
```
- `python` (2.7 and 3.7): Similar to `node`, path to handler file, suffixed with exported function to use: `src/testing/handler.handle` => file `handler.py` defines a method `handle`, inside directory `src/testing`.
```
- src
- handlers
- firstHandler.py => def my_first_handler
- secondHandler.py => def my_second_handler
- serverless.yml
```
Inside serverless.yml:
```yml
provider:
# ...
runtime: python3 # or python for python 2.7
functions:
first:
handler: src/handlers/firstHandler.my_first_handler
second:
handler: src/handlers/secondHandler.my_second_handler
```
- `golang`: Path to your handler's **package**, for example if I have the following structure:
```
- src
- testing
- handler.go -> package main inside "src/testing" directory
- second
- handler.go -> package main inside "src/second" directory
- handler.go -> package main at the root of the project
- serverless.yml
```
Your serverless.yml `functions` should look something like this:
```yml
provider:
# ...
runtime: golang
functions:
root:
handler: "."
testing:
handler: src/testing
second:
handler: src/second
```
```
- src
- testing
- handler.go -> package main inside "src/testing" directory
- second
- handler.go -> package main inside "src/second" directory
- handler.go -> package main at the root of the project
- serverless.yml
```
Your serverless.yml `functions` should look something like this:
```yml
provider:
# ...
runtime: golang
functions:
root:
handler: "."
testing:
handler: src/testing
second:
handler: src/second
```

### Environment Variables

Expand Down
2 changes: 1 addition & 1 deletion examples/nodejs10/handler.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = (event, context, callback) => {
module.exports.handle = (event, context, callback) => {
const result = {
message: 'Hello from Serverless Framework and Scaleway Functions :D',
};
Expand Down
2 changes: 1 addition & 1 deletion examples/nodejs10/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package:

functions:
first:
handler: handler.js
handler: handler.handle
# Local environment variables - used only in given function
env:
local: local
2 changes: 1 addition & 1 deletion examples/nodejs8/handler.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = (event, context, callback) => {
module.exports.handle = (event, context, callback) => {
const result = {
message: 'Hello from Serverless Framework and Scaleway Functions :D',
};
Expand Down
2 changes: 1 addition & 1 deletion examples/nodejs8/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package:

functions:
first:
handler: handler.js
handler: handler.handle
# Local environment variables - used only in given function
env:
local: local
2 changes: 1 addition & 1 deletion examples/python2/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package:

functions:
first:
handler: handler.py
handler: handler.handle
# Local environment variables - used only in given function
env:
local: local
2 changes: 1 addition & 1 deletion examples/python3/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package:

functions:
first:
handler: handler.py
handler: handler.handle
# Local environment variables - used only in given function
env:
local: local
2 changes: 1 addition & 1 deletion examples/typescript/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ functions:
first:
# Path to compiled JavaScript Handler
# Note that this must be a `.js` file even though you are using .ts
handler: src/handler.js
handler: .webpack/handler.myHandler
# Local environment variables - used only in given function
env:
local: local
3 changes: 1 addition & 2 deletions examples/typescript/src/handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, APIGatewayProxyHandler } from 'scaleway-functions-typescript';

const handler: APIGatewayProxyHandler = (event, context, callback) => {
export const myHandler: APIGatewayProxyHandler = (event, context, callback) => {
const result = {
message: 'Hello from Node w/ TypeScript on Scaleway Functions !',
};
Expand All @@ -11,4 +11,3 @@ const handler: APIGatewayProxyHandler = (event, context, callback) => {
};
};

export default handler;
14 changes: 7 additions & 7 deletions remove/scalewayRemove.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ class ScalewayDeploy {
this.provider = this.serverless.getProvider('scaleway');

Object.assign(
this,
setUpDeployment,
removeNamespace,
namespaceUtils,
validate,
this,
setUpDeployment,
removeNamespace,
namespaceUtils,
validate,
);

this.hooks = {
// Validate serverless.yml, set up default values, configure deployment...
'before:remove:remove': () => BbPromise.bind(this)
.then(this.provider.initialize(this.serverless, this.options))
.then(this.validate)
.then(this.setUpDeployment),
.then(this.setUpDeployment)
.then(this.validate),
// Every tasks related to space deletion:
// - Delete given space if it exists
'remove:remove': () => BbPromise.bind(this)
Expand Down
4 changes: 2 additions & 2 deletions shared/setUpDeployment.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
setUpDeployment() {
const service = this.provider.serverless.service;
const provider = service.provider;
const { service } = this.provider.serverless;
const { provider } = service;
this.namespaceName = service.service;
this.namespaceVariables = provider.env || {};
this.runtime = provider.runtime;
Expand Down
45 changes: 43 additions & 2 deletions shared/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ const BbPromise = require('bluebird');
const fs = require('fs');
const path = require('path');

const RUNTIMES_EXTENSIONS = {
node8: ['ts', 'js'],
node10: ['ts', 'js'],
python: ['py'],
python3: ['py'],
golang: ['go'],
};

module.exports = {
validate() {
return BbPromise.bind(this)
Expand Down Expand Up @@ -55,6 +63,20 @@ module.exports = {
let containerNames = [];

const currentErrors = Array.isArray(errors) ? errors : [];
const functionErrors = [];
let containers = [];

const { functions } = this.serverless.service;
if (functions && Object.keys(functions).length !== 0) {
functionNames = Object.keys(functions);

// Check that runtime is authorized
const extensions = RUNTIMES_EXTENSIONS[this.runtime];
if (!extensions) {
const availableRuntimesMessage = Object.keys(RUNTIMES_EXTENSIONS).join(', ');
functionErrors.push(`Runtime ${this.runtime} is not supported. Function runtime must be one of the following: ${availableRuntimesMessage}`);
}

let functionErrors = [];
let containers = [];

Expand All @@ -66,17 +88,36 @@ module.exports = {
const func = functions[functionName];
// Check if function handler exists
try {
if (!fs.existsSync(path.resolve('./', func.handler))) {
// get handler file => path/to/file.handler => split ['path/to/file', 'handler']
const splitHandlerPath = func.handler.split('.');
if (splitHandlerPath.length !== 2) {
throw new Error(`Handler is malformatted for ${functionName}: handler should be path/to/file.functionInsideFile`);
}
const handlerPath = splitHandlerPath[0];

// For each extensions linked to a language (node: .ts,.js, python: .py ...),
// check that a handler file exists with one of the extensions
let handlerFileExists = false;
for (let i = 0; i < extensions.length; i += 1) {
const extension = extensions[i];
const handler = `${handlerPath}.${extension}`;
if (fs.existsSync(path.resolve('./', handler))) {
handlerFileExists = true;
}
}
// If Handler file does not exist, throw an error
if (!handlerFileExists) {
throw new Error('File does not exists');
}
} catch (error) {
const message = `Handler defined for function ${functionName} does not exist.`;
const message = `Handler file defined for function ${functionName} does not exist (${func.handler}).`;
functionErrors.push(message);
}
});
}

if (this.serverless.service.custom) {
// eslint-disable-next-line prefer-destructuring
containers = this.serverless.service.custom.containers;
}
if (containers && Object.keys(containers).length !== 0) {
Expand Down