From c2897fb9495a724e05362527adfe485a39f1a75f Mon Sep 17 00:00:00 2001 From: Robert Auer Date: Mon, 18 Nov 2024 13:47:08 +0100 Subject: [PATCH] Add Trivy implementation structure; #136 --- src/com/cloudogu/ces/cesbuildlib/Trivy.groovy | 44 +++++++++++++++++++ .../ces/cesbuildlib/TrivyScanFormat.groovy | 21 +++++++++ .../ces/cesbuildlib/TrivyScanLevel.groovy | 26 +++++++++++ .../ces/cesbuildlib/TrivyScanStrategy.groovy | 18 ++++++++ 4 files changed, 109 insertions(+) create mode 100644 src/com/cloudogu/ces/cesbuildlib/Trivy.groovy create mode 100644 src/com/cloudogu/ces/cesbuildlib/TrivyScanFormat.groovy create mode 100644 src/com/cloudogu/ces/cesbuildlib/TrivyScanLevel.groovy create mode 100644 src/com/cloudogu/ces/cesbuildlib/TrivyScanStrategy.groovy diff --git a/src/com/cloudogu/ces/cesbuildlib/Trivy.groovy b/src/com/cloudogu/ces/cesbuildlib/Trivy.groovy new file mode 100644 index 00000000..752c4bfe --- /dev/null +++ b/src/com/cloudogu/ces/cesbuildlib/Trivy.groovy @@ -0,0 +1,44 @@ +package com.cloudogu.ces.cesbuildlib + +class Trivy implements Serializable { + def script + String trivyReportFilename + + Trivy(script, String trivyReportFilename = "${env.WORKSPACE}/.trivy/trivyReport.json") { + this.script = script + this.trivyReportFilename = trivyReportFilename + } + + /** + * Scans an image for vulnerabilities. + * Notes: + * - Use a .trivyignore file for allowed CVEs + * - This function will generate a JSON formatted report file which can be converted to other formats via saveFormattedTrivyReport() + * - Evaluate via exit codes: 0 = no vulnerability; 1 = vulnerabilities found; other = function call failed + * + * @param imageName The image name; may include version tag + * @param trivyVersion The version of Trivy used for scanning + * @param additionalFlags Additional Trivy command flags + * @param scanLevel The vulnerability level to scan. Can be a member of TrivyScanLevel or a custom String (e.g. 'CRITICAL,LOW') + * @param strategy The strategy to follow after the scan. Should the build become unstable or failed? Or Should any vulnerability be ignored? (@see TrivyScanStrategy) + * // TODO: A strategy could be implemented by the user via the exit codes of this function. Should we remove the strategy parameter? + * @return Returns 0 if the scan was ok (no vulnerability found); returns 1 if any vulnerability was found + */ + int scanImage(String imageName, String trivyVersion = "0.57.0", String additionalFlags, String scanLevel = TrivyScanLevel.CRITICAL, String strategy = TrivyScanStrategy.FAIL) { + // TODO: Run trivy scan inside Docker container, e.g. via Jenkins' Docker.image() function + // See runTrivyInDocker function: https://github.com/cloudogu/ces-build-lib/blob/c48273409f8f506e31872fe2857650bbfc76a222/vars/findVulnerabilitiesWithTrivy.groovy#L48 + // TODO: Write result to trivyReportFile in json format (--format json), which can be converted in the saveFormattedTrivyReport function + // TODO: Include .trivyignore file, if existent. Do not fail if .trivyignore file does not exist. + } + + /** + * Save the Trivy scan results as a file with a specific format + * + * @param format The format of the output file (@see TrivyScanFormat) + */ + void saveFormattedTrivyReport(String format = TrivyScanFormat.HTML) { + // TODO: DO NOT scan again! Take the trivyReportFile and convert its content + // See https://aquasecurity.github.io/trivy/v0.52/docs/references/configuration/cli/trivy_convert/ + } + +} diff --git a/src/com/cloudogu/ces/cesbuildlib/TrivyScanFormat.groovy b/src/com/cloudogu/ces/cesbuildlib/TrivyScanFormat.groovy new file mode 100644 index 00000000..45164c8a --- /dev/null +++ b/src/com/cloudogu/ces/cesbuildlib/TrivyScanFormat.groovy @@ -0,0 +1,21 @@ +package com.cloudogu.ces.cesbuildlib + +/** + * Defines the output format for the trivy report. + */ +class TrivyScanFormat { + /** + * Output as HTML file. + */ + static String HTML = "html" + + /** + * Output as JSON file. + */ + static String JSON = "json" + + /** + * Output as plain text file. + */ + static String PLAIN = "plain" +} diff --git a/src/com/cloudogu/ces/cesbuildlib/TrivyScanLevel.groovy b/src/com/cloudogu/ces/cesbuildlib/TrivyScanLevel.groovy new file mode 100644 index 00000000..1c7c10c5 --- /dev/null +++ b/src/com/cloudogu/ces/cesbuildlib/TrivyScanLevel.groovy @@ -0,0 +1,26 @@ +package com.cloudogu.ces.cesbuildlib + +/** + * Defines aggregated vulnerability levels + */ +class TrivyScanLevel { + /** + * Only critical vulnerabilities. + */ + static String CRITICAL = "CRITICAL" + + /** + * High or critical vulnerabilities. + */ + static String HIGH = "CRITICAL,HIGH" + + /** + * Medium or higher vulnerabilities. + */ + static String MEDIUM = "CRITICAL,HIGH,MEDIUM" + + /** + * All vunlerabilities. + */ + static String ALL = "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL" +} diff --git a/src/com/cloudogu/ces/cesbuildlib/TrivyScanStrategy.groovy b/src/com/cloudogu/ces/cesbuildlib/TrivyScanStrategy.groovy new file mode 100644 index 00000000..f9db8951 --- /dev/null +++ b/src/com/cloudogu/ces/cesbuildlib/TrivyScanStrategy.groovy @@ -0,0 +1,18 @@ +package com.cloudogu.ces.cesbuildlib + +class TrivyScanStrategy { + /** + * Strategy: Fail if any vulnerability was found. + */ + static String FAIL = "fail" + + /** + * Strategy: Make build unstable if any vulnerability was found. + */ + static String UNSTABLE = "unstable" + + /** + * Strategy: Ignore any found vulnerability. + */ + static String IGNORE = "ignore" +}