mirror of
https://github.com/yldio/copilot.git
synced 2024-11-28 14:10:04 +02:00
feat(portal-api): add instance status data
This commit is contained in:
parent
05d0420813
commit
9c8ea8c489
@ -7,6 +7,7 @@ const Data = require('./data');
|
|||||||
const Pack = require('../package.json');
|
const Pack = require('../package.json');
|
||||||
const Resolvers = require('./resolvers');
|
const Resolvers = require('./resolvers');
|
||||||
const Watch = require('./watch');
|
const Watch = require('./watch');
|
||||||
|
const WatchHealth = require('./watch/health');
|
||||||
|
|
||||||
|
|
||||||
const internals = {};
|
const internals = {};
|
||||||
@ -18,8 +19,7 @@ module.exports = function (server, options, next) {
|
|||||||
if (docker) {
|
if (docker) {
|
||||||
options.data.dockerComposeHost = `tcp://${docker.address}:${docker.port}`;
|
options.data.dockerComposeHost = `tcp://${docker.address}:${docker.port}`;
|
||||||
}
|
}
|
||||||
}
|
} catch (ex) {
|
||||||
catch (ex) {
|
|
||||||
console.error(ex);
|
console.error(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +34,11 @@ module.exports = function (server, options, next) {
|
|||||||
// but this works for now
|
// but this works for now
|
||||||
data.setWatcher(watcher);
|
data.setWatcher(watcher);
|
||||||
|
|
||||||
|
const healthWatcher = new WatchHealth(Object.assign(options.health, { data }));
|
||||||
|
healthWatcher.on('error', (err) => {
|
||||||
|
server.log(['error'], err);
|
||||||
|
});
|
||||||
|
|
||||||
data.on('error', (err) => {
|
data.on('error', (err) => {
|
||||||
server.log(['error'], err);
|
server.log(['error'], err);
|
||||||
});
|
});
|
||||||
@ -47,6 +52,7 @@ module.exports = function (server, options, next) {
|
|||||||
|
|
||||||
Piloted.on('refresh', internals.refresh(data));
|
Piloted.on('refresh', internals.refresh(data));
|
||||||
watcher.poll();
|
watcher.poll();
|
||||||
|
healthWatcher.poll();
|
||||||
|
|
||||||
server.register([
|
server.register([
|
||||||
{
|
{
|
||||||
|
94
packages/portal-api/lib/watch/health.js
Normal file
94
packages/portal-api/lib/watch/health.js
Normal 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);
|
||||||
|
}
|
||||||
|
};
|
@ -31,6 +31,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"boom": "^5.1.0",
|
"boom": "^5.1.0",
|
||||||
|
"consulite": "^1.8.0",
|
||||||
"docker-compose-client": "^1.0.8",
|
"docker-compose-client": "^1.0.8",
|
||||||
"dockerode": "^2.5.0",
|
"dockerode": "^2.5.0",
|
||||||
"graphi": "^2.2.1",
|
"graphi": "^2.2.1",
|
||||||
|
2401
packages/portal-api/yarn.lock
Normal file
2401
packages/portal-api/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user