@sansitech/pkgcloud
Version:
A provider agnostic cloud library for Node.js
706 lines (527 loc) • 25.3 kB
Markdown
# pkgcloud [](http://travis-ci.org/pkgcloud/pkgcloud) [](http://badge.fury.io/js/pkgcloud)
[](https://gitter.im/pkgcloud/pkgcloud?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
pkgcloud is a standard library for node.js that abstracts away differences among multiple cloud providers.
* [Getting started](#getting-started)
* [Basic APIs](#basic-apis)
* [Unified Vocabulary](#unified-vocabulary)
* [Supported APIs](#supported-apis)
* [Compute](#compute)
* [Storage](#storage)
* [Uploading Files](#upload-a-file)
* [Downloading Files](#download-a-file)
* [Database](#databases)
* [DNS](#dns----beta) *(beta)*
* [Block Storage](#block-storage----beta) *(beta)*
* [Load Balancers](#load-balancers----beta) *(beta)*
* [Orchestration](#orchestration----beta) *(beta)*
* [Network](#network----beta) *(beta)*
* [CDN](#cdn----beta) *(beta)*
* _Fine Print_
* [Installation](#installation)
* [Tests](#tests)
* [Logging](#logging)
* [Code Coverage](#code-coverage)
* [Contribute!](#contributing)
* [Roadmap](#roadmap)
<a name="getting-started"></a>
## Getting Started
You can install `pkgcloud` via `npm` or add to it to [dependencies](https://npmjs.org/doc/json.html#dependencies) in your `package.json` file:
```
npm install pkgcloud
```
Currently there are nine service types which are handled by pkgcloud:
* [Compute](#compute)
* [Storage](#storage)
* [Database](#databases)
* [DNS](#dns----beta) *(beta)*
* [Block Storage](#block-storage----beta) *(beta)*
* [Load Balancers](#load-balancers----beta) *(beta)*
* [Network](#network----beta) *(beta)*
* [Orchestration](#orchestration----beta) *(beta)*
* [CDN](#cdn----beta) *(beta)*
In our [Roadmap](#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:
```javascript
client.setCustomUserAgent('my-app/1.2.3');
// returns "my-app/1.2.3 nodejs-pkgcloud/1.1.0"
client.getUserAgent();
```
<a name="basic-apis"></a>
### 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:
``` js
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:
``` js
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({ ... })`.
<a name="unified-vocabulary"></a>
### Unified Vocabulary
Due to the differences between the vocabulary for each service provider, **[pkgcloud uses its own unified vocabulary](docs/vocabulary.md).**
* **Compute:** [Server](#server), [Image](#image), [Flavor](#flavor)
* **Storage:** [Container](#container), [File](#file)
* **DNS:** [Zone](#zone), [Record](#record)
**Note:** Unified vocabularies may not yet be defined for *beta* services.
<a name="supported-apis"></a>
### 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](#compute)**
* [Amazon](docs/providers/amazon.md#using-compute)
* [Azure](docs/providers/azure.md#using-compute)
* [DigitalOcean](docs/providers/digitalocean.md#using-compute)
* [HP](docs/providers/hp/compute.md)
* [Openstack](docs/providers/openstack/compute.md)
* [Rackspace](docs/providers/rackspace/compute.md)
* **[Storage](#storage)**
* [Amazon](docs/providers/amazon.md#using-storage)
* [Azure](docs/providers/azure.md#using-storage)
* [Google](docs/providers/google.md)
* [HP](docs/providers/hp/storage.md)
* [Openstack](docs/providers/openstack/storage.md)
* [Rackspace](docs/providers/rackspace/storage.md)
* **[Database](#databases)**
* [Rackspace](docs/providers/rackspace/database.md)
* **[DNS](#dns----beta)** *(beta)*
* [Rackspace](docs/providers/rackspace/dns.md)
* **[Block Storage](#block-storage----beta)** *(beta)*
* [Rackspace](docs/providers/rackspace/blockstorage.md)
* [Openstack](docs/providers/openstack/blockstorage.md)
* **[Load Balancers](#load-balancers----beta)** *(beta)*
* [Rackspace](docs/providers/rackspace/loadbalancer.md)
* **[Orchestration](#orchestration----beta)** *(beta)*
* [Openstack](docs/providers/openstack/orchestration.md)
* [Rackspace](docs/providers/rackspace/orchestration.md)
* **[Network](#network----beta)** *(beta)*
* [HP](docs/providers/hp/network.md)
* [Openstack](docs/providers/openstack/network.md)
* [Rackspace](docs/providers/rackspace/network.md)
* **[CDN](#cdn----beta)** *(beta)*
* [Openstack](docs/providers/openstack/cdn.md)
* [Rackspace](docs/providers/rackspace/cdn.md)
## 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:
``` js
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:
* [Amazon](docs/providers/amazon.md#using-compute)
* [Azure](docs/providers/azure.md#using-compute)
* [DigitalOcean](docs/providers/digitalocean.md#using-compute)
* [HP](docs/providers/hp/compute.md)
* [Openstack](docs/providers/openstack/compute.md)
* [Rackspace](docs/providers/rackspace/compute.md)
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:
``` js
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:
* [Amazon](docs/providers/amazon.md#using-storage)
* [Azure](docs/providers/azure.md#using-storage)
* [Google](docs/providers/google.md#using-storage)
* [HP](docs/providers/hp/storage.md)
* [Openstack](docs/providers/openstack/storage.md)
* [Rackspace](docs/providers/rackspace/storage.md)
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
``` js
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
``` js
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:
``` js
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:
* **MySQL**
* [Rackspace](docs/providers/rackspace/databases.md)
* **Azure Tables**
* [Azure](docs/providers/azure.md#database)
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:
``` js
var client = require('pkgcloud').dns.createClient({
//
// The name of the provider (e.g. "rackspace")
//
provider: 'provider-name',
//
// ... Provider specific credentials
//
});
```
#### Providers
* [Rackspace](docs/providers/rackspace/dns.md)
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:
``` js
var client = require('pkgcloud').blockstorage.createClient({
//
// The name of the provider (e.g. "rackspace")
//
provider: 'provider-name',
//
// ... Provider specific credentials
//
});
```
#### Providers
* [Rackspace](docs/providers/rackspace/blockstorage.md)
* [Openstack](docs/providers/openstack/blockstorage.md)
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:
``` js
var client = require('pkgcloud').loadbalancer.createClient({
//
// The name of the provider (e.g. "rackspace")
//
provider: 'provider-name',
//
// ... Provider specific credentials
//
});
```
#### Providers
* [Rackspace](docs/providers/rackspace/loadbalancer.md)
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:
``` js
var client = require('pkgcloud').network.createClient({
//
// The name of the provider (e.g. "openstack")
//
provider: 'provider-name',
//
// ... Provider specific credentials
//
});
```
#### Providers
* [HP](docs/providers/hp/network.md)
* [Openstack](docs/providers/openstack/network.md)
* [Rackspace](docs/providers/rackspace/network.md)
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:
``` js
var client = require('pkgcloud').orchestration.createClient({
//
// The name of the provider (e.g. "openstack")
//
provider: 'provider-name',
//
// ... Provider specific credentials
//
});
```
#### Providers
* [Openstack](docs/providers/openstack/orchestration.md)
* [Rackspace](docs/providers/rackspace/orchestration.md)
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:
``` js
var client = require('pkgcloud').cdn.createClient({
//
// The name of the provider (e.g. "openstack")
//
provider: 'provider-name',
//
// ... Provider specific credentials
//
});
```
#### Providers
* [Openstack](docs/providers/openstack/cdn.md)
* [Rackspace](docs/providers/rackspace/cdn.md)
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
``` bash
$ npm install pkgcloud
```
## Tests
To run the tests you will need `mocha@1.9.x` or higher. You may install all
the requirements with:
``` bash
$ npm install
```
Then run the tests:
``` bash
$ npm test
```
The tests use the [`hock`](https://github.com/mmalecki/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.
``` bash
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:
``` bash
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:
``` bash
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.
```Javascript
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](docs/logging-with-winston.md).
## 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
```
<a name="contributing"></a>
## 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](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](https://github.com/indexzero)
#### Contributors: [Ross Kukulinski](https://github.com/rosskukulinski), [Jarrett Cruger](https://github.com/jcrugzz), [Ken Perkins](https://github.com/kenperkins)
#### License: MIT