Skip to content
This repository has been archived by the owner on Dec 9, 2024. It is now read-only.

Commit

Permalink
Merge pull request #73 from andresmgot/update0.2.3
Browse files Browse the repository at this point in the history
Adapt to kubeless 0.2.3
  • Loading branch information
andresmgot authored Oct 18, 2017
2 parents b6aed90 + b7e0e32 commit 8841814
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 67 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ services:
- docker
env:
global:
- KUBELESS_VERSION: 0.2.1
- KUBELESS_VERSION: 0.2.3
- REPO_DOMAIN: serverless
- REPO_NAME: serverless-kubeless
- secure: "s+L8ndj0uMNwqbLvbHePHeMJw2LI8DdEdcq1vJ98hNwHOWQc2mHVB4utG9EZFkaL+RAZYduldSJqr443d2BugxrkmzhLUlM5vDks+zHeKecwTah2uuaMUXVT/y/cWDDTVp3phqSqWbHBMG6u0ImvTVWHpnkux55S3QJTHevvhdodpO6VDTsJCEB3e1d2hHxi0L9tJrFXzQRpooV8IUuODwKBJyhK4CD7rvu0D1gBgHaUNnNLrCy4YTaFl19q5NdZUtrQDC7rpSPOhFI9CBFX8GiFq6nY3XzFASwq/JtKc3K7OLIC7Wqb6JpuvFhG6S1yhBzp73pnoE9U0Bi+YMa3L+nPoh58dCB2ldNCCCMbx7R6PWq/TwYzLvgZZ7queC2kbvCTrtU6JJfmb0CxmX1fnUIpCsNeyXaPuo4Ly6WJeAID32z79CwMo9NH0uOVTLy3LTrLcEfELhBRL5+WkMvKmXUt8yN/jEIa/H38pQN5Y/AnJ0KznO8RZ2nLhi1cR+xUkxfPVZ22Wr2XkbzJDZih/mZR+5GQBfUHWgpUChK+e8dOhplk+4PZJEO6Myja7ykXBPYtL9CV/Xi+1nQqLmfhyChiES201KusJr1IrFklslzCzgrSH8Dv2yaYUTe/Ub/I3gWIhKOXY66gkpmB6MSBJUfMK3uR4/wYfCvbtBTugsY="
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Make sure you have a kubernetes endpoint running and kubeless installed:
```bash
$ kubectl version
$ brew install kubeless/tap/kubeless
$ KUBELESS_VERSION=0.2.1
$ KUBELESS_VERSION=0.2.3
$ kubectl create ns kubeless
$ kubectl create -f https://github.com/kubeless/kubeless/releases/download/v$KUBELESS_VERSION/kubeless-v$KUBELESS_VERSION.yaml
```
Expand Down
54 changes: 37 additions & 17 deletions lib/invoke.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
'use strict';

const _ = require('lodash');
const Api = require('kubernetes-client');
const BbPromise = require('bluebird');
const fs = require('fs');
const path = require('path');
Expand Down Expand Up @@ -77,11 +78,8 @@ function invoke(func, data, funcsDesc, options) {
const namespace = desc.namespace ||
opts.namespace ||
helpers.getDefaultNamespace(config);
const url = `${APIRootUrl}/api/v1/proxy/namespaces/${namespace}/services/${func}/`;
const connectionOptions = Object.assign(
helpers.getConnectionOptions(helpers.loadKubeConfig()),
{ url }
);
const connectionOptions = helpers.getConnectionOptions(helpers.loadKubeConfig());
const core = new Api.Core(connectionOptions);
const requestData = getData(data, {
path: opts.path,
});
Expand Down Expand Up @@ -112,19 +110,41 @@ function invoke(func, data, funcsDesc, options) {
resolve(response);
}
};
if (_.isEmpty(requestData)) {
// There is no data to send, sending a GET request
request.get(connectionOptions, parseReponse);
} else {
// Sending request data with a POST
request.post(
Object.assign(
connectionOptions,
requestData
),
parseReponse
core.services.get((err, servicesInfo) => {
if (err) {
reject(err);
} else {
const functionService = _.find(
servicesInfo.items,
(service) => (
service.metadata.labels &&
service.metadata.labels.function === func
)
);
if (_.isEmpty(functionService)) {
opts.log(`Not found any information about the function "${func}"`);
}
const port = functionService.spec.ports[0].name || functionService.spec.ports[0].port;
const url = `${APIRootUrl}/api/v1/proxy/namespaces/${namespace}/services/${func}:${port}/`;
const invokeConnectionOptions = Object.assign(
connectionOptions,
{ url }
);
}
if (_.isEmpty(requestData)) {
// There is no data to send, sending a GET request
request.get(invokeConnectionOptions, parseReponse);
} else {
// Sending request data with a POST
request.post(
Object.assign(
invokeConnectionOptions,
requestData
),
parseReponse
);
}
}
});
});
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "serverless-kubeless",
"version": "0.2.0",
"version": "0.2.1",
"description": "This plugin enables support for Kubeless within the [Serverless Framework](https://github.com/serverless).",
"main": "index.js",
"directories": {
Expand Down
139 changes: 92 additions & 47 deletions test/kubelessInvoke.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const chaiAsPromised = require('chai-as-promised');
const expect = require('chai').expect;
const helpers = require('../lib/helpers');
const loadKubeConfig = require('./lib/load-kube-config');
const nock = require('nock');
const request = require('request');
const sinon = require('sinon');

Expand All @@ -32,6 +33,34 @@ const serverless = require('./lib/serverless')({ service: { functions: { 'my-fun

require('chai').use(chaiAsPromised);

function nocksvc(url, funcs) {
nock(url)
.get('/api/v1/services')
.reply(200, {
items: _.map(_.flatten([funcs]), f => ({
metadata:
{
name: f,
namespace: 'default',
selfLink: `/api/v1/namespaces/default/services/${f}`,
uid: '010a169d-618c-11e7-9939-080027abf356',
resourceVersion: '248',
creationTimestamp: '2017-07-05T14:12:39Z',
labels: { function: f },
},
spec:
{
ports: [{ protocol: 'TCP', port: 8080, targetPort: 8080, nodePort: 30817 }],
selector: { function: f },
clusterIP: '10.0.0.177',
type: 'NodePort',
sessionAffinity: 'None',
},
status: { loadBalancer: {} },
})),
})
.persist();
}
describe('KubelessInvoke', () => {
describe('#constructor', () => {
const options = { test: 1 };
Expand Down Expand Up @@ -93,6 +122,7 @@ describe('KubelessInvoke', () => {
request.post.restore();
request.get.restore();
helpers.loadKubeConfig.restore();
nock.cleanAll();
});
it('throws an error if the given path with the data does not exists', () => {
const kubelessInvoke = new KubelessInvoke(serverless, {
Expand All @@ -113,16 +143,19 @@ describe('KubelessInvoke', () => {
statusMessage: 'OK',
});
});
expect(kubelessInvoke.invokeFunction()).to.become({
statusCode: 200,
statusMessage: 'OK',
nocksvc(kubeApiURL, func);
return kubelessInvoke.invokeFunction().then((res) => {
expect(res).to.be.eql({
statusCode: 200,
statusMessage: 'OK',
});
expect(
request.get.firstCall.args[0]
).to.contain.keys(['ca', 'auth', 'url']);
expect(request.get.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/my-function:8080/`
);
});
expect(
request.get.firstCall.args[0]
).to.contain.keys(['ca', 'auth', 'url']);
expect(request.get.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/my-function/`
);
});
it('calls the API end point with the correct arguments (with raw data)', () => {
const kubelessInvoke = new KubelessInvoke(serverless, {
Expand All @@ -135,17 +168,20 @@ describe('KubelessInvoke', () => {
statusMessage: 'OK',
});
});
expect(kubelessInvoke.invokeFunction()).to.become({
statusCode: 200,
statusMessage: 'OK',
});
expect(
nocksvc(kubeApiURL, func);
return kubelessInvoke.invokeFunction().then((res) => {
expect(res).to.be.eql({
statusCode: 200,
statusMessage: 'OK',
});
expect(
request.post.firstCall.args[0]
).to.contain.keys(['url', 'body']);
expect(request.post.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/my-function/`
expect(request.post.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/my-function:8080/`
);
expect(request.post.firstCall.args[0].body).to.be.eql('hello');
expect(request.post.firstCall.args[0].body).to.be.eql('hello');
});
});
it('calls the API end point with the correct arguments (with JSON data)', () => {
const kubelessInvoke = new KubelessInvoke(serverless, {
Expand All @@ -158,18 +194,21 @@ describe('KubelessInvoke', () => {
statusMessage: 'OK',
});
});
expect(kubelessInvoke.invokeFunction()).to.become({
statusCode: 200,
statusMessage: 'OK',
});
expect(
nocksvc(kubeApiURL, func);
return kubelessInvoke.invokeFunction().then((res) => {
expect(res).to.be.eql({
statusCode: 200,
statusMessage: 'OK',
});
expect(
request.post.firstCall.args[0]
).to.contain.keys(['url', 'json', 'body']);
expect(request.post.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/my-function/`
expect(request.post.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/my-function:8080/`
);
expect(request.post.firstCall.args[0].json).to.be.eql(true);
expect(request.post.firstCall.args[0].body).to.be.eql({ test: 1 });
expect(request.post.firstCall.args[0].json).to.be.eql(true);
expect(request.post.firstCall.args[0].body).to.be.eql({ test: 1 });
});
});
it('reject when an exit code different than 200 is returned', () => {
const kubelessInvoke = new KubelessInvoke(serverless, {
Expand All @@ -195,13 +234,16 @@ describe('KubelessInvoke', () => {
statusMessage: 'OK',
});
});
expect(kubelessInvoke.invokeFunction()).to.become({
statusCode: 200,
statusMessage: 'OK',
});
expect(request.get.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/test/services/my-function/`
nocksvc(kubeApiURL, func);
return kubelessInvoke.invokeFunction().then((res) => {
expect(res).to.be.eql({
statusCode: 200,
statusMessage: 'OK',
});
expect(request.get.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/test/services/my-function:8080/`
);
});
});
it('calls the API end point with the correct namespace (in the function)', () => {
const serverlessWithNS = _.cloneDeep(serverless);
Expand All @@ -215,15 +257,18 @@ describe('KubelessInvoke', () => {
statusMessage: 'OK',
});
});
expect(kubelessInvoke.invokeFunction()).to.become({
statusCode: 200,
statusMessage: 'OK',
});
expect(request.get.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/test/services/my-function/`
nocksvc(kubeApiURL, func);
return kubelessInvoke.invokeFunction().then((res) => {
expect(res).to.be.eql({
statusCode: 200,
statusMessage: 'OK',
});
expect(request.get.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/test/services/my-function:8080/`
);
});
});
it('calls the API in the correct sequence', (done) => {
it('calls the API in the correct sequence', () => {
const serverlessWithSequence = _.cloneDeep(serverless);
serverlessWithSequence.service.functions = {
sequenceFunc: {
Expand Down Expand Up @@ -258,29 +303,29 @@ describe('KubelessInvoke', () => {
body: 'c',
});
});
kubelessInvoke.invokeFunction().then(res => {
nocksvc(kubeApiURL, ['func1', 'func2', 'func3']);
return kubelessInvoke.invokeFunction().then((res) => {
expect(res).to.be.eql({
statusCode: 200,
statusMessage: 'OK',
body: 'c',
});
expect(request.post.callCount).to.be.eql(3);
expect(request.post.firstCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/func1/`
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/func1:8080/`
);
expect(request.post.firstCall.args[0].body).to.be.eql('hello');
expect(request.post.secondCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/func2/`
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/func2:8080/`
);
expect(request.post.secondCall.args[0].body).to.be.eql('a');
expect(request.post.thirdCall.args[0].url).to.be.eql(
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/func3/`
`${kubeApiURL}/api/v1/proxy/namespaces/default/services/func3:8080/`
);
expect(request.post.thirdCall.args[0].body).to.be.eql('b');
done();
});
});
it('interrupts a sequence if any of the steps fails', (done) => {
it('interrupts a sequence if any of the steps fails', () => {
const serverlessWithSequence = _.cloneDeep(serverless);
serverlessWithSequence.service.functions = {
sequenceFunc: {
Expand Down Expand Up @@ -314,10 +359,10 @@ describe('KubelessInvoke', () => {
body: 'c',
});
});
kubelessInvoke.invokeFunction().catch(err => {
nocksvc(kubeApiURL, ['func1', 'func2', 'func3']);
return kubelessInvoke.invokeFunction().catch((err) => {
expect(request.post.callCount).to.be.eql(2);
expect(err.message).to.be.eql('INTERNAL ERROR');
done();
});
});
});
Expand Down

0 comments on commit 8841814

Please sign in to comment.