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);
|
|
|
|
})
|
|
|
|
});
|
|
|
|
})();
|