@aws-cdk/toolkit-lib 1.29.1 → 1.31.0
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/build-info.json +2 -2
- package/lib/actions/bootstrap/index.js +35 -2
- package/lib/actions/diagnose/index.d.ts +28 -0
- package/lib/actions/diagnose/index.js +1 -1
- package/lib/actions/diff/private/helpers.js +36 -3
- package/lib/actions/validate/index.d.ts +2 -0
- package/lib/actions/validate/index.js +1 -1
- package/lib/api/aws-auth/account-cache.js +36 -3
- package/lib/api/aws-auth/sdk-provider.js +36 -3
- package/lib/api/aws-auth/sdk.d.ts +7 -2
- package/lib/api/aws-auth/sdk.js +6 -1
- package/lib/api/aws-auth/user-agent.js +35 -2
- package/lib/api/aws-auth/util.js +35 -2
- package/lib/api/bootstrap/bootstrap-environment.js +35 -2
- package/lib/api/bootstrap/deploy-bootstrap.js +37 -4
- package/lib/api/cloud-assembly/context-store.js +36 -3
- package/lib/api/cloud-assembly/environment.js +40 -4
- package/lib/api/cloud-assembly/private/context-aware-source.js +35 -2
- package/lib/api/cloud-assembly/private/exec.js +35 -2
- package/lib/api/cloud-assembly/private/prepare-source.js +39 -6
- package/lib/api/cloud-assembly/source-builder.js +37 -4
- package/lib/api/cloud-assembly/stack-assembly.js +8 -4
- package/lib/api/cloud-assembly/stack-collection.d.ts +2 -0
- package/lib/api/cloud-assembly/stack-collection.js +3 -1
- package/lib/api/cloudformation/logical-id-map.js +35 -2
- package/lib/api/cloudformation/nested-stack-helpers.js +36 -3
- package/lib/api/cloudformation/template-body-parameter.js +42 -6
- package/lib/api/deployments/asset-manifest-builder.js +35 -2
- package/lib/api/deployments/assets.js +42 -6
- package/lib/api/deployments/cfn-api.d.ts +4 -2
- package/lib/api/deployments/cfn-api.js +47 -6
- package/lib/api/deployments/deploy-stack.js +11 -6
- package/lib/api/deployments/deployments.js +42 -4
- package/lib/api/diagnosing/diagnosis-formatting.js +54 -13
- package/lib/api/diagnosing/format-utils.d.ts +32 -0
- package/lib/api/diagnosing/format-utils.js +176 -0
- package/lib/api/diagnosing/investigate-custom-resource.d.ts +17 -0
- package/lib/api/diagnosing/investigate-custom-resource.js +247 -0
- package/lib/api/diagnosing/investigate-ecs-service.d.ts +20 -0
- package/lib/api/diagnosing/investigate-ecs-service.js +242 -0
- package/lib/api/diagnosing/resource-identifiers.d.ts +39 -0
- package/lib/api/diagnosing/resource-identifiers.js +90 -0
- package/lib/api/diagnosing/resource-investigation.d.ts +13 -0
- package/lib/api/diagnosing/resource-investigation.js +22 -0
- package/lib/api/diagnosing/stack-diagnoser.d.ts +39 -3
- package/lib/api/diagnosing/stack-diagnoser.js +71 -30
- package/lib/api/diff/diff-formatter.js +11 -8
- package/lib/api/drift/drift-formatter.js +20 -17
- package/lib/api/garbage-collection/garbage-collector.js +7 -4
- package/lib/api/garbage-collection/progress-printer.js +7 -4
- package/lib/api/hotswap/hotswap-deployments.js +46 -10
- package/lib/api/hotswap/hotswap-template-cache.js +36 -3
- package/lib/api/io/private/io-default-messages.js +35 -2
- package/lib/api/io/private/message-maker.d.ts +4 -0
- package/lib/api/io/private/message-maker.js +3 -1
- package/lib/api/io/private/messages.d.ts +2 -0
- package/lib/api/io/private/messages.js +44 -3
- package/lib/api/io/private/span.js +35 -2
- package/lib/api/logs-monitor/logs-monitor.js +40 -4
- package/lib/api/network-detector/network-detector.js +37 -4
- package/lib/api/notices/cached-data-source.js +35 -2
- package/lib/api/notices/filter.js +35 -2
- package/lib/api/notices/notices.js +35 -2
- package/lib/api/notices/web-data-source.js +35 -2
- package/lib/api/refactoring/digest.js +35 -2
- package/lib/api/refactoring/stack-definitions.js +40 -4
- package/lib/api/resource-import/importer.js +58 -15
- package/lib/api/resource-import/migrator.js +42 -6
- package/lib/api/rwlock.js +35 -2
- package/lib/api/settings.js +38 -5
- package/lib/api/source-tracing/private/stack-source-tracing.js +38 -5
- package/lib/api/stack-events/resource-errors.d.ts +12 -0
- package/lib/api/stack-events/resource-errors.js +2 -1
- package/lib/api/stack-events/stack-activity-monitor.js +35 -2
- package/lib/api/stack-events/stack-progress-monitor.js +35 -2
- package/lib/api/toolkit-info.js +7 -4
- package/lib/api/tree.js +36 -3
- package/lib/api/validate/validate-formatting.d.ts +9 -2
- package/lib/api/validate/validate-formatting.js +161 -77
- package/lib/api/work-graph/build-destroy-work-graph.js +35 -2
- package/lib/api/work-graph/work-graph-builder.js +35 -2
- package/lib/context-providers/index.js +35 -2
- package/lib/private/activity-printer/current.js +52 -16
- package/lib/private/activity-printer/history.js +50 -14
- package/lib/private/tools.js +64 -25
- package/lib/toolkit/non-interactive-io-host.js +11 -8
- package/lib/toolkit/private/collect-annotation-report.d.ts +12 -0
- package/lib/toolkit/private/collect-annotation-report.js +118 -0
- package/lib/toolkit/private/validation-report.d.ts +32 -0
- package/lib/toolkit/private/validation-report.js +152 -0
- package/lib/toolkit/toolkit-error.d.ts +20 -0
- package/lib/toolkit/toolkit-error.js +30 -2
- package/lib/toolkit/toolkit.d.ts +12 -7
- package/lib/toolkit/toolkit.js +104 -101
- package/lib/toolkit/types.d.ts +1 -0
- package/lib/toolkit/types.js +1 -1
- package/lib/util/content-hash.js +35 -2
- package/lib/util/directories.js +38 -5
- package/lib/util/glob-matcher.d.ts +19 -7
- package/lib/util/glob-matcher.js +63 -14
- package/lib/util/guess-language.js +36 -3
- package/lib/util/package-info.js +35 -2
- package/lib/util/serialize.js +36 -3
- package/lib/util/version-range.js +35 -2
- package/lib/util/yaml-cfn.js +36 -3
- package/package.json +5 -5
- package/lib/api/diagnosing/tree-builder.d.ts +0 -13
- package/lib/api/diagnosing/tree-builder.js +0 -86
- package/lib/api/diagnosing/tree.d.ts +0 -19
- package/lib/api/diagnosing/tree.js +0 -72
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sideBySide = sideBySide;
|
|
4
|
+
exports.wrapText = wrapText;
|
|
5
|
+
exports.trimToRecentLines = trimToRecentLines;
|
|
6
|
+
exports.parseLambdaLogEvents = parseLambdaLogEvents;
|
|
7
|
+
exports.cloudWatchLogsConsoleUrl = cloudWatchLogsConsoleUrl;
|
|
8
|
+
function sideBySide(left, sep, right) {
|
|
9
|
+
const width = left.map(x => x.length).reduce((acc, n) => Math.max(acc, n), 0);
|
|
10
|
+
const ret = [];
|
|
11
|
+
for (let i = 0; i < left.length || i < right.length; i++) {
|
|
12
|
+
const l = i < left.length ? left[i] : ' '.repeat(width);
|
|
13
|
+
const r = i < right.length ? right[i] : '';
|
|
14
|
+
ret.push(`${l}${sep}${r}`);
|
|
15
|
+
}
|
|
16
|
+
return ret;
|
|
17
|
+
}
|
|
18
|
+
function wrapText(n, text) {
|
|
19
|
+
const breakers = [' ', '\n'];
|
|
20
|
+
const ret = [];
|
|
21
|
+
let lineStart = 0;
|
|
22
|
+
while (lineStart < text.length) {
|
|
23
|
+
let lineEnd = lineStart + n;
|
|
24
|
+
while (lineEnd > lineStart && lineEnd < text.length && !breakers.includes(text[lineEnd])) {
|
|
25
|
+
lineEnd -= 1;
|
|
26
|
+
}
|
|
27
|
+
if (lineEnd === lineStart) {
|
|
28
|
+
// Could not find a space in this line. Seek forward to the first space to get the smallest line overflow
|
|
29
|
+
lineEnd = lineStart + n;
|
|
30
|
+
while (lineEnd < text.length && !breakers.includes(text[lineEnd])) {
|
|
31
|
+
lineEnd += 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
ret.push(text.slice(lineStart, lineEnd));
|
|
35
|
+
lineStart = lineEnd + 1;
|
|
36
|
+
}
|
|
37
|
+
return ret;
|
|
38
|
+
}
|
|
39
|
+
// --- CloudWatch log formatting ---
|
|
40
|
+
/**
|
|
41
|
+
* Maximum number of log lines included per CloudWatch Logs context block.
|
|
42
|
+
*
|
|
43
|
+
* The formatter renders the messages array verbatim, so this is the
|
|
44
|
+
* single user-visible cap.
|
|
45
|
+
*/
|
|
46
|
+
const MAX_LOG_LINES = 50;
|
|
47
|
+
/**
|
|
48
|
+
* Trim already-extracted log lines to the set we render.
|
|
49
|
+
*
|
|
50
|
+
* Keeps only the most recent {@link MAX_LOG_LINES} (newer output is more useful for
|
|
51
|
+
* diagnosis) and prepends an "N earlier lines omitted" marker when truncation happened.
|
|
52
|
+
* This is the single truncation point shared by all CloudWatch contexts — the formatter
|
|
53
|
+
* renders the result verbatim.
|
|
54
|
+
*/
|
|
55
|
+
function trimToRecentLines(lines) {
|
|
56
|
+
const messages = lines.slice(-MAX_LOG_LINES);
|
|
57
|
+
const omitted = lines.length - messages.length;
|
|
58
|
+
if (omitted > 0) {
|
|
59
|
+
messages.unshift(`... (${omitted} earlier lines omitted)`);
|
|
60
|
+
}
|
|
61
|
+
return messages;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Lambda platform log lines (text format) that carry no application signal.
|
|
65
|
+
*/
|
|
66
|
+
const LAMBDA_PLATFORM_LINE = /^(INIT_START|START RequestId:|END RequestId:|REPORT RequestId:)/;
|
|
67
|
+
/**
|
|
68
|
+
* Normalize Lambda CloudWatch log events into readable lines.
|
|
69
|
+
*
|
|
70
|
+
* Lambda emits logs in one of two formats (per the function's `LoggingConfig.LogFormat`):
|
|
71
|
+
* - **Text**: `<timestamp>\t<requestId>\t<LEVEL>\t<message>`, plus platform lines.
|
|
72
|
+
* - **JSON**: one JSON object per event (`{ timestamp, level, message, ... }`).
|
|
73
|
+
*
|
|
74
|
+
* For both we surface `LEVEL message` (or just the message when there's no level), strip the
|
|
75
|
+
* redundant per-line timestamp/requestId (it's all one invocation), and drop pure platform
|
|
76
|
+
* boilerplate. The level and message are combined into a single rendered line. We never drop
|
|
77
|
+
* application output — failure detail is often logged at INFO (e.g. the cfn-response "Response
|
|
78
|
+
* body" line). Anything we don't recognize passes through verbatim, and the full logs remain
|
|
79
|
+
* available via the console link.
|
|
80
|
+
*
|
|
81
|
+
* This is Lambda-specific; it is not applied to ECS logs, which are arbitrary container output.
|
|
82
|
+
*/
|
|
83
|
+
function parseLambdaLogEvents(events) {
|
|
84
|
+
const out = [];
|
|
85
|
+
for (const e of events) {
|
|
86
|
+
const raw = e.message;
|
|
87
|
+
if (raw == null) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const normalized = normalizeLambdaLine(raw);
|
|
91
|
+
if (normalized !== undefined) {
|
|
92
|
+
out.push(normalized);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Normalize a single Lambda log line. Returns `undefined` to drop the line (platform noise),
|
|
99
|
+
* or the cleaned-up text to keep.
|
|
100
|
+
*/
|
|
101
|
+
function normalizeLambdaLine(raw) {
|
|
102
|
+
const trimmed = raw.trimEnd();
|
|
103
|
+
// JSON-format event: { timestamp, level, message, ... } (one object per line).
|
|
104
|
+
const jsonResult = normalizeJsonLogLine(trimmed);
|
|
105
|
+
if (jsonResult !== undefined) {
|
|
106
|
+
return jsonResult || undefined;
|
|
107
|
+
}
|
|
108
|
+
// Text-format platform boilerplate: drop.
|
|
109
|
+
if (LAMBDA_PLATFORM_LINE.test(trimmed)) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
// Text-format app line: `<ISO timestamp>\t<requestId>\t<LEVEL>\t<message>`.
|
|
113
|
+
// Strip the timestamp + requestId prefix; keep `LEVEL message` (or the rest verbatim).
|
|
114
|
+
const parts = trimmed.split('\t');
|
|
115
|
+
if (parts.length >= 4 && /^\d{4}-\d{2}-\d{2}T/.test(parts[0])) {
|
|
116
|
+
const level = parts[2];
|
|
117
|
+
const message = parts.slice(3).join('\t');
|
|
118
|
+
return formatLeveledLine(level, message);
|
|
119
|
+
}
|
|
120
|
+
// Unrecognized (continuation line, plain stdout, etc.) — keep verbatim.
|
|
121
|
+
return trimmed;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* If `line` is a JSON-format Lambda log object, render it as `LEVEL message` (the level
|
|
125
|
+
* space-padded to a fixed width; or just the message when there's no level). Returns
|
|
126
|
+
* `undefined` when it isn't JSON.
|
|
127
|
+
*
|
|
128
|
+
* Drops JSON platform events (`type`/`record` envelopes for `platform.*`), which carry no
|
|
129
|
+
* application signal.
|
|
130
|
+
*/
|
|
131
|
+
function normalizeJsonLogLine(line) {
|
|
132
|
+
if (!line.startsWith('{')) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
let obj;
|
|
136
|
+
try {
|
|
137
|
+
obj = JSON.parse(line);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
if (!obj || typeof obj !== 'object') {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
// Platform events (e.g. { type: 'platform.report', record: {...} }) — drop.
|
|
146
|
+
if (typeof obj.type === 'string' && obj.type.startsWith('platform.')) {
|
|
147
|
+
return '';
|
|
148
|
+
}
|
|
149
|
+
const level = typeof obj.level === 'string' ? obj.level : undefined;
|
|
150
|
+
// Lambda uses `message`; a thrown error envelope uses `errorMessage` (+ optional stackTrace).
|
|
151
|
+
let message;
|
|
152
|
+
if (typeof obj.message === 'string') {
|
|
153
|
+
message = obj.message;
|
|
154
|
+
}
|
|
155
|
+
else if (typeof obj.errorMessage === 'string') {
|
|
156
|
+
message = Array.isArray(obj.stackTrace) ? [obj.errorMessage, ...obj.stackTrace].join('\n') : obj.errorMessage;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// JSON, but not a shape we recognize — render compactly rather than dropping signal.
|
|
160
|
+
message = line;
|
|
161
|
+
}
|
|
162
|
+
return level ? formatLeveledLine(level, message) : message;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Render a log level and message as `LEVEL message`, padding the level to a fixed width so
|
|
166
|
+
* lines align in the terminal. Multi-line messages keep their internal newlines.
|
|
167
|
+
*/
|
|
168
|
+
function formatLeveledLine(level, message) {
|
|
169
|
+
return `${level.padEnd(5)} ${message}`;
|
|
170
|
+
}
|
|
171
|
+
// CloudWatch console uses double-URI-encoding with '$' replacing '%' for the log group in the fragment.
|
|
172
|
+
function cloudWatchLogsConsoleUrl(region, logGroup) {
|
|
173
|
+
const encodedLogGroup = encodeURIComponent(encodeURIComponent(logGroup)).replace(/%/g, '$');
|
|
174
|
+
return `https://${region}.console.aws.amazon.com/cloudwatch/home?region=${region}#logsV2:log-groups/log-group/${encodedLogGroup}`;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWF0LXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZm9ybWF0LXV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsZ0NBVUM7QUFFRCw0QkFzQkM7QUFvQkQsOENBT0M7QUF1QkQsb0RBYUM7QUFtRkQsNERBR0M7QUF2TEQsU0FBZ0IsVUFBVSxDQUFDLElBQWMsRUFBRSxHQUFXLEVBQUUsS0FBZTtJQUNyRSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTlFLE1BQU0sR0FBRyxHQUFhLEVBQUUsQ0FBQztJQUN6QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3pELE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDeEQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzNDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FB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Q0FBQyxNQUFjLEVBQUUsUUFBZ0I7SUFDdkUsTUFBTSxlQUFlLEdBQUcsa0JBQWtCLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQzVGLE9BQU8sV0FBVyxNQUFNLGtEQUFrRCxNQUFNLGdDQUFnQyxlQUFlLEVBQUUsQ0FBQztBQUNwSSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIHNpZGVCeVNpZGUobGVmdDogc3RyaW5nW10sIHNlcDogc3RyaW5nLCByaWdodDogc3RyaW5nW10pIHtcbiAgY29uc3Qgd2lkdGggPSBsZWZ0Lm1hcCh4ID0+IHgubGVuZ3RoKS5yZWR1Y2UoKGFjYywgbikgPT4gTWF0aC5tYXgoYWNjLCBuKSwgMCk7XG5cbiAgY29uc3QgcmV0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlZnQubGVuZ3RoIHx8IGkgPCByaWdodC5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGwgPSBpIDwgbGVmdC5sZW5ndGggPyBsZWZ0W2ldIDogJyAnLnJlcGVhdCh3aWR0aCk7XG4gICAgY29uc3QgciA9IGkgPCByaWdodC5sZW5ndGggPyByaWdodFtpXSA6ICcnO1xuICAgIHJldC5wdXNoKGAke2x9JHtzZXB9JHtyfWApO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3cmFwVGV4dChuOiBudW1iZXIsIHRleHQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgYnJlYWtlcnMgPSBbJyAnLCAnXFxuJ107XG5cbiAgY29uc3QgcmV0OiBzdHJpbmdbXSA9IFtdO1xuICBsZXQgbGluZVN0YXJ0ID0gMDtcbiAgd2hpbGUgKGxpbmVTdGFydCA8IHRleHQubGVuZ3RoKSB7XG4gICAgbGV0IGxpbmVFbmQgPSBsaW5lU3RhcnQgKyBuO1xuICAgIHdoaWxlIChsaW5lRW5kID4gbGluZVN0YXJ0ICYmIGxpbmVFbmQgPCB0ZXh0Lmxlbmd0aCAmJiAhYnJlYWtlcnMuaW5jbHVkZXModGV4dFtsaW5lRW5kXSkpIHtcbiAgICAgIGxpbmVFbmQgLT0gMTtcbiAgICB9XG4gICAgaWYgKGxpbmVFbmQgPT09IGxpbmVTdGFydCkge1xuICAgICAgLy8gQ291bGQgbm90IGZpbmQgYSBzcGFjZSBpbiB0aGlzIGxpbmUuIFNlZWsgZm9yd2FyZCB0byB0aGUgZmlyc3Qgc3BhY2UgdG8gZ2V0IHRoZSBzbWFsbGVzdCBsaW5lIG92ZXJmbG93XG4gICAgICBsaW5lRW5kID0gbGluZVN0YXJ0ICsgbjtcbiAgICAgIHdoaWxlIChsaW5lRW5kIDwgdGV4dC5sZW5ndGggJiYgIWJyZWFrZXJzLmluY2x1ZGVzKHRleHRbbGluZUVuZF0pKSB7XG4gICAgICAgIGxpbmVFbmQgKz0gMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXQucHVzaCh0ZXh0LnNsaWNlKGxpbmVTdGFydCwgbGluZUVuZCkpO1xuICAgIGxpbmVTdGFydCA9IGxpbmVFbmQgKyAxO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8vIC0tLSBDbG91ZFdhdGNoIGxvZyBmb3JtYXR0aW5nIC0tLVxuXG4vKipcbiAqIE1heGltdW0gbnVtYmVyIG9mIGxvZyBsaW5lcyBpbmNsdWRlZCBwZXIgQ2xvdWRXYXRjaCBMb2dzIGNvbnRleHQgYmxvY2suXG4gKlxuICogVGhlIGZvcm1hdHRlciByZW5kZXJzIHRoZSBtZXNzYWdlcyBhcnJheSB2ZXJiYXRpbSwgc28gdGhpcyBpcyB0aGVcbiAqIHNpbmdsZSB1c2VyLXZpc2libGUgY2FwLlxuICovXG5jb25zdCBNQVhfTE9HX0xJTkVTID0gNTA7XG5cbi8qKlxuICogVHJpbSBhbHJlYWR5LWV4dHJhY3RlZCBsb2cgbGluZXMgdG8gdGhlIHNldCB3ZSByZW5kZXIuXG4gKlxuICogS2VlcHMgb25seSB0aGUgbW9zdCByZWNlbnQge0BsaW5rIE1BWF9MT0dfTElORVN9IChuZXdlciBvdXRwdXQgaXMgbW9yZSB1c2VmdWwgZm9yXG4gKiBkaWFnbm9zaXMpIGFuZCBwcmVwZW5kcyBhbiBcIk4gZWFybGllciBsaW5lcyBvbWl0dGVkXCIgbWFya2VyIHdoZW4gdHJ1bmNhdGlvbiBoYXBwZW5lZC5cbiAqIFRoaXMgaXMgdGhlIHNpbmdsZSB0cnVuY2F0aW9uIHBvaW50IHNoYXJlZCBieSBhbGwgQ2xvdWRXYXRjaCBjb250ZXh0cyDigJQgdGhlIGZvcm1hdHRlclxuICogcmVuZGVycyB0aGUgcmVzdWx0IHZlcmJhdGltLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJpbVRvUmVjZW50TGluZXMobGluZXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICBjb25zdCBtZXNzYWdlcyA9IGxpbmVzLnNsaWNlKC1NQVhfTE9HX0xJTkVTKTtcbiAgY29uc3Qgb21pdHRlZCA9IGxpbmVzLmxlbmd0aCAtIG1lc3NhZ2VzLmxlbmd0aDtcbiAgaWYgKG9taXR0ZWQgPiAwKSB7XG4gICAgbWVzc2FnZXMudW5zaGlmdChgLi4uICgke29taXR0ZWR9IGVhcmxpZXIgbGluZXMgb21pdHRlZClgKTtcbiAgfVxuICByZXR1cm4gbWVzc2FnZXM7XG59XG5cbi8qKlxuICogTGFtYmRhIHBsYXRmb3JtIGxvZyBsaW5lcyAodGV4dCBmb3JtYXQpIHRoYXQgY2Fycnkgbm8gYXBwbGljYXRpb24gc2lnbmFsLlxuICovXG5jb25zdCBMQU1CREFfUExBVEZPUk1fTElORSA9IC9eKElOSVRfU1RBUlR8U1RBUlQgUmVxdWVzdElkOnxFTkQgUmVxdWVzdElkOnxSRVBPUlQgUmVxdWVzdElkOikvO1xuXG4vKipcbiAqIE5vcm1hbGl6ZSBMYW1iZGEgQ2xvdWRXYXRjaCBsb2cgZXZlbnRzIGludG8gcmVhZGFibGUgbGluZXMuXG4gKlxuICogTGFtYmRhIGVtaXRzIGxvZ3MgaW4gb25lIG9mIHR3byBmb3JtYXRzIChwZXIgdGhlIGZ1bmN0aW9uJ3MgYExvZ2dpbmdDb25maWcuTG9nRm9ybWF0YCk6XG4gKiAtICoqVGV4dCoqOiBgPHRpbWVzdGFtcD5cXHQ8cmVxdWVzdElkPlxcdDxMRVZFTD5cXHQ8bWVzc2FnZT5gLCBwbHVzIHBsYXRmb3JtIGxpbmVzLlxuICogLSAqKkpTT04qKjogb25lIEpTT04gb2JqZWN0IHBlciBldmVudCAoYHsgdGltZXN0YW1wLCBsZXZlbCwgbWVzc2FnZSwgLi4uIH1gKS5cbiAqXG4gKiBGb3IgYm90aCB3ZSBzdXJmYWNlIGBMRVZFTCAgbWVzc2FnZWAgKG9yIGp1c3QgdGhlIG1lc3NhZ2Ugd2hlbiB0aGVyZSdzIG5vIGxldmVsKSwgc3RyaXAgdGhlXG4gKiByZWR1bmRhbnQgcGVyLWxpbmUgdGltZXN0YW1wL3JlcXVlc3RJZCAoaXQncyBhbGwgb25lIGludm9jYXRpb24pLCBhbmQgZHJvcCBwdXJlIHBsYXRmb3JtXG4gKiBib2lsZXJwbGF0ZS4gVGhlIGxldmVsIGFuZCBtZXNzYWdlIGFyZSBjb21iaW5lZCBpbnRvIGEgc2luZ2xlIHJlbmRlcmVkIGxpbmUuIFdlIG5ldmVyIGRyb3BcbiAqIGFwcGxpY2F0aW9uIG91dHB1dCDigJQgZmFpbHVyZSBkZXRhaWwgaXMgb2Z0ZW4gbG9nZ2VkIGF0IElORk8gKGUuZy4gdGhlIGNmbi1yZXNwb25zZSBcIlJlc3BvbnNlXG4gKiBib2R5XCIgbGluZSkuIEFueXRoaW5nIHdlIGRvbid0IHJlY29nbml6ZSBwYXNzZXMgdGhyb3VnaCB2ZXJiYXRpbSwgYW5kIHRoZSBmdWxsIGxvZ3MgcmVtYWluXG4gKiBhdmFpbGFibGUgdmlhIHRoZSBjb25zb2xlIGxpbmsuXG4gKlxuICogVGhpcyBpcyBMYW1iZGEtc3BlY2lmaWM7IGl0IGlzIG5vdCBhcHBsaWVkIHRvIEVDUyBsb2dzLCB3aGljaCBhcmUgYXJiaXRyYXJ5IGNvbnRhaW5lciBvdXRwdXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxhbWJkYUxvZ0V2ZW50cyhldmVudHM6IEFycmF5PHsgbWVzc2FnZT86IHN0cmluZyB9Pik6IHN0cmluZ1tdIHtcbiAgY29uc3Qgb3V0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGUgb2YgZXZlbnRzKSB7XG4gICAgY29uc3QgcmF3ID0gZS5tZXNzYWdlO1xuICAgIGlmIChyYXcgPT0gbnVsbCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVMYW1iZGFMaW5lKHJhdyk7XG4gICAgaWYgKG5vcm1hbGl6ZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb3V0LnB1c2gobm9ybWFsaXplZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogTm9ybWFsaXplIGEgc2luZ2xlIExhbWJkYSBsb2cgbGluZS4gUmV0dXJucyBgdW5kZWZpbmVkYCB0byBkcm9wIHRoZSBsaW5lIChwbGF0Zm9ybSBub2lzZSksXG4gKiBvciB0aGUgY2xlYW5lZC11cCB0ZXh0IHRvIGtlZXAuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUxhbWJkYUxpbmUocmF3OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCB0cmltbWVkID0gcmF3LnRyaW1FbmQoKTtcblxuICAvLyBKU09OLWZvcm1hdCBldmVudDogeyB0aW1lc3RhbXAsIGxldmVsLCBtZXNzYWdlLCAuLi4gfSAob25lIG9iamVjdCBwZXIgbGluZSkuXG4gIGNvbnN0IGpzb25SZXN1bHQgPSBub3JtYWxpemVKc29uTG9nTGluZSh0cmltbWVkKTtcbiAgaWYgKGpzb25SZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBqc29uUmVzdWx0IHx8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIFRleHQtZm9ybWF0IHBsYXRmb3JtIGJvaWxlcnBsYXRlOiBkcm9wLlxuICBpZiAoTEFNQkRBX1BMQVRGT1JNX0xJTkUudGVzdCh0cmltbWVkKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyBUZXh0LWZvcm1hdCBhcHAgbGluZTogYDxJU08gdGltZXN0YW1wPlxcdDxyZXF1ZXN0SWQ+XFx0PExFVkVMPlxcdDxtZXNzYWdlPmAuXG4gIC8vIFN0cmlwIHRoZSB0aW1lc3RhbXAgKyByZXF1ZXN0SWQgcHJlZml4OyBrZWVwIGBMRVZFTCBtZXNzYWdlYCAob3IgdGhlIHJlc3QgdmVyYmF0aW0pLlxuICBjb25zdCBwYXJ0cyA9IHRyaW1tZWQuc3BsaXQoJ1xcdCcpO1xuICBpZiAocGFydHMubGVuZ3RoID49IDQgJiYgL15cXGR7NH0tXFxkezJ9LVxcZHsyfVQvLnRlc3QocGFydHNbMF0pKSB7XG4gICAgY29uc3QgbGV2ZWwgPSBwYXJ0c1syXTtcbiAgICBjb25zdCBtZXNzYWdlID0gcGFydHMuc2xpY2UoMykuam9pbignXFx0Jyk7XG4gICAgcmV0dXJuIGZvcm1hdExldmVsZWRMaW5lKGxldmVsLCBtZXNzYWdlKTtcbiAgfVxuXG4gIC8vIFVucmVjb2duaXplZCAoY29udGludWF0aW9uIGxpbmUsIHBsYWluIHN0ZG91dCwgZXRjLikg4oCUIGtlZXAgdmVyYmF0aW0uXG4gIHJldHVybiB0cmltbWVkO1xufVxuXG4vKipcbiAqIElmIGBsaW5lYCBpcyBhIEpTT04tZm9ybWF0IExhbWJkYSBsb2cgb2JqZWN0LCByZW5kZXIgaXQgYXMgYExFVkVMICBtZXNzYWdlYCAodGhlIGxldmVsXG4gKiBzcGFjZS1wYWRkZWQgdG8gYSBmaXhlZCB3aWR0aDsgb3IganVzdCB0aGUgbWVzc2FnZSB3aGVuIHRoZXJlJ3Mgbm8gbGV2ZWwpLiBSZXR1cm5zXG4gKiBgdW5kZWZpbmVkYCB3aGVuIGl0IGlzbid0IEpTT04uXG4gKlxuICogRHJvcHMgSlNPTiBwbGF0Zm9ybSBldmVudHMgKGB0eXBlYC9gcmVjb3JkYCBlbnZlbG9wZXMgZm9yIGBwbGF0Zm9ybS4qYCksIHdoaWNoIGNhcnJ5IG5vXG4gKiBhcHBsaWNhdGlvbiBzaWduYWwuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUpzb25Mb2dMaW5lKGxpbmU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghbGluZS5zdGFydHNXaXRoKCd7JykpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCBvYmo6IGFueTtcbiAgdHJ5IHtcbiAgICBvYmogPSBKU09OLnBhcnNlKGxpbmUpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIFBsYXRmb3JtIGV2ZW50cyAoZS5nLiB7IHR5cGU6ICdwbGF0Zm9ybS5yZXBvcnQnLCByZWNvcmQ6IHsuLi59IH0pIOKAlCBkcm9wLlxuICBpZiAodHlwZW9mIG9iai50eXBlID09PSAnc3RyaW5nJyAmJiBvYmoudHlwZS5zdGFydHNXaXRoKCdwbGF0Zm9ybS4nKSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGNvbnN0IGxldmVsID0gdHlwZW9mIG9iai5sZXZlbCA9PT0gJ3N0cmluZycgPyBvYmoubGV2ZWwgOiB1bmRlZmluZWQ7XG4gIC8vIExhbWJkYSB1c2VzIGBtZXNzYWdlYDsgYSB0aHJvd24gZXJyb3IgZW52ZWxvcGUgdXNlcyBgZXJyb3JNZXNzYWdlYCAoKyBvcHRpb25hbCBzdGFja1RyYWNlKS5cbiAgbGV0IG1lc3NhZ2U6IHN0cmluZztcbiAgaWYgKHR5cGVvZiBvYmoubWVzc2FnZSA9PT0gJ3N0cmluZycpIHtcbiAgICBtZXNzYWdlID0gb2JqLm1lc3NhZ2U7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9iai5lcnJvck1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgbWVzc2FnZSA9IEFycmF5LmlzQXJyYXkob2JqLnN0YWNrVHJhY2UpID8gW29iai5lcnJvck1lc3NhZ2UsIC4uLm9iai5zdGFja1RyYWNlXS5qb2luKCdcXG4nKSA6IG9iai5lcnJvck1lc3NhZ2U7XG4gIH0gZWxzZSB7XG4gICAgLy8gSlNPTiwgYnV0IG5vdCBhIHNoYXBlIHdlIHJlY29nbml6ZSDigJQgcmVuZGVyIGNvbXBhY3RseSByYXRoZXIgdGhhbiBkcm9wcGluZyBzaWduYWwuXG4gICAgbWVzc2FnZSA9IGxpbmU7XG4gIH1cbiAgcmV0dXJuIGxldmVsID8gZm9ybWF0TGV2ZWxlZExpbmUobGV2ZWwsIG1lc3NhZ2UpIDogbWVzc2FnZTtcbn1cblxuLyoqXG4gKiBSZW5kZXIgYSBsb2cgbGV2ZWwgYW5kIG1lc3NhZ2UgYXMgYExFVkVMICBtZXNzYWdlYCwgcGFkZGluZyB0aGUgbGV2ZWwgdG8gYSBmaXhlZCB3aWR0aCBzb1xuICogbGluZXMgYWxpZ24gaW4gdGhlIHRlcm1pbmFsLiBNdWx0aS1saW5lIG1lc3NhZ2VzIGtlZXAgdGhlaXIgaW50ZXJuYWwgbmV3bGluZXMuXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdExldmVsZWRMaW5lKGxldmVsOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtsZXZlbC5wYWRFbmQoNSl9ICR7bWVzc2FnZX1gO1xufVxuXG4vLyBDbG91ZFdhdGNoIGNvbnNvbGUgdXNlcyBkb3VibGUtVVJJLWVuY29kaW5nIHdpdGggJyQnIHJlcGxhY2luZyAnJScgZm9yIHRoZSBsb2cgZ3JvdXAgaW4gdGhlIGZyYWdtZW50LlxuZXhwb3J0IGZ1bmN0aW9uIGNsb3VkV2F0Y2hMb2dzQ29uc29sZVVybChyZWdpb246IHN0cmluZywgbG9nR3JvdXA6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGVuY29kZWRMb2dHcm91cCA9IGVuY29kZVVSSUNvbXBvbmVudChlbmNvZGVVUklDb21wb25lbnQobG9nR3JvdXApKS5yZXBsYWNlKC8lL2csICckJyk7XG4gIHJldHVybiBgaHR0cHM6Ly8ke3JlZ2lvbn0uY29uc29sZS5hd3MuYW1hem9uLmNvbS9jbG91ZHdhdGNoL2hvbWU/cmVnaW9uPSR7cmVnaW9ufSNsb2dzVjI6bG9nLWdyb3Vwcy9sb2ctZ3JvdXAvJHtlbmNvZGVkTG9nR3JvdXB9YDtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AdditionalDiagnosticContext } from '../../actions/diagnose';
|
|
2
|
+
import type { SDK } from '../aws-auth/sdk';
|
|
3
|
+
import type { ResourceError } from '../stack-events/resource-errors';
|
|
4
|
+
/**
|
|
5
|
+
* Investigate a failed custom resource by surfacing its backing Lambda's CloudWatch logs.
|
|
6
|
+
*
|
|
7
|
+
* The CloudFormation event does not name the backing function — only the resource's
|
|
8
|
+
* `ServiceToken` (in the template) does. We resolve that to a function name, derive the
|
|
9
|
+
* log group (the `/aws/lambda/<fn>` convention, confirmed via the function's LoggingConfig
|
|
10
|
+
* only if the convention turns up empty), and fetch the relevant log lines.
|
|
11
|
+
*
|
|
12
|
+
* When the handler uses the cfn-response library, the failing log stream name is embedded
|
|
13
|
+
* in the status reason ("See the details in CloudWatch Log Stream: <name>"), so we can
|
|
14
|
+
* target that exact invocation.
|
|
15
|
+
*/
|
|
16
|
+
export declare function investigateCustomResource(err: ResourceError, sdk: SDK, debug: (msg: string) => Promise<void>): Promise<AdditionalDiagnosticContext[]>;
|
|
17
|
+
//# sourceMappingURL=investigate-custom-resource.d.ts.map
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.investigateCustomResource = investigateCustomResource;
|
|
4
|
+
const format_utils_1 = require("./format-utils");
|
|
5
|
+
const resource_identifiers_1 = require("./resource-identifiers");
|
|
6
|
+
const util_1 = require("../../util");
|
|
7
|
+
/** Fallback look-back when no failure timestamp is available. */
|
|
8
|
+
const FALLBACK_LOG_WINDOW_MS = 30 * 60 * 1000;
|
|
9
|
+
/**
|
|
10
|
+
* How far before/after the failure event to search CloudWatch Logs when we have a timestamp.
|
|
11
|
+
*
|
|
12
|
+
* The pre-window absorbs minor clock skew; the post-window covers output the function
|
|
13
|
+
* emits while it runs after the CloudFormation event was recorded.
|
|
14
|
+
*/
|
|
15
|
+
const LOG_WINDOW_BEFORE_MS = 2 * 60 * 1000;
|
|
16
|
+
const LOG_WINDOW_AFTER_MS = 15 * 60 * 1000;
|
|
17
|
+
/**
|
|
18
|
+
* Investigate a failed custom resource by surfacing its backing Lambda's CloudWatch logs.
|
|
19
|
+
*
|
|
20
|
+
* The CloudFormation event does not name the backing function — only the resource's
|
|
21
|
+
* `ServiceToken` (in the template) does. We resolve that to a function name, derive the
|
|
22
|
+
* log group (the `/aws/lambda/<fn>` convention, confirmed via the function's LoggingConfig
|
|
23
|
+
* only if the convention turns up empty), and fetch the relevant log lines.
|
|
24
|
+
*
|
|
25
|
+
* When the handler uses the cfn-response library, the failing log stream name is embedded
|
|
26
|
+
* in the status reason ("See the details in CloudWatch Log Stream: <name>"), so we can
|
|
27
|
+
* target that exact invocation.
|
|
28
|
+
*/
|
|
29
|
+
async function investigateCustomResource(err, sdk, debug) {
|
|
30
|
+
if (!err.logicalId) {
|
|
31
|
+
await debug('Custom resource investigation: no logical ID available');
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
const stackName = err.stackArn;
|
|
35
|
+
if (!stackName) {
|
|
36
|
+
await debug('Custom resource investigation: no stack ARN available');
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
const cfn = sdk.cloudFormation();
|
|
40
|
+
const lambda = sdk.lambda();
|
|
41
|
+
const cwl = sdk.cloudWatchLogs();
|
|
42
|
+
const region = sdk.currentRegion;
|
|
43
|
+
// Fetch the template once: it carries both the ServiceToken and (for functions defined in
|
|
44
|
+
// this stack) the backing function's LoggingConfig. The template survives rollback even
|
|
45
|
+
// when the function itself is deleted, so it's the most reliable source for the log group.
|
|
46
|
+
const template = await getStackTemplate(cfn, stackName, debug);
|
|
47
|
+
if (!template) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
const serviceToken = template.Resources?.[err.logicalId]?.Properties?.ServiceToken;
|
|
51
|
+
if (serviceToken === undefined) {
|
|
52
|
+
await debug(`Custom resource investigation: no ServiceToken on resource "${err.logicalId}"`);
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
const referencedLogicalId = (0, resource_identifiers_1.serviceTokenReferencedLogicalId)(serviceToken);
|
|
56
|
+
const functionName = await resolveServiceTokenToFunctionName(cfn, stackName, serviceToken, referencedLogicalId, debug);
|
|
57
|
+
if (!functionName) {
|
|
58
|
+
await debug('Custom resource investigation: could not resolve ServiceToken to a Lambda function');
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
// Prefer the function's configured log group as derived from the template (rollback-proof).
|
|
62
|
+
// Only resolvable when the function is defined in this stack (ServiceToken is a Ref/GetAtt).
|
|
63
|
+
const templateLogGroup = referencedLogicalId
|
|
64
|
+
? await resolveConfiguredLogGroup(cfn, stackName, template, referencedLogicalId, debug)
|
|
65
|
+
: undefined;
|
|
66
|
+
// The cfn-response library writes the failing log stream name into the status reason
|
|
67
|
+
// (and uses it as the default physical ID). Targeting it gives the exact invocation.
|
|
68
|
+
const streamName = (0, resource_identifiers_1.extractLogStreamName)(err.message) ?? (0, resource_identifiers_1.logStreamNameFromPhysicalId)(err.physicalId);
|
|
69
|
+
return fetchCustomResourceLogs(cwl, lambda, functionName, templateLogGroup, streamName, err.timestamp, region, debug);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Fetch and parse the stack's (original) template. Returns `undefined` if it can't be read.
|
|
73
|
+
*/
|
|
74
|
+
async function getStackTemplate(cfn, stackName, debug) {
|
|
75
|
+
try {
|
|
76
|
+
const resp = await cfn.getTemplate({ StackName: stackName, TemplateStage: 'Original' });
|
|
77
|
+
if (!resp.TemplateBody) {
|
|
78
|
+
await debug('Custom resource investigation: empty template body');
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return (0, util_1.deserializeStructure)(resp.TemplateBody);
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
await debug(`Custom resource investigation: failed to read template: ${e.message}`);
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resolve the backing Lambda's configured log group from the template.
|
|
90
|
+
*
|
|
91
|
+
* The template survives rollback (when the live function may not), so it is the preferred
|
|
92
|
+
* source. Handles the function's `LoggingConfig.LogGroup` as:
|
|
93
|
+
* - a literal string (returned directly);
|
|
94
|
+
* - a `Ref` to an `AWS::Logs::LogGroup` with a literal `LogGroupName` (returned directly);
|
|
95
|
+
* - a `Ref` to an `AWS::Logs::LogGroup` whose name CloudFormation generates (the common CDK
|
|
96
|
+
* case) — resolved to its physical name via `describeStackResources`, which still returns
|
|
97
|
+
* RETAINed/orphaned resources after a rollback.
|
|
98
|
+
*
|
|
99
|
+
* Returns `undefined` when there is no configured log group or it can't be resolved
|
|
100
|
+
* (caller then falls back to the live function configuration).
|
|
101
|
+
*/
|
|
102
|
+
async function resolveConfiguredLogGroup(cfn, stackName, template, functionLogicalId, debug) {
|
|
103
|
+
const logGroup = template.Resources?.[functionLogicalId]?.Properties?.LoggingConfig?.LogGroup;
|
|
104
|
+
if (typeof logGroup === 'string') {
|
|
105
|
+
return logGroup;
|
|
106
|
+
}
|
|
107
|
+
if (logGroup && typeof logGroup === 'object' && typeof logGroup.Ref === 'string') {
|
|
108
|
+
const referenced = template.Resources?.[logGroup.Ref];
|
|
109
|
+
const name = referenced?.Properties?.LogGroupName;
|
|
110
|
+
if (typeof name === 'string') {
|
|
111
|
+
return name;
|
|
112
|
+
}
|
|
113
|
+
// No explicit name (CloudFormation generates it) — resolve the log-group resource's
|
|
114
|
+
// physical name, which is the log group name.
|
|
115
|
+
return (await resolveStackResource(cfn, stackName, logGroup.Ref, debug))?.physicalId;
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Resolve a resource's physical ID and type by logical ID. Returns `undefined` on failure.
|
|
121
|
+
*/
|
|
122
|
+
async function resolveStackResource(cfn, stackName, logicalId, debug) {
|
|
123
|
+
try {
|
|
124
|
+
const resp = await cfn.describeStackResources({ StackName: stackName, LogicalResourceId: logicalId });
|
|
125
|
+
const resource = resp.StackResources?.[0];
|
|
126
|
+
return resource ? { physicalId: resource.PhysicalResourceId, resourceType: resource.ResourceType } : undefined;
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
await debug(`Custom resource investigation: failed to resolve resource "${logicalId}": ${e.message}`);
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Resolve a `ServiceToken` value (a literal ARN, an `Fn::GetAtt`, or a `Ref`) to a Lambda
|
|
135
|
+
* function name. Intrinsics are resolved via `describeStackResources`.
|
|
136
|
+
*/
|
|
137
|
+
async function resolveServiceTokenToFunctionName(cfn, stackName, serviceToken, referencedLogicalId, debug) {
|
|
138
|
+
if (referencedLogicalId) {
|
|
139
|
+
const resource = await resolveStackResource(cfn, stackName, referencedLogicalId, debug);
|
|
140
|
+
// Only treat the reference as a Lambda function. Without this, a ServiceToken pointing at
|
|
141
|
+
// a non-Lambda resource (e.g. an SNS topic) whose physical ID is a bare name would be
|
|
142
|
+
// mistaken for a function name, producing a misleading /aws/lambda/<name> log lookup.
|
|
143
|
+
if (resource?.resourceType && resource.resourceType !== 'AWS::Lambda::Function') {
|
|
144
|
+
await debug(`Custom resource investigation: ServiceToken references a ${resource.resourceType}, not a Lambda function`);
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
return resource?.physicalId ? (0, resource_identifiers_1.functionNameFromArnOrName)(resource.physicalId) : undefined;
|
|
148
|
+
}
|
|
149
|
+
if (typeof serviceToken === 'string') {
|
|
150
|
+
return (0, resource_identifiers_1.functionNameFromArnOrName)(serviceToken);
|
|
151
|
+
}
|
|
152
|
+
await debug('Custom resource investigation: unsupported ServiceToken shape');
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
async function fetchCustomResourceLogs(cwl, lambda, functionName, templateLogGroup, streamName, timestamp, region, debug) {
|
|
156
|
+
const failureTime = timestamp?.valueOf();
|
|
157
|
+
const startTime = failureTime !== undefined ? failureTime - LOG_WINDOW_BEFORE_MS : Date.now() - FALLBACK_LOG_WINDOW_MS;
|
|
158
|
+
const endTime = failureTime !== undefined ? failureTime + LOG_WINDOW_AFTER_MS : undefined;
|
|
159
|
+
// Convention first; only pay for the configured group if the convention group doesn't yield usable lines (empty group or fetch error).
|
|
160
|
+
const conventionGroup = `/aws/lambda/${functionName}`;
|
|
161
|
+
let result = await fetchLogLines(cwl, conventionGroup, streamName, startTime, endTime, debug);
|
|
162
|
+
// The group we point the user at. Once we learn the function's configured log group, prefer
|
|
163
|
+
// it for the link even if it too is empty — it's where the function actually logs, whereas
|
|
164
|
+
// the convention group may not exist for advanced-logging functions.
|
|
165
|
+
let logGroup = conventionGroup;
|
|
166
|
+
if (result.kind !== 'lines') {
|
|
167
|
+
// Prefer the template-derived group (rollback-proof); fall back to the live function
|
|
168
|
+
// configuration only when the template couldn't tell us (e.g. unresolvable intrinsic, or
|
|
169
|
+
// the function is defined outside this stack).
|
|
170
|
+
const configuredGroup = templateLogGroup ?? await configuredLogGroup(lambda, functionName, debug);
|
|
171
|
+
if (configuredGroup && configuredGroup !== conventionGroup) {
|
|
172
|
+
logGroup = configuredGroup;
|
|
173
|
+
const configuredResult = await fetchLogLines(cwl, configuredGroup, streamName, startTime, endTime, debug);
|
|
174
|
+
// Keep the configured-group result unless it errored while the convention attempt was a
|
|
175
|
+
// clean empty (an "empty" answer is more informative to surface than a fetch error).
|
|
176
|
+
if (configuredResult.kind === 'lines' || result.kind !== 'empty') {
|
|
177
|
+
result = configuredResult;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Lead with the log group so the user can tell which function these logs belong to
|
|
182
|
+
// (the formatter renders messages but not `source`, and the link is URL-encoded).
|
|
183
|
+
const header = `Logs from ${logGroup}:`;
|
|
184
|
+
const body = result.kind === 'lines'
|
|
185
|
+
? result.lines
|
|
186
|
+
: result.kind === 'error'
|
|
187
|
+
? ['Could not fetch logs (the log group may not exist, or the credentials lack logs:FilterLogEvents). See the console link below.']
|
|
188
|
+
: ['No log events found around the time of failure. The function may not have produced output, or logging may not be configured.'];
|
|
189
|
+
return [{
|
|
190
|
+
source: 'Custom Resource Lambda Logs',
|
|
191
|
+
messages: [header, ...body],
|
|
192
|
+
link: (0, format_utils_1.cloudWatchLogsConsoleUrl)(region, logGroup),
|
|
193
|
+
linkLabel: 'Logs',
|
|
194
|
+
}];
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Fetch and trim recent log lines from a group.
|
|
198
|
+
*
|
|
199
|
+
* Tries the targeted stream first (most relevant), but the cfn-response stream name can be
|
|
200
|
+
* stale on update/rollback failures (it's pinned to the original create invocation). If the
|
|
201
|
+
* targeted query finds nothing, falls back to a group-wide scan over the time window so a
|
|
202
|
+
* stale stream can't hide the actual failing invocation's logs.
|
|
203
|
+
*/
|
|
204
|
+
async function fetchLogLines(cwl, logGroup, streamName, startTime, endTime, debug) {
|
|
205
|
+
if (streamName) {
|
|
206
|
+
const targeted = await filterLogLines(cwl, logGroup, streamName, startTime, endTime, debug);
|
|
207
|
+
if (targeted.kind === 'lines') {
|
|
208
|
+
return targeted;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return filterLogLines(cwl, logGroup, undefined, startTime, endTime, debug);
|
|
212
|
+
}
|
|
213
|
+
async function filterLogLines(cwl, logGroup, streamName, startTime, endTime, debug) {
|
|
214
|
+
try {
|
|
215
|
+
const resp = await cwl.filterLogEvents({
|
|
216
|
+
logGroupName: logGroup,
|
|
217
|
+
startTime,
|
|
218
|
+
...(endTime !== undefined ? { endTime } : {}),
|
|
219
|
+
limit: 1000,
|
|
220
|
+
...(streamName ? { logStreamNames: [streamName] } : {}),
|
|
221
|
+
});
|
|
222
|
+
const events = resp.events ?? [];
|
|
223
|
+
if (events.length === 0) {
|
|
224
|
+
await debug(`Custom resource investigation: no log events in ${logGroup}${streamName ? ` (stream: ${streamName})` : ''}`);
|
|
225
|
+
return { kind: 'empty' };
|
|
226
|
+
}
|
|
227
|
+
// Lambda log events have a known structure (text- or JSON-format), unlike raw ECS
|
|
228
|
+
// container output, so we normalize them into readable lines before trimming.
|
|
229
|
+
return { kind: 'lines', lines: (0, format_utils_1.trimToRecentLines)((0, format_utils_1.parseLambdaLogEvents)(events)) };
|
|
230
|
+
}
|
|
231
|
+
catch (e) {
|
|
232
|
+
await debug(`Custom resource investigation: failed to fetch logs from ${logGroup}: ${e.message}`);
|
|
233
|
+
return { kind: 'error' };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/** Read the function's configured (advanced-logging) log group, if any. */
|
|
237
|
+
async function configuredLogGroup(lambda, functionName, debug) {
|
|
238
|
+
try {
|
|
239
|
+
const resp = await lambda.getFunctionConfiguration({ FunctionName: functionName });
|
|
240
|
+
return resp.LoggingConfig?.LogGroup;
|
|
241
|
+
}
|
|
242
|
+
catch (e) {
|
|
243
|
+
await debug(`Custom resource investigation: failed to read function configuration: ${e.message}`);
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52ZXN0aWdhdGUtY3VzdG9tLXJlc291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaW52ZXN0aWdhdGUtY3VzdG9tLXJlc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBb0NBLDhEQW9EQztBQXhGRCxpREFBbUc7QUFDbkcsaUVBS2dDO0FBRWhDLHFDQUFrRDtBQUlsRCxpRUFBaUU7QUFDakUsTUFBTSxzQkFBc0IsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUU5Qzs7Ozs7R0FLRztBQUNILE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDM0MsTUFBTSxtQkFBbUIsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUUzQzs7Ozs7Ozs7Ozs7R0FXRztBQUNJLEtBQUssVUFBVSx5QkFBeUIsQ0FDN0MsR0FBa0IsRUFDbEIsR0FBUSxFQUNSLEtBQXFDO0lBRXJDLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDbkIsTUFBTSxLQUFLLENBQUMsd0RBQXdELENBQUMsQ0FBQztRQUN0RSxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFDRCxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDO0lBQy9CLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNmLE1BQU0sS0FBSyxDQUFDLHVEQUF1RCxDQUFDLENBQUM7UUFDckUsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ2pDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUM1QixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDakMsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLGFBQWEsQ0FBQztJQUVqQywwRkFBMEY7SUFDMUYs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QUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ2xHLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDM0IsQ0FBQztBQUNILENBQUM7QUFFRCwyRUFBMkU7QUFDM0UsS0FBSyxVQUFVLGtCQUFrQixDQUMvQixNQUFxQixFQUNyQixZQUFvQixFQUNwQixLQUFxQztJQUVyQyxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksR0FBRyxNQUFNLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQ25GLE9BQU8sSUFBSSxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUM7SUFDdEMsQ0FBQztJQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7UUFDaEIsTUFBTSxLQUFLLENBQUMseUVBQXlFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ2xHLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdHJpbVRvUmVjZW50TGluZXMsIHBhcnNlTGFtYmRhTG9nRXZlbnRzLCBjbG91ZFdhdGNoTG9nc0NvbnNvbGVVcmwgfSBmcm9tICcuL2Zvcm1hdC11dGlscyc7XG5pbXBvcnQge1xuICBzZXJ2aWNlVG9rZW5SZWZlcmVuY2VkTG9naWNhbElkLFxuICBmdW5jdGlvbk5hbWVGcm9tQXJuT3JOYW1lLFxuICBleHRyYWN0TG9nU3RyZWFtTmFtZSxcbiAgbG9nU3RyZWFtTmFtZUZyb21QaHlzaWNhbElkLFxufSBmcm9tICcuL3Jlc291cmNlLWlkZW50aWZpZXJzJztcbmltcG9ydCB0eXBlIHsgQWRkaXRpb25hbERpYWdub3N0aWNDb250ZXh0IH0gZnJvbSAnLi4vLi4vYWN0aW9ucy9kaWFnbm9zZSc7XG5pbXBvcnQgeyBkZXNlcmlhbGl6ZVN0cnVjdHVyZSB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHR5cGUgeyBJQ2xvdWRGb3JtYXRpb25DbGllbnQsIElDbG91ZFdhdGNoTG9nc0NsaWVudCwgSUxhbWJkYUNsaWVudCwgU0RLIH0gZnJvbSAnLi4vYXdzLWF1dGgvc2RrJztcbmltcG9ydCB0eXBlIHsgUmVzb3VyY2VFcnJvciB9IGZyb20gJy4uL3N0YWNrLWV2ZW50cy9yZXNvdXJjZS1lcnJvcnMnO1xuXG4vKiogRmFsbGJhY2sgbG9vay1iYWNrIHdoZW4gbm8gZmFpbHVyZSB0aW1lc3RhbXAgaXMgYXZhaWxhYmxlLiAqL1xuY29uc3QgRkFMTEJBQ0tfTE9HX1dJTkRPV19NUyA9IDMwICogNjAgKiAxMDAwO1xuXG4vKipcbiAqIEhvdyBmYXIgYmVmb3JlL2FmdGVyIHRoZSBmYWlsdXJlIGV2ZW50IHRvIHNlYXJjaCBDbG91ZFdhdGNoIExvZ3Mgd2hlbiB3ZSBoYXZlIGEgdGltZXN0YW1wLlxuICpcbiAqIFRoZSBwcmUtd2luZG93IGFic29yYnMgbWlub3IgY2xvY2sgc2tldzsgdGhlIHBvc3Qtd2luZG93IGNvdmVycyBvdXRwdXQgdGhlIGZ1bmN0aW9uXG4gKiBlbWl0cyB3aGlsZSBpdCBydW5zIGFmdGVyIHRoZSBDbG91ZEZvcm1hdGlvbiBldmVudCB3YXMgcmVjb3JkZWQuXG4gKi9cbmNvbnN0IExPR19XSU5ET1dfQkVGT1JFX01TID0gMiAqIDYwICogMTAwMDtcbmNvbnN0IExPR19XSU5ET1dfQUZURVJfTVMgPSAxNSAqIDYwICogMTAwMDtcblxuLyoqXG4gKiBJbnZlc3RpZ2F0ZSBhIGZhaWxlZCBjdXN0b20gcmVzb3VyY2UgYnkgc3VyZmFjaW5nIGl0cyBiYWNraW5nIExhbWJkYSdzIENsb3VkV2F0Y2ggbG9ncy5cbiAqXG4gKiBUaGUgQ2xvdWRGb3JtYXRpb24gZXZlbnQgZG9lcyBub3QgbmFtZSB0aGUgYmFja2luZyBmdW5jdGlvbiDigJQgb25seSB0aGUgcmVzb3VyY2Unc1xuICogYFNlcnZpY2VUb2tlbmAgKGluIHRoZSB0ZW1wbGF0ZSkgZG9lcy4gV2UgcmVzb2x2ZSB0aGF0IHRvIGEgZnVuY3Rpb24gbmFtZSwgZGVyaXZlIHRoZVxuICogbG9nIGdyb3VwICh0aGUgYC9hd3MvbGFtYmRhLzxmbj5gIGNvbnZlbnRpb24sIGNvbmZpcm1lZCB2aWEgdGhlIGZ1bmN0aW9uJ3MgTG9nZ2luZ0NvbmZpZ1xuICogb25seSBpZiB0aGUgY29udmVudGlvbiB0dXJucyB1cCBlbXB0eSksIGFuZCBmZXRjaCB0aGUgcmVsZXZhbnQgbG9nIGxpbmVzLlxuICpcbiAqIFdoZW4gdGhlIGhhbmRsZXIgdXNlcyB0aGUgY2ZuLXJlc3BvbnNlIGxpYnJhcnksIHRoZSBmYWlsaW5nIGxvZyBzdHJlYW0gbmFtZSBpcyBlbWJlZGRlZFxuICogaW4gdGhlIHN0YXR1cyByZWFzb24gKFwiU2VlIHRoZSBkZXRhaWxzIGluIENsb3VkV2F0Y2ggTG9nIFN0cmVhbTogPG5hbWU+XCIpLCBzbyB3ZSBjYW5cbiAqIHRhcmdldCB0aGF0IGV4YWN0IGludm9jYXRpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbnZlc3RpZ2F0ZUN1c3RvbVJlc291cmNlKFxuICBlcnI6IFJlc291cmNlRXJyb3IsXG4gIHNkazogU0RLLFxuICBkZWJ1ZzogKG1zZzogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+LFxuKTogUHJvbWlzZTxBZGRpdGlvbmFsRGlhZ25vc3RpY0NvbnRleHRbXT4ge1xuICBpZiAoIWVyci5sb2dpY2FsSWQpIHtcbiAgICBhd2FpdCBkZWJ1ZygnQ3VzdG9tIHJlc291cmNlIGludmVzdGlnYXRpb246IG5vIGxvZ2ljYWwgSUQgYXZhaWxhYmxlJyk7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGNvbnN0IHN0YWNrTmFtZSA9IGVyci5zdGFja0FybjtcbiAgaWYgKCFzdGFja05hbWUpIHtcbiAgICBhd2FpdCBkZWJ1ZygnQ3VzdG9tIHJlc291cmNlIGludmVzdGlnYXRpb246IG5vIHN0YWNrIEFSTiBhdmFpbGFibGUnKTtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBjZm4gPSBzZGsuY2xvdWRGb3JtYXRpb24oKTtcbiAgY29uc3QgbGFtYmRhID0gc2RrLmxhbWJkYSgpO1xuICBjb25zdCBjd2wgPSBzZGsuY2xvdWRXYXRjaExvZ3MoKTtcbiAgY29uc3QgcmVnaW9uID0gc2RrLmN1cnJlbnRSZWdpb247XG5cbiAgLy8gRmV0Y2ggdGhlIHRlbXBsYXRlIG9uY2U6IGl0IGNhcnJpZXMgYm90aCB0aGUgU2VydmljZVRva2VuIGFuZCAoZm9yIGZ1bmN0aW9ucyBkZWZpbmVkIGluXG4gIC8vIHRoaXMgc3RhY2spIHRoZSBiYWNraW5nIGZ1bmN0aW9uJ3MgTG9nZ2luZ0NvbmZpZy4gVGhlIHRlbXBsYXRlIHN1cnZpdmVzIHJvbGxiYWNrIGV2ZW5cbiAgLy8gd2hlbiB0aGUgZnVuY3Rpb24gaXRzZWxmIGlzIGRlbGV0ZWQsIHNvIGl0J3MgdGhlIG1vc3QgcmVsaWFibGUgc291cmNlIGZvciB0aGUgbG9nIGdyb3VwLlxuICBjb25zdCB0ZW1wbGF0ZSA9IGF3YWl0IGdldFN0YWNrVGVtcGxhdGUoY2ZuLCBzdGFja05hbWUsIGRlYnVnKTtcbiAgaWYgKCF0ZW1wbGF0ZSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHNlcnZpY2VUb2tlbiA9IHRlbXBsYXRlLlJlc291cmNlcz8uW2Vyci5sb2dpY2FsSWRdPy5Qcm9wZXJ0aWVzPy5TZXJ2aWNlVG9rZW47XG4gIGlmIChzZXJ2aWNlVG9rZW4gPT09IHVuZGVmaW5lZCkge1xuICAgIGF3YWl0IGRlYnVnKGBDdXN0b20gcmVzb3VyY2UgaW52ZXN0aWdhdGlvbjogbm8gU2VydmljZVRva2VuIG9uIHJlc291cmNlIFwiJHtlcnIubG9naWNhbElkfVwiYCk7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgcmVmZXJlbmNlZExvZ2ljYWxJZCA9IHNlcnZpY2VUb2tlblJlZmVyZW5jZWRMb2dpY2FsSWQoc2VydmljZVRva2VuKTtcbiAgY29uc3QgZnVuY3Rpb25OYW1lID0gYXdhaXQgcmVzb2x2ZVNlcnZpY2VUb2tlblRvRnVuY3Rpb25OYW1lKGNmbiwgc3RhY2tOYW1lLCBzZXJ2aWNlVG9rZW4sIHJlZmVyZW5jZWRMb2dpY2FsSWQsIGRlYnVnKTtcbiAgaWYgKCFmdW5jdGlvbk5hbWUpIHtcbiAgICBhd2FpdCBkZWJ1ZygnQ3VzdG9tIHJlc291cmNlIGludmVzdGlnYXRpb246IGNvdWxkIG5vdCByZXNvbHZlIFNlcnZpY2VUb2tlbiB0byBhIExhbWJkYSBmdW5jdGlvbicpO1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8vIFByZWZlciB0aGUgZnVuY3Rpb24ncyBjb25maWd1cmVkIGxvZyBncm91cCBhcyBkZXJpdmVkIGZyb20gdGhlIHRlbXBsYXRlIChyb2xsYmFjay1wcm9vZikuXG4gIC8vIE9ubHkgcmVzb2x2YWJsZSB3aGVuIHRoZSBmdW5jdGlvbiBpcyBkZWZpbmVkIGluIHRoaXMgc3RhY2sgKFNlcnZpY2VUb2tlbiBpcyBhIFJlZi9HZXRBdHQpLlxuICBjb25zdCB0ZW1wbGF0ZUxvZ0dyb3VwID0gcmVmZXJlbmNlZExvZ2ljYWxJZFxuICAgID8gYXdhaXQgcmVzb2x2ZUNvbmZpZ3VyZWRMb2dHcm91cChjZm4sIHN0YWNrTmFtZSwgdGVtcGxhdGUsIHJlZmVyZW5jZWRMb2dpY2FsSWQsIGRlYnVnKVxuICAgIDogdW5kZWZpbmVkO1xuXG4gIC8vIFRoZSBjZm4tcmVzcG9uc2UgbGlicmFyeSB3cml0ZXMgdGhlIGZhaWxpbmcgbG9nIHN0cmVhbSBuYW1lIGludG8gdGhlIHN0YXR1cyByZWFzb25cbiAgLy8gKGFuZCB1c2VzIGl0IGFzIHRoZSBkZWZhdWx0IHBoeXNpY2FsIElEKS4gVGFyZ2V0aW5nIGl0IGdpdmVzIHRoZSBleGFjdCBpbnZvY2F0aW9uLlxuICBjb25zdCBzdHJlYW1OYW1lID0gZXh0cmFjdExvZ1N0cmVhbU5hbWUoZXJyLm1lc3NhZ2UpID8/IGxvZ1N0cmVhbU5hbWVGcm9tUGh5c2ljYWxJZChlcnIucGh5c2ljYWxJZCk7XG5cbiAgcmV0dXJuIGZldGNoQ3VzdG9tUmVzb3VyY2VMb2dzKGN3bCwgbGFtYmRhLCBmdW5jdGlvbk5hbWUsIHRlbXBsYXRlTG9nR3JvdXAsIHN0cmVhbU5hbWUsIGVyci50aW1lc3RhbXAsIHJlZ2lvbiwgZGVidWcpO1xufVxuXG4vKipcbiAqIEZldGNoIGFuZCBwYXJzZSB0aGUgc3RhY2sncyAob3JpZ2luYWwpIHRlbXBsYXRlLiBSZXR1cm5zIGB1bmRlZmluZWRgIGlmIGl0IGNhbid0IGJlIHJlYWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldFN0YWNrVGVtcGxhdGUoXG4gIGNmbjogSUNsb3VkRm9ybWF0aW9uQ2xpZW50LFxuICBzdGFja05hbWU6IHN0cmluZyxcbiAgZGVidWc6IChtc2c6IHN0cmluZykgPT4gUHJvbWlzZTx2b2lkPixcbik6IFByb21pc2U8YW55IHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcCA9IGF3YWl0IGNmbi5nZXRUZW1wbGF0ZSh7IFN0YWNrTmFtZTogc3RhY2tOYW1lLCBUZW1wbGF0ZVN0YWdlOiAnT3JpZ2luYWwnIH0pO1xuICAgIGlmICghcmVzcC5UZW1wbGF0ZUJvZHkpIHtcbiAgICAgIGF3YWl0IGRlYnVnKCdDdXN0b20gcmVzb3VyY2UgaW52ZXN0aWdhdGlvbjogZW1wdHkgdGVtcGxhdGUgYm9keScpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGRlc2VyaWFsaXplU3RydWN0dXJlKHJlc3AuVGVtcGxhdGVCb2R5KTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgYXdhaXQgZGVidWcoYEN1c3RvbSByZXNvdXJjZSBpbnZlc3RpZ2F0aW9uOiBmYWlsZWQgdG8gcmVhZCB0ZW1wbGF0ZTogJHtlLm1lc3NhZ2V9YCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmUgdGhlIGJhY2tpbmcgTGFtYmRhJ3MgY29uZmlndXJlZCBsb2cgZ3JvdXAgZnJvbSB0aGUgdGVtcGxhdGUuXG4gKlxuICogVGhlIHRlbXBsYXRlIHN1cnZpdmVzIHJvbGxiYWNrICh3aGVuIHRoZSBsaXZlIGZ1bmN0aW9uIG1heSBub3QpLCBzbyBpdCBpcyB0aGUgcHJlZmVycmVkXG4gKiBzb3VyY2UuIEhhbmRsZXMgdGhlIGZ1bmN0aW9uJ3MgYExvZ2dpbmdDb25maWcuTG9nR3JvdXBgIGFzOlxuICogLSBhIGxpdGVyYWwgc3RyaW5nIChyZXR1cm5lZCBkaXJlY3RseSk7XG4gKiAtIGEgYFJlZmAgdG8gYW4gYEFXUzo6TG9nczo6TG9nR3JvdXBgIHdpdGggYSBsaXRlcmFsIGBMb2dHcm91cE5hbWVgIChyZXR1cm5lZCBkaXJlY3RseSk7XG4gKiAtIGEgYFJlZmAgdG8gYW4gYEFXUzo6TG9nczo6TG9nR3JvdXBgIHdob3NlIG5hbWUgQ2xvdWRGb3JtYXRpb24gZ2VuZXJhdGVzICh0aGUgY29tbW9uIENES1xuICogICBjYXNlKSDigJQgcmVzb2x2ZWQgdG8gaXRzIHBoeXNpY2FsIG5hbWUgdmlhIGBkZXNjcmliZVN0YWNrUmVzb3VyY2VzYCwgd2hpY2ggc3RpbGwgcmV0dXJuc1xuICogICBSRVRBSU5lZC9vcnBoYW5lZCByZXNvdXJjZXMgYWZ0ZXIgYSByb2xsYmFjay5cbiAqXG4gKiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgaXMgbm8gY29uZmlndXJlZCBsb2cgZ3JvdXAgb3IgaXQgY2FuJ3QgYmUgcmVzb2x2ZWRcbiAqIChjYWxsZXIgdGhlbiBmYWxscyBiYWNrIHRvIHRoZSBsaXZlIGZ1bmN0aW9uIGNvbmZpZ3VyYXRpb24pLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlQ29uZmlndXJlZExvZ0dyb3VwKFxuICBjZm46IElDbG91ZEZvcm1hdGlvbkNsaWVudCxcbiAgc3RhY2tOYW1lOiBzdHJpbmcsXG4gIHRlbXBsYXRlOiBhbnksXG4gIGZ1bmN0aW9uTG9naWNhbElkOiBzdHJpbmcsXG4gIGRlYnVnOiAobXNnOiBzdHJpbmcpID0+IFByb21pc2U8dm9pZD4sXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBsb2dHcm91cCA9IHRlbXBsYXRlLlJlc291cmNlcz8uW2Z1bmN0aW9uTG9naWNhbElkXT8uUHJvcGVydGllcz8uTG9nZ2luZ0NvbmZpZz8uTG9nR3JvdXA7XG4gIGlmICh0eXBlb2YgbG9nR3JvdXAgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGxvZ0dyb3VwO1xuICB9XG4gIGlmIChsb2dHcm91cCAmJiB0eXBlb2YgbG9nR3JvdXAgPT09ICdvYmplY3QnICYmIHR5cGVvZiBsb2dHcm91cC5SZWYgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgcmVmZXJlbmNlZCA9IHRlbXBsYXRlLlJlc291cmNlcz8uW2xvZ0dyb3VwLlJlZl07XG4gICAgY29uc3QgbmFtZSA9IHJlZmVyZW5jZWQ/LlByb3BlcnRpZXM/LkxvZ0dyb3VwTmFtZTtcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG4gICAgLy8gTm8gZXhwbGljaXQgbmFtZSAoQ2xvdWRGb3JtYXRpb24gZ2VuZXJhdGVzIGl0KSDigJQgcmVzb2x2ZSB0aGUgbG9nLWdyb3VwIHJlc291cmNlJ3NcbiAgICAvLyBwaHlzaWNhbCBuYW1lLCB3aGljaCBpcyB0aGUgbG9nIGdyb3VwIG5hbWUuXG4gICAgcmV0dXJuIChhd2FpdCByZXNvbHZlU3RhY2tSZXNvdXJjZShjZm4sIHN0YWNrTmFtZSwgbG9nR3JvdXAuUmVmLCBkZWJ1ZykpPy5waHlzaWNhbElkO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHJlc291cmNlJ3MgcGh5c2ljYWwgSUQgYW5kIHR5cGUgYnkgbG9naWNhbCBJRC4gUmV0dXJucyBgdW5kZWZpbmVkYCBvbiBmYWlsdXJlLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlU3RhY2tSZXNvdXJjZShcbiAgY2ZuOiBJQ2xvdWRGb3JtYXRpb25DbGllbnQsXG4gIHN0YWNrTmFtZTogc3RyaW5nLFxuICBsb2dpY2FsSWQ6IHN0cmluZyxcbiAgZGVidWc6IChtc2c6IHN0cmluZykgPT4gUHJvbWlzZTx2b2lkPixcbik6IFByb21pc2U8eyBwaHlzaWNhbElkPzogc3RyaW5nOyByZXNvdXJjZVR5cGU/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBjZm4uZGVzY3JpYmVTdGFja1Jlc291cmNlcyh7IFN0YWNrTmFtZTogc3RhY2tOYW1lLCBMb2dpY2FsUmVzb3VyY2VJZDogbG9naWNhbElkIH0pO1xuICAgIGNvbnN0IHJlc291cmNlID0gcmVzcC5TdGFja1Jlc291cmNlcz8uWzBdO1xuICAgIHJldHVybiByZXNvdXJjZSA/IHsgcGh5c2ljYWxJZDogcmVzb3VyY2UuUGh5c2ljYWxSZXNvdXJjZUlkLCByZXNvdXJjZVR5cGU6IHJlc291cmNlLlJlc291cmNlVHlwZSB9IDogdW5kZWZpbmVkO1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICBhd2FpdCBkZWJ1ZyhgQ3VzdG9tIHJlc291cmNlIGludmVzdGlnYXRpb246IGZhaWxlZCB0byByZXNvbHZlIHJlc291cmNlIFwiJHtsb2dpY2FsSWR9XCI6ICR7ZS5tZXNzYWdlfWApO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgYFNlcnZpY2VUb2tlbmAgdmFsdWUgKGEgbGl0ZXJhbCBBUk4sIGFuIGBGbjo6R2V0QXR0YCwgb3IgYSBgUmVmYCkgdG8gYSBMYW1iZGFcbiAqIGZ1bmN0aW9uIG5hbWUuIEludHJpbnNpY3MgYXJlIHJlc29sdmVkIHZpYSBgZGVzY3JpYmVTdGFja1Jlc291cmNlc2AuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVTZXJ2aWNlVG9rZW5Ub0Z1bmN0aW9uTmFtZShcbiAgY2ZuOiBJQ2xvdWRGb3JtYXRpb25DbGllbnQsXG4gIHN0YWNrTmFtZTogc3RyaW5nLFxuICBzZXJ2aWNlVG9rZW46IGFueSxcbiAgcmVmZXJlbmNlZExvZ2ljYWxJZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBkZWJ1ZzogKG1zZzogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+LFxuKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgaWYgKHJlZmVyZW5jZWRMb2dpY2FsSWQpIHtcbiAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IHJlc29sdmVTdGFja1Jlc291cmNlKGNmbiwgc3RhY2tOYW1lLCByZWZlcmVuY2VkTG9naWNhbElkLCBkZWJ1Zyk7XG4gICAgLy8gT25seSB0cmVhdCB0aGUgcmVmZXJlbmNlIGFzIGEgTGFtYmRhIGZ1bmN0aW9uLiBXaXRob3V0IHRoaXMsIGEgU2VydmljZVRva2VuIHBvaW50aW5nIGF0XG4gICAgLy8gYSBub24tTGFtYmRhIHJlc291cmNlIChlLmcuIGFuIFNOUyB0b3BpYykgd2hvc2UgcGh5c2ljYWwgSUQgaXMgYSBiYXJlIG5hbWUgd291bGQgYmVcbiAgICAvLyBtaXN0YWtlbiBmb3IgYSBmdW5jdGlvbiBuYW1lLCBwcm9kdWNpbmcgYSBtaXNsZWFkaW5nIC9hd3MvbGFtYmRhLzxuYW1lPiBsb2cgbG9va3VwLlxuICAgIGlmIChyZXNvdXJjZT8ucmVzb3VyY2VUeXBlICYmIHJlc291cmNlLnJlc291cmNlVHlwZSAhPT0gJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpIHtcbiAgICAgIGF3YWl0IGRlYnVnKGBDdXN0b20gcmVzb3VyY2UgaW52ZXN0aWdhdGlvbjogU2VydmljZVRva2VuIHJlZmVyZW5jZXMgYSAke3Jlc291cmNlLnJlc291cmNlVHlwZX0sIG5vdCBhIExhbWJkYSBmdW5jdGlvbmApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc291cmNlPy5waHlzaWNhbElkID8gZnVuY3Rpb25OYW1lRnJvbUFybk9yTmFtZShyZXNvdXJjZS5waHlzaWNhbElkKSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygc2VydmljZVRva2VuID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmdW5jdGlvbk5hbWVGcm9tQXJuT3JOYW1lKHNlcnZpY2VUb2tlbik7XG4gIH1cblxuICBhd2FpdCBkZWJ1ZygnQ3VzdG9tIHJlc291cmNlIGludmVzdGlnYXRpb246IHVuc3VwcG9ydGVkIFNlcnZpY2VUb2tlbiBzaGFwZScpO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmZXRjaEN1c3RvbVJlc291cmNlTG9ncyhcbiAgY3dsOiBJQ2xvdWRXYXRjaExvZ3NDbGllbnQsXG4gIGxhbWJkYTogSUxhbWJkYUNsaWVudCxcbiAgZnVuY3Rpb25OYW1lOiBzdHJpbmcsXG4gIHRlbXBsYXRlTG9nR3JvdXA6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgc3RyZWFtTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICB0aW1lc3RhbXA6IERhdGUgfCB1bmRlZmluZWQsXG4gIHJlZ2lvbjogc3RyaW5nLFxuICBkZWJ1ZzogKG1zZzogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+LFxuKTogUHJvbWlzZTxBZGRpdGlvbmFsRGlhZ25vc3RpY0NvbnRleHRbXT4ge1xuICBjb25zdCBmYWlsdXJlVGltZSA9IHRpbWVzdGFtcD8udmFsdWVPZigpO1xuICBjb25zdCBzdGFydFRpbWUgPSBmYWlsdXJlVGltZSAhPT0gdW5kZWZpbmVkID8gZmFpbHVyZVRpbWUgLSBMT0dfV0lORE9XX0JFRk9SRV9NUyA6IERhdGUubm93KCkgLSBGQUxMQkFDS19MT0dfV0lORE9XX01TO1xuICBjb25zdCBlbmRUaW1lID0gZmFpbHVyZVRpbWUgIT09IHVuZGVmaW5lZCA/IGZhaWx1cmVUaW1lICsgTE9HX1dJTkRPV19BRlRFUl9NUyA6IHVuZGVmaW5lZDtcblxuICAvLyBDb252ZW50aW9uIGZpcnN0OyBvbmx5IHBheSBmb3IgdGhlIGNvbmZpZ3VyZWQgZ3JvdXAgaWYgdGhlIGNvbnZlbnRpb24gZ3JvdXAgZG9lc24ndCB5aWVsZCB1c2FibGUgbGluZXMgKGVtcHR5IGdyb3VwIG9yIGZldGNoIGVycm9yKS5cbiAgY29uc3QgY29udmVudGlvbkdyb3VwID0gYC9hd3MvbGFtYmRhLyR7ZnVuY3Rpb25OYW1lfWA7XG4gIGxldCByZXN1bHQgPSBhd2FpdCBmZXRjaExvZ0xpbmVzKGN3bCwgY29udmVudGlvbkdyb3VwLCBzdHJlYW1OYW1lLCBzdGFydFRpbWUsIGVuZFRpbWUsIGRlYnVnKTtcbiAgLy8gVGhlIGdyb3VwIHdlIHBvaW50IHRoZSB1c2VyIGF0LiBPbmNlIHdlIGxlYXJuIHRoZSBmdW5jdGlvbidzIGNvbmZpZ3VyZWQgbG9nIGdyb3VwLCBwcmVmZXJcbiAgLy8gaXQgZm9yIHRoZSBsaW5rIGV2ZW4gaWYgaXQgdG9vIGlzIGVtcHR5IOKAlCBpdCdzIHdoZXJlIHRoZSBmdW5jdGlvbiBhY3R1YWxseSBsb2dzLCB3aGVyZWFzXG4gIC8vIHRoZSBjb252ZW50aW9uIGdyb3VwIG1heSBub3QgZXhpc3QgZm9yIGFkdmFuY2VkLWxvZ2dpbmcgZnVuY3Rpb25zLlxuICBsZXQgbG9nR3JvdXAgPSBjb252ZW50aW9uR3JvdXA7XG5cbiAgaWYgKHJlc3VsdC5raW5kICE9PSAnbGluZXMnKSB7XG4gICAgLy8gUHJlZmVyIHRoZSB0ZW1wbGF0ZS1kZXJpdmVkIGdyb3VwIChyb2xsYmFjay1wcm9vZik7IGZhbGwgYmFjayB0byB0aGUgbGl2ZSBmdW5jdGlvblxuICAgIC8vIGNvbmZpZ3VyYXRpb24gb25seSB3aGVuIHRoZSB0ZW1wbGF0ZSBjb3VsZG4ndCB0ZWxsIHVzIChlLmcuIHVucmVzb2x2YWJsZSBpbnRyaW5zaWMsIG9yXG4gICAgLy8gdGhlIGZ1bmN0aW9uIGlzIGRlZmluZWQgb3V0c2lkZSB0aGlzIHN0YWNrKS5cbiAgICBjb25zdCBjb25maWd1cmVkR3JvdXAgPSB0ZW1wbGF0ZUxvZ0dyb3VwID8/IGF3YWl0IGNvbmZpZ3VyZWRMb2dHcm91cChsYW1iZGEsIGZ1bmN0aW9uTmFtZSwgZGVidWcpO1xuICAgIGlmIChjb25maWd1cmVkR3JvdXAgJiYgY29uZmlndXJlZEdyb3VwICE9PSBjb252ZW50aW9uR3JvdXApIHtcbiAgICAgIGxvZ0dyb3VwID0gY29uZmlndXJlZEdyb3VwO1xuICAgICAgY29uc3QgY29uZmlndXJlZFJlc3VsdCA9IGF3YWl0IGZldGNoTG9nTGluZXMoY3dsLCBjb25maWd1cmVkR3JvdXAsIHN0cmVhbU5hbWUsIHN0YXJ0VGltZSwgZW5kVGltZSwgZGVidWcpO1xuICAgICAgLy8gS2VlcCB0aGUgY29uZmlndXJlZC1ncm91cCByZXN1bHQgdW5sZXNzIGl0IGVycm9yZWQgd2hpbGUgdGhlIGNvbnZlbnRpb24gYXR0ZW1wdCB3YXMgYVxuICAgICAgLy8gY2xlYW4gZW1wdHkgKGFuIFwiZW1wdHlcIiBhbnN3ZXIgaXMgbW9yZSBpbmZvcm1hdGl2ZSB0byBzdXJmYWNlIHRoYW4gYSBmZXRjaCBlcnJvcikuXG4gICAgICBpZiAoY29uZmlndXJlZFJlc3VsdC5raW5kID09PSAnbGluZXMnIHx8IHJlc3VsdC5raW5kICE9PSAnZW1wdHknKSB7XG4gICAgICAgIHJlc3VsdCA9IGNvbmZpZ3VyZWRSZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTGVhZCB3aXRoIHRoZSBsb2cgZ3JvdXAgc28gdGhlIHVzZXIgY2FuIHRlbGwgd2hpY2ggZnVuY3Rpb24gdGhlc2UgbG9ncyBiZWxvbmcgdG9cbiAgLy8gKHRoZSBmb3JtYXR0ZXIgcmVuZGVycyBtZXNzYWdlcyBidXQgbm90IGBzb3VyY2VgLCBhbmQgdGhlIGxpbmsgaXMgVVJMLWVuY29kZWQpLlxuICBjb25zdCBoZWFkZXIgPSBgTG9ncyBmcm9tICR7bG9nR3JvdXB9OmA7XG4gIGNvbnN0IGJvZHkgPSByZXN1bHQua2luZCA9PT0gJ2xpbmVzJ1xuICAgID8gcmVzdWx0LmxpbmVzXG4gICAgOiByZXN1bHQua2luZCA9PT0gJ2Vycm9yJ1xuICAgICAgPyBbJ0NvdWxkIG5vdCBmZXRjaCBsb2dzICh0aGUgbG9nIGdyb3VwIG1heSBub3QgZXhpc3QsIG9yIHRoZSBjcmVkZW50aWFscyBsYWNrIGxvZ3M6RmlsdGVyTG9nRXZlbnRzKS4gU2VlIHRoZSBjb25zb2xlIGxpbmsgYmVsb3cuJ11cbiAgICAgIDogWydObyBsb2cgZXZlbnRzIGZvdW5kIGFyb3VuZCB0aGUgdGltZSBvZiBmYWlsdXJlLiBUaGUgZnVuY3Rpb24gbWF5IG5vdCBoYXZlIHByb2R1Y2VkIG91dHB1dCwgb3IgbG9nZ2luZyBtYXkgbm90IGJlIGNvbmZpZ3VyZWQuJ107XG5cbiAgcmV0dXJuIFt7XG4gICAgc291cmNlOiAnQ3VzdG9tIFJlc291cmNlIExhbWJkYSBMb2dzJyxcbiAgICBtZXNzYWdlczogW2hlYWRlciwgLi4uYm9keV0sXG4gICAgbGluazogY2xvdWRXYXRjaExvZ3NDb25zb2xlVXJsKHJlZ2lvbiwgbG9nR3JvdXApLFxuICAgIGxpbmtMYWJlbDogJ0xvZ3MnLFxuICB9XTtcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgYXR0ZW1wdGluZyB0byBmZXRjaCBsb2dzIGZyb20gYSBncm91cDogdGhlIGxpbmVzIG9uIHN1Y2Nlc3MsIG9yIGEgcmVhc29uIHdlXG4gKiBoYXZlIG5vbmUg4oCUIGRpc3Rpbmd1aXNoaW5nIGFuIGVtcHR5IGdyb3VwIGZyb20gYSBmYWlsZWQgZmV0Y2ggKGUuZy4gbWlzc2luZyBwZXJtaXNzaW9ucyksXG4gKiBzbyB0aGUgdXNlci1mYWNpbmcgbWVzc2FnZSBjYW4gcmVmbGVjdCB0aGUgcmVhbCBjYXVzZS5cbiAqL1xudHlwZSBMb2dGZXRjaFJlc3VsdCA9XG4gIHwgeyBraW5kOiAnbGluZXMnOyBsaW5lczogc3RyaW5nW10gfVxuICB8IHsga2luZDogJ2VtcHR5JyB9XG4gIHwgeyBraW5kOiAnZXJyb3InIH07XG5cbi8qKlxuICogRmV0Y2ggYW5kIHRyaW0gcmVjZW50IGxvZyBsaW5lcyBmcm9tIGEgZ3JvdXAuXG4gKlxuICogVHJpZXMgdGhlIHRhcmdldGVkIHN0cmVhbSBmaXJzdCAobW9zdCByZWxldmFudCksIGJ1dCB0aGUgY2ZuLXJlc3BvbnNlIHN0cmVhbSBuYW1lIGNhbiBiZVxuICogc3RhbGUgb24gdXBkYXRlL3JvbGxiYWNrIGZhaWx1cmVzIChpdCdzIHBpbm5lZCB0byB0aGUgb3JpZ2luYWwgY3JlYXRlIGludm9jYXRpb24pLiBJZiB0aGVcbiAqIHRhcmdldGVkIHF1ZXJ5IGZpbmRzIG5vdGhpbmcsIGZhbGxzIGJhY2sgdG8gYSBncm91cC13aWRlIHNjYW4gb3ZlciB0aGUgdGltZSB3aW5kb3cgc28gYVxuICogc3RhbGUgc3RyZWFtIGNhbid0IGhpZGUgdGhlIGFjdHVhbCBmYWlsaW5nIGludm9jYXRpb24ncyBsb2dzLlxuICovXG5hc3luYyBmdW5jdGlvbiBmZXRjaExvZ0xpbmVzKFxuICBjd2w6IElDbG91ZFdhdGNoTG9nc0NsaWVudCxcbiAgbG9nR3JvdXA6IHN0cmluZyxcbiAgc3RyZWFtTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBzdGFydFRpbWU6IG51bWJlcixcbiAgZW5kVGltZTogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICBkZWJ1ZzogKG1zZzogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+LFxuKTogUHJvbWlzZTxMb2dGZXRjaFJlc3VsdD4ge1xuICBpZiAoc3RyZWFtTmFtZSkge1xuICAgIGNvbnN0IHRhcmdldGVkID0gYXdhaXQgZmlsdGVyTG9nTGluZXMoY3dsLCBsb2dHcm91cCwgc3RyZWFtTmFtZSwgc3RhcnRUaW1lLCBlbmRUaW1lLCBkZWJ1Zyk7XG4gICAgaWYgKHRhcmdldGVkLmtpbmQgPT09ICdsaW5lcycpIHtcbiAgICAgIHJldHVybiB0YXJnZXRlZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZpbHRlckxvZ0xpbmVzKGN3bCwgbG9nR3JvdXAsIHVuZGVmaW5lZCwgc3RhcnRUaW1lLCBlbmRUaW1lLCBkZWJ1Zyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZpbHRlckxvZ0xpbmVzKFxuICBjd2w6IElDbG91ZFdhdGNoTG9nc0NsaWVudCxcbiAgbG9nR3JvdXA6IHN0cmluZyxcbiAgc3RyZWFtTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBzdGFydFRpbWU6IG51bWJlcixcbiAgZW5kVGltZTogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICBkZWJ1ZzogKG1zZzogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+LFxuKTogUHJvbWlzZTxMb2dGZXRjaFJlc3VsdD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBjd2wuZmlsdGVyTG9nRXZlbnRzKHtcbiAgICAgIGxvZ0dyb3VwTmFtZTogbG9nR3JvdXAsXG4gICAgICBzdGFydFRpbWUsXG4gICAgICAuLi4oZW5kVGltZSAhPT0gdW5kZWZpbmVkID8geyBlbmRUaW1lIH0gOiB7fSksXG4gICAgICBsaW1pdDogMTAwMCxcbiAgICAgIC4uLihzdHJlYW1OYW1lID8geyBsb2dTdHJlYW1OYW1lczogW3N0cmVhbU5hbWVdIH0gOiB7fSksXG4gICAgfSk7XG4gICAgY29uc3QgZXZlbnRzID0gcmVzcC5ldmVudHMgPz8gW107XG4gICAgaWYgKGV2ZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGF3YWl0IGRlYnVnKGBDdXN0b20gcmVzb3VyY2UgaW52ZXN0aWdhdGlvbjogbm8gbG9nIGV2ZW50cyBpbiAke2xvZ0dyb3VwfSR7c3RyZWFtTmFtZSA/IGAgKHN0cmVhbTogJHtzdHJlYW1OYW1lfSlgIDogJyd9YCk7XG4gICAgICByZXR1cm4geyBraW5kOiAnZW1wdHknIH07XG4gICAgfVxuICAgIC8vIExhbWJkYSBsb2cgZXZlbnRzIGhhdmUgYSBrbm93biBzdHJ1Y3R1cmUgKHRleHQtIG9yIEpTT04tZm9ybWF0KSwgdW5saWtlIHJhdyBFQ1NcbiAgICAvLyBjb250YWluZXIgb3V0cHV0LCBzbyB3ZSBub3JtYWxpemUgdGhlbSBpbnRvIHJlYWRhYmxlIGxpbmVzIGJlZm9yZSB0cmltbWluZy5cbiAgICByZXR1cm4geyBraW5kOiAnbGluZXMnLCBsaW5lczogdHJpbVRvUmVjZW50TGluZXMocGFyc2VMYW1iZGFMb2dFdmVudHMoZXZlbnRzKSkgfTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgYXdhaXQgZGVidWcoYEN1c3RvbSByZXNvdXJjZSBpbnZlc3RpZ2F0aW9uOiBmYWlsZWQgdG8gZmV0Y2ggbG9ncyBmcm9tICR7bG9nR3JvdXB9OiAke2UubWVzc2FnZX1gKTtcbiAgICByZXR1cm4geyBraW5kOiAnZXJyb3InIH07XG4gIH1cbn1cblxuLyoqIFJlYWQgdGhlIGZ1bmN0aW9uJ3MgY29uZmlndXJlZCAoYWR2YW5jZWQtbG9nZ2luZykgbG9nIGdyb3VwLCBpZiBhbnkuICovXG5hc3luYyBmdW5jdGlvbiBjb25maWd1cmVkTG9nR3JvdXAoXG4gIGxhbWJkYTogSUxhbWJkYUNsaWVudCxcbiAgZnVuY3Rpb25OYW1lOiBzdHJpbmcsXG4gIGRlYnVnOiAobXNnOiBzdHJpbmcpID0+IFByb21pc2U8dm9pZD4sXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBsYW1iZGEuZ2V0RnVuY3Rpb25Db25maWd1cmF0aW9uKHsgRnVuY3Rpb25OYW1lOiBmdW5jdGlvbk5hbWUgfSk7XG4gICAgcmV0dXJuIHJlc3AuTG9nZ2luZ0NvbmZpZz8uTG9nR3JvdXA7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGF3YWl0IGRlYnVnKGBDdXN0b20gcmVzb3VyY2UgaW52ZXN0aWdhdGlvbjogZmFpbGVkIHRvIHJlYWQgZnVuY3Rpb24gY29uZmlndXJhdGlvbjogJHtlLm1lc3NhZ2V9YCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AdditionalDiagnosticContext } from '../../actions/diagnose';
|
|
2
|
+
import type { SDK } from '../aws-auth/sdk';
|
|
3
|
+
import type { ResourceError } from '../stack-events/resource-errors';
|
|
4
|
+
/**
|
|
5
|
+
* Options that influence how a resource is investigated.
|
|
6
|
+
*/
|
|
7
|
+
export interface InvestigateOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Whether CloudFormation rollback is enabled for this deployment.
|
|
10
|
+
*
|
|
11
|
+
* When rollback is enabled, a failed resource is torn down before we can
|
|
12
|
+
* inspect its runtime state, so we may suggest re-running with `--no-rollback`
|
|
13
|
+
* to retain that detail.
|
|
14
|
+
*
|
|
15
|
+
* @default true
|
|
16
|
+
*/
|
|
17
|
+
readonly rollbackEnabled?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function investigateEcsService(err: ResourceError, sdk: SDK, debug: (msg: string) => Promise<void>, options: InvestigateOptions): Promise<AdditionalDiagnosticContext[]>;
|
|
20
|
+
//# sourceMappingURL=investigate-ecs-service.d.ts.map
|