Skip to content

Instantly share code, notes, and snippets.

@ysmood
Created August 26, 2015 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ysmood/16d784c63a6589855856 to your computer and use it in GitHub Desktop.
Save ysmood/16d784c63a6589855856 to your computer and use it in GitHub Desktop.
var kit = require('nokit');
var _ = kit._;
var Promise = kit.Promise;
/**
* A simple openstack client.
* @param {Object} opts
* ```js
* {
* authUrl: String,
* username: String,
* password: String,
* getPublicURL: function (token) {}
* }
* ```
* @return {Object}
* @example
* ```js
* var client = openstackClient({
* authUrl: 'http:/test.com/v2.0/tokens',
* getPublicURL: function (token) {
* return _.find(
* _.find(
* token.access.serviceCatalog,
* { type: 'object-store' }
* ).endpoints,
* { region: 'Beijing' }
* ).publicURL;
* }
* });
*
* client.request({
* url: '?format=json'
* })
* .then(function (res) {
* kit.logs('storage info:', res.body);
* })
*
* client.request({
* method: "PUT",
* url: '/txt'
* })
* .then(function () {
* kit.logs('txt container created');
*
* var buf = kit.readFileSync('Readme.md');
* return client.request({
* method: 'PUT',
* url: '/txt/test.js',
* headers: {
* 'Content-Length': buf.length,
* 'Content-Type': 'text/plain; charset=UTF-8'
* },
* reqData: buf
* }).then(function (res) {
* kit.logs(res.statusCode, res.headers);
* })
* })
* .then(function () {
* return client.request({
* url: '/txt/test.js'
* }).then(function (res) {
* kit.logs(res.body + '');
* })
* });
* ```
*/
module.exports = function (opts) {
var tokenCache;
var publicURLCache;
var self = {};
function parseRes (res) {
if (res.statusCode < 400) {
if (_.startsWith(res.headers['content-type'], 'application/json')) {
if (res.body)
res.body = JSON.parse(res.body);
else
res.body = null;
return res;
} else
return res;
} else {
var err = new Error(res.statusCode + ' ' + res.body);
err.details = res;
return Promise.reject(err);
}
}
var getTokenTask;
/**
* Get token
* @return {Object}
*/
self.getToken = function () {
if (tokenCache && new Date().toJSON() < tokenCache.access.token.expires)
return Promise.resolve(tokenCache);
if (getTokenTask) return getTokenTask;
return getTokenTask = kit.request({
url: opts.authUrl,
method: 'POST',
body: false,
headers: {
'Content-Type': 'application/json'
},
reqData: JSON.stringify({
"auth": {
"tenantName": opts.username,
"passwordCredentials": {
"username": opts.username,
"password": opts.password
}
}
})
}).then(parseRes).then(function (res) {
getTokenTask = null;
publicURLCache = opts.getPublicURL(res.body);
return tokenCache = res.body;
});
}
/**
* Request
* @param {Object} ropts
* @return {http.IncomingMessage}
*/
self.request = function (ropts) {
return self.getToken().then(function (token) {
if (_.isFunction(ropts.url)) {
ropts.url = ropts.url(token);
} else {
ropts.url = publicURLCache + ropts.url;
}
if (!ropts.headers) ropts.headers = {};
ropts.headers['X-Auth-Token'] = token.access.token.id;
if (_.isUndefined(ropts.body)) ropts.body = false;
return kit.request(ropts).then(parseRes);
});
};
return self;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment