Skip to content

Commit

Permalink
refactor(BaseObject): add a ContainerBaseObject to facilitate named…
Browse files Browse the repository at this point in the history
… resources (#102)

Some named resources (e.g., `pod('foo'))` can contain resources (e.g.,
`pod('foo').log` or `deploy('bar').status`). The ContainerBaseObject makes
implementing these resources easier.

This is groundwork for #47.
  • Loading branch information
silasbw authored May 17, 2017
1 parent a4708cc commit b8d8dac
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 7 deletions.
49 changes: 49 additions & 0 deletions lib/container-base-object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';

const BaseObject = require('./base');

class ContainerBaseObject extends BaseObject {
/**
* Create generic Kubernetes API object that might contain other resources.
* For example, a named Pod contains .log resources (core.ns.pods('foo').log).
*
* @param {object} options - Options object
* @param {string} options.resources - Array of resources to add
*/
constructor(options) {
super(options);
if (options.resources) {
options.resources.forEach(resource => this.addResource(resource));
}
}

/**
* Add a resource to the container object.
* @param {string|object} options - resource name or options object
* @param {string} options.name - resource name
* @param {fn} options.Constructor - constructor for new resource
* @returns {object} returns this to facilitate chaining
*/
addResource(options) {
if (typeof options === 'string') {
options = { name: options, Constructor: BaseObject };
} else if (!options.name || !options.Constructor) {
throw new RangeError(
'NamedBaseObject.addResource: options requires .name and .Constructor');
}

if (this[options.name]) {
throw new RangeError(
`NamedBaseObject.addResource: .${ options.name } already exists`);
}
this[options.name] = new options.Constructor({
api: this.api,
name: options.name,
parentPath: this.path
});

return this;
}
}

module.exports = ContainerBaseObject;
12 changes: 5 additions & 7 deletions lib/pods.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
const util = require('util');

const BaseObject = require('./base');
const ContainerBaseObject = require('./container-base-object');

class NamedPods extends BaseObject {
class NamedPods extends ContainerBaseObject {
/**
* Create a named Pod Kubernetes object with a log.
* @extends BaseObject
Expand All @@ -14,12 +15,9 @@ class NamedPods extends BaseObject {
* @param {string} options.path - Optional path of this resource
*/
constructor(options) {
super(options);
this.log = new BaseObject({
api: this.api,
name: 'log',
parentPath: this.path
});
super(Object.assign({
resources: ['log']
}, options));
}
}

Expand Down
30 changes: 30 additions & 0 deletions test/container-base-object.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';

const assume = require('assume');

const ContainerBaseObject = require('../lib/container-base-object');

describe('lib.container-base-object', () => {
describe('.ContainerBaseObject', () => {
it('adds resources specified in the constructor', () => {
const fake = new ContainerBaseObject({ resources: ['foo'] });
assume(fake.foo).is.a('function');
});

it('throws an error if missing resource name', () => {
const fn = () => new ContainerBaseObject({ resources: [{ Constructor: 'fake' }] });
assume(fn).throws();
});

it('throws an error if missing resource Constructor', () => {
const fn = () => new ContainerBaseObject({ resources: [{ name: 'fake' }] });
assume(fn).throws();
});

it('throws an error for adding the resource', () => {
const fake = new ContainerBaseObject({ resources: ['foo'] });
const fn = () => fake.addResource('foo');
assume(fn).throws();
});
});
});

0 comments on commit b8d8dac

Please sign in to comment.