UNPKG

tooltwist

Version:
370 lines (316 loc) 10.7 kB
var DigitalOceanAPI = require('digitalocean-api'), Templates = require('./templates'), Mustache = require("mustache"), Log = require('./log'), fs = require('fs'), path = require('path'), os = require("os"), printf = require('printf'); // Create an instance with your API credentials var api = new DigitalOceanAPI('GmRxy2PfPFB7KuubUj7yN', '9a64d5965136c28c15a28aac9335c84b'); //5039e5b5a9fd05e5d663232505103c099d1fe2f31cf5e483e94ee86425fe39b5 function showDroplets(callback){ api.dropletGetAll(function(error, result){ console.log("\nDROPLETS:") if (result) { // console.log(result); console.log(printf("%9s %-20s %-7s %-18s %7s %5s %7s %s", 'ID', 'NAME', 'STATUS', 'IP ADDR', 'IMAGE', 'SIZE', 'REGION', 'CREATED')) for (var i = 0; i < result.length; i++) { var rec = result[i]; console.log(printf("%9d %-20s %-7s %-18s %7d %5d %7d %s", rec.id, rec.name, rec.status, rec.ip_address, rec.image_id, rec.size_id, rec.region_id, rec.created_at)) } callback(null) } else { console.log(' could not get droplet information') callback(new Error('Could not get droplet information')) } }); } function showImages(callback){ api.imageGetAll(function(error, result){ console.log("\nIMAGES:") if (result) { // console.log(result); // { id: 4991187, // name: 'WordPress on Ubuntu 14.04', // slug: null, // distribution: 'Ubuntu', // public: true, // regions: [ 1, 2, 3, 4, 5, 6, 7, 8 ], // region_slugs: [ 'nyc1', 'ams1', 'sfo1', 'nyc2', 'ams2', 'sgp1', 'lon1', 'nyc3' ] } ] console.log(printf("%9s %6s %s", 'ID', 'PUBLIC', 'NAME')) for (var i = 0; i < result.length; i++) { var rec = result[i]; console.log(printf("%9d %6s %s", rec.id, rec.public, rec.name)) } callback(null) } else { console.log(' could not get images information') callback(new Error('Could not get images information')) } }); } function getUniqueDropletName(basename, callback){ api.imageGetAll(function(err, result){ if (err) return callback(err); // Find the next sequence number with this prefix var prefix = basename + '-'; var max = 1; for (var i = 0; i < result.length; i++) { var name = result[i].name; if (name.indexOf(prefix) === 0) { var suffix = name.substring(prefix.length); try { var num = parseInt(suffix) if (num >= max) { max = num + 1; } } catch (e) { // Do nothing } } } // console.log('NEXT IN SEQUENCE=' + max) return callback(null, prefix + max) }); } function showSizes(callback){ api.sizeGetAll(function(error, result){ console.log("\nSIZES:") if (result) { // console.log(result); // { id: 60, // name: '32GB', // slug: '32gb', // memory: 32768, // cpu: 12, // disk: 320, // cost_per_hour: 0.47619, // cost_per_month: '320.0' }, console.log(printf("%9s %-10s %5s %5s %6s %6s", 'ID', 'NAME', 'CPU', 'DISK', 'HOUR', 'MONTH')) for (var i = 0; i < result.length; i++) { var rec = result[i]; console.log(printf("%9d %-10s %5d %5d %6.4f %6.2f", rec.id, rec.name, rec.cpu, rec.disk, rec.cost_per_hour, rec.cost_per_month)) } callback(null) } else { console.log(' could not get size information') callback(new Error('Could not get size information')) } }); } function showSizes(callback){ api.sizeGetAll(function(error, result){ console.log("\nSIZES:") if (result) { // console.log(result); // { id: 60, // name: '32GB', // slug: '32gb', // memory: 32768, // cpu: 12, // disk: 320, // cost_per_hour: 0.47619, // cost_per_month: '320.0' }, console.log(printf("%9s %-10s %5s %5s %6s %6s", 'ID', 'NAME', 'CPU', 'DISK', 'HOUR', 'MONTH')) for (var i = 0; i < result.length; i++) { var rec = result[i]; console.log(printf("%9d %-10s %5d %5d %6.4f %6.2f", rec.id, rec.name, rec.cpu, rec.disk, rec.cost_per_hour, rec.cost_per_month)) } callback(null) } else { console.log(' could not get size information') callback(new Error('Could not get size information')) } }); } function showSshKeys(callback){ api.sshKeyGetAll(function(error, result){ console.log("\nSSH Keys:") if (result) { console.log(result); // { id: 18237, name: 'Phil MBP' } console.log(printf("%9s %s", 'ID', 'NAME')) for (var i = 0; i < result.length; i++) { var rec = result[i]; console.log(printf("%9d %s", rec.id, rec.name)) } callback(null) } else { console.log(' could not get SSH Key information') callback(new Error('Could not get SSH Key information')) } }); } function getAdminSshKey(publicKey, callback){ // Look for a key named 'admin'. // Failing that, look for any key. var ADMIN_KEY = 'admin'; api.sshKeyGetAll(function(error, result){ console.log("\nSSH Keys:") if (result) { console.log(result); // { id: 18237, name: 'Phil MBP' } console.log(printf("%9s %s", 'ID', 'NAME')) var anyKey = null; for (var i = 0; i < result.length; i++) { var rec = result[i]; console.log(printf("%9d %s", rec.id, rec.name)) if (rec.name.toLowerCase() === ADMIN_KEY) { // Found admin key Log.info("Found SSH Key " + ADMIN_KEY) return callback(rec); } // Remember the first key if (anyKey == null) { anyKey = rec; } } // If we found any SSH key, return it now. if (anyKey) { console.log("RETURN ANY KEY") return callback(anyKey); } // Need to create a new admin key Log.info("Adding SSH Key " + ADMIN_KEY) api.sshKeyAdd(ADMIN_KEY, publicKey, function(err, result){ if (err) { Log.fatalError('Could not create SSH Key ' + ADMIN_KEY) } // console.log("After adding key: ", err, result) callback(result) }); } else { console.log(' could not get SSH Key information') callback(new Error('Could not get SSH Key information')) } }); } function createDroplet(name, adminSshKeyId, callback) { var sizeId = 66; var imageId = 5505824; // node-v0.10.30 on Ubuntu 14.04 var imageId = 5736991; // Tooltwist var regionId = 6; var optionals = { ssh_key_ids: [ adminSshKeyId ], // private_networking: false, // backups_enabled: false }; api.dropletNew(name, sizeId, imageId, regionId, optionals, callback); } /** * Wait for a droplet to start. */ function waitForServer(dropletId, endTime, callback){ if (endTime <= 0) { endTime = Math.round(new Date().getTime() / 1000) endTime += 120; // Allow 2 minutes for startup. } var now = Math.round(new Date().getTime() / 1000) //console.log('waitForServer ', now, endTime) if (now >= endTime) { console.log('Timeout waiting for server to start') return callback(null, false); } api.dropletGet(dropletId, function(err, result){ if (err) return callback(err, false); // See if the status is now active //console.log('result=', err, result); //console.log('status is ' + result.status) if (result.status === 'active') { return callback(null, true); } else if (result.status !== 'new') { console.log('server has status ' + result.status) callback(null, false); } //console.log('waiting...') setTimeout(function(){ waitForServer(dropletId, endTime, callback) }, 5000); // 5 seconds }) } exports.createServer = function(callback) { Log.debug("digital-ocean.createServer()") // Prepare the script we'll send to the server var publicKey = getPublicKey(); var sourceUUID = createUUID(); var destinationUUID = createUUID(); var passphrase = "Chicken sickle marmalade toebar"; var username = process.env['USER']; var hostname = os.hostname(); Log.info('publicKey=' + publicKey) Log.info('sourceUUID=' + sourceUUID) Log.info('destinationUUID=' + destinationUUID) Log.info('passphrase=' + passphrase) Log.info('username=' + username) Log.info('hostname=' + hostname) // Load the template var view = { PUBLIC_KEY: publicKey, SOURCE_UUID: sourceUUID, DESTINATION_UUID: destinationUUID, PASSPHRASE: passphrase }; var defaultTemplateDir = Config.RESOURCES_DIR + '/templates'; var from = Templates.findTemplate(defaultTemplateDir, 'install/template.prepareRemoteServer.sh'); var template = fs.readFileSync(from, "utf8"); var content = Mustache.render(template, view); console.log('script is: ' + content) // Find an SSH key to use getAdminSshKey(publicKey, function(rec){ Log.info('Using SSH key ' + rec.name) var adminSshKeyId = rec.id; console.log("KEYYYYY ISSSSS ", rec) // Base the server name on the current directory name var name = path.basename(process.cwd()); // Find a name to use getUniqueDropletName(name, function(err, newName){ console.log('Creating a droplet named \'' + newName + '\'.') // Create a new droplet createDroplet(newName, adminSshKeyId, function(err, result){ // console.log('createDroplet returned ', err, result) if (err) return callback(err); var dropletId = result.id; // Wait for droplet to start. console.log('\nWaiting for server to start...') waitForServer(dropletId, 0, function(err, isReady) { if (err) return callback(err); if (!isReady) return callback(null, null); // Something went wrong // Get details (including IP Address) api.dropletGet(dropletId, function(err, dropletDetails){ // Return the details of the new server. //console.log('dropletDetails:', dropletDetails) return callback(null, isReady ? dropletDetails : null); }); }); // waitForServer }); // createDroplet }); // getUniqueDropletName }); // getAdminSshKey showImages(function(){ }) } /** * Get the first line of ~/.ssh/id_rsa.pub */ function getPublicKey() { var home = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME']; var path = home + "/.ssh/id_rsa.pub"; if ( !fs.existsSync(path)) { Log.error() Log.error('\tSorry, you\'ll need to have a ~/.ssh/id_rsa.pub before running this command.') Log.error() process.exit(1) } var keys = fs.readFileSync(path, "utf8"); // console.log('keys=' + keys); var pos = keys.indexOf('\n'); var key = (pos < 0) ? keys : keys.substring(0, pos); // console.log('key=' + key + '<'); return key; } /** * Return a universally unique ID that can be used to identify a FIP source or destination. */ function createUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*36|0,v=c=='x'?r:r&0x3|0x8;return v.toString(36);}); }