This repository has been archived on 2024-07-12. You can view files and clone it, but cannot push or open issues or pull requests.
docker-discover/index.js

111 lines
3.0 KiB
JavaScript

require('require-yaml');
let Docker = require('dockerode');
let handlebars = require('handlebars');
let ssh = require('node-ssh');
let fs = require('fs');
let conf = require('./config.yml');
let docker;
let template;
let isProduction = process.env.NODE_ENV === 'production';
async function updateProxy() {
console.log('Updating reverse proxy configuration.');
let info;
if (!isProduction) {
info = require('./test.json');
} else {
info = {
services: await docker.listServices(),
nodes: await docker.listNodes()
};
}
let services = [];
for (let serviceInfo of info.services) {
let ports = serviceInfo.Endpoint.Ports;
if (!Array.isArray(ports) || !ports.length) continue;
let name = serviceInfo.Spec.Name;
let match = name.match(/(.+)_main$/);
if (match) name = match[1];
let service = {
name,
port: ports[0].PublishedPort,
nodes: []
};
services.push(service);
for (let node of info.nodes) {
let address = node.ManagerStatus
? node.ManagerStatus.Addr.split(':')[0]
: node.Status.Addr;
service.nodes.push({
name: node.Description.Hostname,
endpoint: `${address}:${service.port}`
});
}
}
let tmpConf = `/tmp/rproxy.${new Date().getTime()}`;
let configString = template({info, services});
fs.writeFileSync(tmpConf, configString);
if (conf.debug || !isProduction) {
let delimiter = '#'.repeat(80);
console.log(delimiter);
console.log(configString);
console.log(delimiter);
}
let files = {
local: tmpConf,
remote: conf.rproxy.confPath
};
for (let host of conf.rproxy.hosts) {
console.log(`Updating host: ${host}`);
if (!isProduction) continue;
let sshClient = new ssh();
await sshClient.connect(Object.assign({host}, conf.rproxy.auth));
await sshClient.putFiles([files]);
if (conf.rproxy.reloadCmd)
await ssh.exec(conf.rproxy.reloadCmd);
await sshClient.dispose();
}
fs.unlinkSync(tmpConf);
console.log('Configuration updated.');
}
(async() => {
let timeoutId;
docker = new Docker(conf.docker);
template = handlebars.compile(fs.readFileSync('rproxy.handlebars', 'utf8'));
await updateProxy();
console.log('Listenig for events.')
docker.getEvents({}, (err, stream) => {
if (err || !stream) {
console.error('Failed to monitor docker host', err);
return;
}
stream.on('data', event => {
event = JSON.parse(event);
if (conf.events && conf.events.indexOf(event.Type) == -1) return;
console.log(`Event: ${event.Type}: ${event.Action}`);
if (timeoutId) return;
timeoutId = setTimeout(async () => {
timeoutId = null;
await updateProxy();
}, conf.delay * 1000);
})
});
})();