-
Notifications
You must be signed in to change notification settings - Fork 216
USHIFT-5377: add script to generate a advisory, cves and jira tickets report #4576
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
Merged
Merged
Changes from 5 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
a1b903a
add script to generate a advisory, cves and jira tickets report to de…
agullon 8306fe4
replace double quotes with single quotes
agullon d81f1b3
add extra condition for jira query
agullon ffe8a7c
add README for OCP Advisory Publication Report
agullon 920c86e
few cosmetic changes
agullon 7500059
Update scripts/advisory_publication/README.md
agullon 48b5fc8
Update scripts/advisory_publication/README.md
agullon b0b3877
Update scripts/advisory_publication/README.md
agullon 350b342
Update scripts/advisory_publication/README.md
agullon 45871b9
Update scripts/advisory_publication/README.md
agullon 50dc326
Update scripts/advisory_publication/README.md
agullon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# OCP Advisory Publication Report | ||
|
||
## Description | ||
|
||
Every week for every OCP release MicroShift team decide if a new MicroShift version should be publish. | ||
The decision is done if there are important changes/fixes to the published. | ||
agullon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This script will generate a report with advisory, CVEs and jira ticket relevant info for every OCP version to make the decision. | ||
agullon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Steps | ||
1. Find advisory ids for a OCP version from [ocp-build-data repository](https://github.com/openshift-eng/ocp-build-data) | ||
- For example, for release `4.17` check [`releases.yml`](https://github.com/openshift-eng/ocp-build-data/blob/openshift-4.17/releases.yml) | ||
2. Get list of CVEs from a Red Hat advisory using [Red Hat errata API](https://errata.devel.redhat.com/documentation/developer-guide/api-http-api.html#get-cveshowerrata_id.json) | ||
agullon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Only available behind the Red Hat VPN | ||
- Example for [`144556` advisory](https://errata.devel.redhat.com/cve/show/144556.json) | ||
3. Query Jira to find if there are any MicroShift ticket to address a CVE fix | ||
agullon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Example for [`summary ~ "CVE-2024-21626" AND component = MicroShift and (affectedVersion = 4.17 or affectedVersion = 4.17.z)`](https://issues.redhat.com/issues/?jql=summary%20%20~%20%22CVE-2024-21626%22%20AND%20component%20%3D%20MicroShift%20and%20(affectedVersion%20%3D%204.17%20or%20affectedVersion%20%3D%204.17.z)) query | ||
agullon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Requisites | ||
|
||
### Jira API token | ||
|
||
Visit [the Profile page on the Jira | ||
Server](https://issues.redhat.com/secure/ViewProfile.jspa?selectedTab=com.atlassian.pats.pats-plugin:jira-user-personal-access-tokens) and create a token. | ||
|
||
Set the `JIRA_API_TOKEN` in your env: | ||
|
||
``` | ||
export JIRA_API_TOKEN="TOKEN_VALUE" | ||
``` | ||
|
||
### Connect to Red Hat VPN | ||
|
||
Red Hat VPN connection is mandatory to get info from Red Hat errata tool. | ||
|
||
## Generate report | ||
|
||
Run `./scripts/advisory_publication/advisory_publication_report.sh X.Y.Z` to generate json report. | ||
|
||
`X.Y.Z` is the target OCP version, for example `4.17.12` | ||
|
||
Output format: | ||
|
||
``` | ||
{ | ||
"RHSA-YYYY:NNNNN": { | ||
"type": "extras", | ||
"url": "https://errata.devel.redhat.com/advisory/XXXXX", | ||
"cves": { | ||
"CVE-YYYY-NNNN": {}, | ||
"CVE-YYYY-NNNN": {} | ||
} | ||
}, | ||
"RHSA-2025:0364": { | ||
"type": "image", | ||
"url": "https://errata.devel.redhat.com/advisory/YYYYY", | ||
"cves": { | ||
"CVE-YYYY-NNNN": {}, | ||
"CVE-YYYY-NNNN": { | ||
"jira_ticket": { | ||
"id": "OCPBUGS-MMMMM", | ||
"summary": "CVE-YYYY-NNNN title of the jira ticket", | ||
"status": "Closed", | ||
"resolution": "Not a Bug" | ||
} | ||
} | ||
} | ||
}, | ||
"RHSA-YYYY:NNNNN": { | ||
"type": "metadata", | ||
"url": "https://errata.devel.redhat.com/advisory/ZZZZZ", | ||
"cves": {} | ||
} | ||
} | ||
|
||
``` |
137 changes: 137 additions & 0 deletions
137
scripts/advisory_publication/advisory_publication_report.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import os | ||
import sys | ||
import jira.client | ||
import requests | ||
import urllib3 | ||
import json | ||
import jira | ||
import yaml | ||
|
||
SERVER_URL = 'https://issues.redhat.com/' | ||
JIRA_API_TOKEN = os.environ.get('JIRA_API_TOKEN') | ||
|
||
|
||
def usage(): | ||
print("""\ | ||
usage: advisory_publication_report.py OCP_VERSION | ||
|
||
arguments: | ||
OCP_VERSION: The OCP versions to analyse if MicroShift version should be published. Format: "4.X.Z"\ | ||
""") | ||
|
||
|
||
def get_advisories(ocp_version: str) -> dict[str, int]: | ||
""" | ||
Get a list of advisory ids for a OCP version from github.com/openshift-eng/ocp-build-data repository | ||
Parameters: | ||
ocp_version (str): OCP version with format: "X.Y.Z" | ||
Returns: | ||
(dict): advisory dict with type and id | ||
""" | ||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) | ||
|
||
try: | ||
microshift_xy_version = '.'.join(ocp_version.split('.')[:2]) | ||
request = requests.get(f'https://raw.githubusercontent.com/openshift-eng/ocp-build-data/refs/heads/openshift-{microshift_xy_version}/releases.yml', verify=False) | ||
request.raise_for_status() | ||
except requests.exceptions.HTTPError as err: | ||
raise SystemExit(err) | ||
releases_dict = yaml.load(str(request.text), Loader=yaml.SafeLoader) | ||
|
||
if ocp_version in releases_dict['releases']: | ||
return releases_dict['releases'][ocp_version]['assembly']['group']['advisories'] | ||
else: | ||
raise KeyError(f"{ocp_version} OCP version does NOT exist") | ||
|
||
|
||
def get_advisory_info(advisory_id: int) -> dict[str, str]: | ||
""" | ||
Get a list of strings with the CVEs ids for an advisory | ||
Parameters: | ||
advisory_id (int): advisory id | ||
Returns: | ||
(list): list of strings with CVE ids | ||
""" | ||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) | ||
|
||
try: | ||
request = requests.get(f'https://errata.devel.redhat.com/cve/show/{advisory_id}.json', verify=False) | ||
request.raise_for_status() | ||
except requests.exceptions.HTTPError as err: | ||
raise SystemExit(err) | ||
advisory_info = json.loads(request.text) | ||
|
||
if advisory_info is None: | ||
raise ValueError | ||
if not isinstance(advisory_info, dict): | ||
raise TypeError | ||
return advisory_info | ||
|
||
|
||
def search_microshift_tickets(affects_version: str, cve_id: str) -> jira.client.ResultList: | ||
""" | ||
Query Jira for MicroShift ticket with CVE id and MicroShift version | ||
Parameters: | ||
affects_version (str): MicroShift affected version with format: "X.Y" | ||
cve_id (str): the CVE id with format: "CVE-YYYY-NNNNN" | ||
Returns: | ||
(jira.client.ResultList): a list with all the Jira tickets matching the query | ||
""" | ||
server = jira.JIRA(server=SERVER_URL, token_auth=JIRA_API_TOKEN) | ||
jira_tickets = server.search_issues(f''' | ||
summary ~ "{cve_id}" and component = MicroShift and (affectedVersion = {affects_version} or affectedVersion = {affects_version}.z) | ||
''') | ||
|
||
if not isinstance(jira_tickets, jira.client.ResultList): | ||
raise TypeError | ||
return jira_tickets | ||
|
||
|
||
def get_report(ocp_version: str) -> dict[str, dict]: | ||
""" | ||
Get a json object with all the advisories, CVEs and jira tickets linked | ||
Parameters: | ||
ocp_version (str): OCP version with format: "X.Y.Z" | ||
Returns: | ||
(dict): json object with all the advisories, CVEs and jira tickets linked | ||
""" | ||
result_json = dict() | ||
advisories = get_advisories(ocp_version) | ||
for advisory_type, advisory_id in advisories.items(): | ||
advisory_info = get_advisory_info(advisory_id) | ||
cve_list = advisory_info['cve'] | ||
advisory_dict = dict() | ||
advisory_dict['type'] = advisory_type | ||
advisory_dict['url'] = f'https://errata.devel.redhat.com/advisory/{advisory_id}' | ||
advisory_dict['cves'] = dict() | ||
for cve in cve_list: | ||
jira_tickets = search_microshift_tickets(".".join(ocp_version.split(".")[:2]), cve) | ||
advisory_dict['cves'][cve] = dict() | ||
for ticket in jira_tickets: | ||
jira_ticket_dict = dict() | ||
jira_ticket_dict['id'] = ticket.key | ||
jira_ticket_dict['summary'] = ticket.fields.summary | ||
jira_ticket_dict['status'] = ticket.fields.status.name | ||
jira_ticket_dict['resolution'] = ticket.fields.resolution.name | ||
advisory_dict['cves'][cve]['jira_ticket'] = jira_ticket_dict | ||
result_json[advisory_info['advisory']] = advisory_dict | ||
return result_json | ||
|
||
|
||
def main(): | ||
if len(sys.argv) != 2: | ||
usage() | ||
raise ValueError('Invalid number of arguments') | ||
|
||
if JIRA_API_TOKEN is None: | ||
raise ValueError('JIRA_API_TOKEN var not found in the env') | ||
|
||
ocp_version = str(sys.argv[1]) | ||
result_json = get_report(ocp_version) | ||
print(f"{json.dumps(result_json, indent=4)}") | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
17 changes: 17 additions & 0 deletions
17
scripts/advisory_publication/advisory_publication_report.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/bin/bash | ||
|
||
set -e | ||
|
||
SCRIPTDIR="$(dirname "${BASH_SOURCE[0]}")" | ||
REPOROOT="$(git rev-parse --show-toplevel)" | ||
OUTPUT_DIR="${REPOROOT}/_output" | ||
ENVDIR="${OUTPUT_DIR}/advisory_publication" | ||
|
||
if [ ! -d "${ENVDIR}" ]; then | ||
echo "Setting up required tools..." | ||
mkdir -p "${OUTPUT_DIR}" | ||
python3 -m venv "${ENVDIR}" | ||
"${ENVDIR}/bin/pip3" install -r "${SCRIPTDIR}/requirements.txt" | ||
fi | ||
|
||
"${ENVDIR}/bin/python3" "${SCRIPTDIR}/advisory_publication_report.py" "$@" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
requests>=2.32.2 | ||
jira>=3.5.0 | ||
PyYAML>=6.0.2 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.