From ec3863903b67d3757750d1b876242bbe503556da Mon Sep 17 00:00:00 2001 From: Jakub Kadlcik Date: Mon, 24 Jun 2024 20:27:43 +0200 Subject: [PATCH] backend: add support for pulp domains The pulp.stage.devshift.net instance has domains enabled while our STG instance has them disabled. As long as it is easy to support both cases, I'd do that. --- backend/copr_backend/pulp.py | 32 ++++++++++++++++++++++++----- backend/tests/test_pulp.py | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 backend/tests/test_pulp.py diff --git a/backend/copr_backend/pulp.py b/backend/copr_backend/pulp.py index f3b2e9acc..aa5c64a67 100644 --- a/backend/copr_backend/pulp.py +++ b/backend/copr_backend/pulp.py @@ -5,7 +5,6 @@ import os import tomllib import requests -from six.moves.urllib.parse import urlencode class PulpClient: @@ -53,7 +52,20 @@ def url(self, endpoint): """ A fully qualified URL for a given API endpoint """ - return self.config["base_url"] + self.config["api_root"] + endpoint + domain = self.config["domain"] + if domain == "default": + domain = "" + + relative = os.path.normpath(os.path.join( + self.config["api_root"], + domain, + endpoint, + )) + + # Normpath removes the trailing slash. If it was there, put it back + if endpoint[-1] == "/": + relative += "/" + return self.config["base_url"] + relative @property def request_params(self): @@ -79,7 +91,7 @@ def get_repository(self, name): # There is no endpoint for querying a single repository by its name, # even Pulp CLI does this workaround url = self.url("api/v3/repositories/rpm/rpm/?") - url += urlencode({"name": name, "offset": 0, "limit": 1}) + url += self._urlencode({"name": name, "offset": 0, "limit": 1}) return requests.get(url, **self.request_params) def get_distribution(self, name): @@ -90,9 +102,19 @@ def get_distribution(self, name): # There is no endpoint for querying a single repository by its name, # even Pulp CLI does this workaround url = self.url("api/v3/distributions/rpm/rpm/?") - url += urlencode({"name": name, "offset": 0, "limit": 1}) + url += self._urlencode({"name": name, "offset": 0, "limit": 1}) return requests.get(url, **self.request_params) + def _urlencode(self, query): + """ + Join a dict into URL query string but don't encode special characters + https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode + Our repository names are e.g. frostyx/test-pulp/fedora-39-x86_64. + The standard urlencode would change the slashes to %2F making Pulp to + not find the project when filtering by name. + """ + return "&".join([f"{k}={v}" for k, v in query.items()]) + def create_distribution(self, name, repository, basepath=None): """ Create an RPM distribution @@ -111,7 +133,7 @@ def create_publication(self, repository): Create an RPM publication https://docs.pulpproject.org/pulp_rpm/restapi.html#tag/Publications:-Rpm/operation/publications_rpm_rpm_create """ - url = self.url("api/v3/publications/rpm/rpm") + url = self.url("api/v3/publications/rpm/rpm/") data = {"repository": repository} return requests.post(url, json=data, **self.request_params) diff --git a/backend/tests/test_pulp.py b/backend/tests/test_pulp.py new file mode 100644 index 000000000..e265f0501 --- /dev/null +++ b/backend/tests/test_pulp.py @@ -0,0 +1,39 @@ +""" +Test Pulp client +""" + +# pylint: disable=attribute-defined-outside-init + +from copr_backend.pulp import PulpClient + + +class TestPulp: + + def setup_method(self, _method): + self.config = { + "api_root": "/pulp/", + "base_url": "http://pulp.fpo:24817", + "cert": "", + "domain": "default", + "dry_run": False, + "format": "json", + "key": "", + "password": "1234", + "timeout": 0, + "username": "admin", + "verbose": 0, + "verify_ssl": True, + } + + def test_url(self): + client = PulpClient(self.config) + assert self.config["domain"] == "default" + assert client.url("api/v3/artifacts/")\ + == "http://pulp.fpo:24817/pulp/api/v3/artifacts/" + + assert client.url("api/v3/repositories/rpm/rpm/?")\ + == "http://pulp.fpo:24817/pulp/api/v3/repositories/rpm/rpm/?" + + self.config["domain"] = "copr" + assert client.url("api/v3/artifacts/")\ + == "http://pulp.fpo:24817/pulp/copr/api/v3/artifacts/"