Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aqua log and white-listing fixes #1161

Merged
merged 66 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
2136a47
Update 4.x branch for new release (#976)
BraisVQ Feb 21, 2023
8640294
restore antora config
BraisVQ Feb 21, 2023
e30681b
Removed preview flag
BraisVQ Feb 27, 2023
f9aef74
update index.adoc - remove page latest flag
tbugfinder Feb 28, 2023
59ab2a1
4.x Memory leak cleanup code - for component pipeline (#980)
clemensutschig Mar 21, 2023
ef7a097
Cherry pick on 4.x branch of PRs #982 and #984 (#985)
BraisVQ Mar 21, 2023
c6c6908
Fix/levadoc templates config (#1000)
jorge-romero May 4, 2023
befbc61
Release branch update for v4.3.0 (#1014)
BraisVQ Jul 3, 2023
eb75e02
Prepare 4.x branch for release 4.3.1 (#1019)
BraisVQ Jul 13, 2023
767a864
Prepare release branch for release 4.3.2 (#1039)
BraisVQ Oct 2, 2023
bb5dc58
Merge code from master (#1058)
BraisVQ Nov 7, 2023
239b7c9
Prepare release 4.3.4 (#1073)
BraisVQ Feb 20, 2024
e71d18a
release 4.4.0 (#1095)
BraisVQ Apr 22, 2024
c354ed8
Prepare release 4.5.0 (#1127)
BraisVQ Jun 7, 2024
40bb7f1
Prepare release 4.5.1 (#1131)
BraisVQ Jun 19, 2024
b30f6f1
Release 4.5.2 (#1134)
BraisVQ Jun 25, 2024
6e6638a
Release 4.5.3 (#1137)
BraisVQ Jul 8, 2024
5073b38
Release 4.5.4 (#1142)
BraisVQ Jul 17, 2024
5a4bfb9
Pull request #3: Master local
Aug 8, 2024
a30abee
Release 4.5.5 (#1149)
BraisVQ Aug 26, 2024
4a13ee4
Prepare release 4.5.6 (#1155)
BraisVQ Sep 16, 2024
0cd79b3
Merge branch 'refs/heads/master_ods'
Sep 16, 2024
e00ea99
Merge branch 'refs/heads/master_ods'
Sep 20, 2024
3d56c71
Merge branch 'refs/heads/master_ods' into 4.x
Sep 20, 2024
4e0d60b
Merge branch 'refs/heads/master_ods'
Sep 27, 2024
fd1a6cc
Merge branch 'refs/heads/master_ods' into 4.x
Sep 27, 2024
c877441
Merge branch '4.x' of https://bitbucket-tcvedp-cd.apps.us-test.ocp.aw…
Sep 30, 2024
57f63da
Merge branch 'master' of https://bitbucket-tcvedp-cd.apps.us-test.ocp…
Oct 2, 2024
e9074f3
Merge branch 'refs/heads/master_ods'
Oct 2, 2024
45ab6c9
Update RECV error log.
Oct 2, 2024
a9f8e47
Update RECV error log.
Oct 2, 2024
3d5c909
Debug.
Oct 2, 2024
e1c6dc9
Consider already_acknowledged field.
Oct 2, 2024
7e2fc0a
Log whitelisted RECVs.
Oct 3, 2024
b985cde
Log whitelisted RECVs.
Oct 3, 2024
210b250
Log whitelisted RECVs.
Oct 3, 2024
d9c2aa6
Debug.
Oct 3, 2024
3b797b8
Debug.
Oct 4, 2024
3c981aa
Debug.
Oct 4, 2024
1248839
Debug.
Oct 4, 2024
ec9a64c
Debug.
Oct 4, 2024
77a7cdd
Debug.
Oct 4, 2024
69ab1c6
Debug.
Oct 4, 2024
26efe5e
Debug.
Oct 4, 2024
191ab24
Debug.
Oct 4, 2024
f65cf31
Debug.
Oct 6, 2024
959ec73
Fix git url extraction.
Oct 8, 2024
03c0db7
Fix git url extraction.
Oct 8, 2024
111a758
Fixed create issue method.
Oct 8, 2024
12d35c5
Fix retrieve git branch.
Oct 8, 2024
7e7f5f7
Fix showing scanned branch.
Oct 8, 2024
0a89936
Debug.
Oct 9, 2024
6ba8aab
Debug.
Oct 9, 2024
e3b278c
Fix duplicate issue keys.
Oct 9, 2024
a4d2483
Fix codenarc violations.
Oct 9, 2024
3000b55
Fix codenarc violations.
Oct 9, 2024
1a0eec4
Fix tests.
Oct 9, 2024
39bc418
Debug.
Oct 10, 2024
ca71458
Debug.
Oct 10, 2024
2a6840e
Debug.
Oct 10, 2024
14bd64d
Debug.
Oct 10, 2024
8f16c68
Debug.
Oct 10, 2024
3fff849
Update changelog.
Oct 10, 2024
19c7d42
Reverse condition.
Oct 10, 2024
b29f015
Fix condition.
Oct 10, 2024
81c57c6
Fix condition.
Oct 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Changelog

## Unreleased
* Aqua log readability update and whitelisting mechanism fix ([#1161](https://github.com/opendevstack/ods-jenkins-shared-library/pull/1161))
* Aqua remotely exploitable critical vulnerabilities improvements ([#1157](https://github.com/opendevstack/ods-jenkins-shared-library/pull/1157))
* Fail builds when aqua scan detects remotely exploitable security vulnerabilities with solutions ([#1147](https://github.com/opendevstack/ods-jenkins-shared-library/pull/1147))
* Fail the release manager pipeline and create security vulnerability issues or move them to TODO state if already present ([#1151](https://github.com/opendevstack/ods-jenkins-shared-library/pull/1151))

### Added
* In the release manager pipeline, use the default integration branch for component ([#1144](https://github.com/opendevstack/ods-jenkins-shared-library/pull/1144))
* In the release manager pipeline, use the default integration branch for component ([#1144](https://github.com/opendevstack/ods-jenkins-shared-library/pull/1144))

### Changed
* Enhance SSDS Document Generation Performance using New Atlassian APIs ([#1084](https://github.com/opendevstack/ods-jenkins-shared-library/issues/1084))
Expand Down
10 changes: 9 additions & 1 deletion src/org/ods/component/Context.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,11 @@ class Context implements IContext {

logger.debug 'Retrieving Git information ...'
config.gitUrl = retrieveGitUrl()
logger.debug("Retrieved Git Url: ${config.gitUrl}")
config.gitBranch = retrieveGitBranch()
logger.debug("Retrieved Git Branch: ${config.gitBranch}")
config.gitCommit = retrieveGitCommit()
logger.debug("Retrieved Git Commit: ${config.gitCommit}")
config.gitCommitAuthor = retrieveGitCommitAuthor()
config.gitCommitMessage = retrieveGitCommitMessage()
config.gitCommitRawMessage = retrieveGitCommitRawMessage()
Expand Down Expand Up @@ -708,8 +711,13 @@ class Context implements IContext {
// in case code is already checked out, OpenShift build config can not be used for retrieving branch
branch = script.sh(
returnStdout: true,
script: 'git branch --show-current',
script: 'git rev-parse --abbrev-ref HEAD',
label: 'getting GIT branch to build').trim()
branch = script.sh(
returnStdout: true,
script: "git name-rev --name-only --exclude=tags/* ${branch} | cut -d ' ' -f2 |" +
" sed -e 's|remotes/origin/||g'",
label: 'resolving to real GIT branch to build').trim()
}
logger.debug "resolved branch ${branch}"
return branch
Expand Down
2 changes: 1 addition & 1 deletion src/org/ods/component/HelmDeploymentStrategy.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class HelmDeploymentStrategy extends AbstractDeploymentStrategy {
'helmValuesFiles': options.helmValuesFiles,
'helmValues': options.helmValues,
'helmDefaultFlags': options.helmDefaultFlags,
'helmAdditionalFlags': options.helmAdditionalFlags
'helmAdditionalFlags': options.helmAdditionalFlags,
])
rolloutData["${resourceKind}/${resourceName}"] = podData
// TODO: Once the orchestration pipeline can deal with multiple replicas,
Expand Down
2 changes: 1 addition & 1 deletion src/org/ods/component/Pipeline.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class Pipeline implements Serializable {
script.stage('odsPipeline error') {
logger.warnClocked("${context.componentId}",
"***** Finished ODS Pipeline for ${context.componentId} (with error) *****")
logger.warn "Error: ${err}"
logger.error "${err}"
updateBuildStatus('FAILURE')
setBitbucketBuildStatus('FAILED')
if (err instanceof TailorDeploymentException) {
Expand Down
79 changes: 55 additions & 24 deletions src/org/ods/component/ScanWithAquaStage.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class ScanWithAquaStage extends Stage {
private final OpenShiftService openShift
private final NexusService nexus
private final ScanWithAquaOptions options
private Map configurationAquaCluster
private Map configurationAquaProject
private final Map configurationAquaCluster
private final Map configurationAquaProject

@SuppressWarnings('ParameterCount')
@TypeChecked(TypeCheckingMode.SKIP)
Expand Down Expand Up @@ -113,7 +113,12 @@ class ScanWithAquaStage extends Stage {
try {
def resultInfo = steps.readJSON(text: steps.readFile(file: jsonFile) as String) as Map

actionableVulnerabilities = filterRemoteCriticalWithSolutionVulnerabilities(resultInfo);
List whitelistedRECVs = []
actionableVulnerabilities = filterRemoteCriticalWithSolutionVulnerabilities(resultInfo,
whitelistedRECVs)
if (whitelistedRECVs.size() > 0) {
logger.warn(buildWhiteListedRECVsMessage(whitelistedRECVs))
}

Map vulnerabilities = resultInfo.vulnerability_summary as Map
// returnCode is 0 --> Success or 4 --> Error policies
Expand All @@ -138,41 +143,54 @@ class ScanWithAquaStage extends Stage {
notifyAquaProblem(alertEmails, errorMessages)

if (actionableVulnerabilities?.size() > 0) { // We need to mark the pipeline and delete the image
addAquaVulnerabilityObjectsToContext(actionableVulnerabilities, nexusReportLink)
String response = openShift.deleteImage(context.getComponentId() + ":" + context.getShortGitCommit())
logger.info("Delete image response: " + response)
throw new AquaRemoteCriticalVulnerabilityWithSolutionException(
buildActionableMessageForAquaVulnerabilities(actionableVulnerabilities: actionableVulnerabilities,
nexusReportLink: nexusReportLink, gitUrl: context.getGitUrl(), gitBranch: context.getGitBranch(),
gitCommit: context.getGitCommit(), repoName: context.getRepoName()))
performActionsForRECVs(actionableVulnerabilities, nexusReportLink)
}

return
}

private void addAquaVulnerabilityObjectsToContext(List actionableVulnerabilities, String nexusReportLink) {
private void performActionsForRECVs(List actionableVulnerabilities, String nexusReportLink) {
def scannedBranch = computeScannedBranch()
addAquaVulnerabilityObjectsToContext(actionableVulnerabilities, nexusReportLink, scannedBranch)
String response = openShift.deleteImage(context.getComponentId() + ":" + context.getShortGitCommit())
logger.info("Delete image response: " + response)
throw new AquaRemoteCriticalVulnerabilityWithSolutionException(
buildActionableMessageForAquaVulnerabilities(actionableVulnerabilities: actionableVulnerabilities,
nexusReportLink: nexusReportLink, gitUrl: context.getGitUrl(), gitBranch: scannedBranch,
gitCommit: context.getGitCommit(), repoName: context.getRepoName()))
}

private void addAquaVulnerabilityObjectsToContext(List actionableVulnerabilities, String nexusReportLink,
String scannedBranch) {
context.addArtifactURI('aquaCriticalVulnerability', actionableVulnerabilities)
context.addArtifactURI('jiraComponentId', context.getComponentId())
context.addArtifactURI('gitUrl', context.getGitUrl())
context.addArtifactURI('gitBranch', context.getGitBranch())
context.addArtifactURI('gitBranch', scannedBranch)
context.addArtifactURI('repoName', context.getRepoName())
context.addArtifactURI('nexusReportLink', nexusReportLink)
}

private String buildWhiteListedRECVsMessage(List whiteListedRECVs) {
StringBuilder message = new StringBuilder("The Aqua scan detected the following remotely " +
"exploitable critical vulnerabilities which were whitelisted in Aqua: ")
message.append(whiteListedRECVs.join(", "))
return message.toString()
}

private String buildActionableMessageForAquaVulnerabilities(Map args) {
StringBuilder message = new StringBuilder();
StringBuilder message = new StringBuilder()
String gitBranchUrl = GitUtil.buildGitBranchUrl(args.gitUrl as String, context.getProjectId(),
args.repoName as String, args.gitBranch as String)
message.append("We detected remotely exploitable critical vulnerabilities in repository ${gitBranchUrl}. " +
"Due to their high severity, we must stop the delivery " +
"process until all vulnerabilities have been addressed. ")

message.append("\n\nThe following vulnerabilities were found:\n");
def count= 1;
message.append("\n\nThe following vulnerabilities were found:")
def count = 1
for (def vulnerability : args.actionableVulnerabilities) {
message.append("\n${count}. Vulnerability name: " + (vulnerability as Map).name as String)
message.append("\n${count}.1. Description: " + (vulnerability as Map).description as String)
message.append("\n${count}.2. Solution: " + (vulnerability as Map).solution as String)
message.append("\n\n${count}. Vulnerability name: " + (vulnerability as Map).name as String)
message.append("\n\n${count}.1. Description: " + (vulnerability as Map).description as String)
message.append("\n\n${count}.2. Solution: " + (vulnerability as Map).solution as String)
message.append("\n")
count++
}
Expand All @@ -181,8 +199,8 @@ class ScanWithAquaStage extends Stage {
message.append("\nThis commit exists in the following open pull requests: ")
def cnt = 1
for (def pr : openPRs) {
message.append("\n${cnt}. Pull request: " + (pr as Map).title as String)
message.append("\n${cnt}.1. Link: " + (pr as Map).link as String)
message.append("\n\n${cnt}. Pull request: " + (pr as Map).title as String)
message.append("\n\n${cnt}.1. Link: " + (pr as Map).link as String)
message.append("\n")
cnt++
}
Expand Down Expand Up @@ -214,7 +232,7 @@ class ScanWithAquaStage extends Stage {
}
response.add([
title: pr.title,
link: (((pr.links as Map).self as List)[0] as Map).href
link: (((pr.links as Map).self as List)[0] as Map).href,
])
}
response
Expand Down Expand Up @@ -298,7 +316,7 @@ class ScanWithAquaStage extends Stage {
}
((List) data.messages).add([
title: "Blocking",
value: "Yes"
value: "Yes",
])
}

Expand Down Expand Up @@ -388,18 +406,31 @@ class ScanWithAquaStage extends Stage {
}
}

private List filterRemoteCriticalWithSolutionVulnerabilities(Map aquaJsonMap) {
private List filterRemoteCriticalWithSolutionVulnerabilities(Map aquaJsonMap, List whitelistedRECVs) {
List result = []
aquaJsonMap.resources.each { it ->
(it as Map).vulnerabilities.each { vul ->
Map vulnerability = vul as Map
if ((vulnerability?.exploit_type as String)?.equalsIgnoreCase(REMOTE_EXPLOIT_TYPE)
&& (vulnerability?.aqua_severity as String)?.equalsIgnoreCase(CRITICAL_AQUA_SEVERITY)
&& !StringUtils.isEmpty((vulnerability?.solution as String).trim())) {
result.push(vulnerability)
if (!!vulnerability?.already_acknowledged) {
valituguran marked this conversation as resolved.
Show resolved Hide resolved
whitelistedRECVs.add(vulnerability.name)
} else {
result.push(vulnerability)
}
}
}
}
return result
}

private String computeScannedBranch() {
def scannedBranch = context.getGitBranch()
if (scannedBranch.toLowerCase().startsWith("release/")) { // We scanned the default integration branch
scannedBranch = bitbucket.getDefaultBranch(context.getRepoName())
}
return scannedBranch
}

}
4 changes: 2 additions & 2 deletions src/org/ods/orchestration/BuildStage.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class BuildStage extends Stage {

def aquaCriticalVulnerabilityRepos = filterReposWithAquaCriticalVulnerability(repos)
if (aquaCriticalVulnerabilityRepos?.size() > 0) {
def securityVulnerabilityIssueKeys = project.jiraUseCase?.
Set securityVulnerabilityIssueKeys = project.jiraUseCase?.
createSecurityVulnerabilityIssues(aquaCriticalVulnerabilityRepos)
String aquaMessage = buildAquaSecurityVulnerabilityMessage(securityVulnerabilityIssueKeys)
logMessage += aquaMessage
Expand All @@ -123,7 +123,7 @@ class BuildStage extends Stage {
}
}

String buildAquaSecurityVulnerabilityMessage(List securityVulnerabilityIssueKeys) {
String buildAquaSecurityVulnerabilityMessage(Set securityVulnerabilityIssueKeys) {
if (securityVulnerabilityIssueKeys == null || securityVulnerabilityIssueKeys.size() == 0) {
// No issue created as Jira is not connected
return "\n\nRemotely exploitable critical vulnerabilities were detected (see above). " +
Expand Down
47 changes: 24 additions & 23 deletions src/org/ods/orchestration/service/JiraService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -227,33 +227,34 @@ class JiraService {
throw new IllegalArgumentException('Error: unable to create Jira issue. \'description\' is undefined.')
}

def request = [
fields: [
project: [
key: args.projectKey.toUpperCase()
],
summary: args.summary,
description: args.description,
fixVersions: [
[name: args.fixVersion]
],
issuetype: [
name: args.type
]
]
]

if (args.component) {
request.fields << [components: [[name: args.component]]]
}
if (args.priority) {
request.fields << [priority: [name: args.priority]]
}

def response = Unirest.post("${this.baseURL}/rest/api/2/issue")
.basicAuth(this.username, this.password)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.body(JsonOutput.toJson(
[
fields: [
project: [
key: args.projectKey.toUpperCase()
],
summary: args.summary,
description: args.description,
components: [
[name: args.component]
],
priority: [
name: args.priority
],
fixVersions: [
[name: args.fixVersion]
],
issuetype: [
name: args.type
]
]
]
))
.body(JsonOutput.toJson(request))
.asString()

response.ifSuccess {
Expand Down
Loading