-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathclair.groovy
79 lines (73 loc) · 2.95 KB
/
clair.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//
// Author: Hari Sekhon
// Date: 2023-05-15 05:38:38 +0100 (Mon, 15 May 2023)
//
// vim:ts=2:sts=2:sw=2:et
//
// https://github.com/HariSekhon/Jenkins
//
// License: see accompanying Hari Sekhon LICENSE file
//
// If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback to help steer this or other code I publish
//
// https://www.linkedin.com/in/HariSekhon
//
// ========================================================================== //
// C l a i r
// ========================================================================== //
// https://github.com/quay/clair
// Clair container security scanner
// Pass list of Docker image:tag images (will attempt to infer from environment DOCKER_IMAGE and DOCKER_TAG otherwise)
//
// Set CLAIR_URL, otherwise defaults to http://clair.clair.svc.cluster.local:8080
// Requires:
//
// - a Jenkins agent with Docker available locally see https://github.com/HariSekhon/Kubernetes-configs/blob/master/jenkins/base/jenkins-agent-pod.yaml
//
// - if pulling docker images from Google Container Registry or Google Artifact Registry then be sure to set up Google Application Credentials first by calling
// gcpSetupApplicationCredentials.groovy or setting up general Docker Authentication to GCR/GAR by calling gcpDockerAuth.groovy / gcrDockerAuth.groovy / garDockerAuth.groovy
//
// Usage:
//
// clair("docker_image1:tag") // pass a string for a single image
//
// clair(["docker_image1:tag1", "docker_image2:tag2"]) // pass a list for 2 of more images
//
// Wrap in a 'catchError' to leave it as informational but not break the build - as it's very common for there to be some CVEs etc and you don't usually want it blocking people
//
// catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
// clair(["docker_image1:tag1", "docker_image2:tag2"])
// // or
// clair(env.DOCKER_IMAGES_TAGS.split(',') as List)
// }
//
// If wanting to call without args, must specify a default type otherwise will hit this error:
//
// org.codehaus.groovy.runtime.metaclass.MethodSelectionException: Could not find which method call() to invoke from this list:
//
def call (imageList=[], timeoutMinutes=30) {
label 'Clair'
List images = []
if (imageList) {
images = imageList
} else {
images = dockerInferImageTagList()
}
env.CLAIR_URL = env.CLAIR_URL ?: 'http://clair.clair.svc.cluster.local:8080'
// let caller decide if wrapping this in a container('clairctl') or using downloadClairctl.groovy to save RAM
//container('clairctl') {
timeout (time: timeoutMinutes, unit: 'MINUTES') {
ansiColor('xterm') {
for (image in images) {
withEnv (["image=$image"]) {
echo "Clair scanning container image '$image'"
sh (
label: "Clair",
script: "clairctl -D report --host '$CLAIR_URL' '$image'"
)
}
}
}
}
//}
}