add working dir as input to step
This commit is contained in:
@@ -1,68 +1,102 @@
|
||||
import * as fs from 'node:fs';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
export async function uploadReports() {
|
||||
const baseUrl = (process.env.DEFECTDOJO_URL || "").replace(/\/$/, "");
|
||||
function resolveScanType(fileName: string): string | undefined {
|
||||
if (fileName.endsWith('.sarif')) {
|
||||
return 'SARIF';
|
||||
}
|
||||
|
||||
if (fileName === 'generic-findings.json') {
|
||||
return 'Generic Findings Import';
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function uploadReports(): Promise<void> {
|
||||
const baseUrl = (process.env.DEFECTDOJO_URL || '').replace(/\/$/, '');
|
||||
const apiToken = process.env.DEFECTDOJO_API_TOKEN;
|
||||
const productName = process.env.DEFECTDOJO_PRODUCT_NAME || "agentguard-ci";
|
||||
|
||||
const productTypeName = process.env.DEFECTDOJO_PRODUCT_TYPE_NAME || 'Homelab Security';
|
||||
const productName = process.env.DEFECTDOJO_PRODUCT_NAME || 'agentguard-ci';
|
||||
const engagementName = process.env.DEFECTDOJO_ENGAGEMENT_NAME || 'Default Pipeline';
|
||||
const minimumSeverity = process.env.DEFECTDOJO_MINIMUM_SEVERITY || 'Info';
|
||||
const active = process.env.DEFECTDOJO_ACTIVE || 'true';
|
||||
const verified = process.env.DEFECTDOJO_VERIFIED || 'true';
|
||||
const closeOldFindings = process.env.DEFECTDOJO_CLOSE_OLD_FINDINGS || 'false';
|
||||
const autoCreateContext = process.env.DEFECTDOJO_AUTO_CREATE_CONTEXT || 'true';
|
||||
|
||||
if (!baseUrl || !apiToken) {
|
||||
console.error("DEFECTDOJO_URL and DEFECTDOJO_API_TOKEN must be set.");
|
||||
console.error('DEFECTDOJO_URL and DEFECTDOJO_API_TOKEN must be set.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const scanMap: Record<string, string> = {
|
||||
".sarif": "SARIF",
|
||||
".json": "Generic Findings Import",
|
||||
};
|
||||
const reportsDir = '/workspace/reports';
|
||||
let fileNames: string[];
|
||||
|
||||
const reportsDir = "/workspace/reports";
|
||||
if (!fs.existsSync(reportsDir)) {
|
||||
console.log("No reports directory found.");
|
||||
try {
|
||||
fileNames = (await fs.readdir(reportsDir)).sort();
|
||||
} catch {
|
||||
console.log('No reports directory found.');
|
||||
return;
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(reportsDir).sort();
|
||||
|
||||
for (const file of files) {
|
||||
const fullPath = path.join(reportsDir, file);
|
||||
if (!fs.statSync(fullPath).isFile()) continue;
|
||||
|
||||
const ext = path.extname(file);
|
||||
const scanType = scanMap[ext];
|
||||
if (!scanType) continue;
|
||||
for (const fileName of fileNames) {
|
||||
const fullPath = path.join(reportsDir, fileName);
|
||||
const stats = await fs.stat(fullPath);
|
||||
if (!stats.isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const scanType = resolveScanType(fileName);
|
||||
if (!scanType) {
|
||||
console.log(`Skipping ${fileName}: no DefectDojo importer is configured for this file yet.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const reportContents = await fs.readFile(fullPath);
|
||||
const form = new FormData();
|
||||
form.append('scan_type', scanType);
|
||||
form.append('product_type_name', productTypeName);
|
||||
form.append('product_name', productName);
|
||||
form.append('engagement_name', engagementName);
|
||||
form.append('test_title', fileName);
|
||||
form.append('minimum_severity', minimumSeverity);
|
||||
form.append('active', active);
|
||||
form.append('verified', verified);
|
||||
form.append('close_old_findings', closeOldFindings);
|
||||
form.append('auto_create_context', autoCreateContext);
|
||||
form.append('file', new Blob([reportContents]), fileName);
|
||||
|
||||
console.log(`Uploading ${fileName} to DefectDojo as ${scanType}...`);
|
||||
|
||||
console.log(`Uploading ${file} as ${scanType}...`);
|
||||
|
||||
try {
|
||||
const response = await fetch(`${baseUrl}/api/v2/import-scan/`, {
|
||||
method: "POST",
|
||||
const response = await fetch(`${baseUrl}/api/v2/reimport-scan/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Authorization": `Token ${apiToken}`,
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Token ${apiToken}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
scan_type: scanType,
|
||||
product_name: productName,
|
||||
file_name: file,
|
||||
})
|
||||
body: form,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
console.error(`Failed to upload ${file}: ${response.status} ${response.statusText} - ${text}`);
|
||||
console.error(`Failed to upload ${fileName}: ${response.status} ${response.statusText} - ${text}`);
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log(`Successfully uploaded ${file}`);
|
||||
continue;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Network error uploading ${file}:`, e);
|
||||
|
||||
console.log(`Successfully uploaded ${fileName}`);
|
||||
} catch (error) {
|
||||
console.error(`Network error uploading ${fileName}:`, error);
|
||||
process.exitCode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
|
||||
uploadReports();
|
||||
uploadReports().catch((error: unknown) => {
|
||||
console.error('Unexpected upload failure:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user