Skip to content

Instantly share code, notes, and snippets.

@liyu1981
Last active December 31, 2015 16:49
Show Gist options
  • Select an option

  • Save liyu1981/8016126 to your computer and use it in GitHub Desktop.

Select an option

Save liyu1981/8016126 to your computer and use it in GitHub Desktop.
minimalistic wrapper for the CloudStack API in Node.js. original here -- https://github.com/Chatham/node-cloudstack
// taken from https://github.com/Chatham/node-cloudstack
// adapted by LI, Yu
var http = require('http');
var crypto = require('crypto');
var url = require('url');
module.exports = function cloudstack(options) {
if (!options) { options = {}; }
var apiUri = options.apiUri || process.env.CLOUDSTACK_API_URI,
apiKey = options.apiKey || process.env.CLOUDSTACK_API_KEY,
apiSecret = options.apiSecret || process.env.CLOUDSTACK_API_SECRET;
this.exec = function(cmd, params, callback) {
var paramString = genSignedParamString(apiKey, apiSecret, cmd, params);
var urlObj = url.parse(apiUri);
console.log('issue request: ', paramString);
var r = http.request({
host: urlObj.hostname,
port: urlObj.port || 80,
path: urlObj.pathname + '?' + paramString
},
function(res) {
var body = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
body += chunk;
});
res.on('error', function(err) {
callback(err, null);
});
res.on('end', function() {
if (body === '') {
callback(null, {});
return;
}
try {
var parsedBody = JSON.parse(body);
if (res.statusCode == 200) {
// result is always wrapped in <cmd>response field
// details in
// http://cloudstack.apache.org/docs/en-US/Apache_CloudStack/4.0.2/html/API_Developers_Guide/responses.html
var result = parsedBody[cmd.toLowerCase() + 'response'];
callback(null, result);
return;
}
callback(new Error('Wrong result with code ' + res.statusCode), parsedBody);
} catch(err) {
callback(err, body);
}
});
});
r.on('error', function(err) { callback(err, null); });
r.end();
};
var genSignedParamString = function(apiKey, apiSecret, cmd, params) {
// Detail algorithm can be found in
// http://cloudstack.apache.org/docs/en-US/Apache_CloudStack/4.0.2/html/API_Developers_Guide/responses.html
params.apiKey = apiKey;
params.command = cmd;
params.response = 'json'; // ensure that we get json result
// get all keys and sort them by keys
var paramKeys = [];
for(var key in params) {
if(params.hasOwnProperty(key)) {
paramKeys.push(key);
};
};
paramKeys.sort();
// now encode them
var qsParameters = [];
for(var i = 0; i < paramKeys.length; i++) {
key = paramKeys[i];
qsParameters.push(key + '=' + encodeURIComponent(params[key]));
}
// finally form the param string with signature
var queryString = qsParameters.join('&'),
cryptoAlg = crypto.createHmac('sha1', apiSecret),
signature = cryptoAlg.update(queryString.toLowerCase()).digest('base64');
return queryString + '&signature=' + encodeURIComponent(signature);
};
};
if (typeof module !== 'undefined' && require.main === module) {
if (process.argv.length < 3) {
console.log('Usage: node <this_script> cloudstack_api_name');
process.exit(1);
return;
}
var cs = new module.exports({
"apiUri": "http://127.0.0.1/cloudstack/api",
"apiKey": "your apikey",
"apiSecret": "your apiSecret"
});
var rl = require('readline').createInterface(process.stdin, process.stdout);
rl.setPrompt('Parameters for ' + process.argv[2] + ' (Ctrl-D to Finish)> \n');
rl.prompt();
var paramsLine = '';
rl.on('line', function(line) {
paramsLine += line.trim();
})
.on('close', function() {
var params = JSON.parse(paramsLine === '' ? '{}' : paramsLine);
cs.exec(process.argv[2], params,
function(err, data) {
if (err) {
console.log('error:', err);
return;
}
console.log('got result:\n', data);
});
});
}
@liyu1981
Copy link
Copy Markdown
Author

usage

var cloudstack = new (require('./cloudstack'))({
    apiUri: config.api_uri, // overrides process.env.CLOUDSTACK_API_URI
    apiKey: config.api_key, // overrides process.env.CLOUDSTACK_API_KEY
    apiSecret: config.api_secret // overrides process.env.CLOUDSTACK_API_SECRET
});

cloudstack.exec('listVirtualMachines', {}, function(error, result) {
    console.log(result);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment