Skip to content

Commit

Permalink
Check contract-priority Jira vulnerability issue in advisory
Browse files Browse the repository at this point in the history
Check advisory for JIRA issues that have:
1. Vulnerability type
2. "contract-priority" value in special handling field

JIRA: CWFHEALTH-2892
  • Loading branch information
qixiang committed Jan 20, 2025
1 parent 98cb86b commit 9db2f75
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 117 deletions.
10 changes: 10 additions & 0 deletions freshmaker/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,16 @@ class Config(object):
"default": "",
"desc": "URL to a remote file containing image repositories enabled for rebuilding due to compliance priority CVEs",
},
"jira_server_url": {
"type": str,
"default": "https://issues.redhat.com",
"desc": "The JIRA server url",
},
"jira_token": {
"type": str,
"default": "",
"desc": "A string of the token necessary for JIRA PAT bearer token authorization",
},
}

def __init__(self, conf_section_obj):
Expand Down
123 changes: 54 additions & 69 deletions freshmaker/errata.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
# Written by Jan Kaluza <jkaluza@redhat.com>

import os
import re
import requests
import dogpile.cache
from requests_kerberos import HTTPKerberosAuth, OPTIONAL
from jira import JIRA

from freshmaker.events import BrewSignRPMEvent, ErrataBaseEvent, FreshmakerManualRebuildEvent
from freshmaker import conf, log
Expand All @@ -47,8 +47,9 @@ def __init__(
product_short_name=None,
release_name=None,
cve_list=None,
is_major_incident=None,
is_compliance_priority=None,
is_major_incident=False,
is_compliance_priority=False,
is_contract_priority=False,
):
"""
Initializes the ErrataAdvisory instance.
Expand All @@ -63,6 +64,7 @@ def __init__(
self.cve_list = cve_list or []
self.is_major_incident = is_major_incident
self.is_compliance_priority = is_compliance_priority
self.is_contract_priority = is_contract_priority

self._affected_rpm_nvrs = None
self._reporter = ""
Expand Down Expand Up @@ -120,20 +122,9 @@ def from_advisory_id(cls, errata, errata_id):
# rebuilds for artifacts.
security_impact = erratum_data["security_impact"].lower()

has_hightouch_bug = False
has_compliance_priority_bug = False
bugs = errata._get_bugs(erratum_data["id"]) or []

has_hightouch_bug = any(["hightouch+" in bug.get("flags", "") for bug in bugs])
has_compliance_priority_bug = any(
["compliance_priority+" in bug.get("flags", "") for bug in bugs]
)

has_jira_major_incident = errata.has_jira_major_incidents(errata_id)
is_major_incident = has_hightouch_bug or has_jira_major_incident

has_jira_compliance_priority = errata.has_compliance_priority_jira_label(errata_id)
is_compliance_priority = has_compliance_priority_bug or has_jira_compliance_priority
is_major_incident = errata.is_major_incident_advisory(errata_id)
is_compliance_priority = errata.is_compliance_priority_advisory(errata_id)
is_contract_priority = errata.is_contract_priority_advisory(errata_id)

return ErrataAdvisory(
erratum_data["id"],
Expand All @@ -146,6 +137,7 @@ def from_advisory_id(cls, errata, errata_id):
cve_list,
is_major_incident,
is_compliance_priority,
is_contract_priority,
)

def is_flatpak_module_advisory_ready(self):
Expand Down Expand Up @@ -534,56 +526,49 @@ def is_zstream(self, errata_id):
release = self._get_release(errata_id)
return release["data"]["attributes"]["type"] == "Zstream"

def has_jira_major_incidents(self, errata_id: str) -> bool:
"""
Checks if this errata has a 'major incident' issue in JIRA
:param errata_id: The ID of the errata advisory
:type errata_id: str
:return: Wether the errata has or not a major incident issue in JIRA
:rtype: bool
"""
resp = self._get_jira_issues(errata_id=errata_id)

if isinstance(resp, dict) and resp.get("error", False):
log.info(
f"Error when querying for Jira issues for advisory {errata_id}: {resp['error']}"
)
return False

mi_pattern = re.compile(r"major\s*incident", re.IGNORECASE)

for issue in resp:
if mi_pattern.search(issue["summary"]):
log.info(f"Found 'major incident' issue for advisory {errata_id}: {issue['key']}")
return True

return False

def has_compliance_priority_jira_label(self, errata_id) -> bool:
"""
Checks if this erratas has an issue in JIRA with 'compliance_priority' label.
:param errata_id: The ID of the errata advisory
:type errata_id: str
:return: Wether the errata has or not a compliance priority issue in JIRA
:rtype: bool
"""
resp = self._get_jira_issues(errata_id=errata_id)

if isinstance(resp, dict) and resp.get("error", False):
log.info(
f"Error when querying for Jira issues for advisory {errata_id}: {resp['error']}"
)
@retry(wait_on=Exception, logger=log)
def _check_jira_special_handling(self, issue_keys: list[str], handling_value: str) -> bool:
"""Check if any vulnerability issue has the specified special handling value."""
jira_server = JIRA(server=conf.jira_server_url, token_auth=conf.jira_token)
try:
for issue in issue_keys:
jira_issue = jira_server.issue(issue)
if jira_issue.fields.issuetype.name.lower() != "vulnerability":
continue
special_handling = getattr(jira_issue.fields, "customfield_12324753", []) or []
if handling_value in [x.value for x in special_handling]:
return True
return False

for issue in resp:
if "compliance-priority" in issue["labels"]:
log.info(
f"Found 'compliance-priority' label in issue {issue['key']} for advisory {errata_id}"
)
return True

return False
finally:
jira_server.close()

def is_major_incident_advisory(self, errata_id) -> bool:
"""Check if this advisory is a major incident advisory."""
# check if there is any "hightouch+" bug attached
bugs = self._get_bugs(errata_id)
if bugs and any(["hightouch+" in bug.get("flags", "") for bug in bugs]):
return True

# check if there is any "Major Incident" Jira Vulnerability issue attached
issues = self._get_jira_issues(errata_id)
issue_keys = [x["key"] for x in issues]
return self._check_jira_special_handling(issue_keys, "Major Incident")

def is_compliance_priority_advisory(self, errata_id) -> bool:
"""Check if this advisory is a compliance priority advisory."""
# check if there is any "compliance_priority+" bug attached
bugs = self._get_bugs(errata_id)
if bugs and any(["compliance_priority+" in bug.get("flags", "") for bug in bugs]):
return True

# check if there is any "compliance-priority" Jira Vulnerability issue attached
issues = self._get_jira_issues(errata_id)
issue_keys = [x["key"] for x in issues]
return self._check_jira_special_handling(issue_keys, "compliance-priority")

def is_contract_priority_advisory(self, errata_id) -> bool:
"""Check if this advisory is a contract priority advisory."""
# check if there is any "contract-priority" Jira Vulnerability issue attached
issues = self._get_jira_issues(errata_id)
issue_keys = [x["key"] for x in issues]
return self._check_jira_special_handling(issue_keys, "contract-priority")
1 change: 1 addition & 0 deletions requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Flask-Migrate
Flask-SQLAlchemy
gql[requests, aiohttp]
httplib2
jira
jsonformatter
kobo
koji
Expand Down
21 changes: 19 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ decorator==5.1.1
# gssapi
# moksha-common
defusedxml==0.7.1
# via -r requirements.in
# via
# -r requirements.in
# jira
dogpile-cache==1.2.2
# via -r requirements.in
fedmsg==1.1.7
Expand Down Expand Up @@ -98,6 +100,8 @@ itsdangerous==2.1.2
# via flask
jinja2==3.1.2
# via flask
jira==3.8.0
# via -r requirements.in
jsonformatter==0.3.2
# via -r requirements.in
kitchen==1.2.6
Expand Down Expand Up @@ -136,14 +140,20 @@ munch==4.0.0
# python-fedora
mypy-extensions==1.0.0
# via -r requirements.in
oauthlib==3.2.2
# via requests-oauthlib
odcs[client]==0.7.0
# via -r requirements.in
openidc-client==0.6.0
# via
# odcs
# python-fedora
packaging==24.2
# via jira
pbr==6.0.0
# via stevedore
pillow==11.1.0
# via jira
prometheus-client==0.19.0
# via -r requirements.in
psutil==5.9.6
Expand Down Expand Up @@ -196,21 +206,27 @@ requests==2.31.0
# -r requirements.in
# fedmsg
# gql
# jira
# koji
# odcs
# openidc-client
# python-fedora
# requests-gssapi
# requests-kerberos
# requests-oauthlib
# requests-toolbelt
requests-gssapi==1.2.3
# via
# koji
# odcs
requests-kerberos==0.14.0
# via -r requirements.in
requests-oauthlib==2.0.0
# via jira
requests-toolbelt==1.0.0
# via gql
# via
# gql
# jira
rpm==0.1.0
# via -r requirements.in
semver==2.13.0
Expand Down Expand Up @@ -248,6 +264,7 @@ types-python-dateutil==2.8.19.14
typing-extensions==4.9.0
# via
# alembic
# jira
# twisted
urllib3==2.1.0
# via
Expand Down
Loading

0 comments on commit 9db2f75

Please sign in to comment.