Initial implementation
This commit is contained in:
parent
6ea3da5a9e
commit
98f2329fa0
@ -1 +1,7 @@
|
||||
# command-tower
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
$ CMON_CERT_PATH=us-sw-1_api_joyent_com/cert.pem CMON_KEY_PATH=us-sw-1_api_joyent_com/key.pem control-tower
|
||||
```
|
||||
|
@ -2,9 +2,15 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const Fs = require('fs');
|
||||
const ControlTower = require('../');
|
||||
|
||||
const tower = new ControlTower();
|
||||
|
||||
const cert = process.env.CMON_CERT_PATH ? Fs.readFileSync(process.env.CMON_CERT_PATH) : process.env.CMON_CERT;
|
||||
const key = process.env.CMON_KEY_PATH ? Fs.readFileSync(process.env.CMON_KEY_PATH) : process.env.CMON_KEY;
|
||||
const datacenter = 'cmon.us-sw-1.triton.zone:9163';
|
||||
|
||||
const tower = new ControlTower({ cmon: { cert, key, datacenter } });
|
||||
tower.start((err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
|
@ -5,12 +5,10 @@ const PortalData = require('portal-data');
|
||||
const VAsync = require('vasync');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
module.exports = class {
|
||||
constructor (options) {
|
||||
options = options || {};
|
||||
this._settings = options;
|
||||
this._data = new PortalData(options.data);
|
||||
this._cmon = new CMonClient(options.cmon);
|
||||
this._deployments = {};
|
||||
@ -25,6 +23,10 @@ module.exports = class {
|
||||
this._poll();
|
||||
|
||||
this._data.deploymentChanges((err, changes) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
if (changes) {
|
||||
this._refreshContainers(changes.id);
|
||||
}
|
||||
@ -34,14 +36,13 @@ module.exports = class {
|
||||
|
||||
_refreshContainers (deploymentId) {
|
||||
this._data.getServices(deploymentId).then((services) => {
|
||||
this._deployments[deploymentId] = services.containers;
|
||||
this._deployments[deploymentId] = services[0].containers;
|
||||
});
|
||||
}
|
||||
|
||||
_listContainers () {
|
||||
let containers = [];
|
||||
const deploymentIds = Object.keys(this._deployments);
|
||||
|
||||
deploymentIds.forEach((deploymentId) => {
|
||||
containers = containers.concat(this._deployments[deploymentId]);
|
||||
});
|
||||
@ -56,24 +57,68 @@ module.exports = class {
|
||||
|
||||
const finish = () => {
|
||||
this._isPolling = false;
|
||||
setTimeout(() => this._poll(), 1000);
|
||||
setTimeout(() => { this._poll(); }, this._settings.frequency || 5000);
|
||||
};
|
||||
|
||||
const containers = this._listContainers();
|
||||
if (!containers || !containers.length) {
|
||||
return finish();
|
||||
}
|
||||
|
||||
|
||||
this._isPolling = true;
|
||||
VAsync.forEachParallel({
|
||||
func: this._cmon.metrics,
|
||||
inputs: this._listContainers()
|
||||
func: (containerId, next) => {
|
||||
this._cmon.metrics(containerId, (err, metrics) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
next(null, { containerId, metrics });
|
||||
});
|
||||
},
|
||||
inputs: containers
|
||||
}, (err, results) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return finish();
|
||||
}
|
||||
|
||||
this._saveMetrics(results, finish);
|
||||
if (!results.successes || !results.successes.length) {
|
||||
return finish();
|
||||
}
|
||||
this._saveMetrics(results.successes, finish);
|
||||
});
|
||||
}
|
||||
|
||||
_saveMetrics (metrics, cb) {
|
||||
cb();
|
||||
_saveMetrics (successes, cb) {
|
||||
const metricOperations = successes.map((success) => {
|
||||
const metrics = this._formatMetrics(success);
|
||||
return this._data.insertMetrics(success.containerId, metrics);
|
||||
});
|
||||
|
||||
Promise.all(metricOperations).then(() => {
|
||||
cb();
|
||||
}).catch((err) => {
|
||||
cb(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_formatMetrics (success) {
|
||||
const time = success.metrics.find((metric) => {
|
||||
if (metric.name === 'time_of_day') {
|
||||
return metric;
|
||||
}
|
||||
});
|
||||
|
||||
const formatted = success.metrics.map((metric) => {
|
||||
return {
|
||||
name: metric.name,
|
||||
value: metric.metrics[0].value,
|
||||
time: time.metrics[0].value
|
||||
};
|
||||
});
|
||||
|
||||
return formatted;
|
||||
}
|
||||
};
|
||||
|
@ -10,7 +10,7 @@
|
||||
"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"
|
||||
"test": "npm run lint && lab"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "wyatt",
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
const Code = require('code');
|
||||
const Lab = require('lab');
|
||||
const ControlTower = require('../');
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
@ -13,14 +12,9 @@ const it = lab.it;
|
||||
const expect = Code.expect;
|
||||
|
||||
|
||||
const internals = {
|
||||
options: { data: { test: true, name: 'test' } }
|
||||
};
|
||||
|
||||
|
||||
describe('start()', () => {
|
||||
it.skip('starts to listen for service changes and monitors metrics', (done) => {
|
||||
const controlTower = new ControlTower(internals.options);
|
||||
expect(done).to.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user