-
Notifications
You must be signed in to change notification settings - Fork 0
/
Jenkinsfile.sample
227 lines (199 loc) · 7.11 KB
/
Jenkinsfile.sample
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// This pipeline runs in containerized environments, so there are very
// fewer requirements of the Jenkins worker nodes -- they just need
// to be able to run Docker containers. Megalinter, the SARIF uploader,
// etc. do not need to be installed.
//
// The pipeline has 3 basic steps:
//
// 1. Clone the git repository
// 2. Run Megalinter on the local clone
// 3. Push the results (SARIF files) to DefectDojo
//
// The git repository checkout process uses the Git plugin for Jenkins.
//
// The Megalinter and DefectDojo uploader processes use images available
// from the Internet (e.g., DockerHub). As the Megalinter image -- even
// the security flavor -- can be quite large (e.g.,
// oxsecurity/megalinter-security:v7.10.0 is 999.5MB across 67 layers),
// one may wish to `docker pull oxsecurity/megalinter-security:latest`
// on the worker nodes outside of this pipeline or use a local registry
// to cache the image to improve load times.
//
// It's important to reuse nodes (`reuseNode true`) so that the SARIF
// files produced by Megalinter may be uploaded to DefectDojo; otherwise,
// Docker may run the steps in different workspaces, potentially on
// different nodes or with different agents.
//
// Note: one may wish to configure Jenkins that use Docker-based pipelines
// to use a specific set of credentials to get around rate limitations
// with DockerHub. To do so, a `.withRegistry()` call with the URL and
// credentials ID may be used
//
// Docker images:
// * https://hub.docker.com/r/oxsecurity/megalinter-security
// * https://hub.docker.com/r/wesleydeanflexion/upload-sarif-to-defectdojo
//
// Required Jenkins plugins:
// * Git: https://plugins.jenkins.io/git/
// * AnsiColor: https://plugins.jenkins.io/ansicolor/
//
// Required credential objects:
// * GitHub PAT (for pulling the repository)
// * Defect Dojo token (for uploading the results)
//
// To use this Jenkinsfile, several parameters need to be set:
// * git_repository: URL to the git repository
// * git_credentials: credential ID to use to interact with git
// * defectdojo_token: credential ID to use to interact with DefectDojo
//
// Generally, the fields that need to be updated have three stars (`***`)
// in the `defaultValue` field.
pipeline {
agent any
parameters {
string(
name: 'git_repository',
defaultValue: '*** URL for your git repository goes here ***',
description: 'The URL to the git repository to scan'
)
string(
name: 'git_credentials',
defaultValue: '*** ID of your credentials (e.g., Github PAT) go here ***',
description: 'Credential ID to use when interacting with the git repository'
)
string(
name: 'git_branch',
defaultValue: 'main',
description: 'Branch to clone from the git repository'
)
string(
name: 'megalinter_image',
defaultValue: 'oxsecurity/megalinter-security:latest',
description: 'Megalinter Docker image'
)
string(
name: 'uploader_image',
defaultValue: 'wesleydeanflexion/upload-sarif-to-defectdojo',
description: 'Defectdojo Uploader Docker image'
)
string(
name: 'defectdojo_server_host',
defaultValue: '*** your Defectdojo server hostnames goes here ***',
description: 'Defectdojo server hostname'
)
string(
name: 'defectdojo_product',
defaultValue: '*** your product in Defectdojo goes here ***',
description: 'Defectdojo product'
)
string(
name: 'defectdojo_engagement',
defaultValue: '*** your engagement in Defectdojo goes here ***',
description: 'Defectdojo engagement'
)
string(
name: 'defectdojo_token',
defaultValue: 'DD_TOKEN',
description: 'Defectdojo authentication token'
)
choice(
name: 'minimum_severity',
choices: ['Info', 'Low', 'Medium', 'High', 'Critical'],
description: 'The minimum severity finding to record'
)
choice(
name: 'close_old_findings',
choices: ['true', 'false'],
description: 'Close old findings'
)
choice(
name: 'close_old_findings_product_scope',
choices: ['true', 'false'],
description: 'Close old findings with the same product scope'
)
}
environment {
GIT_REPOSITORY = "$params.git_repository"
GIT_CREDENTIALS = "$params.git_credentials"
GIT_BRANCH = "$params.git_branch"
MEGALINTER_IMAGE = "$params.megalinter_image"
SARIF_REPORTER = "true"
DISABLE_ERRORS = "true"
ADDITIONAL_EXCLUDED_DIRECTORIES = "**/megalinter-reports/**"
VALIDATE_ALL_CODEBASE = "true"
IGNORE_GITIGNORED_FILES="true"
DD_UPLOADER_IMAGE = "$params.uploader_image"
DD_MINIMUM_SEVERITY = "$params.minimum_severity"
DD_SERVER_HOST = "$params.defectdojo_server_host"
DD_PRODUCT = "$params.defectdojo_product"
DD_ENGAGEMENT = "$params.defectdojo_engagement"
DD_TOKEN = credentials("$params.defectdojo_token")
DD_CLOSE_OLD_FINDINGS = "$params.close_old_findings"
DD_CLOSE_OLD_FINDINGS_PRODUCT_SCOPE = "$params.close_old_findings_product_scope"
}
triggers {
// check with the repo for fresh commits every 5 minutes; when there
// are new commits on the main branch, trigger a run of this pipeline
pollSCM 'H/5 * * * *'
}
options {
// when stuff takes a while, it can be helpful to correlate delays with
// log entries
timestamps()
// it can take a few minutes to pull down the Megalinter image the first
// time (expedite with a local proxy or `docker pull` beforehand on the
// worker nodes); after that, a scan generally takes less than a minute
// to run. If a scanner gets stuck, cut it off after 10 minutes
timeout(time: 10, unit: 'MINUTES')
// Megalinter logs can contain ANSI color sequences, so interpret them
// with the ANSI Color plugin: https://plugins.jenkins.io/ansicolor/
// so, if nothing else, at least the color sequences are filtered out
ansiColor('xterm')
}
stages {
stage('Checkout') {
steps {
// we need to cleanup the workspace so old SARIF files are
// removed and not resubmitted after that findings are
// remediated
cleanWs()
git branch: "${env.GIT_BRANCH}",
credentialsId: "${env.GIT_CREDENTIALS}",
url: "${env.GIT_REPOSITORY}"
}
}
stage('MegaLinter') {
agent {
docker {
image "${env.MEGALINTER_IMAGE}"
args "-u root -v ${WORKSPACE}:/tmp/lint -w /tmp/lint --entrypoint=''"
reuseNode true
}
}
steps {
sh '/entrypoint.sh'
}
post {
always {
// capture the linter logs as build artifacts
archiveArtifacts allowEmptyArchive: true,
artifacts: 'mega-linter.log,megalinter-reports/**/*',
defaultExcludes: false,
followSymlinks: false
}
}
}
stage('DefectDojo') {
agent {
docker {
image "${env.DD_UPLOADER_IMAGE}"
args "-v ${WORKSPACE}:/tmp/lint -w /tmp/lint --entrypoint=''"
reuseNode true
}
}
steps {
sh '/upload_sarif_to_defectdojo.bash /tmp/lint/megalinter-reports/sarif/*.sarif'
}
}
}
}