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
Raw Normal View History

2020-01-28 13:57:24 +00:00
require('require-yaml');
2020-01-27 16:25:39 +00:00
let Docker = require('dockerode');
let handlebars = require('handlebars');
let ssh = require('node-ssh');
let fs = require('fs');
2020-01-28 13:57:24 +00:00
let conf = require('./config.yml');
2020-01-27 16:25:39 +00:00
let docker;
let template;
2020-01-28 13:57:24 +00:00
let isProduction = process.env.NODE_ENV === 'production';
2020-01-27 16:25:39 +00:00
async function updateProxy() {
2020-01-28 13:57:24 +00:00
console.log('Updating reverse proxy configuration.');
let info;
2020-01-27 16:25:39 +00:00
2020-01-28 13:57:24 +00:00
if (!isProduction) {
info = require('./test.json');
2020-01-27 16:25:39 +00:00
} else {
2020-01-28 13:57:24 +00:00
info = {
2020-01-27 16:25:39 +00:00
services: await docker.listServices(),
nodes: await docker.listNodes()
};
}
2020-01-28 13:57:24 +00:00
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}`
});
}
}
2020-01-27 16:25:39 +00:00
let tmpConf = `/tmp/rproxy.${new Date().getTime()}`;
2020-01-28 13:57:24 +00:00
let configString = template({info, services});
2020-01-27 16:25:39 +00:00
fs.writeFileSync(tmpConf, configString);
2020-01-28 13:57:24 +00:00
if (conf.debug || !isProduction) {
2020-01-27 16:25:39 +00:00
let delimiter = '#'.repeat(80);
console.log(delimiter);
console.log(configString);
console.log(delimiter);
}
let files = {
local: tmpConf,
2020-01-28 13:57:24 +00:00
remote: conf.rproxy.confPath
2020-01-27 16:25:39 +00:00
};
2020-01-28 13:57:24 +00:00
for (let host of conf.rproxy.hosts) {
2020-01-27 16:25:39 +00:00
console.log(`Updating host: ${host}`);
2020-01-28 13:57:24 +00:00
if (!isProduction) continue;
2020-01-27 16:25:39 +00:00
let sshClient = new ssh();
2020-01-28 13:57:24 +00:00
await sshClient.connect(Object.assign({host}, conf.rproxy.auth));
2020-01-27 16:25:39 +00:00
await sshClient.putFiles([files]);
2020-01-28 13:57:24 +00:00
if (conf.rproxy.reloadCmd)
await ssh.exec(conf.rproxy.reloadCmd);
2020-01-27 16:25:39 +00:00
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'));
2020-01-28 13:57:24 +00:00
await updateProxy();
2020-01-27 16:25:39 +00:00
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;
2020-01-28 13:57:24 +00:00
timeoutId = setTimeout(async () => {
2020-01-27 16:25:39 +00:00
timeoutId = null;
2020-01-28 13:57:24 +00:00
await updateProxy();
2020-01-27 16:25:39 +00:00
}, conf.delay * 1000);
})
});
})();