diff --git a/resources/com/cadoles/trivy/templates/markdown.tpl b/resources/com/cadoles/trivy/templates/markdown.tpl
new file mode 100644
index 0000000..b20a1f5
--- /dev/null
+++ b/resources/com/cadoles/trivy/templates/markdown.tpl
@@ -0,0 +1,56 @@
+{{- if . }}
+{{- range . }}
+
Target {{ escapeXML .Target }}
+{{- if (eq (len .Vulnerabilities) 0) }}
+No Vulnerabilities found
+{{- else }}
+Vulnerabilities ({{ len .Vulnerabilities }})
+
+
+ Package |
+ ID |
+ Severity |
+ Installed Version |
+ Fixed Version |
+
+ {{- range .Vulnerabilities }}
+
+ {{ escapeXML .PkgName }} |
+ {{ escapeXML .VulnerabilityID }} |
+ {{ escapeXML .Severity }} |
+ {{ escapeXML .InstalledVersion }} |
+ {{ escapeXML .FixedVersion }} |
+
+ {{- end }}
+
+{{- end }}
+{{- if (eq (len .Misconfigurations ) 0) }}
+No Misconfigurations found
+{{- else }}
+Misconfigurations
+
+
+ Type |
+ ID |
+ Check |
+ Severity |
+ Message |
+
+ {{- range .Misconfigurations }}
+
+ {{ escapeXML .Type }} |
+ {{ escapeXML .ID }} |
+ {{ escapeXML .Title }} |
+ {{ escapeXML .Severity }} |
+
+ {{ escapeXML .Message }}
+ {{ escapeXML .PrimaryURL }}
+ |
+
+ {{- end }}
+
+{{- end }}
+{{- end }}
+{{- else }}
+Trivy Returned Empty Report
+{{- end }}
\ No newline at end of file
diff --git a/vars/container.groovy b/vars/container.groovy
index da1ecb6..b8f68e8 100644
--- a/vars/container.groovy
+++ b/vars/container.groovy
@@ -6,7 +6,7 @@
* - dockerfile - String - Chemin vers le fichier Dockerfile à utiliser pour construire l'image, par défaut "./Dockerfile"
* - contextDir - String - Répertoire servant de "contexte" pour la construction de l'image, par défault "./"
* - imageName - String - Nom de l'image à construire, par défaut ""
-* - imageTag - String - Tag apposé sur l'image après construction, par défaut résultat de la commande `git describe --always`
+* - imageTags - String - Tag(s) apposé(s) sur l'image après construction, par défaut tags générés par la méthode utils.getProjectVersionTags()
* - gitCredentialsId - String - Identifiant des "credentials" Jenkins utilisés pour cloner le dépôt Git, par défaut "forge-jenkins"
* - dockerRepository - String - Nom d'hôte du registre Docker sur lequel publier l'image, par défaut "reg.cadoles.com"
* - dockerRepositoryCredentialsId - String - Identifiant des "credentials" Jenkins utilisés pour déployer l'image sur le registre Docker, par défault "reg.cadoles.com-jenkins"
@@ -18,7 +18,13 @@ String buildAndPublishImage(Map options = [:]) {
String contextDir = options.get('contextDir', '.')
String imageName = options.get('imageName', '')
String gitRef = sh(returnStdout: true, script: 'git describe --always').trim()
- String imageTag = options.get('imageTag', gitRef)
+
+ List imageTags = options.get('imageTags', utils.getProjectVersionTags())
+ // Handle legacy imageTag parameter
+ if (options.containsKey('imageTag')) {
+ imageTags = [ options.get("imageTag", gitRef) ]
+ }
+
String gitCredentialsId = options.get('gitCredentialsId', 'forge-jenkins')
String dockerRepository = options.get('dockerRepository', 'reg.cadoles.com')
String dockerRepositoryCredentialsId = options.get('dockerRepositoryCredentialsId', 'reg.cadoles.com-jenkins')
@@ -44,13 +50,15 @@ String buildAndPublishImage(Map options = [:]) {
}
}
- stage("Build image '${imageName}:${imageTag}'") {
+ String primaryImageTag = imageTags[0]
+
+ stage("Build image '${imageName}:${primaryImageTag}'") {
git.withHTTPCredentials(gitCredentialsId) {
sh """
docker build \
--build-arg="GIT_USERNAME=${env.GIT_USERNAME}" \
--build-arg="GIT_PASSWORD=${env.GIT_PASSWORD}" \
- -t '${imageName}:${imageTag}' \
+ -t '${imageName}:${primaryImageTag}' \
-f '${dockerfile}' \
'${contextDir}'
"""
@@ -59,20 +67,33 @@ String buildAndPublishImage(Map options = [:]) {
stage('Validate image with Trivy') {
utils.when(!skipVerifications) {
- runTrivyCheck("${imageName}:${imageTag}", projectRepository)
+ runTrivyCheck("${imageName}:${primaryImageTag}", projectRepository)
}
}
- stage("Publish image '${imageName}:${imageTag}'") {
+ stage("Login with image repository") {
utils.when(!dryRun) {
- retry(2) {
+ sh """
+ echo ${env.HUB_PASSWORD} | docker login -u '${env.HUB_USERNAME}' --password-stdin '${dockerRepository}'
+ """
+ }
+ }
+
+ imageTags.each { imageTag ->
+ stage("Publish image '${imageName}:${imageTag}'") {
+ utils.when(!dryRun) {
sh """
- echo ${env.HUB_PASSWORD} | docker login -u '${env.HUB_USERNAME}' --password-stdin '${dockerRepository}'
- docker push '${imageName}:${imageTag}'
+ docker tag "${imageName}:${primaryImageTag}" "${imageName}:${imageTag}"
"""
+ retry(2) {
+ sh """
+ docker push '${imageName}:${imageTag}'
+ """
+ }
}
}
- }
+ }
+
}
}
@@ -87,10 +108,12 @@ void runHadolintCheck(String dockerfile, String projectRepository) {
String lintReport = ''
if (fileExists(reportFile)) {
+ String report = readFile(reportFile)
+
lintReport = """${lintReport}
|
|```
- |${readFile(reportFile)}
+ |${report.trim() ? report : "Rien à signaler."}
|```"""
} else {
lintReport = """${lintReport}
@@ -99,7 +122,7 @@ void runHadolintCheck(String dockerfile, String projectRepository) {
}
String defaultReport = '_Rien à signaler !_ :thumbsup:'
- String report = """## Validation du Dockerfile `${dockerfile}`
+ String report = """## Rapport d'analyse du fichier `${dockerfile}` avec [Hadolint](https://github.com/hadolint/hadolint)
|
|${lintReport ?: defaultReport}
""".stripMargin()
@@ -138,9 +161,8 @@ void runTrivyCheck(String imageName, String projectRepository, Map options = [:]
if (fileExists(reportFile)) {
lintReport = """${lintReport}
|
- |```
|${readFile(reportFile)}
- |```"""
+ |"""
} else {
lintReport = """${lintReport}
|
@@ -148,7 +170,7 @@ void runTrivyCheck(String imageName, String projectRepository, Map options = [:]
}
String defaultReport = '_Rien à signaler !_ :thumbsup:'
- String report = """## Validation de l'image `${imageName}`
+ String report = """## Rapport d'analyse de l'image avec [Trivy](https://github.com/aquasecurity/trivy)
|
|${lintReport ?: defaultReport}
""".stripMargin()
@@ -168,11 +190,14 @@ String validateImageWithTrivy(String imageName, Map options = [:]) {
String cacheDefaultBranch = options.get('cacheDefaultBranch', 'develop')
Integer cacheMaxSize = options.get('cacheMaxSize', 250)
String reportFile = options.get('reportFile', ".trivy-report-${currentBuild.startTimeInMillis}.txt")
-
+
+ String markdownTemplate = libraryResource 'com/cadoles/trivy/templates/markdown.tpl'
+ writeFile file:'.trivy-markdown.tpl', text: markdownTemplate
+
cache(maxCacheSize: cacheMaxSize, defaultBranch: cacheDefaultBranch, caches: [
[$class: 'ArbitraryFileCache', path: cacheDirectory, compressionMethod: 'TARGZ']
]) {
- sh("'${trivyBin}' --cache-dir '${cacheDirectory}' image -o '${reportFile}' ${trivyArgs} '${imageName}'")
+ sh("'${trivyBin}' --cache-dir '${cacheDirectory}' image --format template --template '@.trivy-markdown.tpl' -o '${reportFile}' ${trivyArgs} '${imageName}'")
}
return reportFile