diff --git a/packages/portal-api/bootstrap-data.js b/packages/portal-api/bootstrap-data.js index a3ebc24c..de06d4fe 100644 --- a/packages/portal-api/bootstrap-data.js +++ b/packages/portal-api/bootstrap-data.js @@ -1,7 +1,48 @@ 'use strict'; +const Triton = require('triton'); +const Url = require('url'); +const Path = require('path'); +const Fs = require('fs'); + const Data = require('./lib/data'); +const { + DOCKER_HOST, + DOCKER_CERT_PATH, + SDC_URL, + SDC_ACCOUNT, + SDC_KEY_ID +} = process.env; + +const DOCKER_HOST_URL = DOCKER_HOST ? + Url.parse(DOCKER_HOST) : + {}; + +const settings = { + db: { + host: process.env.RETHINK_HOST || 'localhost' + }, + docker: { + protocol: 'https', + host: DOCKER_HOST_URL.hostname, + port: DOCKER_HOST_URL.port, + ca: DOCKER_CERT_PATH ? + Fs.readFileSync(Path.join(DOCKER_CERT_PATH, 'ca.pem')) : + undefined, + cert: DOCKER_CERT_PATH ? + Fs.readFileSync(Path.join(DOCKER_CERT_PATH, 'cert.pem')) : + undefined, + key: DOCKER_CERT_PATH ? + Fs.readFileSync(Path.join(DOCKER_CERT_PATH, 'key.pem')) : + undefined + }, + triton: { + url: SDC_URL, + account: SDC_ACCOUNT, + keyId: SDC_KEY_ID + } +}; const ifError = function (err) { if (err) { @@ -11,47 +52,39 @@ const ifError = function (err) { }; const bootstrap = function () { - const data = new Data({ - db: { - host: process.env.RETHINK_HOST || 'localhost' - } - }); - + const data = new Data(settings); const region = process.env.TRITON_DC || 'us-sw-1'; - const login = process.env.TRITON_USER || 'nikola'; - data.connect(() => { + data.connect((err) => { + ifError(err); + data.createDatacenter({ region, name: region }, (err, datacenter) => { ifError(err); - data.createUser({ firstName: 'Nikola', lastName: 'Tesla', email: 'nikola@tesla.com', login }, (err, user) => { + Triton.createClient({ + profile: settings.triton + }, (err, { cloudapi }) => { ifError(err); - data.createPortal({ - user, - datacenter - }, (err, portal) => { + cloudapi.getAccount((err, { firstName, lastName, email, login }) => { ifError(err); - console.log('data bootstrapped'); - process.exit(0); + + data.createUser({ firstName, lastName, email, login }, (err, user) => { + ifError(err); + + data.createPortal({ + user, + datacenter + }, (err, portal) => { + ifError(err); + console.log('data bootstrapped'); + process.exit(0); + }); + }); }); }); }); }); }; -/* -const main = function () { - const dropData = new Data({ - db: { - host: process.env.RETHINK_HOST || 'localhost' - } - }); - dropData.connect(() => { - dropData._db.r.dbDrop('portal').run(dropData._db._connection, () => { - bootstrap(); - }); - }); -}; -*/ bootstrap(); diff --git a/packages/portal-api/lib/data/index.js b/packages/portal-api/lib/data/index.js index 4308f323..16ad7963 100644 --- a/packages/portal-api/lib/data/index.js +++ b/packages/portal-api/lib/data/index.js @@ -10,6 +10,7 @@ const Util = require('util'); const DockerClient = require('docker-compose-client'); const Dockerode = require('dockerode'); const Hoek = require('hoek'); +const Triton = require('triton'); const ParamCase = require('param-case'); const Penseur = require('penseur'); const { DEPLOYMENT_GROUP, SERVICE, HASH } = require('../watch'); @@ -70,10 +71,18 @@ module.exports = class Data extends EventEmitter { this._dockerCompose = new DockerClient(settings.dockerComposeHost); this._docker = new Dockerode(settings.docker); this._watcher = null; + this._triton = null; - // if (settings.consul && settings.consul.address) { - // CPClient.config(settings.consul); - // } + Triton.createClient({ + profile: settings.triton + }, (err, client) => { + if (err) { + this.emit('error', err); + return; + } + + this._triton = client.cloudapi; + }); this._dockerCompose.on('error', (err) => { this.emit('error', err); @@ -1002,8 +1011,11 @@ module.exports = class Data extends EventEmitter { return next(err); } - const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]); - container.stop(next); + if (!this._triton) { + return next(); + } + + this._triton.stopMachine(instance.machine_id, next); }); }, inputs: instanceIds @@ -1038,8 +1050,11 @@ module.exports = class Data extends EventEmitter { return next(err); } - const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]); - container.start(next); + if (!this._triton) { + return next(); + } + + this._triton.startMachine(instance.machine_id, next); }); }, inputs: instanceIds @@ -1074,8 +1089,11 @@ module.exports = class Data extends EventEmitter { return next(err); } - const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]); - container.restart(next); + if (!this._triton) { + return next(); + } + + this._triton.rebootMachine(instance.machine_id, next); }); }, inputs: instanceIds @@ -1127,9 +1145,11 @@ module.exports = class Data extends EventEmitter { return next(err); } - const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]); - // Use force in case the container is running. TODO: should we keep force? - container.remove({ force: true }, next); + if (!this._triton) { + return next(); + } + + this._triton.deleteMachine(instance.machine_id, next); }); }, inputs: instanceIds @@ -1220,8 +1240,11 @@ module.exports = class Data extends EventEmitter { VAsync.forEachParallel({ func: (instance, next) => { - const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]); - container.stop(next); + if (!this._triton) { + return next(); + } + + this._triton.stopMachine(instance.machine_id, next); }, inputs: instances }, (err, results) => { @@ -1246,19 +1269,26 @@ module.exports = class Data extends EventEmitter { VAsync.forEachParallel({ func: (instance, next) => { - const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]); - container.start((err) => { + if (!this._triton) { + return next(); + } + + this._triton.startMachine(instance.machine_id, (err) => { if (err) { return next(err); } + const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]); + // Update the IPAddress for the instance container.inspect((err, details) => { if (err) { return next(err); } - this._db.instances.update(instance.id, { ip_address: details.NetworkSettings.IPAddress }, next); + this._db.instances.update(instance.id, { + ip_address: details.NetworkSettings.IPAddress + }, next); }); }); }, @@ -1285,10 +1315,11 @@ module.exports = class Data extends EventEmitter { VAsync.forEachParallel({ func: (instance, next) => { - this.updateInstance({ id: instance.id, status: 'RESTARTING' }, () => { - const container = this._docker.getContainer(instance.machine_id.split(/-/)[0]); - container.restart(next); - }); + if (!this._triton) { + return next(); + } + + this._triton.rebootMachine(instance.machine_id, next); }, inputs: instances }, (err, results) => { diff --git a/packages/portal-api/lib/watch/index.js b/packages/portal-api/lib/watch/index.js index db7a0e29..a448eb9f 100644 --- a/packages/portal-api/lib/watch/index.js +++ b/packages/portal-api/lib/watch/index.js @@ -31,7 +31,9 @@ module.exports = class Watcher { this._queues = {}; - this._tritonWatch.on('change', (container) => { return this.onChange(container); }); + this._tritonWatch.on('change', (container) => { + return this.onChange(container); + }); this._tritonWatch.on('all', (containers) => { containers.forEach((container) => { diff --git a/packages/portal-api/package.json b/packages/portal-api/package.json index 0a66cf18..43140a58 100644 --- a/packages/portal-api/package.json +++ b/packages/portal-api/package.json @@ -40,9 +40,9 @@ "param-case": "^2.1.1", "penseur": "^7.12.3", "piloted": "^3.1.1", - "portal-watch": "^1.0.0", "throat": "^4.0.0", "toppsy": "^1.1.0", + "triton": "^5.2.0", "triton-watch": "^1.1.0", "uuid": "^3.1.0", "vasync": "^1.6.4", diff --git a/packages/portal-api/server.js b/packages/portal-api/server.js index 038cc53f..d04428ab 100644 --- a/packages/portal-api/server.js +++ b/packages/portal-api/server.js @@ -51,6 +51,11 @@ const portalOptions = { key: DOCKER_CERT_PATH ? Fs.readFileSync(Path.join(DOCKER_CERT_PATH, 'key.pem')) : undefined + }, + triton: { + url: SDC_URL, + account: SDC_ACCOUNT, + keyId: SDC_KEY_ID } }, watch: {