mirror of
https://github.com/mmumshad/ansible-playable.git
synced 2025-02-12 16:01:53 +00:00
Update server side test cases and disable client side tests for now. Integrate later.
This commit is contained in:
parent
ab295a073a
commit
9c880c0bba
13 changed files with 588 additions and 318 deletions
|
@ -371,7 +371,9 @@ gulp.task('serve:dist', cb => {
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('test', cb => {
|
gulp.task('test', cb => {
|
||||||
return runSequence('test:server', 'test:client', cb);
|
//return runSequence('test:server', 'test:client', cb);
|
||||||
|
//TODO: Integrate client side tests
|
||||||
|
return runSequence('test:server', cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('test:server', cb => {
|
gulp.task('test:server', cb => {
|
||||||
|
@ -393,6 +395,11 @@ gulp.task('mocha:integration', () => {
|
||||||
.pipe(mocha());
|
.pipe(mocha());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task('mocha:integration:one', () => {
|
||||||
|
return gulp.src([`${serverPath}/**/custom_module.integration.js`, 'mocha.global.js'])
|
||||||
|
.pipe(mocha());
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task('test:server:coverage', cb => {
|
gulp.task('test:server:coverage', cb => {
|
||||||
runSequence('coverage:pre',
|
runSequence('coverage:pre',
|
||||||
'env:all',
|
'env:all',
|
||||||
|
|
|
@ -86,7 +86,11 @@ export function command(req, res) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new Ansible in the DB
|
/**
|
||||||
|
* List Ansible Modules
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
*/
|
||||||
export function modules(req, res) {
|
export function modules(req, res) {
|
||||||
|
|
||||||
var ansibleEngine = req.body.ansibleEngine;
|
var ansibleEngine = req.body.ansibleEngine;
|
||||||
|
@ -108,6 +112,7 @@ export function modules(req, res) {
|
||||||
|
|
||||||
// Gets a single Deploy from the DB
|
// Gets a single Deploy from the DB
|
||||||
export function getLogs(req, res) {
|
export function getLogs(req, res) {
|
||||||
|
console.log("Param ID " + req.params.id);
|
||||||
return Ansible.findById(req.params.id).exec()
|
return Ansible.findById(req.params.id).exec()
|
||||||
.then(handleEntityNotFound(res))
|
.then(handleEntityNotFound(res))
|
||||||
.then(function(entity){
|
.then(function(entity){
|
||||||
|
@ -169,6 +174,7 @@ export function execute(req, res) {
|
||||||
|
|
||||||
var resultSent = false;
|
var resultSent = false;
|
||||||
|
|
||||||
|
// Execute Ansible Playbook and return immediately with a new Job (Ansible) object
|
||||||
ansibleTool.executeAnsible(logfilename, project_folder, playbook_name, inventory_file_name, tags_joined, limit_to_hosts_joined, verbose,check_mode,
|
ansibleTool.executeAnsible(logfilename, project_folder, playbook_name, inventory_file_name, tags_joined, limit_to_hosts_joined, verbose,check_mode,
|
||||||
function(data){
|
function(data){
|
||||||
//res.write(data)
|
//res.write(data)
|
||||||
|
@ -244,6 +250,7 @@ export function playbook_create(req, res) {
|
||||||
function(data){
|
function(data){
|
||||||
//res.write(data);
|
//res.write(data);
|
||||||
//res.end()
|
//res.end()
|
||||||
|
console.log("data = " + data);
|
||||||
if(!resultSent){
|
if(!resultSent){
|
||||||
resultSent = true;
|
resultSent = true;
|
||||||
res.send(data)
|
res.send(data)
|
||||||
|
@ -251,6 +258,7 @@ export function playbook_create(req, res) {
|
||||||
},
|
},
|
||||||
function(data){
|
function(data){
|
||||||
//res.write(data)
|
//res.write(data)
|
||||||
|
console.log("data = " + data);
|
||||||
if(!resultSent){
|
if(!resultSent){
|
||||||
resultSent = true;
|
resultSent = true;
|
||||||
res.status(500).send(data)
|
res.status(500).send(data)
|
||||||
|
|
|
@ -4,187 +4,318 @@
|
||||||
|
|
||||||
var app = require('../..');
|
var app = require('../..');
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
import User from '../user/user.model';
|
||||||
|
|
||||||
var newAnsible;
|
var newAnsible;
|
||||||
|
|
||||||
describe('Ansible API:', function() {
|
describe('Ansible API:', function() {
|
||||||
describe('GET /api/ansible', function() {
|
var token;
|
||||||
var ansibles;
|
var user;
|
||||||
|
var ansible_job;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
// Clear users before testing
|
||||||
|
before(function() {
|
||||||
|
return User.remove().then(function() {
|
||||||
|
user = new User({
|
||||||
|
name: 'Fake User',
|
||||||
|
email: 'test@example.com',
|
||||||
|
password: 'password'
|
||||||
|
});
|
||||||
|
|
||||||
|
return user.save();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear users after testing
|
||||||
|
after(function() {
|
||||||
|
return User.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GET /api/users/me', function() {
|
||||||
|
|
||||||
|
before(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get('/api/ansible')
|
.post('/auth/local')
|
||||||
|
.send({
|
||||||
|
email: 'test@example.com',
|
||||||
|
password: 'password'
|
||||||
|
})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
if(err) {
|
token = res.body.token;
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
ansibles = res.body;
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respond with JSON array', function() {
|
it('should respond with a user profile when authenticated', function(done) {
|
||||||
expect(ansibles).to.be.instanceOf(Array);
|
request(app)
|
||||||
|
.get('/api/users/me')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
|
.expect(200)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
expect(res.body._id.toString()).to.equal(user._id.toString());
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should respond with a 401 when not authenticated', function(done) {
|
||||||
|
request(app)
|
||||||
|
.get('/api/users/me')
|
||||||
|
.expect(401)
|
||||||
|
.end(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /api/ansible', function() {
|
describe('POST /modules/list', function() {
|
||||||
|
var modules;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.post('/api/ansible')
|
.post('/api/ansible/modules/list')
|
||||||
|
.timeout(10000)
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.send({
|
.send({
|
||||||
name: 'New Ansible',
|
ansibleEngine: {
|
||||||
info: 'This is the brand new ansible!!!'
|
'host' : ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
//.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
if(err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
modules = res.text;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should respond with list of Ansible Modules (containing ping module)', function() {
|
||||||
|
expect(modules).to.contain('ping');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('POST /command to execute a sample command - echo "Hello World"', function() {
|
||||||
|
var modules;
|
||||||
|
|
||||||
|
beforeEach(function(done) {
|
||||||
|
request(app)
|
||||||
|
.post('/api/ansible/command')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
|
.send({
|
||||||
|
command: 'echo "Hello World"'
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
//.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
if(err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
modules = res.text;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should respond with the result of command', function() {
|
||||||
|
expect(modules).to.contain('Hello World');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('POST /inventory/create', function() {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
beforeEach(function(done) {
|
||||||
|
request(app)
|
||||||
|
.post('/api/ansible/inventory/create')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
|
.send({
|
||||||
|
ansibleEngine: {
|
||||||
|
host : '',
|
||||||
|
projectFolder: '/tmp'
|
||||||
|
},
|
||||||
|
inventoryName: 'inventory.txt',
|
||||||
|
inventoryFileContents: 'localhost ansible_connection=local'
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
//.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
if(err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
result = res.text;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should respond with "file written"', function() {
|
||||||
|
expect(result).to.contain('file written');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('POST /playbook/create', function() {
|
||||||
|
var result;
|
||||||
|
|
||||||
|
beforeEach(function(done) {
|
||||||
|
request(app)
|
||||||
|
.post('/api/ansible/playbook/create')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
|
.send({
|
||||||
|
ansibleEngine: {
|
||||||
|
host : '',
|
||||||
|
projectFolder: '/tmp'
|
||||||
|
},
|
||||||
|
playbookName: 'test_playbook.yml',
|
||||||
|
playbookFileContents: '-\n' +
|
||||||
|
' name: "Test Play1"\n' +
|
||||||
|
' hosts: localhost\n' +
|
||||||
|
' tasks:\n' +
|
||||||
|
' - name: "Test Task1"\n' +
|
||||||
|
' ping:\n'
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
//.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
if(err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
result = res.text;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should respond with "file written"', function() {
|
||||||
|
expect(result).to.contain('file written');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('POST /execute', function() {
|
||||||
|
|
||||||
|
beforeEach(function(done) {
|
||||||
|
request(app)
|
||||||
|
.post('/api/ansible/execute')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
|
.send({
|
||||||
|
ansibleEngine: {
|
||||||
|
host : '',
|
||||||
|
projectFolder: '/tmp/'
|
||||||
|
},
|
||||||
|
selectedPlaybook: 'test_playbook.yml',
|
||||||
|
inventory_file_name: 'inventory.txt',
|
||||||
})
|
})
|
||||||
.expect(201)
|
.expect(201)
|
||||||
.expect('Content-Type', /json/)
|
//.expect('Content-Type', /json/)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
newAnsible = res.body;
|
ansible_job = res.body;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respond with the newly created ansible', function() {
|
|
||||||
expect(newAnsible.name).to.equal('New Ansible');
|
it('should respond with an Ansible Job object', function() {
|
||||||
expect(newAnsible.info).to.equal('This is the brand new ansible!!!');
|
expect(ansible_job.selectedPlaybook).to.equal('test_playbook.yml');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /api/ansible/:id', function() {
|
describe('GET /:id', function() {
|
||||||
var ansible;
|
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get(`/api/ansible/${newAnsible._id}`)
|
.get('/api/ansible/' + ansible_job._id)
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
//.expect('Content-Type', /json/)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
ansible = res.body;
|
ansible_job = res.body;
|
||||||
|
console.log("ansible_job " + JSON.stringify(ansible_job));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
ansible = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with the requested ansible', function() {
|
it('should respond with an Ansible Job object', function() {
|
||||||
expect(ansible.name).to.equal('New Ansible');
|
expect(ansible_job.selectedPlaybook).to.equal('test_playbook.yml');
|
||||||
expect(ansible.info).to.equal('This is the brand new ansible!!!');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /api/ansible/:id', function() {
|
describe('POST /playbook/delete', function() {
|
||||||
var updatedAnsible;
|
var result;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.put(`/api/ansible/${newAnsible._id}`)
|
.post('/api/ansible/playbook/delete')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.send({
|
.send({
|
||||||
name: 'Updated Ansible',
|
ansibleEngine: {
|
||||||
info: 'This is the updated ansible!!!'
|
host : '',
|
||||||
|
projectFolder: '/tmp'
|
||||||
|
},
|
||||||
|
playbookName: 'test_playbook.yml',
|
||||||
})
|
})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
//.expect('Content-Type', /json/)
|
||||||
.end(function(err, res) {
|
|
||||||
if(err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
updatedAnsible = res.body;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
updatedAnsible = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with the updated ansible', function() {
|
|
||||||
expect(updatedAnsible.name).to.equal('Updated Ansible');
|
|
||||||
expect(updatedAnsible.info).to.equal('This is the updated ansible!!!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with the updated ansible on a subsequent GET', function(done) {
|
|
||||||
request(app)
|
|
||||||
.get(`/api/ansible/${newAnsible._id}`)
|
|
||||||
.expect(200)
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
let ansible = res.body;
|
result = res;
|
||||||
|
|
||||||
expect(ansible.name).to.equal('Updated Ansible');
|
|
||||||
expect(ansible.info).to.equal('This is the updated ansible!!!');
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should respond with status code 200', function() {
|
||||||
|
expect(result.status).to.equal(200);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PATCH /api/ansible/:id', function() {
|
|
||||||
var patchedAnsible;
|
describe('POST /inventory/delete', function() {
|
||||||
|
var result;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.patch(`/api/ansible/${newAnsible._id}`)
|
.post('/api/ansible/inventory/delete')
|
||||||
.send([
|
.set('authorization', `Bearer ${token}`)
|
||||||
{ op: 'replace', path: '/name', value: 'Patched Ansible' },
|
.send({
|
||||||
{ op: 'replace', path: '/info', value: 'This is the patched ansible!!!' }
|
ansibleEngine: {
|
||||||
])
|
host : '',
|
||||||
|
projectFolder: '/tmp'
|
||||||
|
},
|
||||||
|
inventoryName: 'inventory.txt',
|
||||||
|
})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
//.expect('Content-Type', /json/)
|
||||||
.end(function(err, res) {
|
.end((err, res) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
patchedAnsible = res.body;
|
result = res;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
patchedAnsible = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with the patched ansible', function() {
|
it('should respond with status code 200', function() {
|
||||||
expect(patchedAnsible.name).to.equal('Patched Ansible');
|
expect(result.status).to.equal(200);
|
||||||
expect(patchedAnsible.info).to.equal('This is the patched ansible!!!');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /api/ansible/:id', function() {
|
//TODO: Add more Ansible test cases here
|
||||||
it('should respond with 204 on successful removal', function(done) {
|
|
||||||
request(app)
|
|
||||||
.delete(`/api/ansible/${newAnsible._id}`)
|
|
||||||
.expect(204)
|
|
||||||
.end(err => {
|
|
||||||
if(err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with 404 when ansible does not exist', function(done) {
|
|
||||||
request(app)
|
|
||||||
.delete(`/api/ansible/${newAnsible._id}`)
|
|
||||||
.expect(404)
|
|
||||||
.end(err => {
|
|
||||||
if(err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,9 +5,22 @@ var controller = require('./ansible.controller');
|
||||||
|
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
|
|
||||||
router.get('/', controller.index);
|
// List, create and get Ansible Jobs
|
||||||
|
router.get('/runs', controller.index);
|
||||||
|
router.get('/:id', controller.show);
|
||||||
|
router.post('/', controller.create);
|
||||||
|
router.put('/:id', controller.upsert);
|
||||||
|
router.patch('/:id', controller.patch);
|
||||||
|
router.delete('/:id', controller.destroy);
|
||||||
|
|
||||||
router.post('/modules', controller.modules);
|
// Ansible Command line APIs
|
||||||
|
// - Create and modify inventory files
|
||||||
|
// - Create and modify playbooks
|
||||||
|
// - Create and modify roles
|
||||||
|
// - List tags
|
||||||
|
// - Create and modify files
|
||||||
|
// - Create and modify Var files
|
||||||
|
router.post('/modules/list', controller.modules);
|
||||||
router.post('/command', controller.command);
|
router.post('/command', controller.command);
|
||||||
router.post('/execute', controller.execute);
|
router.post('/execute', controller.execute);
|
||||||
|
|
||||||
|
@ -50,10 +63,5 @@ router.post('/vars/roles/get', controller.get_roles_vars);
|
||||||
|
|
||||||
router.get('/logs/:id', controller.getLogs);
|
router.get('/logs/:id', controller.getLogs);
|
||||||
|
|
||||||
router.get('/:id', controller.show);
|
|
||||||
router.post('/', controller.create);
|
|
||||||
router.put('/:id', controller.upsert);
|
|
||||||
router.patch('/:id', controller.patch);
|
|
||||||
router.delete('/:id', controller.destroy);
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
@ -10,7 +10,15 @@ var ansibleCtrlStub = {
|
||||||
create: 'ansibleCtrl.create',
|
create: 'ansibleCtrl.create',
|
||||||
upsert: 'ansibleCtrl.upsert',
|
upsert: 'ansibleCtrl.upsert',
|
||||||
patch: 'ansibleCtrl.patch',
|
patch: 'ansibleCtrl.patch',
|
||||||
destroy: 'ansibleCtrl.destroy'
|
destroy: 'ansibleCtrl.destroy',
|
||||||
|
modules: 'ansibleCtrl.modules',
|
||||||
|
command: 'ansibleCtrl.command',
|
||||||
|
execute: 'ansibleCtrl.execute',
|
||||||
|
project_files: 'ansibleCtrl.project_files',
|
||||||
|
playbook_get: 'ansibleCtrl.playbook_get',
|
||||||
|
playbook_create: 'ansibleCtrl.playbook_create',
|
||||||
|
playbook_delete: 'ansibleCtrl.playbook_delete',
|
||||||
|
playbook_list: 'ansibleCtrl.playbook_list',
|
||||||
};
|
};
|
||||||
|
|
||||||
var routerStub = {
|
var routerStub = {
|
||||||
|
@ -18,7 +26,15 @@ var routerStub = {
|
||||||
put: sinon.spy(),
|
put: sinon.spy(),
|
||||||
patch: sinon.spy(),
|
patch: sinon.spy(),
|
||||||
post: sinon.spy(),
|
post: sinon.spy(),
|
||||||
delete: sinon.spy()
|
delete: sinon.spy(),
|
||||||
|
modules: sinon.spy(),
|
||||||
|
command: sinon.spy(),
|
||||||
|
execute: sinon.spy(),
|
||||||
|
project_files: sinon.spy(),
|
||||||
|
playbook_get: sinon.spy(),
|
||||||
|
playbook_create: sinon.spy(),
|
||||||
|
playbook_delete: sinon.spy(),
|
||||||
|
playbook_list: sinon.spy()
|
||||||
};
|
};
|
||||||
|
|
||||||
// require the index with our stubbed out modules
|
// require the index with our stubbed out modules
|
||||||
|
@ -36,51 +52,70 @@ describe('Ansible API Router:', function() {
|
||||||
expect(ansibleIndex).to.equal(routerStub);
|
expect(ansibleIndex).to.equal(routerStub);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /api/ansible', function() {
|
describe('POST /api/ansible/modules/list', function() {
|
||||||
it('should route to ansible.controller.index', function() {
|
it('should route to ansible.controller.modules', function() {
|
||||||
expect(routerStub.get
|
|
||||||
.withArgs('/', 'ansibleCtrl.index')
|
|
||||||
).to.have.been.calledOnce;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /api/ansible/:id', function() {
|
|
||||||
it('should route to ansible.controller.show', function() {
|
|
||||||
expect(routerStub.get
|
|
||||||
.withArgs('/:id', 'ansibleCtrl.show')
|
|
||||||
).to.have.been.calledOnce;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /api/ansible', function() {
|
|
||||||
it('should route to ansible.controller.create', function() {
|
|
||||||
expect(routerStub.post
|
expect(routerStub.post
|
||||||
.withArgs('/', 'ansibleCtrl.create')
|
.withArgs('/modules/list', 'ansibleCtrl.modules')
|
||||||
).to.have.been.calledOnce;
|
).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /api/ansible/:id', function() {
|
describe('POST /api/ansible/command', function() {
|
||||||
it('should route to ansible.controller.upsert', function() {
|
it('should route to ansible.controller.command', function() {
|
||||||
expect(routerStub.put
|
expect(routerStub.post
|
||||||
.withArgs('/:id', 'ansibleCtrl.upsert')
|
.withArgs('/command', 'ansibleCtrl.command')
|
||||||
).to.have.been.calledOnce;
|
).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PATCH /api/ansible/:id', function() {
|
describe('POST /api/ansible/execute', function() {
|
||||||
it('should route to ansible.controller.patch', function() {
|
it('should route to ansible.controller.execute', function() {
|
||||||
expect(routerStub.patch
|
expect(routerStub.post
|
||||||
.withArgs('/:id', 'ansibleCtrl.patch')
|
.withArgs('/execute', 'ansibleCtrl.execute')
|
||||||
).to.have.been.calledOnce;
|
).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /api/ansible/:id', function() {
|
describe('POST /api/ansible/project/files', function() {
|
||||||
it('should route to ansible.controller.destroy', function() {
|
it('should route to ansible.controller.project_files', function() {
|
||||||
expect(routerStub.delete
|
expect(routerStub.post
|
||||||
.withArgs('/:id', 'ansibleCtrl.destroy')
|
.withArgs('/project/files', 'ansibleCtrl.project_files')
|
||||||
).to.have.been.calledOnce;
|
).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('POST /api/ansible/playbook/get', function() {
|
||||||
|
it('should route to ansible.controller.playbook_get', function() {
|
||||||
|
expect(routerStub.post
|
||||||
|
.withArgs('/playbook/get', 'ansibleCtrl.playbook_get')
|
||||||
|
).to.have.been.calledOnce;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('POST /api/ansible/playbook/create', function() {
|
||||||
|
it('should route to ansible.controller.playbook_create', function() {
|
||||||
|
expect(routerStub.post
|
||||||
|
.withArgs('/playbook/create', 'ansibleCtrl.playbook_create')
|
||||||
|
).to.have.been.calledOnce;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('POST /api/ansible/playbook/delete', function() {
|
||||||
|
it('should route to ansible.controller.playbook_delete', function() {
|
||||||
|
expect(routerStub.post
|
||||||
|
.withArgs('/playbook/delete', 'ansibleCtrl.playbook_delete')
|
||||||
|
).to.have.been.calledOnce;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('POST /api/ansible/playbook/list', function() {
|
||||||
|
it('should route to ansible.controller.playbook_list', function() {
|
||||||
|
expect(routerStub.post
|
||||||
|
.withArgs('/playbook/list', 'ansibleCtrl.playbook_list')
|
||||||
|
).to.have.been.calledOnce;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO: Add the remaining test cases here
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -93,43 +93,38 @@ export function index(req, res) {
|
||||||
.catch(handleError(res));*/
|
.catch(handleError(res));*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets a single CustomModule from the DB
|
// Gets a single CustomModule or a module_template from DB
|
||||||
export function show(req, res) {
|
export function show(req, res) {
|
||||||
console.log("Show " + req.params.custom_module);
|
console.log("Show " + req.params.custom_module);
|
||||||
var ansibleEngine = req.body.ansibleEngine;
|
var ansibleEngine = req.body.ansibleEngine;
|
||||||
|
|
||||||
if(!ansibleEngine.customModules){
|
if(!ansibleEngine.customModules){
|
||||||
res.status(500).send("Custom Modules Folder not defined in Ansible Engine")
|
return res.status(500).send("Custom Modules Folder not defined in Ansible Engine")
|
||||||
}
|
}
|
||||||
|
|
||||||
var command = 'cat "' + ansibleEngine.customModules + '"/' + req.params.custom_module;
|
var command = 'cat "' + ansibleEngine.customModules + '"/' + req.params.custom_module;
|
||||||
|
|
||||||
|
// If request is for module template, return module_template from default path
|
||||||
if(req.params.custom_module === 'template.py'){
|
if(req.params.custom_module === 'template.py'){
|
||||||
//command = 'cat ' + '/opt/ehc-builder-scripts/ansible_modules/template.py';
|
|
||||||
|
|
||||||
return require('fs').readFile('./helpers/module_template.py', (err, data) => {
|
return require('fs').readFile('./helpers/module_template.py', (err, data) => {
|
||||||
if (err) res.status(500).send(data);
|
if (err) return res.status(500).send(data);
|
||||||
res.send(data);
|
res.send(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}else{
|
||||||
|
ssh2_exec.executeCommand(command,
|
||||||
|
null,
|
||||||
|
function(data){
|
||||||
|
res.send(data);
|
||||||
|
},
|
||||||
|
function(data){
|
||||||
|
res.status(500).send(data)
|
||||||
|
},
|
||||||
|
ansibleEngine
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssh2_exec.executeCommand(command,
|
|
||||||
null,
|
|
||||||
function(data){
|
|
||||||
res.send(data);
|
|
||||||
},
|
|
||||||
function(data){
|
|
||||||
res.status(500).send(data)
|
|
||||||
},
|
|
||||||
ansibleEngine
|
|
||||||
);
|
|
||||||
|
|
||||||
/*return CustomModule.findById(req.params.custom_module).exec()
|
|
||||||
.then(handleEntityNotFound(res))
|
|
||||||
.then(respondWithResult(res))
|
|
||||||
.catch(handleError(res));*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test Module
|
// Test Module
|
||||||
|
@ -145,7 +140,7 @@ export function testModule(req, res) {
|
||||||
|
|
||||||
var test_module = '/tmp/test-module';
|
var test_module = '/tmp/test-module';
|
||||||
|
|
||||||
var command = 'chmod 755 ' + test_module + '; ' + test_module + ' -m "' + ansibleEngine.customModules + '/' + req.params.custom_module + "\" -a '" + JSON.stringify(moduleArgs) + "'";
|
var command = 'chmod 755 ' + test_module + '; python ' + test_module + ' -m "' + ansibleEngine.customModules + '/' + req.params.custom_module + "\" -a '" + JSON.stringify(moduleArgs) + "'";
|
||||||
|
|
||||||
scp2_exec.copyFileToScriptEngine('./helpers/test-module',test_module,ansibleEngine,function(){
|
scp2_exec.copyFileToScriptEngine('./helpers/test-module',test_module,ansibleEngine,function(){
|
||||||
console.log("Command=" + command);
|
console.log("Command=" + command);
|
||||||
|
@ -174,8 +169,6 @@ export function testModule(req, res) {
|
||||||
// Creates a new CustomModule in the DB
|
// Creates a new CustomModule in the DB
|
||||||
export function create(req, res) {
|
export function create(req, res) {
|
||||||
|
|
||||||
console.log("Create");
|
|
||||||
|
|
||||||
var custom_module_name = req.params.custom_module;
|
var custom_module_name = req.params.custom_module;
|
||||||
var custom_module_code = req.body.custom_module_code;
|
var custom_module_code = req.body.custom_module_code;
|
||||||
|
|
||||||
|
|
|
@ -4,187 +4,168 @@
|
||||||
|
|
||||||
var app = require('../..');
|
var app = require('../..');
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
import User from '../user/user.model';
|
||||||
|
|
||||||
var newCustomModule;
|
var newCustomModule;
|
||||||
|
|
||||||
describe('CustomModule API:', function() {
|
describe('CustomModule API:', function() {
|
||||||
describe('GET /api/custom_modules', function() {
|
var token;
|
||||||
|
var user;
|
||||||
|
|
||||||
|
// Clear users before testing
|
||||||
|
before(function() {
|
||||||
|
return User.remove().then(function() {
|
||||||
|
user = new User({
|
||||||
|
name: 'Fake User',
|
||||||
|
email: 'test@example.com',
|
||||||
|
password: 'password'
|
||||||
|
});
|
||||||
|
|
||||||
|
return user.save();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear users after testing
|
||||||
|
after(function() {
|
||||||
|
return User.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GET /api/users/me', function() {
|
||||||
|
|
||||||
|
before(function(done) {
|
||||||
|
request(app)
|
||||||
|
.post('/auth/local')
|
||||||
|
.send({
|
||||||
|
email: 'test@example.com',
|
||||||
|
password: 'password'
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
token = res.body.token;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should respond with a user profile when authenticated', function(done) {
|
||||||
|
request(app)
|
||||||
|
.get('/api/users/me')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
|
.expect(200)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
expect(res.body._id.toString()).to.equal(user._id.toString());
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should respond with a 401 when not authenticated', function(done) {
|
||||||
|
request(app)
|
||||||
|
.get('/api/users/me')
|
||||||
|
.expect(401)
|
||||||
|
.end(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('POST /api/custom_modules/template.py/get', function() {
|
||||||
var customModules;
|
var customModules;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get('/api/custom_modules')
|
.post('/api/custom_modules/template.py/get')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.end((err, res) => {
|
|
||||||
if(err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
customModules = res.body;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with JSON array', function() {
|
|
||||||
expect(customModules).to.be.instanceOf(Array);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /api/custom_modules', function() {
|
|
||||||
beforeEach(function(done) {
|
|
||||||
request(app)
|
|
||||||
.post('/api/custom_modules')
|
|
||||||
.send({
|
.send({
|
||||||
name: 'New CustomModule',
|
ansibleEngine: {
|
||||||
info: 'This is the brand new customModule!!!'
|
host : '',
|
||||||
|
customModules: '/'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.expect(201)
|
//.expect('Content-Type', /json/)
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
newCustomModule = res.body;
|
customModules = res.text;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respond with the newly created customModule', function() {
|
it('should respond with module_template', function() {
|
||||||
expect(newCustomModule.name).to.equal('New CustomModule');
|
expect(customModules).to.contain('import AnsibleModule');
|
||||||
expect(newCustomModule.info).to.equal('This is the brand new customModule!!!');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /api/custom_modules/:id', function() {
|
|
||||||
var customModule;
|
describe('POST /api/custom_modules/test_module.py', function() {
|
||||||
|
var customModules;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get(`/api/custom_modules/${newCustomModule._id}`)
|
.post('/api/custom_modules/test_module.py')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.end((err, res) => {
|
|
||||||
if(err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
customModule = res.body;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
customModule = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with the requested customModule', function() {
|
|
||||||
expect(customModule.name).to.equal('New CustomModule');
|
|
||||||
expect(customModule.info).to.equal('This is the brand new customModule!!!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /api/custom_modules/:id', function() {
|
|
||||||
var updatedCustomModule;
|
|
||||||
|
|
||||||
beforeEach(function(done) {
|
|
||||||
request(app)
|
|
||||||
.put(`/api/custom_modules/${newCustomModule._id}`)
|
|
||||||
.send({
|
.send({
|
||||||
name: 'Updated CustomModule',
|
ansibleEngine: {
|
||||||
info: 'This is the updated customModule!!!'
|
host : '',
|
||||||
|
customModules: '/tmp'
|
||||||
|
},
|
||||||
|
custom_module_code: '#!/usr/bin/python\n' +
|
||||||
|
'\n' +
|
||||||
|
'import datetime\n' +
|
||||||
|
'import json\n' +
|
||||||
|
'\n' +
|
||||||
|
'date = str(datetime.datetime.now())\n' +
|
||||||
|
'print(json.dumps({\n' +
|
||||||
|
'"time" : date\n' +
|
||||||
|
'}))'
|
||||||
})
|
})
|
||||||
.expect(200)
|
//.expect('Content-Type', /json/)
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.end(function(err, res) {
|
|
||||||
if(err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
updatedCustomModule = res.body;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
|
||||||
updatedCustomModule = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with the updated customModule', function() {
|
|
||||||
expect(updatedCustomModule.name).to.equal('Updated CustomModule');
|
|
||||||
expect(updatedCustomModule.info).to.equal('This is the updated customModule!!!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with the updated customModule on a subsequent GET', function(done) {
|
|
||||||
request(app)
|
|
||||||
.get(`/api/custom_modules/${newCustomModule._id}`)
|
|
||||||
.expect(200)
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
let customModule = res.body;
|
customModules = res.text;
|
||||||
|
|
||||||
expect(customModule.name).to.equal('Updated CustomModule');
|
|
||||||
expect(customModule.info).to.equal('This is the updated customModule!!!');
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should respond with "Saved"', function() {
|
||||||
|
expect(customModules).to.contain('Saved');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PATCH /api/custom_modules/:id', function() {
|
describe('POST /api/custom_modules/test_module.py/test', function() {
|
||||||
var patchedCustomModule;
|
var result;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.patch(`/api/custom_modules/${newCustomModule._id}`)
|
.post('/api/custom_modules/test_module.py/test')
|
||||||
.send([
|
.set('authorization', `Bearer ${token}`)
|
||||||
{ op: 'replace', path: '/name', value: 'Patched CustomModule' },
|
|
||||||
{ op: 'replace', path: '/info', value: 'This is the patched customModule!!!' }
|
|
||||||
])
|
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.send({
|
||||||
.end(function(err, res) {
|
ansibleEngine: {
|
||||||
|
host : '',
|
||||||
|
customModules: '/tmp'
|
||||||
|
},
|
||||||
|
moduleArgs: {}
|
||||||
|
})
|
||||||
|
//.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
patchedCustomModule = res.body;
|
result = res;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
it('should respond with 200', function() {
|
||||||
patchedCustomModule = {};
|
expect(result.status).to.equal(200);
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with the patched customModule', function() {
|
|
||||||
expect(patchedCustomModule.name).to.equal('Patched CustomModule');
|
|
||||||
expect(patchedCustomModule.info).to.equal('This is the patched customModule!!!');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /api/custom_modules/:id', function() {
|
//TODO: Add more test cases
|
||||||
it('should respond with 204 on successful removal', function(done) {
|
|
||||||
request(app)
|
|
||||||
.delete(`/api/custom_modules/${newCustomModule._id}`)
|
|
||||||
.expect(204)
|
|
||||||
.end(err => {
|
|
||||||
if(err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should respond with 404 when customModule does not exist', function(done) {
|
|
||||||
request(app)
|
|
||||||
.delete(`/api/custom_modules/${newCustomModule._id}`)
|
|
||||||
.expect(404)
|
|
||||||
.end(err => {
|
|
||||||
if(err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@ var controller = require('./custom_module.controller');
|
||||||
|
|
||||||
var router = express.Router();
|
var router = express.Router();
|
||||||
|
|
||||||
router.post('/query', controller.index);
|
router.post('/list', controller.index);
|
||||||
router.post('/:custom_module/test', controller.testModule);
|
router.post('/:custom_module/test', controller.testModule);
|
||||||
router.post('/:custom_module/get', controller.show);
|
router.post('/:custom_module/get', controller.show);
|
||||||
router.post('/:custom_module', controller.create);
|
router.post('/:custom_module', controller.create);
|
||||||
|
|
|
@ -36,10 +36,10 @@ describe('CustomModule API Router:', function() {
|
||||||
expect(customModuleIndex).to.equal(routerStub);
|
expect(customModuleIndex).to.equal(routerStub);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /api/custom_modules/query', function() {
|
describe('GET /api/custom_modules/list', function() {
|
||||||
it('should route to customModule.controller.index', function() {
|
it('should route to customModule.controller.index', function() {
|
||||||
expect(routerStub.post
|
expect(routerStub.post
|
||||||
.withArgs('/query', 'customModuleCtrl.index')
|
.withArgs('/list', 'customModuleCtrl.index')
|
||||||
).to.have.been.calledOnce;
|
).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
import jsonpatch from 'fast-json-patch';
|
import jsonpatch from 'fast-json-patch';
|
||||||
import Project from './project.model';
|
import Project from './project.model';
|
||||||
import config from '../../config/environment';
|
import config from '../../config/environment';
|
||||||
|
const util = require('util');
|
||||||
var ansibleTool = require('../../components/ansible/ansible_tool');
|
var ansibleTool = require('../../components/ansible/ansible_tool');
|
||||||
|
|
||||||
function respondWithResult(res, statusCode) {
|
function respondWithResult(res, statusCode) {
|
||||||
|
@ -50,6 +51,7 @@ function removeEntity(res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEntityNotFound(res) {
|
function handleEntityNotFound(res) {
|
||||||
|
console.log("Entity Not Found");
|
||||||
return function(entity) {
|
return function(entity) {
|
||||||
if(!entity) {
|
if(!entity) {
|
||||||
res.status(404).end();
|
res.status(404).end();
|
||||||
|
@ -62,6 +64,7 @@ function handleEntityNotFound(res) {
|
||||||
function handleError(res, statusCode) {
|
function handleError(res, statusCode) {
|
||||||
statusCode = statusCode || 500;
|
statusCode = statusCode || 500;
|
||||||
return function(err) {
|
return function(err) {
|
||||||
|
console.log("ERror " + err);
|
||||||
res.status(statusCode).send(err);
|
res.status(statusCode).send(err);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -93,13 +96,18 @@ export function show(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Creates a new Project in the DB
|
/**
|
||||||
|
* Create New Project
|
||||||
|
* - If Ansible Engine information is provided use that, else consider localhost as Ansible Engine
|
||||||
|
* - Identify/generate project and library (custom modules location)
|
||||||
|
* - Get Ansible version and create projects folder
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
*/
|
||||||
export function create(req, res) {
|
export function create(req, res) {
|
||||||
|
|
||||||
var ansibleEngine = req.body.ansibleEngine;
|
var ansibleEngine = req.body.ansibleEngine;
|
||||||
|
|
||||||
console.log("Ansible Engine " + JSON.stringify(ansibleEngine));
|
|
||||||
|
|
||||||
req.body.owner_id = req.user._id;
|
req.body.owner_id = req.user._id;
|
||||||
req.body.owner_name = req.user.name;
|
req.body.owner_name = req.user.name;
|
||||||
|
|
||||||
|
@ -118,18 +126,22 @@ export function create(req, res) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If projectFolder is not passed, create a custom project folder
|
||||||
if(!ansibleEngine.projectFolder){
|
if(!ansibleEngine.projectFolder){
|
||||||
ansibleEngine.projectFolder = '/opt/ansible-projects/' + req.user._id + '_' + req.body.name;
|
let projectFolderName = util.format('%s_%s',req.user._id, req.body.name);
|
||||||
ansibleEngine.customModules = '/opt/ansible-projects/' + req.user._id + '_' + req.body.name + '/library';
|
|
||||||
|
ansibleEngine.projectFolder = util.format('/opt/ansible-projects/test_%s', projectFolderName);
|
||||||
|
ansibleEngine.customModules = util.format('/opt/ansible-projects/test_%s/library', projectFolderName);
|
||||||
|
|
||||||
// Update project request body to save in db
|
// Update project request body to save in db
|
||||||
req.body.ansibleEngine.projectFolder = ansibleEngine.projectFolder;
|
req.body.ansibleEngine.projectFolder = ansibleEngine.projectFolder;
|
||||||
req.body.ansibleEngine.customModules = ansibleEngine.customModules;
|
req.body.ansibleEngine.customModules = ansibleEngine.customModules;
|
||||||
|
req.body.ansibleEngine.projectFolderName = projectFolderName;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow creating project if no host is passed. Then use the default Ansible Engine for all operations.
|
||||||
|
// If Ansible host is passed get Ansible version and create project folder
|
||||||
if(ansibleEngine.ansibleHost){
|
if(ansibleEngine.ansibleHost){
|
||||||
ansibleTool.getAnsibleVersion(
|
ansibleTool.getAnsibleVersion(
|
||||||
function(version){
|
function(version){
|
||||||
|
@ -184,10 +196,16 @@ export function patch(req, res) {
|
||||||
.catch(handleError(res));
|
.catch(handleError(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Deletes a Project from the DB
|
// Deletes a Project from the DB
|
||||||
export function destroy(req, res) {
|
export function destroy(req, res) {
|
||||||
return Project.findById(req.params.id).exec()
|
return Project.findById(req.params.id).exec()
|
||||||
.then(handleEntityNotFound(res))
|
.then(handleEntityNotFound(res))
|
||||||
|
.then(function(entity){
|
||||||
|
if(!entity)return null;
|
||||||
|
return ansibleTool.deleteProjectFolder(entity);
|
||||||
|
})
|
||||||
.then(removeEntity(res))
|
.then(removeEntity(res))
|
||||||
.catch(handleError(res));
|
.catch(handleError(res));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,92 @@
|
||||||
|
|
||||||
var app = require('../..');
|
var app = require('../..');
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
import Project from './project.model';
|
||||||
|
import User from '../user/user.model';
|
||||||
|
|
||||||
var newProject;
|
var newProject;
|
||||||
|
|
||||||
describe('Project API:', function() {
|
describe('Project API:', function() {
|
||||||
|
var token;
|
||||||
|
var user;
|
||||||
|
|
||||||
|
// Clear users before testing
|
||||||
|
before(function() {
|
||||||
|
return User.remove().then(function() {
|
||||||
|
user = new User({
|
||||||
|
name: 'Fake User',
|
||||||
|
email: 'test@example.com',
|
||||||
|
password: 'password'
|
||||||
|
});
|
||||||
|
|
||||||
|
return user.save();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear users after testing
|
||||||
|
after(function() {
|
||||||
|
return User.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GET /api/users/me', function() {
|
||||||
|
|
||||||
|
before(function(done) {
|
||||||
|
request(app)
|
||||||
|
.post('/auth/local')
|
||||||
|
.send({
|
||||||
|
email: 'test@example.com',
|
||||||
|
password: 'password'
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
token = res.body.token;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should respond with a user profile when authenticated', function(done) {
|
||||||
|
request(app)
|
||||||
|
.get('/api/users/me')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
|
.expect(200)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.end((err, res) => {
|
||||||
|
expect(res.body._id.toString()).to.equal(user._id.toString());
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should respond with a 401 when not authenticated', function(done) {
|
||||||
|
request(app)
|
||||||
|
.get('/api/users/me')
|
||||||
|
.expect(401)
|
||||||
|
.end(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('GET /api/projects', function() {
|
describe('GET /api/projects', function() {
|
||||||
var projects;
|
var projects;
|
||||||
|
|
||||||
|
// Clear Projects before testing
|
||||||
|
before(function() {
|
||||||
|
return Project.remove().then(function() {
|
||||||
|
var project = new Project({
|
||||||
|
name: 'FakeProject',
|
||||||
|
info: 'Test Project',
|
||||||
|
ansibleEngine: {
|
||||||
|
'host' : ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return project.save();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get('/api/projects')
|
.get('/api/projects')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
|
@ -34,9 +110,13 @@ describe('Project API:', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.post('/api/projects')
|
.post('/api/projects')
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.send({
|
.send({
|
||||||
name: 'New Project',
|
name: 'NewProject',
|
||||||
info: 'This is the brand new project!!!'
|
info: 'This is the brand new project!!!',
|
||||||
|
ansibleEngine: {
|
||||||
|
'host' : ''
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.expect(201)
|
.expect(201)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
|
@ -50,7 +130,7 @@ describe('Project API:', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respond with the newly created project', function() {
|
it('should respond with the newly created project', function() {
|
||||||
expect(newProject.name).to.equal('New Project');
|
expect(newProject.name).to.equal('NewProject');
|
||||||
expect(newProject.info).to.equal('This is the brand new project!!!');
|
expect(newProject.info).to.equal('This is the brand new project!!!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -61,6 +141,7 @@ describe('Project API:', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get(`/api/projects/${newProject._id}`)
|
.get(`/api/projects/${newProject._id}`)
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
|
@ -77,7 +158,7 @@ describe('Project API:', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respond with the requested project', function() {
|
it('should respond with the requested project', function() {
|
||||||
expect(project.name).to.equal('New Project');
|
expect(project.name).to.equal('NewProject');
|
||||||
expect(project.info).to.equal('This is the brand new project!!!');
|
expect(project.info).to.equal('This is the brand new project!!!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -88,6 +169,7 @@ describe('Project API:', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.put(`/api/projects/${newProject._id}`)
|
.put(`/api/projects/${newProject._id}`)
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.send({
|
.send({
|
||||||
name: 'Updated Project',
|
name: 'Updated Project',
|
||||||
info: 'This is the updated project!!!'
|
info: 'This is the updated project!!!'
|
||||||
|
@ -115,6 +197,7 @@ describe('Project API:', function() {
|
||||||
it('should respond with the updated project on a subsequent GET', function(done) {
|
it('should respond with the updated project on a subsequent GET', function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.get(`/api/projects/${newProject._id}`)
|
.get(`/api/projects/${newProject._id}`)
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.end((err, res) => {
|
.end((err, res) => {
|
||||||
|
@ -137,6 +220,7 @@ describe('Project API:', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.patch(`/api/projects/${newProject._id}`)
|
.patch(`/api/projects/${newProject._id}`)
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.send([
|
.send([
|
||||||
{ op: 'replace', path: '/name', value: 'Patched Project' },
|
{ op: 'replace', path: '/name', value: 'Patched Project' },
|
||||||
{ op: 'replace', path: '/info', value: 'This is the patched project!!!' }
|
{ op: 'replace', path: '/info', value: 'This is the patched project!!!' }
|
||||||
|
@ -166,6 +250,7 @@ describe('Project API:', function() {
|
||||||
it('should respond with 204 on successful removal', function(done) {
|
it('should respond with 204 on successful removal', function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.delete(`/api/projects/${newProject._id}`)
|
.delete(`/api/projects/${newProject._id}`)
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.expect(204)
|
.expect(204)
|
||||||
.end(err => {
|
.end(err => {
|
||||||
if(err) {
|
if(err) {
|
||||||
|
@ -178,6 +263,7 @@ describe('Project API:', function() {
|
||||||
it('should respond with 404 when project does not exist', function(done) {
|
it('should respond with 404 when project does not exist', function(done) {
|
||||||
request(app)
|
request(app)
|
||||||
.delete(`/api/projects/${newProject._id}`)
|
.delete(`/api/projects/${newProject._id}`)
|
||||||
|
.set('authorization', `Bearer ${token}`)
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(err => {
|
.end(err => {
|
||||||
if(err) {
|
if(err) {
|
||||||
|
|
|
@ -104,8 +104,11 @@ export function changePassword(req, res) {
|
||||||
export function me(req, res, next) {
|
export function me(req, res, next) {
|
||||||
var userId = req.user._id;
|
var userId = req.user._id;
|
||||||
|
|
||||||
|
console.log("Find User =" + JSON.stringify(req.user));
|
||||||
|
|
||||||
return User.findOne({ _id: userId }, '-salt -password').exec()
|
return User.findOne({ _id: userId }, '-salt -password').exec()
|
||||||
.then(user => { // don't ever give out the password or salt
|
.then(user => { // don't ever give out the password or salt
|
||||||
|
console.log("User =" + JSON.stringify(user));
|
||||||
if(!user) {
|
if(!user) {
|
||||||
return res.status(401).end();
|
return res.status(401).end();
|
||||||
}
|
}
|
||||||
|
|
2
spec.js
2
spec.js
|
@ -8,5 +8,5 @@ require('angular-mocks');
|
||||||
require('./client/components/ui-router/ui-router.mock');
|
require('./client/components/ui-router/ui-router.mock');
|
||||||
|
|
||||||
|
|
||||||
testsContext = require.context('./client', true, /\.spec\.js$/);
|
testsContext = require.context('./client', true, /main.component.spec\.js$/);
|
||||||
testsContext.keys().forEach(testsContext);
|
testsContext.keys().forEach(testsContext);
|
||||||
|
|
Loading…
Reference in a new issue