From 75e77c6abca530538dfe5151c360d338cc7396f5 Mon Sep 17 00:00:00 2001 From: Lubomir Gallovic Date: Tue, 29 Aug 2023 12:43:42 +0200 Subject: [PATCH 1/2] Add product name to ContainerImagePushItems This attribute will be added to the container security manifests when pushing to Quay. The value is gathered from a Errata HTTP query, so an Errata HTTP client is implemented as well. For registry source, the product name is provided directly as a parameter by pub. --- requirements.in | 1 + requirements.txt | 1 + .../errata_source/errata_http_client.py | 127 ++++++ .../backend/errata_source/errata_source.py | 26 +- .../_impl/backend/registry_source.py | 8 +- src/pushsource/_impl/model/container.py | 8 + test-requirements.in | 1 + test-requirements.txt | 12 +- .../cases/errata-containers-legacy-repos.yml | 68 ++++ tests/baseline/cases/errata-containers.yml | 68 ++++ .../cases/koji-operator-container.yml | 2 + .../baseline/cases/koji-source-container.yml | 1 + tests/baseline/test_baseline.py | 17 +- tests/conftest.py | 15 + tests/errata/data/RHBA-2020:2807.json | 362 ++++++++++++++++++ tests/errata/data/dump | 20 + tests/errata/test_errata_containers.py | 10 + tests/errata/test_errata_http_client.py | 219 +++++++++++ tests/test_registry.py | 3 + 19 files changed, 959 insertions(+), 10 deletions(-) create mode 100644 src/pushsource/_impl/backend/errata_source/errata_http_client.py create mode 100644 tests/errata/data/RHBA-2020:2807.json create mode 100644 tests/errata/test_errata_http_client.py diff --git a/requirements.in b/requirements.in index e94619e2..66469d5e 100644 --- a/requirements.in +++ b/requirements.in @@ -8,3 +8,4 @@ frozenlist2 python-dateutil kobo pytz; python_version < '3.9' +requests diff --git a/requirements.txt b/requirements.txt index e2ea5082..b2b0a294 100644 --- a/requirements.txt +++ b/requirements.txt @@ -252,6 +252,7 @@ requests==2.31.0 \ --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 # via + # -r requirements.in # koji # requests-gssapi requests-gssapi==1.2.3 \ diff --git a/src/pushsource/_impl/backend/errata_source/errata_http_client.py b/src/pushsource/_impl/backend/errata_source/errata_http_client.py new file mode 100644 index 00000000..905a3683 --- /dev/null +++ b/src/pushsource/_impl/backend/errata_source/errata_http_client.py @@ -0,0 +1,127 @@ +import os +import threading +import subprocess +import re +import logging +import tempfile +from urllib.parse import urljoin + +import requests +import gssapi +import requests_gssapi + +LOG = logging.getLogger("pushsource.errata_http_client") + +class ErrataHTTPClient: + """Class for performing HTTP API queries with Errata.""" + + def __init__(self, hostname: str, keytab_path: str = None, principal: str = None): + """ + Initialize. + + Args: + hostname (str): + Errata hostname. + keytab_path (str): + Path to a keytab used to perform Kerberos authentication with Errata. + If not set, env variable PUSHSOURCE_ERRATA_KEYTAB_PATH will be used. + principal (str): + Kerberos principal. + If not set, env variable PUSHSOURCE_ERRATA_PRINCIPAL will be used. + """ + self.hostname = hostname + # Generate a random filename for ccache + with tempfile.NamedTemporaryFile(prefix="ccache_pushsource_errata_", delete=False) as file: + self.ccache_filename = file.name + + if keytab_path: + self.keytab_path = keytab_path + else: + self.keytab_path = os.environ.get("PUSHSOURCE_ERRATA_KEYTAB_PATH", None) + + if principal: + self.principal = principal + else: + self.principal = os.environ.get("PUSHSOURCE_ERRATA_PRINCIPAL", None) + + # requests Sessions will be local per thread + self._thread_local = threading.local() + + def create_kerberos_ticket(self): + """ + Use the keytab to create a Kerberos ticket granting ticket. + + This method is expected to be called before any HTTP queries to errata are made. + """ + if not self.keytab_path or not self.principal: + LOG.warning("Errata principal or keytab path is not specified. Skipping creating TGT") + return + + result = subprocess.run( + ["klist", "-c", f"FILE:{self.ccache_filename}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False + ) + regex_res = re.search(r"Default principal: (.*)\n", result.stdout) + + # if Kerberos ticket is not found, or the principal is incorrect + if result.returncode or not regex_res or regex_res.group(1) != self.principal: + LOG.info("Errata TGT doesn't exist, running kinit for principal %s", self.principal) + result = subprocess.run( + [ + "kinit", + self.principal, + "-k", + "-t", + self.keytab_path, + "-c", + f"FILE:{self.ccache_filename}", + ], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + text=True, check=False + ) + if result.returncode: + LOG.warning("kinit has failed: '%s'", result.stdout) + + @property + def session(self) -> requests.Session: + """ + Create requests Session. + + Session is used so that Kerberos authentication only has to be done once. + As pushsource utilizes threading, and sessions are not thread safe, each thread + will have a separate session. + + Returns (object): + Authenticated requests Session object. + """ + + if not hasattr(self._thread_local, "session"): + LOG.debug("Creating Errata requests session") + name = gssapi.Name(self.principal, gssapi.NameType.user) + creds = gssapi.Credentials.acquire( + name=name, usage="initiate", store={"ccache": f"FILE:{self.ccache_filename}"} + ).creds + + session = requests.Session() + session.auth = requests_gssapi.HTTPSPNEGOAuth(creds=creds) + self._thread_local.session = session + + return self._thread_local.session + + def get_advisory_data(self, advisory: str) -> dict: + """ + Get advisory data. + + Uses endpoint GET /api/v1/erratum/{id}. + + Args: + advisory (str): + Advisory ID or name. + Returns (dict): + Parsed JSON data as returned by Errata. + """ + url = urljoin(self.hostname, f"/api/v1/erratum/{advisory}") + LOG.info("Queried Errata HTTP API for %s", advisory) + response = self.session.get(url) + response.raise_for_status() + + return response.json() \ No newline at end of file diff --git a/src/pushsource/_impl/backend/errata_source/errata_source.py b/src/pushsource/_impl/backend/errata_source/errata_source.py index c1bb63ee..139514d8 100644 --- a/src/pushsource/_impl/backend/errata_source/errata_source.py +++ b/src/pushsource/_impl/backend/errata_source/errata_source.py @@ -6,6 +6,7 @@ from more_executors import Executors from .errata_client import ErrataClient +from .errata_http_client import ErrataHTTPClient from ... import compat_attr as attr from ...source import Source @@ -37,6 +38,8 @@ def __init__( koji_source=None, rpm_filter_arch=None, legacy_container_repos=False, + keytab_path=None, + principal=None, threads=4, timeout=60 * 60 * 4, ): @@ -67,6 +70,12 @@ def __init__( This is intended to better support certain legacy code and will be removed when no longer needed. Only use this if you know that you need it. + + keytab_path (str): + Kerberos keytab path for authenticating with Errata HTTP API. + + principal (str): + Kerberos principal for authenticating with Errata HTTP API. threads (int) Number of threads used for concurrent queries to Errata Tool @@ -79,6 +88,9 @@ def __init__( self._url = force_https(url) self._errata = list_argument(errata) self._client = ErrataClient(threads=threads, url=self._errata_service_url) + self._http_client = ErrataHTTPClient(self._url, keytab_path, principal) + # Get TGT only once + self._http_client.create_kerberos_ticket() self._rpm_filter_arch = list_argument(rpm_filter_arch, retain_none=True) @@ -225,6 +237,12 @@ def _push_items_from_container_manifests(self, erratum, docker_file_list): # } # + # Get product name from Errata. Enrich Container push items with this info + advisory_data = self._http_client.get_advisory_data(erratum.name) + # This dictionary key is different based on erratum type + erratum_type = list(advisory_data["errata"].keys())[0] + product_name = advisory_data["errata"][erratum_type]["product"]["name"] + # We'll be getting container metadata from these builds. with self._koji_source( container_build=list(docker_file_list.keys()) @@ -234,7 +252,7 @@ def _push_items_from_container_manifests(self, erratum, docker_file_list): for item in koji_source: if isinstance(item, ContainerImagePushItem): item = self._enrich_container_push_item( - erratum, docker_file_list, item + erratum, docker_file_list, item, product_name ) elif isinstance(item, OperatorManifestPushItem): # Accept this item but nothing special to do @@ -267,7 +285,7 @@ def _push_items_from_appliance_image_list(self, erratum, appliance_image_list): return out - def _enrich_container_push_item(self, erratum, docker_file_list, item): + def _enrich_container_push_item(self, erratum, docker_file_list, item, product_name): # metadata from koji doesn't contain info about where the image should be # pushed and a few other things - enrich it now errata_meta = docker_file_list.get(item.build) or {} @@ -313,7 +331,9 @@ def _enrich_container_push_item(self, erratum, docker_file_list, item): # koji source provided basic info on container image, ET provides policy on # where/how it should be pushed, combine them both to get final push item - return attr.evolve(item, dest=dest, dest_signing_key=dest_signing_key) + return attr.evolve( + item, dest=dest, dest_signing_key=dest_signing_key, product_name=product_name + ) def _push_items_from_rpms(self, erratum, rpm_list): out = [] diff --git a/src/pushsource/_impl/backend/registry_source.py b/src/pushsource/_impl/backend/registry_source.py index 19ecbb68..de5a1896 100644 --- a/src/pushsource/_impl/backend/registry_source.py +++ b/src/pushsource/_impl/backend/registry_source.py @@ -30,7 +30,7 @@ class RegistrySource(Source): """Uses a container image registry as a source of push items.""" - def __init__(self, image, dest=None, dest_signing_key=None): + def __init__(self, image, dest=None, dest_signing_key=None, product_name=None): """Create a new source. Parameters: @@ -56,6 +56,10 @@ def __init__(self, image, dest=None, dest_signing_key=None): argument can affect the number of generated push items. For example, providing two keys would produce double the amount of push items as providing a single key. + + product_name (str) + If provided, this value will be used to populate + :meth:`~pushsource.ContainerImagePushItem.product_name` on generated push items. """ self._images = ["https://%s" % x for x in list_argument(image)] if dest: @@ -65,6 +69,7 @@ def __init__(self, image, dest=None, dest_signing_key=None): self._signing_keys = list_argument(dest_signing_key) self._inspected = {} self._manifests = {} + self._product_name = product_name def __enter__(self): return self @@ -175,6 +180,7 @@ def _push_item_from_registry_uri(self, uri, signing_key): labels=labels, arch=arch, pull_info=pull_info, + product_name=self._product_name, ) def __iter__(self): diff --git a/src/pushsource/_impl/model/container.py b/src/pushsource/_impl/model/container.py index 83dec55c..3d22234d 100644 --- a/src/pushsource/_impl/model/container.py +++ b/src/pushsource/_impl/model/container.py @@ -291,6 +291,14 @@ class ContainerImagePushItem(PushItem): ) """Metadata for pulling this image from a registry.""" + product_name = attr.ib(type=str, default=None) + """Name of the product of this image. + + Brew doesn't provide this information, so it may not be set if the push + items are only generated from brew. This information will be included in the + "container security manifests" (formerly known as SBOMs). + """ + @attr.s() class SourceContainerImagePushItem(ContainerImagePushItem): diff --git a/test-requirements.in b/test-requirements.in index 8236737f..18d404c8 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -21,3 +21,4 @@ alabaster pidiff importlib-resources bandit +pytest-mock diff --git a/test-requirements.txt b/test-requirements.txt index b88947a0..9ffae3ab 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -343,9 +343,9 @@ gssapi==1.8.2 \ --hash=sha256:f75b094913a1757e5e634b70b03e808cab0eb02c802ec50b760636b23b0aa50c \ --hash=sha256:fac7d1f4b14383bd29d3996cf5f6f23d0dc50ffd7965d2bc35bcc0849da24152 # via requests-gssapi -identify==2.5.26 \ - --hash=sha256:7243800bce2f58404ed41b7c002e53d4d22bcf3ae1b7900c2d7aefd95394bf7f \ - --hash=sha256:c22a8ead0d4ca11f1edd6c9418c3220669b3b7533ada0a0ffa6cc0ef85cf9b54 +identify==2.5.27 \ + --hash=sha256:287b75b04a0e22d727bc9a41f0d4f3c1bcada97490fa6eabb5b28f0e9097e733 \ + --hash=sha256:fdb527b2dfe24602809b2201e033c2a113d7bdf716db3ca8e3243f735dcecaba # via pre-commit idna==3.4 \ --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \ @@ -575,10 +575,15 @@ pytest==7.4.0 \ # via # -r test-requirements.in # pytest-cov + # pytest-mock pytest-cov==4.1.0 \ --hash=sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6 \ --hash=sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a # via -r test-requirements.in +pytest-mock==3.11.1 \ + --hash=sha256:21c279fff83d70763b05f8874cc9cfb3fcacd6d354247a976f9529d19f9acf39 \ + --hash=sha256:7f6b125602ac6d743e523ae0bfa71e1a697a2f5534064528c6ff84c2f7c2fc7f + # via -r test-requirements.in python-dateutil==2.8.2 \ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 @@ -643,6 +648,7 @@ requests==2.31.0 \ --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 # via + # -r requirements.in # coveralls # koji # requests-gssapi diff --git a/tests/baseline/cases/errata-containers-legacy-repos.yml b/tests/baseline/cases/errata-containers-legacy-repos.yml index fca46304..05f36b91 100644 --- a/tests/baseline/cases/errata-containers-legacy-repos.yml +++ b/tests/baseline/cases/errata-containers-legacy-repos.yml @@ -29,6 +29,7 @@ items: md5sum: null name: docker-image-sha256:05db9dc3ed76f6cf993f0dd35aa51892a38ba51afdf8ed564a236d53d8375a47.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:16a04fde191ebd8858fa7f97605a9783be570e37d329eec599cfecf03b5cd8f2 @@ -79,6 +80,7 @@ items: md5sum: null name: docker-image-sha256:088c14ddcc989815bb38871fe9e0d3387a762c07a2ca23c9fd375ce42e3e53d6.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -129,6 +131,7 @@ items: md5sum: null name: docker-image-sha256:115387bd7efba2bdb7ee9f0d4fff88f03c1579859c6230cc67bb5c0b31263ba8.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:16a04fde191ebd8858fa7f97605a9783be570e37d329eec599cfecf03b5cd8f2 @@ -179,6 +182,7 @@ items: md5sum: null name: docker-image-sha256:176277a797bafa67823741efa319c2844758b2d5a4cb796b75a8b67580b54d56.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -229,6 +233,7 @@ items: md5sum: null name: docker-image-sha256:1dd3df4e8e532526b10155839caddef35cc731e586de169c60af9d72234e6640.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -279,6 +284,7 @@ items: md5sum: null name: docker-image-sha256:21d47ff01a369d38611df7d513636bd1eaf2787b4424620fa2297093cb7efd87.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -330,6 +336,7 @@ items: md5sum: null name: docker-image-sha256:24d0f51bd83a274c584a2aef98e6e504e71399c1cd536c3891a70d3ae3627278.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -380,6 +387,7 @@ items: md5sum: null name: docker-image-sha256:28b65974f88b0bc2c39b1e8f4aba6b5554f72b1650f69e63aeb5449bb48f58ee.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -430,6 +438,7 @@ items: md5sum: null name: docker-image-sha256:2c6e2f845291914c4e9ecf2eff31be45379ba3ad8b42fc133df83219d5c6039d.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -480,6 +489,7 @@ items: md5sum: null name: docker-image-sha256:30c942b23500e7d289671ebfa3f5a840a264620bae2c470fcf6f8b2928f066a0.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -530,6 +540,7 @@ items: md5sum: null name: docker-image-sha256:39fa57800aaa583cce939c5d1f6b8b9cc47fd903b1f2e8776d5b1d7cbf9dee4b.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -580,6 +591,7 @@ items: md5sum: null name: docker-image-sha256:497acb6ab8035229e662283a4fed020835ff92831ea0300864ae428874181df8.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -630,6 +642,7 @@ items: md5sum: null name: docker-image-sha256:6f1e0eb900873d800ec3cfc2c07405067679a935b4986e4dddb53037b78276ed.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -680,6 +693,7 @@ items: md5sum: null name: docker-image-sha256:8aff8f23622971d84fea7892062731af8c8611b887cbad8a3ef488055fa4ed04.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -730,6 +744,7 @@ items: md5sum: null name: docker-image-sha256:9661ac2d9c97b5cffdf6bc41f1bc98020890a63918416d32e3fdead286229342.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -780,6 +795,7 @@ items: md5sum: null name: docker-image-sha256:96b0fc687f7eac12b7773dfc568cab1f39a005378108a057408cfb184c7b25c5.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -831,6 +847,7 @@ items: md5sum: null name: docker-image-sha256:ac3482bc646895faea206cae1af0ab7fbe5a5e8e323f7fdcd01bda47e33d569f.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -881,6 +898,7 @@ items: md5sum: null name: docker-image-sha256:b248b0d65ac239f8cacbe71d892ea7d829db0171abb922f1caf6e888fb8c1bcc.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -931,6 +949,7 @@ items: md5sum: null name: docker-image-sha256:bbb14d32c62f4303e16256fd8d3f5123e789da1b2aee81e82b316908fcf9e28b.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:16a04fde191ebd8858fa7f97605a9783be570e37d329eec599cfecf03b5cd8f2 @@ -981,6 +1000,7 @@ items: md5sum: null name: docker-image-sha256:bc6da6c39d2778a070d09c619927d0fc3890b71080b00c89412e2b55859a040a.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -1031,6 +1051,7 @@ items: md5sum: null name: docker-image-sha256:be2056f3f63c8391fe60f5a6043c4d1a718bf52fb49fba39c18628b930661baf.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:16a04fde191ebd8858fa7f97605a9783be570e37d329eec599cfecf03b5cd8f2 @@ -1081,6 +1102,7 @@ items: md5sum: null name: docker-image-sha256:cc201958cbe1eb7f5282c1df2a1d1baf8f7c0ab0d2783a4cb1d4e1aa88ba6543.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -1131,6 +1153,7 @@ items: md5sum: null name: docker-image-sha256:d55b1d209c064dc8fd17952f2b0fdaccedf3905bce5701910302a2cd08b3a2a7.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -1181,6 +1204,7 @@ items: md5sum: null name: docker-image-sha256:d9ca1606333cc9badec48c4fe4895ae19b5ea5b29bb9601e17c7fb79cdd7ea19.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -1231,6 +1255,7 @@ items: md5sum: null name: docker-image-sha256:da1d6900c5f541a18295f66312cb8d0999aab6f425a6bbccdd2fd8bcc72300f1.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -1281,6 +1306,7 @@ items: md5sum: null name: docker-image-sha256:e395580a86026948eeed45d1ac406a5b3ce355aa0f48de23877ddfb61ca2cf62.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -1331,6 +1357,7 @@ items: md5sum: null name: docker-image-sha256:e3f74d3b725d2f6f32d652e4c13854e789e283f8673514b0749f796f5367b46f.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -1381,6 +1408,7 @@ items: md5sum: null name: docker-image-sha256:e437e702740efe93906c9b2e9e2a6e53863ccaa2aa49dfc6fa4a9047d37f0d2b.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -1432,6 +1460,7 @@ items: md5sum: null name: docker-image-sha256:e507f8aae9b8b13573e39ffded36375daeed686c0953bc1fd6af601713e0d191.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -1482,6 +1511,7 @@ items: md5sum: null name: docker-image-sha256:e859f5623bde399f46690b91c5be657aaa1fe98943930e6f6a2848199b6a7b03.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -1532,6 +1562,7 @@ items: md5sum: null name: docker-image-sha256:e86f4ab4555a4acf8dcb6f2349b0a8fd8ed16ac9d3df039c50014b36a7a8b181.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -1582,6 +1613,7 @@ items: md5sum: null name: docker-image-sha256:f01dbc59e3d0c08d9df77852cefcd8f8bc4bd66587cd4afbb399853f38b1085c.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -1632,6 +1664,7 @@ items: md5sum: null name: docker-image-sha256:f40245eeba63f6f1cd0b1b59a683a6ca6a5051194f55386e26e5fdd234433bb4.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -1682,6 +1715,7 @@ items: md5sum: null name: docker-image-sha256:f49167b645594fec8171bcffa2ba4c652d2fc6a8a39c8d04c8ac9891833429f6.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -1733,6 +1767,7 @@ items: md5sum: null name: docker-image-sha256:f5b69a6fd18b7c6189824dff60f834ee4405b338579f5e37b7e6316f70460ac8.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -1783,6 +1818,7 @@ items: md5sum: null name: docker-image-sha256:fe0511050968b1355e91c143eea7937e6b96e50e41f1c07d09af3c344c53df65.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -1936,6 +1972,7 @@ items: md5sum: null name: docker-image-sha256:da1d6900c5f541a18295f66312cb8d0999aab6f425a6bbccdd2fd8bcc72300f1.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -1982,6 +2019,7 @@ items: md5sum: null name: docker-image-sha256:e3f74d3b725d2f6f32d652e4c13854e789e283f8673514b0749f796f5367b46f.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -2028,6 +2066,7 @@ items: md5sum: null name: docker-image-sha256:2c6e2f845291914c4e9ecf2eff31be45379ba3ad8b42fc133df83219d5c6039d.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -2074,6 +2113,7 @@ items: md5sum: null name: docker-image-sha256:e859f5623bde399f46690b91c5be657aaa1fe98943930e6f6a2848199b6a7b03.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -2137,6 +2177,7 @@ items: md5sum: null name: docker-image-sha256:f49167b645594fec8171bcffa2ba4c652d2fc6a8a39c8d04c8ac9891833429f6.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -2183,6 +2224,7 @@ items: md5sum: null name: docker-image-sha256:bc6da6c39d2778a070d09c619927d0fc3890b71080b00c89412e2b55859a040a.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -2229,6 +2271,7 @@ items: md5sum: null name: docker-image-sha256:e395580a86026948eeed45d1ac406a5b3ce355aa0f48de23877ddfb61ca2cf62.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -2275,6 +2318,7 @@ items: md5sum: null name: docker-image-sha256:d9ca1606333cc9badec48c4fe4895ae19b5ea5b29bb9601e17c7fb79cdd7ea19.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -2338,6 +2382,7 @@ items: md5sum: null name: docker-image-sha256:21d47ff01a369d38611df7d513636bd1eaf2787b4424620fa2297093cb7efd87.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -2384,6 +2429,7 @@ items: md5sum: null name: docker-image-sha256:6f1e0eb900873d800ec3cfc2c07405067679a935b4986e4dddb53037b78276ed.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -2430,6 +2476,7 @@ items: md5sum: null name: docker-image-sha256:30c942b23500e7d289671ebfa3f5a840a264620bae2c470fcf6f8b2928f066a0.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -2476,6 +2523,7 @@ items: md5sum: null name: docker-image-sha256:088c14ddcc989815bb38871fe9e0d3387a762c07a2ca23c9fd375ce42e3e53d6.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -2539,6 +2587,7 @@ items: md5sum: null name: docker-image-sha256:cc201958cbe1eb7f5282c1df2a1d1baf8f7c0ab0d2783a4cb1d4e1aa88ba6543.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -2585,6 +2634,7 @@ items: md5sum: null name: docker-image-sha256:497acb6ab8035229e662283a4fed020835ff92831ea0300864ae428874181df8.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -2631,6 +2681,7 @@ items: md5sum: null name: docker-image-sha256:f01dbc59e3d0c08d9df77852cefcd8f8bc4bd66587cd4afbb399853f38b1085c.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -2677,6 +2728,7 @@ items: md5sum: null name: docker-image-sha256:e86f4ab4555a4acf8dcb6f2349b0a8fd8ed16ac9d3df039c50014b36a7a8b181.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -2740,6 +2792,7 @@ items: md5sum: null name: docker-image-sha256:24d0f51bd83a274c584a2aef98e6e504e71399c1cd536c3891a70d3ae3627278.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -2786,6 +2839,7 @@ items: md5sum: null name: docker-image-sha256:e507f8aae9b8b13573e39ffded36375daeed686c0953bc1fd6af601713e0d191.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -2832,6 +2886,7 @@ items: md5sum: null name: docker-image-sha256:f5b69a6fd18b7c6189824dff60f834ee4405b338579f5e37b7e6316f70460ac8.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -2878,6 +2933,7 @@ items: md5sum: null name: docker-image-sha256:ac3482bc646895faea206cae1af0ab7fbe5a5e8e323f7fdcd01bda47e33d569f.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -2941,6 +2997,7 @@ items: md5sum: null name: docker-image-sha256:8aff8f23622971d84fea7892062731af8c8611b887cbad8a3ef488055fa4ed04.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -2987,6 +3044,7 @@ items: md5sum: null name: docker-image-sha256:39fa57800aaa583cce939c5d1f6b8b9cc47fd903b1f2e8776d5b1d7cbf9dee4b.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -3033,6 +3091,7 @@ items: md5sum: null name: docker-image-sha256:f40245eeba63f6f1cd0b1b59a683a6ca6a5051194f55386e26e5fdd234433bb4.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -3079,6 +3138,7 @@ items: md5sum: null name: docker-image-sha256:9661ac2d9c97b5cffdf6bc41f1bc98020890a63918416d32e3fdead286229342.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -3142,6 +3202,7 @@ items: md5sum: null name: docker-image-sha256:176277a797bafa67823741efa319c2844758b2d5a4cb796b75a8b67580b54d56.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -3188,6 +3249,7 @@ items: md5sum: null name: docker-image-sha256:b248b0d65ac239f8cacbe71d892ea7d829db0171abb922f1caf6e888fb8c1bcc.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -3234,6 +3296,7 @@ items: md5sum: null name: docker-image-sha256:1dd3df4e8e532526b10155839caddef35cc731e586de169c60af9d72234e6640.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -3280,6 +3343,7 @@ items: md5sum: null name: docker-image-sha256:e437e702740efe93906c9b2e9e2a6e53863ccaa2aa49dfc6fa4a9047d37f0d2b.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -3343,6 +3407,7 @@ items: md5sum: null name: docker-image-sha256:fe0511050968b1355e91c143eea7937e6b96e50e41f1c07d09af3c344c53df65.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -3389,6 +3454,7 @@ items: md5sum: null name: docker-image-sha256:d55b1d209c064dc8fd17952f2b0fdaccedf3905bce5701910302a2cd08b3a2a7.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -3435,6 +3501,7 @@ items: md5sum: null name: docker-image-sha256:28b65974f88b0bc2c39b1e8f4aba6b5554f72b1650f69e63aeb5449bb48f58ee.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -3481,6 +3548,7 @@ items: md5sum: null name: docker-image-sha256:96b0fc687f7eac12b7773dfc568cab1f39a005378108a057408cfb184c7b25c5.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 diff --git a/tests/baseline/cases/errata-containers.yml b/tests/baseline/cases/errata-containers.yml index 25e15004..f81fa74c 100644 --- a/tests/baseline/cases/errata-containers.yml +++ b/tests/baseline/cases/errata-containers.yml @@ -29,6 +29,7 @@ items: md5sum: null name: docker-image-sha256:05db9dc3ed76f6cf993f0dd35aa51892a38ba51afdf8ed564a236d53d8375a47.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:16a04fde191ebd8858fa7f97605a9783be570e37d329eec599cfecf03b5cd8f2 @@ -79,6 +80,7 @@ items: md5sum: null name: docker-image-sha256:088c14ddcc989815bb38871fe9e0d3387a762c07a2ca23c9fd375ce42e3e53d6.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -129,6 +131,7 @@ items: md5sum: null name: docker-image-sha256:115387bd7efba2bdb7ee9f0d4fff88f03c1579859c6230cc67bb5c0b31263ba8.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:16a04fde191ebd8858fa7f97605a9783be570e37d329eec599cfecf03b5cd8f2 @@ -179,6 +182,7 @@ items: md5sum: null name: docker-image-sha256:176277a797bafa67823741efa319c2844758b2d5a4cb796b75a8b67580b54d56.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -229,6 +233,7 @@ items: md5sum: null name: docker-image-sha256:1dd3df4e8e532526b10155839caddef35cc731e586de169c60af9d72234e6640.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -279,6 +284,7 @@ items: md5sum: null name: docker-image-sha256:21d47ff01a369d38611df7d513636bd1eaf2787b4424620fa2297093cb7efd87.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -330,6 +336,7 @@ items: md5sum: null name: docker-image-sha256:24d0f51bd83a274c584a2aef98e6e504e71399c1cd536c3891a70d3ae3627278.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -380,6 +387,7 @@ items: md5sum: null name: docker-image-sha256:28b65974f88b0bc2c39b1e8f4aba6b5554f72b1650f69e63aeb5449bb48f58ee.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -430,6 +438,7 @@ items: md5sum: null name: docker-image-sha256:2c6e2f845291914c4e9ecf2eff31be45379ba3ad8b42fc133df83219d5c6039d.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -480,6 +489,7 @@ items: md5sum: null name: docker-image-sha256:30c942b23500e7d289671ebfa3f5a840a264620bae2c470fcf6f8b2928f066a0.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -530,6 +540,7 @@ items: md5sum: null name: docker-image-sha256:39fa57800aaa583cce939c5d1f6b8b9cc47fd903b1f2e8776d5b1d7cbf9dee4b.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -580,6 +591,7 @@ items: md5sum: null name: docker-image-sha256:497acb6ab8035229e662283a4fed020835ff92831ea0300864ae428874181df8.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -630,6 +642,7 @@ items: md5sum: null name: docker-image-sha256:6f1e0eb900873d800ec3cfc2c07405067679a935b4986e4dddb53037b78276ed.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -680,6 +693,7 @@ items: md5sum: null name: docker-image-sha256:8aff8f23622971d84fea7892062731af8c8611b887cbad8a3ef488055fa4ed04.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -730,6 +744,7 @@ items: md5sum: null name: docker-image-sha256:9661ac2d9c97b5cffdf6bc41f1bc98020890a63918416d32e3fdead286229342.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -780,6 +795,7 @@ items: md5sum: null name: docker-image-sha256:96b0fc687f7eac12b7773dfc568cab1f39a005378108a057408cfb184c7b25c5.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -831,6 +847,7 @@ items: md5sum: null name: docker-image-sha256:ac3482bc646895faea206cae1af0ab7fbe5a5e8e323f7fdcd01bda47e33d569f.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -881,6 +898,7 @@ items: md5sum: null name: docker-image-sha256:b248b0d65ac239f8cacbe71d892ea7d829db0171abb922f1caf6e888fb8c1bcc.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -931,6 +949,7 @@ items: md5sum: null name: docker-image-sha256:bbb14d32c62f4303e16256fd8d3f5123e789da1b2aee81e82b316908fcf9e28b.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:16a04fde191ebd8858fa7f97605a9783be570e37d329eec599cfecf03b5cd8f2 @@ -981,6 +1000,7 @@ items: md5sum: null name: docker-image-sha256:bc6da6c39d2778a070d09c619927d0fc3890b71080b00c89412e2b55859a040a.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -1031,6 +1051,7 @@ items: md5sum: null name: docker-image-sha256:be2056f3f63c8391fe60f5a6043c4d1a718bf52fb49fba39c18628b930661baf.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:16a04fde191ebd8858fa7f97605a9783be570e37d329eec599cfecf03b5cd8f2 @@ -1081,6 +1102,7 @@ items: md5sum: null name: docker-image-sha256:cc201958cbe1eb7f5282c1df2a1d1baf8f7c0ab0d2783a4cb1d4e1aa88ba6543.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -1131,6 +1153,7 @@ items: md5sum: null name: docker-image-sha256:d55b1d209c064dc8fd17952f2b0fdaccedf3905bce5701910302a2cd08b3a2a7.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -1181,6 +1204,7 @@ items: md5sum: null name: docker-image-sha256:d9ca1606333cc9badec48c4fe4895ae19b5ea5b29bb9601e17c7fb79cdd7ea19.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -1231,6 +1255,7 @@ items: md5sum: null name: docker-image-sha256:da1d6900c5f541a18295f66312cb8d0999aab6f425a6bbccdd2fd8bcc72300f1.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -1281,6 +1306,7 @@ items: md5sum: null name: docker-image-sha256:e395580a86026948eeed45d1ac406a5b3ce355aa0f48de23877ddfb61ca2cf62.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -1331,6 +1357,7 @@ items: md5sum: null name: docker-image-sha256:e3f74d3b725d2f6f32d652e4c13854e789e283f8673514b0749f796f5367b46f.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -1381,6 +1408,7 @@ items: md5sum: null name: docker-image-sha256:e437e702740efe93906c9b2e9e2a6e53863ccaa2aa49dfc6fa4a9047d37f0d2b.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -1432,6 +1460,7 @@ items: md5sum: null name: docker-image-sha256:e507f8aae9b8b13573e39ffded36375daeed686c0953bc1fd6af601713e0d191.x86_64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -1482,6 +1511,7 @@ items: md5sum: null name: docker-image-sha256:e859f5623bde399f46690b91c5be657aaa1fe98943930e6f6a2848199b6a7b03.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -1532,6 +1562,7 @@ items: md5sum: null name: docker-image-sha256:e86f4ab4555a4acf8dcb6f2349b0a8fd8ed16ac9d3df039c50014b36a7a8b181.ppc64le.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -1582,6 +1613,7 @@ items: md5sum: null name: docker-image-sha256:f01dbc59e3d0c08d9df77852cefcd8f8bc4bd66587cd4afbb399853f38b1085c.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -1632,6 +1664,7 @@ items: md5sum: null name: docker-image-sha256:f40245eeba63f6f1cd0b1b59a683a6ca6a5051194f55386e26e5fdd234433bb4.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -1682,6 +1715,7 @@ items: md5sum: null name: docker-image-sha256:f49167b645594fec8171bcffa2ba4c652d2fc6a8a39c8d04c8ac9891833429f6.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -1733,6 +1767,7 @@ items: md5sum: null name: docker-image-sha256:f5b69a6fd18b7c6189824dff60f834ee4405b338579f5e37b7e6316f70460ac8.s390x.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -1783,6 +1818,7 @@ items: md5sum: null name: docker-image-sha256:fe0511050968b1355e91c143eea7937e6b96e50e41f1c07d09af3c344c53df65.aarch64.tar.gz origin: RHBA-2020:2807 + product_name: Red Hat OpenShift Enterprise pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -1936,6 +1972,7 @@ items: md5sum: null name: docker-image-sha256:da1d6900c5f541a18295f66312cb8d0999aab6f425a6bbccdd2fd8bcc72300f1.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -1982,6 +2019,7 @@ items: md5sum: null name: docker-image-sha256:e3f74d3b725d2f6f32d652e4c13854e789e283f8673514b0749f796f5367b46f.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -2028,6 +2066,7 @@ items: md5sum: null name: docker-image-sha256:2c6e2f845291914c4e9ecf2eff31be45379ba3ad8b42fc133df83219d5c6039d.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -2074,6 +2113,7 @@ items: md5sum: null name: docker-image-sha256:e859f5623bde399f46690b91c5be657aaa1fe98943930e6f6a2848199b6a7b03.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:e38da0971a67c6b3d4261edd9bd679de1be15d0716d208cddf54b0478a73f0a2 @@ -2137,6 +2177,7 @@ items: md5sum: null name: docker-image-sha256:f49167b645594fec8171bcffa2ba4c652d2fc6a8a39c8d04c8ac9891833429f6.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -2183,6 +2224,7 @@ items: md5sum: null name: docker-image-sha256:bc6da6c39d2778a070d09c619927d0fc3890b71080b00c89412e2b55859a040a.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -2229,6 +2271,7 @@ items: md5sum: null name: docker-image-sha256:e395580a86026948eeed45d1ac406a5b3ce355aa0f48de23877ddfb61ca2cf62.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -2275,6 +2318,7 @@ items: md5sum: null name: docker-image-sha256:d9ca1606333cc9badec48c4fe4895ae19b5ea5b29bb9601e17c7fb79cdd7ea19.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:625ed0e36cff8819aabaadfc67e983ba4486c3ab2c73286fe7bc1726ae08e2c4 @@ -2338,6 +2382,7 @@ items: md5sum: null name: docker-image-sha256:21d47ff01a369d38611df7d513636bd1eaf2787b4424620fa2297093cb7efd87.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -2384,6 +2429,7 @@ items: md5sum: null name: docker-image-sha256:6f1e0eb900873d800ec3cfc2c07405067679a935b4986e4dddb53037b78276ed.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -2430,6 +2476,7 @@ items: md5sum: null name: docker-image-sha256:30c942b23500e7d289671ebfa3f5a840a264620bae2c470fcf6f8b2928f066a0.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -2476,6 +2523,7 @@ items: md5sum: null name: docker-image-sha256:088c14ddcc989815bb38871fe9e0d3387a762c07a2ca23c9fd375ce42e3e53d6.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:a595bff056e37d4d61cc9225504bf7f969adcdd53f8f5180176b612c17ceaedc @@ -2539,6 +2587,7 @@ items: md5sum: null name: docker-image-sha256:cc201958cbe1eb7f5282c1df2a1d1baf8f7c0ab0d2783a4cb1d4e1aa88ba6543.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -2585,6 +2634,7 @@ items: md5sum: null name: docker-image-sha256:497acb6ab8035229e662283a4fed020835ff92831ea0300864ae428874181df8.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -2631,6 +2681,7 @@ items: md5sum: null name: docker-image-sha256:f01dbc59e3d0c08d9df77852cefcd8f8bc4bd66587cd4afbb399853f38b1085c.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -2677,6 +2728,7 @@ items: md5sum: null name: docker-image-sha256:e86f4ab4555a4acf8dcb6f2349b0a8fd8ed16ac9d3df039c50014b36a7a8b181.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:440f56c49b3a3b7490716e5370eacf684529f950f79527016bb265073ffd5332 @@ -2740,6 +2792,7 @@ items: md5sum: null name: docker-image-sha256:24d0f51bd83a274c584a2aef98e6e504e71399c1cd536c3891a70d3ae3627278.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -2786,6 +2839,7 @@ items: md5sum: null name: docker-image-sha256:e507f8aae9b8b13573e39ffded36375daeed686c0953bc1fd6af601713e0d191.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -2832,6 +2886,7 @@ items: md5sum: null name: docker-image-sha256:f5b69a6fd18b7c6189824dff60f834ee4405b338579f5e37b7e6316f70460ac8.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -2878,6 +2933,7 @@ items: md5sum: null name: docker-image-sha256:ac3482bc646895faea206cae1af0ab7fbe5a5e8e323f7fdcd01bda47e33d569f.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:c87692a65005472766fc95effc7e4e0f049e3cd6c244f8e07b8da0604c6c7540 @@ -2941,6 +2997,7 @@ items: md5sum: null name: docker-image-sha256:8aff8f23622971d84fea7892062731af8c8611b887cbad8a3ef488055fa4ed04.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -2987,6 +3044,7 @@ items: md5sum: null name: docker-image-sha256:39fa57800aaa583cce939c5d1f6b8b9cc47fd903b1f2e8776d5b1d7cbf9dee4b.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -3033,6 +3091,7 @@ items: md5sum: null name: docker-image-sha256:f40245eeba63f6f1cd0b1b59a683a6ca6a5051194f55386e26e5fdd234433bb4.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -3079,6 +3138,7 @@ items: md5sum: null name: docker-image-sha256:9661ac2d9c97b5cffdf6bc41f1bc98020890a63918416d32e3fdead286229342.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:2e3b45e6ca30acddd1058a026b1a3fd47fbb02120e7e48b207954307dac53535 @@ -3142,6 +3202,7 @@ items: md5sum: null name: docker-image-sha256:176277a797bafa67823741efa319c2844758b2d5a4cb796b75a8b67580b54d56.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -3188,6 +3249,7 @@ items: md5sum: null name: docker-image-sha256:b248b0d65ac239f8cacbe71d892ea7d829db0171abb922f1caf6e888fb8c1bcc.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -3234,6 +3296,7 @@ items: md5sum: null name: docker-image-sha256:1dd3df4e8e532526b10155839caddef35cc731e586de169c60af9d72234e6640.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -3280,6 +3343,7 @@ items: md5sum: null name: docker-image-sha256:e437e702740efe93906c9b2e9e2a6e53863ccaa2aa49dfc6fa4a9047d37f0d2b.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:5c27155eaec4c610bc8389f7068c4713fcf6148097479f8e1fa8a12d5f3cad75 @@ -3343,6 +3407,7 @@ items: md5sum: null name: docker-image-sha256:fe0511050968b1355e91c143eea7937e6b96e50e41f1c07d09af3c344c53df65.aarch64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -3389,6 +3454,7 @@ items: md5sum: null name: docker-image-sha256:d55b1d209c064dc8fd17952f2b0fdaccedf3905bce5701910302a2cd08b3a2a7.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -3435,6 +3501,7 @@ items: md5sum: null name: docker-image-sha256:28b65974f88b0bc2c39b1e8f4aba6b5554f72b1650f69e63aeb5449bb48f58ee.s390x.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 @@ -3481,6 +3548,7 @@ items: md5sum: null name: docker-image-sha256:96b0fc687f7eac12b7773dfc568cab1f39a005378108a057408cfb184c7b25c5.ppc64le.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9e7f37ad9893d218c9998e53bdb847505c103999200a36afa9fd0875facd7643 diff --git a/tests/baseline/cases/koji-operator-container.yml b/tests/baseline/cases/koji-operator-container.yml index 504106fa..9ff4b3f9 100644 --- a/tests/baseline/cases/koji-operator-container.yml +++ b/tests/baseline/cases/koji-operator-container.yml @@ -33,6 +33,7 @@ items: md5sum: null name: docker-image-sha256:eb6788bfdcb4c1743176a99440754e925725664e037180ab974fd64a238fae29.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:4df4eec0343cc8ed7327eae7d69eb106e3e2b7697a99eb7e762d2d376002213a @@ -94,6 +95,7 @@ items: md5sum: null name: docker-image-sha256:eb6788bfdcb4c1743176a99440754e925725664e037180ab974fd64a238fae29.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:4df4eec0343cc8ed7327eae7d69eb106e3e2b7697a99eb7e762d2d376002213a diff --git a/tests/baseline/cases/koji-source-container.yml b/tests/baseline/cases/koji-source-container.yml index 2db13eb1..560c10a7 100644 --- a/tests/baseline/cases/koji-source-container.yml +++ b/tests/baseline/cases/koji-source-container.yml @@ -22,6 +22,7 @@ items: md5sum: null name: docker-image-sha256:bfe520f7c81aeb3eaeb732ab93dd76b279b6a01a16a27f1ec34d5b2fcefbb363.x86_64.tar.gz origin: null + product_name: null pull_info: digest_specs: - digest: sha256:9ab2d821d9cd40e2483582d418191d2548e2b839ac26c4bfd1a9996dca773f0f diff --git a/tests/baseline/test_baseline.py b/tests/baseline/test_baseline.py index e242b6b1..cf4cd674 100644 --- a/tests/baseline/test_baseline.py +++ b/tests/baseline/test_baseline.py @@ -4,6 +4,7 @@ import logging import difflib import threading +import json import yaml import attr @@ -26,6 +27,7 @@ CASE_DIR = os.path.join(THIS_DIR, "cases") CASE_TEMPLATE_FILE = os.path.join(THIS_DIR, "template.yml.j2") SRC_DIR = os.path.abspath(os.path.join(THIS_DIR, "../..")) +DATA_DIR = os.path.abspath(os.path.join(THIS_DIR, "../..")) def asdict(value): @@ -76,13 +78,22 @@ def koji_test_backend(fake_koji, koji_dir): Source.reset() +@pytest.fixture(autouse=True) +def fake_kerberos_auth(mocker): + mocker.patch("gssapi.Name") + mocker.patch("gssapi.Credentials.acquire") + mocker.patch("requests_gssapi.HTTPSPNEGOAuth", return_value=None) + + +@pytest.fixture(autouse=True) +def baseline_errata_requests_mock(errata_requests_mock): + yield + @pytest.fixture(scope="module", autouse=True) def errata_test_backend(fake_errata_tool, koji_test_backend): # erratatest backend is errata backend pointing at kojitest and our errata testdata - bound = Source.get_partial( - "errata:https://errata.example.com/", koji_source="kojitest:" - ) + bound = Source.get_partial("errata:https://errata.example.com/", koji_source="kojitest:") Source.register_backend("erratatest", bound) yield diff --git a/tests/conftest.py b/tests/conftest.py index 93d2b0f9..708baeda 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,8 @@ import copy +import os from pytest import fixture from mock import patch +import json from pushsource import Source from .errata.fake_errata_tool import FakeErrataToolController @@ -13,6 +15,8 @@ ContainerImageDigestPullSpec, ) +THIS_DIR = os.path.dirname(__file__) +ERRATA_DATA_DIR = os.path.abspath(os.path.join(THIS_DIR, "./errata/data")) @fixture def fake_errata_tool(): @@ -101,6 +105,17 @@ def fake_koji(): def koji_dir(tmpdir): yield str(tmpdir.mkdir("koji")) +@fixture() +def errata_requests_mock(requests_mock): + for root, _, files in os.walk(ERRATA_DATA_DIR): + for filename in files: + if filename.endswith(".json"): + path = os.path.join(root, filename) + with open(path) as fh: + data = json.load(fh) + requests_mock.get(f"/api/v1/erratum/{filename.rstrip('.json')}", json=data) # nosec B113 + + yield @fixture(autouse=True) def clean_backends(): diff --git a/tests/errata/data/RHBA-2020:2807.json b/tests/errata/data/RHBA-2020:2807.json new file mode 100644 index 00000000..3b29ae88 --- /dev/null +++ b/tests/errata/data/RHBA-2020:2807.json @@ -0,0 +1,362 @@ +{ + "who": { + "user": { + "id": 3004368, + "login_name": "lgallovi@redhat.com", + "realname": "Lubomir Gallovic", + "user_organization_id": 142, + "enabled": 1, + "receives_mail": true, + "preferences": {}, + "email_address": null, + "account_name": "lgallovi", + "type": "Person" + } + }, + "params": { + "format": "json", + "controller": "api/v1/erratum", + "action": "show", + "id": "RHBA-2020:2807" + }, + "errata": { + "rhba": { + "id": 56346, + "revision": 3, + "fulladvisory": "RHBA-2020:2807-03", + "issue_date": "2020-07-08T22:16:09Z", + "update_date": "2020-07-08T22:16:09Z", + "release_date": null, + "synopsis": "OpenShift Container Platform 4.3.28 OLM Operators metadata update", + "pushed": 0, + "published": 1, + "deleted": 0, + "qa_complete": 1, + "status": "SHIPPED_LIVE", + "resolution": "", + "reporter_id": 3003538, + "assigned_to_id": 3002269, + "old_delete_product": null, + "severity": "normal", + "priority": "normal", + "rhn_complete": 0, + "request": 0, + "doc_complete": 1, + "rhnqa": 1, + "closed": 0, + "contract": null, + "pushcount": 1, + "text_ready": 0, + "package_owner_id": 3004093, + "manager_id": 3002316, + "rhnqa_shadow": 0, + "published_shadow": 0, + "current_tps_run": null, + "filelist_locked": 0, + "filelist_changed": 0, + "sign_requested": 0, + "security_impact": "None", + "product_id": 79, + "is_brew": 1, + "status_updated_at": "2020-07-08T22:20:59Z", + "group_id": 436, + "created_at": "2020-06-24T10:13:27Z", + "updated_at": "2020-07-08T22:20:59Z", + "respin_count": 1, + "old_advisory": "RHBA-2020:56346-02", + "rating": 0, + "docs_responsibility_id": 1, + "quality_responsibility_id": 139, + "devel_responsibility_id": 3, + "is_valid": 1, + "current_state_index_id": 373778, + "text_only": false, + "publish_date_override": "2020-07-07T00:00:00Z", + "state_machine_rule_set_id": null, + "actual_ship_date": "2020-07-08T22:20:59Z", + "supports_multiple_product_destinations": false, + "security_approved": null, + "batch_id": null, + "is_batch_blocker": false, + "request_rcm_push_comment_id": null, + "content_types": [ + "docker" + ], + "embargo_undated": false, + "security_sla": null, + "cloned_from_id": null, + "is_followup": false, + "expected_publish_date": null, + "builds_updated_at": null, + "cve_mapping_validation_complete": null, + "prevent_auto_push_ready": false, + "suppress_push_request_jira": false, + "embargo_date": null, + "errata_id": 2807, + "publish_date": "2022-03-09T00:00:00Z", + "fulltype": "Red Hat Bug Fix Advisory", + "is_operator_hotfix": false, + "is_operator_prerelease": false, + "skip_customer_notifications": false, + "blocking_advisories": [], + "dependent_advisories": [], + "product": { + "id": 79, + "name": "Red Hat OpenShift Enterprise", + "short_name": "RHOSE" + } + } + }, + "original_type": "RHBA", + "content": { + "content": { + "id": 53926, + "errata_id": 56346, + "topic": "Red Hat OpenShift Container Platform release 4.3.28 is now available with\nupdates to packages and images that fix several bugs.\n\nThis advisory will be used to release the corresponding operator manifests\nvia new operator metadata containers.", + "description": "Red Hat OpenShift Container Platform is Red Hat's cloud computing\nKubernetes application platform solution designed for on-premise or private\ncloud deployments.\n\nThis advisory will be used to release the corresponding operator manifests\nvia new operator metadata containers.\n\nAll OpenShift Container Platform 4.3 users are advised to upgrade to these\nupdated packages and images when they are available in the appropriate\nrelease channel. To check for available updates, use the OpenShift Console\nor the CLI oc command. Instructions for upgrading a cluster are available\nat\nhttps://docs.openshift.com/container-platform/4.3/updating/updating-cluster-between-minor.html#understanding-upgrade-channels_updating-cluster-between-minor.", + "solution": "For OpenShift Container Platform 4.3 see the following documentation, which\nwill be updated shortly for release 4.3.28, for important instructions on\nhow to upgrade your cluster and fully apply this asynchronous errata\nupdate:\n\nhttps://docs.openshift.com/container-platform/4.3/release_notes/ocp-4-3-release-notes.html\n\nDetails on how to access this content are available at\nhttps://docs.openshift.com/container-platform/4.3/updating/updating-cluster-cli.html.", + "keywords": "", + "obsoletes": "", + "cve": "", + "packages": null, + "multilib": null, + "crossref": "", + "reference": "", + "how_to_test": null, + "doc_reviewer_id": 3004540, + "updated_at": "2020-07-06T13:23:15Z", + "revision_count": 1, + "doc_review_due_at": null, + "text_only_cpe": null, + "product_version_text": "", + "product_security_reviewer_id": null + } + }, + "diffs": {}, + "bugs": { + "errata": { + "rhba": { + "id": 56346, + "revision": 3, + "fulladvisory": "RHBA-2020:2807-03", + "issue_date": "2020-07-08T22:16:09Z", + "update_date": "2020-07-08T22:16:09Z", + "release_date": null, + "synopsis": "OpenShift Container Platform 4.3.28 OLM Operators metadata update", + "pushed": 0, + "published": 1, + "deleted": 0, + "qa_complete": 1, + "status": "SHIPPED_LIVE", + "resolution": "", + "reporter_id": 3003538, + "assigned_to_id": 3002269, + "old_delete_product": null, + "severity": "normal", + "priority": "normal", + "rhn_complete": 0, + "request": 0, + "doc_complete": 1, + "rhnqa": 1, + "closed": 0, + "contract": null, + "pushcount": 1, + "text_ready": 0, + "package_owner_id": 3004093, + "manager_id": 3002316, + "rhnqa_shadow": 0, + "published_shadow": 0, + "current_tps_run": null, + "filelist_locked": 0, + "filelist_changed": 0, + "sign_requested": 0, + "security_impact": "None", + "product_id": 79, + "is_brew": 1, + "status_updated_at": "2020-07-08T22:20:59Z", + "group_id": 436, + "created_at": "2020-06-24T10:13:27Z", + "updated_at": "2020-07-08T22:20:59Z", + "respin_count": 1, + "old_advisory": "RHBA-2020:56346-02", + "rating": 0, + "docs_responsibility_id": 1, + "quality_responsibility_id": 139, + "devel_responsibility_id": 3, + "is_valid": 1, + "current_state_index_id": 373778, + "text_only": false, + "publish_date_override": "2020-07-07T00:00:00Z", + "state_machine_rule_set_id": null, + "actual_ship_date": "2020-07-08T22:20:59Z", + "supports_multiple_product_destinations": false, + "security_approved": null, + "batch_id": null, + "is_batch_blocker": false, + "request_rcm_push_comment_id": null, + "content_types": [ + "docker" + ], + "embargo_undated": false, + "security_sla": null, + "cloned_from_id": null, + "is_followup": false, + "expected_publish_date": null, + "builds_updated_at": null, + "cve_mapping_validation_complete": null, + "prevent_auto_push_ready": false, + "suppress_push_request_jira": false, + "embargo_date": null, + "errata_id": 2807, + "publish_date": "2022-03-09T00:00:00Z", + "fulltype": "Red Hat Bug Fix Advisory", + "is_operator_hotfix": false, + "is_operator_prerelease": false, + "skip_customer_notifications": false, + "blocking_advisories": [], + "dependent_advisories": [], + "product": { + "id": 79, + "name": "Red Hat OpenShift Enterprise", + "short_name": "RHOSE" + } + } + }, + "id_field": "id", + "id_prefix": "bz:", + "type": "bugs", + "idsfixed": [ + "1850434" + ], + "bugs": [ + { + "bug": { + "id": 1850434, + "bug_status": "CLOSED", + "short_desc": "Placeholder bug for OCP 4.3.z metadata release", + "package_id": 1672, + "is_private": 0, + "last_updated": "2020-07-08T22:21:18Z", + "is_security": 0, + "alias": "", + "was_marked_on_qa": 0, + "priority": "unspecified", + "bug_severity": "", + "qa_whiteboard": "", + "keywords": "", + "issuetrackers": "", + "pm_score": 0, + "is_blocker": 0, + "is_exception": 0, + "flags": "", + "release_notes": "", + "reconciled_at": "2020-07-14T10:32:33Z", + "verified": "", + "has_security_group": false, + "internal_target_release": "", + "approved_release": "", + "zstream_target_release": "", + "product": "OpenShift Container Platform", + "sla_date": null + } + } + ], + "to_fetch": [] + }, + "jira_issues": { + "errata": { + "rhba": { + "id": 56346, + "revision": 3, + "fulladvisory": "RHBA-2020:2807-03", + "issue_date": "2020-07-08T22:16:09Z", + "update_date": "2020-07-08T22:16:09Z", + "release_date": null, + "synopsis": "OpenShift Container Platform 4.3.28 OLM Operators metadata update", + "pushed": 0, + "published": 1, + "deleted": 0, + "qa_complete": 1, + "status": "SHIPPED_LIVE", + "resolution": "", + "reporter_id": 3003538, + "assigned_to_id": 3002269, + "old_delete_product": null, + "severity": "normal", + "priority": "normal", + "rhn_complete": 0, + "request": 0, + "doc_complete": 1, + "rhnqa": 1, + "closed": 0, + "contract": null, + "pushcount": 1, + "text_ready": 0, + "package_owner_id": 3004093, + "manager_id": 3002316, + "rhnqa_shadow": 0, + "published_shadow": 0, + "current_tps_run": null, + "filelist_locked": 0, + "filelist_changed": 0, + "sign_requested": 0, + "security_impact": "None", + "product_id": 79, + "is_brew": 1, + "status_updated_at": "2020-07-08T22:20:59Z", + "group_id": 436, + "created_at": "2020-06-24T10:13:27Z", + "updated_at": "2020-07-08T22:20:59Z", + "respin_count": 1, + "old_advisory": "RHBA-2020:56346-02", + "rating": 0, + "docs_responsibility_id": 1, + "quality_responsibility_id": 139, + "devel_responsibility_id": 3, + "is_valid": 1, + "current_state_index_id": 373778, + "text_only": false, + "publish_date_override": "2020-07-07T00:00:00Z", + "state_machine_rule_set_id": null, + "actual_ship_date": "2020-07-08T22:20:59Z", + "supports_multiple_product_destinations": false, + "security_approved": null, + "batch_id": null, + "is_batch_blocker": false, + "request_rcm_push_comment_id": null, + "content_types": [ + "docker" + ], + "embargo_undated": false, + "security_sla": null, + "cloned_from_id": null, + "is_followup": false, + "expected_publish_date": null, + "builds_updated_at": null, + "cve_mapping_validation_complete": null, + "prevent_auto_push_ready": false, + "suppress_push_request_jira": false, + "embargo_date": null, + "errata_id": 2807, + "publish_date": "2022-03-09T00:00:00Z", + "fulltype": "Red Hat Bug Fix Advisory", + "is_operator_hotfix": false, + "is_operator_prerelease": false, + "skip_customer_notifications": false, + "blocking_advisories": [], + "dependent_advisories": [], + "product": { + "id": 79, + "name": "Red Hat OpenShift Enterprise", + "short_name": "RHOSE" + } + } + }, + "id_field": "key", + "id_prefix": "jira:", + "type": "jira_issues", + "idsfixed": [], + "jira_issues": [], + "to_fetch": [] + } +} \ No newline at end of file diff --git a/tests/errata/data/dump b/tests/errata/data/dump index eb9d1ad2..70e0db9a 100755 --- a/tests/errata/data/dump +++ b/tests/errata/data/dump @@ -4,6 +4,11 @@ import xmlrpc.client import json import sys import yaml +from urllib.parse import urljoin + +import requests +import gssapi +from requests_gssapi import HTTPSPNEGOAuth DATADIR = os.path.dirname(__file__) @@ -24,6 +29,21 @@ def run(server_url, advisory_id): yaml.dump(data, fh) print("Wrote to", data_file) +def run_http_api(server_url, advisory_id, ca_path): + # This function expects a Kerberos ticket to be present + session = requests.Session() + session.auth = HTTPSPNEGOAuth() + session.verify = ca_path + + res = session.get(urljoin(server_url, f"/api/v1/erratum/{advisory_id}")) + res.raise_for_status() + + data_file = os.path.join(DATADIR, "%s.json" % advisory_id) + with open(data_file, "w") as fh: + json.dump(res.json(), fh, indent=4) + print("Wrote to", data_file) + if __name__ == "__main__": run(*sys.argv[1:]) + # run_http_api(*sys.argv[1:]) diff --git a/tests/errata/test_errata_containers.py b/tests/errata/test_errata_containers.py index 8a98601a..057ba303 100644 --- a/tests/errata/test_errata_containers.py +++ b/tests/errata/test_errata_containers.py @@ -1,10 +1,20 @@ import os from mock import patch +import json import pytest from pushsource import Source, ContainerImagePushItem, OperatorManifestPushItem +@pytest.fixture(autouse=True) +def baseline_errata_requests_mock(errata_requests_mock): + yield + +@pytest.fixture(autouse=True) +def fake_kerberos_auth(mocker): + mocker.patch("gssapi.Name") + mocker.patch("gssapi.Credentials.acquire") + mocker.patch("requests_gssapi.HTTPSPNEGOAuth", return_value=None) @pytest.fixture def source_factory(fake_errata_tool, fake_koji, koji_dir): diff --git a/tests/errata/test_errata_http_client.py b/tests/errata/test_errata_http_client.py new file mode 100644 index 00000000..245d8c63 --- /dev/null +++ b/tests/errata/test_errata_http_client.py @@ -0,0 +1,219 @@ +import mock +import logging +import subprocess + +import requests_mock +import pytest +import requests + +from pushsource._impl.backend.errata_source.errata_http_client import ErrataHTTPClient + + +@pytest.fixture(autouse=True) +def fake_temporary_file(mocker): + mock_file = mocker.patch("tempfile.NamedTemporaryFile") + mock_file.return_value.__enter__.return_value.name = "/temp/ccache_pushsource_errata_1234" + +def test_init(): + client = ErrataHTTPClient( + "https://errata.example.com/", "/path/to/keytab", "pub-errata@IPA.REDHAT.COM" + ) + + assert client.hostname == "https://errata.example.com/" + assert client.keytab_path == "/path/to/keytab" + assert client.principal == "pub-errata@IPA.REDHAT.COM" + assert client.ccache_filename == "/temp/ccache_pushsource_errata_1234" + + +@mock.patch.dict( + "os.environ", + { + "PUSHSOURCE_ERRATA_KEYTAB_PATH": "/path/to/keytab", + "PUSHSOURCE_ERRATA_PRINCIPAL": "pub-errata@IPA.REDHAT.COM", + }, +) +def test_init_env_vars(): + client = ErrataHTTPClient("https://errata.example.com/") + + assert client.hostname == "https://errata.example.com/" + assert client.keytab_path == "/path/to/keytab" + assert client.principal == "pub-errata@IPA.REDHAT.COM" + + +@mock.patch("subprocess.run") +def test_create_kerberos_ticket_already_exists(mock_run): + client = ErrataHTTPClient( + "https://errata.example.com/", "/path/to/keytab", "pub-errata@IPA.REDHAT.COM" + ) + + mock_run.return_value.stdout = "Default principal: pub-errata@IPA.REDHAT.COM\n" + mock_run.return_value.returncode = 0 + + client.create_kerberos_ticket() + mock_run.assert_called_once_with( + ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False + ) + + +@mock.patch("subprocess.run") +def test_create_kerberos_ticket_not_found(mock_run, caplog): + caplog.set_level(logging.INFO) + + client = ErrataHTTPClient( + "https://errata.example.com/", "/path/to/keytab", "pub-errata@IPA.REDHAT.COM" + ) + + ret1 = mock.MagicMock() + ret1.stdout = "No TGT exists" + ret1.returncode = 0 + ret2 = mock.MagicMock() + ret2.stdout = "success" + ret2.returncode = 0 + mock_run.side_effect = [ret1, ret2] + + client.create_kerberos_ticket() + assert mock_run.call_count == 2 + assert mock_run.call_args_list[0] == mock.call( + ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False + ) + assert mock_run.call_args_list[1] == mock.call( + [ + "kinit", + "pub-errata@IPA.REDHAT.COM", + "-k", + "-t", + "/path/to/keytab", + "-c", + "FILE:/temp/ccache_pushsource_errata_1234", + ], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + text=True, + check=False + ) + assert caplog.messages == ["Errata TGT doesn't exist, running kinit " + "for principal pub-errata@IPA.REDHAT.COM"] + + +@mock.patch("subprocess.run") +def test_create_kerberos_ticket_kinit_failed(mock_run, caplog): + caplog.set_level(logging.INFO) + + client = ErrataHTTPClient( + "https://errata.example.com/", "/path/to/keytab", "pub-errata@IPA.REDHAT.COM" + ) + + ret1 = mock.MagicMock() + ret1.stdout = "No TGT exists" + ret1.returncode = 0 + ret2 = mock.MagicMock() + ret2.stdout = "kinit failed" + ret2.returncode = 1 + mock_run.side_effect = [ret1, ret2] + + client.create_kerberos_ticket() + assert mock_run.call_count == 2 + assert mock_run.call_args_list[0] == mock.call( + ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False + ) + assert mock_run.call_args_list[1] == mock.call( + [ + "kinit", + "pub-errata@IPA.REDHAT.COM", + "-k", + "-t", + "/path/to/keytab", + "-c", + "FILE:/temp/ccache_pushsource_errata_1234", + ], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + text=True, + check=False + ) + assert caplog.messages == ["Errata TGT doesn't exist, running kinit " + "for principal pub-errata@IPA.REDHAT.COM", + "kinit has failed: 'kinit failed'"] + + +@mock.patch("subprocess.run") +def test_create_kerberos_ticket_skip(mock_run, caplog): + caplog.set_level(logging.INFO) + + client = ErrataHTTPClient("https://errata.example.com/") + + client.create_kerberos_ticket() + assert mock_run.call_count == 0 + assert caplog.messages == [ + "Errata principal or keytab path is not specified. Skipping creating TGT" + ] + + +@mock.patch("gssapi.Name") +@mock.patch("gssapi.Credentials.acquire") +@mock.patch("requests.Session") +@mock.patch("requests_gssapi.HTTPSPNEGOAuth") +def test_get_session(mock_auth, mock_session, mock_acquire, mock_name, caplog): + caplog.set_level(logging.DEBUG) + + client = ErrataHTTPClient( + "https://errata.example.com/", "/path/to/keytab", "pub-errata@IPA.REDHAT.COM" + ) + assert not hasattr(client._thread_local, "session") + + session = client.session + + mock_name.assert_called_once() + mock_acquire.assert_called_once_with( + name=mock_name.return_value, usage="initiate", store={"ccache": "FILE:/temp/ccache_pushsource_errata_1234"} + ) + mock_session.assert_called_once_with() + mock_auth.assert_called_once_with(creds=mock_acquire.return_value.creds) + + assert session == mock_session.return_value + assert client._thread_local.session == mock_session.return_value + + assert caplog.messages == ["Creating Errata requests session"] + +@mock.patch("gssapi.Name") +@mock.patch("gssapi.Credentials.acquire") +@mock.patch("requests.Session") +@mock.patch("requests_gssapi.HTTPSPNEGOAuth") +def test_get_session_already_exists(mock_auth, mock_session, mock_acquire, mock_name, caplog): + caplog.set_level(logging.DEBUG) + + client = ErrataHTTPClient( + "https://errata.example.com/", "/path/to/keytab", "pub-errata@IPA.REDHAT.COM" + ) + assert not hasattr(client._thread_local, "session") + session_mock = client._thread_local.session = mock.MagicMock() + session = client.session + + mock_name.assert_not_called() + mock_acquire.assert_not_called() + mock_session.assert_not_called() + mock_auth.assert_not_called() + + assert session == session_mock + assert caplog.messages == [] + + +def test_get_advisory_data(caplog): + caplog.set_level(logging.DEBUG) + + client = ErrataHTTPClient( + "https://errata.example.com/", "/path/to/keytab", "pub-errata@IPA.REDHAT.COM" + ) + client._thread_local.session = requests.Session() + with requests_mock.Mocker() as m: + m.get( + "https://errata.example.com/api/v1/erratum/RHSA-123456789", + json={"errata": "data"}, + ) + + data = client.get_advisory_data("RHSA-123456789") + + assert data == {"errata": "data"} + assert m.call_count == 1 + assert caplog.messages == [ + "Queried Errata HTTP API for RHSA-123456789", + "GET https://errata.example.com/api/v1/erratum/RHSA-123456789 200", + ] diff --git a/tests/test_registry.py b/tests/test_registry.py index b36543db..ae194be6 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -145,6 +145,7 @@ def test_registry_push_items(mocked_inspect, mocked_get_manifest): "registry.redhat.io/openshift/serverless-1-net-istio-controller-rhel8:1.1", ], dest_signing_key="1234abcde", + product_name="test-product", ) # Eagerly fetch with source: @@ -156,6 +157,7 @@ def test_registry_push_items(mocked_inspect, mocked_get_manifest): assert items[0].dest_signing_key == "1234abcde" assert items[0].source_tags == ["latest"] assert items[0].dest == ["repo1", "repo2"] + assert items[0].product_name == "test-product" assert ( items[1].name @@ -168,6 +170,7 @@ def test_registry_push_items(mocked_inspect, mocked_get_manifest): assert items[1].dest_signing_key == "1234abcde" assert items[1].source_tags == ["1.1"] assert items[1].dest == ["repo1", "repo2"] + assert items[1].product_name == "test-product" @patch("pushsource._impl.backend.registry_source.get_manifest") From 876410ce4083be5e555c8e6c5de8f1f7c1da448b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 11:11:48 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../errata_source/errata_http_client.py | 34 ++++++++--- .../backend/errata_source/errata_source.py | 13 +++-- .../_impl/backend/registry_source.py | 4 +- tests/baseline/test_baseline.py | 5 +- tests/conftest.py | 7 ++- tests/errata/data/dump | 1 + tests/errata/test_errata_containers.py | 3 + tests/errata/test_errata_http_client.py | 56 ++++++++++++++----- 8 files changed, 91 insertions(+), 32 deletions(-) diff --git a/src/pushsource/_impl/backend/errata_source/errata_http_client.py b/src/pushsource/_impl/backend/errata_source/errata_http_client.py index 905a3683..d7db4718 100644 --- a/src/pushsource/_impl/backend/errata_source/errata_http_client.py +++ b/src/pushsource/_impl/backend/errata_source/errata_http_client.py @@ -12,6 +12,7 @@ LOG = logging.getLogger("pushsource.errata_http_client") + class ErrataHTTPClient: """Class for performing HTTP API queries with Errata.""" @@ -31,7 +32,9 @@ def __init__(self, hostname: str, keytab_path: str = None, principal: str = None """ self.hostname = hostname # Generate a random filename for ccache - with tempfile.NamedTemporaryFile(prefix="ccache_pushsource_errata_", delete=False) as file: + with tempfile.NamedTemporaryFile( + prefix="ccache_pushsource_errata_", delete=False + ) as file: self.ccache_filename = file.name if keytab_path: @@ -54,17 +57,26 @@ def create_kerberos_ticket(self): This method is expected to be called before any HTTP queries to errata are made. """ if not self.keytab_path or not self.principal: - LOG.warning("Errata principal or keytab path is not specified. Skipping creating TGT") + LOG.warning( + "Errata principal or keytab path is not specified. Skipping creating TGT" + ) return result = subprocess.run( - ["klist", "-c", f"FILE:{self.ccache_filename}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False + ["klist", "-c", f"FILE:{self.ccache_filename}"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + check=False, ) regex_res = re.search(r"Default principal: (.*)\n", result.stdout) # if Kerberos ticket is not found, or the principal is incorrect if result.returncode or not regex_res or regex_res.group(1) != self.principal: - LOG.info("Errata TGT doesn't exist, running kinit for principal %s", self.principal) + LOG.info( + "Errata TGT doesn't exist, running kinit for principal %s", + self.principal, + ) result = subprocess.run( [ "kinit", @@ -75,8 +87,10 @@ def create_kerberos_ticket(self): "-c", f"FILE:{self.ccache_filename}", ], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - text=True, check=False + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + check=False, ) if result.returncode: LOG.warning("kinit has failed: '%s'", result.stdout) @@ -98,13 +112,15 @@ def session(self) -> requests.Session: LOG.debug("Creating Errata requests session") name = gssapi.Name(self.principal, gssapi.NameType.user) creds = gssapi.Credentials.acquire( - name=name, usage="initiate", store={"ccache": f"FILE:{self.ccache_filename}"} + name=name, + usage="initiate", + store={"ccache": f"FILE:{self.ccache_filename}"}, ).creds session = requests.Session() session.auth = requests_gssapi.HTTPSPNEGOAuth(creds=creds) self._thread_local.session = session - + return self._thread_local.session def get_advisory_data(self, advisory: str) -> dict: @@ -124,4 +140,4 @@ def get_advisory_data(self, advisory: str) -> dict: response = self.session.get(url) response.raise_for_status() - return response.json() \ No newline at end of file + return response.json() diff --git a/src/pushsource/_impl/backend/errata_source/errata_source.py b/src/pushsource/_impl/backend/errata_source/errata_source.py index 139514d8..ab282762 100644 --- a/src/pushsource/_impl/backend/errata_source/errata_source.py +++ b/src/pushsource/_impl/backend/errata_source/errata_source.py @@ -70,10 +70,10 @@ def __init__( This is intended to better support certain legacy code and will be removed when no longer needed. Only use this if you know that you need it. - + keytab_path (str): Kerberos keytab path for authenticating with Errata HTTP API. - + principal (str): Kerberos principal for authenticating with Errata HTTP API. @@ -285,7 +285,9 @@ def _push_items_from_appliance_image_list(self, erratum, appliance_image_list): return out - def _enrich_container_push_item(self, erratum, docker_file_list, item, product_name): + def _enrich_container_push_item( + self, erratum, docker_file_list, item, product_name + ): # metadata from koji doesn't contain info about where the image should be # pushed and a few other things - enrich it now errata_meta = docker_file_list.get(item.build) or {} @@ -332,7 +334,10 @@ def _enrich_container_push_item(self, erratum, docker_file_list, item, product_n # koji source provided basic info on container image, ET provides policy on # where/how it should be pushed, combine them both to get final push item return attr.evolve( - item, dest=dest, dest_signing_key=dest_signing_key, product_name=product_name + item, + dest=dest, + dest_signing_key=dest_signing_key, + product_name=product_name, ) def _push_items_from_rpms(self, erratum, rpm_list): diff --git a/src/pushsource/_impl/backend/registry_source.py b/src/pushsource/_impl/backend/registry_source.py index de5a1896..65880004 100644 --- a/src/pushsource/_impl/backend/registry_source.py +++ b/src/pushsource/_impl/backend/registry_source.py @@ -56,9 +56,9 @@ def __init__(self, image, dest=None, dest_signing_key=None, product_name=None): argument can affect the number of generated push items. For example, providing two keys would produce double the amount of push items as providing a single key. - + product_name (str) - If provided, this value will be used to populate + If provided, this value will be used to populate :meth:`~pushsource.ContainerImagePushItem.product_name` on generated push items. """ self._images = ["https://%s" % x for x in list_argument(image)] diff --git a/tests/baseline/test_baseline.py b/tests/baseline/test_baseline.py index cf4cd674..39651e14 100644 --- a/tests/baseline/test_baseline.py +++ b/tests/baseline/test_baseline.py @@ -78,6 +78,7 @@ def koji_test_backend(fake_koji, koji_dir): Source.reset() + @pytest.fixture(autouse=True) def fake_kerberos_auth(mocker): mocker.patch("gssapi.Name") @@ -93,7 +94,9 @@ def baseline_errata_requests_mock(errata_requests_mock): @pytest.fixture(scope="module", autouse=True) def errata_test_backend(fake_errata_tool, koji_test_backend): # erratatest backend is errata backend pointing at kojitest and our errata testdata - bound = Source.get_partial("errata:https://errata.example.com/", koji_source="kojitest:") + bound = Source.get_partial( + "errata:https://errata.example.com/", koji_source="kojitest:" + ) Source.register_backend("erratatest", bound) yield diff --git a/tests/conftest.py b/tests/conftest.py index 708baeda..7aafe0df 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,6 +18,7 @@ THIS_DIR = os.path.dirname(__file__) ERRATA_DATA_DIR = os.path.abspath(os.path.join(THIS_DIR, "./errata/data")) + @fixture def fake_errata_tool(): controller = FakeErrataToolController() @@ -105,6 +106,7 @@ def fake_koji(): def koji_dir(tmpdir): yield str(tmpdir.mkdir("koji")) + @fixture() def errata_requests_mock(requests_mock): for root, _, files in os.walk(ERRATA_DATA_DIR): @@ -113,10 +115,13 @@ def errata_requests_mock(requests_mock): path = os.path.join(root, filename) with open(path) as fh: data = json.load(fh) - requests_mock.get(f"/api/v1/erratum/{filename.rstrip('.json')}", json=data) # nosec B113 + requests_mock.get( + f"/api/v1/erratum/{filename.rstrip('.json')}", json=data + ) # nosec B113 yield + @fixture(autouse=True) def clean_backends(): """Reset any modifications of Source._BACKENDS performed during tests.""" diff --git a/tests/errata/data/dump b/tests/errata/data/dump index 70e0db9a..faf30f10 100755 --- a/tests/errata/data/dump +++ b/tests/errata/data/dump @@ -29,6 +29,7 @@ def run(server_url, advisory_id): yaml.dump(data, fh) print("Wrote to", data_file) + def run_http_api(server_url, advisory_id, ca_path): # This function expects a Kerberos ticket to be present session = requests.Session() diff --git a/tests/errata/test_errata_containers.py b/tests/errata/test_errata_containers.py index 057ba303..25cc947c 100644 --- a/tests/errata/test_errata_containers.py +++ b/tests/errata/test_errata_containers.py @@ -6,16 +6,19 @@ from pushsource import Source, ContainerImagePushItem, OperatorManifestPushItem + @pytest.fixture(autouse=True) def baseline_errata_requests_mock(errata_requests_mock): yield + @pytest.fixture(autouse=True) def fake_kerberos_auth(mocker): mocker.patch("gssapi.Name") mocker.patch("gssapi.Credentials.acquire") mocker.patch("requests_gssapi.HTTPSPNEGOAuth", return_value=None) + @pytest.fixture def source_factory(fake_errata_tool, fake_koji, koji_dir): ctor = Source.get_partial( diff --git a/tests/errata/test_errata_http_client.py b/tests/errata/test_errata_http_client.py index 245d8c63..b2dab997 100644 --- a/tests/errata/test_errata_http_client.py +++ b/tests/errata/test_errata_http_client.py @@ -12,7 +12,10 @@ @pytest.fixture(autouse=True) def fake_temporary_file(mocker): mock_file = mocker.patch("tempfile.NamedTemporaryFile") - mock_file.return_value.__enter__.return_value.name = "/temp/ccache_pushsource_errata_1234" + mock_file.return_value.__enter__.return_value.name = ( + "/temp/ccache_pushsource_errata_1234" + ) + def test_init(): client = ErrataHTTPClient( @@ -51,7 +54,11 @@ def test_create_kerberos_ticket_already_exists(mock_run): client.create_kerberos_ticket() mock_run.assert_called_once_with( - ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False + ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + check=False, ) @@ -74,7 +81,11 @@ def test_create_kerberos_ticket_not_found(mock_run, caplog): client.create_kerberos_ticket() assert mock_run.call_count == 2 assert mock_run.call_args_list[0] == mock.call( - ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False + ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + check=False, ) assert mock_run.call_args_list[1] == mock.call( [ @@ -86,12 +97,15 @@ def test_create_kerberos_ticket_not_found(mock_run, caplog): "-c", "FILE:/temp/ccache_pushsource_errata_1234", ], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, text=True, - check=False + check=False, ) - assert caplog.messages == ["Errata TGT doesn't exist, running kinit " - "for principal pub-errata@IPA.REDHAT.COM"] + assert caplog.messages == [ + "Errata TGT doesn't exist, running kinit " + "for principal pub-errata@IPA.REDHAT.COM" + ] @mock.patch("subprocess.run") @@ -113,7 +127,11 @@ def test_create_kerberos_ticket_kinit_failed(mock_run, caplog): client.create_kerberos_ticket() assert mock_run.call_count == 2 assert mock_run.call_args_list[0] == mock.call( - ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False + ["klist", "-c", "FILE:/temp/ccache_pushsource_errata_1234"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + check=False, ) assert mock_run.call_args_list[1] == mock.call( [ @@ -125,13 +143,16 @@ def test_create_kerberos_ticket_kinit_failed(mock_run, caplog): "-c", "FILE:/temp/ccache_pushsource_errata_1234", ], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, text=True, - check=False + check=False, ) - assert caplog.messages == ["Errata TGT doesn't exist, running kinit " - "for principal pub-errata@IPA.REDHAT.COM", - "kinit has failed: 'kinit failed'"] + assert caplog.messages == [ + "Errata TGT doesn't exist, running kinit " + "for principal pub-errata@IPA.REDHAT.COM", + "kinit has failed: 'kinit failed'", + ] @mock.patch("subprocess.run") @@ -163,7 +184,9 @@ def test_get_session(mock_auth, mock_session, mock_acquire, mock_name, caplog): mock_name.assert_called_once() mock_acquire.assert_called_once_with( - name=mock_name.return_value, usage="initiate", store={"ccache": "FILE:/temp/ccache_pushsource_errata_1234"} + name=mock_name.return_value, + usage="initiate", + store={"ccache": "FILE:/temp/ccache_pushsource_errata_1234"}, ) mock_session.assert_called_once_with() mock_auth.assert_called_once_with(creds=mock_acquire.return_value.creds) @@ -173,11 +196,14 @@ def test_get_session(mock_auth, mock_session, mock_acquire, mock_name, caplog): assert caplog.messages == ["Creating Errata requests session"] + @mock.patch("gssapi.Name") @mock.patch("gssapi.Credentials.acquire") @mock.patch("requests.Session") @mock.patch("requests_gssapi.HTTPSPNEGOAuth") -def test_get_session_already_exists(mock_auth, mock_session, mock_acquire, mock_name, caplog): +def test_get_session_already_exists( + mock_auth, mock_session, mock_acquire, mock_name, caplog +): caplog.set_level(logging.DEBUG) client = ErrataHTTPClient(