diff.js
1 "use strict"; 2 Object.defineProperty(exports, "__esModule", { value: true }); 3 exports.printSecurityDiff = exports.RequireApproval = exports.printStackDiff = void 0; 4 const cxschema = require("@aws-cdk/cloud-assembly-schema"); 5 const cfnDiff = require("@aws-cdk/cloudformation-diff"); 6 const colors = require("colors/safe"); 7 const logging_1 = require("./logging"); 8 /** 9 * Pretty-prints the differences between two template states to the console. 10 * 11 * @param oldTemplate the old/current state of the stack. 12 * @param newTemplate the new/target state of the stack. 13 * @param strict do not filter out AWS::CDK::Metadata 14 * @param context lines of context to use in arbitrary JSON diff 15 * 16 * @returns the count of differences that were rendered. 17 */ 18 function printStackDiff(oldTemplate, newTemplate, strict, context, stream) { 19 const diff = cfnDiff.diffTemplate(oldTemplate, newTemplate.template); 20 // filter out 'AWS::CDK::Metadata' resources from the template 21 if (diff.resources && !strict) { 22 diff.resources = diff.resources.filter(change => { 23 if (!change) { 24 return true; 25 } 26 if (change.newResourceType === 'AWS::CDK::Metadata') { 27 return false; 28 } 29 if (change.oldResourceType === 'AWS::CDK::Metadata') { 30 return false; 31 } 32 return true; 33 }); 34 } 35 if (!diff.isEmpty) { 36 cfnDiff.formatDifferences(stream || process.stderr, diff, buildLogicalToPathMap(newTemplate), context); 37 } 38 else { 39 logging_1.print(colors.green('There were no differences')); 40 } 41 return diff.differenceCount; 42 } 43 exports.printStackDiff = printStackDiff; 44 var RequireApproval; 45 (function (RequireApproval) { 46 RequireApproval["Never"] = "never"; 47 RequireApproval["AnyChange"] = "any-change"; 48 RequireApproval["Broadening"] = "broadening"; 49 })(RequireApproval = exports.RequireApproval || (exports.RequireApproval = {})); 50 /** 51 * Print the security changes of this diff, if the change is impactful enough according to the approval level 52 * 53 * Returns true if the changes are prompt-worthy, false otherwise. 54 */ 55 function printSecurityDiff(oldTemplate, newTemplate, requireApproval) { 56 const diff = cfnDiff.diffTemplate(oldTemplate, newTemplate.template); 57 if (difRequiresApproval(diff, requireApproval)) { 58 // eslint-disable-next-line max-len 59 logging_1.warning(`This deployment will make potentially sensitive changes according to your current security approval level (--require-approval ${requireApproval}).`); 60 logging_1.warning('Please confirm you intend to make the following modifications:\n'); 61 cfnDiff.formatSecurityChanges(process.stdout, diff, buildLogicalToPathMap(newTemplate)); 62 return true; 63 } 64 return false; 65 } 66 exports.printSecurityDiff = printSecurityDiff; 67 /** 68 * Return whether the diff has security-impacting changes that need confirmation 69 * 70 * TODO: Filter the security impact determination based off of an enum that allows 71 * us to pick minimum "severities" to alert on. 72 */ 73 function difRequiresApproval(diff, requireApproval) { 74 switch (requireApproval) { 75 case RequireApproval.Never: return false; 76 case RequireApproval.AnyChange: return diff.permissionsAnyChanges; 77 case RequireApproval.Broadening: return diff.permissionsBroadened; 78 default: throw new Error(`Unrecognized approval level: ${requireApproval}`); 79 } 80 } 81 function buildLogicalToPathMap(stack) { 82 const map = {}; 83 for (const md of stack.findMetadataByType(cxschema.ArtifactMetadataEntryType.LOGICAL_ID)) { 84 map[md.data] = md.path; 85 } 86 return map; 87 } 88 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImRpZmYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkRBQTJEO0FBQzNELHdEQUF3RDtBQUV4RCxzQ0FBc0M7QUFDdEMsdUNBQTJDO0FBRTNDOzs7Ozs7Ozs7R0FTRztBQUNILFNBQWdCLGNBQWMsQ0FDNUIsV0FBZ0IsRUFDaEIsV0FBOEMsRUFDOUMsTUFBZSxFQUNmLE9BQWUsRUFDZixNQUE2QjtJQUU3QixNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7SUFFckUsOERBQThEO0lBQzlELElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLE1BQU0sRUFBRTtRQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzlDLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQUUsT0FBTyxJQUFJLENBQUM7YUFBRTtZQUM3QixJQUFJLE1BQU0sQ0FBQyxlQUFlLEtBQUssb0JBQW9CLEVBQUU7Z0JBQUUsT0FBTyxLQUFLLENBQUM7YUFBRTtZQUN0RSxJQUFJLE1BQU0sQ0FBQyxlQUFlLEtBQUssb0JBQW9CLEVBQUU7Z0JBQUUsT0FBTyxLQUFLLENBQUM7YUFBRTtZQUN0RSxPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FBQyxDQUFDO0tBQ0o7SUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtRQUNqQixPQUFPLENBQUMsaUJBQWlCLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0tBQ3hHO1NBQU07UUFDTCxlQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUM7S0FDbEQ7SUFFRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUM7QUFDOUIsQ0FBQztBQTFCRCx3Q0EwQkM7QUFFRCxJQUFZLGVBTVg7QUFORCxXQUFZLGVBQWU7SUFDekIsa0NBQWUsQ0FBQTtJQUVmLDJDQUF3QixDQUFBO0lBRXhCLDRDQUF5QixDQUFBO0FBQzNCLENBQUMsRUFOVyxlQUFlLEdBQWYsdUJBQWUsS0FBZix1QkFBZSxRQU0xQjtBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixpQkFBaUIsQ0FBQyxXQUFnQixFQUFFLFdBQThDLEVBQUUsZUFBZ0M7SUFDbEksTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXJFLElBQUksbUJBQW1CLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxFQUFFO1FBQzlDLG1DQUFtQztRQUNuQyxpQkFBTyxDQUFDLGlJQUFpSSxlQUFlLElBQUksQ0FBQyxDQUFDO1FBQzlKLGlCQUFPLENBQUMsa0VBQWtFLENBQUMsQ0FBQztRQUU1RSxPQUFPLENBQUMscUJBQXFCLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUscUJBQXFCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUN4RixPQUFPLElBQUksQ0FBQztLQUNiO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBWkQsOENBWUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsbUJBQW1CLENBQUMsSUFBMEIsRUFBRSxlQUFnQztJQUN2RixRQUFRLGVBQWUsRUFBRTtRQUN2QixLQUFLLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLEtBQUssQ0FBQztRQUN6QyxLQUFLLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztRQUNsRSxLQUFLLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztRQUNsRSxPQUFPLENBQUMsQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO0tBQzdFO0FBQ0gsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUMsS0FBd0M7SUFDckUsTUFBTSxHQUFHLEdBQTZCLEVBQUUsQ0FBQztJQUN6QyxLQUFLLE1BQU0sRUFBRSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMseUJBQXlCLENBQUMsVUFBVSxDQUFDLEVBQUU7UUFDeEYsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFjLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO0tBQ2xDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3hzY2hlbWEgZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCAqIGFzIGNmbkRpZmYgZnJvbSAnQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24tZGlmZic7XG5pbXBvcnQgKiBhcyBjeGFwaSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0ICogYXMgY29sb3JzIGZyb20gJ2NvbG9ycy9zYWZlJztcbmltcG9ydCB7IHByaW50LCB3YXJuaW5nIH0gZnJvbSAnLi9sb2dnaW5nJztcblxuLyoqXG4gKiBQcmV0dHktcHJpbnRzIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHR3byB0ZW1wbGF0ZSBzdGF0ZXMgdG8gdGhlIGNvbnNvbGUuXG4gKlxuICogQHBhcmFtIG9sZFRlbXBsYXRlIHRoZSBvbGQvY3VycmVudCBzdGF0ZSBvZiB0aGUgc3RhY2suXG4gKiBAcGFyYW0gbmV3VGVtcGxhdGUgdGhlIG5ldy90YXJnZXQgc3RhdGUgb2YgdGhlIHN0YWNrLlxuICogQHBhcmFtIHN0cmljdCAgICAgIGRvIG5vdCBmaWx0ZXIgb3V0IEFXUzo6Q0RLOjpNZXRhZGF0YVxuICogQHBhcmFtIGNvbnRleHQgICAgIGxpbmVzIG9mIGNvbnRleHQgdG8gdXNlIGluIGFyYml0cmFyeSBKU09OIGRpZmZcbiAqXG4gKiBAcmV0dXJucyB0aGUgY291bnQgb2YgZGlmZmVyZW5jZXMgdGhhdCB3ZXJlIHJlbmRlcmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJpbnRTdGFja0RpZmYoXG4gIG9sZFRlbXBsYXRlOiBhbnksXG4gIG5ld1RlbXBsYXRlOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QsXG4gIHN0cmljdDogYm9vbGVhbixcbiAgY29udGV4dDogbnVtYmVyLFxuICBzdHJlYW0/OiBjZm5EaWZmLkZvcm1hdFN0cmVhbSk6IG51bWJlciB7XG5cbiAgY29uc3QgZGlmZiA9IGNmbkRpZmYuZGlmZlRlbXBsYXRlKG9sZFRlbXBsYXRlLCBuZXdUZW1wbGF0ZS50ZW1wbGF0ZSk7XG5cbiAgLy8gZmlsdGVyIG91dCAnQVdTOjpDREs6Ok1ldGFkYXRhJyByZXNvdXJjZXMgZnJvbSB0aGUgdGVtcGxhdGVcbiAgaWYgKGRpZmYucmVzb3VyY2VzICYmICFzdHJpY3QpIHtcbiAgICBkaWZmLnJlc291cmNlcyA9IGRpZmYucmVzb3VyY2VzLmZpbHRlcihjaGFuZ2UgPT4ge1xuICAgICAgaWYgKCFjaGFuZ2UpIHsgcmV0dXJuIHRydWU7IH1cbiAgICAgIGlmIChjaGFuZ2UubmV3UmVzb3VyY2VUeXBlID09PSAnQVdTOjpDREs6Ok1ldGFkYXRhJykgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgIGlmIChjaGFuZ2Uub2xkUmVzb3VyY2VUeXBlID09PSAnQVdTOjpDREs6Ok1ldGFkYXRhJykgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKCFkaWZmLmlzRW1wdHkpIHtcbiAgICBjZm5EaWZmLmZvcm1hdERpZmZlcmVuY2VzKHN0cmVhbSB8fCBwcm9jZXNzLnN0ZGVyciwgZGlmZiwgYnVpbGRMb2dpY2FsVG9QYXRoTWFwKG5ld1RlbXBsYXRlKSwgY29udGV4dCk7XG4gIH0gZWxzZSB7XG4gICAgcHJpbnQoY29sb3JzLmdyZWVuKCdUaGVyZSB3ZXJlIG5vIGRpZmZlcmVuY2VzJykpO1xuICB9XG5cbiAgcmV0dXJuIGRpZmYuZGlmZmVyZW5jZUNvdW50O1xufVxuXG5leHBvcnQgZW51bSBSZXF1aXJlQXBwcm92YWwge1xuICBOZXZlciA9ICduZXZlcicsXG5cbiAgQW55Q2hhbmdlID0gJ2FueS1jaGFuZ2UnLFxuXG4gIEJyb2FkZW5pbmcgPSAnYnJvYWRlbmluZydcbn1cblxuLyoqXG4gKiBQcmludCB0aGUgc2VjdXJpdHkgY2hhbmdlcyBvZiB0aGlzIGRpZmYsIGlmIHRoZSBjaGFuZ2UgaXMgaW1wYWN0ZnVsIGVub3VnaCBhY2NvcmRpbmcgdG8gdGhlIGFwcHJvdmFsIGxldmVsXG4gKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBjaGFuZ2VzIGFyZSBwcm9tcHQtd29ydGh5LCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmludFNlY3VyaXR5RGlmZihvbGRUZW1wbGF0ZTogYW55LCBuZXdUZW1wbGF0ZTogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LCByZXF1aXJlQXBwcm92YWw6IFJlcXVpcmVBcHByb3ZhbCk6IGJvb2xlYW4ge1xuICBjb25zdCBkaWZmID0gY2ZuRGlmZi5kaWZmVGVtcGxhdGUob2xkVGVtcGxhdGUsIG5ld1RlbXBsYXRlLnRlbXBsYXRlKTtcblxuICBpZiAoZGlmUmVxdWlyZXNBcHByb3ZhbChkaWZmLCByZXF1aXJlQXBwcm92YWwpKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICB3YXJuaW5nKGBUaGlzIGRlcGxveW1lbnQgd2lsbCBtYWtlIHBvdGVudGlhbGx5IHNlbnNpdGl2ZSBjaGFuZ2VzIGFjY29yZGluZyB0byB5b3VyIGN1cnJlbnQgc2VjdXJpdHkgYXBwcm92YWwgbGV2ZWwgKC0tcmVxdWlyZS1hcHByb3ZhbCAke3JlcXVpcmVBcHByb3ZhbH0pLmApO1xuICAgIHdhcm5pbmcoJ1BsZWFzZSBjb25maXJtIHlvdSBpbnRlbmQgdG8gbWFrZSB0aGUgZm9sbG93aW5nIG1vZGlmaWNhdGlvbnM6XFxuJyk7XG5cbiAgICBjZm5EaWZmLmZvcm1hdFNlY3VyaXR5Q2hhbmdlcyhwcm9jZXNzLnN0ZG91dCwgZGlmZiwgYnVpbGRMb2dpY2FsVG9QYXRoTWFwKG5ld1RlbXBsYXRlKSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIFJldHVybiB3aGV0aGVyIHRoZSBkaWZmIGhhcyBzZWN1cml0eS1pbXBhY3RpbmcgY2hhbmdlcyB0aGF0IG5lZWQgY29uZmlybWF0aW9uXG4gKlxuICogVE9ETzogRmlsdGVyIHRoZSBzZWN1cml0eSBpbXBhY3QgZGV0ZXJtaW5hdGlvbiBiYXNlZCBvZmYgb2YgYW4gZW51bSB0aGF0IGFsbG93c1xuICogdXMgdG8gcGljayBtaW5pbXVtIFwic2V2ZXJpdGllc1wiIHRvIGFsZXJ0IG9uLlxuICovXG5mdW5jdGlvbiBkaWZSZXF1aXJlc0FwcHJvdmFsKGRpZmY6IGNmbkRpZmYuVGVtcGxhdGVEaWZmLCByZXF1aXJlQXBwcm92YWw6IFJlcXVpcmVBcHByb3ZhbCkge1xuICBzd2l0Y2ggKHJlcXVpcmVBcHByb3ZhbCkge1xuICAgIGNhc2UgUmVxdWlyZUFwcHJvdmFsLk5ldmVyOiByZXR1cm4gZmFsc2U7XG4gICAgY2FzZSBSZXF1aXJlQXBwcm92YWwuQW55Q2hhbmdlOiByZXR1cm4gZGlmZi5wZXJtaXNzaW9uc0FueUNoYW5nZXM7XG4gICAgY2FzZSBSZXF1aXJlQXBwcm92YWwuQnJvYWRlbmluZzogcmV0dXJuIGRpZmYucGVybWlzc2lvbnNCcm9hZGVuZWQ7XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgYXBwcm92YWwgbGV2ZWw6ICR7cmVxdWlyZUFwcHJvdmFsfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJ1aWxkTG9naWNhbFRvUGF0aE1hcChzdGFjazogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0KSB7XG4gIGNvbnN0IG1hcDogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gIGZvciAoY29uc3QgbWQgb2Ygc3RhY2suZmluZE1ldGFkYXRhQnlUeXBlKGN4c2NoZW1hLkFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuTE9HSUNBTF9JRCkpIHtcbiAgICBtYXBbbWQuZGF0YSBhcyBzdHJpbmddID0gbWQucGF0aDtcbiAgfVxuICByZXR1cm4gbWFwO1xufSJdfQ==