Skip to content
This repository has been archived by the owner on Jun 19, 2018. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mmurphy committed May 28, 2012
0 parents commit 4d017be
Show file tree
Hide file tree
Showing 9 changed files with 406 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
@@ -0,0 +1,10 @@
lib-cov/
dist/
output/
man/
test/log/
*~
.project
.settings/
node_modules/
.DS_Store
Empty file added README.md
Empty file.
10 changes: 10 additions & 0 deletions config/dev.json
@@ -0,0 +1,10 @@
{
"auth": {
"passwordCredentials": {
"username": "user1234",
"password":"secretpassword"
}
},
"host": "http://192.168.28.52:5000",
"storageName": "swift-service"
}
74 changes: 74 additions & 0 deletions lib/authenticate.js
@@ -0,0 +1,74 @@
var request = require('request');
var async = require('async');
var url = require('url');

var defaults = {
openstackIdentityTokens: "/v2.0/tokens"
};

/*
* Authenticate with Keystone, getting auth token and the storageURL to use for Swift
*
* options:
* {
* "auth": {
* "passwordCredentials": {
* "username": "feedhenry",
* "password":"PASSWORD"
* }
* },
* host: "https://lon.identity.api.rackspacecloud.com",
* storageName: "cloudFiles"
* }
*
*
* callback(err, tokens)
* where tokens is:
* {
* id: // the token
* expires: // expiry time/dat of token
* storageUrl: // the url to use for accessing storage
* }
*/
var getTokens = exports.getTokens = function (options, callback) {
var uri = url.parse(options.host);
uri.pathname = defaults.openstackIdentityTokens;
var targetURL = url.format(uri);
request(
{
method: 'POST',
uri: targetURL,
json: {"auth": options.auth},
headers: {"Accept": "application/json"}
},
function (err, res, body) {
var tokens = {};
if (!err && res && res.statusCode && res.statusCode === 200) {
var respBody = body;
console.log('responseBody ', respBody);
tokens.id = respBody.access.token.id;
tokens.expires = respBody.access.token.expires;
async.detect(
respBody.access.serviceCatalog,
function (item, cb) {
var doesMatch = (item.type === 'object-store') && (item.name === options.storageName);
return cb(doesMatch);
},
function (matchingItem) {
if(matchingItem && matchingItem.endpoints && matchingItem.endpoints[0] && matchingItem.endpoints[0].publicURL) {
tokens.storageUrl = matchingItem.endpoints[0].publicURL;
} else {
err = new Error("storageURL not available");
}
return callback(err, res, tokens);
}
);
} else {
if(!err) {
err = new Error("request unsuccessful, statusCode: " + res.statusCode);
}
return callback(err, res, tokens);
}
}
);
};
154 changes: 154 additions & 0 deletions lib/storage.js
@@ -0,0 +1,154 @@
var request = require('request');
var async = require('async');
var url = require('url');
var fs = require('fs');

var OpenStackStorage = exports.OpenStackStorage = function (pAuthFunction, callback) {
var self = this;
self.authFn = pAuthFunction;
self.tokens = {};
self.authFn(function (err, res, tokens) {
if(!err) {
self.tokens = tokens;
// console.log("setting tokens to ", tokens);
}
callback(err, res, tokens);
});
};

OpenStackStorage.prototype.getFiles = function (containerName, callback) {
var self = this;
// console.log("tokens: ", self.tokens);
var targetURL = url.parse(self.tokens.storageUrl + '/' + containerName);

// console.log("targetURL: ", targetURL);
request(
{
method: 'GET',
uri: targetURL,
json: {},
headers: {
"X-Auth-Token": self.tokens.id,
"Accept": "application/json"
}
},
function (err, res, body) {
if (!err && res && res.statusCode && res.statusCode >= 200 && res.statusCode <= 204) {
// console.log("Successful return from getFiles: ", res.statusCode, 'body: ', body);
var files = body;
return callback(err, files);
} else {
if(!err) {
err = new Error("request unsuccessful, statusCode: " + res.statusCode);
}
return callback(err, res.statusCode);
}
}
);
};

OpenStackStorage.prototype.getContainers = function (callback) {
var self = this;
return self.getFiles("", callback);
};

OpenStackStorage.prototype.createContainer = function (containerName, callback) {
var self = this;
// console.log("tokens: ", self.tokens);
var targetURL = url.parse(self.tokens.storageUrl + '/' + containerName);
// console.log("targetURL: ", targetURL);
request(
{
method: 'PUT',
uri: targetURL,
json: {},
headers: {
"X-Auth-Token": self.tokens.id,
"Accept": "application/json"
}
},
function (err, res, body) {
if (!err && res && res.statusCode && res.statusCode >= 200 && res.statusCode <= 204) {
return callback(err, res.statusCode);
} else {
if(!err) {
err = new Error("request unsuccessful, statusCode: " + res.statusCode);
}
return callback(err, res.statusCode);
}
}
);
};

OpenStackStorage.prototype.deleteContainer = function (containerName, callback) {
var self = this;
// console.log("tokens: ", self.tokens);
var targetURL = url.parse(self.tokens.storageUrl + '/' + containerName);
// console.log("targetURL: ", targetURL);
request(
{
method: 'DELETE',
uri: targetURL,
json: {},
headers: {
"X-Auth-Token": self.tokens.id,
"Accept": "application/json"
}
},
function (err, res, body) {
if (!err && res && res.statusCode && res.statusCode >= 200 && res.statusCode <= 204) {
return callback(err, res.statusCode);
} else {
if(!err) {
err = new Error("request unsuccessful, statusCode: " + res.statusCode);
}
return callback(err, res.statusCode);
}
}
);
};

OpenStackStorage.prototype.deleteFile = function (containerName, remoteNameToDelete, callback) {
var self = this;
return self.deleteContainer(containerName + '/' + remoteNameToDelete, callback);
};

OpenStackStorage.prototype.addFile = function (containerName, fileToSend, callback) {
var self = this;
if(!fileToSend || !fileToSend.remoteName || (!fileToSend.localFile && !fileToSend.stream)) {
return callback(new Error("must specify remoteName and either .localFile or .stream for file uploads"));
}
// console.log("tokens: ", self.tokens);
var targetURL = url.parse(self.tokens.storageUrl + '/' + containerName + '/' + fileToSend.remoteName);
// console.log("targetURL: ", targetURL);
var headers = {
"X-Auth-Token": self.tokens.id,
"Accept": "application/json"
};
var fileStream = null;
if(fileToSend.stream) {
fileStream = fileToSend.stream;
} else if (fileToSend.localFile) {
headers['Content-Length'] = fs.statSync(fileToSend.localFile).size;
fileStream = fs.createReadStream(fileToSend.localFile);
}
var uploadStream = request(
{
method: 'PUT',
uri: targetURL,
headers: headers
},
function (err, res, body) {
if (!err && res && res.statusCode && res.statusCode >= 200 && res.statusCode <= 204) {
return callback(err, res.statusCode);
} else {
if(!err) {
err = new Error("request unsuccessful, statusCode: " + res.statusCode);
}
return callback(err, res.statusCode);
}
}
);
fileStream.pipe(uploadStream);
};

21 changes: 21 additions & 0 deletions package.json
@@ -0,0 +1,21 @@
{
"author": "Martin Murphy <martin.murphy@feedhenry.com>",
"name": "openstack-swift",
"description": "Openstack Object Store (Swift) client",
"version": "0.1.0-BUILD-NUMBER",
"repository": {
"url": ""
},
"dependencies": {
"optimist": "*",
"winston": "*",
"dateformat": "*",
"async": "0.1.18",
"request": "2.9.202"
},
"devDependencies": {},
"optionalDependencies": {},
"engines": {
"node": "*"
}
}
62 changes: 62 additions & 0 deletions test/testContainers.js
@@ -0,0 +1,62 @@
// Arguments parser
var args = require('optimist').argv;

// Logger Library
var winston = require('winston');

var dateFormat = require('dateformat');

// Usage
function usage() {
console.error("Usage: " + args.$0 + " <config file>");
process.exit(0);
}

if(args.h) {
usage();
}

if(args._.length != 1) {
usage();
}

var configFile = args._[0];
var config = require(configFile);

var async = require('async');
var storage = require('storage');
var authenticate = require('authenticate');


var authFn = async.apply(authenticate.getTokens, config);
var storageSwift = new storage.OpenStackStorage (authFn, function(err, res, tokens) {
console.log('Storage constructor - err: ', err, ', tokens: ', tokens);
var containers = storageSwift.getContainers(function(err, containers) {
console.log('getCOntainers - err: ', err, ', containers: ', containers);
async.forEachSeries(
containers,
function (container, containerCB) {
storageSwift.getFiles(container.name, function (err, files) {
console.log('in container: ', container.name, ', got files: ', files);
return containerCB();
});
},
function (err) {
console.log('async complete - err: ', err);
storageSwift.createContainer("EngTest", function (err, statusCode) {
console.log('after createContainer - err: ', err, ", statusCode: ", statusCode);
storageSwift.addFile("EngTest", {remoteName:'file1.png', localFile:'./test.png'}, function(err, statusCode) {
console.log('after addFile - err: ', err, ", statusCode: ", statusCode);
storageSwift.deleteFile("EngTest", 'file1.png', function (err, statusCode) {
console.log('after deleteFile - err: ', err, ", statusCode: ", statusCode);
storageSwift.deleteContainer("EngTest", function (err, statusCode) {
console.log('after deleteContainer - err: ', err, ", statusCode: ", statusCode);
});
});
});
});
}
);
});
});

39 changes: 39 additions & 0 deletions test/testDeleteFile.js
@@ -0,0 +1,39 @@
// Arguments parser
var args = require('optimist').argv;

// Logger Library
var winston = require('winston');

var dateFormat = require('dateformat');

// Usage
function usage() {
console.error("Usage: " + args.$0 + " <config file>");
process.exit(0);
}

if(args.h) {
usage();
}

if(args._.length != 1) {
usage();
}

var configFile = args._[0];
var config = require(configFile);

var async = require('async');
var storage = require('storage');
var authenticate = require('authenticate');

var authFn = async.apply(authenticate.getTokens, config);
var storageSwift = new storage.OpenStackStorage (authFn, function(err, res, tokens) {
console.log('Storage constructor - err: ', err, ', tokens: ', tokens);
storageSwift.deleteFile("EngTest", 'file1.png', function (err, statusCode) {
console.log('after deleteFile - err: ', err, ", statusCode: ", statusCode);
storageSwift.deleteContainer("EngTest", function (err, statusCode) {
console.log('after deleteContainer - err: ', err, ", statusCode: ", statusCode);
});
});
});

0 comments on commit 4d017be

Please sign in to comment.