Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 4d017be544d2fb2886870d6d78fe98f6c6affa61 @mmurphy mmurphy committed May 28, 2012
Showing with 406 additions and 0 deletions.
  1. +10 −0 .gitignore
  2. 0 README.md
  3. +10 −0 config/dev.json
  4. +74 −0 lib/authenticate.js
  5. +154 −0 lib/storage.js
  6. +21 −0 package.json
  7. +62 −0 test/testContainers.js
  8. +39 −0 test/testDeleteFile.js
  9. +36 −0 test/testTokens.js
10 .gitignore
@@ -0,0 +1,10 @@
+lib-cov/
+dist/
+output/
+man/
+test/log/
+*~
+.project
+.settings/
+node_modules/
+.DS_Store
0 README.md
No changes.
10 config/dev.json
@@ -0,0 +1,10 @@
+{
+ "auth": {
+ "passwordCredentials": {
+ "username": "user1234",
+ "password":"secretpassword"
+ }
+ },
+ "host": "http://192.168.28.52:5000",
+ "storageName": "swift-service"
+}
74 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 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 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 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 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);
+ });
+ });
+});
36 test/testTokens.js
@@ -0,0 +1,36 @@
+// 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 authenticate = require('authenticate');
+
+var res = authenticate.getTokens(config, function (err, res, tokens) {
+ console.log("err: ", err);
+// console.log("res: ", res);
+ console.log("tokens: ", tokens);
+});
+
+
+
+

0 comments on commit 4d017be

Please sign in to comment.