Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 40 additions & 23 deletions lib/utilities/healthcheckHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,7 @@ function writeResponse(res, error, log, results, cb) {
* @return {undefined}
*/
function clientCheck(flightCheckOnStartUp, log, cb) {
const clients = [
data,
metadata,
vault,
kms,
];
const clients = [data, metadata, vault, kms];
const clientTasks = [];
clients.forEach(client => {
if (typeof client.checkHealth === 'function') {
Expand All @@ -56,6 +51,24 @@ function clientCheck(flightCheckOnStartUp, log, cb) {
}
});
async.parallel(clientTasks, (err, results) => {
// Error's message/name/stack are non-enumerable, so JSON.stringify
// would drop them and log "error":{}. Copy them onto a plain object.
results.forEach(clientResult => {
Object.keys(clientResult).forEach(k => {
const e = clientResult[k] && clientResult[k].error;
if (e instanceof Error) {
// eslint-disable-next-line no-param-reassign
clientResult[k].error = {
...e,
message: e.message,
name: e.name,
...(e.code !== undefined && { code: e.code }),
...(e.statusCode !== undefined && { statusCode: e.statusCode }),
...(e.$metadata !== undefined && { $metadata: e.$metadata }),
};
}
});
});
// obj will be an object of the healthcheck results of
// every backends. No errors were returned directly to
// async.parallel in order to complete the check, so a
Expand All @@ -65,21 +78,27 @@ function clientCheck(flightCheckOnStartUp, log, cb) {
// Each result in the array represents one client (data, metadata, vault, kms)
// with its backend locations as keys.
// If ALL backend/locations of ANY client have errors, the overall check fails.
const { obj, fail } = results.reduce((acc, clientResult) => {
Object.assign(acc.obj, clientResult);
const { obj, fail } = results.reduce(
(acc, clientResult) => {
Object.assign(acc.obj, clientResult);

// Check if ALL backends/locations of this client have errors
const keys = Object.keys(clientResult);
// eslint-disable-next-line no-param-reassign
acc.fail ||= keys.length > 0 && keys.every(k =>
// if there is an error from an external backend,
// only return a 500 if it is on startup
// (flightCheckOnStartUp set to true)
clientResult[k].error && (flightCheckOnStartUp || !clientResult[k].external)
);
// Check if ALL backends/locations of this client have errors
const keys = Object.keys(clientResult);
// eslint-disable-next-line no-param-reassign
acc.fail ||=
keys.length > 0 &&
keys.every(
k =>
// if there is an error from an external backend,
// only return a 500 if it is on startup
// (flightCheckOnStartUp set to true)
clientResult[k].error && (flightCheckOnStartUp || !clientResult[k].external),
);

return acc;
}, { obj: {}, fail: false });
return acc;
},
{ obj: {}, fail: false },
);
if (fail) {
return cb(errors.InternalError, obj);
}
Expand All @@ -106,8 +125,7 @@ function routeHandler(deep, req, res, log, statsClient, cb) {
}

function checkIP(clientIP) {
return ipCheck.ipMatchCidrList(
_config.healthChecks.allowFrom, clientIP);
return ipCheck.ipMatchCidrList(_config.healthChecks.allowFrom, clientIP);
}

/**
Expand Down Expand Up @@ -139,8 +157,7 @@ function healthcheckHandler(clientIP, req, res, log, statsClient, deep) {
if (!checkIP(clientIP)) {
return healthcheckEndHandler(errors.AccessDenied, []);
}
return routeHandler(deep, req, res, log, statsClient,
healthcheckEndHandler);
return routeHandler(deep, req, res, log, statsClient, healthcheckEndHandler);
}

module.exports = {
Expand Down
Loading
Loading