Skip to content

Commit

Permalink
Merge pull request #4164 from snyk/feat/add-error-code-to-iac-json-ou…
Browse files Browse the repository at this point in the history
…tput

feat: add error code to iac json output
  • Loading branch information
YairZ101 authored Oct 20, 2022
2 parents 2777f09 + 4d08086 commit b007370
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 27 deletions.
13 changes: 8 additions & 5 deletions src/lib/iac/test/v2/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
// fields must be produced in the JSON output, and they must have those values
// to keep backwards compatibility.

import { Resource, ScanError, TestOutput, Vulnerability } from './scan/results';
import { Resource, TestOutput, Vulnerability } from './scan/results';
import * as path from 'path';
import { createErrorMappedResultsForJsonOutput } from '../../../formatters/test/format-test-results';
import { IacProjectType, iacRemediationTypes } from '../../constants';
import { State } from './scan/policy-engine';
import {
IacTestError,
mapIacTestError,
} from '../../../snyk-test/iac-test-result';

export interface Result {
meta: Meta;
Expand Down Expand Up @@ -92,18 +95,18 @@ export function convertEngineToJsonResults({
}: {
results: TestOutput;
projectName: string;
}): Array<Result | ScanError> {
}): Array<Result | IacTestError> {
const vulnerabilityGroups = groupVulnerabilitiesByFile(results); // all vulns groups by file
const resourceGroups = groupResourcesByFile(results); // all resources grouped by file
const filesWithoutIssues = findFilesWithoutIssues(
resourceGroups,
vulnerabilityGroups,
); // all resources without issues grouped by file

const output: Array<Result | ScanError> = [];
const output: Array<Result | IacTestError> = [];

if (results.errors) {
output.push(...createErrorMappedResultsForJsonOutput(results.errors));
output.push(...results.errors.map((e) => mapIacTestError(e)));
}

for (const [file, resources] of Object.entries(filesWithoutIssues)) {
Expand Down
19 changes: 13 additions & 6 deletions src/lib/snyk-test/iac-test-result.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pick = require('lodash.pick');
import { CustomError } from '../errors';
import { BasicResultData, SEVERITY, TestDepGraphMeta } from './legacy';

export interface AnnotatedIacIssue {
Expand Down Expand Up @@ -40,6 +41,7 @@ type FILTERED_OUT_FIELDS = 'cloudConfigPath' | 'name' | 'from';

export interface IacTestResponse extends BasicResultData {
path: string;
code?: number;
targetFile: string;
projectName: string;
displayTargetFile: string; // used for display only
Expand All @@ -56,12 +58,8 @@ const IAC_ISSUES_KEY = 'infrastructureAsCodeIssues';
export function mapIacTestResult(
iacTest: IacTestResponse,
): MappedIacTestResponse | IacTestError {
if (iacTest instanceof Error) {
return {
ok: false,
error: iacTest.message,
path: (iacTest as any).path,
};
if (iacTest instanceof CustomError) {
return mapIacTestError(iacTest);
}

const infrastructureAsCodeIssues =
Expand All @@ -78,6 +76,15 @@ export function mapIacTestResult(
};
}

export function mapIacTestError(error: CustomError) {
return {
ok: false,
code: error.code,
error: error.message,
path: (error as any).path,
};
}

/**
* The following types represent manipulations to the data structure returned from Registry's `test-iac`.
* These manipulations are being done prior to outputing as JSON, for renaming fields only.
Expand Down
3 changes: 2 additions & 1 deletion test/fixtures/iac/output-formats/test-error-json-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"code": {"type": "integer"},
"error": { "type": "string" },
"path": { "type": "string" }
},
"required": ["ok", "error", "path"],
"required": ["ok", "code", "error", "path"],
"additionalProperties": false
}
30 changes: 15 additions & 15 deletions test/jest/unit/cli/commands/test/iac/v2/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ describe('test', () => {
formattedUserMessage:
"Test Failures\n\n The Snyk CLI couldn't find any valid IaC configuration files to scan\n Path: invalid_file.txt",
json:
'[\n {\n "ok": false,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
jsonStringifiedResults:
'[\n {\n "ok": false,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
sarifStringifiedResults: `{\n "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",\n "version": "2.1.0",\n "runs": [\n {\n "originalUriBaseIds": {\n "PROJECTROOT": {\n "uri": "${
pathToFileURL(path.join(process.cwd(), '/')).href
}",\n "description": {\n "text": "The root directory for all project files."\n }\n }\n },\n "tool": {\n "driver": {\n "name": "Snyk IaC",\n "fullName": "Snyk Infrastructure as Code",\n "version": "1.0.0-monorepo",\n "informationUri": "https://docs.snyk.io/products/snyk-infrastructure-as-code",\n "rules": []\n }\n },\n "automationDetails": {\n "id": "snyk-iac"\n },\n "results": []\n }\n ]\n}`,
Expand Down Expand Up @@ -189,9 +189,9 @@ describe('test', () => {
`"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"`,
),
jsonStringifiedResults:
'[\n {\n "ok": false,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
json:
'[\n {\n "ok": false,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
}),
);
});
Expand Down Expand Up @@ -250,13 +250,13 @@ describe('test', () => {
strCode: 'NO_FILES_TO_SCAN_ERROR',
innerError: undefined,
userMessage:
'[\n {\n "ok": false,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
formattedUserMessage:
'[\n {\n "ok": false,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
json:
'[\n {\n "ok": false,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
jsonStringifiedResults:
'[\n {\n "ok": false,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
sarifStringifiedResults: `{\n "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",\n "version": "2.1.0",\n "runs": [\n {\n "originalUriBaseIds": {\n "PROJECTROOT": {\n "uri": "${
pathToFileURL(path.join(process.cwd(), '/')).href
}",\n "description": {\n "text": "The root directory for all project files."\n }\n }\n },\n "tool": {\n "driver": {\n "name": "Snyk IaC",\n "fullName": "Snyk Infrastructure as Code",\n "version": "1.0.0-monorepo",\n "informationUri": "https://docs.snyk.io/products/snyk-infrastructure-as-code",\n "rules": []\n }\n },\n "automationDetails": {\n "id": "snyk-iac"\n },\n "results": []\n }\n ]\n}`,
Expand Down Expand Up @@ -292,24 +292,24 @@ describe('test', () => {
expect.objectContaining({
name: 'NoLoadableInputError',
message:
'[\n {\n "ok": false,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
code: 1010,
strCode: 'NO_FILES_TO_SCAN_ERROR',
fields: {
path: 'path/to/test',
},
path: 'path/to/test',
userMessage:
'[\n {\n "ok": false,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
formattedUserMessage:
'[\n {\n "ok": false,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
sarifStringifiedResults: expect.stringContaining(
`"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"`,
),
jsonStringifiedResults:
'[\n {\n "ok": false,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
json:
'[\n {\n "ok": false,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
}),
);
});
Expand Down Expand Up @@ -371,7 +371,7 @@ describe('test', () => {
pathToFileURL(path.join(process.cwd(), '/')).href
}",\n "description": {\n "text": "The root directory for all project files."\n }\n }\n },\n "tool": {\n "driver": {\n "name": "Snyk IaC",\n "fullName": "Snyk Infrastructure as Code",\n "version": "1.0.0-monorepo",\n "informationUri": "https://docs.snyk.io/products/snyk-infrastructure-as-code",\n "rules": []\n }\n },\n "automationDetails": {\n "id": "snyk-iac"\n },\n "results": []\n }\n ]\n}`,
jsonStringifiedResults:
'[\n {\n "ok": false,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "",\n "path": "invalid_file.txt"\n }\n]',
sarifStringifiedResults: `{\n "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",\n "version": "2.1.0",\n "runs": [\n {\n "originalUriBaseIds": {\n "PROJECTROOT": {\n "uri": "${
pathToFileURL(path.join(process.cwd(), '/')).href
}",\n "description": {\n "text": "The root directory for all project files."\n }\n }\n },\n "tool": {\n "driver": {\n "name": "Snyk IaC",\n "fullName": "Snyk Infrastructure as Code",\n "version": "1.0.0-monorepo",\n "informationUri": "https://docs.snyk.io/products/snyk-infrastructure-as-code",\n "rules": []\n }\n },\n "automationDetails": {\n "id": "snyk-iac"\n },\n "results": []\n }\n ]\n}`,
Expand Down Expand Up @@ -425,7 +425,7 @@ describe('test', () => {
`"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"`,
),
jsonStringifiedResults:
'[\n {\n "ok": false,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
'[\n {\n "ok": false,\n "code": 2114,\n "error": "no loadable input: path/to/test",\n "path": "path/to/test"\n }\n]',
json: expect.stringContaining(
`"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"`,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[
{
"ok": false,
"code": 2114,
"error": "",
"path": "invalid_file.txt"
},
Expand Down

0 comments on commit b007370

Please sign in to comment.