UNPKG

@sansitech/pkgcloud

Version:

A provider agnostic cloud library for Node.js

706 lines (527 loc) 25.3 kB
# pkgcloud [![Build Status](https://secure.travis-ci.org/pkgcloud/pkgcloud.png?branch=master)](http://travis-ci.org/pkgcloud/pkgcloud) [![NPM version](https://badge.fury.io/js/pkgcloud.png)](http://badge.fury.io/js/pkgcloud) [![Join the chat at https://gitter.im/pkgcloud/pkgcloud](https://badges.gitter.im/Join%20Chat.svg)](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