Last active
February 26, 2024 12:48
-
-
Save greenido/e2eceff5ea69fa94a84c74ed308bd74a to your computer and use it in GitHub Desktop.
Fetch JFrog Xray violations into CSV so you can use them in an external monitoring/logging tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Fetch Xray Data into CSV and later any DB/Logging/Monitoring tool you wish. | |
// | |
// @author: Ido Green | @greenido | |
// @date: March 2020 | |
// | |
// @see: | |
// https://greenido.wordpress.com/2019/12/04/how-to-build-an-integration-with-jfrog-xray/ | |
// https://greenido.wordpress.com/2020/02/12/continuous-software-updates/ | |
// | |
// https://csvkit.readthedocs.io/en/latest/ | |
// | |
// init project | |
const fs = require("fs"); | |
var request = require("request"); | |
require('dotenv').config() | |
// TODO: change these values in your .env file to meet your credentials | |
const BASE_URL = process.env.BASE_URL; | |
const USERNAME = process.env.XRAY_USER; | |
const PASSWORD = process.env.XRAY_PASS; | |
// | |
// Fetch violations from Xray | |
// TODO: change the 'watch_name' to a watch that is defined at your Xray | |
// | |
function fetchViolations() { | |
// Create the base64 auth string | |
let auth = 'Basic ' + Buffer.from(USERNAME + ':' + PASSWORD).toString('base64'); | |
// Using the REST API on: /api/v1/violations | |
// With an example payload for specific watch_name. | |
var options = { | |
method: "POST", | |
url: "http://" + BASE_URL + "/api/v1/violations", | |
headers: { | |
"Content-Type": "application/json", | |
Authorization: auth | |
}, | |
body: JSON.stringify({ | |
"filters": { "watch_name": "step3-create-docker-image-product" }, | |
"pagination": { "order_by": "updated", "limit": 25, "offset": 1 } | |
}) | |
}; | |
request(options, function(error, response) { | |
if (error) { | |
console.log("😳 ERROR with fetching violations: "); | |
console.log(error); | |
return; | |
} | |
console.log("Status code: "+ response.statusCode); | |
if (response.statusCode == 200) { | |
let resJson = JSON.parse(response.body); | |
console.log("🏵 Total Violations: " + resJson.total_violations); | |
console.log("Violations: " + response.body); | |
// Now let's convert the JSON to CSV and save it | |
exportJson2Csv(resJson); | |
} | |
}); | |
} | |
// | |
// Export the JSON to CSV | |
// | |
function exportJson2Csv(jsonInput) { | |
var json = jsonInput.violations; | |
var fields = [ | |
"description", | |
"severity", | |
"type", | |
"infected_component", | |
"created", | |
"watch_name", | |
"issue_id", | |
"violation_details_url", | |
"impacted_artifacts" | |
]; | |
var replacer = function(key, value) { | |
if (value === null || value === undefined) { | |
// handle null cases in Xray response | |
return ""; | |
} else { | |
if ( (key.indexOf("infected_component") > -1 || | |
key.indexOf("impacted_artifacts" > -1)) && | |
Array.isArray(value)) { | |
// We have an array to save in one cell | |
value = value.join(" -- "); | |
return value; | |
} | |
else if (key.indexOf("violation_details_url") > -1 ) { | |
// let's save it in a seperate file so we can run on it later to add more details. | |
saveDetailedUrl(value); | |
return value; | |
} | |
} | |
// This will make sure we aren't breaking our CSV | |
value = value.replace(/,/g, ';'); | |
value = value.replace(/\"/g, "'"); | |
return value; | |
}; | |
// Building the CSV output | |
var csv = json.map(function(row) { | |
return fields | |
.map(function(fieldName) { | |
let cellValue = replacer(fieldName, row[fieldName]); | |
let desc = row[fieldName]; | |
return JSON.stringify(cellValue); | |
}) | |
.join(","); | |
}); | |
// Add header column | |
csv.unshift(fields.join(",")); | |
csv = csv.join("\r\n"); | |
// | |
// save it to a CSV file | |
// | |
let curTime = new Date().getTime(); | |
fs.writeFile("./xray-violations-" + curTime + ".csv", csv, err => { | |
if (err) { | |
console.log("😳 Error writing CSV file", err); | |
} else { | |
console.log("🥎 Successfully wrote the CSV file"); | |
} | |
}); | |
} | |
// | |
// Saving the details url on a file we can use in the next script (with another process). | |
// | |
function saveDetailedUrl(detailUrl) { | |
fs.appendFile("./xray-violations-details-urls-" + curTime + ".txt", detailUrl + "\n", err => { | |
if (err) { | |
console.log("😳 Error writing detailUrl: ", err); | |
} | |
// else { console.log("🥎 Successfully wrote detailUrl:" + detailUrl); } | |
}); | |
} | |
// | |
// Let's start the work | |
// | |
fetchViolations(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment