Skip to content

Commit

Permalink
Merge pull request #11 from endlessm/T35672-support-redis-tls
Browse files Browse the repository at this point in the history
Allow connecting to Redis with TLS
  • Loading branch information
wjt authored Sep 30, 2024
2 parents 15ddd15 + 8373c45 commit 92bba54
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 12 deletions.
2 changes: 1 addition & 1 deletion api/activation.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const activation = (router, logger) => {
res.status(200)
.json({ success: true });
}).catch((err) => {
logger.error(err);
logger.error('Failed to save activation: ' + err);

res.status(500)
.json({ error: err.toString(),
Expand Down
2 changes: 1 addition & 1 deletion api/ping.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const ping = (router, logger) => {
res.status(200)
.json({ success: true });
}).catch((err) => {
logger.error(err);
logger.error('Failed to save ping: ' + err);

res.status(500)
.json({ error: err.toString(),
Expand Down
20 changes: 11 additions & 9 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,20 @@ app.use(api.router);

// Error handler
app.use((err, req, res, next) => {
if (err) {
logger.error(err);
logger.error(`while handling ${req.method} ${req.url}: ${err}`);

let errorMessage = "Server error";
if (process.env.NODE_ENV == 'test') {
errorMessage = err.toString() + '\n' + err.stack;
}
if (res.headersSent) {
return next(err);
}

res.status(500)
.json({ error: errorMessage,
success: false });
let errorMessage = "Server error";
if (process.env.NODE_ENV == 'test') {
errorMessage = err.stack;
}

res.status(500)
.json({ error: errorMessage,
success: false });
});

logger.info('Server starting on ' +
Expand Down
4 changes: 3 additions & 1 deletion config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ const server_bind_address = process.env.BIND_ADDRESS || '127.0.0.1';
const redis_host = process.env.REDIS_HOST || '127.0.0.1';
const redis_port = parseInt(process.env.REDIS_PORT, 10) || 6379;
const redis_password = process.env.REDIS_PASSWORD || '';
const redis_tls = ["true", "1"].includes((process.env.REDIS_TLS || '').toLowerCase());

// Crash handler
process.on('uncaughtException', (err) => {
logger.error(err.stack);
logger.error(`Uncaught exception: ${err.stack}`);
process.exit(1);
});

Expand All @@ -26,4 +27,5 @@ exports = module.exports = {
redis_host,
redis_port,
redis_password,
redis_tls,
};
46 changes: 46 additions & 0 deletions util/redis.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,56 @@ exports = module.exports = {
redisPort: config.redis_port,
redisPassword: config.redis_password,
getRedis: (callback) => {
/* ioredis uses tls.connect() if the tls option is set, and passes it as
* additional options to tls.connect().
*/
let tls = config.redis_tls ? {} : undefined;

const redis = new Redis({
host: config.redis_host,
port: config.redis_port,
password: config.redis_password,
tls,
reconnectOnError(err) {
/* Reconnect when ElastiCache has promoted some other node to primary &
* demoted the node we are connected to a replica.
* https://github.com/redis/ioredis/blob/main/README.md#reconnect-on-error
*/
var targetError = 'READONLY';
if (err.message.slice(0, targetError.length) === targetError) {
config.logger.info(`Reconnecting due to error: ${err.message}`);
/* Possible return values:
* - 0: don't reconnect
* - 1 or true: reconnect
* - 2: reconnect, and then resend the failed command
* Returning 2 is appealing but if, after reconnecting, the resent
* command fails with READONLY, then we will loop; and unlike in the
* case of a connection error, there is no backoff between
* reconnection attempts.
*
* The client (eos-phone-home) will retry failed requests on its next
* run (typically after 3 hours or after a network change) so it is
* not imperative to retry on the server.
*/
return 2;
}
},
});

redis.on('connect', () => {
config.logger.info('Connected to Redis server');
});
redis.on('ready', () => {
config.logger.info('Redis connection ready');
});
redis.on('reconnecting', (delay) => {
config.logger.info(`Reconnecting to ${config.redis_host}:${config.redis_port} in ${delay} ms`);
});
redis.on('close', () => {
config.logger.info('Disconnected from Redis server');
});
redis.on('error', (err) => {
config.logger.error('Error connecting to Redis server: ' + err);
});

callback(redis);
Expand Down

0 comments on commit 92bba54

Please sign in to comment.