-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathhealth_checks.js
157 lines (144 loc) · 4.6 KB
/
health_checks.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* -----------------------------------------------------------------------------
* @copyright (C) 2018, Alert Logic, Inc
* @doc
*
* Halth check functions common for all collectors
*
* @end
* -----------------------------------------------------------------------------
*/
const { CloudFormation } = require("@aws-sdk/client-cloudformation");
const m_alAws = require('./al_aws');
const logger = require('./logger');
const INGEST_INVALID_ENCODING = {
code: 400
}
/**
* checks status of CF, returns error in case if it's in failed state, returns error.
* All custom healthchecks should follow the same interface as this function.
*
* @function
*
* @param {Object} event - checkin event for Lambda function, can be used to send needed parameters for health checks. Example: stackName.
* @param {Object} context - context of Lambda's function.
* @param {function} callback - callback, which is called by health check when it's done.
*
* @returns {function} callback(err)
*
* {ErrorMsg} err - The ErrorMsg object if an error occurred, null otherwise.
*
*/
function checkCloudFormationStatus(stackName, callback) {
var cloudformation = new CloudFormation({
maxAttempts:7,
retryDelayOptions: {
customBackoff: m_alAws.customBackoff
}
});
cloudformation.describeStacks({StackName: stackName}, function(err, data) {
if (err) {
return callback(errorMsg('ALAWS00001', stringify(err)));
} else {
var stackStatus = data.Stacks[0].StackStatus;
if (stackStatus === 'CREATE_COMPLETE' ||
stackStatus === 'UPDATE_COMPLETE' ||
stackStatus === 'UPDATE_IN_PROGRESS' ||
stackStatus === 'UPDATE_ROLLBACK_COMPLETE' ||
stackStatus === 'UPDATE_ROLLBACK_IN_PROGRESS' ||
stackStatus === 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS' ||
stackStatus === 'REVIEW_IN_PROGRESS') {
return callback(null);
} else {
return callback(errorMsg('ALAWS00002', 'CF stack has wrong status: ' + stackStatus));
}
}
});
}
function stringify(jsonObj) {
return JSON.stringify(jsonObj, null, 0);
}
/**
* @typedef {Object} ErrorMsg
* @property {string} status - status of healtcheck (ok, warning, error).
* @property {string} code - unique error code.
* @property {string} details - description of particular error.
*
*/
/**
* @function
*
* @param {string} code - error code
* @param {string} message - error message
*
* @returns {ErrorMsg} returns error message object
*/
function errorMsg(code, message) {
return {
status: 'error',
code: code,
details: message
};
}
/**
*
* @param {*} error
* @returns httpErrorCode
*/
function extractHttpErrorCode(error) {
let httpErrorCode;
if (typeof (error) === 'string') {
httpErrorCode = parseInt(error.slice(0, 3));
if (isNaN(httpErrorCode) && error.includes(':')) {
const splitErrorMessage = error.split(':');
httpErrorCode = parseInt(splitErrorMessage[1].replace(/ /, '').slice(0, 3));
}
} else {
httpErrorCode = error.response.status;
}
return httpErrorCode;
}
/**
*
* @param {*} code
* @param {*} message
* @param {*} httpErrorCode
* @returns errorObject
*/
function formatError(code, exception, type) {
const httpCode = extractHttpErrorCode(exception);
let errorObject = {
errorCode: code,
message: `${code} failed at ${type} : ${exception.message}`,
httpErrorCode: httpCode
}
return errorObject;
}
/**
*
* @param {*} error
* @param {*} param1 - S3 putObject parameters
* @param {*} callback
* @returns
*/
function handleIngestEncodingInvalidError(err, { data, key, bucketName }, callback) {
if (err.httpErrorCode === INGEST_INVALID_ENCODING.code) {
let bucket = bucketName ? bucketName : process.env.dl_s3_bucket_name;
if (bucket) {
m_alAws.uploadS3Object({ data, key, bucket }, (err) => {
if (err) {
logger.warn(`ALAWS00003 error while uploading the ${key} object in ${bucket} bucket : ${JSON.stringify(err)}`);
}
return callback(null);
});
}
else return callback(null);
}
else return callback(err);
}
module.exports = {
errorMsg : errorMsg,
checkCloudFormationStatus : checkCloudFormationStatus,
extractHttpErrorCode: extractHttpErrorCode,
formatError: formatError,
handleIngestEncodingInvalidError: handleIngestEncodingInvalidError
};