ec2-instance-running-scheduler 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/devcontainer.json +54 -0
- package/.jsii +8966 -0
- package/API.md +1687 -0
- package/LICENSE +202 -0
- package/README.md +151 -0
- package/assets/funcs/running-scheduler.lambda/index.js +22982 -0
- package/assets/funcs/running-scheduler.lambda/index.js.map +7 -0
- package/lib/constructs/ec2-instance-running-scheduler.d.ts +62 -0
- package/lib/constructs/ec2-instance-running-scheduler.js +143 -0
- package/lib/funcs/running-scheduler-function.d.ts +13 -0
- package/lib/funcs/running-scheduler-function.js +23 -0
- package/lib/funcs/running-scheduler-predicates.d.ts +13 -0
- package/lib/funcs/running-scheduler-predicates.js +16 -0
- package/lib/funcs/running-scheduler.lambda.d.ts +34 -0
- package/lib/funcs/running-scheduler.lambda.js +261 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +22 -0
- package/lib/stacks/ec2-instance-running-schedule-stack.d.ts +31 -0
- package/lib/stacks/ec2-instance-running-schedule-stack.js +33 -0
- package/package.json +152 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EC2 Running Scheduler – Durable Functions implementation.
|
|
4
|
+
*
|
|
5
|
+
* Implements the running-control flow using AWS Lambda Durable Execution.
|
|
6
|
+
* Step checkpoints, wait (no charge), and parallel map provide a flow equivalent to Step Functions.
|
|
7
|
+
*
|
|
8
|
+
* @see https://docs.aws.amazon.com/lambda/latest/dg/durable-execution-sdk.html
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.handler = void 0;
|
|
12
|
+
const durable_execution_sdk_js_1 = require("@aws/durable-execution-sdk-js");
|
|
13
|
+
const client_ec2_1 = require("@aws-sdk/client-ec2");
|
|
14
|
+
const client_resource_groups_tagging_api_1 = require("@aws-sdk/client-resource-groups-tagging-api");
|
|
15
|
+
const web_api_1 = require("@slack/web-api");
|
|
16
|
+
const aws_lambda_secret_fetcher_1 = require("aws-lambda-secret-fetcher");
|
|
17
|
+
const safe_env_getter_1 = require("safe-env-getter");
|
|
18
|
+
const running_scheduler_predicates_1 = require("./running-scheduler-predicates");
|
|
19
|
+
/** Mapping of EC2 instance state to display name and emoji for Slack. */
|
|
20
|
+
const STATE_LIST = [
|
|
21
|
+
{ name: 'RUNNING', emoji: '😆', state: 'running' },
|
|
22
|
+
{ name: 'STOPPED', emoji: '😴', state: 'stopped' },
|
|
23
|
+
];
|
|
24
|
+
/** Seconds to wait between polling instance state after start/stop. */
|
|
25
|
+
const STATUS_CHANGE_WAIT_SECONDS = 20;
|
|
26
|
+
/**
|
|
27
|
+
* Returns display name and emoji for an EC2 instance state.
|
|
28
|
+
*
|
|
29
|
+
* @param current - Current instance state (e.g. 'running', 'stopped').
|
|
30
|
+
* @returns Display info or undefined if state is not in STATE_LIST.
|
|
31
|
+
*/
|
|
32
|
+
const getStateDisplay = (current) => {
|
|
33
|
+
const found = STATE_LIST.find((s) => s.state === current);
|
|
34
|
+
return found ? { emoji: found.emoji, name: found.name } : undefined;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Processes one EC2 instance: describes state, issues start/stop when needed, then polls until
|
|
38
|
+
* {@link isDesiredStableState} is satisfied (durable `step` / `wait` between attempts).
|
|
39
|
+
*
|
|
40
|
+
* @param ctx - Durable execution context (child context per instance recommended).
|
|
41
|
+
* @param targetResource - EC2 instance ARN.
|
|
42
|
+
* @param params - Scheduler params (`TagKey`, `TagValues`, `Mode`).
|
|
43
|
+
* @param resourceIndex - Index used in durable step names for this resource.
|
|
44
|
+
* @returns Final resource ARN, EC2 state name, parsed account, region, and instance id.
|
|
45
|
+
* @throws {Error} If the state is neither actionable, transitioning, nor the desired stable state.
|
|
46
|
+
*/
|
|
47
|
+
const processOneResource = async (ctx, targetResource, params, resourceIndex) => {
|
|
48
|
+
const parts = targetResource.split('/');
|
|
49
|
+
const identifier = parts[parts.length - 1] ?? 'unknown';
|
|
50
|
+
const arnParts = targetResource.split(':');
|
|
51
|
+
const account = arnParts[4] ?? '';
|
|
52
|
+
const region = arnParts[3] ?? '';
|
|
53
|
+
const stepPrefix = `resource-${resourceIndex}-${identifier}`;
|
|
54
|
+
ctx.logger.info('processOneResource: start', {
|
|
55
|
+
resourceIndex,
|
|
56
|
+
identifier,
|
|
57
|
+
region,
|
|
58
|
+
account,
|
|
59
|
+
mode: params.Mode,
|
|
60
|
+
});
|
|
61
|
+
let loopCount = 0;
|
|
62
|
+
let currentState = '';
|
|
63
|
+
do {
|
|
64
|
+
currentState = await ctx.step(`${stepPrefix}-describe-${loopCount}`, async () => {
|
|
65
|
+
const ec2 = new client_ec2_1.EC2Client({});
|
|
66
|
+
const out = await ec2.send(new client_ec2_1.DescribeInstancesCommand({ InstanceIds: [identifier] }));
|
|
67
|
+
return out.Reservations?.[0]?.Instances?.[0]?.State?.Name ?? 'unknown';
|
|
68
|
+
});
|
|
69
|
+
ctx.logger.info('processOneResource: described', {
|
|
70
|
+
identifier,
|
|
71
|
+
loopCount,
|
|
72
|
+
currentState,
|
|
73
|
+
mode: params.Mode,
|
|
74
|
+
});
|
|
75
|
+
const mode = params.Mode;
|
|
76
|
+
if (mode === 'Start' && currentState === 'stopped') {
|
|
77
|
+
ctx.logger.info('processOneResource: starting instance', { identifier, loopCount });
|
|
78
|
+
await ctx.step(`${stepPrefix}-start-${loopCount}`, async () => {
|
|
79
|
+
const ec2 = new client_ec2_1.EC2Client({});
|
|
80
|
+
await ec2.send(new client_ec2_1.StartInstancesCommand({ InstanceIds: [identifier] }));
|
|
81
|
+
});
|
|
82
|
+
ctx.logger.info('processOneResource: wait after start', {
|
|
83
|
+
identifier,
|
|
84
|
+
seconds: STATUS_CHANGE_WAIT_SECONDS,
|
|
85
|
+
});
|
|
86
|
+
await ctx.wait({ seconds: STATUS_CHANGE_WAIT_SECONDS });
|
|
87
|
+
loopCount += 1;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (mode === 'Stop' && currentState === 'running') {
|
|
91
|
+
ctx.logger.info('processOneResource: stopping instance', { identifier, loopCount });
|
|
92
|
+
await ctx.step(`${stepPrefix}-stop-${loopCount}`, async () => {
|
|
93
|
+
const ec2 = new client_ec2_1.EC2Client({});
|
|
94
|
+
await ec2.send(new client_ec2_1.StopInstancesCommand({ InstanceIds: [identifier] }));
|
|
95
|
+
});
|
|
96
|
+
ctx.logger.info('processOneResource: wait after stop', {
|
|
97
|
+
identifier,
|
|
98
|
+
seconds: STATUS_CHANGE_WAIT_SECONDS,
|
|
99
|
+
});
|
|
100
|
+
await ctx.wait({ seconds: STATUS_CHANGE_WAIT_SECONDS });
|
|
101
|
+
loopCount += 1;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (!(0, running_scheduler_predicates_1.isDesiredStableState)(mode, currentState)) {
|
|
105
|
+
const transitioning = (mode === 'Start' && currentState === 'pending') ||
|
|
106
|
+
(mode === 'Stop' && (currentState === 'stopping' || currentState === 'shutting-down'));
|
|
107
|
+
if (transitioning) {
|
|
108
|
+
ctx.logger.info('processOneResource: wait while transitioning', {
|
|
109
|
+
identifier,
|
|
110
|
+
loopCount,
|
|
111
|
+
currentState,
|
|
112
|
+
mode,
|
|
113
|
+
seconds: STATUS_CHANGE_WAIT_SECONDS,
|
|
114
|
+
});
|
|
115
|
+
await ctx.wait({ seconds: STATUS_CHANGE_WAIT_SECONDS });
|
|
116
|
+
loopCount += 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
ctx.logger.error('processOneResource: unexpected state', {
|
|
120
|
+
identifier,
|
|
121
|
+
mode,
|
|
122
|
+
currentState,
|
|
123
|
+
loopCount,
|
|
124
|
+
});
|
|
125
|
+
throw new Error(`instance status fail: mode=${mode} currentState=${currentState}`);
|
|
126
|
+
}
|
|
127
|
+
} while (!(0, running_scheduler_predicates_1.isDesiredStableState)(params.Mode, currentState));
|
|
128
|
+
ctx.logger.info('processOneResource: reached desired stable state', {
|
|
129
|
+
identifier,
|
|
130
|
+
finalState: currentState,
|
|
131
|
+
mode: params.Mode,
|
|
132
|
+
loopCount,
|
|
133
|
+
});
|
|
134
|
+
return {
|
|
135
|
+
identifier,
|
|
136
|
+
account,
|
|
137
|
+
region,
|
|
138
|
+
resource: targetResource,
|
|
139
|
+
status: currentState,
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Durable Lambda entry point for the EC2 running scheduler.
|
|
144
|
+
*
|
|
145
|
+
* Resolves instances via Resource Groups Tagging API, runs {@link processOneResource} for each ARN
|
|
146
|
+
* in parallel (bounded concurrency), posts a parent Slack message and per-instance thread replies,
|
|
147
|
+
* and uses durable `step` / `wait` / `map` so the run can resume across suspensions.
|
|
148
|
+
*
|
|
149
|
+
* @param event - Payload from EventBridge Scheduler; must include `Params.TagKey`, `Params.TagValues`, `Params.Mode`.
|
|
150
|
+
* @param ctx - Root durable execution context.
|
|
151
|
+
* @returns
|
|
152
|
+
* - `{ status: 'TargetResourcesNotFound' }` when no instances match the tag filter.
|
|
153
|
+
* - `{ status: 'Completed', processed, results }` when instances were handled (`results` entries match {@link processOneResource}).
|
|
154
|
+
* @throws {Error} If `Params` is invalid, `SLACK_SECRET_NAME` is unset, the Slack secret is incomplete, or instance processing fails.
|
|
155
|
+
*/
|
|
156
|
+
exports.handler = (0, durable_execution_sdk_js_1.withDurableExecution)(async (event, ctx) => {
|
|
157
|
+
const params = event.Params;
|
|
158
|
+
ctx.logger.info('running-scheduler: invocation', {
|
|
159
|
+
mode: params?.Mode,
|
|
160
|
+
tagKey: params?.TagKey,
|
|
161
|
+
tagValueCount: params?.TagValues?.length ?? 0,
|
|
162
|
+
});
|
|
163
|
+
if (!params?.TagKey || !params?.TagValues || !params?.Mode) {
|
|
164
|
+
throw new Error('Invalid event: Params.TagKey, Params.TagValues, Params.Mode are required.');
|
|
165
|
+
}
|
|
166
|
+
// safe get Secrets name from environment variable
|
|
167
|
+
const slackSecretName = safe_env_getter_1.SafeEnvGetter.getEnv('SLACK_SECRET_NAME');
|
|
168
|
+
const slackSecretValue = await ctx.step('fetch-slack-secret', async () => {
|
|
169
|
+
ctx.logger.info('running-scheduler: fetching Slack secret', { secretName: slackSecretName });
|
|
170
|
+
return aws_lambda_secret_fetcher_1.secretFetcher.getSecretValue(slackSecretName);
|
|
171
|
+
});
|
|
172
|
+
ctx.logger.info('running-scheduler: Slack secret loaded');
|
|
173
|
+
if (!slackSecretValue?.token || !slackSecretValue?.channel) {
|
|
174
|
+
throw new Error('Slack secret must contain token and channel.');
|
|
175
|
+
}
|
|
176
|
+
const targetResources = await ctx.step('get-target-resources', async () => {
|
|
177
|
+
const client = new client_resource_groups_tagging_api_1.ResourceGroupsTaggingAPIClient({});
|
|
178
|
+
const result = await client.send(new client_resource_groups_tagging_api_1.GetResourcesCommand({
|
|
179
|
+
ResourceTypeFilters: ['ec2:instance'],
|
|
180
|
+
TagFilters: [{ Key: params.TagKey, Values: params.TagValues }],
|
|
181
|
+
}));
|
|
182
|
+
const arns = (result.ResourceTagMappingList ?? [])
|
|
183
|
+
.map((m) => m.ResourceARN)
|
|
184
|
+
.filter((arn) => arn != null);
|
|
185
|
+
ctx.logger.info('running-scheduler: get-target-resources done', { count: arns.length });
|
|
186
|
+
return arns;
|
|
187
|
+
});
|
|
188
|
+
if (targetResources.length === 0) {
|
|
189
|
+
ctx.logger.info('running-scheduler: no matching instances', { tagKey: params.TagKey });
|
|
190
|
+
return { status: 'TargetResourcesNotFound' };
|
|
191
|
+
}
|
|
192
|
+
const client = new web_api_1.WebClient(slackSecretValue.token);
|
|
193
|
+
const channel = slackSecretValue.channel;
|
|
194
|
+
ctx.logger.info('running-scheduler: posting parent Slack message', {
|
|
195
|
+
instanceCount: targetResources.length,
|
|
196
|
+
});
|
|
197
|
+
// send slack message
|
|
198
|
+
const slackParentMessageResult = await ctx.step('post-slack-messages', async () => {
|
|
199
|
+
return client.chat.postMessage({
|
|
200
|
+
channel,
|
|
201
|
+
text: `${params.Mode === 'Start' ? '😆 Starts' : '🥱 Stops'} the scheduled EC2 Instance.`,
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
ctx.logger.info('running-scheduler: parent Slack message posted', {
|
|
205
|
+
threadTs: slackParentMessageResult?.ts ?? null,
|
|
206
|
+
});
|
|
207
|
+
ctx.logger.info('running-scheduler: starting parallel instance processing', {
|
|
208
|
+
count: targetResources.length,
|
|
209
|
+
maxConcurrency: 10,
|
|
210
|
+
});
|
|
211
|
+
const results = await ctx.map(targetResources,
|
|
212
|
+
// async (ctx: DurableContext, targetResource: string, index: number) =>
|
|
213
|
+
// ctx.step(`process-resource-${index}`, async () =>
|
|
214
|
+
// processOneResource(ctx, targetResource, params, index),
|
|
215
|
+
// ),
|
|
216
|
+
async (mapCtx, targetResource, index) => {
|
|
217
|
+
return mapCtx.runInChildContext(`resource-${index}`, async (childCtx) => {
|
|
218
|
+
const result = await processOneResource(childCtx, targetResource, params, index);
|
|
219
|
+
// if (result.status === 'skipped') {
|
|
220
|
+
// return result;
|
|
221
|
+
// }
|
|
222
|
+
childCtx.logger.info('running-scheduler: posting thread Slack message', {
|
|
223
|
+
index,
|
|
224
|
+
identifier: result.identifier,
|
|
225
|
+
status: result.status,
|
|
226
|
+
});
|
|
227
|
+
// send slack thread message
|
|
228
|
+
await childCtx.step('post-slack-child-messages', async () => {
|
|
229
|
+
const display = getStateDisplay(result.status);
|
|
230
|
+
return client.chat.postMessage({
|
|
231
|
+
channel,
|
|
232
|
+
thread_ts: slackParentMessageResult?.ts,
|
|
233
|
+
attachments: [
|
|
234
|
+
{
|
|
235
|
+
color: '#36a64f',
|
|
236
|
+
pretext: `${display?.emoji} The status of the EC2 Instance ${result.identifier} changed to ${display?.name} due to the schedule.`,
|
|
237
|
+
fields: [
|
|
238
|
+
{ title: 'Account', value: result.account, short: true },
|
|
239
|
+
{ title: 'Region', value: result.region, short: true },
|
|
240
|
+
{ title: 'Identifier', value: result.identifier, short: true },
|
|
241
|
+
{ title: 'Status', value: (display?.name ?? 'Unknown'), short: true },
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
return result;
|
|
248
|
+
});
|
|
249
|
+
}, { maxConcurrency: 10 });
|
|
250
|
+
const resultList = Array.isArray(results) ? results : [];
|
|
251
|
+
ctx.logger.info('running-scheduler: completed', {
|
|
252
|
+
processed: targetResources.length,
|
|
253
|
+
resultCount: resultList.length,
|
|
254
|
+
});
|
|
255
|
+
return {
|
|
256
|
+
status: 'Completed',
|
|
257
|
+
processed: targetResources.length,
|
|
258
|
+
results: resultList,
|
|
259
|
+
};
|
|
260
|
+
});
|
|
261
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVubmluZy1zY2hlZHVsZXIubGFtYmRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Z1bmNzL3J1bm5pbmctc2NoZWR1bGVyLmxhbWJkYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7R0FPRzs7O0FBRUgsNEVBQTBGO0FBQzFGLG9EQUs2QjtBQUM3QixvR0FBa0g7QUFDbEgsNENBQTJDO0FBQzNDLHlFQUEwRDtBQUMxRCxxREFBZ0Q7QUFDaEQsaUZBQXNFO0FBRXRFLHlFQUF5RTtBQUN6RSxNQUFNLFVBQVUsR0FBRztJQUNqQixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFO0lBQ2xELEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUU7Q0FDMUMsQ0FBQztBQUVYLHVFQUF1RTtBQUN2RSxNQUFNLDBCQUEwQixHQUFHLEVBQUUsQ0FBQztBQXNCdEM7Ozs7O0dBS0c7QUFDSCxNQUFNLGVBQWUsR0FBRyxDQUFDLE9BQWUsRUFBK0MsRUFBRTtJQUN2RixNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLE9BQU8sQ0FBQyxDQUFDO0lBQzFELE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUN0RSxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLEVBQzlCLEdBQW1CLEVBQ25CLGNBQXNCLEVBQ3RCLE1BQWdDLEVBQ2hDLGFBQXFCLEVBQytFLEVBQUU7SUFDdEcsTUFBTSxL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Q0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDhCQUE4QixFQUFFO1FBQzlDLFNBQVMsRUFBRSxlQUFlLENBQUMsTUFBTTtRQUNqQyxXQUFXLEVBQUUsVUFBVSxDQUFDLE1BQU07S0FDL0IsQ0FBQyxDQUFDO0lBQ0gsT0FBTztRQUNMLE1BQU0sRUFBRSxXQUFvQjtRQUM1QixTQUFTLEVBQUUsZUFBZSxDQUFDLE1BQU07UUFDakMsT0FBTyxFQUFFLFVBQVU7S0FDcEIsQ0FBQztBQUNKLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFQzIgUnVubmluZyBTY2hlZHVsZXIg4oCTIER1cmFibGUgRnVuY3Rpb25zIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIEltcGxlbWVudHMgdGhlIHJ1bm5pbmctY29udHJvbCBmbG93IHVzaW5nIEFXUyBMYW1iZGEgRHVyYWJsZSBFeGVjdXRpb24uXG4gKiBTdGVwIGNoZWNrcG9pbnRzLCB3YWl0IChubyBjaGFyZ2UpLCBhbmQgcGFyYWxsZWwgbWFwIHByb3ZpZGUgYSBmbG93IGVxdWl2YWxlbnQgdG8gU3RlcCBGdW5jdGlvbnMuXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGFtYmRhL2xhdGVzdC9kZy9kdXJhYmxlLWV4ZWN1dGlvbi1zZGsuaHRtbFxuICovXG5cbmltcG9ydCB7IHdpdGhEdXJhYmxlRXhlY3V0aW9uLCB0eXBlIER1cmFibGVDb250ZXh0IH0gZnJvbSAnQGF3cy9kdXJhYmxlLWV4ZWN1dGlvbi1zZGstanMnO1xuaW1wb3J0IHtcbiAgRUMyQ2xpZW50LFxuICBEZXNjcmliZUluc3RhbmNlc0NvbW1hbmQsXG4gIFN0YXJ0SW5zdGFuY2VzQ29tbWFuZCxcbiAgU3RvcEluc3RhbmNlc0NvbW1hbmQsXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1lYzInO1xuaW1wb3J0IHsgR2V0UmVzb3VyY2VzQ29tbWFuZCwgUmVzb3VyY2VHcm91cHNUYWdnaW5nQVBJQ2xpZW50IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXJlc291cmNlLWdyb3Vwcy10YWdnaW5nLWFwaSc7XG5pbXBvcnQgeyBXZWJDbGllbnQgfSBmcm9tICdAc2xhY2svd2ViLWFwaSc7XG5pbXBvcnQgeyBzZWNyZXRGZXRjaGVyIH0gZnJvbSAnYXdzLWxhbWJkYS1zZWNyZXQtZmV0Y2hlcic7XG5pbXBvcnQgeyBTYWZlRW52R2V0dGVyIH0gZnJvbSAnc2FmZS1lbnYtZ2V0dGVyJztcbmltcG9ydCB7IGlzRGVzaXJlZFN0YWJsZVN0YXRlIH0gZnJvbSAnLi9ydW5uaW5nLXNjaGVkdWxlci1wcmVkaWNhdGVzJztcblxuLyoqIE1hcHBpbmcgb2YgRUMyIGluc3RhbmNlIHN0YXRlIHRvIGRpc3BsYXkgbmFtZSBhbmQgZW1vamkgZm9yIFNsYWNrLiAqL1xuY29uc3QgU1RBVEVfTElTVCA9IFtcbiAgeyBuYW1lOiAnUlVOTklORycsIGVtb2ppOiAn8J+YhicsIHN0YXRlOiAncnVubmluZycgfSxcbiAgeyBuYW1lOiAnU1RPUFBFRCcsIGVtb2ppOiAn8J+YtCcsIHN0YXRlOiAnc3RvcHBlZCcgfSxcbl0gYXMgY29uc3Q7XG5cbi8qKiBTZWNvbmRzIHRvIHdhaXQgYmV0d2VlbiBwb2xsaW5nIGluc3RhbmNlIHN0YXRlIGFmdGVyIHN0YXJ0L3N0b3AuICovXG5jb25zdCBTVEFUVVNfQ0hBTkdFX1dBSVRfU0VDT05EUyA9IDIwO1xuXG4vKiogRXZlbnQgcGF5bG9hZCBmcm9tIEV2ZW50QnJpZGdlIFNjaGVkdWxlciBpbnZva2luZyB0aGlzIExhbWJkYS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2NoZWR1bGVyRXZlbnQge1xuICBQYXJhbXM6IHtcbiAgICAvKiogVGFnIGtleSB1c2VkIHRvIHNlbGVjdCBFQzIgaW5zdGFuY2VzLiAqL1xuICAgIFRhZ0tleTogc3RyaW5nO1xuICAgIC8qKiBUYWcgdmFsdWVzIHRvIG1hdGNoLiAqL1xuICAgIFRhZ1ZhbHVlczogc3RyaW5nW107XG4gICAgLyoqIFdoZXRoZXIgdG8gc3RhcnQgb3Igc3RvcCBpbnN0YW5jZXMuICovXG4gICAgTW9kZTogJ1N0YXJ0JyB8ICdTdG9wJztcbiAgfTtcbn1cblxuLyoqIFNsYWNrIGNyZWRlbnRpYWxzIGFuZCBkZWZhdWx0IGNoYW5uZWwgbG9hZGVkIGZyb20gU2VjcmV0cyBNYW5hZ2VyIChgU0xBQ0tfU0VDUkVUX05BTUVgKS4gKi9cbmludGVyZmFjZSBTbGFja1NlY3JldCB7XG4gIC8qKiBTbGFjayBib3QgdG9rZW4gZm9yIHRoZSBTbGFjayBgV2ViQ2xpZW50YC4gKi9cbiAgdG9rZW46IHN0cmluZztcbiAgLyoqIENoYW5uZWwgSUQgb3IgbmFtZSBwYXNzZWQgdG8gYGNoYXQucG9zdE1lc3NhZ2VgLiAqL1xuICBjaGFubmVsOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmV0dXJucyBkaXNwbGF5IG5hbWUgYW5kIGVtb2ppIGZvciBhbiBFQzIgaW5zdGFuY2Ugc3RhdGUuXG4gKlxuICogQHBhcmFtIGN1cnJlbnQgLSBDdXJyZW50IGluc3RhbmNlIHN0YXRlIChlLmcuICdydW5uaW5nJywgJ3N0b3BwZWQnKS5cbiAqIEByZXR1cm5zIERpc3BsYXkgaW5mbyBvciB1bmRlZmluZWQgaWYgc3RhdGUgaXMgbm90IGluIFNUQVRFX0xJU1QuXG4gKi9cbmNvbnN0IGdldFN0YXRlRGlzcGxheSA9IChjdXJyZW50OiBzdHJpbmcpOiB7IGVtb2ppOiBzdHJpbmc7IG5hbWU6IHN0cmluZyB9IHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgZm91bmQgPSBTVEFURV9MSVNULmZpbmQoKHMpID0+IHMuc3RhdGUgPT09IGN1cnJlbnQpO1xuICByZXR1cm4gZm91bmQgPyB7IGVtb2ppOiBmb3VuZC5lbW9qaSwgbmFtZTogZm91bmQubmFtZSB9IDogdW5kZWZpbmVkO1xufTtcblxuLyoqXG4gKiBQcm9jZXNzZXMgb25lIEVDMiBpbnN0YW5jZTogZGVzY3JpYmVzIHN0YXRlLCBpc3N1ZXMgc3RhcnQvc3RvcCB3aGVuIG5lZWRlZCwgdGhlbiBwb2xscyB1bnRpbFxuICoge0BsaW5rIGlzRGVzaXJlZFN0YWJsZVN0YXRlfSBpcyBzYXRpc2ZpZWQgKGR1cmFibGUgYHN0ZXBgIC8gYHdhaXRgIGJldHdlZW4gYXR0ZW1wdHMpLlxuICpcbiAqIEBwYXJhbSBjdHggLSBEdXJhYmxlIGV4ZWN1dGlvbiBjb250ZXh0IChjaGlsZCBjb250ZXh0IHBlciBpbnN0YW5jZSByZWNvbW1lbmRlZCkuXG4gKiBAcGFyYW0gdGFyZ2V0UmVzb3VyY2UgLSBFQzIgaW5zdGFuY2UgQVJOLlxuICogQHBhcmFtIHBhcmFtcyAtIFNjaGVkdWxlciBwYXJhbXMgKGBUYWdLZXlgLCBgVGFnVmFsdWVzYCwgYE1vZGVgKS5cbiAqIEBwYXJhbSByZXNvdXJjZUluZGV4IC0gSW5kZXggdXNlZCBpbiBkdXJhYmxlIHN0ZXAgbmFtZXMgZm9yIHRoaXMgcmVzb3VyY2UuXG4gKiBAcmV0dXJucyBGaW5hbCByZXNvdXJjZSBBUk4sIEVDMiBzdGF0ZSBuYW1lLCBwYXJzZWQgYWNjb3VudCwgcmVnaW9uLCBhbmQgaW5zdGFuY2UgaWQuXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHN0YXRlIGlzIG5laXRoZXIgYWN0aW9uYWJsZSwgdHJhbnNpdGlvbmluZywgbm9yIHRoZSBkZXNpcmVkIHN0YWJsZSBzdGF0ZS5cbiAqL1xuY29uc3QgcHJvY2Vzc09uZVJlc291cmNlID0gYXN5bmMgKFxuICBjdHg6IER1cmFibGVDb250ZXh0LFxuICB0YXJnZXRSZXNvdXJjZTogc3RyaW5nLFxuICBwYXJhbXM6IFNjaGVkdWxlckV2ZW50WydQYXJhbXMnXSxcbiAgcmVzb3VyY2VJbmRleDogbnVtYmVyLFxuKTogUHJvbWlzZTx7IHJlc291cmNlOiBzdHJpbmc7IHN0YXR1czogc3RyaW5nOyBhY2NvdW50OiBzdHJpbmc7IHJlZ2lvbjogc3RyaW5nOyBpZGVudGlmaWVyOiBzdHJpbmcgfT4gPT4ge1xuICBjb25zdCBwYXJ0cyA9IHRhcmdldFJlc291cmNlLnNwbGl0KCcvJyk7XG4gIGNvbnN0IGlkZW50aWZpZXIgPSBwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXSA/PyAndW5rbm93bic7XG4gIGNvbnN0IGFyblBhcnRzID0gdGFyZ2V0UmVzb3VyY2Uuc3BsaXQoJzonKTtcbiAgY29uc3QgYWNjb3VudCA9IGFyblBhcnRzWzRdID8/ICcnO1xuICBjb25zdCByZWdpb24gPSBhcm5QYXJ0c1szXSA/PyAnJztcbiAgY29uc3Qgc3RlcFByZWZpeCA9IGByZXNvdXJjZS0ke3Jlc291cmNlSW5kZXh9LSR7aWRlbnRpZmllcn1gO1xuXG4gIGN0eC5sb2dnZXIuaW5mbygncHJvY2Vzc09uZVJlc291cmNlOiBzdGFydCcsIHtcbiAgICByZXNvdXJjZUluZGV4LFxuICAgIGlkZW50aWZpZXIsXG4gICAgcmVnaW9uLFxuICAgIGFjY291bnQsXG4gICAgbW9kZTogcGFyYW1zLk1vZGUsXG4gIH0pO1xuXG4gIGxldCBsb29wQ291bnQgPSAwO1xuICBsZXQgY3VycmVudFN0YXRlID0gJyc7XG4gIGRvIHtcbiAgICBjdXJyZW50U3RhdGUgPSBhd2FpdCBjdHguc3RlcChgJHtzdGVwUHJlZml4fS1kZXNjcmliZS0ke2xvb3BDb3VudH1gLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBlYzIgPSBuZXcgRUMyQ2xpZW50KHt9KTtcbiAgICAgIGNvbnN0IG91dCA9IGF3YWl0IGVjMi5zZW5kKG5ldyBEZXNjcmliZUluc3RhbmNlc0NvbW1hbmQoeyBJbnN0YW5jZUlkczogW2lkZW50aWZpZXJdIH0pKTtcbiAgICAgIHJldHVybiBvdXQuUmVzZXJ2YXRpb25zPy5bMF0/Lkluc3RhbmNlcz8uWzBdPy5TdGF0ZT8uTmFtZSA/PyAndW5rbm93bic7XG4gICAgfSk7XG5cbiAgICBjdHgubG9nZ2VyLmluZm8oJ3Byb2Nlc3NPbmVSZXNvdXJjZTogZGVzY3JpYmVkJywge1xuICAgICAgaWRlbnRpZmllcixcbiAgICAgIGxvb3BDb3VudCxcbiAgICAgIGN1cnJlbnRTdGF0ZSxcbiAgICAgIG1vZGU6IHBhcmFtcy5Nb2RlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbW9kZSA9IHBhcmFtcy5Nb2RlO1xuXG4gICAgaWYgKG1vZGUgPT09ICdTdGFydCcgJiYgY3VycmVudFN0YXRlID09PSAnc3RvcHBlZCcpIHtcbiAgICAgIGN0eC5sb2dnZXIuaW5mbygncHJvY2Vzc09uZVJlc291cmNlOiBzdGFydGluZyBpbnN0YW5jZScsIHsgaWRlbnRpZmllciwgbG9vcENvdW50IH0pO1xuICAgICAgYXdhaXQgY3R4LnN0ZXAoYCR7c3RlcFByZWZpeH0tc3RhcnQtJHtsb29wQ291bnR9YCwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBlYzIgPSBuZXcgRUMyQ2xpZW50KHt9KTtcbiAgICAgICAgYXdhaXQgZWMyLnNlbmQobmV3IFN0YXJ0SW5zdGFuY2VzQ29tbWFuZCh7IEluc3RhbmNlSWRzOiBbaWRlbnRpZmllcl0gfSkpO1xuICAgICAgfSk7XG4gICAgICBjdHgubG9nZ2VyLmluZm8oJ3Byb2Nlc3NPbmVSZXNvdXJjZTogd2FpdCBhZnRlciBzdGFydCcsIHtcbiAgICAgICAgaWRlbnRpZmllcixcbiAgICAgICAgc2Vjb25kczogU1RBVFVTX0NIQU5HRV9XQUlUX1NFQ09ORFMsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGN0eC53YWl0KHsgc2Vjb25kczogU1RBVFVTX0NIQU5HRV9XQUlUX1NFQ09ORFMgfSk7XG4gICAgICBsb29wQ291bnQgKz0gMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChtb2RlID09PSAnU3RvcCcgJiYgY3VycmVudFN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgIGN0eC5sb2dnZXIuaW5mbygncHJvY2Vzc09uZVJlc291cmNlOiBzdG9wcGluZyBpbnN0YW5jZScsIHsgaWRlbnRpZmllciwgbG9vcENvdW50IH0pO1xuICAgICAgYXdhaXQgY3R4LnN0ZXAoYCR7c3RlcFByZWZpeH0tc3RvcC0ke2xvb3BDb3VudH1gLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVjMiA9IG5ldyBFQzJDbGllbnQoe30pO1xuICAgICAgICBhd2FpdCBlYzIuc2VuZChuZXcgU3RvcEluc3RhbmNlc0NvbW1hbmQoeyBJbnN0YW5jZUlkczogW2lkZW50aWZpZXJdIH0pKTtcbiAgICAgIH0pO1xuICAgICAgY3R4LmxvZ2dlci5pbmZvKCdwcm9jZXNzT25lUmVzb3VyY2U6IHdhaXQgYWZ0ZXIgc3RvcCcsIHtcbiAgICAgICAgaWRlbnRpZmllcixcbiAgICAgICAgc2Vjb25kczogU1RBVFVTX0NIQU5HRV9XQUlUX1NFQ09ORFMsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGN0eC53YWl0KHsgc2Vjb25kczogU1RBVFVTX0NIQU5HRV9XQUlUX1NFQ09ORFMgfSk7XG4gICAgICBsb29wQ291bnQgKz0gMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICghaXNEZXNpcmVkU3RhYmxlU3RhdGUobW9kZSwgY3VycmVudFN0YXRlKSkge1xuICAgICAgY29uc3QgdHJhbnNpdGlvbmluZyA9XG4gICAgICAgIChtb2RlID09PSAnU3RhcnQnICYmIGN1cnJlbnRTdGF0ZSA9PT0gJ3BlbmRpbmcnKSB8fFxuICAgICAgICAobW9kZSA9PT0gJ1N0b3AnICYmIChjdXJyZW50U3RhdGUgPT09ICdzdG9wcGluZycgfHwgY3VycmVudFN0YXRlID09PSAnc2h1dHRpbmctZG93bicpKTtcblxuICAgICAgaWYgKHRyYW5zaXRpb25pbmcpIHtcbiAgICAgICAgY3R4LmxvZ2dlci5pbmZvKCdwcm9jZXNzT25lUmVzb3VyY2U6IHdhaXQgd2hpbGUgdHJhbnNpdGlvbmluZycsIHtcbiAgICAgICAgICBpZGVudGlmaWVyLFxuICAgICAgICAgIGxvb3BDb3VudCxcbiAgICAgICAgICBjdXJyZW50U3RhdGUsXG4gICAgICAgICAgbW9kZSxcbiAgICAgICAgICBzZWNvbmRzOiBTVEFUVVNfQ0hBTkdFX1dBSVRfU0VDT05EUyxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IGN0eC53YWl0KHsgc2Vjb25kczogU1RBVFVTX0NIQU5HRV9XQUlUX1NFQ09ORFMgfSk7XG4gICAgICAgIGxvb3BDb3VudCArPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY3R4LmxvZ2dlci5lcnJvcigncHJvY2Vzc09uZVJlc291cmNlOiB1bmV4cGVjdGVkIHN0YXRlJywge1xuICAgICAgICBpZGVudGlmaWVyLFxuICAgICAgICBtb2RlLFxuICAgICAgICBjdXJyZW50U3RhdGUsXG4gICAgICAgIGxvb3BDb3VudCxcbiAgICAgIH0pO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnN0YW5jZSBzdGF0dXMgZmFpbDogbW9kZT0ke21vZGV9IGN1cnJlbnRTdGF0ZT0ke2N1cnJlbnRTdGF0ZX1gKTtcbiAgICB9XG4gIH0gd2hpbGUgKCFpc0Rlc2lyZWRTdGFibGVTdGF0ZShwYXJhbXMuTW9kZSwgY3VycmVudFN0YXRlKSk7XG5cbiAgY3R4LmxvZ2dlci5pbmZvKCdwcm9jZXNzT25lUmVzb3VyY2U6IHJlYWNoZWQgZGVzaXJlZCBzdGFibGUgc3RhdGUnLCB7XG4gICAgaWRlbnRpZmllcixcbiAgICBmaW5hbFN0YXRlOiBjdXJyZW50U3RhdGUsXG4gICAgbW9kZTogcGFyYW1zLk1vZGUsXG4gICAgbG9vcENvdW50LFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIGlkZW50aWZpZXIsXG4gICAgYWNjb3VudCxcbiAgICByZWdpb24sXG4gICAgcmVzb3VyY2U6IHRhcmdldFJlc291cmNlLFxuICAgIHN0YXR1czogY3VycmVudFN0YXRlLFxuICB9O1xufTtcblxuLyoqXG4gKiBEdXJhYmxlIExhbWJkYSBlbnRyeSBwb2ludCBmb3IgdGhlIEVDMiBydW5uaW5nIHNjaGVkdWxlci5cbiAqXG4gKiBSZXNvbHZlcyBpbnN0YW5jZXMgdmlhIFJlc291cmNlIEdyb3VwcyBUYWdnaW5nIEFQSSwgcnVucyB7QGxpbmsgcHJvY2Vzc09uZVJlc291cmNlfSBmb3IgZWFjaCBBUk5cbiAqIGluIHBhcmFsbGVsIChib3VuZGVkIGNvbmN1cnJlbmN5KSwgcG9zdHMgYSBwYXJlbnQgU2xhY2sgbWVzc2FnZSBhbmQgcGVyLWluc3RhbmNlIHRocmVhZCByZXBsaWVzLFxuICogYW5kIHVzZXMgZHVyYWJsZSBgc3RlcGAgLyBgd2FpdGAgLyBgbWFwYCBzbyB0aGUgcnVuIGNhbiByZXN1bWUgYWNyb3NzIHN1c3BlbnNpb25zLlxuICpcbiAqIEBwYXJhbSBldmVudCAtIFBheWxvYWQgZnJvbSBFdmVudEJyaWRnZSBTY2hlZHVsZXI7IG11c3QgaW5jbHVkZSBgUGFyYW1zLlRhZ0tleWAsIGBQYXJhbXMuVGFnVmFsdWVzYCwgYFBhcmFtcy5Nb2RlYC5cbiAqIEBwYXJhbSBjdHggLSBSb290IGR1cmFibGUgZXhlY3V0aW9uIGNvbnRleHQuXG4gKiBAcmV0dXJuc1xuICogLSBgeyBzdGF0dXM6ICdUYXJnZXRSZXNvdXJjZXNOb3RGb3VuZCcgfWAgd2hlbiBubyBpbnN0YW5jZXMgbWF0Y2ggdGhlIHRhZyBmaWx0ZXIuXG4gKiAtIGB7IHN0YXR1czogJ0NvbXBsZXRlZCcsIHByb2Nlc3NlZCwgcmVzdWx0cyB9YCB3aGVuIGluc3RhbmNlcyB3ZXJlIGhhbmRsZWQgKGByZXN1bHRzYCBlbnRyaWVzIG1hdGNoIHtAbGluayBwcm9jZXNzT25lUmVzb3VyY2V9KS5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBgUGFyYW1zYCBpcyBpbnZhbGlkLCBgU0xBQ0tfU0VDUkVUX05BTUVgIGlzIHVuc2V0LCB0aGUgU2xhY2sgc2VjcmV0IGlzIGluY29tcGxldGUsIG9yIGluc3RhbmNlIHByb2Nlc3NpbmcgZmFpbHMuXG4gKi9cbmV4cG9ydCBjb25zdCBoYW5kbGVyID0gd2l0aER1cmFibGVFeGVjdXRpb24oYXN5bmMgKGV2ZW50OiBTY2hlZHVsZXJFdmVudCwgY3R4OiBEdXJhYmxlQ29udGV4dCkgPT4ge1xuXG4gIGNvbnN0IHBhcmFtcyA9IGV2ZW50LlBhcmFtcztcblxuICBjdHgubG9nZ2VyLmluZm8oJ3J1bm5pbmctc2NoZWR1bGVyOiBpbnZvY2F0aW9uJywge1xuICAgIG1vZGU6IHBhcmFtcz8uTW9kZSxcbiAgICB0YWdLZXk6IHBhcmFtcz8uVGFnS2V5LFxuICAgIHRhZ1ZhbHVlQ291bnQ6IHBhcmFtcz8uVGFnVmFsdWVzPy5sZW5ndGggPz8gMCxcbiAgfSk7XG5cbiAgaWYgKCFwYXJhbXM/LlRhZ0tleSB8fCAhcGFyYW1zPy5UYWdWYWx1ZXMgfHwgIXBhcmFtcz8uTW9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBldmVudDogUGFyYW1zLlRhZ0tleSwgUGFyYW1zLlRhZ1ZhbHVlcywgUGFyYW1zLk1vZGUgYXJlIHJlcXVpcmVkLicpO1xuICB9XG5cbiAgLy8gc2FmZSBnZXQgU2VjcmV0cyBuYW1lIGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGVcbiAgY29uc3Qgc2xhY2tTZWNyZXROYW1lID0gU2FmZUVudkdldHRlci5nZXRFbnYoJ1NMQUNLX1NFQ1JFVF9OQU1FJyk7XG5cbiAgY29uc3Qgc2xhY2tTZWNyZXRWYWx1ZSA9IGF3YWl0IGN0eC5zdGVwKCdmZXRjaC1zbGFjay1zZWNyZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgY3R4LmxvZ2dlci5pbmZvKCdydW5uaW5nLXNjaGVkdWxlcjogZmV0Y2hpbmcgU2xhY2sgc2VjcmV0JywgeyBzZWNyZXROYW1lOiBzbGFja1NlY3JldE5hbWUgfSk7XG4gICAgcmV0dXJuIHNlY3JldEZldGNoZXIuZ2V0U2VjcmV0VmFsdWU8U2xhY2tTZWNyZXQ+KHNsYWNrU2VjcmV0TmFtZSk7XG4gIH0pO1xuXG4gIGN0eC5sb2dnZXIuaW5mbygncnVubmluZy1zY2hlZHVsZXI6IFNsYWNrIHNlY3JldCBsb2FkZWQnKTtcblxuICBpZiAoIXNsYWNrU2VjcmV0VmFsdWU/LnRva2VuIHx8ICFzbGFja1NlY3JldFZhbHVlPy5jaGFubmVsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTbGFjayBzZWNyZXQgbXVzdCBjb250YWluIHRva2VuIGFuZCBjaGFubmVsLicpO1xuICB9XG5cbiAgY29uc3QgdGFyZ2V0UmVzb3VyY2VzID0gYXdhaXQgY3R4LnN0ZXAoJ2dldC10YXJnZXQtcmVzb3VyY2VzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBSZXNvdXJjZUdyb3Vwc1RhZ2dpbmdBUElDbGllbnQoe30pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNsaWVudC5zZW5kKFxuICAgICAgbmV3IEdldFJlc291cmNlc0NvbW1hbmQoe1xuICAgICAgICBSZXNvdXJjZVR5cGVGaWx0ZXJzOiBbJ2VjMjppbnN0YW5jZSddLFxuICAgICAgICBUYWdGaWx0ZXJzOiBbeyBLZXk6IHBhcmFtcy5UYWdLZXksIFZhbHVlczogcGFyYW1zLlRhZ1ZhbHVlcyB9XSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgY29uc3QgYXJucyA9IChyZXN1bHQuUmVzb3VyY2VUYWdNYXBwaW5nTGlzdCA/PyBbXSlcbiAgICAgIC5tYXAoKG06IHsgUmVzb3VyY2VBUk4/OiBzdHJpbmcgfSkgPT4gbS5SZXNvdXJjZUFSTilcbiAgICAgIC5maWx0ZXIoKGFybjogc3RyaW5nIHwgdW5kZWZpbmVkKTogYXJuIGlzIHN0cmluZyA9PiBhcm4gIT0gbnVsbCk7XG4gICAgY3R4LmxvZ2dlci5pbmZvKCdydW5uaW5nLXNjaGVkdWxlcjogZ2V0LXRhcmdldC1yZXNvdXJjZXMgZG9uZScsIHsgY291bnQ6IGFybnMubGVuZ3RoIH0pO1xuICAgIHJldHVybiBhcm5zO1xuICB9KTtcblxuICBpZiAodGFyZ2V0UmVzb3VyY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgIGN0eC5sb2dnZXIuaW5mbygncnVubmluZy1zY2hlZHVsZXI6IG5vIG1hdGNoaW5nIGluc3RhbmNlcycsIHsgdGFnS2V5OiBwYXJhbXMuVGFnS2V5IH0pO1xuICAgIHJldHVybiB7IHN0YXR1czogJ1RhcmdldFJlc291cmNlc05vdEZvdW5kJyBhcyBjb25zdCB9O1xuICB9XG5cbiAgY29uc3QgY2xpZW50ID0gbmV3IFdlYkNsaWVudChzbGFja1NlY3JldFZhbHVlLnRva2VuKTtcbiAgY29uc3QgY2hhbm5lbCA9IHNsYWNrU2VjcmV0VmFsdWUuY2hhbm5lbDtcblxuICBjdHgubG9nZ2VyLmluZm8oJ3J1bm5pbmctc2NoZWR1bGVyOiBwb3N0aW5nIHBhcmVudCBTbGFjayBtZXNzYWdlJywge1xuICAgIGluc3RhbmNlQ291bnQ6IHRhcmdldFJlc291cmNlcy5sZW5ndGgsXG4gIH0pO1xuXG4gIC8vIHNlbmQgc2xhY2sgbWVzc2FnZVxuICBjb25zdCBzbGFja1BhcmVudE1lc3NhZ2VSZXN1bHQgPSBhd2FpdCBjdHguc3RlcCgncG9zdC1zbGFjay1tZXNzYWdlcycsIGFzeW5jICgpID0+IHtcbiAgICByZXR1cm4gY2xpZW50LmNoYXQucG9zdE1lc3NhZ2Uoe1xuICAgICAgY2hhbm5lbCxcbiAgICAgIHRleHQ6IGAke3BhcmFtcy5Nb2RlID09PSAnU3RhcnQnID8gJ/CfmIYgU3RhcnRzJyA6ICfwn6WxIFN0b3BzJ30gdGhlIHNjaGVkdWxlZCBFQzIgSW5zdGFuY2UuYCxcbiAgICB9KTtcbiAgfSk7XG5cbiAgY3R4LmxvZ2dlci5pbmZvKCdydW5uaW5nLXNjaGVkdWxlcjogcGFyZW50IFNsYWNrIG1lc3NhZ2UgcG9zdGVkJywge1xuICAgIHRocmVhZFRzOiBzbGFja1BhcmVudE1lc3NhZ2VSZXN1bHQ/LnRzID8/IG51bGwsXG4gIH0pO1xuXG4gIGN0eC5sb2dnZXIuaW5mbygncnVubmluZy1zY2hlZHVsZXI6IHN0YXJ0aW5nIHBhcmFsbGVsIGluc3RhbmNlIHByb2Nlc3NpbmcnLCB7XG4gICAgY291bnQ6IHRhcmdldFJlc291cmNlcy5sZW5ndGgsXG4gICAgbWF4Q29uY3VycmVuY3k6IDEwLFxuICB9KTtcblxuICBjb25zdCByZXN1bHRzID0gYXdhaXQgY3R4Lm1hcChcbiAgICB0YXJnZXRSZXNvdXJjZXMsXG4gICAgLy8gYXN5bmMgKGN0eDogRHVyYWJsZUNvbnRleHQsIHRhcmdldFJlc291cmNlOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+XG4gICAgLy8gICBjdHguc3RlcChgcHJvY2Vzcy1yZXNvdXJjZS0ke2luZGV4fWAsIGFzeW5jICgpID0+XG4gICAgLy8gICAgIHByb2Nlc3NPbmVSZXNvdXJjZShjdHgsIHRhcmdldFJlc291cmNlLCBwYXJhbXMsIGluZGV4KSxcbiAgICAvLyAgICksXG4gICAgYXN5bmMgKG1hcEN0eDogRHVyYWJsZUNvbnRleHQsIHRhcmdldFJlc291cmNlOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBtYXBDdHgucnVuSW5DaGlsZENvbnRleHQoYHJlc291cmNlLSR7aW5kZXh9YCwgYXN5bmMgKGNoaWxkQ3R4OiBEdXJhYmxlQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm9jZXNzT25lUmVzb3VyY2UoY2hpbGRDdHgsIHRhcmdldFJlc291cmNlLCBwYXJhbXMsIGluZGV4KTtcbiAgICAgICAgLy8gaWYgKHJlc3VsdC5zdGF0dXMgPT09ICdza2lwcGVkJykge1xuICAgICAgICAvLyAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIC8vIH1cbiAgICAgICAgY2hpbGRDdHgubG9nZ2VyLmluZm8oJ3J1bm5pbmctc2NoZWR1bGVyOiBwb3N0aW5nIHRocmVhZCBTbGFjayBtZXNzYWdlJywge1xuICAgICAgICAgIGluZGV4LFxuICAgICAgICAgIGlkZW50aWZpZXI6IHJlc3VsdC5pZGVudGlmaWVyLFxuICAgICAgICAgIHN0YXR1czogcmVzdWx0LnN0YXR1cyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHNlbmQgc2xhY2sgdGhyZWFkIG1lc3NhZ2VcbiAgICAgICAgYXdhaXQgY2hpbGRDdHguc3RlcCgncG9zdC1zbGFjay1jaGlsZC1tZXNzYWdlcycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBkaXNwbGF5ID0gZ2V0U3RhdGVEaXNwbGF5KHJlc3VsdC5zdGF0dXMpO1xuXG4gICAgICAgICAgcmV0dXJuIGNsaWVudC5jaGF0LnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIGNoYW5uZWwsXG4gICAgICAgICAgICB0aHJlYWRfdHM6IHNsYWNrUGFyZW50TWVzc2FnZVJlc3VsdD8udHMsXG4gICAgICAgICAgICBhdHRhY2htZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29sb3I6ICcjMzZhNjRmJyxcbiAgICAgICAgICAgICAgICBwcmV0ZXh0OiBgJHtkaXNwbGF5Py5lbW9qaX0gVGhlIHN0YXR1cyBvZiB0aGUgRUMyIEluc3RhbmNlICR7cmVzdWx0LmlkZW50aWZpZXJ9IGNoYW5nZWQgdG8gJHtkaXNwbGF5Py5uYW1lfSBkdWUgdG8gdGhlIHNjaGVkdWxlLmAsXG4gICAgICAgICAgICAgICAgZmllbGRzOiBbXG4gICAgICAgICAgICAgICAgICB7IHRpdGxlOiAnQWNjb3VudCcsIHZhbHVlOiByZXN1bHQuYWNjb3VudCwgc2hvcnQ6IHRydWUgfSxcbiAgICAgICAgICAgICAgICAgIHsgdGl0bGU6ICdSZWdpb24nLCB2YWx1ZTogcmVzdWx0LnJlZ2lvbiwgc2hvcnQ6IHRydWUgfSxcbiAgICAgICAgICAgICAgICAgIHsgdGl0bGU6ICdJZGVudGlmaWVyJywgdmFsdWU6IHJlc3VsdC5pZGVudGlmaWVyLCBzaG9ydDogdHJ1ZSB9LFxuICAgICAgICAgICAgICAgICAgeyB0aXRsZTogJ1N0YXR1cycsIHZhbHVlOiAoZGlzcGxheT8ubmFtZSA/PyAnVW5rbm93bicpLCBzaG9ydDogdHJ1ZSB9LFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgeyBtYXhDb25jdXJyZW5jeTogMTAgfSxcbiAgKTtcblxuICBjb25zdCByZXN1bHRMaXN0ID0gQXJyYXkuaXNBcnJheShyZXN1bHRzKSA/IHJlc3VsdHMgOiBbXTtcbiAgY3R4LmxvZ2dlci5pbmZvKCdydW5uaW5nLXNjaGVkdWxlcjogY29tcGxldGVkJywge1xuICAgIHByb2Nlc3NlZDogdGFyZ2V0UmVzb3VyY2VzLmxlbmd0aCxcbiAgICByZXN1bHRDb3VudDogcmVzdWx0TGlzdC5sZW5ndGgsXG4gIH0pO1xuICByZXR1cm4ge1xuICAgIHN0YXR1czogJ0NvbXBsZXRlZCcgYXMgY29uc3QsXG4gICAgcHJvY2Vzc2VkOiB0YXJnZXRSZXNvdXJjZXMubGVuZ3RoLFxuICAgIHJlc3VsdHM6IHJlc3VsdExpc3QsXG4gIH07XG59KTtcbiJdfQ==
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* Public API: EC2 instance running scheduler construct and stack.
|
|
19
|
+
*/
|
|
20
|
+
__exportStar(require("./constructs/ec2-instance-running-scheduler"), exports);
|
|
21
|
+
__exportStar(require("./stacks/ec2-instance-running-schedule-stack"), exports);
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztHQUVHO0FBQ0gsOEVBQTREO0FBQzVELCtFQUE2RCIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUHVibGljIEFQSTogRUMyIGluc3RhbmNlIHJ1bm5pbmcgc2NoZWR1bGVyIGNvbnN0cnVjdCBhbmQgc3RhY2suXG4gKi9cbmV4cG9ydCAqIGZyb20gJy4vY29uc3RydWN0cy9lYzItaW5zdGFuY2UtcnVubmluZy1zY2hlZHVsZXInO1xuZXhwb3J0ICogZnJvbSAnLi9zdGFja3MvZWMyLWluc3RhbmNlLXJ1bm5pbmctc2NoZWR1bGUtc3RhY2snOyJdfQ==
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Stack, StackProps } from 'aws-cdk-lib';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
import { TargetResource, Secrets, Schedule } from '../constructs/ec2-instance-running-scheduler';
|
|
4
|
+
/**
|
|
5
|
+
* Props for the EC2 instance running schedule CDK stack.
|
|
6
|
+
*/
|
|
7
|
+
export interface EC2InstanceRunningScheduleStackProps extends StackProps {
|
|
8
|
+
/** Tag-based target resource for EC2 instances to start/stop. */
|
|
9
|
+
readonly targetResource: TargetResource;
|
|
10
|
+
/** Whether scheduling is enabled. Defaults to true if omitted. */
|
|
11
|
+
readonly enableScheduling?: boolean;
|
|
12
|
+
/** Secrets (e.g. Slack) for the scheduler. */
|
|
13
|
+
readonly secrets: Secrets;
|
|
14
|
+
/** Cron schedule for stopping instances. */
|
|
15
|
+
readonly stopSchedule?: Schedule;
|
|
16
|
+
/** Cron schedule for starting instances. */
|
|
17
|
+
readonly startSchedule?: Schedule;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* CDK Stack that deploys the EC2 instance running scheduler (EventBridge Scheduler + Durable Lambda).
|
|
21
|
+
*/
|
|
22
|
+
export declare class EC2InstanceRunningScheduleStack extends Stack {
|
|
23
|
+
/**
|
|
24
|
+
* Creates the stack and the EC2InstanceRunningScheduler construct.
|
|
25
|
+
*
|
|
26
|
+
* @param scope - Parent construct.
|
|
27
|
+
* @param id - Stack id.
|
|
28
|
+
* @param props - Stack props (target resource, schedules, secrets).
|
|
29
|
+
*/
|
|
30
|
+
constructor(scope: Construct, id: string, props: EC2InstanceRunningScheduleStackProps);
|
|
31
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.EC2InstanceRunningScheduleStack = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
7
|
+
const ec2_instance_running_scheduler_1 = require("../constructs/ec2-instance-running-scheduler");
|
|
8
|
+
/**
|
|
9
|
+
* CDK Stack that deploys the EC2 instance running scheduler (EventBridge Scheduler + Durable Lambda).
|
|
10
|
+
*/
|
|
11
|
+
class EC2InstanceRunningScheduleStack extends aws_cdk_lib_1.Stack {
|
|
12
|
+
/**
|
|
13
|
+
* Creates the stack and the EC2InstanceRunningScheduler construct.
|
|
14
|
+
*
|
|
15
|
+
* @param scope - Parent construct.
|
|
16
|
+
* @param id - Stack id.
|
|
17
|
+
* @param props - Stack props (target resource, schedules, secrets).
|
|
18
|
+
*/
|
|
19
|
+
constructor(scope, id, props) {
|
|
20
|
+
super(scope, id, props);
|
|
21
|
+
new ec2_instance_running_scheduler_1.EC2InstanceRunningScheduler(this, 'EC2InstanceRunningScheduler', {
|
|
22
|
+
targetResource: props.targetResource,
|
|
23
|
+
enableScheduling: props.enableScheduling,
|
|
24
|
+
secrets: props.secrets,
|
|
25
|
+
stopSchedule: props.stopSchedule,
|
|
26
|
+
startSchedule: props.startSchedule,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.EC2InstanceRunningScheduleStack = EC2InstanceRunningScheduleStack;
|
|
31
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
32
|
+
EC2InstanceRunningScheduleStack[_a] = { fqn: "ec2-instance-running-scheduler.EC2InstanceRunningScheduleStack", version: "0.1.1" };
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWMyLWluc3RhbmNlLXJ1bm5pbmctc2NoZWR1bGUtc3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhY2tzL2VjMi1pbnN0YW5jZS1ydW5uaW5nLXNjaGVkdWxlLXN0YWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkNBQWdEO0FBRWhELGlHQUE4SDtBQWtCOUg7O0dBRUc7QUFDSCxNQUFhLCtCQUFnQyxTQUFRLG1CQUFLO0lBQ3hEOzs7Ozs7T0FNRztJQUNILFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBMkM7UUFDbkYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFeEIsSUFBSSw0REFBMkIsQ0FBQyxJQUFJLEVBQUUsNkJBQTZCLEVBQUU7WUFDbkUsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjO1lBQ3BDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7WUFDeEMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtZQUNoQyxhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7U0FDbkMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUFsQkgsMEVBbUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3RhY2ssIFN0YWNrUHJvcHMgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEVDMkluc3RhbmNlUnVubmluZ1NjaGVkdWxlciwgVGFyZ2V0UmVzb3VyY2UsIFNlY3JldHMsIFNjaGVkdWxlIH0gZnJvbSAnLi4vY29uc3RydWN0cy9lYzItaW5zdGFuY2UtcnVubmluZy1zY2hlZHVsZXInO1xuXG4vKipcbiAqIFByb3BzIGZvciB0aGUgRUMyIGluc3RhbmNlIHJ1bm5pbmcgc2NoZWR1bGUgQ0RLIHN0YWNrLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVDMkluc3RhbmNlUnVubmluZ1NjaGVkdWxlU3RhY2tQcm9wcyBleHRlbmRzIFN0YWNrUHJvcHMge1xuICAvKiogVGFnLWJhc2VkIHRhcmdldCByZXNvdXJjZSBmb3IgRUMyIGluc3RhbmNlcyB0byBzdGFydC9zdG9wLiAqL1xuICByZWFkb25seSB0YXJnZXRSZXNvdXJjZTogVGFyZ2V0UmVzb3VyY2U7XG4gIC8qKiBXaGV0aGVyIHNjaGVkdWxpbmcgaXMgZW5hYmxlZC4gRGVmYXVsdHMgdG8gdHJ1ZSBpZiBvbWl0dGVkLiAqL1xuICByZWFkb25seSBlbmFibGVTY2hlZHVsaW5nPzogYm9vbGVhbjtcbiAgLyoqIFNlY3JldHMgKGUuZy4gU2xhY2spIGZvciB0aGUgc2NoZWR1bGVyLiAqL1xuICByZWFkb25seSBzZWNyZXRzOiBTZWNyZXRzO1xuICAvKiogQ3JvbiBzY2hlZHVsZSBmb3Igc3RvcHBpbmcgaW5zdGFuY2VzLiAqL1xuICByZWFkb25seSBzdG9wU2NoZWR1bGU/OiBTY2hlZHVsZTtcbiAgLyoqIENyb24gc2NoZWR1bGUgZm9yIHN0YXJ0aW5nIGluc3RhbmNlcy4gKi9cbiAgcmVhZG9ubHkgc3RhcnRTY2hlZHVsZT86IFNjaGVkdWxlO1xufVxuXG4vKipcbiAqIENESyBTdGFjayB0aGF0IGRlcGxveXMgdGhlIEVDMiBpbnN0YW5jZSBydW5uaW5nIHNjaGVkdWxlciAoRXZlbnRCcmlkZ2UgU2NoZWR1bGVyICsgRHVyYWJsZSBMYW1iZGEpLlxuICovXG5leHBvcnQgY2xhc3MgRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVTdGFjayBleHRlbmRzIFN0YWNrIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIHN0YWNrIGFuZCB0aGUgRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVyIGNvbnN0cnVjdC5cbiAgICpcbiAgICogQHBhcmFtIHNjb3BlIC0gUGFyZW50IGNvbnN0cnVjdC5cbiAgICogQHBhcmFtIGlkIC0gU3RhY2sgaWQuXG4gICAqIEBwYXJhbSBwcm9wcyAtIFN0YWNrIHByb3BzICh0YXJnZXQgcmVzb3VyY2UsIHNjaGVkdWxlcywgc2VjcmV0cykuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVTdGFja1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG5cbiAgICBuZXcgRUMySW5zdGFuY2VSdW5uaW5nU2NoZWR1bGVyKHRoaXMsICdFQzJJbnN0YW5jZVJ1bm5pbmdTY2hlZHVsZXInLCB7XG4gICAgICB0YXJnZXRSZXNvdXJjZTogcHJvcHMudGFyZ2V0UmVzb3VyY2UsXG4gICAgICBlbmFibGVTY2hlZHVsaW5nOiBwcm9wcy5lbmFibGVTY2hlZHVsaW5nLFxuICAgICAgc2VjcmV0czogcHJvcHMuc2VjcmV0cyxcbiAgICAgIHN0b3BTY2hlZHVsZTogcHJvcHMuc3RvcFNjaGVkdWxlLFxuICAgICAgc3RhcnRTY2hlZHVsZTogcHJvcHMuc3RhcnRTY2hlZHVsZSxcbiAgICB9KTtcbiAgfVxufSJdfQ==
|
package/package.json
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ec2-instance-running-scheduler",
|
|
3
|
+
"repository": {
|
|
4
|
+
"type": "git",
|
|
5
|
+
"url": "https://github.com/gammarers-aws-cdk-constructs/ec2-instance-running-scheduler.git"
|
|
6
|
+
},
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "projen build",
|
|
9
|
+
"bump": "projen bump",
|
|
10
|
+
"bundle": "projen bundle",
|
|
11
|
+
"bundle:funcs/running-scheduler.lambda": "projen bundle:funcs/running-scheduler.lambda",
|
|
12
|
+
"bundle:funcs/running-scheduler.lambda:watch": "projen bundle:funcs/running-scheduler.lambda:watch",
|
|
13
|
+
"clobber": "projen clobber",
|
|
14
|
+
"compat": "projen compat",
|
|
15
|
+
"compile": "projen compile",
|
|
16
|
+
"default": "projen default",
|
|
17
|
+
"docgen": "projen docgen",
|
|
18
|
+
"eject": "projen eject",
|
|
19
|
+
"eslint": "projen eslint",
|
|
20
|
+
"package": "projen package",
|
|
21
|
+
"package-all": "projen package-all",
|
|
22
|
+
"package:js": "projen package:js",
|
|
23
|
+
"post-compile": "projen post-compile",
|
|
24
|
+
"post-upgrade": "projen post-upgrade",
|
|
25
|
+
"pre-compile": "projen pre-compile",
|
|
26
|
+
"release": "projen release",
|
|
27
|
+
"test": "projen test",
|
|
28
|
+
"test:watch": "projen test:watch",
|
|
29
|
+
"unbump": "projen unbump",
|
|
30
|
+
"upgrade": "projen upgrade",
|
|
31
|
+
"watch": "projen watch",
|
|
32
|
+
"projen": "projen"
|
|
33
|
+
},
|
|
34
|
+
"author": {
|
|
35
|
+
"name": "yicr",
|
|
36
|
+
"email": "yicr@users.noreply.github.com",
|
|
37
|
+
"organization": false
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@aws-sdk/client-ec2": "^3",
|
|
41
|
+
"@aws-sdk/client-resource-groups-tagging-api": "^3",
|
|
42
|
+
"@aws/durable-execution-sdk-js": "^1",
|
|
43
|
+
"@slack/web-api": "^6",
|
|
44
|
+
"@stylistic/eslint-plugin": "^2",
|
|
45
|
+
"@types/aws-lambda": "^8",
|
|
46
|
+
"@types/jest": "^29.5.14",
|
|
47
|
+
"@types/node": "^20",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^8",
|
|
49
|
+
"@typescript-eslint/parser": "^8",
|
|
50
|
+
"aws-cdk-lib": "2.232.0",
|
|
51
|
+
"aws-lambda-secret-fetcher": "^0.3",
|
|
52
|
+
"aws-sdk-client-mock": "^2",
|
|
53
|
+
"aws-sdk-client-mock-jest": "^2",
|
|
54
|
+
"commit-and-tag-version": "^12",
|
|
55
|
+
"constructs": "10.5.1",
|
|
56
|
+
"esbuild": "^0.28.0",
|
|
57
|
+
"eslint": "^9",
|
|
58
|
+
"eslint-import-resolver-typescript": "^3.10.1",
|
|
59
|
+
"eslint-plugin-import": "^2.32.0",
|
|
60
|
+
"jest": "^29.7.0",
|
|
61
|
+
"jest-junit": "^16",
|
|
62
|
+
"jsii": "5.9.x",
|
|
63
|
+
"jsii-diff": "^1.128.0",
|
|
64
|
+
"jsii-docgen": "^10.5.0",
|
|
65
|
+
"jsii-pacmak": "^1.128.0",
|
|
66
|
+
"jsii-rosetta": "5.9.x",
|
|
67
|
+
"projen": "^0.99.48",
|
|
68
|
+
"safe-env-getter": "^0.2",
|
|
69
|
+
"ts-jest": "^29.4.9",
|
|
70
|
+
"ts-node": "^10.9.2",
|
|
71
|
+
"typescript": "5.9.x"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"aws-cdk-lib": "^2.232.0",
|
|
75
|
+
"constructs": "^10.5.1"
|
|
76
|
+
},
|
|
77
|
+
"keywords": [
|
|
78
|
+
"cdk"
|
|
79
|
+
],
|
|
80
|
+
"engines": {
|
|
81
|
+
"node": ">= 20.0.0"
|
|
82
|
+
},
|
|
83
|
+
"devEngines": {
|
|
84
|
+
"packageManager": {
|
|
85
|
+
"name": "yarn",
|
|
86
|
+
"version": "1.22.22",
|
|
87
|
+
"onFail": "ignore"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"main": "lib/index.js",
|
|
91
|
+
"license": "Apache-2.0",
|
|
92
|
+
"publishConfig": {
|
|
93
|
+
"access": "public"
|
|
94
|
+
},
|
|
95
|
+
"version": "0.1.1",
|
|
96
|
+
"jest": {
|
|
97
|
+
"coverageProvider": "v8",
|
|
98
|
+
"testMatch": [
|
|
99
|
+
"<rootDir>/@(src|test)/**/*(*.)@(spec|test).ts?(x)",
|
|
100
|
+
"<rootDir>/@(src|test)/**/__tests__/**/*.ts?(x)",
|
|
101
|
+
"<rootDir>/@(projenrc)/**/*(*.)@(spec|test).ts?(x)",
|
|
102
|
+
"<rootDir>/@(projenrc)/**/__tests__/**/*.ts?(x)"
|
|
103
|
+
],
|
|
104
|
+
"clearMocks": true,
|
|
105
|
+
"collectCoverage": true,
|
|
106
|
+
"coverageReporters": [
|
|
107
|
+
"json",
|
|
108
|
+
"lcov",
|
|
109
|
+
"clover",
|
|
110
|
+
"cobertura",
|
|
111
|
+
"text"
|
|
112
|
+
],
|
|
113
|
+
"coverageDirectory": "coverage",
|
|
114
|
+
"coveragePathIgnorePatterns": [
|
|
115
|
+
"/node_modules/"
|
|
116
|
+
],
|
|
117
|
+
"testPathIgnorePatterns": [
|
|
118
|
+
"/node_modules/"
|
|
119
|
+
],
|
|
120
|
+
"watchPathIgnorePatterns": [
|
|
121
|
+
"/node_modules/"
|
|
122
|
+
],
|
|
123
|
+
"reporters": [
|
|
124
|
+
"default",
|
|
125
|
+
[
|
|
126
|
+
"jest-junit",
|
|
127
|
+
{
|
|
128
|
+
"outputDirectory": "test-reports"
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
],
|
|
132
|
+
"transform": {
|
|
133
|
+
"^.+\\.[t]sx?$": [
|
|
134
|
+
"ts-jest",
|
|
135
|
+
{
|
|
136
|
+
"tsconfig": "tsconfig.dev.json"
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"types": "lib/index.d.ts",
|
|
142
|
+
"stability": "stable",
|
|
143
|
+
"jsii": {
|
|
144
|
+
"outdir": "dist",
|
|
145
|
+
"targets": {},
|
|
146
|
+
"tsc": {
|
|
147
|
+
"outDir": "lib",
|
|
148
|
+
"rootDir": "src"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"."
|
|
152
|
+
}
|