feat(container): publish image with multiple tags
This commit is contained in:
parent
2c182df6a6
commit
4e3cd2d092
|
@ -0,0 +1,56 @@
|
||||||
|
{{- if . }}
|
||||||
|
{{- range . }}
|
||||||
|
<h3>Target <code>{{ escapeXML .Target }}</code></h3>
|
||||||
|
{{- if (eq (len .Vulnerabilities) 0) }}
|
||||||
|
<h4>No Vulnerabilities found</h4>
|
||||||
|
{{- else }}
|
||||||
|
<h4>Vulnerabilities ({{ len .Vulnerabilities }})</h4>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Package</th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Severity</th>
|
||||||
|
<th>Installed Version</th>
|
||||||
|
<th>Fixed Version</th>
|
||||||
|
</tr>
|
||||||
|
{{- range .Vulnerabilities }}
|
||||||
|
<tr>
|
||||||
|
<td><code>{{ escapeXML .PkgName }}</code></td>
|
||||||
|
<td>{{ escapeXML .VulnerabilityID }}</td>
|
||||||
|
<td>{{ escapeXML .Severity }}</td>
|
||||||
|
<td>{{ escapeXML .InstalledVersion }}</td>
|
||||||
|
<td>{{ escapeXML .FixedVersion }}</td>
|
||||||
|
</tr>
|
||||||
|
{{- end }}
|
||||||
|
</table>
|
||||||
|
{{- end }}
|
||||||
|
{{- if (eq (len .Misconfigurations ) 0) }}
|
||||||
|
<h4>No Misconfigurations found</h4>
|
||||||
|
{{- else }}
|
||||||
|
<h4>Misconfigurations</h4>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Check</th>
|
||||||
|
<th>Severity</th>
|
||||||
|
<th>Message</th>
|
||||||
|
</tr>
|
||||||
|
{{- range .Misconfigurations }}
|
||||||
|
<tr>
|
||||||
|
<td>{{ escapeXML .Type }}</td>
|
||||||
|
<td>{{ escapeXML .ID }}</td>
|
||||||
|
<td>{{ escapeXML .Title }}</td>
|
||||||
|
<td>{{ escapeXML .Severity }}</td>
|
||||||
|
<td>
|
||||||
|
{{ escapeXML .Message }}
|
||||||
|
<br><a href={{ escapeXML .PrimaryURL | printf "%q" }}>{{ escapeXML .PrimaryURL }}</a></br>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{- end }}
|
||||||
|
</table>
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- else }}
|
||||||
|
<h3>Trivy Returned Empty Report</h3>
|
||||||
|
{{- end }}
|
|
@ -6,7 +6,7 @@
|
||||||
* - dockerfile - String - Chemin vers le fichier Dockerfile à utiliser pour construire l'image, par défaut "./Dockerfile"
|
* - 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 "./"
|
* - 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 ""
|
* - 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"
|
* - 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"
|
* - 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"
|
* - 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 contextDir = options.get('contextDir', '.')
|
||||||
String imageName = options.get('imageName', '')
|
String imageName = options.get('imageName', '')
|
||||||
String gitRef = sh(returnStdout: true, script: 'git describe --always').trim()
|
String gitRef = sh(returnStdout: true, script: 'git describe --always').trim()
|
||||||
String imageTag = options.get('imageTag', gitRef)
|
|
||||||
|
List<String> 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 gitCredentialsId = options.get('gitCredentialsId', 'forge-jenkins')
|
||||||
String dockerRepository = options.get('dockerRepository', 'reg.cadoles.com')
|
String dockerRepository = options.get('dockerRepository', 'reg.cadoles.com')
|
||||||
String dockerRepositoryCredentialsId = options.get('dockerRepositoryCredentialsId', 'reg.cadoles.com-jenkins')
|
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) {
|
git.withHTTPCredentials(gitCredentialsId) {
|
||||||
sh """
|
sh """
|
||||||
docker build \
|
docker build \
|
||||||
--build-arg="GIT_USERNAME=${env.GIT_USERNAME}" \
|
--build-arg="GIT_USERNAME=${env.GIT_USERNAME}" \
|
||||||
--build-arg="GIT_PASSWORD=${env.GIT_PASSWORD}" \
|
--build-arg="GIT_PASSWORD=${env.GIT_PASSWORD}" \
|
||||||
-t '${imageName}:${imageTag}' \
|
-t '${imageName}:${primaryImageTag}' \
|
||||||
-f '${dockerfile}' \
|
-f '${dockerfile}' \
|
||||||
'${contextDir}'
|
'${contextDir}'
|
||||||
"""
|
"""
|
||||||
|
@ -59,20 +67,33 @@ String buildAndPublishImage(Map options = [:]) {
|
||||||
|
|
||||||
stage('Validate image with Trivy') {
|
stage('Validate image with Trivy') {
|
||||||
utils.when(!skipVerifications) {
|
utils.when(!skipVerifications) {
|
||||||
runTrivyCheck("${imageName}:${imageTag}", projectRepository)
|
runTrivyCheck("${imageName}:${primaryImageTag}", projectRepository)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage("Publish image '${imageName}:${imageTag}'") {
|
stage("Login with image repository") {
|
||||||
utils.when(!dryRun) {
|
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 """
|
sh """
|
||||||
echo ${env.HUB_PASSWORD} | docker login -u '${env.HUB_USERNAME}' --password-stdin '${dockerRepository}'
|
docker tag "${imageName}:${primaryImageTag}" "${imageName}:${imageTag}"
|
||||||
docker push '${imageName}:${imageTag}'
|
|
||||||
"""
|
"""
|
||||||
|
retry(2) {
|
||||||
|
sh """
|
||||||
|
docker push '${imageName}:${imageTag}'
|
||||||
|
"""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,10 +108,12 @@ void runHadolintCheck(String dockerfile, String projectRepository) {
|
||||||
String lintReport = ''
|
String lintReport = ''
|
||||||
|
|
||||||
if (fileExists(reportFile)) {
|
if (fileExists(reportFile)) {
|
||||||
|
String report = readFile(reportFile)
|
||||||
|
|
||||||
lintReport = """${lintReport}
|
lintReport = """${lintReport}
|
||||||
|
|
|
|
||||||
|```
|
|```
|
||||||
|${readFile(reportFile)}
|
|${report.trim() ? report : "Rien à signaler."}
|
||||||
|```"""
|
|```"""
|
||||||
} else {
|
} else {
|
||||||
lintReport = """${lintReport}
|
lintReport = """${lintReport}
|
||||||
|
@ -99,7 +122,7 @@ void runHadolintCheck(String dockerfile, String projectRepository) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String defaultReport = '_Rien à signaler !_ :thumbsup:'
|
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}
|
|${lintReport ?: defaultReport}
|
||||||
""".stripMargin()
|
""".stripMargin()
|
||||||
|
@ -138,9 +161,8 @@ void runTrivyCheck(String imageName, String projectRepository, Map options = [:]
|
||||||
if (fileExists(reportFile)) {
|
if (fileExists(reportFile)) {
|
||||||
lintReport = """${lintReport}
|
lintReport = """${lintReport}
|
||||||
|
|
|
|
||||||
|```
|
|
||||||
|${readFile(reportFile)}
|
|${readFile(reportFile)}
|
||||||
|```"""
|
|"""
|
||||||
} else {
|
} else {
|
||||||
lintReport = """${lintReport}
|
lintReport = """${lintReport}
|
||||||
|
|
|
|
||||||
|
@ -148,7 +170,7 @@ void runTrivyCheck(String imageName, String projectRepository, Map options = [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
String defaultReport = '_Rien à signaler !_ :thumbsup:'
|
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}
|
|${lintReport ?: defaultReport}
|
||||||
""".stripMargin()
|
""".stripMargin()
|
||||||
|
@ -168,11 +190,14 @@ String validateImageWithTrivy(String imageName, Map options = [:]) {
|
||||||
String cacheDefaultBranch = options.get('cacheDefaultBranch', 'develop')
|
String cacheDefaultBranch = options.get('cacheDefaultBranch', 'develop')
|
||||||
Integer cacheMaxSize = options.get('cacheMaxSize', 250)
|
Integer cacheMaxSize = options.get('cacheMaxSize', 250)
|
||||||
String reportFile = options.get('reportFile', ".trivy-report-${currentBuild.startTimeInMillis}.txt")
|
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: [
|
cache(maxCacheSize: cacheMaxSize, defaultBranch: cacheDefaultBranch, caches: [
|
||||||
[$class: 'ArbitraryFileCache', path: cacheDirectory, compressionMethod: 'TARGZ']
|
[$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
|
return reportFile
|
||||||
|
|
Loading…
Reference in New Issue