forked from serverless/serverless-local-schedule
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
100 lines (85 loc) · 3.23 KB
/
index.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
const {localCrontabToUtcCrontabs} = require('local-crontab');
/**
* Convert an AWS CloudWatch crontab to a standard crontab.
*
* Main differences are:
* * A year field
* * ? instead of * sometimes
* * Some others.. implementation TBD
*
* The data that is removed is returned as well so that it can be used to
* roundtrip back to an AWS CloudWatch crontab
*
*/
const convertAwsToStandardCrontab = (awsCrontab) => {
const crontabParts = awsCrontab.split(/\s+/);
// standard crontabs don't have a year
const year = crontabParts.pop();
// replace ? with *, but remember where they were
const questionParts = [];
for (const i in crontabParts) {
if (crontabParts[i] === '?') {
questionParts.push(i);
crontabParts[i] = '*';
}
}
return {
crontab: crontabParts.join(' '),
awsSpecificDetails: {
year,
questionParts,
},
};
};
const convertStandardCrontabToAws = ({crontab, awsSpecificDetails}) => {
const parts = crontab.split(/\s+/);
for (const questionPart of awsSpecificDetails.questionParts) {
parts[questionPart] = parts[questionPart].replace(/\*/, '?');
}
parts.push(awsSpecificDetails.year);
return parts.join(' ');
};
const convertAwsLocalCrontabToAwsUtcCrontab = (localCrontab, timezone) => {
const {crontab, awsSpecificDetails} = convertAwsToStandardCrontab(localCrontab);
const utcCrontabs = localCrontabToUtcCrontabs(crontab, timezone);
return utcCrontabs.map((crontab) => convertStandardCrontabToAws({crontab, awsSpecificDetails}))
};
function convertCrontabs() {
this.serverless.cli.log('Converting local crontabs to UTC crontabs...');
for (const funcName in this.serverless.service.functions) {
for (const eventIndex in this.serverless.service.functions[funcName].events) {
const event = this.serverless.service.functions[funcName].events[eventIndex];
// only process events with a schedule & a timezone
if (event.hasOwnProperty('schedule') && event.schedule.hasOwnProperty('timezone')) {
const schedule = event.schedule;
const match = schedule.rate.match(/^cron\((.*)\)$/);
if (!match) // skip rate() schedules
continue;
// convert the local crontab to utc crontabs
const newCrontabs = convertAwsLocalCrontabToAwsUtcCrontab(match[1], schedule.timezone);
// remove the original schedule event
this.serverless.service.functions[funcName].events.splice(eventIndex, 1);
if (this.options.verbose || this.options.v) {
this.serverless.cli.log(`Converted ${match[1]} ${schedule.timezone} to
${newCrontabs.join('\n ')}`);
}
// remove timezone from original schedule event
delete schedule.timezone;
// append new utc crontab schedule events
this.serverless.service.functions[funcName].events.push(...newCrontabs.map((crontab) => ({
schedule: Object.assign({}, schedule, {rate: `cron(${crontab})`}),
})))
}
}
}
}
class ServerlessLocalCrontabs {
constructor(serverless, options) {
this.serverless = serverless;
this.options = options;
this.hooks = {
'before:package:initialize': convertCrontabs.bind(this),
};
}
}
module.exports = ServerlessLocalCrontabs;