diff --git a/parser-sdk/nodejs/findings-schema.json b/parser-sdk/nodejs/findings-schema.json index 27860b6237..4c4b6ff5fc 100644 --- a/parser-sdk/nodejs/findings-schema.json +++ b/parser-sdk/nodejs/findings-schema.json @@ -78,6 +78,35 @@ "description": "Full URL with protocol, port, and path if existing.", "type": "string", "nullable": true + }, + "scan": { + "description": "Contains information about the scan that identified the finding. This will always be present", + "type": "object", + "properties": { + "created_at": { + "description": "Date-Time when the scan was created according to ISO8601", + "type": "string", + "format": "date-time" + }, + "name": { + "description": "Name of the scan.", + "type": "string" + }, + "namespace": { + "description": "Namespace in which the scan was run.", + "type": "string" + }, + "scan_type": { + "description": "Type of the scan.", + "type": "string" + } + }, + "required": [ + "created_at", + "name", + "namespace", + "scan_type" + ] } }, "required": [ @@ -85,7 +114,8 @@ "parsed_at", "severity", "category", - "name" + "name", + "scan" ] } } diff --git a/parser-sdk/nodejs/parser-utils.js b/parser-sdk/nodejs/parser-utils.js index 6fd601de41..655b436fe3 100644 --- a/parser-sdk/nodejs/parser-utils.js +++ b/parser-sdk/nodejs/parser-utils.js @@ -21,36 +21,61 @@ function addIdsAndDates(findings) { }); } -async function validateAgainstJsonSchema(jsonData) { +function addScanMetadata(findings, scan) { + const scanMetadata = { + created_at: scan.metadata.creationTimestamp, + name: scan.metadata.name, + namespace: scan.metadata.namespace, + scan_type: scan.spec.scanType, + }; + + return findings.map((finding) => ({ + ...finding, + scan: scanMetadata, + })); +} + +async function validateAgainstJsonSchema(findings) { const jsonSchemaString = await readFile( __dirname + "/findings-schema.json", "utf8" ); const jsonSchema = JSON.parse(jsonSchemaString); const validator = ajv.compile(jsonSchema); - const valid = validator(jsonData); + const valid = validator(findings); if (!valid) { - const errorMessage = generateErrorMessage(validator.errors, jsonData); + const errorMessage = generateErrorMessage(validator.errors, findings); throw new Error(errorMessage); } } -async function addSampleIdsAndDatesAndValidate(jsonData) { - // add sample IDs and Dates only if the jsonData Array is not empty - const extendedData = addIdsAndDates(jsonData); +async function addSampleIdsAndDatesAndValidate(findings) { + const sampleScan = { + metadata: { + creationTimestamp: new Date().toISOString(), + name: "sample-scan-name", + namespace: "sample-namespace", + }, + spec: { + scanType: "sample-scan-type", + }, + } + // add sample IDs and Dates only if the findings Array is not empty + const extendedData = addScanMetadata(addIdsAndDates(findings),sampleScan); return validateAgainstJsonSchema(extendedData); } -function generateErrorMessage(errors, jsonData) { +function generateErrorMessage(errors, findings) { errors = errors.map((error) => { return { ...error, - invalidValue: jsonpointer.get(jsonData, error.instancePath), + invalidValue: jsonpointer.get(findings, error.instancePath), }; }); return JSON.stringify(errors, null, 2); } module.exports.addIdsAndDates = addIdsAndDates; +module.exports.addScanMetadata = addScanMetadata; module.exports.validate = validateAgainstJsonSchema; module.exports.validateParser = addSampleIdsAndDatesAndValidate; diff --git a/parser-sdk/nodejs/parser-wrapper.js b/parser-sdk/nodejs/parser-wrapper.js index 50a789e305..7f645dc30b 100644 --- a/parser-sdk/nodejs/parser-wrapper.js +++ b/parser-sdk/nodejs/parser-wrapper.js @@ -4,7 +4,7 @@ const axios = require("axios"); const { parse } = require("./parser/parser"); -const { validate, addIdsAndDates } = require("./parser-utils"); +const { validate, addIdsAndDates, addScanMetadata } = require("./parser-utils"); const k8s = require("@kubernetes/client-node"); const kc = new k8s.KubeConfig(); @@ -129,9 +129,6 @@ async function extractParseDefinition(scan) { } } - - - async function main() { console.log("Starting Parser"); let scan = await extractScan(); @@ -162,11 +159,13 @@ async function main() { console.log("Adding UUIDs and Dates to the findings"); const findingsWithIdsAndDates = addIdsAndDates(findings); + console.log("Adding scan metadata to the findings"); + const findingsWithMetadata = addScanMetadata(findingsWithIdsAndDates, scan); const crash_on_failed_validation = process.env["CRASH_ON_FAILED_VALIDATION"] === "true" console.log("Validating Findings. Environment variable CRASH_ON_FAILED_VALIDATION is set to %s", crash_on_failed_validation); try { - await validate(findingsWithIdsAndDates); + await validate(findingsWithMetadata); console.log("The Findings were successfully validated") } catch (error) { console.error("The Findings Validation failed with error(s):"); @@ -182,7 +181,7 @@ async function main() { await uploadResultToFileStorageService( resultUploadUrl, - findingsWithIdsAndDates + findingsWithMetadata ); console.log(`Completed parser`); @@ -191,3 +190,4 @@ async function main() { main(); module.exports.addIdsAndDates = addIdsAndDates; +module.exports.addScanMetadata = addScanMetadata;