Merge pull request #4 from keedya/add-sel-poller

Restructure the code using Promises
This commit is contained in:
Andre Keedy 2015-12-04 14:58:16 -05:00
commit 1767b1eb51
14 changed files with 719 additions and 697 deletions

View File

@ -300,7 +300,7 @@
"get": { "get": {
"x-swagger-router-controller": "Shovel", "x-swagger-router-controller": "Shovel",
"tags": [ "GET" ], "tags": [ "GET" ],
"operationId": "GetSELData", "operationId": "getSeldata",
"parameters": [ "parameters": [
{ {
"name": "identifier", "name": "identifier",
@ -649,8 +649,8 @@
"type": "object", "type": "object",
"required": [ "required": [
"uuid", "uuid",
"kernel", "kernel",
"ramdisk", "ramdisk",
"port" "port"
], ],
"properties": { "properties": {

View File

@ -20,8 +20,11 @@ var HttpClient = {
response.on('data', function(chunk) { response.on('data', function(chunk) {
body += chunk; body += chunk;
}); });
response.on('error', function (err) {
output(err);
});
response.on('end', function() { response.on('end', function() {
output(body); output(null, body);
}); });
}; };
@ -61,8 +64,11 @@ var HttpClient = {
response.on('data', function(chunk) { response.on('data', function(chunk) {
body += chunk; body += chunk;
}); });
response.on('error', function (err) {
output(err);
});
response.on('end', function() { response.on('end', function() {
output(body); output(null,body);
}); });
}; };
@ -103,8 +109,11 @@ var HttpClient = {
response.on('data', function(chunk) { response.on('data', function(chunk) {
body += chunk; body += chunk;
}); });
response.on('error', function (err) {
output(err);
});
response.on('end', function() { response.on('end', function() {
output(body); output(null,body);
}); });
}; };
@ -144,9 +153,12 @@ var HttpClient = {
response.on('data', function(chunk) { response.on('data', function(chunk) {
body += chunk; body += chunk;
}); });
response.on('end', function() { response.on('error', function (err) {
output(body); output(err);
}); });
response.on('end', function () {
output(null, body);
});
}; };
request = http.request(options, cb); request = http.request(options, cb);
@ -186,9 +198,12 @@ var HttpClient = {
response.on('data', function(chunk) { response.on('data', function(chunk) {
body += chunk; body += chunk;
}); });
response.on('end', function() { response.on('error', function (err) {
output(body); output(err);
}); });
response.on('end', function () {
output(null, body);
});
}; };
request = http.request(options, cb); request = http.request(options, cb);

View File

@ -4,8 +4,8 @@ var url = require('url');
var monorail = require('./../lib/api/monorail/monorail'); var monorail = require('./../lib/api/monorail/monorail');
var ironic = require('./../lib/api/openstack/ironic'); var ironic = require('./../lib/api/openstack/ironic');
var config = require('./../config.json'); var config = require('./../config.json');
var promise = require('bluebird')
var glance = require('./../lib/api/openstack/glance'); var glance = require('./../lib/api/openstack/glance');
var keystone = require('./../lib/api/openstack/keystone');
/* /*
* @api {get} /api/1.1/info / GET / * @api {get} /api/1.1/info / GET /
@ -29,15 +29,18 @@ module.exports.infoGet = function infoGet(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.driversGet = function driversGet(req, res, next) { module.exports.driversGet = function driversGet(req, res, next) {
ironic.get_client(function (client) { return keystone.authenticate('password').
client.get_driver_list(function (result) { then(function (token) {
if (typeof result !== 'undefined') { token = JSON.parse(token).access.token.id;
res.setHeader('Content-Type', 'application/json'); return ironic.get_driver_list(token);
res.end(result); }).
} then(function (result) {
else if (typeof result !== 'undefined') {
res.end(); res.setHeader('Content-Type', 'application/json');
}); res.end(result);
}
else
res.end();
}); });
}; };
@ -47,23 +50,19 @@ module.exports.driversGet = function driversGet(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.ironicnodesGet = function ironicnodesGet(req, res, next) { module.exports.ironicnodesGet = function ironicnodesGet(req, res, next) {
var ironic_client; return keystone.authenticate('password').
return new promise(function (resolve, reject) { then(function (token) {
ironic.get_client(function (client) { token = JSON.parse(token).access.token.id;
resolve(client); return ironic.get_node_list(token);
ironic_client = client; }).
}); then(function (result) {
}).then(function () { if (typeof result !== 'undefined') {
ironic_client.get_node_list(function (result) { res.setHeader('Content-Type', 'application/json');
if (typeof result !== 'undefined') { res.end(result);
res.setHeader('Content-Type', 'application/json'); }
res.end(result); else
} res.end();
else
res.end();
});
}); });
}; };
/* /*
@ -72,15 +71,18 @@ module.exports.ironicnodesGet = function ironicnodesGet(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.ironicchassisGet = function ironicchassisGet(req, res, next) { module.exports.ironicchassisGet = function ironicchassisGet(req, res, next) {
ironic.get_client(function (client) { return keystone.authenticate('password').
client.get_chassis_by_id(req.swagger.params.identifier.value, function (result) { then(function (token) {
if (typeof result !== 'undefined') { token = JSON.parse(token).access.token.id;
res.setHeader('Content-Type', 'application/json'); return ironic.get_chassis_by_id(token, req.swagger.params.identifier.value);
res.end(result); }).
} then(function (result) {
else if (typeof result !== 'undefined') {
res.end(); res.setHeader('Content-Type', 'application/json');
}); res.end(result);
}
else
res.end();
}); });
}; };
@ -90,15 +92,18 @@ module.exports.ironicchassisGet = function ironicchassisGet(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.ironicnodeGet = function ironicnodeGet(req, res, next) { module.exports.ironicnodeGet = function ironicnodeGet(req, res, next) {
ironic.get_client(function (client) { return keystone.authenticate('password').
client.get_node(req.swagger.params.identifier.value, function (result) { then(function (token) {
if (typeof result !== 'undefined') { token = JSON.parse(token).access.token.id;
res.setHeader('Content-Type', 'application/json'); return ironic.get_nodeAsync(token, req.swagger.params.identifier.value);
res.end(result); }).
} then(function (result) {
else if (typeof result !== 'undefined') {
res.end(); res.setHeader('Content-Type', 'application/json');
}); res.end(result);
}
else
res.end();
}); });
}; };
@ -108,27 +113,28 @@ module.exports.ironicnodeGet = function ironicnodeGet(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.ironicnodePatch = function ironicnodePatch(req, res, next) { module.exports.ironicnodePatch = function ironicnodePatch(req, res, next) {
ironic.get_client(function (client) { return keystone.authenticate('password').
then(function (token) {
token = JSON.parse(token).access.token.id;
var data = JSON.stringify(req.body); var data = JSON.stringify(req.body);
client.patch_node(req.swagger.params.identifier.value, data, function (result) { return ironic.patch_node(token, req.swagger.params.identifier.value, data);
console.info('\r\patched node:\r\n' + result); }).
if (result) { then(function (result) {
res.setHeader('Content-Type', 'application/json'); if (result) {
res.end(result); res.setHeader('Content-Type', 'application/json');
return; res.end(result);
} }
});
}); });
}; };
/* /*
* @api {get} /api/1.1/catalogs/identifier / GET / * @api {get} /api/1.1/catalogs/identifier / GET /
* @apiDescription get catalogs * @apiDescription get catalogs
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.catalogsGet = function catalogsGet(req, res, next) { module.exports.catalogsGet = function catalogsGet(req, res, next) {
monorail.request_catalogs_get(req.swagger.params.identifier.value, function (catalogs) { return monorail.request_catalogs_get(req.swagger.params.identifier.value).
then(function (catalogs) {
if (typeof catalogs !== 'undefined') { if (typeof catalogs !== 'undefined') {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(catalogs); res.end(catalogs);
@ -144,7 +150,8 @@ module.exports.catalogsGet = function catalogsGet(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.catalogsbysourceGet = function catalogsbysourceGet(req, res, next) { module.exports.catalogsbysourceGet = function catalogsbysourceGet(req, res, next) {
monorail.get_catalog_data_by_source(req.swagger.params.identifier.value, req.swagger.params.source.value, function (catalogs) { return monorail.get_catalog_data_by_source(req.swagger.params.identifier.value, req.swagger.params.source.value).
then(function (catalogs) {
if (typeof catalogs !== 'undefined') { if (typeof catalogs !== 'undefined') {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(catalogs); res.end(catalogs);
@ -160,7 +167,8 @@ module.exports.catalogsbysourceGet = function catalogsbysourceGet(req, res, next
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.nodeGet = function nodeGet(req, res, next) { module.exports.nodeGet = function nodeGet(req, res, next) {
monorail.request_node_get(req.swagger.params.identifier.value, function (node) { return monorail.request_node_get(req.swagger.params.identifier.value).
then(function (node) {
if (typeof node !== 'undefined') { if (typeof node !== 'undefined') {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(node); res.end(node);
@ -176,7 +184,8 @@ module.exports.nodeGet = function nodeGet(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.nodesGet = function nodesGet(req, res, next) { module.exports.nodesGet = function nodesGet(req, res, next) {
monorail.request_nodes_get(function (nodes) { return monorail.request_nodes_get().
then(function (nodes) {
if (typeof nodes !== 'undefined') { if (typeof nodes !== 'undefined') {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(nodes); res.end(nodes);
@ -186,19 +195,20 @@ module.exports.nodesGet = function nodesGet(req, res, next) {
}); });
}; };
/* /*
* @api {get} /api/1.1/nodes/identifier/sel / GET / * @api {get} /api/1.1/nodes/identifier/sel / GET /
* @apiDescription get specific node by id * @apiDescription get specific node by id
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.GetSELData = function nodeGet(req, res, next) { module.exports.getSeldata = function getSeldata(req, res, next) {
monorail.request_poller_get(req.swagger.params.identifier.value, function (pollers) { return monorail.request_poller_get(req.swagger.params.identifier.value).
then(function (pollers) {
if (typeof pollers !== 'undefined') { if (typeof pollers !== 'undefined') {
pollers = JSON.parse(pollers); pollers = JSON.parse(pollers);
for( var i in pollers ) { for (var i in pollers) {
if( pollers[i]['config']['command'] === 'sel' ) { if (pollers[i]['config']['command'] === 'sel') {
monorail.request_poller_data_get(pollers[i]['id'], function (data) { return monorail.request_poller_data_get(pollers[i]['id']).
then(function (data) {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(data); res.end(data);
}); });
@ -220,10 +230,10 @@ module.exports.registerpost = function registerpost(req, res, next) {
var info = {}; var info = {};
var node = {}; var node = {};
var propreties = {}; var propreties = {};
var local_gb = {}; var local_gb;
var extra = {}; var extra = {};
var port = {} var port = {}
var ironic_client; var ironicToken;
var ironic_node; var ironic_node;
var onrack_node; var onrack_node;
var user_entry = req.body; var user_entry = req.body;
@ -236,29 +246,27 @@ module.exports.registerpost = function registerpost(req, res, next) {
else { else {
info = {}; info = {};
} }
/* Fill in the extra meta data with some failover and event data */ /* Fill in the extra meta data with some failover and event data */
extra = { 'nodeid': user_entry.uuid, 'name': user_entry.name, 'events':{'time':'0'}, 'eventcnt': '0' }; extra = { 'nodeid': user_entry.uuid, 'name': user_entry.name, 'lsevents': { 'time': 0 }, 'eventcnt': 0, 'timer': {} };
if ( typeof user_entry.failovernode !== 'undefined' ) { if (typeof user_entry.failovernode !== 'undefined') {
extra['failover'] = user_entry.failovernode; extra['failover'] = user_entry.failovernode;
} }
if ( typeof user_entry.eventre !== 'undefined' ) { if (typeof user_entry.eventre !== 'undefined') {
extra['eventre'] = user_entry.eventre; extra['eventre'] = user_entry.eventre;
} }
local_gb = 0.0; local_gb = 0.0;
return new promise(function (resolve, reject) { return monorail.request_node_get(user_entry.uuid).
monorail.request_node_get(user_entry.uuid, function (result) { then(function (result) {
if (!JSON.parse(result).name) { if (!JSON.parse(result).name) {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(result); res.end(result);
return; }
} onrack_node = JSON.parse(result);
resolve(onrack_node);
onrack_node = JSON.parse(result);
});
}).then(function () { }).then(function () {
monorail.get_catalog_data_by_source(user_entry.uuid, 'lsscsi', function (scsi) { return monorail.get_catalog_data_by_source(user_entry.uuid, 'lsscsi').
then(function (scsi) {
scsi = JSON.parse(scsi); scsi = JSON.parse(scsi);
if (scsi.data) { if (scsi.data) {
for (var elem in scsi.data) { for (var elem in scsi.data) {
@ -269,10 +277,9 @@ module.exports.registerpost = function registerpost(req, res, next) {
} }
} }
}); });
return;
}).then(function () { }).then(function () {
monorail.get_catalog_data_by_source(user_entry.uuid, 'dmi', function (dmi) { monorail.get_catalog_data_by_source(user_entry.uuid, 'dmi').
then(function (dmi) {
dmi = JSON.parse(dmi); dmi = JSON.parse(dmi);
if (dmi.data) { if (dmi.data) {
var dmi_total = 0; var dmi_total = 0;
@ -280,13 +287,12 @@ module.exports.registerpost = function registerpost(req, res, next) {
var memory_device = dmi.data['Memory Device']; var memory_device = dmi.data['Memory Device'];
for (var elem in memory_device) { for (var elem in memory_device) {
var item = memory_device[elem]; var item = memory_device[elem];
//console.info(item['Size']); //console.log(item['Size']);
if (item['Size'].indexOf('GB') > -1) { if (item['Size'].indexOf('GB') > -1) {
dmi_total += parseFloat(item['Size'].replace('GB', '').trim()) * 1000; dmi_total += parseFloat(item['Size'].replace('GB', '').trim()) * 1000;
} }
if (item['Size'].indexOf('MB') > -1) { if (item['Size'].indexOf('MB') > -1) {
dmi_total += parseFloat(item['Size'].replace('MB', '').trim()); dmi_total += parseFloat(item['Size'].replace('MB', '').trim());
} }
} }
} }
@ -296,61 +302,64 @@ module.exports.registerpost = function registerpost(req, res, next) {
'local_gb': local_gb 'local_gb': local_gb
}; };
} }
node = {
node = { 'name': user_entry.uuid,
'name': user_entry.uuid, 'driver': user_entry.driver,
'driver': user_entry.driver, 'driver_info': info,
'driver_info': info, 'properties': propreties,
'properties': propreties, 'extra': extra
'extra': extra
}; };
}); });
return;
}).then(function () { }).then(function () {
return new promise(function (resolve, reject) { return (keystone.authenticate('password'));
ironic.get_client(function (client) { }).
resolve(client); then(function (token) {
ironic_client = client; ironicToken = JSON.parse(token).access.token.id;
}); return ironic.create_node(ironicToken, JSON.stringify(node));
}); }).
}).then(function () { then(function (ret) {
return new promise(function (resolve, reject) { console.log('\r\ncreate node:\r\n' + ret);
ironic_client.create_node(JSON.stringify(node), function (ret) { if (ret && JSON.parse(ret).error_message) {
console.info('\r\ncreate node:\r\n' + ret);
if (ret && JSON.parse(ret).error_message) {
res.setHeader('Content-Type', 'application/json');
res.end(ret);
return;
}
resolve(ret);
ironic_node = JSON.parse(ret);
});
});
}).then(function () {
port = { 'address': user_entry.port, 'node_uuid': ironic_node.uuid };
console.info('\r\nCreate port:\r\n' + JSON.stringify(port));
ironic_client.create_port(JSON.stringify(port), function (create_port) {
});
}).then(function () {
return new promise(function (resolve, reject) {
ironic_client.set_power_state(ironic_node.uuid, "on", function (pwr_state) {
console.info('\r\npwr_state: on');
if (pwr_state && JSON.parse(pwr_state).error_message) {
console.error(JSON.parse(pwr_state).error_message);
res.setHeader('Content-Type', 'application/json');
res.end(pwr_state);
return;
}
resolve(pwr_state);
});
});
}).then(function () {
monorail.request_whitelist_set(user_entry.port, function (whitelist) {
console.info('\r\nmonorail whitelist:\r\n' + JSON.stringify(whitelist));
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(whitelist); res.end(ret);
return; }
}); ironic_node = JSON.parse(ret);
port = { 'address': user_entry.port, 'node_uuid': ironic_node.uuid };
return ironic.create_port(ironicToken, JSON.stringify(port));
}).
then(function (create_port) {
console.log('\r\nCreate port:\r\n' + JSON.stringify(create_port));
return ironic.set_power_state(ironicToken, ironic_node.uuid, "on");
}).
then(function (pwr_state) {
console.log('\r\npwr_state: on');
if (pwr_state && JSON.parse(pwr_state).error_message) {
console.error(JSON.parse(pwr_state).error_message);
res.setHeader('Content-Type', 'application/json');
res.end(pwr_state);
}
}).then(function () {
var timer = {};
timer.start = new Date().toJSON();
timer.finish = new Date().toJSON();
timer.stop = false;
timer.timeInterval = 15000;
timer.isDone = true;
var data = [{ 'path': '/extra/timer', 'value': timer, 'op': 'replace' }];
return ironic.patch_node(ironicToken, ironic_node.uuid, JSON.stringify(data));
}).
then(function (result) {
console.log('\r\patched node:\r\n' + result);
}).then(function () {
return monorail.request_whitelist_set(user_entry.port)
}).
then(function (whitelist) {
console.log('\r\nmonorail whitelist:\r\n' + JSON.stringify(whitelist));
res.setHeader('Content-Type', 'application/json');
res.end(whitelist);
}).
catch(function(err){
res.end(err);
}); });
}; };
/* /*
@ -359,31 +368,40 @@ module.exports.registerpost = function registerpost(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.unregisterdel = function unregisterdel(req, res, next) { module.exports.unregisterdel = function unregisterdel(req, res, next) {
ironic.get_client(function (client) { return keystone.authenticate('password').
client.delete_node(req.swagger.params.identifier.value, function (del_node) { then(function (token) {
if (del_node && JSON.parse(del_node).error_message) { token = JSON.parse(token).access.token.id;;
console.info(del_node); return ironic.delete_node(token, req.swagger.params.identifier.value);
res.setHeader('Content-Type', 'application/json'); }).
res.end(del_node); then(function (del_node) {
return; if (del_node && JSON.parse(del_node).error_message) {
} console.log(del_node);
monorail.request_node_get(req.swagger.params.identifier.value, function (onrack_node) { res.setHeader('Content-Type', 'application/json');
if (onrack_node && !JSON.parse(onrack_node).name) { res.end(del_node);
console.info(onrack_node); return;
res.setHeader('Content-Type', 'application/json'); }
res.end(onrack_node); return monorail.request_node_get(req.swagger.params.identifier.value);
return; }).
} then(function (onrack_node) {
monorail.request_whitelist_del(JSON.parse(onrack_node).name, function (whitelist) { if (onrack_node && !JSON.parse(onrack_node).name) {
res.setHeader('Content-Type', 'application/json'); console.log(onrack_node);
var success = { res.setHeader('Content-Type', 'application/json');
result: 'success' res.end(onrack_node);
}; return;
res.end(JSON.stringify(success)); }
}); return monorail.request_whitelist_del(JSON.parse(onrack_node).name);
}); }).
}); then(function (whitelist) {
res.setHeader('Content-Type', 'application/json');
var success = {
result: 'success'
};
res.end(JSON.stringify(success));
}).
catch(function(err){
res.end(err);
}); });
}; };
/* /*
@ -392,32 +410,7 @@ module.exports.unregisterdel = function unregisterdel(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.configsetmono = function configsetmono(req, res, next) { module.exports.configsetmono = function configsetmono(req, res, next) {
var fs = require('fs'); var content = setConfig('monorail',req.body);
var path = require('path');
var is_changed = false;
var appDir = path.dirname(require.main.filename);
var file_content = fs.readFileSync(appDir + '/config.json');
var output = JSON.parse(file_content);
var content = output.monorail;
var entry = req.body;
//console.info(entry);
for (var initem in Object.keys(entry)) {
//console.info(Object.keys(entry)[initem]);
for (var orgitem in Object.keys(content)) {
//console.info(Object.keys(content)[orgitem]);
if (Object.keys(entry)[initem] == Object.keys(content)[orgitem]) {
var key = Object.keys(content)[orgitem];
//console.info(content[Object.keys(content)[orgitem]]);
content[key] = entry[key];
is_changed = true;
}
}
}
//console.info(content);
if (is_changed) {
output.monorail = content;
fs.writeFileSync(appDir + '/config.json', JSON.stringify(output));
}
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(content)); res.end(JSON.stringify(content));
}; };
@ -428,34 +421,9 @@ module.exports.configsetmono = function configsetmono(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.configsetkeystone = function configsetkeystone(req, res, next) { module.exports.configsetkeystone = function configsetkeystone(req, res, next) {
var fs = require('fs'); var content = setConfig('keystone',req.body);
var path = require('path');
var is_changed = false;
var appDir = path.dirname(require.main.filename);
var file_content = fs.readFileSync(appDir + '/config.json');
var output = JSON.parse(file_content);
var content = output.keystone;
var entry = req.body;
//console.info(entry);
for (var initem in Object.keys(entry)) {
//console.info(Object.keys(entry)[initem]);
for (var orgitem in Object.keys(content)) {
//console.info(Object.keys(content)[orgitem]);
if (Object.keys(entry)[initem] == Object.keys(content)[orgitem]) {
var key = Object.keys(content)[orgitem];
//console.info(content[Object.keys(content)[orgitem]]);
content[key] = entry[key];
is_changed = true;
}
}
}
//console.info(content);
if (is_changed) {
output.keystone = content;
fs.writeFileSync(appDir + '/config.json', JSON.stringify(output));
}
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(content)); res.end(JSON.stringify(content));
}; };
/* /*
@ -463,33 +431,8 @@ module.exports.configsetkeystone = function configsetkeystone(req, res, next) {
* @apiDescription modify shovel config.json file and restart the server * @apiDescription modify shovel config.json file and restart the server
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.configsetironic = function configsetironic(req, res, next) { module.exports.configsetironic = function configsetironic(req, res, next) {
var fs = require('fs'); var content = setConfig('ironic',req.body);
var path = require('path');
var is_changed = false;
var appDir = path.dirname(require.main.filename);
var file_content = fs.readFileSync(appDir + '/config.json');
var output = JSON.parse(file_content);
var content = output.ironic;
var entry = req.body;
//console.info(entry);
for (var initem in Object.keys(entry)) {
//console.info(Object.keys(entry)[initem]);
for (var orgitem in Object.keys(content)) {
//console.info(Object.keys(content)[orgitem]);
if (Object.keys(entry)[initem] == Object.keys(content)[orgitem]) {
var key = Object.keys(content)[orgitem];
//console.info(content[Object.keys(content)[orgitem]]);
content[key] = entry[key];
is_changed = true;
}
}
}
//console.info(content);
if (is_changed) {
output.ironic = content;
fs.writeFileSync(appDir + '/config.json', JSON.stringify(output));
}
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(content)); res.end(JSON.stringify(content));
}; };
@ -499,35 +442,10 @@ module.exports.configsetironic = function configsetironic(req, res, next) {
* @apiDescription modify shovel config.json file and restart the server * @apiDescription modify shovel config.json file and restart the server
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.configsetglance = function configsetglance(req, res, next) { module.exports.configsetglance = function configsetglance(req, res, next) {
var fs = require('fs'); var content = setConfig('glance',req.body);
var path = require('path');
var is_changed = false;
var appDir = path.dirname(require.main.filename);
var file_content = fs.readFileSync(appDir + '/config.json');
var output = JSON.parse(file_content);
var content = output.glance;
var entry = req.body;
//console.info(entry);
for (var initem in Object.keys(entry)) {
//console.info(Object.keys(entry)[initem]);
for (var orgitem in Object.keys(content)) {
//console.info(Object.keys(content)[orgitem]);
if (Object.keys(entry)[initem] == Object.keys(content)[orgitem]) {
var key = Object.keys(content)[orgitem];
//console.info(content[Object.keys(content)[orgitem]]);
content[key] = entry[key];
is_changed = true;
}
}
}
//console.info(content);
if (is_changed) {
output.glance = content;
fs.writeFileSync(appDir + '/config.json', JSON.stringify(output));
}
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(content)); res.end(JSON.stringify(content));
}; };
/* /*
@ -536,33 +454,40 @@ module.exports.configsetglance = function configsetglance(req, res, next) {
* @apiVersion 1.1.0 * @apiVersion 1.1.0
*/ */
module.exports.configset = function configset(req, res, next) { module.exports.configset = function configset(req, res, next) {
var content = setConfig(null,req.body);
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(content));
};
function setConfig(keyValue,entry){
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var is_changed = false; var is_changed = false;
var appDir = path.dirname(require.main.filename); var appDir = path.dirname(require.main.filename);
var file_content = fs.readFileSync(appDir + '/config.json'); var file_content = fs.readFileSync(appDir + '/config.json');
var content = JSON.parse(file_content); var output = JSON.parse(file_content);
var entry = req.body; var content = (keyValue == null)? output: output[keyValue];
//console.info(entry); console.log(content);
for (var initem in Object.keys(entry)) { for (var initem in Object.keys(entry)) {
//console.info(Object.keys(entry)[initem]);
for (var orgitem in Object.keys(content)) { for (var orgitem in Object.keys(content)) {
//console.info(Object.keys(content)[orgitem]);
if (Object.keys(entry)[initem] == Object.keys(content)[orgitem]) { if (Object.keys(entry)[initem] == Object.keys(content)[orgitem]) {
var key = Object.keys(content)[orgitem]; var key = Object.keys(content)[orgitem];
//console.info(content[Object.keys(content)[orgitem]]);
content[key] = entry[key]; content[key] = entry[key];
is_changed = true; is_changed = true;
} }
} }
} }
//console.info(content);
if (is_changed) { if (is_changed) {
fs.writeFileSync(appDir + '/config.json', JSON.stringify(content)); if(keyValue != null){
output[keyValue] = content;
}
else{
output = content;
}
fs.writeFileSync(appDir + '/config.json', JSON.stringify(output));
} }
res.setHeader('Content-Type', 'application/json'); return content
res.end(JSON.stringify(content)); }
};
/* /*
* @api config.json: get * @api config.json: get
@ -579,19 +504,22 @@ module.exports.configget = function configget(req, res, next) {
res.end(JSON.stringify(content)); res.end(JSON.stringify(content));
}; };
/* /*
* @api {get} /api/1.1/glance/images / GET / * @api {get} /api/1.1/glance/images / GET /
* @apiDescription get glance images * @apiDescription get glance images
*/ */
module.exports.imagesGet = function imagesGet(req, res, next) { module.exports.imagesGet = function imagesGet(req, res, next) {
glance.get_client(function (client) { return keystone.authenticate('password').
client.get_images(function (result) { then(function (token) {
if (typeof result !== 'undefined') { token = JSON.parse(token).access.token.id;
res.setHeader('Content-Type', 'application/json'); return glance.get_images(token);
res.end(result); }).
} then(function (result) {
else if (typeof result !== 'undefined') {
res.end(); res.setHeader('Content-Type', 'application/json');
}); res.end(result);
}); }
else
res.end();
});
}; };

View File

@ -1,9 +1,11 @@
/* global process */
'use strict'; 'use strict';
var app = require('connect')(); var app = require('connect')();
var http = require('http'); var http = require('http');
var swaggerTools = require('swagger-tools'); var swaggerTools = require('swagger-tools');
var config = require('./config.json'); var config = require('./config.json');
var Poller = require('./lib/services/poller');
var serverPort = config.httpPort; var serverPort = config.httpPort;
// swaggerRouter configuration // swaggerRouter configuration
@ -31,8 +33,10 @@ swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
app.use(middleware.swaggerUi()); app.use(middleware.swaggerUi());
// Start the server // Start the server
http.createServer(app).listen(config.httpPort, config.hostname, function () { http.createServer(app).listen(config.httpPort, config.hostname, function () {
console.log('Your server is listening on port %d ', config.httpPort); console.log('Your server is listening on port %d ', config.httpPort);
console.log('Swagger-ui is available on http://%s:%d/docs', config.hostname,config.httpPort); console.log('Swagger-ui is available on http://%s:%d/docs', config.hostname, config.httpPort);
var pollerInstance = new Poller(5000);//timeInterval to 5s
pollerInstance.startServer();
}); });
}); });

View File

@ -1,66 +1,53 @@
var config = require('./../../../config.json'); var config = require('./../../../config.json');
var client = require('./../../../client'); var client = require('./../../../client');
var Promise = require('bluebird');
Promise.promisifyAll(client);
var pfx = '/api/' + config.monorail.version; var pfx = '/api/' + config.monorail.version;
var request = { var request = {
host: config.monorail.httpHost, host: config.monorail.httpHost,
port: config.monorail.httpPort, port: config.monorail.httpPort,
path: pfx, path: pfx,
token: '', token: '',
data: '', data: '',
api:'' api: ''
}; };
/* /*
* Monorail wrapper functions * Monorail wrapper functions
*/ */
var MonorailWrapper = { var MonorailWrapper = {
request_nodes_get: function( ret ) { request_nodes_get: function (ret) {
request.path = pfx + '/nodes'; request.path = pfx + '/nodes';
client.Get(request, function(body) { return client.GetAsync(request);
ret(body);
});
}, },
request_node_get: function( identifier, ret ) { request_node_get: function (identifier, ret) {
request.path = pfx + '/nodes/' + identifier; request.path = pfx + '/nodes/' + identifier;
client.Get(request, function(body) { return client.GetAsync(request);
ret(body);
});
}, },
request_whitelist_set: function (hwaddr,ret) { request_whitelist_set: function (hwaddr, ret) {
request.path = pfx + '/nodes/' + hwaddr + '/dhcp/whitelist'; request.path = pfx + '/nodes/' + hwaddr + '/dhcp/whitelist';
client.Post(request,function(body){ return client.PostAsync(request);
ret (body);
});
}, },
request_whitelist_del: function (hwaddr, ret) { request_whitelist_del: function (hwaddr, ret) {
request.path = pfx + '/nodes/' + hwaddr + '/dhcp/whitelist'; request.path = pfx + '/nodes/' + hwaddr + '/dhcp/whitelist';
client.Delete(request, function (body) { return client.DeleteAsync(request);
ret(body);
});
}, },
request_catalogs_get: function (hwaddr,ret) { request_catalogs_get: function (hwaddr, ret) {
request.path = pfx + '/nodes/' + hwaddr + '/catalogs'; request.path = pfx + '/nodes/' + hwaddr + '/catalogs';
client.Get(request, function (body) { return client.GetAsync(request);
ret(body);
});
}, },
get_catalog_data_by_source: function (hwaddr, source, ret) { get_catalog_data_by_source: function (hwaddr, source, ret) {
request.path = pfx + '/nodes/' + hwaddr + '/catalogs/' + source; request.path = pfx + '/nodes/' + hwaddr + '/catalogs/' + source;
client.Get(request, function (body) { return client.GetAsync(request);
ret(body);
});
}, },
request_poller_get: function( identifier, ret ) { request_poller_get: function (identifier, ret) {
request.path = pfx + '/nodes/' + identifier + '/pollers'; request.path = pfx + '/nodes/' + identifier + '/pollers';
client.Get(request, function(body) { return client.GetAsync(request);
ret(body);
});
}, },
request_poller_data_get: function( identifier, ret ) { request_poller_data_get: function (identifier, ret) {
request.path = pfx + '/pollers/' + identifier + '/data/current'; request.path = pfx + '/pollers/' + identifier + '/data/current';
client.Get(request, function(body) { return client.GetAsync(request);
ret(body);
});
} }
}; };
module.exports = Object.create(MonorailWrapper); module.exports = Object.create(MonorailWrapper);

View File

@ -1,38 +0,0 @@
'use strict';
function ironicRouter ( router ) {
/**
* @api {get} /api/1.1/catalogs/ GET /
* @apiDescription get list of catalogs
* @apiVersion 1.1.0
* @apiDescription get list of catalogs or an empty list if no catalogs exist.
* @apiName catalogs-get
* @apiGroup catalogs
*/
router.get('/catalogs', rest(function (req) {
return waterline.catalogs.find(req.query);
}));
/**
* @api {get} /api/1.1/catalogs/:identifier GET /:id
* @apiVersion 1.1.0
* @apiDescription get specific catalog details
* @apiName catalog-get
* @apiGroup catalogs
* @apiParam {String} identifier of catalog, must cast to ObjectId
* @apiError NotFound The catalog with the <code>id</code> was not found.
* @apiErrorExample {json} Error-Response:
* HTTP/1.1 404 Not Found
* {
* "error": "Not Found"
* }
*/
router.get('/catalogs/:identifier', rest(function (req) {
return waterline.catalogs.needByIdentifier(req.params.identifier);
}));
return router;
}

View File

@ -1,37 +1,25 @@
var config = require('./../../../config.json'); var config = require('./../../../config.json');
var client = require('./../../../client'); var client = require('./../../../client');
var keystone = require('./keystone'); var Promise = require('bluebird');
var pfx = config.glance.version; Promise.promisifyAll(client);
var request = {
host: config.glance.httpHost, var pfx = config.glance.version;
port: config.glance.httpPort, var request = {
path: pfx, host: config.glance.httpHost,
token: '', port: config.glance.httpPort,
data: '' path: pfx,
}; token: '',
data: ''
/* };
* glance client object
*/ /*
var glanceClient = { * glance wrapper functions
get_client: function (ret) { */
keystone.authenticate('password', function (token) { var glanceWrapper = {
request.token = token; get_images: function (token) {
ret(glanceWrapper); request.token = token;
}); request.path = pfx + '/images';
} return client.GetAsync(request);
}; }
module.exports = Object.create(glanceClient); };
module.exports = Object.create(glanceWrapper);
/*
* glance wrapper functions
*/
var glanceWrapper = {
get_images: function (ret) {
request.path = pfx + '/images';
client.Get(request, function (images) {
ret(images);
});
}
};

View File

@ -1,6 +1,7 @@
var config = require('./../../../config.json'); var config = require('./../../../config.json');
var client = require('./../../../client'); var client = require('./../../../client');
var keystone = require('./keystone'); var Promise = require('bluebird');
Promise.promisifyAll(client);
var pfx = config.ironic.version; var pfx = config.ironic.version;
var request = { var request = {
host: config.ironic.httpHost, host: config.ironic.httpHost,
@ -11,108 +12,83 @@ var request = {
api: { 'name': 'X-OpenStack-Ironic-API-Version', 'version': '1.6' } /* TODO: set version from ironic */ api: { 'name': 'X-OpenStack-Ironic-API-Version', 'version': '1.6' } /* TODO: set version from ironic */
}; };
/*
* Ironic client object
*/
var ironicClient = {
get_client: function (ret) {
keystone.authenticate('password', function (token) {
request.token = token;
ret(ironicWrapper);
});
}
};
module.exports = Object.create(ironicClient);
/* /*
* Ironic wrapper functions * Ironic wrapper functions
*/ */
var ironicWrapper = { var ironicWrapper = {
get_chassis: function (ret) { get_chassis: function (token, ret) {
request.token = token;
request.path = pfx + '/chassis'; request.path = pfx + '/chassis';
client.Get(request, function (chassis) { return client.GetAsync(request);
ret(chassis);
});
}, },
get_chassis_by_id: function (identifier, ret) { get_chassis_by_id: function (token, identifier, ret) {
request.token = token;
request.path = pfx + '/chassis/' + identifier; request.path = pfx + '/chassis/' + identifier;
client.Get(request, function (chassis) { return client.GetAsync(request);
ret(chassis);
});
}, },
get_node_list: function (ret) { get_node_list: function (token) {
request.token = token;
request.path = pfx + '/nodes/detail'; request.path = pfx + '/nodes/detail';
client.Get(request, function (node) { return client.GetAsync(request);
ret(node);
});
}, },
get_node: function (identifier, ret) { get_node: function (token, identifier, ret) {
request.token = token;
request.path = pfx + '/nodes/' + identifier; request.path = pfx + '/nodes/' + identifier;
client.Get(request, function (node) { return client.GetAsync(request);
ret(node);
});
}, },
create_node: function (node, ret) { create_node: function (token, node, ret) {
request.token = token;
request.path = pfx + '/nodes'; request.path = pfx + '/nodes';
request.data = node; request.data = node;
client.Post(request, function (body) { return client.PostAsync(request);
ret(body);
});
}, },
patch_node: function (identifier, data, ret) { patch_node: function (token, identifier, data, ret) {
request.token = token;
request.path = pfx + '/nodes/' + identifier; request.path = pfx + '/nodes/' + identifier;
request.data = data; request.data = data;
client.Patch(request, function (body) { return client.PatchAsync(request);
ret(body);
});
}, },
delete_node: function (identifier, ret) { delete_node: function (token, identifier, ret) {
request.token = token;
request.path = pfx + '/nodes/' + identifier; request.path = pfx + '/nodes/' + identifier;
client.Delete(request, function (body) { return client.DeleteAsync(request);
ret(body);
});
}, },
get_port_list: function (ret) { get_port_list: function (token, ret) {
request.token = token;
request.path = pfx + '/ports'; request.path = pfx + '/ports';
client.Get(request, function (ports) { return client.GetAsync(request);
ret(ports);
});
}, },
get_port: function (identifier, ret) { get_port: function (token, identifier, ret) {
request.token = token;
request.path = pfx + '/ports/' + identifier; request.path = pfx + '/ports/' + identifier;
client.Get(request, function (port) { return client.GetAsync(request);;
ret(port);
});
}, },
create_port: function (port, ret) { create_port: function (token, port, ret) {
request.token = token;
request.path = pfx + '/ports'; request.path = pfx + '/ports';
request.data = port; request.data = port;
client.Post(request, function (body) { return client.PostAsync(request);
ret(body);
});
}, },
set_power_state: function (identifier, state, ret) { set_power_state: function (token, identifier, state, ret) {
request.token = token;
request.path = pfx + '/nodes/' + identifier + '/states/power'; request.path = pfx + '/nodes/' + identifier + '/states/power';
if (state === 'off' || state === 'on') { if (state === 'off' || state === 'on') {
request.data = { target: 'power ' + state } request.data = JSON.stringify({ target: 'power ' + state });
} }
if (state === 'reboot') { if (state === 'reboot') {
request.data = { target: 'rebooting' }; request.data = JSON.stringify({ target: 'rebooting' });
} }
request.data = JSON.stringify(request.data); return client.PutAsync(request);
client.Put(request, function (node) {
ret(node);
});
}, },
get_driver_list: function (ret) { get_driver_list: function (token, ret) {
request.token = token;
request.path = pfx + '/drivers'; request.path = pfx + '/drivers';
client.Get(request, function (node) { return client.GetAsync(request);
ret(node);
});
} }
}; };
module.exports = Object.create(ironicWrapper);

View File

@ -1,11 +1,13 @@
/* keystone authentication */ /* keystone authentication */
var config = require('./../../../config.json'); var config = require('./../../../config.json');
var client = require('./../../../client'); var client = require('./../../../client');
var Promise = require('bluebird');
Promise.promisifyAll(client);
var KeystoneAuthentication = { var KeystoneAuthentication = {
authenticate: function( authType, ret ) { authenticate: function (authType) {
var request = { var request = {
host: config.keystone.httpHost, host: config.keystone.httpHost,
path: '/' + config.keystone.version + '/tokens', path: '/' + config.keystone.version + '/tokens',
port: config.keystone.httpPort, port: config.keystone.httpPort,
token: '', token: '',
@ -13,33 +15,30 @@ var KeystoneAuthentication = {
api: {}, api: {},
useragent: '' useragent: ''
}; };
if (authType == 'password') {
if( authType == 'password' ) {
request.data = JSON.stringify( request.data = JSON.stringify(
{ 'auth':{ {
'tenantName':config.ironic.os_tenant_name, 'auth': {
'passwordCredentials':{ 'tenantName': config.ironic.os_tenant_name,
'username':config.ironic.os_username, 'passwordCredentials': {
'password':config.ironic.os_password 'username': config.ironic.os_username,
'password': config.ironic.os_password
}
} }
} });
});
}; };
if (authType == 'token') {
if( authType == 'token' ) {
request.data = JSON.stringify( request.data = JSON.stringify(
{ "auth":{ {
"tenantName":config.ironic.os_tenant_name, "auth": {
"token":{ "tenantName": config.ironic.os_tenant_name,
"id": config.ironic.os_auth_token "token": {
"id": config.ironic.os_auth_token
}
} }
} });
});
}; };
return (client.PostAsync(request));
client.Post(request, function(body) {
ret(JSON.parse(body).access.token.id);
});
} }
}; };
module.exports = Object.create(KeystoneAuthentication); module.exports = Object.create(KeystoneAuthentication);

View File

@ -0,0 +1,147 @@
var monorail = require('./../api/monorail/monorail');
var ironic = require('./../api/openstack/ironic');
var keystone = require('./../api/openstack/keystone');
var _ = require('underscore');
module.exports = Poller;
function Poller(timeInterval) {
this._timeInterval = timeInterval;
this._ironicToken = null;
this._timeObj = null;
Poller.prototype.getToken = function () {
var self = this;
return keystone.authenticate('password').
then(function (token) {
self._ironicToken = token = JSON.parse(token).access.token.id;
return token;
});
};
Poller.prototype.stopServer = function () {
clearInterval(this.timeObj);
this.timeObj = 0;
};
Poller.prototype.runPoller = function (ironic_nodes) {
var self = this;
for (var i in ironic_nodes) {
console.log('Running poller on :' + ironic_nodes[i].uuid + ':');
self.searchIronic(ironic_nodes[i]);
}
};
Poller.prototype.searchIronic = function (ironic_node) {
var self = this;
return ironic.get_node(self._ironicToken, ironic_node.uuid).
then(function (node_data) {
node_data = JSON.parse(node_data);
if (node_data != undefined &&
node_data.extra && node_data.extra.timer) {
if (!node_data.extra.timer.stop) {
var timeNow = new Date();
var timeFinished = node_data.extra.timer.finish;
var _timeInterval = node_data.extra.timer.timeInterval;
var parsedDate = new Date(Date.parse(timeFinished));
var newDate = new Date(parsedDate.getTime() + _timeInterval);
if (newDate < timeNow) {
node_data.extra.timer.start = new Date().toJSON();
if (node_data.extra.timer.isDone) {
node_data.extra.timer.isDone = false;
self.updateInfo(self._ironicToken, node_data).
then(function (data) {
return self.patchData(node_data.uuid, JSON.stringify(data));
}).
then(function (result) {
return result;
});
}
}
}
}
});
};
Poller.prototype.getNodes = function (token) {
return ironic.get_node_list(token).
then(function (result) {
return (JSON.parse(result).nodes);
});
};
Poller.prototype.patchData = function (uuid, data) {
var self = this;
return ironic.patch_node(self._ironicToken, uuid, data).
then(function (result) {
result = JSON.parse(result);
if (result != undefined) {
return result.extra;
}
return null;
});
};
Poller.prototype.updateInfo = function (token, node_data) {
var self = this;
return this.getSeldata(node_data.extra.nodeid).
then(function (result) {
if (result != undefined) {
var lastEvent = {};
result = JSON.parse(result);
if (result[0] && result[0].hasOwnProperty('sel')) {
if (node_data.extra.eventre != undefined) {
var arr = result[0].sel;
var events = _.where(arr, { event: node_data.extra.eventre });
if (events != undefined) {
console.log(events);
node_data.extra.eventcnt = events.length;
lastEvent = events[events.length - 1];
}
}
}
}
//update finish time
node_data.extra.timer.finish = new Date().toJSON();
node_data.extra.timer.isDone = true;
node_data.extra.events = lastEvent;
var data = [{ 'path': '/extra', 'value': node_data.extra, 'op': 'replace' }];
return data;
});
}
Poller.prototype.getSeldata = function (identifier) {
return monorail.request_poller_get(identifier).
then(function (pollers) {
if (typeof pollers !== 'undefined') {
pollers = JSON.parse(pollers);
for (var i in pollers) {
if (pollers[i]['config']['command'] === 'sel') {
return monorail.request_poller_data_get(pollers[i]['id']).
then(function (data) {
return (data);
});
}
}
return (null);
}
else {
return (null);
}
});
}
Poller.prototype.startServer = function () {
var self = this;
return self.getToken().
then(function (token) {
self._timeObj = setInterval(function () {
return self.getNodes(token).
then(function (ironic_nodes) {
return self.runPoller(ironic_nodes);
});
}, self._timeInterval);
});
};
}

View File

@ -15,7 +15,13 @@
}, },
"devDependencies": { "devDependencies": {
"should": "~7.0.1", "should": "~7.0.1",
"supertest": "~1.0.1" "mocha": "^2.1.0",
"sinon": "1.16.1",
"sinon-as-promised": "^2.0.3",
"sinon-chai": "^2.7.0",
"supertest": "^0.15.0",
"underscore": "^1.8.3",
"xunit-file": "0.0.6"
}, },
"scripts" :{ "scripts" :{
"postinstall": "scripts/post-install.sh", "postinstall": "scripts/post-install.sh",

27
Shovel/test/helper.js Normal file
View File

@ -0,0 +1,27 @@
var app = require('connect')();
var http = require('http');
var swaggerTools = require('swagger-tools');
var options = {
swaggerUi: '/swagger.json',
controllers: './controllers',
useStubs: process.env.NODE_ENV === 'development' ? true : false // Conditionally turn on stubs (mock mode)
};
var swaggerDoc = require('./../api/swagger.json');
module.exports.startServer = function startServer() {
swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
app.use(middleware.swaggerMetadata());
app.use(middleware.swaggerRouter(options));
http.createServer(app).listen(9008, 'localhost');
});
};
module.exports.stopServer = function stopServer() {
var net = require('net');
var socket = net.createConnection(9008);
socket.end();
};

View File

@ -1,183 +0,0 @@
var should = require('should');
var assert = require('assert');
var request = require('supertest');
describe('Routing', function () {
var url = 'http://localhost:9005';
//variable for neg testing
var info = {
'negative_testing': {
'onrack_id': '123456789',
'ironic_chassis_id': '123456789',
'ironic_name': '123456789'
},
'positive_testing': {
'onrack_id': '123456789',
'ironic_chassis_id': '123456789',
'ironic_name': '123456789'
}
}
console.info('**********Variables used in this test**********');
console.info(info);
describe('shovel-info', function () {
it('response should have property \'name\': \'shovel\'', function (done) {
request(url)
.get('/api/1.1/info')
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
JSON.parse(res.text).should.have.property('name', 'shovel');
done();
});
});
});
describe('negative testing:\r\n', function () {
describe('shovel-catalogs/{identifier}', function () {
it('in case of a wrong onrack id, response should include property: "message": "Could not find node with identifier ' + info.negative_testing.onrack_id + '"', function (done) {
request(url)
.get('/api/1.1/catalogs/' + info.negative_testing.onrack_id)
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
JSON.parse(res.text).should.have.property('message', 'Could not find node with identifier ' + info.negative_testing.onrack_id);
done();
});
});
});
describe('shovel-nodes/{identifier}', function () {
it('in case of a wrong onrack id, response should include property: "message": "Could not find node with identifier ' + info.negative_testing.onrack_id + '"', function (done) {
request(url)
.get('/api/1.1/nodes/' + info.negative_testing.onrack_id)
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
JSON.parse(res.text).should.have.property('message', 'Could not find node with identifier ' + info.negative_testing.onrack_id);
done();
});
});
});
describe('shovel-ironic/chassis/{identifier}', function () {
it('in case of a wrong onrack id, response should include property: error_message', function (done) {
request(url)
.get('/api/1.1/ironic/chassis/' + info.negative_testing.ironic_chassis_id)
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
JSON.parse(JSON.parse(res.text).error_message).should.have.property('faultstring');
done();
});
});
});
describe('shovel-register', function () {
it('in case of a wrong onrack id, response should include property: "message": "Could not find node with identifier ' + info.negative_testing.onrack_id + '"', function (done) {
var body = {
"id": info.negative_testing.onrack_id,
"driver": "string",
"ipmihost": "string",
"ipmiusername": "string",
"ipmipasswd": "string",
"sshhost": "string",
"sshuser": "string",
"sshpswd": "string"
}
request(url)
.post('/api/1.1/register')
.send(body)
.expect('Content-Type', /json/)
.expect(200) //Status code
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
JSON.parse(res.text).should.have.property('message', 'Could not find node with identifier ' + info.negative_testing.onrack_id);
done();
});
});
});
describe('shovel-unregister/{identifier}', function () {
it('in case of a wrong ironic id, response should include property: error_message', function (done) {
request(url)
.delete('/api/1.1/unregister/' + info.negative_testing.ironic_name)
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
JSON.parse(JSON.parse(res.text).error_message).should.have.property('faultstring','Node '+ info.negative_testing.ironic_name +' could not be found.');
done();
});
});
});
});
describe('positive testing testing:\r\n', function () {
describe('shovel-ironic/drivers', function () {
it('response should have property \'drivers\'', function (done) {
request(url)
.get('/api/1.1/ironic/drivers')
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
JSON.parse(res.text).should.have.property('drivers');
done();
});
});
});
describe('shovel-ironic/nodes', function () {
it('response should have property \'nodes\'', function (done) {
request(url)
.get('/api/1.1/ironic/nodes')
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
JSON.parse(res.text).should.have.property('nodes');
done();
});
});
});
describe('shovel-nodes', function () {
it('response should have property "identifiers"', function (done) {
request(url)
.get('/api/1.1/nodes')
// end handles the response
.end(function (err, res) {
if (err) {
throw err;
}
// this is should.js syntax, very clear
for (item in JSON.parse(res.text)) {
JSON.parse(res.text)[item].should.have.property('identifiers');
}
done();
});
});
});
});
});

View File

@ -0,0 +1,166 @@
var request = require('supertest');
var should = require('should');
var assert = require('assert');
var sinon = require('sinon');
var monorail = require('./../../lib/api/monorail/monorail');
var ironic = require('./../../lib/api/openstack/ironic');
var keystone = require('./../../lib/api/openstack/keystone');
var Promise = require('bluebird');
var Poller = require('./../../lib/services/poller');
var _ = require('underscore');
describe('Shovel poller unit testing', function () {
var identifier = '9a761508-4eee-4065-b47b-45c22dff54c2';
var ironic_node_list = [
{
uuid: "9a761508-4eee-4065-b47b-45c22dff54c2",
extra: {
name: "D51B-2U (dual 10G LoM)",
eventre: "",
nodeid: "564cefa014ee77be18e48efd",
timer: {
start: "2015-11-30T21:14:11.753Z",
finish: "2015-11-30T21:14:11.772Z",
stop: false,
isDone: true,
timeInteval: 5000
},
eventcnt: 0
}
}
]
var nodePollers = [{
config: {
command: "sel"
},
id: "564dd86285fb1e7c72721543"
}]
var _sel = {
sel:[
{
logId: "1",
date: "12/03/2015",
time: "08:54:11",
sensorType: "Memory",
sensorNumber: "#0x53",
event: "Correctable ECC",
value: "Asserted"
}
]
};
var keyToken = {
access:{
token:{id:'123456'}
}
};
var selEvent = { message: "There is no cache record for the poller with ID 564cf02a4978dadc187976f5.Perhaps it has not been run yet?" };
var extraPatch = {
extra: {
name: "QuantaPlex T41S-2U",
eventre: "Correctable ECC",
nodeid: "565f3f3b4c95bce26f35c6a0",
timer: {
timeInterval: 15000,
start: "2015-12-03T17:38:20.569Z",
finish: "2015-12-03T17:38:20.604Z",
stop: false,
isDone: true
}
}
};
var patchedData = [{ 'path': '/extra', 'value': extraPatch.extra, 'op': 'replace' }];
var pollerInstance;
before('start HTTP server', function () {
pollerInstance = new Poller(5000);//timeInterval to 5s
});
beforeEach('set up mocks', function () {
sinon.stub(monorail, 'request_poller_get').returns(Promise.resolve(JSON.stringify(nodePollers)));
sinon.stub(monorail, 'request_poller_data_get').returns(Promise.resolve(JSON.stringify(_sel)));
sinon.stub(ironic,'patch_node').returns(Promise.resolve(JSON.stringify(extraPatch)));
sinon.stub(keystone,'authenticate').returns(Promise.resolve(JSON.stringify(keyToken)));
sinon.stub(ironic,'get_node_list').returns(Promise.resolve(JSON.stringify(ironic_node_list)))
});
afterEach('teardown mocks', function () {
monorail['request_poller_get'].restore();
monorail['request_poller_data_get'].restore();
ironic['patch_node'].restore();
keystone['authenticate'].restore();
ironic['get_node_list'].restore();
});
it('pollerInstance.getSeldata()', function (done) {
return pollerInstance.getSeldata(identifier).
then(function (data) {
var result = JSON.parse(data);
result.should.have.property('sel');
_.each(result[0],function(item){
console.info(item);
item.should.have.property('sensorNumber');
item.should.have.property('event');
});
done();
}).
catch (function(err){
throw(err);
});
});
it('Poller.prototype.updateInfo',function(done){
return pollerInstance.updateInfo(identifier,extraPatch).
then(function(data){
var result = data;
_.each(result,function(item){
item.should.have.property('path');
item.should.have.property('value');
});
done();
}).
catch(function(err){
throw err;
});
});
it('Poller.prototype.patchData',function(done){
return Poller.prototype.patchData('uuid',JSON.stringify(patchedData)).
then(function(data){
data.should.have.property('nodeid');
data.should.have.property('timer');
done();
}).
catch(function(err){
throw(err);
done();
});
});
it('Poller.prototype.getNodes',function(done){
return pollerInstance.getNodes().
then(function(result){
_.each(result,function(item){
item.should.have.property('uuid');
item.should.have.property('extra');
});
done();
}).
catch(function(err){
throw(err);
});
});
it('Poller.prototype.getToken',function(done){
return pollerInstance.getToken().
then(function(token){
token.should.be.equal('123456');
done();
}).
catch(function(err){
throw err;
});
});
});