Issue/58 (#59)

* feature: provide a range of health check ports, HTTP_PORT to HTTP_PORT_MAX, bind to first available

* feature: provide a range of aws sns ports, AWS_SNS_PORT to AWS_SNS_PORT_MAX, bind to first available

* AWS SNS port range 3010-3019
This commit is contained in:
Dave Horton
2022-10-30 13:08:07 -04:00
committed by GitHub
parent 030059a596
commit 44d298a4f3
2 changed files with 51 additions and 11 deletions
+28 -6
View File
@@ -1,7 +1,7 @@
const Emitter = require('events');
const bent = require('bent');
const assert = require('assert');
const PORT = process.env.AWS_SNS_PORT || 3001;
const PORT = process.env.AWS_SNS_PORT || 3010;
const {LifeCycleEvents} = require('./constants');
const express = require('express');
const app = express();
@@ -21,6 +21,26 @@ class SnsNotifier extends Emitter {
this.logger = logger;
}
_doListen(logger, app, port, resolve) {
return app.listen(port, () => {
this.snsEndpoint = `http://${this.publicIp}:${port}`;
logger.info(`SNS lifecycle server listening on http://localhost:${port}`);
resolve(app);
});
}
_handleErrors(logger, app, resolve, reject, e) {
if (e.code === 'EADDRINUSE' &&
process.env.AWS_SNS_PORT_MAX &&
e.port < process.env.AWS_SNS_PORT_MAX) {
logger.info(`SNS lifecycle server failed to bind port on ${e.port}, will try next port`);
const server = this._doListen(logger, app, ++e.port, resolve);
server.on('error', this._handleErrors.bind(null, logger, app, resolve, reject));
return;
}
reject(e);
}
async _handlePost(req, res) {
try {
@@ -45,6 +65,7 @@ class SnsNotifier extends Emitter {
}, 'response from SNS SubscribeURL');
const data = await this.describeInstance();
this.lifecycleState = data.AutoScalingInstances[0].LifecycleState;
this.emit('SubscriptionConfirmation', {publicIp: this.publicIp});
break;
case 'Notification':
@@ -80,14 +101,12 @@ class SnsNotifier extends Emitter {
async init() {
try {
this.logger.info('SnsNotifier: retrieving instance data');
this.logger.debug('SnsNotifier: retrieving instance data');
this.instanceId = await getString('http://169.254.169.254/latest/meta-data/instance-id');
this.publicIp = await getString('http://169.254.169.254/latest/meta-data/public-ipv4');
this.snsEndpoint = `http://${this.publicIp}:${PORT}`;
this.logger.info({
instanceId: this.instanceId,
publicIp: this.publicIp,
snsEndpoint: this.snsEndpoint
publicIp: this.publicIp
}, 'retrieved AWS instance data');
// start listening
@@ -99,7 +118,10 @@ class SnsNotifier extends Emitter {
this.logger.error(err, 'burped error');
res.status(err.status || 500).json({msg: err.message});
});
app.listen(PORT);
return new Promise((resolve, reject) => {
const server = this._doListen(this.logger, app, PORT, resolve);
server.on('error', this._handleErrors.bind(null, this.logger, app, resolve, reject));
});
} catch (err) {
this.logger.error({err}, 'Error retrieving AWS instance metadata');
+23 -5
View File
@@ -71,6 +71,26 @@ const systemHealth = async(redisClient, ping, getCount) => {
return getCount();
};
const doListen = (logger, app, port, resolve) => {
return app.listen(port, () => {
logger.info(`Health check server listening on http://localhost:${port}`);
resolve(app);
});
};
const handleErrors = (logger, app, resolve, reject, e) => {
if (e.code === 'EADDRINUSE' &&
process.env.HTTP_PORT_MAX &&
e.port < process.env.HTTP_PORT_MAX) {
logger.info(`Health check server failed to bind port on ${e.port}, will try next port`);
const server = doListen(logger, app, ++e.port, resolve);
server.on('error', handleErrors.bind(null, logger, app, resolve, reject));
return;
}
reject(e);
};
const createHealthCheckApp = (port, logger) => {
const express = require('express');
const app = express();
@@ -78,11 +98,9 @@ const createHealthCheckApp = (port, logger) => {
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
return new Promise((resolve) => {
app.listen(port, () => {
logger.info(`Health check server started at http://localhost:${port}`);
resolve(app);
});
return new Promise((resolve, reject) => {
const server = doListen(logger, app, port, resolve);
server.on('error', handleErrors.bind(null, logger, app, resolve, reject));
});
};