Skip to content

Commit

Permalink
Expose scans via API
Browse files Browse the repository at this point in the history
  • Loading branch information
lbarcziova committed Oct 31, 2024
1 parent a1f9446 commit a9152b1
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 11 deletions.
10 changes: 10 additions & 0 deletions packit_service/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4091,6 +4091,16 @@ def get_by_task_id(cls, task_id: int) -> Optional["OSHScanModel"]:
with sa_session_transaction() as session:
return session.query(cls).filter_by(task_id=task_id).first()

@classmethod
def get_by_id(cls, id_: int) -> Optional["OSHScanModel"]:
with sa_session_transaction() as session:
return session.query(OSHScanModel).filter_by(id=id_).first()

@classmethod
def get_range(cls, first: int, last: int) -> Iterable["OSHScanModel"]:
with sa_session_transaction() as session:
return session.query(OSHScanModel).order_by(desc(OSHScanModel.id)).slice(first, last)


@cached(cache=TTLCache(maxsize=2048, ttl=(60 * 60 * 24)))
def get_usage_data(datetime_from=None, datetime_to=None, top=10) -> dict:
Expand Down
2 changes: 2 additions & 0 deletions packit_service/service/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.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
from packit_service.service.api.pull_from_upstream import ns as pull_from_upstream_ns
Expand Down Expand Up @@ -44,3 +45,4 @@
api.add_namespace(pull_from_upstream_ns)
api.add_namespace(system_ns)
api.add_namespace(bodhi_updates_ns)
api.add_namespace(osh_scans_ns)
85 changes: 85 additions & 0 deletions packit_service/service/api/osh_scans.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# 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 (
OSHScanModel,
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")

ns = Namespace("osh-scans", description="OpenScanHub scans")


@ns.route("")
class ScansList(Resource):
@ns.expect(pagination_arguments)
@ns.response(HTTPStatus.PARTIAL_CONTENT.value, "Scans list follows")
def get(self):
"""List all scans."""

first, last = indices()
result = []

for scan in OSHScanModel.get_range(first, last):
update_dict = {
"packit_id": scan.id,
"task_id": scan.task_id,
"status": scan.status,
"url": scan.url,
"issues_added_url": scan.issues_added_url,
"issues_fixed_url": scan.issues_fixed_url,
"scan_results_url": scan.scan_results_url,
"copr_build_target_id": scan.copr_build_target_id,
"submitted_time": optional_timestamp(scan.submitted_time),
}

if project := scan.copr_build_target.get_project():
update_dict["project_url"] = project.project_url
update_dict["repo_namespace"] = project.namespace
update_dict["repo_name"] = project.repo_name

result.append(update_dict)

resp = response_maker(
result,
status=HTTPStatus.PARTIAL_CONTENT,
)
resp.headers["Content-Range"] = f"osh-scans {first + 1}-{last}/*"
return resp


@ns.route("/<int:id>")
@ns.param("id", "Packit id of the scan")
class ScanItem(Resource):
@ns.response(HTTPStatus.OK.value, "OK, scan details follow")
@ns.response(HTTPStatus.NOT_FOUND.value, "Scan identifier not in db/hash")
def get(self, id):
"""A specific copr build details for one chroot."""
scan = OSHScanModel.get_by_id(int(id))
if not scan:
return response_maker(
{"error": "No info about scan stored in DB"},
status=HTTPStatus.NOT_FOUND,
)

scan_dict = {
"task_id": scan.task_id,
"status": scan.status,
"url": scan.url,
"issues_added_url": scan.issues_added_url,
"issues_fixed_url": scan.issues_fixed_url,
"scan_results_url": scan.scan_results_url,
"copr_build_target_id": scan.copr_build_target_id,
"submitted_time": optional_timestamp(scan.submitted_time),
}

scan_dict.update(get_project_info_from_build(scan.copr_build_target))
return response_maker(scan_dict)
21 changes: 15 additions & 6 deletions tests_openshift/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
KojiBuildGroupModel,
KojiBuildTargetModel,
OSHScanModel,
OSHScanStatus,
PipelineModel,
ProjectAuthenticationIssueModel,
ProjectEventModel,
Expand Down Expand Up @@ -164,6 +165,14 @@ class SampleValues:
anitya_project_id = 12345
anitya_project_name = "packit-anitya"

# scan
task_id = 123
scan_url = "https://scan-url"
issues_added_url = "https://issues-added-url"
issues_fixed_url = "https://issues-fixed-url"
scan_results_url = "https://scan-results-url"
scan_status_success = OSHScanStatus.succeeded


@pytest.fixture(scope="session", autouse=True)
def global_service_config():
Expand Down Expand Up @@ -2488,10 +2497,10 @@ def multiple_bodhi_update_runs(branch_project_event_model):

@pytest.fixture()
def a_scan(a_copr_build_for_pr):
scan = a_copr_build_for_pr.add_scan(123)
scan.status = "success"
scan.url = "task url"
scan.issues_added_url = "added issues"
scan.issues_fixed_url = "fixed issues"
scan.scan_results_url = "results"
scan = a_copr_build_for_pr.add_scan(SampleValues.task_id)
scan.status = SampleValues.scan_status_success
scan.url = SampleValues.scan_url
scan.issues_added_url = SampleValues.issues_added_url
scan.issues_fixed_url = SampleValues.issues_fixed_url
scan.scan_results_url = SampleValues.scan_results_url
yield scan
10 changes: 5 additions & 5 deletions tests_openshift/database/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1134,11 +1134,11 @@ def test_project_event_get_and_reset_older_than_with_packages_config(

def test_create_scan(clean_before_and_after, a_scan):
assert a_scan.task_id == 123
assert a_scan.status == "success"
assert a_scan.url == "task url"
assert a_scan.issues_added_url == "added issues"
assert a_scan.issues_fixed_url == "fixed issues"
assert a_scan.scan_results_url == "results"
assert a_scan.status == "succeeded"
assert a_scan.url == "https://scan-url"
assert a_scan.issues_added_url == "https://issues-added-url"
assert a_scan.issues_fixed_url == "https://issues-fixed-url"
assert a_scan.scan_results_url == "https://scan-results-url"
assert a_scan.copr_build_target.build_id == "123456"


Expand Down
31 changes: 31 additions & 0 deletions tests_openshift/service/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -959,3 +959,34 @@ def test_bodhi_update_info(
assert response_dict["repo_namespace"] == SampleValues.repo_namespace
assert response_dict["status"] == "error"
assert response_dict["submitted_time"] is not None


def test_scan_info(
client,
clean_before_and_after,
a_scan,
):
response = client.get(
url_for("api.osh-scans_scan_item", id=a_scan.id),
)
response_dict = response.json
assert response_dict["task_id"] == SampleValues.task_id
assert response_dict["url"] == SampleValues.scan_url
assert response_dict["status"] == SampleValues.scan_status_success
assert response_dict["issues_added_url"] == SampleValues.issues_added_url
assert response_dict["issues_fixed_url"] == SampleValues.issues_fixed_url
assert response_dict["scan_results_url"] == SampleValues.scan_results_url
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_scans_list(
client,
clean_before_and_after,
a_scan,
):
response = client.get(url_for("api.osh-scans_scans_list"))
response_dict = response.json

assert len(response_dict) == 1

0 comments on commit a9152b1

Please sign in to comment.