feat(portal-api): add instance status data

This commit is contained in:
geek 2017-06-29 13:19:01 -05:00 committed by Sérgio Ramos
parent 05d0420813
commit 9c8ea8c489
4 changed files with 2504 additions and 2 deletions

View File

@ -7,6 +7,7 @@ const Data = require('./data');
const Pack = require('../package.json');
const Resolvers = require('./resolvers');
const Watch = require('./watch');
const WatchHealth = require('./watch/health');
const internals = {};
@ -18,8 +19,7 @@ module.exports = function (server, options, next) {
if (docker) {
options.data.dockerComposeHost = `tcp://${docker.address}:${docker.port}`;
}
}
catch (ex) {
} catch (ex) {
console.error(ex);
}
@ -34,6 +34,11 @@ module.exports = function (server, options, next) {
// but this works for now
data.setWatcher(watcher);
const healthWatcher = new WatchHealth(Object.assign(options.health, { data }));
healthWatcher.on('error', (err) => {
server.log(['error'], err);
});
data.on('error', (err) => {
server.log(['error'], err);
});
@ -47,6 +52,7 @@ module.exports = function (server, options, next) {
Piloted.on('refresh', internals.refresh(data));
watcher.poll();
healthWatcher.poll();
server.register([
{

View File

@ -0,0 +1,94 @@
'use strict';
const Events = require('events');
const Consulite = require('consulite');
const VAsync = require('vasync');
module.exports = class Health extends Events {
constructor (options) {
super();
options = options || {};
// todo assert options
this._data = options.data;
this._frequency = options.frequency || 2000;
// consul is the base url to the consul cluster
if (options.consul) {
Consulite.config({ consul: options.consul });
}
}
poll () {
if (this._timeoutId) {
return;
}
this._timeoutId = setTimeout(() => {
this.check((err) => {
if (err) {
this.emit('error', err);
}
delete this._timeoutId;
this.poll();
});
}, this._frequency);
}
check (cb) {
Consulite.getServiceNames((err, consulServices) => {
if (err) {
return cb(err);
}
// filter out telemetry services
consulServices = consulServices.filter((consulService) => {
return consulService !== 'containerpilot';
});
this._data.instances.all((err, instances) => {
if (err) {
return cb(err);
}
// we match consul nodes using the IP address
instances = instances.filter((instance) => {
return instance.ips && instance.ips.length;
});
VAsync.forEachParallel({
inputs: consulServices,
func: (consulService, next) => {
Consulite.getServiceStatus(consulService, (err, nodes) => {
if (err) {
return next(err);
}
this.findAndUpdateInstances(instances, nodes, next);
});
}
}, cb);
});
});
}
findAndUpdateInstances (instances, nodes, cb) {
VAsync.forEachPipeline({
inputs: nodes,
func: (node, next) => {
const instance = instances.find((instance) => {
return (instance.ips.indexOf(nodes.address) !== -1);
});
if (!instance) {
return next();
}
this._data.updateInstance({ id: instance.id, status: node.status }, next);
}
}, cb);
}
};

View File

@ -31,6 +31,7 @@
},
"dependencies": {
"boom": "^5.1.0",
"consulite": "^1.8.0",
"docker-compose-client": "^1.0.8",
"dockerode": "^2.5.0",
"graphi": "^2.2.1",

File diff suppressed because it is too large Load Diff