UNPKG

liveapicreator-admin-cli

Version:

The NodeJS command line utility for 'CA Live API Creator' DevOps Administration from CA Technologies

680 lines (649 loc) 19.9 kB
var Client = require('node-rest-client').Client; var colors = require('colors'); var _ = require('underscore'); var Table = require('easy-table'); //var sync = require('synchronize'); var fs = require('fs'); var context = require('./context.js'); var login = require('../util/login.js'); var printObject = require('../util/printObject.js'); var dotfile = require('../util/dotfile.js'); module.exports = { doResource: function(action, cmd) { if (action === 'list') { module.exports.list(cmd); } else if (action === 'create') { module.exports.create(cmd); } else if (action === 'update') { module.exports.update(cmd); } else if (action === 'delete') { module.exports.del(cmd); } else if (action === 'export') { module.exports.export(cmd); } else if (action === 'import') { module.exports.import(cmd); } else { console.log('You must specify an action: list, create, export, update or delete'); //program.help(); } }, list: function (cmd) { var client = new Client(); var loginInfo = login.login(cmd); if ( ! loginInfo) return; var url = loginInfo.url; var apiKey = loginInfo.apiKey; var projIdent = cmd.project_ident; if ( ! projIdent) { projIdent = dotfile.getCurrentProject(); if ( ! projIdent) { console.log('There is no current project.'.yellow); return; } } // This gets called once we have figured out which API version to use function listResources(apiversion_ident) { client.get(url + "/resources?sysfilter=equal(container_ident: null, apiversion_ident:" + apiversion_ident +")", { headers: { Authorization: "CALiveAPICreator " + apiKey + ":1", "Content-Type" : "application/json" } }, function(data) { if (data.errorMessage) { console.log(data.errorMessage.red); return; } printObject.printHeader('Top-level resources for API Version: '+apiversion_ident); var table = new Table(); var verboseDisplay = ""; _.each(data, function(p) { table.cell("Ident", p.ident); table.cell("Name", p.name); table.cell("Prefix", p.prefix); table.cell("Table", p.table_name); var type = ""; switch(p.resource_type_ident) { case 1: type = "normal"; break; case 2: type = "free SQL"; break; case 3: type = "JavaScript"; break; case 4: type = "stored proc"; break; case 5: type = "Mongo"; break; default: type = "unknown"; } table.cell("Type", type); var comments = p.description; if (comments) { comments = comments.replace(/\n/g, ''); } if ( ! comments) { comments = ""; } else if (comments.length > 50){ comments = comments.substring(0, 47) + "..."; } table.cell("Comments", comments); table.newRow(); if(cmd.verbose) { verboseDisplay += "\n"; verboseDisplay += "lacadmin resource export --file RESOURCE_"+p.name + ".json\n"; verboseDisplay += "#lacadmin resource import --file RESOURCE_"+p.name + ".json\n"; } }); table.sort(['Name']); if (data.length === 0) { console.log('There is no resource defined for this API version'.yellow); } else { console.log(table.toString()); } printObject.printHeader("# resources: " + data.length); if(cmd.verbose) { console.log(verboseDisplay); } }); } module.exports.getApiVersionAndDoSomething(cmd, listResources); }, create: function(cmd) { var client = new Client(); var loginInfo = login.login(cmd); if ( ! loginInfo) return; if ( ! cmd.resource_name) { console.log('Missing parameter: name'.red); return; } if ( ! cmd.prefix) { cmd.prefix = "main"; } if ( ! cmd.table_name) { console.log('Missing parameter: table_name'.red); return; } var curProj = cmd.project_ident; if ( ! curProj) { curProj = dotfile.getCurrentProject(); } if ( ! curProj) { console.log('There is no current project.'.yellow); return; } if ( ! cmd.type) { cmd.type = 1; } else { switch(cmd.type.toLowerCase()) { case 'normal': cmd.type = 1; break; case 'sql': cmd.type = 2; break; case 'javascript': cmd.type = 3; break; case 'storedproc': cmd.type = 4; break; case 'mongo': cmd.type = 5; break; default: console.log(('Unknown resource type: ' + cmd.type).red); return; } } if ( ! cmd.is_collection) { cmd.is_collection = 1; } else { cmd.is_collection = (cmd.is_collection === 'true') ? 1 : 0; } module.exports.getApiVersionAndDoSomething(cmd, function(apiversion_ident) { var newResource = { name: cmd.resource_name, table_name: cmd.table_name, prefix: cmd.prefix, description: cmd.description, resource_type_ident: cmd.type, is_collection: cmd.is_collection, container_ident: cmd.container_ident, apiversion_ident: apiversion_ident, sibling_rank: 1 }; var startTime = new Date(); client.post(loginInfo.url + "/resources", { data: newResource, headers: { Authorization: "CALiveAPICreator " + loginInfo.apiKey + ":1", "Content-Type" : "application/json" } }, function(data) { var endTime = new Date(); if (data.errorMessage) { console.log(data.errorMessage.red); return; } // console.log(data.txsummary[0]['@metadata']); var newResource = _.find(data.txsummary, function(r) { return r['@metadata'].resource === 'admin:resources' && r['@metadata'].verb === 'INSERT'; }); if ( ! newResource) throw 'Unable to find newly inserted resource in tx summary'; function addAttribute(alias, colName, callback) { var newAtt = { name: alias, column_name: colName, is_defined_key_part: false, resource_ident: newResource.ident }; client.post(loginInfo.url + "/resourceattributes", { data: newAtt, headers: { Authorization: "CALiveAPICreator " + loginInfo.apiKey + ":1", "Content-Type" : "application/json" } }, function(data2) { if (data2.errorMessage) { console.log(data2.errorMessage.red); if (callback) { callback(data2, null); } return; } if (callback) { callback(null, data2.txsummary[0]); } }); } // This gets called when we're done, possibly with extra objects to show function showSummary(extra) { printObject.printHeader('Resource was created'); _.each(data.txsummary, function(obj) { printObject.printObject(obj, obj['@metadata'].entity, 0, obj['@metadata'].verb); }); if (extra) { _.each(extra, function(obj) { printObject.printObject(obj, obj['@metadata'].entity, 0, obj['@metadata'].verb); }); } var trailer = "Request took: " + (endTime - startTime) + "ms"; trailer += " - # objects touched: "; var numObjects = data.txsummary.length; if (extra) { numObjects += extra.length; } if (data.txsummary.length == 0) { console.log('No data returned'.yellow); } else { trailer += numObjects; } printObject.printHeader(trailer); } // If there are attributes, we have to synchronize to wait for them to be created if (cmd.attributes) { //console.log('Creating attributes...'); var atts = null; try { //console.log('Attributes: ' + cmd.attributes); atts = eval('(' + cmd.attributes + ')'); } catch(e) { console.log(('Error parsing attributes: ' + e).red); } var newAtts = []; //sync.fiber(function(){ for (var colName in atts) { //var newAtt = sync.await(addAttribute(atts[colName], colName, sync.defer())); //console.log('Attribute created'); newAtts.push(newAtt); } showSummary(newAtts); //}); } else { showSummary(); } }); }); }, update: function(cmd) { var client = new Client(); var loginInfo = login.login(cmd); if ( ! loginInfo) return; var url = loginInfo.url; var apiKey = loginInfo.apiKey; var projIdent = cmd.project_ident; if ( ! projIdent) { projIdent = dotfile.getCurrentProject(); if ( ! projIdent) { console.log('There is no current project.'.yellow); return; } } var filter = ""; if( cmd.resource_name != null && cmd.apiversion != null) { filter = "sysfilter=equal(container_ident: null,name:" + cmd.resource_name + ",version: " + cmd.apiversion + ")"; } else { if ( ! cmd.ident) { console.log('Missing parameter: ident'.red); return; } filter = "sysfilter=equal(container_ident: null,ident:" + cmd.ident +")"; } // This gets called to get the resource before we do an update client.get(url + "/resources", { headers: { Authorization: "CALiveAPICreator " + apiKey + ":1", "Content-Type" : "application/json" } }, function(data) { if (data.errorMessage) { console.log(data.errorMessage.red); return; } if (data.length === 0) { console.log('Resource not found for ident :'+cmd.ident.yellow); return; } var resource = data[0]; resource.prop1 = cmd.prop1 || resource.prop1; resource.prop2 = cmd.prop2 || resource.prop2; resource.prop3 = cmd.prop3 || resource.prop3; resource.prop4 = cmd.prop4 || resource.prop4; resource.prefix = cmd.prefix || resource.prefix; resource.table_name = cmd.table_name || resource.table_name; client.put(url + "/resources", { data: resource, headers: { Authorization: "CALiveAPICreator " + apiKey + ":1", "Content-Type" : "application/json" } }, function(res) { if (res.errorMessage) { console.log(res); return; } if (res.length === 0) { console.log('Update Resource not found for ident :'+cmd.ident.yellow); return; } console.log(JSON.stringify(res,null,2)); }); }); }, del : function(cmd) { var client = new Client(); var loginInfo = login.login(cmd); if ( ! loginInfo) { console.log('You are not currently logged into any API Creator server.'.red); return; } var projIdent = cmd.project_ident; if ( ! projIdent) { projIdent = dotfile.getCurrentProject(); if ( ! projIdent) { console.log('There is no current project.'.yellow); return; } } filt = "project_ident:"+projIdent if(cmd.ident) { filt += ",ident:" + cmd.ident + ")"; } else if ( cmd.resource_name) { filt += ",name:'" + cmd.resource_name + "')"; } else { console.log('Missing parameter: please specify a resource_name or ident'.red); return; } client.get(loginInfo.url + "/resources?sysfilter=equal(container_ident: null," + filt, { headers: { Authorization: "CALiveAPICreator " + loginInfo.apiKey + ":1", "Content-Type" : "application/json" } }, function(data) { //console.log('get result: ' + JSON.stringify(data, null, 2)); if (data.errorMessage) { console.log(("Error: " + data.errorMessage).red); return; } if (data.length === 0) { console.log(("Resource(s) not found").red); return; } if (data.length > 1) { console.log(("Error: more than one resource with the given filter =: " + filt).red); return; } var db = data[0]; var startTime = new Date(); client['delete'](db['@metadata'].href + "?checksum=" + db['@metadata'].checksum, { headers: { Authorization: "CALiveAPICreator " + loginInfo.apiKey + ":1", "Content-Type" : "application/json" } }, function(data2) { var endTime = new Date(); if (data2.errorMessage) { console.log(data2.errorMessage.red); return; } printObject.printHeader('Resource was deleted, including the following objects:'); _.each(data2.txsummary, function(obj) { printObject.printObject(obj, obj['@metadata'].entity, 0, obj['@metadata'].verb); }); var trailer = "Request took: " + (endTime - startTime) + "ms"; trailer += " - # objects touched: "; if (data2.txsummary.length == 0) { console.log('No data returned'.yellow); } else { trailer += data2.txsummary.length; } printObject.printHeader(trailer); }); }); }, // Given an apiversion parameter, retrieve the API version, then call callback getApiVersionAndDoSomething: function(cmd, callback) { var client = new Client(); var loginInfo = login.login(cmd); if ( ! loginInfo) return; var url = loginInfo.url; var apiKey = loginInfo.apiKey; var curProj = cmd.project_ident; if ( ! curProj) { curProj = dotfile.getCurrentProject(); } if ( ! curProj) { console.log('There is no current project.'.yellow); return; } // Now figure out which API version to use if (cmd.apiversion) { client.get(url + "/apiversions?sysfilter=equal(project_ident:" + curProj + " , name:'" + cmd.apiversion + "')", { headers: { Authorization: "CALiveAPICreator " + apiKey + ":1", "Content-Type" : "application/json" } }, function(data) { if (data.errorMessage) { console.log(data.errorMessage.red); return; } if (data.length === 0) { console.log('No such API version: ' + cmd.apiversion); return; } if (data.length > 1) { console.log('More than one API version with name: ' + cmd.apiversion); return; } callback(data[0].ident); }); } else { client.get(url + "/apiversions?sysfilter=equal(project_ident:" + curProj +")", { headers: { Authorization: "CALiveAPICreator " + apiKey + ":1", "Content-Type" : "application/json" } }, function(data) { if (data.errorMessage) { console.log(data.errorMessage.red); return; } if (data.length === 0) { console.log('No API version has been defined in this project.'.yellow); return; } if (data.length > 1) { console.log('There are ' + data.length + ' API versions defined in this project. Please specify one.'); var table = new Table(); _.each(data, function(a) { table.cell("Name", a.name); table.newRow(); }); console.log(table.toString()); return; } callback(data[0].ident); }); } }, export: function(cmd) { var client = new Client(); var loginInfo = login.login(cmd); if ( ! loginInfo) return; var url = loginInfo.url; var apiKey = loginInfo.apiKey; var apiversion = 'v1'; if(cmd.apiversion){ apiversion = cmd.apiversion; } var projIdent = cmd.project_ident; var rootIdent = cmd.ident; if ( !cmd.ident) { console.log("You must specifiy a specific specfic resource using --ident (use lacadmin resource list)".red); return; } if ( ! projIdent) { projIdent = dotfile.getCurrentProject(); if ( ! projIdent) { console.log('There is no current project.'.yellow); return; } } var sysfilter = 'equal_or(ident:' + rootIdent + ')'; var sysorder = 'sysorder=(table_name:asc_uc)'; client.get(url + "/AllResources?sysfilter="+sysfilter+"&pagesize=1"+sysorder, { headers: { Authorization: "CALiveAPICreator " + loginInfo.apiKey + ":1", "Content-Type" : "application/json" } }, function(data) { console.log('get result: ' + JSON.stringify(data, null, 2)); if (data.errorMessage) { console.log(("Error: " + data.errorMessage).red); return; } if (data.length === 0) { console.log(("Resource not found").red); return; } var toStdout = false; if ( ! cmd.file) { toStdout = true; } for(var i = 0; i < data.length ; i++){ delete data[i].project_ident; delete data[i]['@metadata']; delete data[i].apiversion_ident; for(var j = 0; j < data[i].Attributes.length; j++){ delete data[i].Attributes[j]['@metadata']; } } if (toStdout) { console.log(JSON.stringify(data, null, 2)); } else { var exportFile = fs.openSync(cmd.file, 'w+', 0600); fs.writeSync(exportFile, JSON.stringify(data, null, 2)); console.log(('Resources have been exported to file: ' + cmd.file).green); } }); }, import: function(cmd) { var client = new Client(); var loginInfo = login.login(cmd); if ( ! loginInfo) return; var url = loginInfo.url; var apiversion = "v1"; if(cmd.apiversion){ apiversion = cmd.apiversion; } var apiKey = loginInfo.apiKey; var projIdent = cmd.project_ident; if ( ! projIdent) { projIdent = dotfile.getCurrentProject(); if ( ! projIdent) { console.log('There is no current project.'.yellow); return; } } var importResourceLevel = function(cmd, res, newRootIdent, newResIdent, containerIdent, originalResource) { console.log("function importResourceLevel \n" + JSON.stringify(res,null,0)); var client = new Client(); var loginInfo = login.login(cmd); if ( ! loginInfo) { return; } var url = loginInfo.url; var originalIdent = res.ident; delete res['@metadata']; delete res.ident; res.container_ident = newResIdent; delete res.entity_name; _.each(res.Attributes, function (a) { delete a.ident; delete a['@metadata']; delete a.resource_ident; }); //console.log("newRootIdent: "+newRootIdent); //console.log("originalIdent: " + originalIdent); //console.log("containerIdent: "+containerIdent); client.post(loginInfo.url + "/AllResources", { data: res, headers: { Authorization: "CALiveAPICreator " + loginInfo.apiKey + ":1", "Content-Type" : "application/json" } }, function(data) { if (data.errorMessage) { console.log(data.errorMessage.red); return; } var newRes = _.find(data.txsummary, function (b) { return b['@metadata'].resource === 'AllResources'; }); if ( ! newRes) { throw "Unable to find newly created resource"; } newResIdent =newRes.ident; // If this is the top resource if ( ! newRootIdent) { newRootIdent = newRes.ident; } var children = _.filter(originalResource, function (r) { return r.container_ident === originalIdent; }); _.each(children, function (c) { importResourceLevel(cmd, c, newRootIdent ,newRes.ident, originalIdent, originalResource); }); }); } client.get(url + "/admin:apiversions?sysfilter=equal(project_ident:" + projIdent +")&sysfilter=equal(name:'" + apiversion +"')&pagesize=1", { headers: { Authorization: "CALiveAPICreator " + loginInfo.apiKey + ":1", "Content-Type" : "application/json" } }, function(versionident) { //console.log('get result: ' + JSON.stringify(data, null, 2)); if (versionident.errorMessage) { console.log(("Error: " + versionident.errorMessage).red); return; } if (versionident.length === 0) { console.log(("API version not found for resources").red); return; } console.log("Version "+ JSON.stringify(versionident[0].name,null,2)); var apiversion_ident = versionident[0].ident; if ( ! cmd.file) { cmd.file = '/dev/stdin'; } context.getContext(cmd, function() { var fileContent = JSON.parse(fs.readFileSync(cmd.file)); var resourceCnt = 0; var rootRes = null; var parent_ident = null; if(Array.isArray(fileContent)){ for(var i = 0 ; i < fileContent.length; i++){ delete fileContent[i]["@metadata"]; delete fileContent[i].ts; delete fileContent.root_ident; fileContent[i].apiversion_ident = apiversion_ident; if(fileContent[i].container_ident === null) { resourceCnt++; rootRes = fileContent[i]; } } } if(resourceCnt > 1){ console.log("You can only import a single resource - use project import for multiple resources".red); return; } importResourceLevel(cmd, rootRes , null, null , null ,fileContent); printObject.printHeader('Import Resource ' + rootRes.name + ':'); }); }); } };