Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

pkgcloud

pkgcloud32.1k2.2.0TypeScript support: definitely-typed

A provider agnostic cloud library for Node.js

cloud, cloud computing, api, rackspace, aws, amazon, azure, google, iaas, servers, compute, storage, client, openstack, hpcloud, hp, helion

readme

pkgcloud Build Status NPM version

Join the chat at https://gitter.im/pkgcloud/pkgcloud

pkgcloud is a standard library for node.js that abstracts away differences among multiple cloud providers.

Getting Started

You can install pkgcloud via npm or add to it to dependencies in your package.json file:

npm install pkgcloud

Currently there are nine service types which are handled by pkgcloud:

In our Roadmap, we plan to add support for more services, such as Queueing, Monitoring, and more. Additionally, we plan to implement more providers for the beta services, thus moving them out of beta.

User Agent

By default, all pkgcloud HTTP requests will have a user agent with the library and version: nodejs-pkgcloud/x.y.z where x.y.z is the current version.

You can get this from a client at any time by calling client.getUserAgent();. Some providers may have an additional suffix as a function of the underlying HTTP stacks.

You can also set a custom User Agent prefix:

client.setCustomUserAgent('my-app/1.2.3');

// returns "my-app/1.2.3 nodejs-pkgcloud/1.1.0"
client.getUserAgent();

Basic APIs for pkgcloud

Services provided by pkgcloud are exposed in two ways:

  • By service type: For example, if you wanted to create an API client to communicate with a compute service you could simply:
  var client = require('pkgcloud').compute.createClient({
    //
    // The name of the provider (e.g. "openstack")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });
  • By provider name: For example, if you knew the name of the provider you wished to communicate with you could do so directly:
  var client = require('pkgcloud').providers.openstack.compute.createClient({
    //
    // ... Provider specific credentials
    //
  });

All API clients exposed by pkgcloud can be instantiated through pkgcloud[serviceType].createClient({ ... }) or pkcloud.providers[provider][serviceType].createClient({ ... }).

Unified Vocabulary

Due to the differences between the vocabulary for each service provider, pkgcloud uses its own unified vocabulary.

Note: Unified vocabularies may not yet be defined for beta services.

Supported APIs

Supporting every API for every cloud service provider in Node.js is a huge undertaking, but that is the long-term goal of pkgcloud. Special attention has been made to ensure that each service type has enough providers for a critical mass of portability between providers (i.e. Each service implemented has multiple providers).

If a service does not have at least two providers, it is considered a beta interface; We reserve the right to improve the API as multiple providers will allow generalization to be better determined.

Compute

The pkgcloud.compute service is designed to make it easy to provision and work with VMs. To get started with a pkgcloud.compute client just create one:

  var client = require('pkgcloud').compute.createClient({
    //
    // The name of the provider (e.g. "openstack")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Each compute provider takes different credentials to authenticate; these details about each specific provider can be found below:

Each instance of pkgcloud.compute.Client returned from pkgcloud.compute.createClient has a set of uniform APIs:

Server

  • client.getServers(function (err, servers) { })
  • client.createServer(options, function (err, server) { })
  • client.destroyServer(serverId, function (err, server) { })
  • client.getServer(serverId, function (err, server) { })
  • client.rebootServer(server, function (err, server) { })

Image

  • client.getImages(function (err, images) { })
  • client.getImage(imageId, function (err, image) { })
  • client.destroyImage(image, function (err, ok) { })
  • client.createImage(options, function (err, image) { })

Flavor

  • client.getFlavors(function (err, flavors) { })
  • client.getFlavor(flavorId, function (err, flavor) { })

Storage

The pkgcloud.storage service is designed to make it easy to upload and download files to various infrastructure providers. Special attention has been paid so that methods are streams and pipe-capable.

To get started with a pkgcloud.storage client just create one:

  var client = require('pkgcloud').storage.createClient({
    //
    // The name of the provider (e.g. "openstack")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Each storage provider takes different credentials to authenticate; these details about each specific provider can be found below:

Each instance of pkgcloud.storage.Client returned from pkgcloud.storage.createClient has a set of uniform APIs:

Container

  • client.getContainers(function (err, containers) { })
  • client.createContainer(options, function (err, container) { })
  • client.destroyContainer(containerName, function (err) { })
  • client.getContainer(containerName, function (err, container) { })

File

  • client.upload(options)
  • client.download(options, function (err) { })
  • client.getFiles(container, function (err, files) { })
  • client.getFile(container, file, function (err, server) { })
  • client.removeFile(container, file, function (err) { })

Both the .upload(options) and .download(options) have had careful attention paid to make sure they are pipe and stream capable:

Upload a File

  var pkgcloud = require('pkgcloud'),
      fs = require('fs');

  var client = pkgcloud.storage.createClient({ /* ... */ });

  var readStream = fs.createReadStream('a-file.txt');
  var writeStream = client.upload({
    container: 'a-container',
    remote: 'remote-file-name.txt'
  });

  writeStream.on('error', function(err) {
    // handle your error case
  });

  writeStream.on('success', function(file) {
    // success, file will be a File model
  });

  readStream.pipe(writeStream);

Download a File

  var pkgcloud = require('pkgcloud'),
      fs = require('fs');

  var client = pkgcloud.storage.createClient({ /* ... */ });

  client.download({
    container: 'a-container',
    remote: 'remote-file-name.txt'
  }).pipe(fs.createWriteStream('a-file.txt'));

Databases

The pkgcloud.database service is designed to consistently work with a variety of Database-as-a-Service (DBaaS) providers.

To get started with a pkgcloud.storage client just create one:

  var client = require('pkgcloud').database.createClient({
    //
    // The name of the provider (e.g. "openstack")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Each database provider takes different credentials to authenticate; these details about each specific provider can be found below:

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:

  • client.create(options, callback)

All of the individual methods are documented for each DBaaS provider listed above.

DNS -- Beta

Note: DNS is considered Beta until there are multiple providers; presently only Rackspace are supported.

The pkgcloud.dns service is designed to make it easy to manage DNS zones and records on various infrastructure providers. Special attention has been paid so that methods are streams and pipe-capable.

To get started with a pkgcloud.dns client just create one:

  var client = require('pkgcloud').dns.createClient({
    //
    // The name of the provider (e.g. "rackspace")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Providers

Each instance of pkgcloud.dns.Client returned from pkgcloud.dns.createClient has a set of uniform APIs:

Zone

  • client.getZones(details, function (err, zones) { })
  • client.getZone(zone, function (err, zone) { })
  • client.createZone(details, function (err, zone) { })
  • client.updateZone(zone, function (err) { })
  • client.deleteZone(zone, function (err) { })

Record

  • client.getRecords(zone, function (err, records) { })
  • client.getRecord(zone, record, function (err, record) { })
  • client.createRecord(zone, record, function (err, record) { })
  • client.updateRecord(zone, record, function (err, record) { })
  • client.deleteRecord(zone, record, function (err) { })

Block Storage -- Beta

Note: Block Storage is considered Beta until there are multiple providers; presently only Openstack and Rackspace are supported.

The pkgcloud.blockstorage service is designed to make it easy to create and manage block storage volumes and snapshots.

To get started with a pkgcloud.blockstorage client just create one:

  var client = require('pkgcloud').blockstorage.createClient({
    //
    // The name of the provider (e.g. "rackspace")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Providers

Each instance of pkgcloud.blockstorage.Client returned from pkgcloud.blockstorage.createClient has a set of uniform APIs:

Volume

  • client.getVolumes(options, function (err, volumes) { })
  • client.getVolume(volume, function (err, volume) { })
  • client.createVolume(details, function (err, volume) { })
  • client.updateVolume(volume, function (err, volume) { })
  • client.deleteVolume(volume, function (err) { })

Snapshot

  • client.getSnapshots(options, function (err, snapshots) { })
  • client.getSnapshot(snapshot, function (err, snapshot) { })
  • client.createSnapshot(details, function (err, snapshot) { })
  • client.updateSnapshot(snapshot, function (err, snapshot) { })
  • client.deleteSnapshot(snapshot, function (err) { })

Load Balancers -- Beta

Note: Load Balancers is considered Beta until there are multiple providers; presently only Rackspace are supported.

The pkgcloud.loadbalancer service is designed to make it easy to create and manage block storage volumes and snapshots.

To get started with a pkgcloud.loadbalancer client just create one:

  var client = require('pkgcloud').loadbalancer.createClient({
    //
    // The name of the provider (e.g. "rackspace")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Providers

Each instance of pkgcloud.loadbalancer.Client returned from pkgcloud.loadbalancer.createClient has a set of uniform APIs:

LoadBalancers

  • client.getLoadBalancers(options, function (err, loadBalancers) { })
  • client.getLoadBalancer(loadBalancer, function (err, loadBalancer) { })
  • client.createLoadBalancer(details, function (err, loadBalancer) { })
  • client.updateLoadBalancer(loadBalancer, function (err) { })
  • client.deleteLoadBalancer(loadBalancer, function (err) { })

Nodes

  • client.getNodes(loadBalancer, function (err, nodes) { })
  • client.addNodes(loadBalancer, nodes, function (err, nodes) { })
  • client.updateNode(loadBalancer, node, function (err) { })
  • client.removeNode(loadBalancer, node, function (err) { })

Network -- Beta

Note: Network is considered Beta until there are multiple providers; presently only HP & Openstack providers are supported.

The pkgcloud.network service is designed to make it easy to create and manage networks.

To get started with a pkgcloud.network client just create one:

  var client = require('pkgcloud').network.createClient({
    //
    // The name of the provider (e.g. "openstack")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Providers

Each instance of pkgcloud.network.Client returned from pkgcloud.network.createClient has a set of uniform APIs:

Networks

  • client.getNetworks(options, function (err, networks) { })
  • client.getNetwork(network, function (err, network) { })
  • client.createNetwork(options, function (err, network) { })
  • client.updateNetwork(network, function (err, network) { })
  • client.deleteNetwork(network, function (err, networkId) { })

Subnets

  • client.getSubnets(options, function (err, subnets) { })
  • client.getSubnet(subnet, function (err, subnet) { })
  • client.createSubnet(options, function (err, subnet) { })
  • client.updateSubnet(subnet, function (err, subnet) { })
  • client.deleteSubnet(subnet, function (err, subnetId) { })

Ports

  • client.getPorts(options, function (err, ports) { })
  • client.getPort(port, function (err, port) { })
  • client.createPort(options, function (err, port) { })
  • client.updatePort(port, function (err, port) { })
  • client.deletePort(port, function (err, portId) { })

Orchestration -- Beta

Note: Orchestration is considered Beta until there are multiple providers; presently only Openstack are supported.

The pkgcloud.orchestration service is designed to allow you to access Openstack Heat via node.js. You can manage stacks and resources from within any node.js application.

To get started with a pkgcloud.orchestration client just create one:

  var client = require('pkgcloud').orchestration.createClient({
    //
    // The name of the provider (e.g. "openstack")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Providers

Each instance of pkgcloud.orchestration.Client returned from pkgcloud.orchestration.createClient has a set of uniform APIs:

Stack

  • client.getStack(stack, function (err, stack) { })
  • client.getStacks(options, function (err, stacks) { })
  • client.createStack(details, function (err, stack) { })
  • client.previewStack(details, function (err, stack) { })
  • client.adoptStack(details, function (err, stack) { })
  • client.updateStack(stack, function (err, stack) { })
  • client.deleteStack(stack, function (err) { })
  • client.abandonStack(stack, function (err, abandonedStack) { })
  • client.getTemplate(stack, function (err, template) { })

Resources

  • client.getResource(stack, resource, function (err, resource) { })
  • client.getResources(stack, function (err, resources) { })
  • client.getResourceTypes(function (err, resourceTypes) { })
  • client.getResourceSchema(resourceType, function (err, resourceSchema) { })
  • client.getResourceTemplate(resourceType, function (err, resourceTemplate) { })

Events

  • client.getEvent(stack, resource, eventId, function (err, event) { })
  • client.getEvents(stack, function (err, events) { })
  • client.getResourceEvents(stack, resource, function (err, events) { })

Templates

  • client.validateTemplate(template, function (err, template) { })

CDN -- Beta

Note: CDN is considered Beta until there are multiple providers; presently only Openstack and Rackspace are supported.

The pkgcloud.cdn service is designed to allow you to access Openstack Poppy via node.js. You can manage services and flavors from within any node.js application.

To get started with a pkgcloud.cdn client just create one:

  var client = require('pkgcloud').cdn.createClient({
    //
    // The name of the provider (e.g. "openstack")
    //
    provider: 'provider-name',

    //
    // ... Provider specific credentials
    //
  });

Providers

Each instance of pkgcloud.cdn.Client returned from pkgcloud.cdn.createClient has a set of uniform APIs:

Base

  • client.getHomeDocument(function (err, homeDocument) { })
  • client.getPing(function (err) { })

Service

  • client.getService(service, function (err, service) { })
  • client.getServices(options, function (err, services) { })
  • client.createService(details, function (err, service) { })
  • client.updateService(service, function (err, service) { })
  • client.deleteService(service, function (err) { })

Service Assets

  • client.deleteServiceCachedAssets(service, assetUrl, function(err) { })

Flavors

  • client.getFlavor(flavor, function (err, flavor) { })
  • client.getFlavors(options, function (err, flavors) { })

Installation

  $ npm install pkgcloud

Tests

To run the tests you will need `mocha@1.9.x` or higher. You may install all the requirements with:

 $ npm install

Then run the tests:

 $ npm test

The tests use the hock library for mock up the response of providers, so the tests run without do any connection to the providers, there is a notorius advantage of speed on that, also you can run the tests without Internet connection and also can highlight a change of API just disabling hock.

Running tests without mocks

By default the npm test command run the tests enabling hock. And sometimes you will want to test against the live provider, so you need to do this steps, in order to test without mocks.

  1. Copy a provider config file from test/configs/mock to test/configs
  2. Fill in with your own credentials for the provider.
  3. (Optional) The compute test suite run the common tests for all providers listed on test/configs/providers.json, there you can enable or disable providers.
  4. Run the tests using mocha.
Mocha installed globally
 $ mocha -R spec test/*/*/*-test.js test/*/*/*/*-test.js

Linux/Mac - Mocha installed locally
 $ ./node_modules/.bin/mocha -R spec test/*/*/*-test.js test/*/*/*/*-test.js

Windows - Mocha installed locally:
 $ node_modules\.bin\mocha.cmd -R spec test/*/*/*-test.js test/*/*/*/*-test.js

Other ways to run the tests

Also you can run the tests directly using mocha with hock enabled:

Linux/Mac - Mocha installed globally:
 $ MOCK=on mocha -R spec test/*/*/*-test.js test/*/*/*/*-test.js

Linux/Mac - Mocha installed locally:
 $ MOCK=on node_modules/.bin/mocha -R spec test/*/*/*-test.js test/*/*/*/*-test.js

Windows - Mocha installed globally:
 $ set MOCK=on&mocha -R spec test/*/*/*-test.js test/*/*/*/*-test.js

Windows - Mocha installed locally:
 $ set MOCK=on&node_modules\.bin\mocha.cmd -R spec test/*/*/*-test.js test/*/*/*/*-test.js

Even better, you can run the tests for some specific provider:

Linux/Mac - Mocha installed globally:
 $ MOCK=on mocha -R spec test/openstack/*/*-test.js

Linux/Mac - Mocha installed locally:
 $ MOCK=on ./node_modules/.bin/mocha -R spec test/openstack/*/*-test.js

Windows - Mocha installed globally:
 $ set MOCK=on&mocha -R spec test/openstack/*/*-test.js

Windows - Mocha installed locally:
 $ set MOCK=on&node_modules\.bin\mocha.cmd -R spec test/openstack/*/*-test.js

Logging

Any client you create with createClient can emit logging events. If you're interested in more detail from the internals of pkgcloud, you can wire up an event handler for log events.

var client = pkgcloud.compute.createClient(options);

client.on('log::*', function(message, object) {
  if (object) {
   console.log(this.event.split('::')[1] + ' ' + message);
   console.dir(object);
  }
  else {
    console.log(this.event.split('::')[1]  + ' ' + message);
  }
});

The valid log events raised are log::debug, log::verbose, log::info, log::warn, and log::error. There is also a more detailed logging example using pkgcloud with Winston.

Code Coverage

Run Coverage locally and send to coveralls.io

Travis takes care of coveralls, so this shouldn't be necessary unless you're troubleshooting a problem with Travis / Coveralls. You'll need to have access to the coveralls repo_token, which should only be visible to pkgcloud/pkgcloud admins.

  1. Create a .coveralls.yml containing the repo_token from https://coveralls.io/r/pkgcloud/pkgcloud
  2. Run the following:
    npm test
    npm run coverage

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.

We are pretty flexible about these guidelines, but the closer you follow them the more likely we are to merge your pull-request.

Author: Charlie Robbins

Contributors: Ross Kukulinski, Jarrett Cruger, Ken Perkins

License: MIT

changelog

CHANGELOG

v2.2.0

  • [#678] [@jcrugzz] support more aws auth scenarios via credentials object or sessionToken.

v2.1.1

  • [#666], [@guischdi] Fix GCS upload.

v2.1.0

  • Add content encoding option for s3 upload

v2.0.0

  • [BREAKING] Drop all legacy providers.
  • Update dependencies.
  • Documentation fixes.
    • Fix broken links to databases.md
    • Replace Openstack with OpenStack
    • Fix page title markdown formatting
  • this.protocol from client instance is used as the URL protocol as it should be. Fixes [#526].

v1.7.0

  • Amazon use native aws-sdk for s3 uploads instead of s3-upload-stream module
  • Update the aws-sdk to 2.382.0
  • Amazon storage client.upload - expose concurrency - queueSize and partSize configurability and add ability to abort an upload

v1.6.0

  • Equivalent to v1.5.0.

v1.5.0

  • Added 1&1 support with tests.
  • Set Content-Type with Google storage. Fixes [#635].
  • Attempt to restrict to node@6 and node@8.
  • [fix] Patched RegEx DoS vuln & Remote Memory Exposure vuln. This addresses two major security issues:
  • Fix typo in OpenStack createSecurityGroupRule. Fixes [#556].
  • Fix typo in createSecurityGroup. Fixes [#454].
  • Fix breaking test due to expired auth token.

v1.4.0

  • Pass in other aws options that allow an s3 like API to be configured correctly
  • Fixing broken merge from replacing underscore with lodash

v1.3.0

  • OpenStack identity v3 (keystone) support, Issue #367, #477, PR #461
  • OpenStack cancel client download, Issue #379, PR #416
  • OpenStack improved directory support for getFiles, PR #390
  • Add support for prepending a custom user agent, Issue #394, PR #395
  • OpenStack fixed storage copy function, Issue #396 , PR #350
  • OpenStack allow non-strict SSL, PR #397
  • Adding a refresh method on the stack model, Issue #398, PR #402
  • Google storage return metadata in success handler, Issue #400, PR #401
  • OpenStack added template outputs field to stack, PR #403
  • Amazon fixes to AWS config, Issue #406, PR #407, #409
  • Added support for nestedDepth option to stack getResources method, Issue #410, PR #411
  • Added support for networking security groups, security group rules, PR #412
  • Allow passing options to rebuildServer, Issue #414, PR #415
  • Allow deleteStack to accept stack object or stack name, Issue #418, PR #420
  • Amazon createServer: use pluralized keys for SecurityGroups/SecurityGroupIds, Issue #432, PR #433
  • RackSpace, OpenStack add enableRootUser and listRootStatus, PR #438
  • Amazon storage added cache control support to s3 buckets, PR #447
  • OpenStack compute added deleteRule, PR #456
  • DigitalOcean ported provider to APIv2, PR #470
  • OpenStack handle request errors in client.upload flow, Issue #481, PR #484
  • OpenStack added adminPass attribute to createServer, PR #486
  • Amazon added AWS specific options for cache control and file encryption, PR #496
  • Misc doc fixes, PR #417, #426, #429, #442, #444, #449, #498

v1.2.0

  • Added Support for Openstack CDN (Poppy)

v1.1.0

  • Added support for Google Cloud Storage
  • Added support for Rackspace Cloud Networks

v1.0.3

  • Adding support for Openstack Trove, and adding HP, rackspace providers

v1.0.2

  • Adding support for OpenStack Cinder

v1.0.1

  • Adding a rackspace orchestration provider

v1.0.0

  • Requires node 0.10, dropping support for node v0.8
  • Fundamentally changed the streaming file api for upload. No longer takes a callback. See #332
  • Significant cleanup across storage apis across providers
  • Added toJSON on all models
  • Changed underlying Amazon provider to use aws-sdk
  • Added Openstack Heat provider
  • updated all package dependencies, including removing utile
  • static website support for Rackspace Cloud Files
  • Added compute.keys support for HP Compute provider

v0.9.6

  • Fixed a long-standing bug in openstack.compute.getFlavor #292

v0.9.5

  • Openstack Network service.
  • Added support for HP Cloud provider.
  • Added support for Rackspace Storage Temporary URLs

v0.9.4

  • Added support for os-security-groups compute extension

v0.9.2

  • fixed a bug where CDN containers were broken with Rackspace CloudFiles #257

v0.9.1

  • Removing an unnecessary continuity check in openstack identity client
  • Switching Debug events to trace events
  • Be more explicit with content types for openstack authentication
  • Allow passing tenant to the context authenticator
  • Fixing the networks property to be on server options for openstack compute

v0.9.0

  • OpenStack Documentation
  • Openstack Storage Provider
  • fixed a bug with piping downloads from storage services #195
  • internal refactor for leaky abstractions
  • OpenStack identity client as a proper client

v0.8.17

  • Make default for destroyServer (DigitalOcean) to scrub data #215

v0.8.16

  • Add beta support for Rackspace Cloud Load Balancers

v0.8.15

  • Various fixes in openstack/rackspace compute provider
  • Added doc updates for rackspace storage provider
  • fixed a bug in rackspace dns provider

v0.8.14

  • Added support to specify network in openstack.createServer
  • More robust error handling for API inconsistencies in Rackspace/Openstack

v0.8.13

  • Added support for Rackspace Cloud BlockStorage

v0.8.12

  • Changed the callback signature for openstack.identity.getTenantInfo to include body

v0.8.11

  • Added more robust error handling for openstack.identity admin methods

v0.8.10

  • Fixing a bug in rackspace.dns where status call can be an empty response

v0.8.9

  • Fixing a bug when rackspace.dns.createRecord returns an array

v0.8.8

  • Adding support for uploading a tar.gz to Cloud files and extract on upload
  • Minor tenant changes for openstack identity providers

v0.8.7

  • Adding Rackspace CloudDNS as a DNS service

v0.8.5

  • Fixing a bug introduced by pre-release services listed in the Openstack Service Catalog

v0.8.4

  • Rackspace provider can now validate token with admin account
  • Using through in lieu of pause-stream

v0.8.3

  • Dependency bump for request (2.22.0)
  • Support internal Openstack service URLs

v0.8.2

  • Added support for File/Container metadata for Rackspace Storage
  • Adding support for Rackspace CDN enabled Containers

v0.8.1

  • Added support for limit/marker options for Rackspace getContainers, getFiles
  • removed unused Rackspace.File.rm/ls/cp methods
  • Fixed a bug in File.fullPath
  • Fixed a bug in Azure header signing

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

  • Fixed inline authentication for streaming to rackspace/openstack storage #109
  • Fixed S3 multi-part upload signing #137
  • Optimized S3 upload #124
  • Fixed Rackspace authentication to return error on unauthorized #140

v0.7.2

  • Added a pkgcloud User-Agent for outbound HTTP requests #134
  • Added tests for core compute method signatures