From 3fd18589a93358ce113fd98671593fc98128eb82 Mon Sep 17 00:00:00 2001 From: geek Date: Thu, 11 May 2017 15:18:51 -0500 Subject: [PATCH] Initial portal-data --- portal-data/.gitignore | 3 + portal-data/README.md | 1 + portal-data/lib/index.js | 164 ++++++++++++++++++++++++++++++++++++++ portal-data/package.json | 25 ++++++ portal-data/test/index.js | 57 +++++++++++++ 5 files changed, 250 insertions(+) create mode 100644 portal-data/.gitignore create mode 100644 portal-data/README.md create mode 100644 portal-data/lib/index.js create mode 100644 portal-data/package.json create mode 100644 portal-data/test/index.js diff --git a/portal-data/.gitignore b/portal-data/.gitignore new file mode 100644 index 00000000..825fc67c --- /dev/null +++ b/portal-data/.gitignore @@ -0,0 +1,3 @@ +node_modules +.DS_Store +npm-debug.log diff --git a/portal-data/README.md b/portal-data/README.md new file mode 100644 index 00000000..644a0fd9 --- /dev/null +++ b/portal-data/README.md @@ -0,0 +1 @@ +# portal-data diff --git a/portal-data/lib/index.js b/portal-data/lib/index.js new file mode 100644 index 00000000..fa886260 --- /dev/null +++ b/portal-data/lib/index.js @@ -0,0 +1,164 @@ +'use strict'; + +const Hoek = require('hoek'); +const Penseur = require('penseur'); + + +const internals = { + defaults: { + name: 'portal' + } +}; + + +module.exports = class Data { + constructor (options) { + const settings = Hoek.applyToDefaults(options || {}, internals.defaults); + const name = settings.name; + delete settings.name; + + // Penseur will assert that the options are correct + this._db = new Penseur.Db(name, settings); + } + + connect (cb) { + return new Promise((resolve, reject) => { + this._db.establish(['activities', 'datacenters', 'deployments', 'manifests', 'metrics'], (err) => { + if (typeof cb === 'function') { + return cb(err); + } + + if (err) { + return reject(err); + } + + resolve(); + }); + }); + } + + createDeployment (deployment) { + return new Promise((resolve, reject) => { + deployment.services = []; + deployment.state = { current: 'stopped' }; + + this._db.deployments.insert(deployment, (err, key) => { + if (err) { + return reject(err); + } + + deployment.id = key; + + resolve(deployment); + }); + }); + } + + getDeployment (id) { + return new Promise((resolve, reject) => { + this._db.deployments.get(id, (err, deployment) => { + return err ? reject(err) : resolve(deployment); + }); + }); + } + + updateDeployment (deployment) { + return new Promise((resolve, reject) => { + this._db.deployments.update(deployment.id, deployment, (err) => { + return err ? reject(err) : resolve(deployment); + }); + }); + } + + deleteDeployment (id) { + return new Promise((resolve, reject) => { + this._db.deployments.remove(id, (err) => { + return err ? reject(err) : resolve(); + }); + }); + } + + getDeployments () { + return new Promise((resolve, reject) => { + this._db.deployments.all((err, deployments) => { + return err ? reject(err) : resolve(deployments); + }); + }); + } + + getDatacenters () { + return new Promise((resolve, reject) => { + this._db.datacenters.all((err, datacenters) => { + return err ? reject(err) : resolve(datacenters || []); + }); + }); + } + + createManifest (deploymentId, manifest) { + return new Promise((resolve, reject) => { + manifest.deploymentId = deploymentId; + manifest.created = Date.now(); + + this._db.manifests.insert(manifest, (err, id) => { + if (err) { + return reject(err); + } + + manifest.id = id; + resolve(manifest); + }); + }); + } + getManifest (id) { + return new Promise((resolve, reject) => { + this._db.manifests.get(id, (err, manifest) => { + return err ? reject(err) : resolve(manifest); + }); + }); + } + + getActivities (deploymentId) { + return new Promise((resolve, reject) => { + this._db.activities.query({ deploymentId }, (err, activities) => { + return err ? reject(err) : resolve(activities || []); + }); + }); + } + + getMetrics (deploymentId) { + return new Promise((resolve, reject) => { + this._db.metrics.query({ deploymentId }, (err, metrics) => { + return err ? reject(err) : resolve(metrics || []); + }); + }); + } + + getServices (deploymentId) { + return new Promise((resolve, reject) => { + this._db.deployments.get(deploymentId, { filter: 'services' }, (err, deployment) => { + return err ? reject(err) : resolve(deployment.services); + }); + }); + } + updateService (deploymentId, service) { + return new Promise((resolve, reject) => { + this._db.deployments.get(deploymentId, { filter: 'services' }, (err, deployment) => { + if (err) { + return reject(err); + } + + const services = deployment.services.map((currentService) => { + if (currentService.name === service.name) { + currentService.count = service.count; + } + + return currentService; + }); + + this._db.deployments.update(deploymentId, { services }, (err, keys) => { + return err ? reject(err) : resolve(service); + }); + }); + }); + } +}; diff --git a/portal-data/package.json b/portal-data/package.json new file mode 100644 index 00000000..f8898c17 --- /dev/null +++ b/portal-data/package.json @@ -0,0 +1,25 @@ +{ + "name": "portal-data", + "version": "1.0.0", + "description": "portal data layer", + "main": "lib", + "scripts": { + "bootstrap": "node ./bootstrap-data", + "lint": "belly-button", + "rethinkdb-up": "docker run -d -p 8080:8080 -p 28015:28015 -p 29015:29015 --name rethinkdb rethinkdb", + "rethinkdb-down": "docker rm -f rethinkdb", + "test": "npm run lint && lab -t 40" + }, + "keywords": [], + "author": "wyatt", + "license": "MPL-2.0", + "devDependencies": { + "belly-button": "^3.1.0", + "code": "^4.0.0", + "lab": "^13.0.4" + }, + "dependencies": { + "hoek": "^4.1.1", + "penseur": "^7.8.1" + } +} diff --git a/portal-data/test/index.js b/portal-data/test/index.js new file mode 100644 index 00000000..653f1f06 --- /dev/null +++ b/portal-data/test/index.js @@ -0,0 +1,57 @@ +'use strict'; + +const Code = require('code'); +const Lab = require('lab'); +const PortalData = require('../'); + + +// Test shortcuts + +const lab = exports.lab = Lab.script(); +const describe = lab.describe; +const it = lab.it; +const expect = Code.expect; + + +const internals = { + options: { test: true, name: 'test' } +}; + + +describe('createDeployment()', () => { + it('creates a deployment record in the deployment table', (done) => { + const data = new PortalData(internals.options); + data.connect().then(() => { + const deployment = { + name: 'User Services', + datacenter: 'us-sw-1' + }; + + data.createDeployment(deployment).then((deployment) => { + expect(deployment.id).to.exist(); + done(); + }); + }); + }); +}); + + +describe('getDeployment()', () => { + it('will retrieve an existing deployment', (done) => { + const data = new PortalData(internals.options); + data.connect().then(() => { + const deployment = { + name: 'User Services', + datacenter: 'us-sw-1' + }; + + data.createDeployment(deployment).then((deployment) => { + expect(deployment.id).to.exist(); + data.getDeployment(deployment.id).then((retrievedDeployment) => { + expect(deployment).to.equal(retrievedDeployment); + done(); + }); + }); + }); + }); +});