Skip to content

Commit

Permalink
fix(Nag Reports): compliance reports not generated for stacks with no…
Browse files Browse the repository at this point in the history
… relevant resources (#723)
  • Loading branch information
dontirun authored Mar 17, 2022
1 parent 94ab0c6 commit d3c556c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
32 changes: 23 additions & 9 deletions src/nag-pack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,13 @@ export abstract class NagPack implements IAspect {
const ruleId = `${this.packName}-${ruleSuffix}`;
try {
const ruleCompliance = params.rule(params.node);
if (
this.reports === true &&
ruleCompliance === NagRuleCompliance.COMPLIANT
) {
this.writeToStackComplianceReport(params, ruleId, ruleCompliance);
} else if (this.isNonCompliant(ruleCompliance)) {
if (this.reports === true) {
this.initializeStackReport(params);
if (ruleCompliance === NagRuleCompliance.COMPLIANT) {
this.writeToStackComplianceReport(params, ruleId, ruleCompliance);
}
}
if (this.isNonCompliant(ruleCompliance)) {
const findings = this.asFindings(ruleCompliance);
for (const findingId of findings) {
const suppressionReason = this.ignoreRule(
Expand Down Expand Up @@ -249,7 +250,7 @@ export abstract class NagPack implements IAspect {
}

/**
* Write a line to the rule packs compliance report for the resource's Stack
* Write a line to the rule pack's compliance report for the resource's Stack
* @param params The @IApplyRule interface with rule details.
* @param ruleId The id of the rule.
* @param compliance The compliance status of the rule.
Expand All @@ -270,20 +271,33 @@ export abstract class NagPack implements IAspect {
compliance,
explanation
);
let outDir = App.of(params.node)?.outdir;
const outDir = App.of(params.node)?.outdir;
const stackName = params.node.stack.nested
? Names.uniqueId(params.node.stack)
: params.node.stack.stackName;
const fileName = `${this.packName}-${stackName}-NagReport.csv`;
const filePath = join(outDir ? outDir : '', fileName);
appendFileSync(filePath, line);
}

/**
* Initialize the report for the rule pack's compliance report for the resource's Stack if it doesn't exist
* @param params
*/
protected initializeStackReport(params: IApplyRule): void {
const stackName = params.node.stack.nested
? Names.uniqueId(params.node.stack)
: params.node.stack.stackName;
const fileName = `${this.packName}-${stackName}-NagReport.csv`;
if (!this.reportStacks.includes(fileName)) {
const outDir = App.of(params.node)?.outdir;
const filePath = join(outDir ? outDir : '', fileName);
this.reportStacks.push(fileName);
writeFileSync(
filePath,
'Rule ID,Resource ID,Compliance,Exception Reason,Rule Level,Rule Info\n'
);
}
appendFileSync(filePath, line);
}

/**
Expand Down
16 changes: 15 additions & 1 deletion test/Engine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,9 @@ describe('Report system', () => {
explanation: 'bar.',
level: NagMessageLevel.ERROR,
rule: function (node2: CfnResource): NagRuleCompliance {
if (node2.cfnResourceType !== 'Error') {
if (node2.cfnResourceType === 'N/A') {
return NagRuleCompliance.NOT_APPLICABLE;
} else if (node2.cfnResourceType !== 'Error') {
return compliance;
}
throw Error('foobar');
Expand Down Expand Up @@ -958,6 +960,18 @@ describe('Report system', () => {
app.synth();
expect(pack.readReportStacks.length).toEqual(2);
});
test('Reports are initialized for stacks with no relevant resources', () => {
const app = new App();
const stack = new Stack(app, 'Stack1');
const pack = new TestPack();
Aspects.of(app).add(pack);
new CfnResource(stack, 'rNAResource', {
type: 'N/A',
});
app.synth();
expect(pack.readReportStacks.length).toEqual(1);
expect(pack.lines.length).toBe(0);
});
test('Nested Stack reports do not contain tokens in names', () => {
const app = new App();
const parent = new Stack(app, 'Parent');
Expand Down

0 comments on commit d3c556c

Please sign in to comment.