/* jslint node:true */ 'use strict'; var assert = require('assert'), debug = require('debug')('e2e:digitalocean'), safe = require('safetydance'), superagent = require('superagent'), util = require('util'); module.exports = exports = { setCredentials: setCredentials, create: createDroplet, get: getDroplet, destroy: destroyDroplet }; var DIGITALOCEAN = 'https://api.digitalocean.com/v2'; var gAuth = null; function setCredentials(token) { gAuth = 'Bearer ' + token; } function getSSHKeyId(keyName, callback) { assert.strictEqual(typeof keyName, 'string'); assert.strictEqual(typeof callback, 'function'); superagent.get(DIGITALOCEAN + '/account/keys').set('Authorization', gAuth).end(function (error, result) { if (error) return callback(error); if (result.statusCode === 403) return callback('not authorized'); if (result.statusCode !== 200) return callback(util.format('failed with %s - %j', result.statusCode, result.text)); var sshKeys = result.body.ssh_keys || []; var sshKeyId = null; sshKeys.forEach(function (key) { if (key.name === keyName) sshKeyId = key.id; }); if (!sshKeyId) return callback('no ssh key found'); callback(null, sshKeyId); }); } function getDroplet(id, callback) { assert.strictEqual(typeof id, 'number'); assert.strictEqual(typeof callback, 'function'); superagent.get(DIGITALOCEAN + '/droplets/' + id).set('Authorization', gAuth).end(function (error, result) { if (error) return callback(error); if (result.statusCode === 403) return callback('not authorized'); if (result.statusCode !== 200) return callback('droplet not found'); var droplet = result.body.droplet; if (!droplet || typeof droplet !== 'object') return callback('Missing droplet in body, this is a DO issue'); var ip = safe.query(droplet, 'networks.v4[0].ip_address'); callback(null, { name: droplet.name, id: droplet.id, ip: ip, status: droplet.status }); }); } function createDroplet(name, image, sshKeyName, region, size, userData, callback) { assert.strictEqual(typeof name, 'string'); assert.strictEqual(typeof image, 'string'); assert.strictEqual(typeof sshKeyName, 'string'); assert.strictEqual(typeof region, 'string'); assert.strictEqual(typeof size, 'string'); assert.strictEqual(typeof userData, 'string'); assert.strictEqual(typeof callback, 'function'); debug('addDroplet: with name "' + name + '".'); getSSHKeyId(sshKeyName, function (error, sshKeyId) { if (error) return callback(error); var options = { name: name, size: size, image: image, region: region, backups: false, user_data: userData, ssh_keys: [ sshKeyId ] }; debug('addDroplet: Creating droplet with name:%s size: %s image: %s', options.name, options.size, options.image); superagent.post(DIGITALOCEAN + '/droplets').set('Authorization', gAuth).send(options).end(function (error, result) { if (error) return callback(error); if (result.statusCode === 403) return callback('not authorized'); if (result.statusCode !== 202) return callback(util.format('Failed with status %s - %j', result.statusCode, result.text)); var droplet = result.body.droplet; if (!droplet || typeof droplet !== 'object') return callback('Missing droplet in body, this is a DO issue'); debug('addDroplet: new droplet with id %s and name %s created', droplet.id, droplet.name); callback(null, { id: droplet.id, name: droplet.name }); }); }); } function destroyDroplet(id, callback) { assert.strictEqual(typeof id, 'number'); assert.strictEqual(typeof callback, 'function'); debug('destroyDroplet: ' + id); superagent.del(DIGITALOCEAN + '/droplets/' + id).set('Authorization', gAuth).end(function (error, result) { if (error) return callback(error); if (result.statusCode === 403) return callback('not authorized'); if (result.statusCode === 404) return callback(null); if (result.statusCode !== 204) debug('destroyDroplet: unable to delete droplet. Maybe it was already deleted.'); debug('destroyDroplet: success'); callback(null); }); }