UNPKG

@yawetse/pkgcloud

Version:

An infrastructure-as-a-service agnostic cloud library for node.js

299 lines (260 loc) 7.59 kB
/* * servers.js: Instance methods for working with servers from AWS Cloud * * (C) 2012 Charlie Robbins, Ken Perkins, Ross Kukulinski & the Contributors. * */ var async = require('async'), base = require('../../../core/compute'), pkgcloud = require('../../../../../lib/pkgcloud'), errs = require('errs'), compute = pkgcloud.providers.amazon.compute; // // ### function getVersion (callback) // #### @callback {function} f(err, version). // // Gets the current API version // exports.getVersion = function getVersion(callback) { var self = this; process.nextTick(function() { callback(null, self.version); }); }; // // ### function getLimits (callback) // #### @callback {function} f(err, version). // // Gets the current API limits // exports.getLimits = function getLimits(callback) { return errs.handle( errs.create({ message: 'AWS\'s API is not rate limited' }), callback ); }; // // ### function _getDetails (details, callback) // #### @details {Object} Short details of server // #### @callback {function} f(err, details) Amended short details. // // Loads IP and name of server. // exports._getDetails = function getDetails(details, callback) { var self = this; self.ec2.describeInstanceAttribute({ InstanceId: details.instanceId || details.InstanceId, Attribute: 'userData' }, function(err, data) { if (err) { // disregard the errors, if any return callback(null, details); } var meta = new Buffer( data.UserData.Value || '', 'base64' ).toString(); try { meta = JSON.parse(meta); } catch (e) { meta = {}; } details.name = meta.name; callback(null, details); }); }; // // ### function getServers (callback) // #### @callback {function} f(err, servers). `servers` is an array that // represents the servers that are available to your account // // Lists all servers available to your account. // exports.getServers = function getServers(options, callback) { if (typeof options === 'function') { callback = options; options = {}; } var self = this; self.ec2.describeInstances(options, function(err, data) { if (err) { callback(err); return; } var servers = []; data.Reservations.forEach(function(reservation) { reservation.Instances.forEach(function(instance) { servers.push(instance); }); }); // TODO investigate performance when getServers returns 100s of servers async.map(servers, self._getDetails.bind(self), function finish(err, servers) { return err ? callback(err) : callback(null, servers.map(function (server) { return new compute.Server(self, server); })); } ); }); }; // // ### function createServer (options, callback) // #### @opts {Object} **Optional** options // #### @name {String} **Optional** the name of server // #### @image {String|Image} the image (AMI) to use // #### @flavor {String|Flavor} **Optional** flavor to use for this image // #### @callback {Function} f(err, server). // // Creates a server with the specified options. The flavor // properties of the options can be instances of Flavor // OR ids to those entities in AWS. // exports.createServer = function createServer(options, callback) { if (typeof options === 'function') { callback = options; options = {}; } options = options || {}; // no args var self = this, meta = { name: options.name || '' }, createOptions = { UserData: new Buffer(JSON.stringify(meta)).toString('base64'), MinCount: 1, MaxCount: 1 }, securityGroup, securityGroupId; if (!options.image) { return errs.handle( errs.create({ message: 'options.image is a required argument.' }), callback ); } securityGroup = this.securityGroup || options['SecurityGroup']; if (securityGroup) { createOptions['SecurityGroups'] = [securityGroup]; } securityGroupId = this.securityGroupId || options['SecurityGroupId']; if (securityGroupId) { createOptions['SecurityGroupIds'] = [securityGroupId]; } createOptions.ImageId = options.image instanceof base.Image ? options.image.id : options.image; if (options.flavor) { createOptions.InstanceType = options.flavor instanceof base.Flavor ? options.flavor.id : options.flavor; } if (options.keyname || options.KeyName) { createOptions.KeyName = options.keyname || options.KeyName; } if (options.zone || options['Placement.AvailabilityZone']) { createOptions['Placement.AvailabilityZone'] = options.zone || options['Placement.AvailabilityZone']; } self.ec2.runInstances(createOptions, function(err, data) { var server; if (err) { return callback(err); } data.Instances.forEach(function (instance) { instance.meta = meta; server = new compute.Server(self, instance); }); callback(null, server); }); }; // // ### function destroyServer(server, callback) // #### @server {Server|String} Server id or a server // #### @callback {Function} f(err, serverId). // // Destroy a server in AWS. // exports.destroyServer = function destroyServer(server, callback) { var self = this, serverId = server instanceof base.Server ? server.id : server; self.ec2.terminateInstances({ InstanceIds: [ serverId ] }, function(err) { return err ? callback && callback(err) : callback && callback(null, { ok: serverId }); }); }; // // ### function getServer(server, callback) // #### @server {Server|String} Server id or a server // #### @callback {Function} f(err, serverId). // // Gets a server in AWS. // exports.getServer = function getServer(server, callback) { var self = this, serverId = server instanceof base.Server ? server.id : server; self.ec2.describeInstances({ InstanceIds: [ serverId ], Filters: [ { Name: 'instance-state-code', Values : [ '0', '16', '32', '64', '80' ] } ] }, function (err, data) { var server; if (err) { return callback(err); } data.Reservations.forEach(function(reservation) { reservation.Instances.forEach(function (instance) { server = instance; }); }); if (server === undefined) { return callback(new Error('Server not found')); } self._getDetails(server, function (err, server) { if (err) { return callback(err); } callback(null, new compute.Server(self, server)); }); } ); }; // // ### function rebootServer (server, options, callback) // #### @server {Server|String} The server to reboot // #### @callback {Function} f(err, server). // // Reboots a server // exports.rebootServer = function rebootServer(server, callback) { var self = this, serverId = server instanceof base.Server ? server.id : server; self.ec2.rebootInstances({ InstanceIds: [ serverId ] }, function (err) { return err ? callback && callback(err) : callback && callback(null, { ok: serverId }); }); }; // // ### function renameServer(server, name, callback) // #### @server {Server|String} Server id or a server // #### @name {String} New name to apply to the server // #### @callback {Function} f(err, server). // // Renames a server // exports.renameServer = function renameServer(server, name, callback) { return errs.handle( errs.create({ message: 'Not supported by AWS.' }), callback ); };