-
Notifications
You must be signed in to change notification settings - Fork 16
/
checkin.js
128 lines (115 loc) · 4.31 KB
/
checkin.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
/* -----------------------------------------------------------------------------
* @copyright (C) 2017, Alert Logic, Inc
* @doc
*
* Lambda collector health check functions.
*
* @end
* -----------------------------------------------------------------------------
*/
const { CloudWatchEvents } = require("@aws-sdk/client-cloudwatch-events");
const { Lambda } = require("@aws-sdk/client-lambda");
const async = require('async');
const AlLogger = require('@alertlogic/al-aws-collector-js').Logger;
function checkCloudWatchEventsRule(event, finalCallback) {
var cwe = new CloudWatchEvents();
async.waterfall([
function(callback) {
cwe.describeRule({Name: event.CloudWatchEventsRule}, function(err, data) {
if (err) {
return callback(errorMsg('CWE00003', stringify(err)));
} else {
if (data.State === 'ENABLED' &&
data.EventPattern === event.CweRulePattern) {
return callback(null);
} else {
return callback(errorMsg('CWE00004', 'CWE Rule is incorrectly configured: ' + stringify(data)));
}
}
});
},
function(callback) {
cwe.listTargetsByRule({Rule: event.CloudWatchEventsRule}, function(err, data) {
if (err) {
return callback(errorMsg('CWE00005', stringify(err)));
} else {
if (data.Targets.length === 1 &&
data.Targets[0].Arn === event.KinesisArn) {
return callback(null);
} else {
return callback(errorMsg('CWE00006', 'CWE rule ' + event.CloudWatchEventsRule + ' has incorrect target set'));
}
}
});
}
], finalCallback);
}
function checkEventSourceMapping(checkinEvent, context, callback) {
var lambda = new Lambda();
lambda.listEventSourceMappings({FunctionName: context.functionName},
function(err, data) {
if (err) {
return callback(errorMsg('CWE00010', stringify(err)));
} else {
var eventSource = data.EventSourceMappings.find(
obj => obj.EventSourceArn === checkinEvent.KinesisArn);
if (eventSource) {
return checkEventSourceStatus(checkinEvent, eventSource, callback);
} else {
return callback(errorMsg(
'CWE00015',
'Event source mapping doesn\'t exist: ' + stringify(data)));
}
}
});
}
function checkEventSourceStatus(checkinEvent, eventSource, callback) {
var lastProcessingResult = eventSource.LastProcessingResult;
var state = eventSource.State;
if (state === 'Enabled' &&
(lastProcessingResult === 'OK' ||
// At this point the assumption is that all kinesis and events configuration
// around collect lambda is correct and 'No records processed'
// means just no events being generated.
lastProcessingResult === 'No records processed')) {
return callback(null);
} else {
return callback(errorMsg('CWE00020', 'Incorrect event source mapping status: ' + stringify(eventSource)));
}
}
function checkHealth(event, context, finalCallback) {
async.waterfall([
function(callback) {
checkCloudWatchEventsRule(event, callback);
},
function(callback) {
checkEventSourceMapping(event, context, callback);
}
],
function(errMsg) {
if (errMsg) {
AlLogger.warn('Health check failed with', errMsg);
return finalCallback(errMsg);
} else {
return finalCallback(null);
}
});
}
function stringify(jsonObj) {
return JSON.stringify(jsonObj, null, 0);
}
function errorMsg(code, message) {
return {
status: 'error',
code: code,
details: message
};
}
module.exports = {
checkHealth : function(event, context){
//close over the event and context to creat a function compatible with the framework.
return function(callback){
checkHealth(event, context, callback);
};
}
};