Comparing version 0.7.3 to 0.8.0
@@ -0,1 +1,7 @@ | ||
## v0.8.0 | ||
* Rewrote Rackspace Client to derive from Openstack Client | ||
* Updated Rackspace & Openstack createClient calls to take a proper URI for authUrl | ||
* Added support to specify region in Rackspace & Openstack createClient options | ||
* Added the ability to automatically re-authenticate on token expiry | ||
## v0.7.3 | ||
@@ -2,0 +8,0 @@ * Fixed inline authentication for streaming to rackspace/openstack storage #109 |
@@ -1,7 +0,72 @@ | ||
var pkgcloud = require('../../lib/pkgcloud'); | ||
var pkgcloud = require('pkgcloud'), | ||
_ = require('underscore'); | ||
var rackspace = pkgcloud.compute.createClient({ | ||
provider: 'rackspace', | ||
username: 'nodejitsu', | ||
apiKey: 'foobar' | ||
// create our client with your rackspace credentials | ||
var client = pkgcloud.providers.rackspace.compute.createClient({ | ||
username: 'your-username', | ||
apiKey: 'your-api-key' | ||
}); | ||
// first we're going to get our flavors | ||
client.getFlavors(function (err, flavors) { | ||
if (err) { | ||
console.dir(err); | ||
return; | ||
} | ||
// then get our base images | ||
client.getImages(function (err, images) { | ||
if (err) { | ||
console.dir(err); | ||
return; | ||
} | ||
// Pick a 512MB instance flavor | ||
var flavor = _.findWhere(flavors, { name: '512MB Standard Instance' }); | ||
// Pick an image based on Ubuntu 12.04 | ||
var image = _.findWhere(images, { name: 'Ubuntu 12.04 LTS (Precise Pangolin)' }); | ||
// Create our first server | ||
client.createServer({ | ||
name: 'server1', | ||
image: image, | ||
flavor: flavor | ||
}, handleServerResponse); | ||
// Create our second server | ||
client.createServer({ | ||
name: 'server2', | ||
image: image, | ||
flavor: flavor | ||
}, handleServerResponse); | ||
}); | ||
}); | ||
// This function will handle our server creation, | ||
// as well as waiting for the server to come online after we've | ||
// created it. | ||
function handleServerResponse(err, server) { | ||
if (err) { | ||
console.dir(err); | ||
return; | ||
} | ||
console.log('SERVER CREATED: ' + server.name + ', waiting for active status'); | ||
// Wait for status: ACTIVE on our server, and then callback | ||
server.setWait({ status: 'ACTIVE' }, 5000, function (err) { | ||
if (err) { | ||
console.dir(err); | ||
return; | ||
} | ||
console.log('SERVER INFO'); | ||
console.log(server.name); | ||
console.log(server.status); | ||
console.log(server.id); | ||
console.log('Make sure you DELETE server: ' + server.id + | ||
' in order to not accrue billing charges'); | ||
}); | ||
} |
@@ -9,6 +9,6 @@ /* | ||
var async = require('async'), | ||
request = require('request'), | ||
base = require('../../../core/storage'), | ||
pkgcloud = require('../../../../../lib/pkgcloud'), | ||
storage = pkgcloud.providers.amazon.storage; | ||
request = require('request'), | ||
base = require('../../../core/storage'), | ||
pkgcloud = require('../../../../../lib/pkgcloud'), | ||
storage = pkgcloud.providers.amazon.storage; | ||
@@ -18,3 +18,3 @@ // | ||
// #### @callback {function} Continuation to respond to when complete. | ||
// Gets all Rackspace Cloudfiles containers for this instance. | ||
// Gets all AWS S3 containers for this instance. | ||
// | ||
@@ -45,3 +45,3 @@ exports.getContainers = function (callback) { | ||
// #### @callback {function} Continuation to respond to when complete. | ||
// Responds with the Rackspace Cloudfiles container for the specified | ||
// Responds with the AWS S3 container for the specified | ||
// `container`. | ||
@@ -51,3 +51,3 @@ // | ||
var containerName = container instanceof storage.Container ? container.name : container, | ||
self = this; | ||
self = this; | ||
@@ -65,5 +65,5 @@ this.xmlRequest({ | ||
// ### function createContainer (container, callback) | ||
// #### @container {string|Container} Container to create in Rackspace Cloudfiles. | ||
// #### @container {string|Container} Container to create in AWS S3. | ||
// #### @callback {function} Continuation to respond to when complete. | ||
// Creates the specified `container` in the Rackspace Cloudfiles associated | ||
// Creates the specified `container` in AWS S3 account associated | ||
// with this instance. | ||
@@ -73,3 +73,3 @@ // | ||
var containerName = container instanceof base.Container ? container.name : container, | ||
self = this; | ||
self = this; | ||
@@ -94,3 +94,3 @@ this.xmlRequest({ | ||
var containerName = container instanceof base.Container ? container.name : container, | ||
self = this; | ||
self = this; | ||
@@ -108,5 +108,5 @@ this.getFiles(containerName, false, function (err, files) { | ||
self.xmlRequest({ | ||
method: 'DELETE', | ||
container: containerName | ||
}, function (err, body, res) { | ||
method: 'DELETE', | ||
container: containerName | ||
}, function (err, body, res) { | ||
return err | ||
@@ -113,0 +113,0 @@ ? callback(err) |
@@ -40,4 +40,8 @@ /* | ||
if (this.protocol === 'https://') { | ||
this.before.push(function(req, options) { | ||
req.agent = new https.Agent({host: this.serversUrl, key: options.key, cert: options.cert}); | ||
this.before.push(function (req) { | ||
req.agent = new https.Agent({ | ||
host: this.serversUrl, | ||
key: options.key, | ||
cert: options.cert | ||
}); | ||
}); | ||
@@ -44,0 +48,0 @@ } |
@@ -52,3 +52,2 @@ /* | ||
body = _.template(template, params); | ||
//console.log(body); | ||
headers['content-length'] = body.length; | ||
@@ -55,0 +54,0 @@ self.request({ |
@@ -187,3 +187,2 @@ /* | ||
//console.log(body); | ||
options.headers['content-length'] = body.length; | ||
@@ -190,0 +189,0 @@ |
@@ -287,3 +287,2 @@ /** | ||
body = _.template(template, params); | ||
//console.log(body); | ||
headers['content-length'] = body.length; | ||
@@ -290,0 +289,0 @@ headers['content-type'] = 'application/xml'; |
@@ -84,4 +84,2 @@ /** | ||
//console.log(stringToSign) | ||
req.headers[HeaderConstants.AUTHORIZATION] = 'SharedKey ' + this.storageAccount + ':' + signature; | ||
@@ -88,0 +86,0 @@ }; |
@@ -85,3 +85,2 @@ /* | ||
function sendRequest(opts) { | ||
@@ -113,4 +112,2 @@ | ||
//console.log((opts.method ? opts.method : 'GET') + ': ' + opts.uri + (opts.qs ? '?' + qs.encode(opts.qs) : '')); | ||
// Clean up our polluted options | ||
@@ -130,5 +127,7 @@ // | ||
try { | ||
self.emit('log::debug', 'Sending (non-callback) client request', opts); | ||
return request(opts); | ||
} // if request throws still return an EE | ||
catch (exc1) { | ||
self.emit('log::error', 'Unable to create (non-callback) request', opts); | ||
return errs.handle(exc1); | ||
@@ -138,4 +137,6 @@ } | ||
try { | ||
self.emit('log::debug', 'Sending client request', opts); | ||
return request(opts, self.defaultRequestHandler(callback)); | ||
} catch (exc2) { | ||
self.emit('log::error', 'Unable to create request', opts); | ||
return errs.handle(exc2, callback); | ||
@@ -149,7 +150,7 @@ } | ||
Client.prototype.defaultRequestHandler = function(callback) { | ||
Client.prototype.defaultRequestHandler = function (callback) { | ||
var self = this; | ||
return function(err, res, body) { | ||
return function (err, res, body) { | ||
if (err) { | ||
@@ -169,4 +170,7 @@ return callback(err); | ||
failCode: self.failCodes[statusCode], | ||
statusCode: res.statusCode, | ||
message: self.provider + ' Error (' + | ||
statusCode + '): ' + self.failCodes[statusCode] | ||
statusCode + '): ' + self.failCodes[statusCode], | ||
href: res.request.uri.href, | ||
method: res.request.method | ||
}; | ||
@@ -180,7 +184,14 @@ | ||
self.emit('log::error', 'Error during provider response', err2); | ||
return callback(errs.create(err2)); | ||
} | ||
self.emit('log::debug', 'Provider Response', { | ||
href: res.request.uri.href, | ||
method: res.request.method, | ||
statusCode: res.statusCode | ||
}); | ||
callback(err, body, res); | ||
} | ||
}; |
@@ -25,2 +25,7 @@ /* | ||
var Client = exports.Client = function (options) { | ||
options.earlyTokenTimeout = typeof options.earlyTokenTimeout === 'number' | ||
? options.earlyTokenTimeout | ||
: (1000 * 60 * 5); | ||
base.Client.call(this, options); | ||
@@ -102,3 +107,3 @@ | ||
self.identity = auth; | ||
self.authorized = true; | ||
callback(); | ||
@@ -138,11 +143,15 @@ }); | ||
if (!self.authorized) { | ||
if (!self.isAuthorized()) { | ||
self.emit('log::debug', 'Not-Authenticated, inlining Auth...'); | ||
var buf = ps().pause(); | ||
self.auth(function (err) { | ||
if (err) { | ||
return callback(err); | ||
self.emit('log::error', 'Error with inline authentication', err); | ||
return errs.handle(err, callback); | ||
} | ||
self.emit('log::debug', 'Creating Authenticated Proxy Request'); | ||
var apiStream = Client.super_.prototype._doRequest.call(self, options, callback); | ||
@@ -163,4 +172,19 @@ | ||
else { | ||
self.emit('log::debug', 'Creating Authenticated Request'); | ||
return Client.super_.prototype._doRequest.call(self, options, callback); | ||
} | ||
}; | ||
}; | ||
Client.prototype.isAuthorized = function () { | ||
var self = this, | ||
authorized = false; | ||
if (!self.identity || !self.identity.token || !self.identity.token.id || !self.identity.token.expires) { | ||
authorized = false; | ||
} | ||
else if (self.identity.token.expires.getTime() - new Date().getTime() > self.config.earlyTokenTimeout) { | ||
authorized = true; | ||
} | ||
return authorized; | ||
} |
@@ -8,5 +8,6 @@ /* | ||
var utile = require('utile'), | ||
urlJoin = require('url-join'),s | ||
openstack = require('../../client'); | ||
var utile = require('utile'), | ||
openstack = require('../../client'), | ||
ComputeClient = require('../computeClient').ComputeClient, | ||
_ = require('underscore'); | ||
@@ -20,45 +21,12 @@ var Client = exports.Client = function (options) { | ||
utile.mixin(this, require('./keys')); | ||
this.serviceType = 'compute'; | ||
}; | ||
utile.inherits(Client, openstack.Client); | ||
_.extend(Client.prototype, ComputeClient.prototype); | ||
Client.prototype.getUrl = function (options) { | ||
options = options || {}; | ||
return urlJoin(this.getServiceUrl('compute'), | ||
typeof options === 'string' | ||
? options | ||
: options.path); | ||
}; | ||
// | ||
// Gets the version of the OpenStack Compute API we are running against | ||
// Parameters: callback | ||
// | ||
Client.prototype.getVersion = function getVersion(callback) { | ||
var self = this, | ||
verbose; | ||
this.auth(function (err) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
self.request({ | ||
uri: self.getUrl('/').replace(self.identity.token.tenant.id + '/', '') | ||
}, function (err, body) { | ||
if (err) { return callback(err); } | ||
verbose = ((typeof body === 'object') ? body.version : JSON.parse(body).version); | ||
return callback(null, verbose.id, verbose); | ||
}); | ||
}); | ||
}; | ||
Client.prototype.getOsFloatingIps = function (callback) { | ||
this.request({ | ||
path: 'os-floating-ips' | ||
}, function (err, body, res) { | ||
return err | ||
? callback(err) | ||
: callback(null, body.floating_ips); | ||
this.request('os-floating-ips', callback, function (body, res) { | ||
return callback(null, body.floating_ips); | ||
}); | ||
@@ -76,1 +44,2 @@ }; | ||
}; | ||
@@ -220,3 +220,3 @@ /* | ||
// Data integrity check, make sure we got the right user back | ||
if (self.options.username !== data.access.user.username) { | ||
if (self.options.username !== data.access.user.name) { | ||
return callback(new Error('Username did not match provided username!')); | ||
@@ -223,0 +223,0 @@ } |
@@ -9,5 +9,2 @@ /* | ||
// TODO node.js doesn't always gracefully handle exceptions, so we may need | ||
// TODO revisit how we expose invalid input errors | ||
var _ = require('underscore'); | ||
@@ -14,0 +11,0 @@ |
@@ -9,28 +9,13 @@ /* | ||
var utile = require('utile'), | ||
request = require('request'), | ||
ps = require('pause-stream'), | ||
auth = require('../common/auth'), | ||
base = require('../core/base'), | ||
pkgcloud = require('../../pkgcloud'); | ||
identity = require('./identity'), | ||
base = require('../openstack/client'); | ||
var Client = exports.Client = function (options) { | ||
options = options || {}; | ||
options.authUrl = options.authUrl || 'https://identity.api.rackspacecloud.com'; | ||
options.region = options.region || 'DFW'; | ||
base.Client.call(this, options); | ||
this.authUrl = options.authUrl || 'auth.api.rackspacecloud.com'; | ||
this.serversUrl = options.serversUrl || 'servers.api.rackspacecloud.com'; | ||
this.protocol = options.protocol || 'https://'; | ||
this.provider = 'rackspace'; | ||
if (!this.before) { | ||
this.before = []; | ||
} | ||
this.before.push(auth.authToken); | ||
this.before.push(function (req) { | ||
req.json = true; | ||
if (typeof req.body !== 'undefined') { | ||
req.headers['Content-Type'] = 'application/json'; | ||
req.body = JSON.stringify(req.body); | ||
} | ||
}); | ||
this.provider = 'rackspace'; | ||
}; | ||
@@ -40,92 +25,31 @@ | ||
Client.prototype.failCodes = { | ||
400: 'Bad Request', | ||
401: 'Unauthorized', | ||
403: 'Resize not allowed', | ||
404: 'Item not found', | ||
409: 'Build in progress', | ||
413: 'Over Limit', | ||
415: 'Bad Media Type', | ||
500: 'Fault', | ||
503: 'Service Unavailable' | ||
}; | ||
Client.prototype.successCodes = { | ||
200: 'OK', | ||
201: 'Created', | ||
202: 'Accepted', | ||
203: 'Non-authoritative information', | ||
204: 'No content' | ||
}; | ||
Client.prototype.auth = function (callback) { | ||
var self = this, | ||
authOptions; | ||
options = { | ||
url: self.authUrl, | ||
username: self.config.username, | ||
password: self.config.password, | ||
apiKey: self.config.apiKey, | ||
region: self.region | ||
authOptions = { | ||
uri: this.protocol + this.authUrl + '/v1.0', | ||
headers: { | ||
'HOST': this.authUrl, | ||
'X-AUTH-USER': this.config.username, | ||
'X-AUTH-KEY': this.config.apiKey, | ||
'User-Agent': utile.format('nodejs-pkgcloud/%s', pkgcloud.version) | ||
} | ||
}; | ||
}; | ||
request(authOptions, self.defaultRequestHandler(function(err, body, res) { | ||
if (self.config.tenantId) { | ||
options.tenantId = self.config.tenantId; | ||
} | ||
else if (self.config.tenantName) { | ||
options.tenantName = self.config.tenantName; | ||
} | ||
identity.createIdentity(options, function (err, auth) { | ||
if (err) { | ||
return callback(err); | ||
callback(err); | ||
return; | ||
} | ||
self.authorized = true; | ||
self.config.serverUrl = res.headers['x-server-management-url']; | ||
self.config.storageUrl = res.headers['x-storage-url']; | ||
self.config.cdnUrl = res.headers['x-cdn-management-url']; | ||
self.config.authToken = res.headers['x-auth-token']; | ||
self.identity = auth; | ||
callback(null, res); | ||
})); | ||
callback(); | ||
}); | ||
}; | ||
Client.prototype.getServiceUrl = function (service) { | ||
var serviceName = service + 'Url'; | ||
return this.config[serviceName]; | ||
}; | ||
Client.prototype._doRequest = function (options, callback) { | ||
var self = this; | ||
// | ||
// If this instance is not yet authorized, then return | ||
// a `BufferedStream` which can be piped to in the current | ||
// tick. | ||
// | ||
if (!self.authorized) { | ||
var buf = ps().pause(); | ||
self.auth(function (err) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
var apiStream = Client.super_.prototype._doRequest.call(self, options, callback); | ||
if (options.upload) { | ||
buf.pipe(apiStream); | ||
} | ||
else if (options.download) { | ||
apiStream.pipe(buf); | ||
} | ||
buf.resume(); | ||
}); | ||
return buf; | ||
} | ||
else { | ||
return Client.super_.prototype._doRequest.call(self, options, callback); | ||
} | ||
}; |
@@ -8,5 +8,6 @@ /* | ||
var utile = require('utile'), | ||
urlJoin = require('url-join'), | ||
rackspace = require('../../client'); | ||
var utile = require('utile'), | ||
rackspace = require('../../client'), | ||
ComputeClient = require('../../../openstack/compute/computeClient').ComputeClient, | ||
_ = require('underscore'); | ||
@@ -16,25 +17,23 @@ var Client = exports.Client = function (options) { | ||
utile.mixin(this, require('./flavors')); | ||
utile.mixin(this, require('./images')); | ||
utile.mixin(this, require('./servers')); | ||
utile.mixin(this, require('../../../openstack/compute/client/flavors')); | ||
utile.mixin(this, require('../../../openstack/compute/client/images')); | ||
utile.mixin(this, require('../../../openstack/compute/client/servers')); | ||
utile.mixin(this, require('../../../openstack/compute/client/keys')); | ||
this.serviceType = 'compute'; | ||
}; | ||
utile.inherits(Client, rackspace.Client); | ||
_.extend(Client.prototype, ComputeClient.prototype); | ||
Client.prototype.bootstrapOptions = function (options, keys) { | ||
return { | ||
personality: [{ | ||
path: '/root/.ssh/authorized_keys', | ||
contents: keys['public'].base64 | ||
}] | ||
personality: [ | ||
{ | ||
path: '/root/.ssh/authorized_keys', | ||
contents: keys['public'].base64 | ||
} | ||
] | ||
}; | ||
}; | ||
Client.prototype.getUrl = function (options) { | ||
options = options || {}; | ||
return urlJoin(this.config.serverUrl || 'http://servers.api.rackspacecloud.com', | ||
typeof options === 'string' | ||
? options | ||
: options.path); | ||
}; |
@@ -9,5 +9,5 @@ /* | ||
exports.Client = require('./client').Client; | ||
exports.Flavor = require('./flavor').Flavor; | ||
exports.Image = require('./image').Image; | ||
exports.Server = require('./server').Server; | ||
exports.Flavor = require('../../openstack/compute/flavor').Flavor; | ||
exports.Image = require('../../openstack/compute/image').Image; | ||
exports.Server = require('../../openstack/compute/server').Server; | ||
@@ -14,0 +14,0 @@ exports.createClient = function (options) { |
@@ -13,3 +13,3 @@ /* | ||
auth = require('../../../common/auth.js'), | ||
pkgcloud = require('../../../../pkgcloud'); | ||
_ = require('underscore'); | ||
@@ -26,3 +26,3 @@ var Client = exports.Client = function (options) { | ||
this.databaseUrl = options.databaseUrl || 'ord.databases.api.rackspacecloud.com'; | ||
this.serviceType = 'rax:database'; | ||
}; | ||
@@ -32,87 +32,34 @@ | ||
Client.prototype.getUrl = function url(options) { | ||
Client.prototype.getUrl = function (options) { | ||
options = options || {}; | ||
return urlJoin([ | ||
this.protocol + this.databaseUrl, | ||
'v1.0', | ||
((this.config.accountNumber) ? this.config.accountNumber : '') | ||
].join('/'), (typeof options === 'string' ? | ||
options : options.path)); | ||
}; | ||
return urlJoin(this.getServiceUrl(this.serviceType), | ||
typeof options === 'string' | ||
? options | ||
: options.path); | ||
// Using own auth for Databases Client | ||
Client.prototype.auth = function auth(callback) { | ||
var self = this; | ||
var authOptions = { | ||
uri: this.protocol + this.authUrl + '/v1.1/auth', | ||
headers: { | ||
'HOST': this.authUrl, | ||
'X-AUTH-USER': this.config.username, | ||
'X-AUTH-KEY': this.config.apiKey, | ||
'User-Agent': utile.format('nodejs-pkgcloud/%s', pkgcloud.version) | ||
}, | ||
body: { | ||
"credentials": { | ||
"username": this.config.username, | ||
"key": this.config.apiKey | ||
} | ||
}, | ||
json: true, | ||
method: 'POST' | ||
}; | ||
function serviceDefault(server) { | ||
return (server.v1Default); | ||
} | ||
request(authOptions, function (err, res, body) { | ||
if (err) return callback(err); | ||
if (res.body.unauthorized && | ||
res.body.unauthorized.message) return callback(res.body); | ||
var headers = {}, | ||
services = body.auth.serviceCatalog, | ||
isDefault = function (server) { return server.v1Default; }, | ||
getUrl = function (list) { var selected = list.filter(isDefault)[0]; return selected.publicURL; }, | ||
servers = {"cdnUrl": getUrl(services.cloudFilesCDN), | ||
"storageUrl": getUrl(services.cloudFiles), | ||
"serverUrl": getUrl(services.cloudServers) | ||
}; | ||
if (res.statusCode === 200 && body.auth) { | ||
self.authorized = true; | ||
self.config.authToken = body.auth.token.id; | ||
self.config.accountNumber = servers.serverUrl.split('/').pop(); | ||
utile.mixin(self.config, servers); | ||
// Compatibility with v1.0 tests | ||
headers['x-server-management-url'] = servers.serverUrl; | ||
headers['x-storage-url'] = servers.storageUrl; | ||
headers['x-cdn-management-url'] = servers.cdnUrl; | ||
headers['x-auth-token'] = body.auth.token.id; | ||
utile.mixin(res.headers, headers); | ||
} | ||
callback(err, res); | ||
}); | ||
}; | ||
// | ||
// Gets the version of the Rackspace CloudServers API we are running against | ||
// Gets the version of the OpenStack Compute API we are running against | ||
// Parameters: callback | ||
// | ||
Client.prototype.getVersion = function getVersion(callback) { | ||
var versionOptions = { | ||
uri: this.protocol + this.serversUrl, | ||
headers: { | ||
'User-Agent': utile.format('nodejs-pkgcloud/%s', pkgcloud.version) | ||
var self = this; | ||
this.auth(function (err) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
}; | ||
request(versionOptions, function (err, res, body) { | ||
return callback(null, | ||
((typeof body === 'object') ? body.versions : JSON.parse(body).versions)); | ||
self.request({ | ||
uri: self.getUrl('/').replace('/v1.0/' + self.identity.token.tenant.id + '/', '') | ||
}, function (err, body) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
return callback(null, | ||
((typeof body === 'object') ? body.versions : JSON.parse(body).versions)); | ||
}); | ||
}); | ||
}; |
@@ -9,3 +9,3 @@ /* | ||
var utile = require('utile'), | ||
base = require('../compute/flavor'); | ||
base = require('../../openstack/compute/flavor'); | ||
@@ -12,0 +12,0 @@ var Flavor = exports.Flavor = function Flavor(client, details) { |
@@ -154,9 +154,9 @@ /* | ||
exports.getFiles = function (container, download, callback) { | ||
exports.getFiles = function (container, options, callback) { | ||
var containerName = container instanceof base.Container ? container.name : container, | ||
self = this; | ||
if (typeof download == 'function' && !(download instanceof RegExp)) { | ||
callback = download; | ||
download = false; | ||
if (typeof options === 'function') { | ||
callback = options; | ||
options = null; | ||
} | ||
@@ -163,0 +163,0 @@ |
@@ -16,4 +16,5 @@ /* | ||
utile.mixin(this, require('./containers')); | ||
utile.mixin(this, require('./directories')); | ||
utile.mixin(this, require('./files')); | ||
this.serviceType = 'object-store'; | ||
}; | ||
@@ -27,6 +28,6 @@ | ||
if (!options || options === '' || options.path === '') { | ||
return this.getServiceUrl('storage'); | ||
return this.getServiceUrl(this.serviceType); | ||
} | ||
return urlJoin(this.getServiceUrl('storage'), (typeof options === 'string' ? | ||
return urlJoin(this.getServiceUrl(this.serviceType), (typeof options === 'string' ? | ||
options : options.path)); | ||
@@ -33,0 +34,0 @@ }; |
@@ -10,3 +10,2 @@ /* | ||
exports.Container = require('./container').Container; | ||
exports.Directory = require('./directory').Directory; | ||
exports.File = require('./file').File; | ||
@@ -13,0 +12,0 @@ |
{ | ||
"name": "pkgcloud", | ||
"description": "An infrastructure-as-a-service agnostic cloud library for node.js", | ||
"version": "0.7.3", | ||
"version": "0.8.0", | ||
"author": "Nodejitsu Inc <info@nodejitsu.com>", | ||
@@ -45,5 +45,5 @@ "contributors": [ | ||
"devDependencies": { | ||
"hock" : "0.1.x", | ||
"mocha": "1.9.x", | ||
"should": "1.2.x", | ||
"hock" : "0.1.x" | ||
"should": "1.2.x" | ||
}, | ||
@@ -50,0 +50,0 @@ "main": "./lib/pkgcloud", |
@@ -66,3 +66,3 @@ # pkgcloud [![Build Status](https://secure.travis-ci.org/nodejitsu/pkgcloud.png?branch=master)](http://travis-ci.org/nodejitsu/pkgcloud) [![NPM version](https://badge.fury.io/js/pkgcloud.png)](http://badge.fury.io/js/pkgcloud) | ||
Due to the differences between the vocabulary for each service provider, **[pkgcloud uses its own unified vocabulary](https://github.com/nodejitsu/pkgcloud/blob/master/docs/vocabulary.md).** | ||
Due to the differences between the vocabulary for each service provider, **[pkgcloud uses its own unified vocabulary](docs/vocabulary.md).** | ||
@@ -78,16 +78,16 @@ * **Compute:** [Server](#server), [Image](#image), [Flavor](#flavor) | ||
* **[Compute](#compute)** | ||
* [Joyent](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/joyent.md#using-compute) | ||
* [Azure](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/azure.md#using-compute) | ||
* [Rackspace](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/rackspace.md#using-compute) | ||
* [Amazon](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/amazon.md#using-compute) | ||
* [Joyent](docs/providers/joyent.md#using-compute) | ||
* [Azure](docs/providers/azure.md#using-compute) | ||
* [Rackspace](docs/providers/rackspace/compute.md) | ||
* [Amazon](docs/providers/amazon.md#using-compute) | ||
* **[Storage](#storage)** | ||
* [Azure](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/azure.md#using-storage) | ||
* [Rackspace](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/rackspace.md#using-storage) | ||
* [Amazon](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/amazon.md#using-storage) | ||
* [Azure](docs/providers/azure.md#using-storage) | ||
* [Rackspace](docs/providers/rackspace/storage.md) | ||
* [Amazon](docs/providers/amazon.md#using-storage) | ||
* **[Database](#database)** | ||
* [IrisCouch](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/iriscouch.md) | ||
* [MongoLab](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/mongolab.md) | ||
* [Rackspace](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/rackspace.md#database) | ||
* [MongoHQ](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/mongohq.md) | ||
* [RedisToGo](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/redistogo.md) | ||
* [IrisCouch](docs/providers/iriscouch.md) | ||
* [MongoLab](docs/providers/mongolab.md) | ||
* [Rackspace](docs/providers/rackspace/database.md) | ||
* [MongoHQ](docs/providers/mongohq.md) | ||
* [RedisToGo](docs/providers/redistogo.md) | ||
@@ -114,6 +114,6 @@ <a name="compute"></a> | ||
* [Joyent](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/joyent.md#using-compute) | ||
* [Azure](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/azure.md#using-compute) | ||
* [Rackspace](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/rackspace.md#using-compute) | ||
* [Amazon](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/amazon.md#using-compute) | ||
* [Joyent](docs/providers/joyent.md#using-compute) | ||
* [Azure](docs/providers/azure.md#using-compute) | ||
* [Rackspace](docs/providers/rackspace/compute.md) | ||
* [Amazon](docs/providers/amazon.md#using-compute) | ||
@@ -164,5 +164,5 @@ Each instance of `pkgcloud.compute.Client` returned from `pkgcloud.compute.createClient` has a set of uniform APIs: | ||
* [Azure](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/azure.md#using-storage) | ||
* [Rackspace](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/rackspace.md#using-storage) | ||
* [Amazon](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/amazon.md#using-storage) | ||
* [Azure](docs/providers/azure.md#using-storage) | ||
* [Rackspace](docs/providers/rackspace/storage.md) | ||
* [Amazon](docs/providers/amazon.md#using-storage) | ||
@@ -237,13 +237,13 @@ Each instance of `pkgcloud.storage.Client` returned from `pkgcloud.storage.createClient` has a set of uniform APIs: | ||
* **CouchDB** | ||
* [IrisCouch](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/iriscouch.md#couchdb) | ||
* [IrisCouch](docs/providers/iriscouch.md#couchdb) | ||
* **MongoDB** | ||
* [MongoLab](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/mongolab.md) | ||
* [MongoHQ](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/mongohq.md) | ||
* [MongoLab](docs/providers/mongolab.md) | ||
* [MongoHQ](docs/providers/mongohq.md) | ||
* **Redis** | ||
* [IrisCouch](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/iriscouch.md#redis) | ||
* [RedisToGo](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/redistogo.md) | ||
* [IrisCouch](docs/providers/iriscouch.md#redis) | ||
* [RedisToGo](docs/providers/redistogo.md) | ||
* **MySQL** | ||
* [Rackspace](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/rackspace.md#database) | ||
* [Rackspace](docs/providers/rackspace/databases.md) | ||
* **Azure Tables** | ||
* [Azure](https://github.com/nodejitsu/pkgcloud/blob/master/docs/providers/azure.md#database) | ||
* [Azure](docs/providers/azure.md#database) | ||
@@ -332,3 +332,3 @@ Due to the various differences in how these DBaaS providers provision databases only a small surface area of the API for instances of `pkgcloud.database.Client` returned from `pkgcloud.database.createClient` is consistent across all providers: | ||
## Contribute! | ||
We welcome contribution to `pkgcloud` by any and all individuals or organizations. Before contributing please take a look at the [Contribution Guidelines in CONTRIBUTING.md](https://github.com/nodejitsu/pkgcloud/blob/master/CONTRIBUTING.md). | ||
We welcome contribution to `pkgcloud` by any and all individuals or organizations. Before contributing please take a look at the [Contribution Guidelines in CONTRIBUTING.md](CONTRIBUTING.md). | ||
@@ -335,0 +335,0 @@ We are pretty flexible about these guidelines, but the closer you follow them the more likely we are to merge your pull-request. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
188
437832
12685