From 01b9b2e5ed6ec12d325114308e6e2b5d08d70516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Forr=C3=B3?= Date: Wed, 20 Nov 2024 14:38:47 +0100 Subject: [PATCH] Add API endpoints for Koji tagging requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nikola Forró --- packit_service/service/api/__init__.py | 2 + .../service/api/koji_tag_requests.py | 124 ++++++++++++++++++ tests_openshift/service/test_api.py | 30 +++++ 3 files changed, 156 insertions(+) create mode 100644 packit_service/service/api/koji_tag_requests.py diff --git a/packit_service/service/api/__init__.py b/packit_service/service/api/__init__.py index 0663bcbfc..b1e345e09 100644 --- a/packit_service/service/api/__init__.py +++ b/packit_service/service/api/__init__.py @@ -10,6 +10,7 @@ from packit_service.service.api.healthz import ns as healthz_ns from packit_service.service.api.installations import ns as installations_ns from packit_service.service.api.koji_builds import koji_builds_ns +from packit_service.service.api.koji_tag_requests import koji_tag_requests_ns from packit_service.service.api.osh_scans import ns as osh_scans_ns from packit_service.service.api.projects import ns as projects_ns from packit_service.service.api.propose_downstream import ns as propose_downstream_ns @@ -38,6 +39,7 @@ api.add_namespace(webhooks_ns) api.add_namespace(allowlist_ns) api.add_namespace(koji_builds_ns) +api.add_namespace(koji_tag_requests_ns) api.add_namespace(srpm_builds_ns) api.add_namespace(runs_ns) api.add_namespace(propose_downstream_ns) diff --git a/packit_service/service/api/koji_tag_requests.py b/packit_service/service/api/koji_tag_requests.py new file mode 100644 index 000000000..9d12c92e2 --- /dev/null +++ b/packit_service/service/api/koji_tag_requests.py @@ -0,0 +1,124 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT + +from http import HTTPStatus +from logging import getLogger + +from flask_restx import Namespace, Resource + +from packit_service.models import ( + KojiTagRequestGroupModel, + KojiTagRequestTargetModel, + optional_timestamp, +) +from packit_service.service.api.parsers import indices, pagination_arguments +from packit_service.service.api.utils import get_project_info_from_build, response_maker + +logger = getLogger("packit_service") + +koji_tag_requests_ns = Namespace("koji-tag-requests", description="Koji tagging requests") + + +@koji_tag_requests_ns.route("") +class KojiTagRequestsList(Resource): + @koji_tag_requests_ns.expect(pagination_arguments) + @koji_tag_requests_ns.response(HTTPStatus.PARTIAL_CONTENT, "Koji tagging requests list follows") + def get(self): + """List all Koji tagging requests.""" + first, last = indices() + result = [] + + for tag_request in KojiTagRequestTargetModel.get_range(first, last): + tag_request_dict = { + "packit_id": tag_request.id, + "task_id": tag_request.task_id, + "tag_request_submitted_time": optional_timestamp( + tag_request.tag_request_submitted_time + ), + "chroot": tag_request.target, + "sidetag": tag_request.sidetag, + "nvr": tag_request.nvr, + "web_url": tag_request.web_url, + "pr_id": tag_request.get_pr_id(), + "branch_name": tag_request.get_branch_name(), + "release": tag_request.get_release_tag(), + } + + if project := tag_request.get_project(): + tag_request_dict["project_url"] = project.project_url + tag_request_dict["repo_namespace"] = project.namespace + tag_request_dict["repo_name"] = project.repo_name + + result.append(tag_request_dict) + + resp = response_maker( + result, + status=HTTPStatus.PARTIAL_CONTENT, + ) + resp.headers["Content-Range"] = f"koji-tag-requests {first + 1}-{last}/*" + return resp + + +@koji_tag_requests_ns.route("/") +@koji_tag_requests_ns.param("id", "Packit id of the tagging request") +class KojiTagRequestItem(Resource): + @koji_tag_requests_ns.response(HTTPStatus.OK, "OK, koji tagging request details follow") + @koji_tag_requests_ns.response( + HTTPStatus.NOT_FOUND.value, + "No info about tagging request stored in DB", + ) + def get(self, id): + """A specific koji tagging request details.""" + tag_request = KojiTagRequestTargetModel.get_by_id(int(id)) + + if not tag_request: + return response_maker( + {"error": "No info about tagging request stored in DB"}, + status=HTTPStatus.NOT_FOUND, + ) + + tag_request_dict = { + "task_id": tag_request.task_id, + "chroot": tag_request.target, + "sidetag": tag_request.sidetag, + "nvr": tag_request.nvr, + "tag_request_submitted_time": optional_timestamp( + tag_request.tag_request_submitted_time + ), + "commit_sha": tag_request.commit_sha, + "web_url": tag_request.web_url, + "run_ids": sorted(run.id for run in tag_request.group_of_targets.runs), + } + + tag_request_dict.update(get_project_info_from_build(tag_request)) + return response_maker(tag_request_dict) + + +@koji_tag_requests_ns.route("/groups/") +@koji_tag_requests_ns.param("id", "Packit id of the koji tagging request group") +class KojiTagRequestGroup(Resource): + @koji_tag_requests_ns.response(HTTPStatus.OK, "OK, koji tagging request group details follow") + @koji_tag_requests_ns.response( + HTTPStatus.NOT_FOUND.value, + "No info about koji tagging request group stored in DB", + ) + def get(self, id): + """A specific test run details.""" + group_model = KojiTagRequestGroupModel.get_by_id(int(id)) + + if not group_model: + return response_maker( + {"error": "No info about group stored in DB"}, + status=HTTPStatus.NOT_FOUND, + ) + + group_dict = { + "submitted_time": optional_timestamp(group_model.submitted_time), + "run_ids": sorted(run.id for run in group_model.runs), + "tag_request_target_ids": sorted( + tag_request.id for tag_request in group_model.grouped_targets + ), + } + + group_dict.update(get_project_info_from_build(group_model)) + return response_maker(group_dict) diff --git a/tests_openshift/service/test_api.py b/tests_openshift/service/test_api.py index e972ced56..c72cd5416 100644 --- a/tests_openshift/service/test_api.py +++ b/tests_openshift/service/test_api.py @@ -991,3 +991,33 @@ def test_scans_list( response_dict = response.json assert len(response_dict) == 1 + + +def test_koji_tag_request_info( + client, + clean_before_and_after, + a_koji_tag_request, +): + response = client.get( + url_for("api.koji-tag-requests_koji_tag_request_item", id=a_koji_tag_request.id), + ) + response_dict = response.json + assert response_dict["task_id"] == SampleValues.build_id + assert response_dict["web_url"] == SampleValues.koji_web_url + assert response_dict["chroot"] == SampleValues.target + assert response_dict["sidetag"] == SampleValues.sidetag + assert response_dict["nvr"] == SampleValues.nvr + assert response_dict["repo_namespace"] == SampleValues.repo_namespace + assert response_dict["repo_name"] == SampleValues.repo_name + assert response_dict["project_url"] == SampleValues.project_url + + +def test_koji_tag_requests_list( + client, + clean_before_and_after, + a_koji_tag_request, +): + response = client.get(url_for("api.koji-tag-requests_koji_tag_requests_list")) + response_dict = response.json + + assert len(response_dict) == 1