-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support get a product's release' all tasks from Product Pages
1. Created an client to connect to PP for release api 2. Updated README on some command and links 3. Rename customize logging class, otherwise it confused with internal logging class 4. Adding Tests(WIP) JIRA: RHELWF-10975
- Loading branch information
Lu Zhang
committed
Jun 11, 2024
1 parent
a2c1106
commit 347a833
Showing
13 changed files
with
653 additions
and
24 deletions.
There are no files selected for viewing
This file contains 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 |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
/.mypy_cache | ||
/.ruff_cache | ||
/.tox | ||
__pycache__/ |
This file contains 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
This file contains 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
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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
This file contains 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
This file contains 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,9 @@ | ||
""" | ||
Constants Values | ||
""" | ||
|
||
# Product Pages | ||
PP_REST = "https://pp.engineering.redhat.com/api/latest/" | ||
# rhel_av and rhscl will be discontinued | ||
SUPPORTED_PRODUCTES = ["rhel", "cs", "directory", "dts", "dotnet", "rhel_av", "rhscl"] | ||
UNSUPPORTED_PHASE_ID = 1000 |
This file contains 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,165 @@ | ||
# SPDX-License-Identifier: GPL-3.0-or-later | ||
""" | ||
Production Pages API | ||
""" | ||
|
||
from functools import lru_cache | ||
from retasc import requests_session | ||
from retasc import constants | ||
|
||
_no_auth_session = requests_session.requests_session() | ||
|
||
|
||
class ProductPagesApi: | ||
""" | ||
Product Pages API Client | ||
""" | ||
|
||
pp_release_url = constants.PP_REST + "releases/" | ||
|
||
@lru_cache(maxsize=None) | ||
@staticmethod | ||
def releases_by_product_phase( | ||
product_shortname: str, | ||
active_only: bool = True, | ||
fields: str = "shortname,product_shortname,ga_date,phase_display", | ||
) -> list[dict]: | ||
""" | ||
https://{pp_release_url}?product__shortname={product_shortname}&phase__lt=1000&fields=a,b,c | ||
The response have the following fields:shortname,product_shortname,ga_date,phase_display | ||
phase id 1000 is unsupported, `lt` is less than | ||
""" | ||
print(ProductPagesApi.pp_release_url) | ||
opt = { | ||
"product__shortname": product_shortname, | ||
"fields": fields, | ||
} | ||
if active_only is True: | ||
opt.update({"phase__lt": constants.UNSUPPORTED_PHASE_ID}) | ||
res = _no_auth_session.get(ProductPagesApi.pp_release_url, params=opt) | ||
return res.json() | ||
|
||
@lru_cache(maxsize=None) | ||
@staticmethod | ||
def release_schedules( | ||
release_short_name: str, | ||
fields: str = "name,date_start,date_finish,flags", | ||
) -> list[dict]: | ||
""" | ||
https://{pp_release_url}{release_short_name}/schedule-tasks?fields=a,b,c | ||
The response have the following fields:name,,date_start,date_finish,flags | ||
""" | ||
res = _no_auth_session.get( | ||
f"{ProductPagesApi.pp_release_url}{release_short_name}/schedule-tasks/", | ||
params={ | ||
"fields": fields, | ||
}, | ||
) | ||
return res.json() | ||
|
||
@lru_cache(maxsize=None) | ||
@staticmethod | ||
def release_schedules_by_flags( | ||
release_short_name: str, | ||
flag_cond: str = "flags_or__in", | ||
flags: str = "rcm,releng,exd,sp", | ||
fields: str = "release_shortname,name,date_start,date_finish", | ||
) -> list[dict]: | ||
""" | ||
https://{pp_release_url}{release_short_name}/schedule-tasks/?{flag_cond}={flags}&fields=a,b,c | ||
Only one flag in condition use `flags_in=sp` | ||
Multiple flags in OR condition use `flags_or__in=sp,rcm,releng` | ||
Multiple flags in AND condition use `flags_and__in=sp,ga` | ||
The response have the following fields:release_shortname,name,slug,date_start,date_finish | ||
""" | ||
res = _no_auth_session.get( | ||
f"{ProductPagesApi.pp_release_url}{release_short_name}/schedule-tasks/", | ||
params={ | ||
flag_cond: flags, | ||
"fields": fields, | ||
}, | ||
) | ||
return res.json() | ||
|
||
@lru_cache(maxsize=None) | ||
@staticmethod | ||
def product_releases( | ||
product_shortname: str, | ||
fields: str = "phase_display,product_shortname,id,name,shortname,ga_date", | ||
) -> list[dict]: | ||
""" | ||
https://{pp_release_url}?product__shortname={product_shortname}&fields=a,b,c | ||
The response have the following fields:phase_display,product_shortname,id,name,shortname,ga_date | ||
A similar url https://pp.engineering.redhat.com/api/v7/products/rhel/?fields=releases | ||
but with less info in reponse | ||
""" | ||
res = _no_auth_session.get( | ||
ProductPagesApi.pp_release_url, | ||
params={ | ||
"product__shortname": product_shortname, | ||
"fields": fields, | ||
}, | ||
) | ||
return res.json() | ||
|
||
@lru_cache(maxsize=None) | ||
@staticmethod | ||
def release_schedules_by_name_search( | ||
release_short_name: str, | ||
condition: str, | ||
fields: str = "release_shortname,name,slug,date_start,date_finish", | ||
) -> list[dict]: | ||
""" | ||
https://{pp_release_url}{release_short_name}/schedule-tasks/?{flag_cond}={flags}&fields=a,b,c | ||
Only one flag in condition use `flags_in=sp` | ||
Multiple flags in OR condition use `flags_or__in=sp,rcm,releng` | ||
Multiple flags in AND condition use `flags_and__in=sp,ga` | ||
The response have the following fields:release_shortname,name,slug,date_start,date_finish | ||
""" | ||
res = _no_auth_session.get( | ||
f"{ProductPagesApi.pp_release_url}{release_short_name}/schedule-tasks/", | ||
params={ | ||
"name__regex": condition, | ||
"fields": fields, | ||
}, | ||
) | ||
return res.json() | ||
|
||
@lru_cache(maxsize=None) | ||
@staticmethod | ||
def get_all_active_releases_tasks_for_product(product_shortname: str) -> dict: | ||
""" | ||
Get all release names that are still supported by rest api: | ||
https://{pp_release_url}?product__shortname={product_shortname}&phase__lt=1000&fields=shortname | ||
Loop through the releases and get the tasks of it by rest api | ||
https://{pp_release_url}{release_short_name}/schedule-tasks/fields=name,slug,date_start,date_finish | ||
""" | ||
|
||
product_shortname = product_shortname.strip() | ||
if product_shortname not in constants.SUPPORTED_PRODUCTES: | ||
raise ValueError( | ||
f"Product - {product_shortname} is not supported yet. The products we supported currently are {constants.SUPPORTED_PRODUCTES}" | ||
) | ||
|
||
releases_list = ProductPagesApi.releases_by_product_phase( | ||
product_shortname, True | ||
) | ||
all_tasks = {} | ||
all_tasks[product_shortname] = {} | ||
for r in releases_list: | ||
r_name = r["shortname"] | ||
r_tasks = ProductPagesApi.release_schedules(r_name) | ||
all_tasks[product_shortname][r_name] = r_tasks | ||
# { | ||
# "rhscl": | ||
# {"rhscl-3-8": [ | ||
# { | ||
# "name": "Planning Phase", | ||
# "date_start": "2021-03-08", | ||
# "date_finish": "2021-05-10", | ||
# "flags": [ | ||
# "phase" | ||
# ] | ||
# },]} | ||
# } | ||
return all_tasks |
This file contains 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,28 @@ | ||
# SPDX-License-Identifier: GPL-3.0-or-later | ||
""" | ||
Http Reuqest client with retry and kerberos capabilities | ||
""" | ||
|
||
import requests | ||
from requests.adapters import HTTPAdapter | ||
from urllib3.util.retry import Retry | ||
|
||
|
||
def requests_session(): | ||
"""Returns http(s) session for request processing.""" | ||
|
||
session = requests.Session() | ||
retry = Retry( | ||
total=3, | ||
read=3, | ||
connect=3, | ||
backoff_factor=1, | ||
status_forcelist=(500, 502, 503, 504), | ||
allowed_methods=Retry.DEFAULT_ALLOWED_METHODS.union(("POST",)), | ||
) | ||
adapter = HTTPAdapter(max_retries=retry) | ||
session.mount("http://", adapter) | ||
session.mount("https://", adapter) | ||
session.headers["User-Agent"] = "sp-retasc-agent" | ||
session.headers["Content-type"] = "application/json" | ||
return session |
File renamed without changes.
This file contains 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
Empty file.
This file contains 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,15 @@ | ||
# SPDX-License-Identifier: GPL-3.0+ | ||
from unittest.mock import Mock, patch | ||
|
||
from retasc.requests_session import requests_session | ||
|
||
@patch("retasc.requests_session.requests.get") | ||
def test_requests_session(mock_get): | ||
body = {"text": "Hello, World!"} | ||
mock_get.return_value = Mock(ok=True) | ||
mock_get.return_value.json.return_value = body | ||
|
||
session = requests_session() | ||
response = session.get("http://example.com/api") | ||
|
||
assert response.status_code == 200 |