Skip to content

Commit 2520824

Browse files
committed
Proof of concept
1 parent e12143d commit 2520824

10 files changed

+791
-2
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
3+
config/*
4+
!config/*.example.js

README.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
# ConsulTemplate-NodeJS
2-
Like Consul-template, but different. And written in Node.js.
1+
# ConsulWatcher
2+
3+
This is a much simplified version of HashiCorp's Consul-Template, because what it accomplishes is awesome but I really dislike the Go template syntax. All configuration in this version are plain JavaScript.
4+
5+
It's main purpose is creating output files based on a Consul catalog, much like Consul-Template, but since the update handlers are just JavaScript functions you are free to do whatever you want, like calling a webservice or using a template library.

config/included.example.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = async (catalog, logger) =>
2+
{
3+
// Use catalog parameter to generate output
4+
};

config/index.example.js

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
const config = {
2+
onUpdate: [],
3+
afterUpdate: null
4+
};
5+
6+
7+
/*
8+
9+
Consul agent configuration
10+
Determines the agent or server which will be queried and
11+
monitored for the service catalog.
12+
13+
Recommended to be a local agent connected to the cluster.
14+
15+
Passed to the initialization of the Node Consul client.
16+
For all options, see: https://github.com/silas/node-consul#init
17+
18+
*/
19+
config.consul = {
20+
host: 'localhost'
21+
}
22+
23+
24+
25+
/*
26+
27+
Logging
28+
See: https://github.com/winstonjs/winston#transports
29+
30+
*/
31+
const winston = require('winston');
32+
33+
config.logging = {
34+
transports: [
35+
new winston.transports.Console({
36+
level: 'debug',
37+
timestamp: true,
38+
format: winston.format.combine(
39+
winston.format.colorize(),
40+
winston.format.simple()
41+
)
42+
})
43+
]
44+
};
45+
46+
47+
/*
48+
49+
onUpdate handlers
50+
When a change occurs in the Consul catalog, each handler is called in order.
51+
Callbacks may return a Promise. Note that when using multiple handlers,
52+
they are not awaited immediately but at the end using Promise.all(), which
53+
means the handlers effectively run in parallel.
54+
55+
The catalog parameter has a services property to enumerate the registered
56+
services. See the Readme for the documentation of the ConsulCatalog class.
57+
58+
For more information about a service, including it's address and health,
59+
an additional call to Consul is required. Calling these methods will result
60+
in the service being watched for changes as well.
61+
62+
The second parameter is a reference to the Winston logger instance.
63+
64+
*/
65+
const fs = require('fs').promises;
66+
67+
68+
config.onUpdate.push((catalog, logger) =>
69+
{
70+
// Use catalog parameter to generate output
71+
let output = '';
72+
73+
for (const service of catalog.services)
74+
{
75+
output +=
76+
`Service: ${service.name}
77+
Tags: ${JSON.stringify(service.tags)}
78+
Address: ${await service.getAddress()}
79+
Port: ${await service.getPort()}
80+
81+
`;
82+
};
83+
84+
await fs.writeFile('example-output.txt', output);
85+
});
86+
87+
88+
/*
89+
afterUpdate handler
90+
This is a single handler which is called after all the onUpdate handlers
91+
have finished, including any Promises returned.
92+
93+
It can be used for example to reload a proxy server after the configuration
94+
changes have been written in onUpdate.
95+
*/
96+
97+
config.afterUpdate = (catalog, logger) =>
98+
{
99+
// Call a reload script
100+
101+
}
102+
103+
104+
105+
module.exports = config;

consulwatcher.service

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[Unit]
2+
Description=ConsulWatcher
3+
Requires=network-online.target
4+
After=network-online.target
5+
6+
[Service]
7+
Restart=on-failure
8+
ExecStart=/usr/local/bin/node /srv/consulwatcher/index.js
9+
KillSignal=SIGINT
10+
11+
[Install]
12+
WantedBy=multi-user.target

index.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const ConsulCatalog = require('./lib/consulcatalog');
2+
const logger = require('./lib/logger');
3+
const config = require('./config');
4+
5+
const catalog = new ConsulCatalog(logger, config);
6+
7+
// TODO detect if the connection is down for too long, allow a custom notification to be sent
8+
9+
// TODO provide a way to easily switch between configs, for multiple environments

0 commit comments

Comments
 (0)