Skip to content

Commit

Permalink
feat: add MockController, MockKubeResourceMeta
Browse files Browse the repository at this point in the history
- these will enable simpler testing here
- it should also enable simpler testing of the `mustachetemplate`
  controller
- this is also ground work for a PR to `mustachetemplate` to add a new
  script it its `bin/` that can render MTPs from files on disk, instead
  of only k8s resources in a live environment, to enable better testing
  of MTPs generally
  • Loading branch information
charlesthomas committed Jun 27, 2022
1 parent 3321891 commit e40c9e1
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 114 deletions.
8 changes: 7 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ const CompositeController = require('./lib/CompositeController');

const FetchEnvs = require('./lib/FetchEnvs');

const MockController = require('./lib/MockController');

const MockKubeResourceMeta = require('./lib/MockKubeResourceMeta');

module.exports = {
BaseController,
BaseDownloadController,
BaseTemplateController,
CompositeController,
FetchEnvs
FetchEnvs,
MockController,
MockKubeResourceMeta
};
11 changes: 8 additions & 3 deletions lib/BaseTemplateController.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,19 @@ module.exports = class BaseTemplateController extends CompositeController {
super(params);
}

async added() {
let fetchEnvs = new FetchEnvs(this);
let env = await fetchEnvs.get('spec');
concatTemplates() {
let objTemplates = objectPath.get(this.data, ['object', 'spec', 'templates'], []);
if (!Array.isArray(objTemplates)) objTemplates = [objTemplates];
let strTemplates = objectPath.get(this.data, ['object', 'spec', 'strTemplates'], []);
if (!Array.isArray(strTemplates)) strTemplates = [strTemplates];
let templates = objTemplates.concat(strTemplates);
return templates;
}

async added() {
let fetchEnvs = new FetchEnvs(this);
let env = await fetchEnvs.get('spec');
let templates = this.concatTemplates();
templates = await this.processTemplate(templates, env);
if (!Array.isArray(templates) || templates.length == 0) {
this.updateRazeeLogs('warn', { controller: 'BaseTemplate', message: 'No templates found to apply' });
Expand Down
17 changes: 17 additions & 0 deletions lib/MockController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const MockKubeResourceMeta = require('../lib/MockKubeResourceMeta');

module.exports = class MockController {
constructor(eventData, kubeData) {
this.data = eventData;
this.kubeResourceMeta = new MockKubeResourceMeta(
this.data.object.apiVersion,
this.data.object.kind,
kubeData
);
this.kubeClass = {
getKubeResourceMeta: (apiVersion, kind) => {
return new MockKubeResourceMeta(apiVersion, kind, kubeData);
}
};
}
};
60 changes: 60 additions & 0 deletions lib/MockKubeResourceMeta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module.exports = class MockKubeResourceMeta {
constructor(apiVersion, kind, kubeData) {
this._apiVersion = ((apiVersion === undefined || apiVersion === '') ? 'deploy.razee.io/v1alpha2' : apiVersion);
this._kind = ((kind === undefined || kind === '') ? 'MustacheTemplate' : kind);
this.kubeData = kubeData;
}

async request(reqOpt) {
const ref = {
apiVersion: reqOpt.uri.apiVersion,
kind: reqOpt.uri.kind,
name: reqOpt.uri.name,
namespace: reqOpt.uri.namespace,
labelSelector: reqOpt?.qs?.labelSelector
};

const res = await this.kubeGetResource(ref);
return res;
}

async get(name, namespace) {
const ref = this.uri({ name, namespace });
return await this.kubeGetResource(ref);
}

uri(options) {
return { ...options, apiVersion: this._apiVersion, kind: this._kind, };
}

async kubeGetResource(ref) {
const {
name,
labelSelector,
namespace,
kind,
apiVersion
} = ref;
if (!this.kubeData[kind]) {
return;
}

let fn = labelSelector ? 'filter' : 'find';
let lookup = this.kubeData[kind][fn](obj => {
let match = true;
match = (obj.apiVersion === apiVersion && match) ? true : false;
match = (obj.kind === kind && match) ? true : false;
match = ((obj.metadata.name === name || labelSelector !== undefined) && match) ? true : false;
match = (obj.metadata.namespace === namespace && match) ? true : false;
if (labelSelector) {
const objLabels = obj.metadata.labels ?? {};
labelSelector.split(',').forEach(label => {
let [key, value] = label.split('=');
match = (objLabels[key] === value && match) ? true : false;
});
}
return match;
});
return labelSelector ? { items: lookup } : lookup;
}
};
146 changes: 36 additions & 110 deletions test/fetchEnvs-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,124 +17,50 @@
const assert = require('chai').assert;
const FetchEnvs = require('../lib/FetchEnvs');
const fs = require('fs-extra');


const krm = {
_apiVersion: 'deploy.razee.io/v1alpha2',
_kind: 'MustacheTemplate',
async request(reqOpt) {
const ref = {
apiVersion: reqOpt.uri.apiVersion,
kind: reqOpt.uri.kind,
name: reqOpt.uri.name,
namespace: reqOpt.uri.namespace,
labelSelector: reqOpt?.qs?.labelSelector
};

const res = await kubeGetResource(ref);
return res;
},
async get(name, namespace) {
const ref = this.uri({ name, namespace });

return await kubeGetResource(ref);
},
uri(options) {
return { ...options, apiVersion: this._apiVersion, kind: this._kind, };
const MockController = require('../lib/MockController');

const envData = fs.readJsonSync(`${__dirname}/fetchEnvs-test-scenarios/sampleData.json`);

const controllerData = {
type: 'ADDED',
object: {
apiVersion: 'deploy.razee.io/v1alpha2',
kind: 'MustacheTemplate',
metadata: {
name: 'rd-test',
namespace: 'razeedeploy',
},
spec: {
clusterAuth: { impersonateUser: 'razeedeploy' },
templateEngine: 'handlebars',
envFrom: [],
env: [],
tempates: [],
strTemplates: [],
}
}
};

const controllerObject = {
data: {
type: 'ADDED',
object: {
apiVersion: 'deploy.razee.io/v1alpha2',
kind: 'MustacheTemplate',
metadata: {
name: 'rd-test',
namespace: 'razeedeploy',
},
spec: {
clusterAuth: { impersonateUser: 'razeedeploy' },
templateEngine: 'handlebars',
const altPathControllerData = {
type: 'ADDED',
object: {
apiVersion: 'deploy.razee.io/v1alpha2',
kind: 'FeatureFlagSetLD',
metadata: {
name: 'rd-test',
namespace: 'razeedeploy',
},
spec: {
identityRef: {
envFrom: [],
env: [],
tempates: [],
strTemplates: [],
}
}
},
kubeResourceMeta: krm,
kubeClass: {
getKubeResourceMeta: (apiVersion, kind) => {
const newKRM = { ...krm };
newKRM._apiVersion = apiVersion;
newKRM._kind = kind;
return newKRM;
}
},
};

const altPathControllerObject = {
data: {
type: 'ADDED',
object: {
apiVersion: 'deploy.razee.io/v1alpha2',
kind: 'FeatureFlagSetLD',
metadata: {
name: 'rd-test',
namespace: 'razeedeploy',
},
spec: {
identityRef: {
envFrom: [],
env: []
}
env: []
}
}
},
kubeResourceMeta: krm,
kubeClass: {
getKubeResourceMeta: (apiVersion, kind) => {
const newKRM = { ...krm };
newKRM._apiVersion = apiVersion;
newKRM._kind = kind;
return newKRM;
}
},
};

async function kubeGetResource(ref) {
const kubeData = await fs.readJSON(`${__dirname}/fetchEnvs-test-scenarios/sampleData.json`);
const {
name,
labelSelector,
namespace,
kind,
apiVersion
} = ref;
if (!kubeData[kind]) {
return;
}
};

let fn = labelSelector ? 'filter' : 'find';
let lookup = kubeData[kind][fn](obj => {
let match = true;
match = (obj.apiVersion === apiVersion && match) ? true : false;
match = (obj.kind === kind && match) ? true : false;
match = ((obj.metadata.name === name || labelSelector !== undefined) && match) ? true : false;
match = (obj.metadata.namespace === namespace && match) ? true : false;
if (labelSelector) {
const objLabels = obj.metadata.labels ?? {};
labelSelector.split(',').forEach(label => {
let [key, value] = label.split('=');
match = (objLabels[key] === value && match) ? true : false;
});
}
return match;
});
return labelSelector ? { items: lookup } : lookup;
}
const controllerObject = new MockController(controllerData, envData);
const altPathControllerObject = new MockController(altPathControllerData, envData);

describe('fetchEnvs', function () {
afterEach(function () {
Expand Down

0 comments on commit e40c9e1

Please sign in to comment.