1/** 2 * Initiate a scan of Synopsys Detect. By default the working directory ('./') is scanned and all detectors are enabled. 3 * Java MUST be installed for this to be successful, and it is suggested to scan in a docker container due to the 4 * detector possibly building the project automatically. 5 * 6 * The 'optional' map supports these fields: 7 * - clearPriorScans: false. Clear previous scans (but doesn't delete them) for the associated project and version on the server. 8 * - coreCount: -1. Scanner parallel processors where -1 uses the number of cores on the system. 9 * - disableDetector: false. Disable the synopsys detector; the detector SHOULD be run but it can result in build issues 10 * and can be disabled. 11 * - logLevel: info. Logging level of synopsys. 12 * - productionScan: false. Set this to true to send scan results to the production blackduck server; staging is used by default. 13 * - scanOpts: [:]. A map of additional hub command-line arguments, or overrides, depending on project needs. for example, 14 * users can control the detector search depth with optional.scanOpts["--detect.detector.search.depth"] = "0". 15 * - scannerMemoryMB: 1024. 16 * - timeout: 60. Maximum scan timeout, in minutes, before failing the build. 17 * 18 * Important implementation notes: 19 * - Java must be installed and in the path. 20 * - A temporary directory, scanTempDir, is created at '/tmp/synopsys-detect-<projectName>-<projectVersion>-XXXXXXXX'. 21 * This temporary is DELETED after the scan to avoid excessive storage usage. 22 * - Synopsys Detect Air Gap (600MB+ zip, 1.5GB+ extracted) is generated at '$scanTempDir/synopsys-detect-air-gap/<synopVersion>'. 23 * This path is deleted along with the temp dir after the scan. 24 * - The files in $scanTempDir/runs/** are archived. 25 * - URLs 26 * - https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/622673/Synopsys+Detect+Properties 27 * - https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/62423113/Synopsys+Detect 28 * 29 * @param optional map of optional arguments 30 * @param projectName the name of the project 31 * @param projectVersion the version of the project 32 */ 33def call(Map optional = [:], String projectName, String projectVersion) { 34 optional.projectName = projectName 35 optional.projectVersion = projectVersion 36 optional.scanOpts = (Map) optional.scanOpts ?: [:] 37 call(optional) 38} 39 40def call(Map optional) { 41 String projectVersion = optional.projectVersion 42 String projectName = optional.projectName 43 String synopsysDetectVersion = optional.synopsysDetectVersion ?: "6.3.0" 44 BLACKDUCK_SKIP_PHONE_HOME = true 45 46 String url = "https://blackduck-staging.eng.netapp.com" 47 String credId = 'hubStagingToken' 48 49 // Use the production server if productionScan is explicitly set to true 50 if (new Boolean(optional.productionScan)) { 51 url = "https://blackduck.eng.netapp.com" 52 credId = 'hubProductionToken' 53 } 54 55 withCredentials([string(credentialsId: credId, variable: 'TOKEN')]) { 56 String timeoutMinutes = optional.timeout ?: 60 57 58 // Create the temporary directory for the scan logs and the extracted hub-detect zip 59 def scanTempDir = sh(returnStdout: true, script: "mktemp --directory \"/tmp/synopsys-detect-${projectName}-${projectVersion}-XXXXXXXXXX\"").trim() 60 def synopsysDir = "${scanTempDir}/synopsys-detect-air-gap/${synopsysDetectVersion}" 61 setupSynopsysDetect(synopsysDetectVersion, synopsysDir: synopsysDir) 62 63 echo "Using temporary directory ${scanTempDir}" 64 echo "Sending results to ${url}" 65 echo "Additional parameters: ${optional}" 66 echo "Using timeout of ${timeoutMinutes} minutes" 67 68 Map m = [:] 69 m["--blackduck.trust.cert"] = "true" 70 m["--blackduck.url"] = url 71 m["--blackduck.api.token"] = TOKEN 72 m["--detect.project.name"] = projectName 73 m["--detect.project.version.name"] = projectVersion 74 m["--detect.code.location.name"] = "${projectName}-${projectVersion}" 75 m["--detect.project.codelocation.unmap"] = optional.clearPriorScans ?: "false" 76 m["--detect.blackduck.signature.scanner.memory"] = optional.scannerMemoryMB ?: "1024" 77 m["--detect.parallel.processors"] = optional.coreCount ?: -1 78 m["--detect.cleanup"] = "false" 79 m["--detect.blackduck.signature.scanner.paths"] = optional.scanDir ?: './' 80 m["--detect.output.path"] = scanTempDir 81 m["--logging.level.com.synopsys.integration"] = optional.logLevel ?: "INFO" 82 m["--detect.detector.search.depth"] = "3" 83 m["--detect.sbt.report.depth"] = "3" 84 m["--detect.blackduck.signature.scanner.exclusion.name.patterns"] = "node_modules,.git,.gradle" 85 m["--detect.blackduck.signature.scanner.exclusion.pattern.search.depth"] = "30" 86 m["--detect.docker.inspector.air.gap.path"] = "${synopsysDir}/packaged-inspectors/docker" 87 m["--detect.nuget.inspector.air.gap.path"] = "${synopsysDir}/packaged-inspectors/nuget" 88 m["--detect.gradle.inspector.air.gap.path"] = "${synopsysDir}/packaged-inspectors/gradle" 89 m["--detect.blackduck.signature.scanner.individual.file.matching"] = "ALL" 90 91 if (optional.cloneVersion) { 92 m["--detect.clone.project.version.name"] = optional.cloneVersion 93 } 94 if ((boolean) optional.disableDetector) { 95 m["--detect.tools.excluded"] = "DETECTOR" 96 } 97 98 m.putAll((Map) optional.scanOpts) 99 100 synopsysArgs = m.collectEntries { k, v -> ["$k=$v"] }.keySet().join(" \\\n ") 101 synopsysExec = "java -Xms1024m -Xmx2048m -jar ${synopsysDir}/synopsys-detect-${synopsysDetectVersion}.jar ${synopsysArgs}" 102 echo "The blackduck scan execute command: \n'${synopsysExec}'" 103 104 try { 105 timeout(time: "${timeoutMinutes}", unit: 'MINUTES') { 106 sh """ 107 ${synopsysExec} 108 # Delete any existing docker extractions from this scan to avoid excessive storage use. 109 rm -rf ${scanTempDir}/runs/*/extractions || true 110 mv ${scanTempDir}/runs synopsysRuns 111 """ 112 113 // NOTE: Archiving works **ONLY** in the build workspace. All artifacts must be copied to the workspace. 114 // Ignore gz to avoid archiving docker images. 115 archiveArtifacts artifacts: "synopsysRuns/**", excludes: "**/*.gz" 116 } 117 } finally { 118 dir("${scanTempDir}") { 119 deleteDir() 120 } 121 } 122 } 123} 124