Initial implementation
This commit is contained in:
parent
6ea3da5a9e
commit
98f2329fa0
@ -1 +1,7 @@
|
|||||||
# command-tower
|
# 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';
|
'use strict';
|
||||||
|
|
||||||
|
const Fs = require('fs');
|
||||||
const ControlTower = require('../');
|
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) => {
|
tower.start((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -5,12 +5,10 @@ const PortalData = require('portal-data');
|
|||||||
const VAsync = require('vasync');
|
const VAsync = require('vasync');
|
||||||
|
|
||||||
|
|
||||||
const internals = {};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = class {
|
module.exports = class {
|
||||||
constructor (options) {
|
constructor (options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
this._settings = options;
|
||||||
this._data = new PortalData(options.data);
|
this._data = new PortalData(options.data);
|
||||||
this._cmon = new CMonClient(options.cmon);
|
this._cmon = new CMonClient(options.cmon);
|
||||||
this._deployments = {};
|
this._deployments = {};
|
||||||
@ -25,6 +23,10 @@ module.exports = class {
|
|||||||
this._poll();
|
this._poll();
|
||||||
|
|
||||||
this._data.deploymentChanges((err, changes) => {
|
this._data.deploymentChanges((err, changes) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
if (changes) {
|
if (changes) {
|
||||||
this._refreshContainers(changes.id);
|
this._refreshContainers(changes.id);
|
||||||
}
|
}
|
||||||
@ -34,14 +36,13 @@ module.exports = class {
|
|||||||
|
|
||||||
_refreshContainers (deploymentId) {
|
_refreshContainers (deploymentId) {
|
||||||
this._data.getServices(deploymentId).then((services) => {
|
this._data.getServices(deploymentId).then((services) => {
|
||||||
this._deployments[deploymentId] = services.containers;
|
this._deployments[deploymentId] = services[0].containers;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_listContainers () {
|
_listContainers () {
|
||||||
let containers = [];
|
let containers = [];
|
||||||
const deploymentIds = Object.keys(this._deployments);
|
const deploymentIds = Object.keys(this._deployments);
|
||||||
|
|
||||||
deploymentIds.forEach((deploymentId) => {
|
deploymentIds.forEach((deploymentId) => {
|
||||||
containers = containers.concat(this._deployments[deploymentId]);
|
containers = containers.concat(this._deployments[deploymentId]);
|
||||||
});
|
});
|
||||||
@ -56,24 +57,68 @@ module.exports = class {
|
|||||||
|
|
||||||
const finish = () => {
|
const finish = () => {
|
||||||
this._isPolling = false;
|
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;
|
this._isPolling = true;
|
||||||
VAsync.forEachParallel({
|
VAsync.forEachParallel({
|
||||||
func: this._cmon.metrics,
|
func: (containerId, next) => {
|
||||||
inputs: this._listContainers()
|
this._cmon.metrics(containerId, (err, metrics) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
next(null, { containerId, metrics });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
inputs: containers
|
||||||
}, (err, results) => {
|
}, (err, results) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return finish();
|
return finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._saveMetrics(results, finish);
|
if (!results.successes || !results.successes.length) {
|
||||||
|
return finish();
|
||||||
|
}
|
||||||
|
this._saveMetrics(results.successes, finish);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_saveMetrics (metrics, 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();
|
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",
|
"lint": "belly-button",
|
||||||
"rethinkdb-up": "docker run -d -p 8080:8080 -p 28015:28015 -p 29015:29015 --name rethinkdb rethinkdb",
|
"rethinkdb-up": "docker run -d -p 8080:8080 -p 28015:28015 -p 29015:29015 --name rethinkdb rethinkdb",
|
||||||
"rethinkdb-down": "docker rm -f rethinkdb",
|
"rethinkdb-down": "docker rm -f rethinkdb",
|
||||||
"test": "npm run lint && lab -t 40"
|
"test": "npm run lint && lab"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "wyatt",
|
"author": "wyatt",
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const Code = require('code');
|
const Code = require('code');
|
||||||
const Lab = require('lab');
|
const Lab = require('lab');
|
||||||
const ControlTower = require('../');
|
|
||||||
|
|
||||||
|
|
||||||
// Test shortcuts
|
// Test shortcuts
|
||||||
@ -13,14 +12,9 @@ const it = lab.it;
|
|||||||
const expect = Code.expect;
|
const expect = Code.expect;
|
||||||
|
|
||||||
|
|
||||||
const internals = {
|
|
||||||
options: { data: { test: true, name: 'test' } }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
describe('start()', () => {
|
describe('start()', () => {
|
||||||
it.skip('starts to listen for service changes and monitors metrics', (done) => {
|
it.skip('starts to listen for service changes and monitors metrics', (done) => {
|
||||||
const controlTower = new ControlTower(internals.options);
|
expect(done).to.exist();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user