UNPKG

nfifo

Version:

Simple node.js lib and cli that connects with a Project-FiFo API

172 lines (123 loc) 4.07 kB
//How nice... https://github.com/mikeal/request/issues/418 process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" var request = require('request') var Fifo = module.exports = function fifo(ip, api_version) { var schema = ip.indexOf('http') < 0? 'https://': '' this.ip = ip this.api_version = api_version || '0.1.0' this.endpoint = schema + ip + '/api/' + this.api_version + '/' this.defaultParams = { json: true, headers: {'x-full-list': true} } } //Explicit login Fifo.prototype.login = function(user, pass, cb) { var body = {user: user, password: pass} this.send('sessions').post({body: body}, function(err, res, body) { if (err) return cb(err) //When running on the browser, we will not get the raw 303, but the redirected one. will be status 200 if (typeof window == 'object') { if (res.statusCode != 200) return cb(new Error(body || ('Could not login :( ' + res.statusCode))) this.token = body.session return cb && cb(null, res, body) } if (res.statusCode != 303) return cb(new Error(body || ('Could not login :( ' + res.statusCode))) this.token = res.headers['x-snarl-token'] cb && cb(null, res, body) }.bind(this)) } //Try to reutilize token. if not, login. Fifo.prototype.access = function(user, pass, cb) { if (this.token) { this.send('sessions').get(this.token, function(err, res) { if (err) return cb(err) if (res.statusCode === 200) return cb(null, res) this.login(user, pass, cb) }.bind(this)) } else this.login(user, pass, cb) return this } //Merge default options into obj function merge(obj, defaults) { for (var k in defaults) { if (typeof obj[k] == 'undefined') obj[k] = defaults[k] if (typeof obj[k] == 'object') merge(obj[k], defaults[k]) } return obj } Fifo.prototype.buildParams = function(opts, defaultOpts) { //Opts can be a string, array or object. var params = {} //typeof [] is 'object' !! if (typeof opts == 'object' && !Array.isArray(opts)) params = opts else params.args = opts //Args should be an array. if string put it in the array... if (params.args && !Array.isArray(params.args)) params.args = [params.args] return this.addDefaults(params, defaultOpts) } //Add default values Fifo.prototype.addDefaults = function(opts, defaultOpts) { var params = merge(opts, defaultOpts), url = this.endpoint + opts.resource if (opts.args) url += '/' + opts.args.join('/') //Put the default params/headers merge(params, this.defaultParams) params.url = url if (this.token) params.headers['x-snarl-token'] = this.token if (params.json) params.headers['content-type'] = 'application/json;charset=UTF-8' //If the request is json, request will transform it for us. if not, assume its json anyway :P if (!params.json) params.body = JSON.stringify(params.body) return params } function requestClosure(method, resource) { method = method || 'GET' //opts: {params: [], body: } return function req(opts, cb) { //If first params is a function, there is no options to pass if (typeof opts == 'function') { cb = opts opts = {} } var params = this.buildParams(opts, {method: method, resource: resource}) // return request(params, cb) //In case the response is json, and json: true is not set, parse the body //i.e. https://jira.project-fifo.net/browse/FIFO-566 return request(params, function(err, res, body) { if (typeof body === 'string' && (body[0] == '{' || body[0] == '[')) try { body = JSON.parse(body || '{}') } catch(e){ console.log('Could not parse body', e.message) } cb && cb(err, res, body) }) } } //Send a message to a fifo resource. Could be vms, hypervisors, etc. Fifo.prototype.send = function(resource) { if (resource != 'sessions' && !this.token) throw new Error('No token!') return { get: requestClosure('GET', resource).bind(this), post: requestClosure('POST', resource).bind(this), delete: requestClosure('DELETE', resource).bind(this), put: requestClosure('PUT', resource).bind(this) } }