@jjrawlins/cfn-drift-remediate 0.0.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/.tool-versions +3 -0
- package/CLAUDE.md +61 -0
- package/LICENSE +202 -0
- package/README.md +113 -0
- package/lib/cli.d.ts +6 -0
- package/lib/cli.js +391 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +151 -0
- package/lib/lib/cfn-client.d.ts +75 -0
- package/lib/lib/cfn-client.js +258 -0
- package/lib/lib/eligible-resources.d.ts +27 -0
- package/lib/lib/eligible-resources.js +415 -0
- package/lib/lib/interactive.d.ts +30 -0
- package/lib/lib/interactive.js +238 -0
- package/lib/lib/plan.d.ts +21 -0
- package/lib/lib/plan.js +153 -0
- package/lib/lib/resource-identifier.d.ts +28 -0
- package/lib/lib/resource-identifier.js +231 -0
- package/lib/lib/resource-importer.d.ts +37 -0
- package/lib/lib/resource-importer.js +211 -0
- package/lib/lib/template-transformer.d.ts +64 -0
- package/lib/lib/template-transformer.js +531 -0
- package/lib/lib/types.d.ts +220 -0
- package/lib/lib/types.js +3 -0
- package/lib/lib/utils.d.ts +37 -0
- package/lib/lib/utils.js +51 -0
- package/package.json +122 -0
package/lib/cli.js
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.remediate = remediate;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const cfn_client_1 = require("./lib/cfn-client");
|
|
40
|
+
const eligible_resources_1 = require("./lib/eligible-resources");
|
|
41
|
+
const interactive_1 = require("./lib/interactive");
|
|
42
|
+
const plan_1 = require("./lib/plan");
|
|
43
|
+
const resource_importer_1 = require("./lib/resource-importer");
|
|
44
|
+
const template_transformer_1 = require("./lib/template-transformer");
|
|
45
|
+
const utils_1 = require("./lib/utils");
|
|
46
|
+
const DEFAULT_CAPABILITIES = ['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND'];
|
|
47
|
+
function packageVersion() {
|
|
48
|
+
try {
|
|
49
|
+
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
50
|
+
return JSON.parse(fs.readFileSync(pkgPath, 'utf-8')).version;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return 'unknown';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Main remediation function that orchestrates the drift remediation process
|
|
58
|
+
*/
|
|
59
|
+
async function remediate(options, spinner) {
|
|
60
|
+
const client = new cfn_client_1.CfnClientWrapper({
|
|
61
|
+
region: options.region,
|
|
62
|
+
profile: options.profile,
|
|
63
|
+
});
|
|
64
|
+
const result = {
|
|
65
|
+
success: false,
|
|
66
|
+
remediatedResources: [],
|
|
67
|
+
skippedResources: [],
|
|
68
|
+
removedResources: [],
|
|
69
|
+
errors: [],
|
|
70
|
+
};
|
|
71
|
+
const log = (message) => {
|
|
72
|
+
if (spinner) {
|
|
73
|
+
spinner.text = message;
|
|
74
|
+
}
|
|
75
|
+
else if (options.verbose) {
|
|
76
|
+
console.log(message);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
try {
|
|
80
|
+
// Step 1: Get stack info and original template
|
|
81
|
+
log('Fetching stack information...');
|
|
82
|
+
const stackInfo = await client.getStackInfo(options.stackName);
|
|
83
|
+
log('Fetching original template...');
|
|
84
|
+
const originalTemplateBody = await client.getTemplate(stackInfo.stackId, true);
|
|
85
|
+
const originalTemplate = (0, template_transformer_1.parseTemplate)(originalTemplateBody);
|
|
86
|
+
if (options.verbose) {
|
|
87
|
+
console.log(`Found stack: ${stackInfo.stackName} (${stackInfo.stackId})`);
|
|
88
|
+
}
|
|
89
|
+
// Steps 2-4: Detect drift and collect decisions (or load from plan)
|
|
90
|
+
let allDriftedResources;
|
|
91
|
+
let decisions;
|
|
92
|
+
if (options.applyPlan) {
|
|
93
|
+
// Apply a previously exported plan — skip drift detection and prompting
|
|
94
|
+
log('Loading remediation plan...');
|
|
95
|
+
const planJson = fs.readFileSync(path.resolve(options.applyPlan), 'utf-8');
|
|
96
|
+
const plan = (0, plan_1.loadPlan)(planJson, options.stackName);
|
|
97
|
+
const loaded = (0, plan_1.planToDecisions)(plan);
|
|
98
|
+
allDriftedResources = loaded.allDriftedResources;
|
|
99
|
+
decisions = loaded.decisions;
|
|
100
|
+
if (spinner)
|
|
101
|
+
spinner.start('Processing...');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Normal flow: detect drift and prompt interactively
|
|
105
|
+
// Step 2: Detect drift
|
|
106
|
+
log('Detecting stack drift...');
|
|
107
|
+
const detectionId = await client.detectDrift(stackInfo.stackId);
|
|
108
|
+
log('Waiting for drift detection to complete...');
|
|
109
|
+
const detectionResult = await client.waitForDriftDetection(detectionId);
|
|
110
|
+
if (detectionResult.status !== 'DETECTION_COMPLETE') {
|
|
111
|
+
result.errors.push(`Drift detection did not complete: ${detectionResult.status}`);
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
if (detectionResult.driftStatus === 'IN_SYNC') {
|
|
115
|
+
if (spinner)
|
|
116
|
+
spinner.succeed('Stack is in sync - no drift detected');
|
|
117
|
+
result.success = true;
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
// Step 3: Get drifted resources and separate by type
|
|
121
|
+
log('Analyzing drifted resources...');
|
|
122
|
+
allDriftedResources = await client.getDriftedResources(stackInfo.stackId);
|
|
123
|
+
if (allDriftedResources.length === 0) {
|
|
124
|
+
if (spinner)
|
|
125
|
+
spinner.succeed('No drifted resources found');
|
|
126
|
+
result.success = true;
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
// Filter to only importable resources
|
|
130
|
+
const modifiedResources = [];
|
|
131
|
+
const deletedResources = [];
|
|
132
|
+
for (const resource of allDriftedResources) {
|
|
133
|
+
if (!(0, eligible_resources_1.isResourceImportable)(resource.resourceType)) {
|
|
134
|
+
result.skippedResources.push(resource.logicalResourceId);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (resource.stackResourceDriftStatus === 'DELETED') {
|
|
138
|
+
deletedResources.push(resource);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
modifiedResources.push(resource);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (modifiedResources.length === 0 && deletedResources.length === 0) {
|
|
145
|
+
result.errors.push('All drifted resources are not eligible for import');
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
// Step 4: Interactive decisions
|
|
149
|
+
if (spinner)
|
|
150
|
+
spinner.stop();
|
|
151
|
+
decisions = await (0, interactive_1.promptForDecisions)(modifiedResources, deletedResources, options.yes ?? false);
|
|
152
|
+
if (spinner)
|
|
153
|
+
spinner.start('Processing...');
|
|
154
|
+
// Export plan if requested (exit without executing)
|
|
155
|
+
if (options.exportPlan) {
|
|
156
|
+
const planMetadata = {
|
|
157
|
+
stackName: stackInfo.stackName,
|
|
158
|
+
region: client.region,
|
|
159
|
+
createdAt: new Date().toISOString(),
|
|
160
|
+
toolVersion: packageVersion(),
|
|
161
|
+
driftDetectionId: detectionId,
|
|
162
|
+
};
|
|
163
|
+
const plan = (0, plan_1.buildPlan)(planMetadata, decisions);
|
|
164
|
+
const planPath = path.resolve(options.exportPlan);
|
|
165
|
+
fs.writeFileSync(planPath, (0, plan_1.serializePlan)(plan));
|
|
166
|
+
if (spinner)
|
|
167
|
+
spinner.succeed(`Plan exported to ${planPath}`);
|
|
168
|
+
result.success = true;
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Record skipped resources
|
|
173
|
+
for (const r of decisions.skip) {
|
|
174
|
+
result.skippedResources.push(r.logicalResourceId);
|
|
175
|
+
}
|
|
176
|
+
// If everything was skipped or cancelled, we're done
|
|
177
|
+
if (decisions.autofix.length === 0 && decisions.reimport.length === 0 && decisions.remove.length === 0) {
|
|
178
|
+
if (spinner)
|
|
179
|
+
spinner.succeed('No actions selected');
|
|
180
|
+
result.success = true;
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
// Step 5: Build resources to import from decisions
|
|
184
|
+
const resourceIdentifiers = await client.getResourceIdentifiers(originalTemplateBody);
|
|
185
|
+
// Autofix resources: use existing buildResourcesToImport
|
|
186
|
+
const { importable: autofixImportable, skipped: autofixSkipped } = (0, resource_importer_1.buildResourcesToImport)(decisions.autofix, resourceIdentifiers);
|
|
187
|
+
for (const s of autofixSkipped) {
|
|
188
|
+
if (!result.skippedResources.includes(s.logicalResourceId)) {
|
|
189
|
+
result.skippedResources.push(s.logicalResourceId);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Reimport resources: build from user-provided physical IDs
|
|
193
|
+
const reimportImportable = [];
|
|
194
|
+
for (const { resource, physicalId } of decisions.reimport) {
|
|
195
|
+
const descriptor = (0, resource_importer_1.buildReimportDescriptor)(resource, physicalId, resourceIdentifiers);
|
|
196
|
+
if (descriptor) {
|
|
197
|
+
reimportImportable.push(descriptor);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
result.errors.push(`Could not determine import identifier for ${resource.logicalResourceId} from "${physicalId}"`);
|
|
201
|
+
result.skippedResources.push(resource.logicalResourceId);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Combined importable list
|
|
205
|
+
const allImportable = [...autofixImportable, ...reimportImportable];
|
|
206
|
+
// If nothing to import AND nothing to remove, we're stuck
|
|
207
|
+
if (allImportable.length === 0 && decisions.remove.length === 0) {
|
|
208
|
+
result.errors.push('Could not determine import identifiers for any selected resources');
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
// Build the set of logical IDs that need removal from the template
|
|
212
|
+
// This includes everything being acted on (autofix, reimport, remove)
|
|
213
|
+
const logicalIdsToRemove = new Set([
|
|
214
|
+
...autofixImportable.map((r) => r.LogicalResourceId),
|
|
215
|
+
...reimportImportable.map((r) => r.LogicalResourceId),
|
|
216
|
+
...decisions.remove.map((r) => r.logicalResourceId),
|
|
217
|
+
]);
|
|
218
|
+
// Analyze cascade removals (resources with broken Ref/GetAtt to removed resources)
|
|
219
|
+
const cascadeRemovals = (0, template_transformer_1.analyzeCascadeRemovals)(originalTemplate, logicalIdsToRemove);
|
|
220
|
+
// Partition into permanent (depend on user-removed resources) vs temporary (depend on autofix/reimport)
|
|
221
|
+
const permanentlyRemovedIds = new Set(decisions.remove.map((r) => r.logicalResourceId));
|
|
222
|
+
const permanentCascade = cascadeRemovals.filter((c) => permanentlyRemovedIds.has(c.dependsOn));
|
|
223
|
+
const temporaryCascade = cascadeRemovals.filter((c) => !permanentlyRemovedIds.has(c.dependsOn));
|
|
224
|
+
if (cascadeRemovals.length > 0) {
|
|
225
|
+
if (spinner)
|
|
226
|
+
spinner.stop();
|
|
227
|
+
(0, interactive_1.displayCascadeWarning)(permanentCascade, temporaryCascade);
|
|
228
|
+
if (spinner)
|
|
229
|
+
spinner.start('Processing...');
|
|
230
|
+
}
|
|
231
|
+
// Dry run - show what would be done
|
|
232
|
+
if (options.dryRun) {
|
|
233
|
+
if (spinner)
|
|
234
|
+
spinner.info('Dry run - planned actions:');
|
|
235
|
+
if (allImportable.length > 0) {
|
|
236
|
+
console.log('\nResources to remediate:');
|
|
237
|
+
for (const resource of allImportable) {
|
|
238
|
+
console.log(` - ${resource.LogicalResourceId} (${resource.ResourceType})`);
|
|
239
|
+
console.log(` Identifier: ${JSON.stringify(resource.ResourceIdentifier)}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (decisions.remove.length > 0) {
|
|
243
|
+
console.log('\nResources to remove from stack:');
|
|
244
|
+
for (const r of decisions.remove) {
|
|
245
|
+
console.log(` - ${r.logicalResourceId} (${r.resourceType})`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (permanentCascade.length > 0) {
|
|
249
|
+
console.log('\nResources permanently cascade-removed (broken references):');
|
|
250
|
+
for (const c of permanentCascade) {
|
|
251
|
+
console.log(` - ${c.logicalResourceId} (${c.resourceType}) -> depends on ${c.dependsOn}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (temporaryCascade.length > 0) {
|
|
255
|
+
console.log('\nResources temporarily removed and recreated:');
|
|
256
|
+
for (const c of temporaryCascade) {
|
|
257
|
+
console.log(` - ${c.logicalResourceId} (${c.resourceType}) -> depends on ${c.dependsOn}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
result.success = true;
|
|
261
|
+
result.remediatedResources = allImportable.map((r) => r.LogicalResourceId);
|
|
262
|
+
result.removedResources = [
|
|
263
|
+
...decisions.remove.map((r) => r.logicalResourceId),
|
|
264
|
+
...permanentCascade.map((c) => c.logicalResourceId),
|
|
265
|
+
];
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
// Determine required capabilities
|
|
269
|
+
const resourceTypes = allImportable.map((r) => r.ResourceType);
|
|
270
|
+
const additionalCaps = (0, eligible_resources_1.getAllRequiredCapabilities)(resourceTypes);
|
|
271
|
+
const capabilities = [...new Set([...DEFAULT_CAPABILITIES, ...additionalCaps])];
|
|
272
|
+
// Save recovery checkpoint before any stack mutations
|
|
273
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
274
|
+
const backupFileName = `.cfn-drift-remediate-backup-${stackInfo.stackName}-${timestamp}.json`;
|
|
275
|
+
const backupPath = path.resolve(process.cwd(), backupFileName);
|
|
276
|
+
const checkpoint = {
|
|
277
|
+
stackName: stackInfo.stackName,
|
|
278
|
+
stackId: stackInfo.stackId,
|
|
279
|
+
originalTemplateBody,
|
|
280
|
+
parameters: stackInfo.parameters,
|
|
281
|
+
driftedResourceIds: Array.from(logicalIdsToRemove),
|
|
282
|
+
timestamp: new Date().toISOString(),
|
|
283
|
+
};
|
|
284
|
+
fs.writeFileSync(backupPath, JSON.stringify(checkpoint, null, 2));
|
|
285
|
+
log(`Recovery checkpoint saved to: ${backupPath}`);
|
|
286
|
+
if (options.verbose) {
|
|
287
|
+
console.log(`Recovery checkpoint: ${backupPath}`);
|
|
288
|
+
}
|
|
289
|
+
// Step 6: Set DeletionPolicy: Retain on all resources
|
|
290
|
+
// DELETED resources must be removed from the template first — CloudFormation
|
|
291
|
+
// cannot update metadata on resources that no longer exist in AWS.
|
|
292
|
+
log('Setting DeletionPolicy: Retain on all resources...');
|
|
293
|
+
const deletedLogicalIds = new Set(allDriftedResources
|
|
294
|
+
.filter((r) => r.stackResourceDriftStatus === 'DELETED' && logicalIdsToRemove.has(r.logicalResourceId))
|
|
295
|
+
.map((r) => r.logicalResourceId));
|
|
296
|
+
let retainTemplate = (0, template_transformer_1.setRetentionOnAllResources)(originalTemplate);
|
|
297
|
+
if (deletedLogicalIds.size > 0) {
|
|
298
|
+
// Remove deleted resources and clean up their dangling references
|
|
299
|
+
const { template: cleanedTemplate } = (0, template_transformer_1.transformTemplateForRemoval)(retainTemplate, deletedLogicalIds, new Map());
|
|
300
|
+
retainTemplate = cleanedTemplate;
|
|
301
|
+
}
|
|
302
|
+
await client.updateStack(stackInfo.stackId, (0, template_transformer_1.stringifyTemplate)(retainTemplate), retainTemplate.Parameters ? stackInfo.parameters : undefined, capabilities);
|
|
303
|
+
// Step 7: Resolve cross-references to MODIFIED resources being removed
|
|
304
|
+
// (DELETED resources are already removed from the template, so only MODIFIED refs remain)
|
|
305
|
+
const modifiedIdsToRemove = new Set([...logicalIdsToRemove].filter((id) => !deletedLogicalIds.has(id)));
|
|
306
|
+
const references = (0, template_transformer_1.collectReferences)(retainTemplate, modifiedIdsToRemove);
|
|
307
|
+
let resolvedValues = new Map();
|
|
308
|
+
if (references.size > 0) {
|
|
309
|
+
log('Resolving references to drifted resources...');
|
|
310
|
+
const outputTemplate = (0, template_transformer_1.addResolutionOutputs)(retainTemplate, references);
|
|
311
|
+
await client.updateStack(stackInfo.stackId, (0, template_transformer_1.stringifyTemplate)(outputTemplate), outputTemplate.Parameters ? stackInfo.parameters : undefined, capabilities);
|
|
312
|
+
const updatedStackInfo = await client.getStackInfo(stackInfo.stackId);
|
|
313
|
+
resolvedValues = (0, template_transformer_1.parseResolvedOutputs)(updatedStackInfo.outputs || [], references);
|
|
314
|
+
}
|
|
315
|
+
// Step 8: Remove remaining (MODIFIED) resources from template
|
|
316
|
+
log('Removing resources from stack (resources retained in AWS)...');
|
|
317
|
+
const { template: removalTemplate } = (0, template_transformer_1.transformTemplateForRemoval)(retainTemplate, modifiedIdsToRemove, resolvedValues);
|
|
318
|
+
const removalParams = removalTemplate.Parameters ? stackInfo.parameters : undefined;
|
|
319
|
+
await client.updateStack(stackInfo.stackId, (0, template_transformer_1.stringifyTemplate)(removalTemplate), removalParams, capabilities);
|
|
320
|
+
// Step 9: Import resources (only if there are resources to import)
|
|
321
|
+
if (allImportable.length > 0) {
|
|
322
|
+
log('Preparing import template with actual resource state...');
|
|
323
|
+
// Build import template from the removal template (current stack state)
|
|
324
|
+
// and add back the resources being imported with their actual properties
|
|
325
|
+
const importTemplate = (0, utils_1.deepClone)(removalTemplate);
|
|
326
|
+
for (const importable of allImportable) {
|
|
327
|
+
const logicalId = importable.LogicalResourceId;
|
|
328
|
+
const originalResource = originalTemplate.Resources?.[logicalId];
|
|
329
|
+
if (!originalResource)
|
|
330
|
+
continue;
|
|
331
|
+
// Start with original resource definition
|
|
332
|
+
importTemplate.Resources[logicalId] = (0, utils_1.deepClone)(originalResource);
|
|
333
|
+
// For autofix resources, override with actual (drifted) properties
|
|
334
|
+
const autofixResource = decisions.autofix.find((r) => r.logicalResourceId === logicalId);
|
|
335
|
+
if (autofixResource?.actualProperties && Object.keys(autofixResource.actualProperties).length > 0) {
|
|
336
|
+
importTemplate.Resources[logicalId].Properties = autofixResource.actualProperties;
|
|
337
|
+
}
|
|
338
|
+
importTemplate.Resources[logicalId].DeletionPolicy = 'Retain';
|
|
339
|
+
}
|
|
340
|
+
// Ensure Retain on all resources in import template
|
|
341
|
+
for (const logicalId of Object.keys(importTemplate.Resources)) {
|
|
342
|
+
importTemplate.Resources[logicalId].DeletionPolicy = 'Retain';
|
|
343
|
+
}
|
|
344
|
+
log('Creating import change set...');
|
|
345
|
+
const changeSetName = await client.createImportChangeSet(stackInfo.stackName, (0, template_transformer_1.stringifyTemplate)(importTemplate), allImportable, capabilities);
|
|
346
|
+
log('Executing import...');
|
|
347
|
+
await client.executeChangeSet(stackInfo.stackName, changeSetName);
|
|
348
|
+
}
|
|
349
|
+
// Step 10: Restore template
|
|
350
|
+
if (decisions.remove.length > 0) {
|
|
351
|
+
// Some resources permanently removed — restore original MINUS removed resources
|
|
352
|
+
log('Restoring template (excluding removed resources)...');
|
|
353
|
+
const restoredTemplate = (0, utils_1.deepClone)(originalTemplate);
|
|
354
|
+
for (const r of decisions.remove) {
|
|
355
|
+
delete restoredTemplate.Resources[r.logicalResourceId];
|
|
356
|
+
}
|
|
357
|
+
// Clean up references and outputs pointing to removed resources
|
|
358
|
+
const { template: cleanedTemplate } = (0, template_transformer_1.transformTemplateForRemoval)(restoredTemplate, new Set(decisions.remove.map((r) => r.logicalResourceId)), resolvedValues);
|
|
359
|
+
// Restore original DeletionPolicy values (transformTemplateForRemoval sets Retain on all)
|
|
360
|
+
for (const [logicalId, resource] of Object.entries(cleanedTemplate.Resources || {})) {
|
|
361
|
+
const originalResource = originalTemplate.Resources?.[logicalId];
|
|
362
|
+
if (originalResource?.DeletionPolicy) {
|
|
363
|
+
resource.DeletionPolicy = originalResource.DeletionPolicy;
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
delete resource.DeletionPolicy;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
await client.updateStack(stackInfo.stackName, (0, template_transformer_1.stringifyTemplate)(cleanedTemplate), cleanedTemplate.Parameters ? stackInfo.parameters : undefined, capabilities);
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
// No removals — restore exact original
|
|
373
|
+
log('Restoring original template...');
|
|
374
|
+
await client.updateStack(stackInfo.stackName, originalTemplateBody, stackInfo.parameters, capabilities);
|
|
375
|
+
}
|
|
376
|
+
result.success = true;
|
|
377
|
+
result.remediatedResources = allImportable.map((r) => r.LogicalResourceId);
|
|
378
|
+
result.removedResources = [
|
|
379
|
+
...decisions.remove.map((r) => r.logicalResourceId),
|
|
380
|
+
...permanentCascade.map((c) => c.logicalResourceId),
|
|
381
|
+
];
|
|
382
|
+
if (options.verbose) {
|
|
383
|
+
console.log(`Remediation complete. Recovery checkpoint can be removed: ${backupPath}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
result.errors.push(error instanceof Error ? error.message : String(error));
|
|
388
|
+
}
|
|
389
|
+
return result;
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBDQSw4QkE2YUM7QUF2ZEQsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQUU3QixpREFBb0Q7QUFDcEQsaUVBQTRGO0FBQzVGLG1EQUE4RTtBQUM5RSxxQ0FBaUY7QUFDakYsK0RBQTBGO0FBQzFGLHFFQVNvQztBQVNwQyx1Q0FBd0M7QUFFeEMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLGdCQUFnQixFQUFFLHNCQUFzQixFQUFFLHdCQUF3QixDQUFDLENBQUM7QUFFbEcsU0FBUyxjQUFjO0lBQ3JCLElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQztRQUMzRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDL0QsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7QUFDSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSSxLQUFLLFVBQVUsU0FBUyxDQUM3QixPQUEyQixFQUMzQixPQUFhO0lBRWIsTUFBTSxNQUFNLEdBQUcsSUFBSSw2QkFBZ0IsQ0FBQztRQUNsQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07UUFDdEIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO0tBQ3pCLENBQUMsQ0FBQztJQUVILE1BQU0sTUFBTSxHQUFzQjtRQUNoQyxPQUFPLEVBQUUsS0FBSztRQUNkLG1CQUFtQixFQUFFLEVBQUU7UUFDdkIsZ0JBQWdCLEVBQUUsRUFBRTtRQUNwQixnQkFBZ0IsRUFBRSxFQUFFO1FBQ3BCLE1BQU0sRUFBRSxFQUFFO0tBQ1gs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TUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgT3JhIH0gZnJvbSAnb3JhJztcbmltcG9ydCB7IENmbkNsaWVudFdyYXBwZXIgfSBmcm9tICcuL2xpYi9jZm4tY2xpZW50JztcbmltcG9ydCB7IGlzUmVzb3VyY2VJbXBvcnRhYmxlLCBnZXRBbGxSZXF1aXJlZENhcGFiaWxpdGllcyB9IGZyb20gJy4vbGliL2VsaWdpYmxlLXJlc291cmNlcyc7XG5pbXBvcnQgeyBkaXNwbGF5Q2FzY2FkZVdhcm5pbmcsIHByb21wdEZvckRlY2lzaW9ucyB9IGZyb20gJy4vbGliL2ludGVyYWN0aXZlJztcbmltcG9ydCB7IGJ1aWxkUGxhbiwgc2VyaWFsaXplUGxhbiwgbG9hZFBsYW4sIHBsYW5Ub0RlY2lzaW9ucyB9IGZyb20gJy4vbGliL3BsYW4nO1xuaW1wb3J0IHsgYnVpbGRSZXNvdXJjZXNUb0ltcG9ydCwgYnVpbGRSZWltcG9ydERlc2NyaXB0b3IgfSBmcm9tICcuL2xpYi9yZXNvdXJjZS1pbXBvcnRlcic7XG5pbXBvcnQge1xuICBwYXJzZVRlbXBsYXRlLFxuICBzdHJpbmdpZnlUZW1wbGF0ZSxcbiAgY29sbGVjdFJlZmVyZW5jZXMsXG4gIGFkZFJlc29sdXRpb25PdXRwdXRzLFxuICBwYXJzZVJlc29sdmVkT3V0cHV0cyxcbiAgc2V0UmV0ZW50aW9uT25BbGxSZXNvdXJjZXMsXG4gIHRyYW5zZm9ybVRlbXBsYXRlRm9yUmVtb3ZhbCxcbiAgYW5hbHl6ZUNhc2NhZGVSZW1vdmFscyxcbn0gZnJvbSAnLi9saWIvdGVtcGxhdGUtdHJhbnNmb3JtZXInO1xuaW1wb3J0IHtcbiAgUmVtZWRpYXRpb25PcHRpb25zLFxuICBSZW1lZGlhdGlvblJlc3VsdCxcbiAgUmVjb3ZlcnlDaGVja3BvaW50LFxuICBEcmlmdGVkUmVzb3VyY2UsXG4gIEludGVyYWN0aXZlRGVjaXNpb25zLFxuICBSZXNvdXJjZVRvSW1wb3J0LFxufSBmcm9tICcuL2xpYi90eXBlcyc7XG5pbXBvcnQgeyBkZWVwQ2xvbmUgfSBmcm9tICcuL2xpYi91dGlscyc7XG5cbmNvbnN0IERFRkFVTFRfQ0FQQUJJTElUSUVTID0gWydDQVBBQklMSVRZX0lBTScsICdDQVBBQklMSVRZX05BTUVEX0lBTScsICdDQVBBQklMSVRZX0FVVE9fRVhQQU5EJ107XG5cbmZ1bmN0aW9uIHBhY2thZ2VWZXJzaW9uKCk6IHN0cmluZyB7XG4gIHRyeSB7XG4gICAgY29uc3QgcGtnUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICdwYWNrYWdlLmpzb24nKTtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMocGtnUGF0aCwgJ3V0Zi04JykpLnZlcnNpb247XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiAndW5rbm93bic7XG4gIH1cbn1cblxuLyoqXG4gKiBNYWluIHJlbWVkaWF0aW9uIGZ1bmN0aW9uIHRoYXQgb3JjaGVzdHJhdGVzIHRoZSBkcmlmdCByZW1lZGlhdGlvbiBwcm9jZXNzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW1lZGlhdGUoXG4gIG9wdGlvbnM6IFJlbWVkaWF0aW9uT3B0aW9ucyxcbiAgc3Bpbm5lcj86IE9yYSxcbik6IFByb21pc2U8UmVtZWRpYXRpb25SZXN1bHQ+IHtcbiAgY29uc3QgY2xpZW50ID0gbmV3IENmbkNsaWVudFdyYXBwZXIoe1xuICAgIHJlZ2lvbjogb3B0aW9ucy5yZWdpb24sXG4gICAgcHJvZmlsZTogb3B0aW9ucy5wcm9maWxlLFxuICB9KTtcblxuICBjb25zdCByZXN1bHQ6IFJlbWVkaWF0aW9uUmVzdWx0ID0ge1xuICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgIHJlbWVkaWF0ZWRSZXNvdXJjZXM6IFtdLFxuICAgIHNraXBwZWRSZXNvdXJjZXM6IFtdLFxuICAgIHJlbW92ZWRSZXNvdXJjZXM6IFtdLFxuICAgIGVycm9yczogW10sXG4gIH07XG5cbiAgY29uc3QgbG9nID0gKG1lc3NhZ2U6IHN0cmluZykgPT4ge1xuICAgIGlmIChzcGlubmVyKSB7XG4gICAgICBzcGlubmVyLnRleHQgPSBtZXNzYWdlO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICBjb25zb2xlLmxvZyhtZXNzYWdlKTtcbiAgICB9XG4gIH07XG5cbiAgdHJ5IHtcbiAgICAvLyBTdGVwIDE6IEdldCBzdGFjayBpbmZvIGFuZCBvcmlnaW5hbCB0ZW1wbGF0ZVxuICAgIGxvZygnRmV0Y2hpbmcgc3RhY2sgaW5mb3JtYXRpb24uLi4nKTtcbiAgICBjb25zdCBzdGFja0luZm8gPSBhd2FpdCBjbGllbnQuZ2V0U3RhY2tJbmZvKG9wdGlvbnMuc3RhY2tOYW1lKTtcblxuICAgIGxvZygnRmV0Y2hpbmcgb3JpZ2luYWwgdGVtcGxhdGUuLi4nKTtcbiAgICBjb25zdCBvcmlnaW5hbFRlbXBsYXRlQm9keSA9IGF3YWl0IGNsaWVudC5nZXRUZW1wbGF0ZShzdGFja0luZm8uc3RhY2tJZCwgdHJ1ZSk7XG4gICAgY29uc3Qgb3JpZ2luYWxUZW1wbGF0ZSA9IHBhcnNlVGVtcGxhdGUob3JpZ2luYWxUZW1wbGF0ZUJvZHkpO1xuXG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgY29uc29sZS5sb2coYEZvdW5kIHN0YWNrOiAke3N0YWNrSW5mby5zdGFja05hbWV9ICgke3N0YWNrSW5mby5zdGFja0lkfSlgKTtcbiAgICB9XG5cbiAgICAvLyBTdGVwcyAyLTQ6IERldGVjdCBkcmlmdCBhbmQgY29sbGVjdCBkZWNpc2lvbnMgKG9yIGxvYWQgZnJvbSBwbGFuKVxuICAgIGxldCBhbGxEcmlmdGVkUmVzb3VyY2VzOiBEcmlmdGVkUmVzb3VyY2VbXTtcbiAgICBsZXQgZGVjaXNpb25zOiBJbnRlcmFjdGl2ZURlY2lzaW9ucztcblxuICAgIGlmIChvcHRpb25zLmFwcGx5UGxhbikge1xuICAgICAgLy8gQXBwbHkgYSBwcmV2aW91c2x5IGV4cG9ydGVkIHBsYW4g4oCUIHNraXAgZHJpZnQgZGV0ZWN0aW9uIGFuZCBwcm9tcHRpbmdcbiAgICAgIGxvZygnTG9hZGluZyByZW1lZGlhdGlvbiBwbGFuLi4uJyk7XG4gICAgICBjb25zdCBwbGFuSnNvbiA9IGZzLnJlYWRGaWxlU3luYyhwYXRoLnJlc29sdmUob3B0aW9ucy5hcHBseVBsYW4pLCAndXRmLTgnKTtcbiAgICAgIGNvbnN0IHBsYW4gPSBsb2FkUGxhbihwbGFuSnNvbiwgb3B0aW9ucy5zdGFja05hbWUpO1xuICAgICAgY29uc3QgbG9hZGVkID0gcGxhblRvRGVjaXNpb25zKHBsYW4pO1xuICAgICAgYWxsRHJpZnRlZFJlc291cmNlcyA9IGxvYWRlZC5hbGxEcmlmdGVkUmVzb3VyY2VzO1xuICAgICAgZGVjaXNpb25zID0gbG9hZGVkLmRlY2lzaW9ucztcblxuICAgICAgaWYgKHNwaW5uZXIpIHNwaW5uZXIuc3RhcnQoJ1Byb2Nlc3NpbmcuLi4nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm9ybWFsIGZsb3c6IGRldGVjdCBkcmlmdCBhbmQgcHJvbXB0IGludGVyYWN0aXZlbHlcblxuICAgICAgLy8gU3RlcCAyOiBEZXRlY3QgZHJpZnRcbiAgICAgIGxvZygnRGV0ZWN0aW5nIHN0YWNrIGRyaWZ0Li4uJyk7XG4gICAgICBjb25zdCBkZXRlY3Rpb25JZCA9IGF3YWl0IGNsaWVudC5kZXRlY3REcmlmdChzdGFja0luZm8uc3RhY2tJZCk7XG5cbiAgICAgIGxvZygnV2FpdGluZyBmb3IgZHJpZnQgZGV0ZWN0aW9uIHRvIGNvbXBsZXRlLi4uJyk7XG4gICAgICBjb25zdCBkZXRlY3Rpb25SZXN1bHQgPSBhd2FpdCBjbGllbnQud2FpdEZvckRyaWZ0RGV0ZWN0aW9uKGRldGVjdGlvbklkKTtcblxuICAgICAgaWYgKGRldGVjdGlvblJlc3VsdC5zdGF0dXMgIT09ICdERVRFQ1RJT05fQ09NUExFVEUnKSB7XG4gICAgICAgIHJlc3VsdC5lcnJvcnMucHVzaChgRHJpZnQgZGV0ZWN0aW9uIGRpZCBub3QgY29tcGxldGU6ICR7ZGV0ZWN0aW9uUmVzdWx0LnN0YXR1c31gKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgaWYgKGRldGVjdGlvblJlc3VsdC5kcmlmdFN0YXR1cyA9PT0gJ0lOX1NZTkMnKSB7XG4gICAgICAgIGlmIChzcGlubmVyKSBzcGlubmVyLnN1Y2NlZWQoJ1N0YWNrIGlzIGluIHN5bmMgLSBubyBkcmlmdCBkZXRlY3RlZCcpO1xuICAgICAgICByZXN1bHQuc3VjY2VzcyA9IHRydWU7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0ZXAgMzogR2V0IGRyaWZ0ZWQgcmVzb3VyY2VzIGFuZCBzZXBhcmF0ZSBieSB0eXBlXG4gICAgICBsb2coJ0FuYWx5emluZyBkcmlmdGVkIHJlc291cmNlcy4uLicpO1xuICAgICAgYWxsRHJpZnRlZFJlc291cmNlcyA9IGF3YWl0IGNsaWVudC5nZXREcmlmdGVkUmVzb3VyY2VzKHN0YWNrSW5mby5zdGFja0lkKTtcblxuICAgICAgaWYgKGFsbERyaWZ0ZWRSZXNvdXJjZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlmIChzcGlubmVyKSBzcGlubmVyLnN1Y2NlZWQoJ05vIGRyaWZ0ZWQgcmVzb3VyY2VzIGZvdW5kJyk7XG4gICAgICAgIHJlc3VsdC5zdWNjZXNzID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgLy8gRmlsdGVyIHRvIG9ubHkgaW1wb3J0YWJsZSByZXNvdXJjZXNcbiAgICAgIGNvbnN0IG1vZGlmaWVkUmVzb3VyY2VzOiBEcmlmdGVkUmVzb3VyY2VbXSA9IFtdO1xuICAgICAgY29uc3QgZGVsZXRlZFJlc291cmNlczogRHJpZnRlZFJlc291cmNlW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCByZXNvdXJjZSBvZiBhbGxEcmlmdGVkUmVzb3VyY2VzKSB7XG4gICAgICAgIGlmICghaXNSZXNvdXJjZUltcG9ydGFibGUocmVzb3VyY2UucmVzb3VyY2VUeXBlKSkge1xuICAgICAgICAgIHJlc3VsdC5za2lwcGVkUmVzb3VyY2VzLnB1c2gocmVzb3VyY2UubG9naWNhbFJlc291cmNlSWQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXNvdXJjZS5zdGFja1Jlc291cmNlRHJpZnRTdGF0dXMgPT09ICdERUxFVEVEJykge1xuICAgICAgICAgIGRlbGV0ZWRSZXNvdXJjZXMucHVzaChyZXNvdXJjZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbW9kaWZpZWRSZXNvdXJjZXMucHVzaChyZXNvdXJjZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG1vZGlmaWVkUmVzb3VyY2VzLmxlbmd0aCA9PT0gMCAmJiBkZWxldGVkUmVzb3VyY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXN1bHQuZXJyb3JzLnB1c2goJ0FsbCBkcmlmdGVkIHJlc291cmNlcyBhcmUgbm90IGVsaWdpYmxlIGZvciBpbXBvcnQnKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgLy8gU3RlcCA0OiBJbnRlcmFjdGl2ZSBkZWNpc2lvbnNcbiAgICAgIGlmIChzcGlubmVyKSBzcGlubmVyLnN0b3AoKTtcblxuICAgICAgZGVjaXNpb25zID0gYXdhaXQgcHJvbXB0Rm9yRGVjaXNpb25zKFxuICAgICAgICBtb2RpZmllZFJlc291cmNlcyxcbiAgICAgICAgZGVsZXRlZFJlc291cmNlcyxcbiAgICAgICAgb3B0aW9ucy55ZXMgPz8gZmFsc2UsXG4gICAgICApO1xuXG4gICAgICBpZiAoc3Bpbm5lcikgc3Bpbm5lci5zdGFydCgnUHJvY2Vzc2luZy4uLicpO1xuXG4gICAgICAvLyBFeHBvcnQgcGxhbiBpZiByZXF1ZXN0ZWQgKGV4aXQgd2l0aG91dCBleGVjdXRpbmcpXG4gICAgICBpZiAob3B0aW9ucy5leHBvcnRQbGFuKSB7XG4gICAgICAgIGNvbnN0IHBsYW5NZXRhZGF0YSA9IHtcbiAgICAgICAgICBzdGFja05hbWU6IHN0YWNrSW5mby5zdGFja05hbWUsXG4gICAgICAgICAgcmVnaW9uOiBjbGllbnQucmVnaW9uLFxuICAgICAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIHRvb2xWZXJzaW9uOiBwYWNrYWdlVmVyc2lvbigpLFxuICAgICAgICAgIGRyaWZ0RGV0ZWN0aW9uSWQ6IGRldGVjdGlvbklkLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwbGFuID0gYnVpbGRQbGFuKHBsYW5NZXRhZGF0YSwgZGVjaXNpb25zKTtcbiAgICAgICAgY29uc3QgcGxhblBhdGggPSBwYXRoLnJlc29sdmUob3B0aW9ucy5leHBvcnRQbGFuKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhwbGFuUGF0aCwgc2VyaWFsaXplUGxhbihwbGFuKSk7XG4gICAgICAgIGlmIChzcGlubmVyKSBzcGlubmVyLnN1Y2NlZWQoYFBsYW4gZXhwb3J0ZWQgdG8gJHtwbGFuUGF0aH1gKTtcbiAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSB0cnVlO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlY29yZCBza2lwcGVkIHJlc291cmNlc1xuICAgIGZvciAoY29uc3QgciBvZiBkZWNpc2lvbnMuc2tpcCkge1xuICAgICAgcmVzdWx0LnNraXBwZWRSZXNvdXJjZXMucHVzaChyLmxvZ2ljYWxSZXNvdXJjZUlkKTtcbiAgICB9XG5cbiAgICAvLyBJZiBldmVyeXRoaW5nIHdhcyBza2lwcGVkIG9yIGNhbmNlbGxlZCwgd2UncmUgZG9uZVxuICAgIGlmIChkZWNpc2lvbnMuYXV0b2ZpeC5sZW5ndGggPT09IDAgJiYgZGVjaXNpb25zLnJlaW1wb3J0Lmxlbmd0aCA9PT0gMCAmJiBkZWNpc2lvbnMucmVtb3ZlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKHNwaW5uZXIpIHNwaW5uZXIuc3VjY2VlZCgnTm8gYWN0aW9ucyBzZWxlY3RlZCcpO1xuICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSB0cnVlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyBTdGVwIDU6IEJ1aWxkIHJlc291cmNlcyB0byBpbXBvcnQgZnJvbSBkZWNpc2lvbnNcbiAgICBjb25zdCByZXNvdXJjZUlkZW50aWZpZXJzID0gYXdhaXQgY2xpZW50LmdldFJlc291cmNlSWRlbnRpZmllcnMob3JpZ2luYWxUZW1wbGF0ZUJvZHkpO1xuXG4gICAgLy8gQXV0b2ZpeCByZXNvdXJjZXM6IHVzZSBleGlzdGluZyBidWlsZFJlc291cmNlc1RvSW1wb3J0XG4gICAgY29uc3QgeyBpbXBvcnRhYmxlOiBhdXRvZml4SW1wb3J0YWJsZSwgc2tpcHBlZDogYXV0b2ZpeFNraXBwZWQgfSA9XG4gICAgICBidWlsZFJlc291cmNlc1RvSW1wb3J0KGRlY2lzaW9ucy5hdXRvZml4LCByZXNvdXJjZUlkZW50aWZpZXJzKTtcblxuICAgIGZvciAoY29uc3QgcyBvZiBhdXRvZml4U2tpcHBlZCkge1xuICAgICAgaWYgKCFyZXN1bHQuc2tpcHBlZFJlc291cmNlcy5pbmNsdWRlcyhzLmxvZ2ljYWxSZXNvdXJjZUlkKSkge1xuICAgICAgICByZXN1bHQuc2tpcHBlZFJlc291cmNlcy5wdXNoKHMubG9naWNhbFJlc291cmNlSWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlaW1wb3J0IHJlc291cmNlczogYnVpbGQgZnJvbSB1c2VyLXByb3ZpZGVkIHBoeXNpY2FsIElEc1xuICAgIGNvbnN0IHJlaW1wb3J0SW1wb3J0YWJsZTogUmVzb3VyY2VUb0ltcG9ydFtdID0gW107XG4gICAgZm9yIChjb25zdCB7IHJlc291cmNlLCBwaHlzaWNhbElkIH0gb2YgZGVjaXNpb25zLnJlaW1wb3J0KSB7XG4gICAgICBjb25zdCBkZXNjcmlwdG9yID0gYnVpbGRSZWltcG9ydERlc2NyaXB0b3IocmVzb3VyY2UsIHBoeXNpY2FsSWQsIHJlc291cmNlSWRlbnRpZmllcnMpO1xuICAgICAgaWYgKGRlc2NyaXB0b3IpIHtcbiAgICAgICAgcmVpbXBvcnRJbXBvcnRhYmxlLnB1c2goZGVzY3JpcHRvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQuZXJyb3JzLnB1c2goXG4gICAgICAgICAgYENvdWxkIG5vdCBkZXRlcm1pbmUgaW1wb3J0IGlkZW50aWZpZXIgZm9yICR7cmVzb3VyY2UubG9naWNhbFJlc291cmNlSWR9IGZyb20gXCIke3BoeXNpY2FsSWR9XCJgLFxuICAgICAgICApO1xuICAgICAgICByZXN1bHQuc2tpcHBlZFJlc291cmNlcy5wdXNoKHJlc291cmNlLmxvZ2ljYWxSZXNvdXJjZUlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDb21iaW5lZCBpbXBvcnRhYmxlIGxpc3RcbiAgICBjb25zdCBhbGxJbXBvcnRhYmxlID0gWy4uLmF1dG9maXhJbXBvcnRhYmxlLCAuLi5yZWltcG9ydEltcG9ydGFibGVdO1xuXG4gICAgLy8gSWYgbm90aGluZyB0byBpbXBvcnQgQU5EIG5vdGhpbmcgdG8gcmVtb3ZlLCB3ZSdyZSBzdHVja1xuICAgIGlmIChhbGxJbXBvcnRhYmxlLmxlbmd0aCA9PT0gMCAmJiBkZWNpc2lvbnMucmVtb3ZlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmVzdWx0LmVycm9ycy5wdXNoKCdDb3VsZCBub3QgZGV0ZXJtaW5lIGltcG9ydCBpZGVudGlmaWVycyBmb3IgYW55IHNlbGVjdGVkIHJlc291cmNlcycpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyBCdWlsZCB0aGUgc2V0IG9mIGxvZ2ljYWwgSURzIHRoYXQgbmVlZCByZW1vdmFsIGZyb20gdGhlIHRlbXBsYXRlXG4gICAgLy8gVGhpcyBpbmNsdWRlcyBldmVyeXRoaW5nIGJlaW5nIGFjdGVkIG9uIChhdXRvZml4LCByZWltcG9ydCwgcmVtb3ZlKVxuICAgIGNvbnN0IGxvZ2ljYWxJZHNUb1JlbW92ZSA9IG5ldyBTZXQoW1xuICAgICAgLi4uYXV0b2ZpeEltcG9ydGFibGUubWFwKChyKSA9PiByLkxvZ2ljYWxSZXNvdXJjZUlkKSxcbiAgICAgIC4uLnJlaW1wb3J0SW1wb3J0YWJsZS5tYXAoKHIpID0+IHIuTG9naWNhbFJlc291cmNlSWQpLFxuICAgICAgLi4uZGVjaXNpb25zLnJlbW92ZS5tYXAoKHIpID0+IHIubG9naWNhbFJlc291cmNlSWQpLFxuICAgIF0pO1xuXG4gICAgLy8gQW5hbHl6ZSBjYXNjYWRlIHJlbW92YWxzIChyZXNvdXJjZXMgd2l0aCBicm9rZW4gUmVmL0dldEF0dCB0byByZW1vdmVkIHJlc291cmNlcylcbiAgICBjb25zdCBjYXNjYWRlUmVtb3ZhbHMgPSBhbmFseXplQ2FzY2FkZVJlbW92YWxzKG9yaWdpbmFsVGVtcGxhdGUsIGxvZ2ljYWxJZHNUb1JlbW92ZSk7XG5cbiAgICAvLyBQYXJ0aXRpb24gaW50byBwZXJtYW5lbnQgKGRlcGVuZCBvbiB1c2VyLXJlbW92ZWQgcmVzb3VyY2VzKSB2cyB0ZW1wb3JhcnkgKGRlcGVuZCBvbiBhdXRvZml4L3JlaW1wb3J0KVxuICAgIGNvbnN0IHBlcm1hbmVudGx5UmVtb3ZlZElkcyA9IG5ldyBTZXQoZGVjaXNpb25zLnJlbW92ZS5tYXAoKHIpID0+IHIubG9naWNhbFJlc291cmNlSWQpKTtcbiAgICBjb25zdCBwZXJtYW5lbnRDYXNjYWRlID0gY2FzY2FkZVJlbW92YWxzLmZpbHRlcigoYykgPT4gcGVybWFuZW50bHlSZW1vdmVkSWRzLmhhcyhjLmRlcGVuZHNPbikpO1xuICAgIGNvbnN0IHRlbXBvcmFyeUNhc2NhZGUgPSBjYXNjYWRlUmVtb3ZhbHMuZmlsdGVyKChjKSA9PiAhcGVybWFuZW50bHlSZW1vdmVkSWRzLmhhcyhjLmRlcGVuZHNPbikpO1xuXG4gICAgaWYgKGNhc2NhZGVSZW1vdmFscy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoc3Bpbm5lcikgc3Bpbm5lci5zdG9wKCk7XG4gICAgICBkaXNwbGF5Q2FzY2FkZVdhcm5pbmcocGVybWFuZW50Q2FzY2FkZSwgdGVtcG9yYXJ5Q2FzY2FkZSk7XG4gICAgICBpZiAoc3Bpbm5lcikgc3Bpbm5lci5zdGFydCgnUHJvY2Vzc2luZy4uLicpO1xuICAgIH1cblxuICAgIC8vIERyeSBydW4gLSBzaG93IHdoYXQgd291bGQgYmUgZG9uZVxuICAgIGlmIChvcHRpb25zLmRyeVJ1bikge1xuICAgICAgaWYgKHNwaW5uZXIpIHNwaW5uZXIuaW5mbygnRHJ5IHJ1biAtIHBsYW5uZWQgYWN0aW9uczonKTtcbiAgICAgIGlmIChhbGxJbXBvcnRhYmxlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1xcblJlc291cmNlcyB0byByZW1lZGlhdGU6Jyk7XG4gICAgICAgIGZvciAoY29uc3QgcmVzb3VyY2Ugb2YgYWxsSW1wb3J0YWJsZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgIC0gJHtyZXNvdXJjZS5Mb2dpY2FsUmVzb3VyY2VJZH0gKCR7cmVzb3VyY2UuUmVzb3VyY2VUeXBlfSlgKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICAgIElkZW50aWZpZXI6ICR7SlNPTi5zdHJpbmdpZnkocmVzb3VyY2UuUmVzb3VyY2VJZGVudGlmaWVyKX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRlY2lzaW9ucy5yZW1vdmUubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zb2xlLmxvZygnXFxuUmVzb3VyY2VzIHRvIHJlbW92ZSBmcm9tIHN0YWNrOicpO1xuICAgICAgICBmb3IgKGNvbnN0IHIgb2YgZGVjaXNpb25zLnJlbW92ZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgIC0gJHtyLmxvZ2ljYWxSZXNvdXJjZUlkfSAoJHtyLnJlc291cmNlVHlwZX0pYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChwZXJtYW5lbnRDYXNjYWRlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1xcblJlc291cmNlcyBwZXJtYW5lbnRseSBjYXNjYWRlLXJlbW92ZWQgKGJyb2tlbiByZWZlcmVuY2VzKTonKTtcbiAgICAgICAgZm9yIChjb25zdCBjIG9mIHBlcm1hbmVudENhc2NhZGUpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICAtICR7Yy5sb2dpY2FsUmVzb3VyY2VJZH0gKCR7Yy5yZXNvdXJjZVR5cGV9KSAtPiBkZXBlbmRzIG9uICR7Yy5kZXBlbmRzT259YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0ZW1wb3JhcnlDYXNjYWRlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1xcblJlc291cmNlcyB0ZW1wb3JhcmlseSByZW1vdmVkIGFuZCByZWNyZWF0ZWQ6Jyk7XG4gICAgICAgIGZvciAoY29uc3QgYyBvZiB0ZW1wb3JhcnlDYXNjYWRlKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYCAgLSAke2MubG9naWNhbFJlc291cmNlSWR9ICgke2MucmVzb3VyY2VUeXBlfSkgLT4gZGVwZW5kcyBvbiAke2MuZGVwZW5kc09ufWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXN1bHQuc3VjY2VzcyA9IHRydWU7XG4gICAgICByZXN1bHQucmVtZWRpYXRlZFJlc291cmNlcyA9IGFsbEltcG9ydGFibGUubWFwKChyKSA9PiByLkxvZ2ljYWxSZXNvdXJjZUlkKTtcbiAgICAgIHJlc3VsdC5yZW1vdmVkUmVzb3VyY2VzID0gW1xuICAgICAgICAuLi5kZWNpc2lvbnMucmVtb3ZlLm1hcCgocikgPT4gci5sb2dpY2FsUmVzb3VyY2VJZCksXG4gICAgICAgIC4uLnBlcm1hbmVudENhc2NhZGUubWFwKChjKSA9PiBjLmxvZ2ljYWxSZXNvdXJjZUlkKSxcbiAgICAgIF07XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIERldGVybWluZSByZXF1aXJlZCBjYXBhYmlsaXRpZXNcbiAgICBjb25zdCByZXNvdXJjZVR5cGVzID0gYWxsSW1wb3J0YWJsZS5tYXAoKHIpID0+IHIuUmVzb3VyY2VUeXBlKTtcbiAgICBjb25zdCBhZGRpdGlvbmFsQ2FwcyA9IGdldEFsbFJlcXVpcmVkQ2FwYWJpbGl0aWVzKHJlc291cmNlVHlwZXMpO1xuICAgIGNvbnN0IGNhcGFiaWxpdGllcyA9IFsuLi5uZXcgU2V0KFsuLi5ERUZBVUxUX0NBUEFCSUxJVElFUywgLi4uYWRkaXRpb25hbENhcHNdKV07XG5cbiAgICAvLyBTYXZlIHJlY292ZXJ5IGNoZWNrcG9pbnQgYmVmb3JlIGFueSBzdGFjayBtdXRhdGlvbnNcbiAgICBjb25zdCB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkucmVwbGFjZSgvWzouXS9nLCAnLScpO1xuICAgIGNvbnN0IGJhY2t1cEZpbGVOYW1lID0gYC5jZm4tZHJpZnQtcmVtZWRpYXRlLWJhY2t1cC0ke3N0YWNrSW5mby5zdGFja05hbWV9LSR7dGltZXN0YW1wfS5qc29uYDtcbiAgICBjb25zdCBiYWNrdXBQYXRoID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGJhY2t1cEZpbGVOYW1lKTtcbiAgICBjb25zdCBjaGVja3BvaW50OiBSZWNvdmVyeUNoZWNrcG9pbnQgPSB7XG4gICAgICBzdGFja05hbWU6IHN0YWNrSW5mby5zdGFja05hbWUsXG4gICAgICBzdGFja0lkOiBzdGFja0luZm8uc3RhY2tJZCxcbiAgICAgIG9yaWdpbmFsVGVtcGxhdGVCb2R5LFxuICAgICAgcGFyYW1ldGVyczogc3RhY2tJbmZvLnBhcmFtZXRlcnMsXG4gICAgICBkcmlmdGVkUmVzb3VyY2VJZHM6IEFycmF5LmZyb20obG9naWNhbElkc1RvUmVtb3ZlKSxcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgIH07XG4gICAgZnMud3JpdGVGaWxlU3luYyhiYWNrdXBQYXRoLCBKU09OLnN0cmluZ2lmeShjaGVja3BvaW50LCBudWxsLCAyKSk7XG4gICAgbG9nKGBSZWNvdmVyeSBjaGVja3BvaW50IHNhdmVkIHRvOiAke2JhY2t1cFBhdGh9YCk7XG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgY29uc29sZS5sb2coYFJlY292ZXJ5IGNoZWNrcG9pbnQ6ICR7YmFja3VwUGF0aH1gKTtcbiAgICB9XG5cbiAgICAvLyBTdGVwIDY6IFNldCBEZWxldGlvblBvbGljeTogUmV0YWluIG9uIGFsbCByZXNvdXJjZXNcbiAgICAvLyBERUxFVEVEIHJlc291cmNlcyBtdXN0IGJlIHJlbW92ZWQgZnJvbSB0aGUgdGVtcGxhdGUgZmlyc3Qg4oCUIENsb3VkRm9ybWF0aW9uXG4gICAgLy8gY2Fubm90IHVwZGF0ZSBtZXRhZGF0YSBvbiByZXNvdXJjZXMgdGhhdCBubyBsb25nZXIgZXhpc3QgaW4gQVdTLlxuICAgIGxvZygnU2V0dGluZyBEZWxldGlvblBvbGljeTogUmV0YWluIG9uIGFsbCByZXNvdXJjZXMuLi4nKTtcbiAgICBjb25zdCBkZWxldGVkTG9naWNhbElkcyA9IG5ldyBTZXQoXG4gICAgICBhbGxEcmlmdGVkUmVzb3VyY2VzXG4gICAgICAgIC5maWx0ZXIoKHIpID0+IHIuc3RhY2tSZXNvdXJjZURyaWZ0U3RhdHVzID09PSAnREVMRVRFRCcgJiYgbG9naWNhbElkc1RvUmVtb3ZlLmhhcyhyLmxvZ2ljYWxSZXNvdXJjZUlkKSlcbiAgICAgICAgLm1hcCgocikgPT4gci5sb2dpY2FsUmVzb3VyY2VJZCksXG4gICAgKTtcblxuICAgIGxldCByZXRhaW5UZW1wbGF0ZSA9IHNldFJldGVudGlvbk9uQWxsUmVzb3VyY2VzKG9yaWdpbmFsVGVtcGxhdGUpO1xuXG4gICAgaWYgKGRlbGV0ZWRMb2dpY2FsSWRzLnNpemUgPiAwKSB7XG4gICAgICAvLyBSZW1vdmUgZGVsZXRlZCByZXNvdXJjZXMgYW5kIGNsZWFuIHVwIHRoZWlyIGRhbmdsaW5nIHJlZmVyZW5jZXNcbiAgICAgIGNvbnN0IHsgdGVtcGxhdGU6IGNsZWFuZWRUZW1wbGF0ZSB9ID0gdHJhbnNmb3JtVGVtcGxhdGVGb3JSZW1vdmFsKFxuICAgICAgICByZXRhaW5UZW1wbGF0ZSxcbiAgICAgICAgZGVsZXRlZExvZ2ljYWxJZHMsXG4gICAgICAgIG5ldyBNYXAoKSwgLy8gbm8gcmVzb2x2ZWQgdmFsdWVzIOKAlCBqdXN0IHN0cmlwIHVucmVzb2x2YWJsZSByZWZlcmVuY2VzXG4gICAgICApO1xuICAgICAgcmV0YWluVGVtcGxhdGUgPSBjbGVhbmVkVGVtcGxhdGU7XG4gICAgfVxuXG4gICAgYXdhaXQgY2xpZW50LnVwZGF0ZVN0YWNrKFxuICAgICAgc3RhY2tJbmZvLnN0YWNrSWQsXG4gICAgICBzdHJpbmdpZnlUZW1wbGF0ZShyZXRhaW5UZW1wbGF0ZSksXG4gICAgICByZXRhaW5UZW1wbGF0ZS5QYXJhbWV0ZXJzID8gc3RhY2tJbmZvLnBhcmFtZXRlcnMgOiB1bmRlZmluZWQsXG4gICAgICBjYXBhYmlsaXRpZXMsXG4gICAgKTtcblxuICAgIC8vIFN0ZXAgNzogUmVzb2x2ZSBjcm9zcy1yZWZlcmVuY2VzIHRvIE1PRElGSUVEIHJlc291cmNlcyBiZWluZyByZW1vdmVkXG4gICAgLy8gKERFTEVURUQgcmVzb3VyY2VzIGFyZSBhbHJlYWR5IHJlbW92ZWQgZnJvbSB0aGUgdGVtcGxhdGUsIHNvIG9ubHkgTU9ESUZJRUQgcmVmcyByZW1haW4pXG4gICAgY29uc3QgbW9kaWZpZWRJZHNUb1JlbW92ZSA9IG5ldyBTZXQoXG4gICAgICBbLi4ubG9naWNhbElkc1RvUmVtb3ZlXS5maWx0ZXIoKGlkKSA9PiAhZGVsZXRlZExvZ2ljYWxJZHMuaGFzKGlkKSksXG4gICAgKTtcbiAgICBjb25zdCByZWZlcmVuY2VzID0gY29sbGVjdFJlZmVyZW5jZXMocmV0YWluVGVtcGxhdGUsIG1vZGlmaWVkSWRzVG9SZW1vdmUpO1xuXG4gICAgbGV0IHJlc29sdmVkVmFsdWVzID0gbmV3IE1hcDxzdHJpbmcsIHVua25vd24+KCk7XG4gICAgaWYgKHJlZmVyZW5jZXMuc2l6ZSA+IDApIHtcbiAgICAgIGxvZygnUmVzb2x2aW5nIHJlZmVyZW5jZXMgdG8gZHJpZnRlZCByZXNvdXJjZXMuLi4nKTtcblxuICAgICAgY29uc3Qgb3V0cHV0VGVtcGxhdGUgPSBhZGRSZXNvbHV0aW9uT3V0cHV0cyhyZXRhaW5UZW1wbGF0ZSwgcmVmZXJlbmNlcyk7XG4gICAgICBhd2FpdCBjbGllbnQudXBkYXRlU3RhY2soXG4gICAgICAgIHN0YWNrSW5mby5zdGFja0lkLFxuICAgICAgICBzdHJpbmdpZnlUZW1wbGF0ZShvdXRwdXRUZW1wbGF0ZSksXG4gICAgICAgIG91dHB1dFRlbXBsYXRlLlBhcmFtZXRlcnMgPyBzdGFja0luZm8ucGFyYW1ldGVycyA6IHVuZGVmaW5lZCxcbiAgICAgICAgY2FwYWJpbGl0aWVzLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgdXBkYXRlZFN0YWNrSW5mbyA9IGF3YWl0IGNsaWVudC5nZXRTdGFja0luZm8oc3RhY2tJbmZvLnN0YWNrSWQpO1xuICAgICAgcmVzb2x2ZWRWYWx1ZXMgPSBwYXJzZVJlc29sdmVkT3V0cHV0cyh1cGRhdGVkU3RhY2tJbmZvLm91dHB1dHMgfHwgW10sIHJlZmVyZW5jZXMpO1xuICAgIH1cblxuICAgIC8vIFN0ZXAgODogUmVtb3ZlIHJlbWFpbmluZyAoTU9ESUZJRUQpIHJlc291cmNlcyBmcm9tIHRlbXBsYXRlXG4gICAgbG9nKCdSZW1vdmluZyByZXNvdXJjZXMgZnJvbSBzdGFjayAocmVzb3VyY2VzIHJldGFpbmVkIGluIEFXUykuLi4nKTtcbiAgICBjb25zdCB7IHRlbXBsYXRlOiByZW1vdmFsVGVtcGxhdGUgfSA9IHRyYW5zZm9ybVRlbXBsYXRlRm9yUmVtb3ZhbChcbiAgICAgIHJldGFpblRlbXBsYXRlLFxuICAgICAgbW9kaWZpZWRJZHNUb1JlbW92ZSxcbiAgICAgIHJlc29sdmVkVmFsdWVzLFxuICAgICk7XG5cbiAgICBjb25zdCByZW1vdmFsUGFyYW1zID0gcmVtb3ZhbFRlbXBsYXRlLlBhcmFtZXRlcnMgPyBzdGFja0luZm8ucGFyYW1ldGVycyA6IHVuZGVmaW5lZDtcbiAgICBhd2FpdCBjbGllbnQudXBkYXRlU3RhY2soXG4gICAgICBzdGFja0luZm8uc3RhY2tJZCxcbiAgICAgIHN0cmluZ2lmeVRlbXBsYXRlKHJlbW92YWxUZW1wbGF0ZSksXG4gICAgICByZW1vdmFsUGFyYW1zLFxuICAgICAgY2FwYWJpbGl0aWVzLFxuICAgICk7XG5cbiAgICAvLyBTdGVwIDk6IEltcG9ydCByZXNvdXJjZXMgKG9ubHkgaWYgdGhlcmUgYXJlIHJlc291cmNlcyB0byBpbXBvcnQpXG4gICAgaWYgKGFsbEltcG9ydGFibGUubGVuZ3RoID4gMCkge1xuICAgICAgbG9nKCdQcmVwYXJpbmcgaW1wb3J0IHRlbXBsYXRlIHdpdGggYWN0dWFsIHJlc291cmNlIHN0YXRlLi4uJyk7XG5cbiAgICAgIC8vIEJ1aWxkIGltcG9ydCB0ZW1wbGF0ZSBmcm9tIHRoZSByZW1vdmFsIHRlbXBsYXRlIChjdXJyZW50IHN0YWNrIHN0YXRlKVxuICAgICAgLy8gYW5kIGFkZCBiYWNrIHRoZSByZXNvdXJjZXMgYmVpbmcgaW1wb3J0ZWQgd2l0aCB0aGVpciBhY3R1YWwgcHJvcGVydGllc1xuICAgICAgY29uc3QgaW1wb3J0VGVtcGxhdGUgPSBkZWVwQ2xvbmUocmVtb3ZhbFRlbXBsYXRlKTtcblxuICAgICAgZm9yIChjb25zdCBpbXBvcnRhYmxlIG9mIGFsbEltcG9ydGFibGUpIHtcbiAgICAgICAgY29uc3QgbG9naWNhbElkID0gaW1wb3J0YWJsZS5Mb2dpY2FsUmVzb3VyY2VJZDtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxSZXNvdXJjZSA9IG9yaWdpbmFsVGVtcGxhdGUuUmVzb3VyY2VzPy5bbG9naWNhbElkXTtcbiAgICAgICAgaWYgKCFvcmlnaW5hbFJlc291cmNlKSBjb250aW51ZTtcblxuICAgICAgICAvLyBTdGFydCB3aXRoIG9yaWdpbmFsIHJlc291cmNlIGRlZmluaXRpb25cbiAgICAgICAgaW1wb3J0VGVtcGxhdGUuUmVzb3VyY2VzW2xvZ2ljYWxJZF0gPSBkZWVwQ2xvbmUob3JpZ2luYWxSZXNvdXJjZSk7XG5cbiAgICAgICAgLy8gRm9yIGF1dG9maXggcmVzb3VyY2VzLCBvdmVycmlkZSB3aXRoIGFjdHVhbCAoZHJpZnRlZCkgcHJvcGVydGllc1xuICAgICAgICBjb25zdCBhdXRvZml4UmVzb3VyY2UgPSBkZWNpc2lvbnMuYXV0b2ZpeC5maW5kKChyKSA9PiByLmxvZ2ljYWxSZXNvdXJjZUlkID09PSBsb2dpY2FsSWQpO1xuICAgICAgICBpZiAoYXV0b2ZpeFJlc291cmNlPy5hY3R1YWxQcm9wZXJ0aWVzICYmIE9iamVjdC5rZXlzKGF1dG9maXhSZXNvdXJjZS5hY3R1YWxQcm9wZXJ0aWVzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaW1wb3J0VGVtcGxhdGUuUmVzb3VyY2VzW2xvZ2ljYWxJZF0uUHJvcGVydGllcyA9IGF1dG9maXhSZXNvdXJjZS5hY3R1YWxQcm9wZXJ0aWVzO1xuICAgICAgICB9XG5cbiAgICAgICAgaW1wb3J0VGVtcGxhdGUuUmVzb3VyY2VzW2xvZ2ljYWxJZF0uRGVsZXRpb25Qb2xpY3kgPSAnUmV0YWluJztcbiAgICAgIH1cblxuICAgICAgLy8gRW5zdXJlIFJldGFpbiBvbiBhbGwgcmVzb3VyY2VzIGluIGltcG9ydCB0ZW1wbGF0ZVxuICAgICAgZm9yIChjb25zdCBsb2dpY2FsSWQgb2YgT2JqZWN0LmtleXMoaW1wb3J0VGVtcGxhdGUuUmVzb3VyY2VzKSkge1xuICAgICAgICBpbXBvcnRUZW1wbGF0ZS5SZXNvdXJjZXNbbG9naWNhbElkXS5EZWxldGlvblBvbGljeSA9ICdSZXRhaW4nO1xuICAgICAgfVxuXG4gICAgICBsb2coJ0NyZWF0aW5nIGltcG9ydCBjaGFuZ2Ugc2V0Li4uJyk7XG4gICAgICBjb25zdCBjaGFuZ2VTZXROYW1lID0gYXdhaXQgY2xpZW50LmNyZWF0ZUltcG9ydENoYW5nZVNldChcbiAgICAgICAgc3RhY2tJbmZvLnN0YWNrTmFtZSxcbiAgICAgICAgc3RyaW5naWZ5VGVtcGxhdGUoaW1wb3J0VGVtcGxhdGUpLFxuICAgICAgICBhbGxJbXBvcnRhYmxlLFxuICAgICAgICBjYXBhYmlsaXRpZXMsXG4gICAgICApO1xuXG4gICAgICBsb2coJ0V4ZWN1dGluZyBpbXBvcnQuLi4nKTtcbiAgICAgIGF3YWl0IGNsaWVudC5leGVjdXRlQ2hhbmdlU2V0KHN0YWNrSW5mby5zdGFja05hbWUsIGNoYW5nZVNldE5hbWUpO1xuICAgIH1cblxuICAgIC8vIFN0ZXAgMTA6IFJlc3RvcmUgdGVtcGxhdGVcbiAgICBpZiAoZGVjaXNpb25zLnJlbW92ZS5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBTb21lIHJlc291cmNlcyBwZXJtYW5lbnRseSByZW1vdmVkIOKAlCByZXN0b3JlIG9yaWdpbmFsIE1JTlVTIHJlbW92ZWQgcmVzb3VyY2VzXG4gICAgICBsb2coJ1Jlc3RvcmluZyB0ZW1wbGF0ZSAoZXhjbHVkaW5nIHJlbW92ZWQgcmVzb3VyY2VzKS4uLicpO1xuICAgICAgY29uc3QgcmVzdG9yZWRUZW1wbGF0ZSA9IGRlZXBDbG9uZShvcmlnaW5hbFRlbXBsYXRlKTtcbiAgICAgIGZvciAoY29uc3QgciBvZiBkZWNpc2lvbnMucmVtb3ZlKSB7XG4gICAgICAgIGRlbGV0ZSByZXN0b3JlZFRlbXBsYXRlLlJlc291cmNlc1tyLmxvZ2ljYWxSZXNvdXJjZUlkXTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFuIHVwIHJlZmVyZW5jZXMgYW5kIG91dHB1dHMgcG9pbnRpbmcgdG8gcmVtb3ZlZCByZXNvdXJjZXNcbiAgICAgIGNvbnN0IHsgdGVtcGxhdGU6IGNsZWFuZWRUZW1wbGF0ZSB9ID0gdHJhbnNmb3JtVGVtcGxhdGVGb3JSZW1vdmFsKFxuICAgICAgICByZXN0b3JlZFRlbXBsYXRlLFxuICAgICAgICBuZXcgU2V0KGRlY2lzaW9ucy5yZW1vdmUubWFwKChyKSA9PiByLmxvZ2ljYWxSZXNvdXJjZUlkKSksXG4gICAgICAgIHJlc29sdmVkVmFsdWVzLFxuICAgICAgKTtcbiAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgRGVsZXRpb25Qb2xpY3kgdmFsdWVzICh0cmFuc2Zvcm1UZW1wbGF0ZUZvclJlbW92YWwgc2V0cyBSZXRhaW4gb24gYWxsKVxuICAgICAgZm9yIChjb25zdCBbbG9naWNhbElkLCByZXNvdXJjZV0gb2YgT2JqZWN0LmVudHJpZXMoY2xlYW5lZFRlbXBsYXRlLlJlc291cmNlcyB8fCB7fSkpIHtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxSZXNvdXJjZSA9IG9yaWdpbmFsVGVtcGxhdGUuUmVzb3VyY2VzPy5bbG9naWNhbElkXTtcbiAgICAgICAgaWYgKG9yaWdpbmFsUmVzb3VyY2U/LkRlbGV0aW9uUG9saWN5KSB7XG4gICAgICAgICAgcmVzb3VyY2UuRGVsZXRpb25Qb2xpY3kgPSBvcmlnaW5hbFJlc291cmNlLkRlbGV0aW9uUG9saWN5O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSByZXNvdXJjZS5EZWxldGlvblBvbGljeTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYXdhaXQgY2xpZW50LnVwZGF0ZVN0YWNrKFxuICAgICAgICBzdGFja0luZm8uc3RhY2tOYW1lLFxuICAgICAgICBzdHJpbmdpZnlUZW1wbGF0ZShjbGVhbmVkVGVtcGxhdGUpLFxuICAgICAgICBjbGVhbmVkVGVtcGxhdGUuUGFyYW1ldGVycyA/IHN0YWNrSW5mby5wYXJhbWV0ZXJzIDogdW5kZWZpbmVkLFxuICAgICAgICBjYXBhYmlsaXRpZXMsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyByZW1vdmFscyDigJQgcmVzdG9yZSBleGFjdCBvcmlnaW5hbFxuICAgICAgbG9nKCdSZXN0b3Jpbmcgb3JpZ2luYWwgdGVtcGxhdGUuLi4nKTtcbiAgICAgIGF3YWl0IGNsaWVudC51cGRhdGVTdGFjayhcbiAgICAgICAgc3RhY2tJbmZvLnN0YWNrTmFtZSxcbiAgICAgICAgb3JpZ2luYWxUZW1wbGF0ZUJvZHksXG4gICAgICAgIHN0YWNrSW5mby5wYXJhbWV0ZXJzLFxuICAgICAgICBjYXBhYmlsaXRpZXMsXG4gICAgICApO1xuICAgIH1cblxuICAgIHJlc3VsdC5zdWNjZXNzID0gdHJ1ZTtcbiAgICByZXN1bHQucmVtZWRpYXRlZFJlc291cmNlcyA9IGFsbEltcG9ydGFibGUubWFwKChyKSA9PiByLkxvZ2ljYWxSZXNvdXJjZUlkKTtcbiAgICByZXN1bHQucmVtb3ZlZFJlc291cmNlcyA9IFtcbiAgICAgIC4uLmRlY2lzaW9ucy5yZW1vdmUubWFwKChyKSA9PiByLmxvZ2ljYWxSZXNvdXJjZUlkKSxcbiAgICAgIC4uLnBlcm1hbmVudENhc2NhZGUubWFwKChjKSA9PiBjLmxvZ2ljYWxSZXNvdXJjZUlkKSxcbiAgICBdO1xuXG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgY29uc29sZS5sb2coYFJlbWVkaWF0aW9uIGNvbXBsZXRlLiBSZWNvdmVyeSBjaGVja3BvaW50IGNhbiBiZSByZW1vdmVkOiAke2JhY2t1cFBhdGh9YCk7XG4gICAgfVxuXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmVzdWx0LmVycm9ycy5wdXNoKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuIl19
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export { remediate } from './cli';
|
|
3
|
+
export { CfnClientWrapper } from './lib/cfn-client';
|
|
4
|
+
export * from './lib/types';
|
|
5
|
+
export * from './lib/eligible-resources';
|
|
6
|
+
export * from './lib/template-transformer';
|
|
7
|
+
export * from './lib/resource-importer';
|
|
8
|
+
export * from './lib/resource-identifier';
|
|
9
|
+
export { promptForDecisions, formatDriftDiff, displayCascadeWarning } from './lib/interactive';
|
|
10
|
+
export { buildPlan, serializePlan, loadPlan, planToDecisions } from './lib/plan';
|