diff --git a/pytest_fixtures/component/taxonomy.py b/pytest_fixtures/component/taxonomy.py index ed2f6d547ad..ec9bce0c11f 100644 --- a/pytest_fixtures/component/taxonomy.py +++ b/pytest_fixtures/component/taxonomy.py @@ -77,9 +77,9 @@ def module_org_with_manifest(module_org): @pytest.fixture(scope='module') -def module_entitlement_manifest_org(module_org, module_entitlement_manifest): +def module_entitlement_manifest_org(module_org, module_entitlement_manifest, module_target_sat): """Creates an organization and uploads an entitlement mode manifest generated with manifester""" - upload_manifest(module_org.id, module_entitlement_manifest.content) + module_target_sat.upload_manifest(module_org.id, module_entitlement_manifest.content) return module_org @@ -90,10 +90,23 @@ def module_sca_manifest_org(module_org, module_sca_manifest): return module_org +@pytest.fixture(scope='module') +def module_extra_rhel_entitlement_manifest_org( + module_target_sat, + module_org, + module_extra_rhel_entitlement_manifest, +): + """Creates an organization and uploads an entitlement mode manifest generated by manifester and + containing more RHEL entitlements than the default entitlement manifest""" + module_org.sca_disable() + module_target_sat.upload_manifest(module_org.id, module_extra_rhel_entitlement_manifest.content) + return module_org + + @pytest.fixture(scope='function') -def function_entitlement_manifest_org(function_org, function_entitlement_manifest): +def function_entitlement_manifest_org(function_org, function_entitlement_manifest, target_sat): """Creates an organization and uploads an entitlement mode manifest generated with manifester""" - upload_manifest(function_org.id, function_entitlement_manifest.content) + target_sat.upload_manifest(function_org.id, function_entitlement_manifest.content) return function_org @@ -106,7 +119,7 @@ def upgrade_entitlement_manifest_org(function_org, upgrade_entitlement_manifest, return function_org -@pytest.fixture +@pytest.fixture(scope='function') def function_sca_manifest_org(function_org, function_sca_manifest, target_sat): """Creates an organization and uploads an SCA mode manifest generated with manifester""" upload_manifest(function_org.id, function_sca_manifest.content) diff --git a/robottelo/cli/factory.py b/robottelo/cli/factory.py index 8f884c13c82..3f0e0ea2066 100644 --- a/robottelo/cli/factory.py +++ b/robottelo/cli/factory.py @@ -66,6 +66,7 @@ from robottelo.cli.virt_who_config import VirtWhoConfig from robottelo.config import settings from robottelo.logging import logger +from robottelo.utils import clone from robottelo.utils import ssh from robottelo.utils.datafactory import valid_cron_expressions from robottelo.utils.decorators import cacheable @@ -1735,7 +1736,7 @@ def setup_org_for_a_custom_repo(options=None): } -def _setup_org_for_a_rh_repo(options=None): +def _setup_org_for_a_rh_repo(target_sat, options=None): """Sets up Org for the given Red Hat repository by: 1. Checks if organization and lifecycle environment were given, otherwise @@ -1774,10 +1775,10 @@ def _setup_org_for_a_rh_repo(options=None): else: env_id = options['lifecycle-environment-id'] # Clone manifest and upload it - with manifests.clone() as manifest: - ssh.get_client().put(manifest, manifest.filename) + with clone() as manifest: + target_sat.put(manifest.path, manifest.name) try: - Subscription.upload({'file': manifest.filename, 'organization-id': org_id}) + Subscription.upload({'file': manifest.name, 'organization-id': org_id}) except CLIReturnCodeError as err: raise CLIFactoryError(f'Failed to upload manifest\n{err.msg}') # Enable repo from Repository Set diff --git a/robottelo/host_helpers/repository_mixins.py b/robottelo/host_helpers/repository_mixins.py index 95a53964b36..5637a453997 100644 --- a/robottelo/host_helpers/repository_mixins.py +++ b/robottelo/host_helpers/repository_mixins.py @@ -6,7 +6,6 @@ import sys from robottelo import constants -from robottelo import manifests from robottelo.config import settings from robottelo.exceptions import DistroNotSupportedError from robottelo.exceptions import OnlyOneOSRepositoryAllowed @@ -660,7 +659,7 @@ def setup_content( if self.need_subscription: # upload manifest only when needed if upload_manifest and not self.organization_has_manifest(org_id): - manifests.upload_manifest_locked(org_id, interface=manifests.INTERFACE_CLI) + self.satellite.upload_manifest(org_id, interface='CLI') if not rh_subscriptions: # add the default subscription if no subscription provided rh_subscriptions = [constants.DEFAULT_SUBSCRIPTION_NAME] diff --git a/robottelo/host_helpers/satellite_mixins.py b/robottelo/host_helpers/satellite_mixins.py index 803cd055ee8..813de4f09e8 100644 --- a/robottelo/host_helpers/satellite_mixins.py +++ b/robottelo/host_helpers/satellite_mixins.py @@ -15,6 +15,7 @@ from robottelo.host_helpers.api_factory import APIFactory from robottelo.host_helpers.cli_factory import CLIFactory from robottelo.logging import logger +from robottelo.manifests import clone from robottelo.utils.installer import InstallerCommand @@ -127,6 +128,41 @@ def md5_by_url(self, url): f'wget -qO - {url} | tee {filename} | md5sum | awk \'{{print $1}}\'' ).stdout + def upload_manifest(self, org_id, manifest=None, interface='API', timeout=None): + """Upload a manifest using the requested interface. + + :type org_id: int + :type manifest: Manifester object or None + :type interface: str + :type timeout: int + + :returns: the manifest upload result + + """ + if manifest is None: + manifest = clone() + if timeout is None: + # Set the timeout to 1500 seconds to align with the API timeout. + timeout = 1500000 + if interface == 'CLI': + if isinstance(manifest.content, bytes): + self.put(f'{manifest.path}', f'{manifest.name}') + result = self.cli.Subscription.upload( + {'file': manifest.name, 'organization-id': org_id}, timeout=timeout + ) + else: + self.put(manifest, manifest.filename) + result = self.cli.Subscription.upload( + {'file': manifest.filename, 'organization-id': org_id}, timeout=timeout + ) + else: + if not isinstance(manifest, bytes): + manifest = manifest.content + result = self.api.Subscription().upload( + data={'organization_id': org_id}, files={'content': manifest} + ) + return result + def is_sca_mode_enabled(self, org_id): """This method checks whether Simple Content Access (SCA) mode is enabled for a given organization. diff --git a/robottelo/utils/__init__.py b/robottelo/utils/__init__.py index c49f620a970..a6949ada472 100644 --- a/robottelo/utils/__init__.py +++ b/robottelo/utils/__init__.py @@ -1,14 +1,23 @@ # General utility functions which does not fit into other util modules OR # Independent utility functions that doesnt need separate module import base64 +import io +import json import os import re +import time +import uuid +import zipfile from pathlib import Path +import requests from cryptography.hazmat.backends import default_backend as crypto_default_backend +from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import serialization as crypto_serialization +from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.asymmetric import rsa +from robottelo.config import settings from robottelo.constants import Colored from robottelo.exceptions import InvalidVaultURLForOIDC @@ -80,3 +89,171 @@ def slugify_component(string, keep_hyphens=True): if not keep_hyphens: string = string.replace('-', '_') return re.sub("[^-_a-zA-Z0-9]", "", string.lower()) + + +# Manifest Cloning +class ManifestCloner: + """Manifest cloning utility class.""" + + def __init__(self, template=None, private_key=None, signing_key=None): + self.template = template + self.signing_key = signing_key + self.private_key = private_key + + def _download_manifest_info(self, name='default'): + """Download and cache the manifest information.""" + if self.template is None: + self.template = {} + self.template[name] = requests.get(settings.fake_manifest.url[name], verify=False).content + if self.signing_key is None: + self.signing_key = requests.get(settings.fake_manifest.key_url, verify=False).content + if self.private_key is None: + self.private_key = crypto_serialization.load_pem_private_key( + self.signing_key, password=None, backend=crypto_default_backend() + ) + + def manifest_clone(self, org_environment_access=False, name='default'): + """Clones a RedHat-manifest file. + + Change the consumer ``uuid`` and sign the new manifest with + signing key. The certificate for the key must be installed on the + candlepin server in order to accept uploading the cloned + manifest. + + :param org_environment_access: Whether to modify consumer content + access mode to org_environment (Golden ticket enabled manifest). + + :param name: which manifest url to clone (named key-value pairs + are defined as fake_manifest.url value in robottelo.properties + (default: 'default') + + :return: A file-like object (``BytesIO`` on Python 3 and + ``StringIO`` on Python 2) with the contents of the cloned + manifest. + """ + if self.signing_key is None or self.template is None or self.template.get(name) is None: + self._download_manifest_info(name) + + template_zip = zipfile.ZipFile(io.BytesIO(self.template[name])) + # Extract the consumer_export.zip from the template manifest. + consumer_export_zip = zipfile.ZipFile(io.BytesIO(template_zip.read('consumer_export.zip'))) + + # Generate a new consumer_export.zip file changing the consumer + # uuid. + consumer_export = io.BytesIO() + with zipfile.ZipFile(consumer_export, 'w') as new_consumer_export_zip: + for name in consumer_export_zip.namelist(): + if name == 'export/consumer.json': + consumer_data = json.loads(consumer_export_zip.read(name).decode('utf-8')) + consumer_data['uuid'] = str(uuid.uuid1()) + if org_environment_access: + consumer_data['contentAccessMode'] = 'org_environment' + consumer_data['owner'][ + 'contentAccessModeList' + ] = 'entitlement,org_environment' + new_consumer_export_zip.writestr(name, json.dumps(consumer_data)) + else: + new_consumer_export_zip.writestr(name, consumer_export_zip.read(name)) + + # Generate a new manifest.zip file with the generated + # consumer_export.zip and new signature. + manifest = io.BytesIO() + with zipfile.ZipFile(manifest, 'w', zipfile.ZIP_DEFLATED) as manifest_zip: + consumer_export.seek(0) + manifest_zip.writestr('consumer_export.zip', consumer_export.read()) + consumer_export.seek(0) + signature = self.private_key.sign( + consumer_export.read(), padding.PKCS1v15(), hashes.SHA256() + ) + manifest_zip.writestr('signature', signature) + # Make sure that the file-like object is at the beginning and + # ready to be read. + manifest.seek(0) + return manifest + + def original(self, name='default'): + """Returns the original manifest as a file-like object. + + :param name: A name of the manifest as defined in robottelo.properties + + Be aware that using the original manifest and not removing it + afterwards will make it impossible to import it to any other + Organization. + + Make sure to close the returned file-like object in order to clean up + the memory used to store it. + """ + if self.signing_key is None or self.template is None or self.template.get(name) is None: + self._download_manifest_info(name) + return io.BytesIO(self.template[name]) + + +# Cache the ManifestCloner in order to avoid downloading the manifest template +# every single time. +_manifest_cloner = ManifestCloner() + + +class Manifest: + """Class that holds the contents of a manifest with a generated filename + based on ``time.time``. + + To ensure that the manifest content is closed use this class as a context + manager with the ``with`` statement:: + + with Manifest() as manifest: + # my fancy stuff + """ + + def __init__(self, content=None, filename=None, org_environment_access=False, name='default'): + self._content = content + self.filename = filename + + if self._content is None: + self._content = _manifest_cloner.manifest_clone( + org_environment_access=org_environment_access, name=name + ) + if self.filename is None: + self.filename = f'/var/tmp/manifest-{int(time.time())}.zip' + + @property + def content(self): + if not self._content.closed: + # Make sure that the content is always ready to read + self._content.seek(0) + return self._content + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + if not self.content.closed: + self.content.close() + + +def clone(org_environment_access=False, name='default'): + """Clone the cached manifest and return a ``Manifest`` object. + + :param org_environment_access: Whether to modify consumer content + access mode to org_environment (Golden ticket enabled manifest). + + :param name: key name of the fake_manifests.url dict defined in + robottelo.properties + + Is hightly recommended to use this with the ``with`` statement to make that + the content of the manifest (file-like object) is closed properly:: + + with clone() as manifest: + # my fancy stuff + """ + + return Manifest(org_environment_access=org_environment_access, name=name) + + +def original_manifest(name='default'): + """Returns a ``Manifest`` object filed with the template manifest. + + :param name: key name of the fake_manifests.url dict defined in + robottelo.properties + """ + + return Manifest(_manifest_cloner.original(name=name)) diff --git a/tests/foreman/cli/test_activationkey.py b/tests/foreman/cli/test_activationkey.py index db9667c147a..dd597c8861b 100644 --- a/tests/foreman/cli/test_activationkey.py +++ b/tests/foreman/cli/test_activationkey.py @@ -751,7 +751,9 @@ def test_positive_add_custom_product(module_org): @pytest.mark.tier3 @pytest.mark.upgrade @pytest.mark.skipif((not settings.robottelo.REPOS_HOSTING_URL), reason='Missing repos_hosting_url') -def test_positive_add_redhat_and_custom_products(module_org): +def test_positive_add_redhat_and_custom_products( + module_target_sat, function_entitlement_manifest_org +): """Test if RH/Custom product can be associated to Activation key :id: 74c77426-18f5-4abb-bca9-a2135f7fcc1f @@ -790,8 +792,8 @@ def test_positive_add_redhat_and_custom_products(module_org): 'lifecycle-environment-id': result['lifecycle-environment-id'], } ) - repo = Repository.info({'id': result['repository-id']}) - content = ActivationKey.product_content( + repo = module_target_sat.cli.Repository.info({'id': result['repository-id']}) + content = module_target_sat.cli.ActivationKey.product_content( {'id': result['activationkey-id'], 'organization-id': org['id']} ) assert len(content) == 2 @@ -837,7 +839,7 @@ def test_positive_delete_manifest(function_org): @pytest.mark.run_in_one_thread @pytest.mark.skip_if_not_set('fake_manifest') @pytest.mark.tier2 -def test_positive_delete_subscription(module_manifest_org): +def test_positive_delete_subscription(function_entitlement_manifest_org, module_target_sat): """Check if deleting a subscription removes it from Activation key :id: bbbe4641-bfb0-48d6-acfc-de4294b18c15 @@ -847,16 +849,17 @@ def test_positive_delete_subscription(module_manifest_org): :CaseLevel: Integration """ - new_ak = make_activation_key({'organization-id': module_manifest_org.id}) + new_ak = make_activation_key({'organization-id': function_entitlement_manifest_org.id}) subscription_result = Subscription.list( - {'organization-id': module_manifest_org.id, 'order': 'id desc'}, per_page=False + {'organization-id': function_entitlement_manifest_org.id, 'order': 'id desc'}, + per_page=False, ) result = ActivationKey.add_subscription( {'id': new_ak['id'], 'subscription-id': subscription_result[-1]['id']} ) assert 'Subscription added to activation key.' in result ak_subs_info = ActivationKey.subscriptions( - {'id': new_ak['id'], 'organization-id': module_manifest_org.id} + {'id': new_ak['id'], 'organization-id': function_entitlement_manifest_org.id} ) assert subscription_result[-1]['name'] in ak_subs_info result = ActivationKey.remove_subscription( @@ -864,7 +867,7 @@ def test_positive_delete_subscription(module_manifest_org): ) assert 'Subscription removed from activation key.' in result ak_subs_info = ActivationKey.subscriptions( - {'id': new_ak['id'], 'organization-id': module_manifest_org.id} + {'id': new_ak['id'], 'organization-id': function_entitlement_manifest_org.id} ) assert subscription_result[-1]['name'] not in ak_subs_info @@ -1092,7 +1095,7 @@ def test_positive_remove_host_collection_by_name(module_org, host_col): @pytest.mark.tier2 -def test_create_ak_with_syspurpose_set(module_org, module_manifest_org): +def test_create_ak_with_syspurpose_set(module_entitlement_manifest_org, module_target_sat): """Test that an activation key can be created with system purpose values set. :id: ac8931e5-7089-494a-adac-cee2a8ab57ee @@ -1114,7 +1117,7 @@ def test_create_ak_with_syspurpose_set(module_org, module_manifest_org): 'purpose-role': "test-role", 'purpose-usage': "test-usage", 'service-level': "Self-Support", - 'organization-id': module_manifest_org.id, + 'organization-id': module_entitlement_manifest_org.id, } ) assert new_ak['system-purpose']['purpose-addons'] == "test-addon1, test-addon2" @@ -1130,10 +1133,12 @@ def test_create_ak_with_syspurpose_set(module_org, module_manifest_org): 'purpose-role': '', 'purpose-usage': '', 'service-level': '', - 'organization-id': module_org.id, + 'organization-id': module_entitlement_manifest_org.id, } ) - updated_ak = ActivationKey.info({'id': new_ak['id'], 'organization-id': module_org.id}) + updated_ak = ActivationKey.info( + {'id': new_ak['id'], 'organization-id': module_entitlement_manifest_org.id} + ) assert updated_ak['system-purpose']['purpose-addons'] == '' assert updated_ak['system-purpose']['purpose-role'] == '' assert updated_ak['system-purpose']['purpose-usage'] == '' diff --git a/tests/foreman/cli/test_contentaccess.py b/tests/foreman/cli/test_contentaccess.py index 50067ae4d0e..387c2a6308f 100644 --- a/tests/foreman/cli/test_contentaccess.py +++ b/tests/foreman/cli/test_contentaccess.py @@ -19,7 +19,6 @@ import pytest from nailgun import entities -from robottelo import manifests from robottelo.api.utils import promote from robottelo.cli.host import Host from robottelo.cli.package import Package @@ -28,6 +27,7 @@ from robottelo.constants import REAL_RHEL7_0_2_PACKAGE_FILENAME from robottelo.constants import REAL_RHEL7_0_2_PACKAGE_NAME from robottelo.constants import REPOS +from robottelo.utils import clone pytestmark = [ pytest.mark.skipif( @@ -170,7 +170,9 @@ def test_positive_erratum_installable(vm): @pytest.mark.tier2 -def test_negative_rct_not_shows_golden_ticket_enabled(target_sat): +def test_negative_rct_not_shows_golden_ticket_enabled( + target_sat, function_org, function_entitlement_manifest +): """Assert restricted manifest has no Golden Ticket enabled . :id: 754c1be7-468e-4795-bcf9-258a38f3418b @@ -185,11 +187,11 @@ def test_negative_rct_not_shows_golden_ticket_enabled(target_sat): :CaseImportance: High """ - # need a clean org for a new manifest - org = entities.Organization().create() # upload organization manifest with org environment access disabled - manifest = manifests.clone() - manifests.upload_manifest_locked(org.id, manifest, interface=manifests.INTERFACE_CLI) + target_sat.upload_manifest(function_org.id, function_entitlement_manifest, interface='CLI') + result = target_sat.execute(f'rct cat-manifest {function_entitlement_manifest.name}') + manifest = clone() + target_sat.upload_manifest(function_org.id, manifest, interface='CLI') result = target_sat.execute(f'rct cat-manifest {manifest.filename}') assert result.status == 0 assert 'Content Access Mode: Simple Content Access' not in result.stdout diff --git a/tests/foreman/cli/test_satellitesync.py b/tests/foreman/cli/test_satellitesync.py index 1438b742524..a47f9c9fa96 100644 --- a/tests/foreman/cli/test_satellitesync.py +++ b/tests/foreman/cli/test_satellitesync.py @@ -949,6 +949,8 @@ def test_positive_export_import_redhat_cv( manifests.upload_manifest_locked( importing_org['id'], interface=manifests.INTERFACE_CLI, timeout=7200000 ) + importing_org.sca_disable() + target_sat.upload_manifest(importing_org['id'], interface='CLI', timeout=7200000) # set disconnected mode Settings.set({'name': 'subscription_connection_enabled', 'value': "No"}) ContentImport.version({'organization-id': importing_org['id'], 'path': import_path}) @@ -1062,6 +1064,9 @@ def test_positive_export_import_redhat_cv_with_huge_contents( manifests.upload_manifest_locked( importing_org['id'], interface=manifests.INTERFACE_CLI, timeout=7200000 ) + + importing_org.sca_disable() + target_sat.upload_manifest(importing_org['id'], interface='CLI', timeout=7200000) # set disconnected mode Settings.set({'name': 'subscription_connection_enabled', 'value': "No"}) ContentImport.version( diff --git a/tests/foreman/cli/test_subscription.py b/tests/foreman/cli/test_subscription.py index 645cfcd4481..bdc1b748961 100644 --- a/tests/foreman/cli/test_subscription.py +++ b/tests/foreman/cli/test_subscription.py @@ -33,15 +33,16 @@ from robottelo.constants import PRDS from robottelo.constants import REPOS from robottelo.constants import REPOSET +from robottelo.utils import clone pytestmark = [pytest.mark.run_in_one_thread] @pytest.fixture(scope='module') -def golden_ticket_host_setup(request, module_org): - with manifests.clone(name='golden_ticket') as manifest: - upload_manifest(module_org.id, manifest.content) +def golden_ticket_host_setup(request, module_org, module_target_sat): + with clone(name='golden_ticket') as manifest: + module_target_sat.upload_manifest(module_org.id, manifest.content) new_product = make_product({'organization-id': module_org.id}) new_repo = make_repository({'product-id': new_product['id']}) Repository.synchronize({'id': new_repo['id']}) @@ -57,9 +58,9 @@ def golden_ticket_host_setup(request, module_org): @pytest.fixture(scope='function') -def manifest_clone_upload(function_org): - with manifests.clone() as cloned_manifest: - upload_manifest(function_org.id, cloned_manifest.content) +def manifest_clone_upload(function_org, target_sat): + with clone() as cloned_manifest: + target_sat.upload_manifest(function_org.id, cloned_manifest.content) yield diff --git a/tests/foreman/endtoend/test_api_endtoend.py b/tests/foreman/endtoend/test_api_endtoend.py index c3707f4a673..64d95d45fb0 100644 --- a/tests/foreman/endtoend/test_api_endtoend.py +++ b/tests/foreman/endtoend/test_api_endtoend.py @@ -38,6 +38,7 @@ from robottelo.config import settings from robottelo.config import user_nailgun_config from robottelo.constants.repos import CUSTOM_RPM_REPO +from robottelo.utils import clone from robottelo.utils.issue_handlers import is_open diff --git a/tests/foreman/ui/test_contentview.py b/tests/foreman/ui/test_contentview.py index bb8ee5e2df9..8c0bd0e4bff 100644 --- a/tests/foreman/ui/test_contentview.py +++ b/tests/foreman/ui/test_contentview.py @@ -969,7 +969,9 @@ def test_positive_publish_with_rh_content(session): @pytest.mark.skip_if_not_set('fake_manifest') @pytest.mark.tier2 @pytest.mark.skipif((not settings.robottelo.REPOS_HOSTING_URL), reason='Missing repos_hosting_url') -def test_positive_publish_composite_with_custom_content(session): +def test_positive_publish_composite_with_custom_content( + session, function_entitlement_manifest_org, target_sat +): """Attempt to publish composite content view containing custom content :id: 73947204-408e-4e2e-b87f-ba2e52ee50b6 diff --git a/tests/foreman/ui/test_reporttemplates.py b/tests/foreman/ui/test_reporttemplates.py index d76e250cf93..8b8c863840f 100644 --- a/tests/foreman/ui/test_reporttemplates.py +++ b/tests/foreman/ui/test_reporttemplates.py @@ -27,10 +27,7 @@ from lxml import etree from nailgun import entities -from robottelo import manifests -from robottelo.api.utils import enable_rhrepo_and_fetchid from robottelo.api.utils import promote -from robottelo.api.utils import upload_manifest from robottelo.config import robottelo_tmp_dir from robottelo.constants import DEFAULT_SUBSCRIPTION_NAME from robottelo.constants import PRDS @@ -41,12 +38,11 @@ @pytest.fixture(scope='module') -def setup_content(module_org): - with manifests.clone() as manifest: - upload_manifest(module_org.id, manifest.content) - rh_repo_id = enable_rhrepo_and_fetchid( +def setup_content(module_entitlement_manifest_org, module_target_sat): + org = module_entitlement_manifest_org + rh_repo_id = module_target_sat.api_factory.enable_rhrepo_and_fetchid( basearch='x86_64', - org_id=module_org.id, + org_id=org.id, product=PRDS['rhel'], repo=REPOS['rhst7']['name'], reposet=REPOSET['rhst7'], @@ -54,27 +50,30 @@ def setup_content(module_org): ) rh_repo = entities.Repository(id=rh_repo_id).read() rh_repo.sync() - custom_product = entities.Product(organization=module_org).create() + custom_product = entities.Product(organization=org).create() custom_repo = entities.Repository( name=gen_string('alphanumeric').upper(), product=custom_product ).create() custom_repo.sync() - lce = entities.LifecycleEnvironment(organization=module_org).create() + lce = entities.LifecycleEnvironment(organization=org).create() cv = entities.ContentView( - organization=module_org, + organization=org, repository=[rh_repo_id, custom_repo.id], ).create() cv.publish() cvv = cv.read().version[0].read() promote(cvv, lce.id) ak = entities.ActivationKey( - content_view=cv, organization=module_org, environment=lce, auto_attach=True + content_view=cv, + organization=org, + environment=lce, + auto_attach=True, ).create() - subscription = entities.Subscription(organization=module_org).search( + subscription = entities.Subscription(organization=org).search( query={'search': f'name="{DEFAULT_SUBSCRIPTION_NAME}"'} )[0] ak.add_subscriptions(data={'quantity': 1, 'subscription_id': subscription.id}) - return module_org, ak + return org, ak @pytest.mark.tier3 diff --git a/tests/upgrades/test_subscription.py b/tests/upgrades/test_subscription.py index 75a3f49fee5..1e3a68d5359 100644 --- a/tests/upgrades/test_subscription.py +++ b/tests/upgrades/test_subscription.py @@ -128,7 +128,6 @@ def test_pre_subscription_scenario_auto_attach( content_view=content_view, organization=org, environment=lce, - auto_attach=False, ).create() activation_key.add_subscriptions(data={'subscription_id': subscription[0].id}) rhel_contenthost.install_katello_ca(target_sat)