Skip to content

Commit

Permalink
Update: add selfLink annotation before returning getResource (#106)
Browse files Browse the repository at this point in the history
* Update: add selfLink annotation to getResources

all resources returned via kubeclass getResource will include the selfLink annotation

* Update: add selfLink to watchman event data

all resources returned via the watchman event objectHandler will include the selfLink annotation

* Update: move watchman kubeResourceMeta to options obj

* Update: pass kubeResourceMeta to EventHandler

* Update: fix logical operator for validUri check

* Update: dont require kubeResourceMeta in watchman

* Update: no longer need to pass kubeResourceMeta to watchman

* Chore: tests
  • Loading branch information
alewitt2 authored Aug 25, 2020
1 parent fef94c1 commit 2c9611a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 62 deletions.
28 changes: 14 additions & 14 deletions lib/EventHandler.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/**
* Copyright 2019 IBM Corp. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Copyright 2019 IBM Corp. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const merge = require('deepmerge');
const touch = require('touch');
const watchman = require('./Watchman');
Expand Down
39 changes: 18 additions & 21 deletions lib/Watchman.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/**
* Copyright 2019 IBM Corp. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Copyright 2019 IBM Corp. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const request = require('request');
const validUrl = require('valid-url');
const JSONStream = require('JSONStream');
Expand All @@ -22,7 +22,7 @@ const merge = require('deepmerge');
module.exports = class Watchman {
constructor(options, objectHandler) {
if ((typeof objectHandler) !== 'function') {
throw 'objectHandler must be a function.';
throw 'Watchman objectHandler must be a function.';
}
this._objectHandler = objectHandler;
this._requestOptions = merge({
Expand All @@ -35,15 +35,12 @@ module.exports = class Watchman {
}, options.requestOptions || {});
this._requestOptions.uri = options.watchUri;

if ((typeof objectHandler) !== 'function') {
throw 'objectHandler must be a function.';
}
if ((options.logger) && ((typeof options.logger) !== 'object')) {
throw 'options.logger must be an object.';
}
this._logger = options.logger;
if (!validUrl.isUri(`${this._requestOptions.baseUrl}${this._requestOptions.uri}`)) {
throw `uri '${this._requestOptions.baseUrl}${this._requestOptions.uri}' not valid.`;
if (!validUrl.isUri(`${this._requestOptions.baseUrl}${this._requestOptions.uri}`) || !this._requestOptions.uri.includes('watch')) {
throw `uri '${this._requestOptions.baseUrl}${this._requestOptions.uri}' not valid watch uri.`;
}

this._rewatchOnTimeout = options.rewatchOnTimeout || true;
Expand Down Expand Up @@ -71,7 +68,7 @@ module.exports = class Watchman {
this._errors++;
this.end(this._rewatchOnTimeout);
delay(this._errors * 1000).then(() => {
if(this._rewatchOnTimeout)
if (this._rewatchOnTimeout)
this.watch();
});
}
Expand Down
11 changes: 10 additions & 1 deletion lib/kubeClass.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ module.exports = class KubeClass {
}


injectSelfLink(object, resourceMeta) {
let resources = objectPath.get(object, 'items', []);
resources.forEach(r => {
let metadata = { name: objectPath.get(r, 'metadata.name'), namespace: objectPath.get(r, 'metadata.namespace') };
objectPath.set(r, 'metadata.annotations.selfLink', resourceMeta.uri(metadata));
});
return object;
}

async getResource(resourceMeta, queryParams = {}) {
let result;
if (!resourceMeta) {
Expand All @@ -132,7 +141,7 @@ module.exports = class KubeClass {
result.statusCode = response.statusCode;
switch (response.statusCode) {
case 200:
result.object = response.body;
result.object = this.injectSelfLink(response.body, resourceMeta);
break;
default:
// this.logger.error(`this.getResource ${uri} ${response.statusCode} ${status[response.statusCode]}.`, response.body);
Expand Down
52 changes: 26 additions & 26 deletions test/Watchman-test.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
/**
* Copyright 2019 IBM Corp. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Copyright 2019 IBM Corp. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const assert = require('chai').assert;
const nock = require('nock');
const watchman = require('../lib/Watchman');
const log = require('../lib/bunyan-api').createLogger('Watchman-test');

const dummyOptions = { rewatchOnTimeout: false, requestOptions: { baseUrl: 'https://localhost:32263' }, watchUri: '/api/v1/namespaces/default/services/kubernetes' };
const dummyOptions = { rewatchOnTimeout: false, requestOptions: { baseUrl: 'https://localhost:32263' }, watchUri: '/api/v1/watch/namespaces/default/services/kubernetes' };
const data1 = { 'type': 'ADDED', 'object': { 'kind': 'Service', 'apiVersion': 'v1', 'metadata': { 'name': 'kubernetes', 'namespace': 'default', 'selfLink': '/api/v1/namespaces/default/services/kubernetes', 'uid': '7c75c135-fca7-11e8-9f10-3a7d3a0f8cf2', 'resourceVersion': '14840391', 'creationTimestamp': '2018-12-10T18:14:51Z', 'labels': { 'component': 'apiserver', 'provider': 'kubernetes', 'razee/watch-resource': 'lite' } }, 'spec': { 'ports': [{ 'name': 'https', 'protocol': 'TCP', 'port': 443, 'targetPort': 2040 }], 'clusterIP': '172.21.0.1', 'type': 'ClusterIP', 'sessionAffinity': 'None' }, 'status': { 'loadBalancer': {} } } };

let mockObjectHandler = (data) => { }; // eslint-disable-line no-unused-vars
let mockObjectHandler = (data) => {}; // eslint-disable-line no-unused-vars

describe('watchman', () => {

Expand All @@ -43,7 +43,7 @@ describe('watchman', () => {
var wm = new watchman(dummyOptions, ''); // eslint-disable-line no-unused-vars
} catch (err) {
errorsHappen = true;
assert.equal(err, 'objectHandler must be a function.');
assert.equal(err, 'Watchman objectHandler must be a function.');
} finally {
assert.isTrue(errorsHappen);
}
Expand All @@ -53,7 +53,7 @@ describe('watchman', () => {
try {
var wm = new watchman('', mockObjectHandler); // eslint-disable-line no-unused-vars
} catch (err) {
assert.equal(err, 'uri \'undefinedundefined\' not valid.');
assert.equal(err, 'uri \'undefinedundefined\' not valid watch uri.');
errorsHappen = true;
}
assert.isTrue(errorsHappen);
Expand Down Expand Up @@ -83,7 +83,7 @@ describe('watchman', () => {
errorsHappen = true;
assert.equal(err, '');
} finally {
assert.equal(wm.selfLink, '/api/v1/namespaces/default/services/kubernetes');
assert.equal(wm.selfLink, '/api/v1/watch/namespaces/default/services/kubernetes');
assert.isFalse(errorsHappen);
}

Expand Down Expand Up @@ -154,7 +154,7 @@ describe('watchman', () => {
let myOptions = dummyOptions;
myOptions.logger = dummyLogger;
nock('https://localhost:32263')
.get('/api/v1/namespaces/default/services/kubernetes')
.get('/api/v1/watch/namespaces/default/services/kubernetes')
.reply(200, data1);
let errorsHappen = false;
try {
Expand Down Expand Up @@ -201,19 +201,19 @@ describe('watchman', () => {
log.info('dummyLogger', msg);
},
error: (msg) => {
assert.equal(msg, 'GET /api/v1/namespaces/default/services/kubernetes returned 201');
assert.equal(msg, 'GET /api/v1/watch/namespaces/default/services/kubernetes returned 201');
wm.end();
}
};
let myOptions = dummyOptions;
myOptions.logger = dummyLogger;
myOptions.requestOptions.baseUrl = 'https://localhost:666';
myOptions.rewatchOnTimeout=false;
myOptions.rewatchOnTimeout = false;
let xmockObjectHandler = (data) => {
log.info('xmockObjectHandler', data);
};
nock('https://localhost:666')
.get('/api/v1/namespaces/default/services/kubernetes')
.get('/api/v1/watch/namespaces/default/services/kubernetes')
.reply(201);
let errorsHappen = false;
try {
Expand All @@ -239,20 +239,20 @@ describe('watchman', () => {
log.info('dummyLogger', msg);
},
error: (msg) => {
assert.equal(msg, 'GET /api/v1/namespaces/default/services/kubernetes errored');
assert.equal(msg, 'GET /api/v1/watch/namespaces/default/services/kubernetes errored');
wm.end();
done();
}
};
let myOptions = dummyOptions;
myOptions.logger = dummyLogger;
myOptions.requestOptions.baseUrl = 'https://localhost:666';
myOptions.rewatchOnTimeout=false;
myOptions.rewatchOnTimeout = false;
let xmockObjectHandler = (data) => {
log.info('xmockObjectHandler', data);
};
nock('https://localhost:666')
.get('/api/v1/namespaces/default/services/kubernetes')
.get('/api/v1/watch/namespaces/default/services/kubernetes')
.replyWithError('test errorstream error');
let errorsHappen = false;
try {
Expand Down

0 comments on commit 2c9611a

Please sign in to comment.