Skip to content

Commit

Permalink
feat(CustomResourceDefinition): Add support for CRDs (#149)
Browse files Browse the repository at this point in the history
Adds `CustomResourceDefinition`, which replaces `ThirdPartyResources` starting Kubernetes 1.7.
  • Loading branch information
fhemberger authored and silasbw committed Nov 14, 2017
1 parent 8e77449 commit 4261c2e
Show file tree
Hide file tree
Showing 9 changed files with 343 additions and 1 deletion.
22 changes: 22 additions & 0 deletions lib/api-extensions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

const ApiGroup = require('./api-group');
const CustomResourceDefiniton = require('./custom-resource-definition');

class ApiExtensions extends ApiGroup {
constructor(options) {
options = Object.assign({}, options, {
path: 'apis/apiextensions.k8s.io',
version: options.version || 'v1beta1',
groupResources: [
'customresourcedefinitions'
],
namespaceResources: [
{ name: 'customresourcedefinitions', Constructor: CustomResourceDefiniton }
]
});
super(options);
}
}

module.exports = ApiExtensions;
6 changes: 5 additions & 1 deletion lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ const Extensions = require('./extensions');
const Apps = require('./apps');
const Batch = require('./batch');
const Rbac = require('./rbac');
const ApiExtensions = require('./api-extensions');

const groups = {
'extensions': Extensions,
'apps': Apps,
'batch': Batch,
'rbac.authorization.k8s.io': Rbac
'rbac.authorization.k8s.io': Rbac,
'apiextensions.k8s.io': ApiExtensions
};

class Api {
Expand All @@ -22,6 +24,7 @@ class Api {
* @param {object} options.apps - Optional default Apps client
* @param {object} options.batch - Optional default Batch client
* @param {object} options.rbac - Optional default RBAC client
* @param {object} options.apiExtensions - Optional default ApiExtensions client
*/
constructor(options) {
this.options = options;
Expand All @@ -30,6 +33,7 @@ class Api {
this.apps = options.apps || new Apps(options);
this.batch = options.batch || new Batch(options);
this.rbac = options.rbac || new Rbac(options);
this.apiExtensions = options.apiExtensions || new ApiExtensions(options);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions lib/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports.aliasResources = function (resourceObject) {
componentstatuses: ['cs'],
configmaps: ['cm'],
cronjobs: [],
customresourcedefinitions: ['crd'],
daemonsets: ['ds'],
deployments: ['deploy'],
events: ['ev'],
Expand All @@ -36,6 +37,7 @@ module.exports.aliasResources = function (resourceObject) {
serviceaccounts: [],
services: ['svc'],
statefulsets: [],
// Deprecated name of customresourcedefinition in kubernetes 1.7
thirdpartyresources: []
};

Expand Down
27 changes: 27 additions & 0 deletions lib/custom-resource-definition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict';

const ApiGroup = require('./api-group');

class CustomResourceDefinition extends ApiGroup {
constructor(options) {
options = Object.assign({}, options, {
path: `apis/${ options.group }`,
version: options.version || 'v1',
groupResources: [],
namespaceResources: []
});
super(options);

if (options.resources) {
options.resources.forEach(resource => this.addResource(resource));
}
}

addResource(resourceName) {
this.namespace.addResource(resourceName);
super.addResource(resourceName);
return this;
}
}

module.exports = CustomResourceDefinition;
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports.Api = require('./api');
module.exports.Core = core;
module.exports.Extensions = require('./extensions');
module.exports.ThirdPartyResources = require('./third-party-resources');
module.exports.CustomResourceDefinitions = require('./custom-resource-definitions');
module.exports.config = require('./config');
module.exports.Apps = require('./apps');
module.exports.Batch = require('./batch');
Expand Down
95 changes: 95 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions test/api-extensions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict';

const assume = require('assume');
const async = require('async');
const nock = require('nock');

const common = require('./common');
const beforeTesting = common.beforeTesting;

const testApiExtensions = {
apiVersion: 'apiextensions.k8s.io/v1beta1',
kind: 'CustomResourceDefinition',
metadata: {
name: 'test.example.com'
},
spec: {
group: 'example.com',
version: 'v1',
scope: 'Namespaced',
names: {
plural: 'tests',
singular: 'test',
kind: 'Test',
shortNames: [
't'
]
}
}
};

describe('lib.apiextensions', () => {
describe('.ApiExtensions', () => {
const testCustomResourceName = testApiExtensions.metadata.name;

beforeTesting('unit', () => {
nock(common.apiExtensions.url)
.post(`${ common.apiExtensions.path }/customresourcedefinitions`)
.reply(201, testApiExtensions)
.get(`${ common.apiExtensions.path }/customresourcedefinitions/${ testCustomResourceName }`)
.reply(200, testApiExtensions);
});

// NOTE: Running only unit tests. Setting up CRD is more involved, and it
// makes it cumbersome to run the other integration tests. We need
// improvements to our integration test harness to make this work well.
common.only('unit', 'can POST and GET', done => {
async.series([
next => common.apiExtensions.customresourcedefinitions.post({ body: testApiExtensions }, next),
next => common.apiExtensions.customresourcedefinitions.get(testCustomResourceName, next)
], (err, results) => {
assume(err).is.falsy();
const getResult = results[1];
assume(getResult.metadata.name).is.equal(testCustomResourceName);
done();
});
});
});
});
7 changes: 7 additions & 0 deletions test/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ const path = require('path');
const yaml = require('js-yaml');

const Api = require('../lib/api');
const ApiExtensions = require('../lib/api-extensions');
const Apps = require('../lib/apps');
const Batch = require('../lib/batch');
const Core = require('../lib/core');
const Extensions = require('../lib/extensions');
const Rbac = require('../lib/rbac');
const ThirdPartyResources = require('../lib/third-party-resources');
const CustomResourceDefinition = require('../lib/custom-resource-definition');

const defaultName = process.env.NAMESPACE || 'integration-tests';
const defaultTimeout = process.env.TIMEOUT || 30000;
Expand Down Expand Up @@ -68,6 +70,7 @@ function newName() {
function injectApis(options) {
const apis = {
api: { Constructor: Core },
apiExtensions: { Constructor: ApiExtensions },
apiGroup: { Constructor: Api },
apps: { Constructor: Apps },
batch: { Constructor: Batch },
Expand All @@ -76,6 +79,9 @@ function injectApis(options) {
rbac: { Constructor: Rbac },
thirdPartyResources: {
Constructor: ThirdPartyResources, options: { group: 'kubernetes-client.com' }
},
customResourceDefinitions: {
Constructor: CustomResourceDefinition, options: { group: 'kubernetes-client.com' }
}
};
Object.keys(apis).forEach(apiName => {
Expand Down Expand Up @@ -198,3 +204,4 @@ module.exports.beforeTesting = beforeTesting;
module.exports.beforeTestingEach = beforeTestingEach;
module.exports.only = only;
module.exports.thirdPartyDomain = 'kubernetes-client.com';
module.exports.customResourceDomain = 'kubernetes-client.com';
Loading

0 comments on commit 4261c2e

Please sign in to comment.