def host( rhel7_contenthost_module, module_manifest_org, dev_lce, qe_lce, custom_repo, module_ak, module_cv, ): # Create client machine and register it to satellite with rhel_7_partial_ak rhel7_contenthost_module.install_katello_ca() # Register, enable tools repo and install katello-host-tools. rhel7_contenthost_module.register_contenthost(module_manifest_org.label, module_ak.name) rhel7_contenthost_module.enable_repo(REPOS['rhst7']['id']) rhel7_contenthost_module.install_katello_host_tools() # AK added custom repo for errata package, just install it. rhel7_contenthost_module.execute(f'yum install -y {FAKE_4_CUSTOM_PACKAGE}') rhel7_contenthost_module.execute('katello-package-upload') host = entities.Host().search( query={'search': f'name={rhel7_contenthost_module.hostname}'}) # Force host to generate or refresh errata applicability call_entity_method_with_timeout(host[0].errata_applicability, timeout=600) # Add filter of type include but do not include anything. # this will hide all RPMs from selected erratum before publishing. entities.RPMContentViewFilter(content_view=module_cv, inclusion=True, name='Include Nothing').create() module_cv.publish() module_cv = module_cv.read() return rhel7_contenthost_module
def test_post_user_scenario_capsule_sync(self): """Post-upgrade scenario that sync capsule from satellite and then verifies if the repo/rpm of pre-upgrade scenario is synced to capsule :id: postupgrade-eb8970fa-98cc-4a99-99fb-1c12c4e319c9 :steps: 1. Run capsule sync post upgrade. 2. Check if the repo/rpm is been synced to capsule. :expectedresults: 1. The capsule sync should be successful 2. The repos/rpms from satellite should be synced to satellite """ env_name = get_entity_data(self.__class__.__name__)['env_name'] org_name = (entities.Organization().search( query={'search': 'id={}'.format(self.org_id)})[0].label) capsule = entities.SmartProxy().search( query={'search': 'name={}'.format(self.cap_host)})[0] call_entity_method_with_timeout( entities.Capsule(id=capsule.id).content_sync, timeout=3600) result = execute( lambda: run('[ -f /var/lib/pulp/published/yum/http/repos/' '{0}/{1}/{2}/custom/{3}/{4}/Packages/b/{5} ]; echo $?'. format(org_name, env_name, self.cv_name, self. prod_name, self.repo_name, self.rpm_name)), host=self.cap_host, )[self.cap_host] self.assertEqual('0', result)
def _publish_content_view(self, org, repolist): """publish content view and return content view""" content_view = entities.ContentView(organization=org).create() content_view.repository = repolist content_view = content_view.update(['repository']) call_entity_method_with_timeout(content_view.publish, timeout=3400) content_view = content_view.read() return content_view
def test_post_user_scenario_capsule_sync( self, request, dependent_scenario_name, target_sat, default_org ): """Post-upgrade scenario that sync capsule from satellite and then verifies if the repo/rpm of pre-upgrade scenario is synced to capsule :id: postupgrade-eb8970fa-98cc-4a99-99fb-1c12c4e319c9 :steps: 1. Run capsule sync post upgrade. 2. Check if the repo/rpm is been synced to capsule. :expectedresults: 1. The capsule sync should be successful 2. The repos/rpms from satellite should be synced to satellite """ request.addfinalizer(lambda: cleanup(content_view, repo, product)) pre_test_name = dependent_scenario_name rpm_name = rpm1.split('/')[-1] cap_host = settings.upgrade.capsule_hostname activation_key = ( settings.upgrade.capsule_ak[settings.upgrade.os] or settings.upgrade.custom_capsule_ak[settings.upgrade.os] ) ak = target_sat.api.ActivationKey(organization=default_org.id).search( query={'search': f'name={activation_key}'} )[0] repo = target_sat.api.Repository(organization=default_org.id).search( query={'search': f'name={pre_test_name}_repo'} )[0] product = target_sat.api.Product(organization=default_org.id).search( query={'search': f'name={pre_test_name}_prod'} )[0] env_name = ak.environment.read() org_name = env_name.organization.read_json()['label'] content_view = target_sat.api.ContentView(organization=f'{default_org.id}').search( query={'search': f'name={pre_test_name}_cv'} )[0] capsule = target_sat.api.SmartProxy().search(query={'search': f'name={cap_host}'})[0] call_entity_method_with_timeout( target_sat.api.Capsule(id=capsule.id).content_sync, timeout=3600 ) result = execute( lambda: run( f'[ -f /var/lib/pulp/published/yum/http/repos/' f'{org_name}/{env_name.name}/{content_view.name}/custom/{pre_test_name}_prod/' f'{pre_test_name}_repo/Packages/b/{rpm_name} ]; echo $?' ), host=cap_host, )[cap_host] assert result == '0'
def _create_custom_tools_repos(self, product): """Create custom tools repo and sync it""" tools_repo_url = settings.sattools_repo[DISTRO_RHEL7] if None in [tools_repo_url]: raise ValueError('The Tools Repo URL {} is not provided!'.format(self.client_os)) tools_repo = entities.Repository( product=product, content_type='yum', url=tools_repo_url ).create() call_entity_method_with_timeout(tools_repo.sync, timeout=1400) return tools_repo
def _create_custom_rhel_tools_repos(self, product): """Install packge on docker content host.""" rhel_repo_url = settings.rhel7_os tools_repo_url = settings.sattools_repo[DISTRO_RHEL7] if None in [rhel_repo_url, tools_repo_url]: raise ValueError('The rhel7_os or tools_rhel7 Repo url is not set in settings!') tools_repo = entities.Repository( product=product, content_type='yum', url=tools_repo_url).create() rhel_repo = entities.Repository( product=product, content_type='yum', url=rhel_repo_url).create() call_entity_method_with_timeout(rhel_repo.sync, timeout=3000) call_entity_method_with_timeout(tools_repo.sync, timeout=3000) return tools_repo, rhel_repo
def test_positive_sync_kickstart_repo(self, module_manifest_org, default_sat): """No encoding gzip errors on kickstart repositories sync. :id: dbdabc0e-583c-4186-981a-a02844f90412 :expectedresults: No encoding gzip errors present in /var/log/messages. :CaseLevel: Integration :customerscenario: true :steps: 1. Sync a kickstart repository. 2. After the repo is synced, change the download policy to immediate. 3. Sync the repository again. 4. Assert that no errors related to encoding gzip are present in /var/log/messages. 5. Assert that sync was executed properly. :CaseComponent: Pulp :Assignee: ltran :BZ: 1687801 """ rh_repo_id = enable_rhrepo_and_fetchid( basearch='x86_64', org_id=module_manifest_org.id, product=constants.PRDS['rhel8'], repo=constants.REPOS['rhel8_bos_ks']['name'], reposet=constants.REPOSET['rhel8_bos_ks'], releasever='8.4', ) rh_repo = entities.Repository(id=rh_repo_id).read() rh_repo.sync() rh_repo.download_policy = 'immediate' rh_repo = rh_repo.update(['download_policy']) call_entity_method_with_timeout(rh_repo.sync, timeout=600) result = default_sat.execute( 'grep pulp /var/log/messages | grep failed | grep encoding | grep gzip' ) assert result.status == 1 assert not result.stdout rh_repo = rh_repo.read() assert rh_repo.content_counts['package'] > 0 assert rh_repo.content_counts['package_group'] > 0 assert rh_repo.content_counts['rpm'] > 0
def publish_content_view(org=None, repolist=None): """ publish content view and return content view :param: str org: Name of the organisation :param: str repolist: Name of the repolist :return: Return content view """ content_view = entities.ContentView(organization=org).create() content_view.repository = repolist if type(repolist) is list else [repolist] content_view = content_view.update(['repository']) call_entity_method_with_timeout(content_view.publish, timeout=3400) content_view = content_view.read() return content_view
def test_post_user_scenario_capsule_sync_puppet_repo(self, request): """Post-upgrade scenario that creates and sync repository with puppet modules, sync capsule with satellite and verifies it's status. :id: postupgrade-7c597e9d-8db9-455e-bd19-acb5efa990a7 :steps: 1. Post Upgrade , Sync a puppet repo, Add to C.V. in Satellite. 2. Run Capsule sync. 3. Check Capsule sync status. :expectedresults: Capsule sync should complete successfully with puppet repo content. """ request.addfinalizer(lambda: cleanup(content_view, repo, product)) cap_host = settings.upgrade.rhev_cap_host or settings.upgrade.capsule_hostname org = entities.Organization().search( query={'search': f'name="{DEFAULT_ORG}"'})[0] lc_env = entities.LifecycleEnvironment(organization=org).search( query={'search': 'name="{}"'.format('Dev')})[0] product = entities.Product(organization=org).create() repo = entities.Repository(product=product, content_type='puppet', url=CUSTOM_PUPPET_REPO).create() repo.sync() module = repo.puppet_modules() content_view = entities.ContentView(organization=org).create() entities.ContentViewPuppetModule( author=module['results'][0]['author'], name=module['results'][0]['name'], content_view=content_view, ).create() entities.ContentViewPuppetModule( author=module['results'][1]['author'], name=module['results'][1]['name'], content_view=content_view, ).create() content_view.publish() promote(content_view.read().version[0], lc_env.id) # Run a Capsule sync capsule = entities.SmartProxy().search( query={'search': f'name={cap_host}'})[0] call_entity_method_with_timeout( entities.Capsule(id=capsule.id).content_sync, timeout=3600) sync_status = entities.Capsule(id=capsule.id).content_get_sync() assert sync_status['active_sync_tasks'] assert sync_status['last_failed_sync_tasks']
def test_positive_sync_kickstart_repo(self, default_sat): """No encoding gzip errors on kickstart repositories sync. :id: dbdabc0e-583c-4186-981a-a02844f90412 :expectedresults: No encoding gzip errors present in /var/log/messages. :CaseLevel: Integration :customerscenario: true :steps: 1. Sync a kickstart repository. 2. After the repo is synced, change the download policy to immediate. 3. Sync the repository again. 4. Assert that no errors related to encoding gzip are present in /var/log/messages. 5. Assert that sync was executed properly. :CaseComponent: Pulp :Assignee: ltran :BZ: 1687801 """ org = entities.Organization().create() product = entities.Product(organization=org).create() repo = entities.Repository( product=product, url=constants.repos.CUSTOM_KICKSTART_REPO).create() repo.sync() repo.download_policy = 'immediate' repo = repo.update(['download_policy']) call_entity_method_with_timeout(repo.sync, timeout=600) result = default_sat.execute( 'grep pulp /var/log/messages | grep failed | grep encoding | grep gzip' ) assert result.status == 1 assert not result.stdout repo = repo.read() assert repo.content_counts['package'] > 0 assert repo.content_counts['package_group'] > 0 assert repo.content_counts['rpm'] > 0
def test_post_user_scenario_capsule_sync_3(self): """ Post-upgrade scenario that creates and sync repository with puppet modules, sync capsule with satellite and verifies it's status. :id: postupgrade-7c597e9d-8db9-455e-bd19-acb5efa990a7 :steps: 1. Post Upgrade , Sync a puppet repo, Add to C.V. in Satellite. 2. Run Capsule sync. 3. Check Capsule sync status. :expectedresults: Capsule sync should complete successfully with puppet repo content. """ product = entities.Product(organization=self.org).create() repo = entities.Repository( product=product, content_type='puppet', url=CUSTOM_PUPPET_REPO, ).create() repo.sync() module = repo.puppet_modules() content_view = entities.ContentView(organization=self.org).create() entities.ContentViewPuppetModule( author=module['results'][0]['author'], name=module['results'][0]['name'], content_view=content_view, ).create() entities.ContentViewPuppetModule( author=module['results'][1]['author'], name=module['results'][1]['name'], content_view=content_view, ).create() content_view.publish() promote(content_view.read().version[0], self.lc_env.id) # Run a Capsule sync capsule = entities.SmartProxy().search( query={'search': 'name={}'.format(self.cap_host)})[0] call_entity_method_with_timeout( entities.Capsule(id=capsule.id).content_sync, timeout=1500) sync_status = entities.Capsule(id=capsule.id).content_get_sync() self.assertEqual(len(sync_status['active_sync_tasks']), 0) self.assertEqual(len(sync_status['last_failed_sync_tasks']), 0)
def setup_to_create_cv(self, repo_name=None, repo_url=None, repo_type=None, repo_unprotected=True, rh_repo=None, org_id=None, docker_upstream_name=None): """Create product/repo and sync it""" if not rh_repo: repo_name = repo_name or gen_string('alpha') # Creates new custom product via API's product = entities.Product( organization=org_id or self.organization).create() # Creates new custom repository via API's repo_id = entities.Repository( name=repo_name, url=(repo_url or FAKE_1_YUM_REPO), content_type=(repo_type or REPO_TYPE['yum']), product=product, unprotected=repo_unprotected, docker_upstream_name=docker_upstream_name, ).create().id elif rh_repo: # Uploads the manifest and returns the result. with manifests.clone() as manifest: upload_manifest(org_id, manifest.content) # Enables the RedHat repo and fetches it's Id. repo_id = enable_rhrepo_and_fetchid( basearch=rh_repo['basearch'], # OrgId is passed as data in API hence str org_id=str(org_id), product=rh_repo['product'], repo=rh_repo['name'], reposet=rh_repo['reposet'], releasever=rh_repo['releasever'], ) # Sync repository with custom timeout call_entity_method_with_timeout(entities.Repository(id=repo_id).sync, timeout=1500) return repo_id
def _create_custom_rhel_tools_repos(self, product): """Install packge on docker content host.""" rhel_repo_url = os.environ.get('{}_CUSTOM_REPO'.format(self.client_os.upper())) tools_repo_url = os.environ.get( 'TOOLS_{}'.format(self.client_os.upper())) if None in [rhel_repo_url, tools_repo_url]: raise ValueError('The Tools Repo URL/RHEL Repo url environment variable for ' 'OS {} is not provided!'.format(self.client_os)) tools_repo = entities.Repository(product=product, content_type='yum', url=tools_repo_url ).create() rhel_repo = entities.Repository(product=product, content_type='yum', url=rhel_repo_url, ).create() call_entity_method_with_timeout(rhel_repo.sync, timeout=1400) return tools_repo, rhel_repo
def test_post_scenario_yum_plugins_count(self, default_org): """Upgrade katello agent on pre-upgrade content host registered with Satellite. :id: postupgrade-45241ada-c2c4-409e-a6e2-92c2cf0ac16c :steps: 1. Create Product, custom tools repo and sync them. 2. Add in content-view and publish it. 3. Attach custom subscription to content host. 4. Install katello-host-tools, so enabled_repos_upload yum plugin is enabled. 4. Update katello-agent and Restart goferd. 5. Check yum plugins count. :expectedresults: 1. Loaded yum plugins should not load more than two times. """ entity_data = get_entity_data(self.__class__.__name__) client = entity_data.get('rhel_client') client_container_id = list(client.values())[0] client_container_name = list(client.keys())[0] cv = entities.ContentView(id=entity_data.get('cv_id')).read() product = entities.Product(organization=default_org).create() tools_repo = self._create_custom_tools_repos(product) product.sync() cv.repository.pop() cv.repository.append(tools_repo) cv = cv.update(['repository']) call_entity_method_with_timeout(cv.publish, timeout=3400) attach_custom_product_subscription(prod_name=product.name, host_name=client_container_name) install_or_update_package(client_hostname=client_container_id, update=True, package='katello-host-tools') install_or_update_package(client_hostname=client_container_id, update=True, package='katello-agent') run_goferd(client_hostname=client_container_id) self._check_yum_plugins_count(client_container_id)
def test_positive_list_hosts_applicable(self): """Request `errata/hosts_applicable` and assert the host with no attached subscriptions is present. :id: 68ed5b10-7a45-4f2d-93ed-cffa737211d5 :steps: 1. Request errata/hosts_applicable for organization created on setUp. :CaseAutomation: automated :expectedresults: 1. Assert the host with no attached subscription is listed to have access to errata content. :CaseImportance: Critical """ with VirtualMachine(distro=DISTRO_RHEL7) as vm: setup_virtual_machine( vm, self.org.label, rh_repos_id=[ repo['repository-id'] for repo in self.repos if repo['cdn'] ], product_label=self.custom_product['label'], repos_label=[ repo['label'] for repo in self.repos_info if repo['red-hat-repository'] == 'no' ], lce=ENVIRONMENT, patch_os_release_distro=DISTRO_RHEL7, install_katello_agent=True, ) host = entities.Host( name=vm.hostname, organization=self.org).search()[0].read() # force host to generate errata applicability call_entity_method_with_timeout( host.errata_applicability, timeout=600) erratum = host.errata()['results'] self.assertGreater(len(erratum), 0)
def test_positive_list_hosts_applicable(self): """Request `errata/hosts_applicable` and assert the host with no attached subscriptions is present. :id: 68ed5b10-7a45-4f2d-93ed-cffa737211d5 :steps: 1. Request errata/hosts_applicable for organization created on setUp. :CaseAutomation: automated :expectedresults: 1. Assert the host with no attached subscription is listed to have access to errata content. :CaseImportance: Critical """ with VirtualMachine(distro=DISTRO_RHEL7) as vm: setup_virtual_machine( vm, self.org.label, rh_repos_id=[ repo['repository-id'] for repo in self.repos if repo['cdn'] ], product_label=self.custom_product['label'], repos_label=[ repo['label'] for repo in self.repos_info if repo['red-hat-repository'] == 'no' ], lce=ENVIRONMENT, patch_os_release_distro=DISTRO_RHEL7, install_katello_agent=True, ) host = entities.Host(name=vm.hostname, organization=self.org).search()[0].read() # force host to generate errata applicability call_entity_method_with_timeout(host.errata_applicability, timeout=600) erratum = host.errata()['results'] self.assertGreater(len(erratum), 0)
def test_positive_list_available_packages(self): """Access content hosts and assert all packages are listed on installable updates and not only those for attached subscriptions. :id: 37383e25-7b1d-433e-9e05-faaa8ec70ee8 :steps: 1. Access Content-Host Packages tab. :CaseAutomation: notautomated :expectedresults: 1. All packages are available independent of subscription because Golden Ticket is enabled. """ with VirtualMachine(distro=DISTRO_RHEL7) as vm: self._setup_virtual_machine(vm) # install a the packages that has updates with errata result = vm.run( 'yum install -y {0}'.format(REAL_RHEL7_0_0_PACKAGE)) self.assertEqual(result.return_code, 0) result = vm.run('rpm -q {0}'.format(REAL_RHEL7_0_0_PACKAGE)) self.assertEqual(result.return_code, 0) # force host to generate/refresh errata applicability host = entities.Host( name=vm.hostname, organization=self.session_org ).search()[0].read() call_entity_method_with_timeout( host.errata_applicability, timeout=600) # check that package errata is applicable with Session(self) as session: set_context(session, org=self.session_org.name) self.assertIsNotNone( session.contenthost.package_search( vm.hostname, REAL_RHEL7_0_1_PACKAGE, package_tab='applicable' ) )
def test_positive_sync_kickstart_repo(self): """No encoding gzip errors on kickstart repositories sync. :id: dbdabc0e-583c-4186-981a-a02844f90412 :expectedresults: No encoding gzip errors present in /var/log/messages. :CaseLevel: Integration :steps: 1. Sync a kickstart repository. 2. After the repo is synced, change the download policy to immediate. 3. Sync the repository again. 4. Assert that no errors related to encoding gzip are present in /var/log/messages. 5. Assert that sync was executed properly. :CaseComponent: Pulp :BZ: 1687801 """ org = entities.Organization().create() product = entities.Product(organization=org).create() repo = entities.Repository(product=product, url=CUSTOM_KICKSTART_REPO).create() repo.sync() repo.download_policy = 'immediate' repo = repo.update(['download_policy']) call_entity_method_with_timeout(repo.sync, timeout=600) result = ssh.command( 'grep pulp /var/log/messages | grep failed | grep encoding | grep gzip' ) self.assertEqual(result.return_code, 1) self.assertEqual(len(result.stdout), 0) repo = repo.read() self.assertGreater(repo.content_counts['package'], 0) self.assertGreater(repo.content_counts['package_group'], 0) self.assertGreater(repo.content_counts['rpm'], 0)
def _create_custom_rhel_tools_repos(self, product): """Install packge on docker content host.""" rhel_repo_url = os.environ.get('{}_CUSTOM_REPO'.format( self.client_os.upper())) tools_repo_url = os.environ.get('TOOLS_{}'.format( self.client_os.upper())) if None in [rhel_repo_url, tools_repo_url]: raise ValueError( 'The Tools Repo URL/RHEL Repo url environment variable for ' 'OS {} is not provided!'.format(self.client_os)) tools_repo = entities.Repository(product=product, content_type='yum', url=tools_repo_url).create() rhel_repo = entities.Repository( product=product, content_type='yum', url=rhel_repo_url, ).create() call_entity_method_with_timeout(rhel_repo.sync, timeout=1400) return tools_repo, rhel_repo
def setup_to_create_cv(self, repo_name=None, repo_url=None, repo_type=None, repo_unprotected=True, rh_repo=None, org_id=None, docker_upstream_name=None): """Create product/repo and sync it""" if not rh_repo: repo_name = repo_name or gen_string('alpha') # Creates new custom product via API's product = entities.Product( organization=org_id or self.organization ).create() # Creates new custom repository via API's repo_id = entities.Repository( name=repo_name, url=(repo_url or FAKE_1_YUM_REPO), content_type=(repo_type or REPO_TYPE['yum']), product=product, unprotected=repo_unprotected, docker_upstream_name=docker_upstream_name, ).create().id elif rh_repo: # Uploads the manifest and returns the result. with manifests.clone() as manifest: upload_manifest(org_id, manifest.content) # Enables the RedHat repo and fetches it's Id. repo_id = enable_rhrepo_and_fetchid( basearch=rh_repo['basearch'], # OrgId is passed as data in API hence str org_id=str(org_id), product=rh_repo['product'], repo=rh_repo['name'], reposet=rh_repo['reposet'], releasever=rh_repo['releasever'], ) # Sync repository with custom timeout call_entity_method_with_timeout( entities.Repository(id=repo_id).sync, timeout=1500) return repo_id
def test_positive_list_available_packages(self): """Access content hosts and assert all packages are listed on installable updates and not only those for attached subscriptions. :id: 37383e25-7b1d-433e-9e05-faaa8ec70ee8 :steps: 1. Access Content-Host Packages tab. :CaseAutomation: notautomated :expectedresults: 1. All packages are available independent of subscription because Golden Ticket is enabled. """ with VirtualMachine(distro=DISTRO_RHEL7) as vm: self._setup_virtual_machine(vm) # install a the packages that has updates with errata result = vm.run( 'yum install -y {0}'.format(REAL_RHEL7_0_0_PACKAGE)) self.assertEqual(result.return_code, 0) result = vm.run('rpm -q {0}'.format(REAL_RHEL7_0_0_PACKAGE)) self.assertEqual(result.return_code, 0) # force host to generate/refresh errata applicability host = entities.Host( name=vm.hostname, organization=self.session_org).search()[0].read() call_entity_method_with_timeout(host.errata_applicability, timeout=600) # check that package errata is applicable with Session(self) as session: set_context(session, org=self.session_org.name) self.assertIsNotNone( session.contenthost.package_search( vm.hostname, REAL_RHEL7_0_1_PACKAGE, package_tab='applicable'))
def test_post_scenario_errata_count_installation(self): """Post-upgrade scenario that installs the package on pre-upgrade client remotely and then verifies if the package installed. :id: 88fd28e6-b4df-46c0-91d6-784859fd1c21 :steps: 1. Recovered pre_upgrade data for post_upgrade verification 2. Verifying errata count has not changed on satellite 3. Update Katello-agent and Restart goferd 4. Verifying the errata_ids 5. Verifying installation errata passes successfully 6. Verifying that package installation passed successfully by remote docker exec :expectedresults: 1. errata count, erratum list should same after satellite upgrade 2. Installation of errata should be pass successfully """ entity_data = get_entity_data(self.__class__.__name__) client = entity_data.get('rhel_client') client_container_id = list(client.values())[0] custom_repo_id = entity_data.get('custom_repo_id') product_id = entity_data.get('product_id') conten_view_id = entity_data.get('conten_view_id') product = entities.Product(id=product_id).read() content_view = entities.ContentView(id=conten_view_id).read() custom_yum_repo = entities.Repository(id=custom_repo_id).read() activation_key = entity_data.get('activation_key') host = entities.Host().search( query={'search': f'activation_key={activation_key}'})[0] installable_errata_count = host.content_facet_attributes[ 'errata_counts']['total'] tools_repo, rhel_repo = self._create_custom_rhel_tools_repos(product) call_entity_method_with_timeout(product.sync, timeout=1400) for repo in (tools_repo, rhel_repo): content_view.repository.append(repo) content_view = content_view.update(['repository']) content_view.publish() install_or_update_package(client_hostname=client_container_id, update=True, package="katello-agent") run_goferd(client_hostname=client_container_id) assert installable_errata_count > 1 erratum_list = entities.Errata(repository=custom_yum_repo).search( query={ 'order': 'updated ASC', 'per_page': 1000 }) errata_ids = [errata.errata_id for errata in erratum_list] assert sorted(errata_ids) == sorted(settings.repos.yum_9.errata) for errata in settings.repos.yum_9.errata: host.errata_apply(data={'errata_ids': [errata]}) installable_errata_count -= 1 # waiting for errata count to become 0, as profile uploading take some # amount of time wait_for( lambda: self._errata_count(ak=activation_key) == 0, timeout=400, delay=2, logger=logger, ) host = entities.Host().search( query={'search': f'activation_key={activation_key}'})[0] assert host.content_facet_attributes['errata_counts']['total'] == 0 for package in FAKE_9_YUM_UPDATED_PACKAGES: install_or_update_package(client_hostname=client_container_id, package=package)
def test_pre_scenario_generate_errata_with_previous_version_katello_agent_client( self, default_org): """Create product and repo from which the errata will be generated for the Satellite client or content host. :id: preupgrade-4e515f84-2582-4b8b-a625-9f6c6966aa59 :steps: 1. Create Life Cycle Environment, Product and Custom Yum Repo. 2. Enable/sync 'base os RHEL7' and tools repos. 3. Create a content view and publish it. 4. Create activation key and add subscription. 5. Registering Docker Content Host RHEL7. 6. Install and check katello agent and goferd service running on host. 7. Generate Errata by Installing Outdated/Older Packages. 8. Collect the Erratum list. :expectedresults: 1. The content host is created. 2. errata count, erratum list will be generated to satellite client/content host. """ environment = entities.LifecycleEnvironment( organization=default_org).search( query={'search': 'name=Library'})[0] product = entities.Product(organization=default_org).create() custom_yum_repo = entities.Repository( product=product, content_type='yum', url=settings.repos.yum_9.url).create() call_entity_method_with_timeout(product.sync, timeout=1400) repos = self._get_rh_rhel_tools_repos(default_org) repos.append(custom_yum_repo) content_view = publish_content_view(org=default_org, repolist=repos) custom_sub = entities.Subscription(organization=default_org).search( query={'search': f'name={product.name}'})[0] rh_sub = entities.Subscription(organization=1).search( query={'search': f'{DEFAULT_SUBSCRIPTION_NAME}'})[0] ak = entities.ActivationKey( content_view=content_view, organization=default_org.id, environment=environment, auto_attach=False, ).create() ak.add_subscriptions(data={'subscription_id': custom_sub.id}) ak.add_subscriptions(data={'subscription_id': rh_sub.id}) rhel7_client = dockerize(ak_name=ak.name, distro='rhel7', org_label=default_org.label) client_container_id = list(rhel7_client.values())[0] docker_vm = settings.upgrade.docker_vm wait_for( lambda: default_org.label in execute( docker_execute_command, client_container_id, 'subscription-manager identity', host=docker_vm, )[docker_vm], timeout=800, delay=2, logger=logger, ) status = execute( docker_execute_command, client_container_id, 'subscription-manager identity', host=docker_vm, )[docker_vm] assert default_org.label in status # Update OS to make errata count 0 execute(docker_execute_command, client_container_id, 'yum update -y', host=docker_vm)[docker_vm] install_or_update_package(client_hostname=client_container_id, package="katello-agent") run_goferd(client_hostname=client_container_id) for package in FAKE_9_YUM_OUTDATED_PACKAGES: install_or_update_package(client_hostname=client_container_id, package=package) host = entities.Host().search( query={'search': f'activation_key={ak.name}'})[0] installable_errata_count = host.content_facet_attributes[ 'errata_counts']['total'] assert installable_errata_count > 1 erratum_list = entities.Errata(repository=custom_yum_repo).search( query={ 'order': 'updated ASC', 'per_page': 1000 }) errata_ids = [errata.errata_id for errata in erratum_list] assert sorted(errata_ids) == sorted(settings.repos.yum_9.errata) scenario_dict = { self.__class__.__name__: { 'rhel_client': rhel7_client, 'activation_key': ak.name, 'custom_repo_id': custom_yum_repo.id, 'product_id': product.id, } } create_dict(scenario_dict)
def create_activation_key_for_client_registration( ak_name, client_os, org, environment, sat_state): """Creates Activation key for client registration :param str ak_name: Activation key name :param str client_os: rhel6/rhel7 :param nailgun.entity.Organization org: Organization :param nailgun.entity.Environment environment: Environment :param str sat_state: pre or post :return nailgun.entity.ActivationKey: Activation key """ client_os = client_os.upper() from_ver = os.environ.get('FROM_VERSION') rhel_prod_name = 'scenarios_rhel{}_prod'.format(client_os[-1]) rhel_repo_name = '{}_repo'.format(rhel_prod_name) rhel_url = os.environ.get('{}_CUSTOM_REPO'.format(client_os)) if rhel_url is None: raise ValueError('The RHEL Repo URL environment variable for OS {} ' 'is not provided!'.format(client_os)) rhel_prod = entities.Product( name=rhel_prod_name, organization=org.id).create() if sat_state.lower() == 'pre' and from_ver in ['6.1', '6.2']: rhel_repo = entities.Repository( name=rhel_repo_name, product=rhel_prod, url=rhel_url, content_type='yum' ).create() else: rhel_repo = entities.Repository( name=rhel_repo_name, product=rhel_prod, url=rhel_url, content_type='yum', verify_ssl_on_sync=False ).create() call_entity_method_with_timeout(rhel_repo.sync, timeout=1400) if sat_state.lower() == 'pre': product_name = 'Red Hat Enterprise Linux Server' repo_name = 'Red Hat Satellite Tools {0} for RHEL ' \ '{1} Server RPMs x86_64'.format(from_ver, client_os[-1]) tools_prod = entities.Product( organization=org.id ).search( query={ 'per_page': 1000, 'search': 'name="{}"'.format(product_name) } )[0] tools_repo = entities.Repository( organization=org.id, product=tools_prod ).search( query={ 'per_page': 1000, 'search': 'name="{}"'.format(repo_name) } )[0] elif sat_state.lower() == 'post': product_name = 'scenarios_tools_product' tools_repo_url = os.environ.get( 'TOOLS_{}'.format(client_os.upper())) if tools_repo_url is None: raise ValueError('The Tools Repo URL environment variable for ' 'OS {} is not provided!'.format(client_os)) repo_name = '{}_repo'.format(product_name) tools_prod = entities.Product( organization=org.id ).search(query={'search': 'name={}'.format(product_name)}) if not tools_prod: tools_prod = entities.Product( name=product_name, organization=org.id).create() tools_repo = entities.Repository( name=repo_name, product=tools_prod, url=tools_repo_url, content_type='yum' ).create() tools_repo.sync() else: tools_repo = entities.Repository( organization=org.id, product=tools_prod ).search(query={'search': 'name={}'.format(repo_name)}) tools_cv = entities.ContentView( name=ak_name + '_cv', label=ak_name + '_cv', organization=org.id ).create() tools_cv.repository = [tools_repo, rhel_repo] tools_cv = tools_cv.update(['repository']) tools_cv.publish() tools_cv = tools_cv.read() # Published CV with new version # Promote CV cvv = entities.ContentViewVersion( id=max([cvv.id for cvv in tools_cv.version]) ).read() cvv.promote( data={ u'environment_id': environment.id, u'force': False } ) tools_ak = entities.ActivationKey( name=ak_name, content_view=tools_cv, organization=org.id, environment=environment ).create() if sat_state == 'pre': tools_sub = 'Red Hat Satellite Employee Subscription' tools_content = 'rhel-{0}-server-satellite-tools-{1}-rpms'.format( client_os[-1], from_ver) else: tools_sub = tools_prod.name tools_subscription = entities.Subscription(organization=org.id).search( query={ 'search': 'name="{}"'.format(tools_sub), 'per_page': 1000 } )[0] rhel_subscription = entities.Subscription(organization=org.id).search( query={ 'search': 'name={}'.format(rhel_prod.name), 'per_page': 1000 } )[0] tools_ak.add_subscriptions(data={ 'subscription_id': tools_subscription.id}) if sat_state == 'pre': tools_ak.content_override(data={ 'content_override': { u'content_label': tools_content, u'value': u'1' }} ) tools_ak.add_subscriptions(data={ 'subscription_id': rhel_subscription.id}) return tools_ak
def test_positive_iso_library_sync(self): """Ensure RH repo with ISOs after publishing to Library is synchronized to capsule automatically :id: 221a2d41-0fef-46dd-a804-fdedd7187163 :customerscenario: true :BZ: 1303102, 1480358, 1303103, 1734312 :expectedresults: ISOs are present on external capsule :CaseLevel: System """ # Create organization, product, enable & sync RH repository with ISOs org = entities.Organization(smart_proxy=[self.capsule_id]).create() with manifests.clone() as manifest: upload_manifest(org.id, manifest.content) rh_repo_id = enable_rhrepo_and_fetchid( basearch='x86_64', org_id=org.id, product=PRDS['rhsc'], repo=REPOS['rhsc7_iso']['name'], reposet=REPOSET['rhsc7_iso'], releasever=None, ) rh_repo = entities.Repository(id=rh_repo_id).read() call_entity_method_with_timeout(rh_repo.sync, timeout=2500) capsule = entities.Capsule(id=self.capsule_id).read() # Find "Library" lifecycle env for specific organization lce = entities.LifecycleEnvironment(organization=org).search( query={'search': 'name={}'.format(ENVIRONMENT)})[0] # Associate the lifecycle environment with the capsule capsule.content_add_lifecycle_environment(data={ 'environment_id': lce.id, }) result = capsule.content_lifecycle_environments() self.assertGreaterEqual(len(result['results']), 1) self.assertIn(lce.id, [capsule_lce['id'] for capsule_lce in result['results']]) # Create a content view with the repository cv = entities.ContentView( organization=org, repository=[rh_repo], ).create() # Publish new version of the content view cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 1) # Verify ISOs are present on satellite repo_path = os.path.join(PULP_PUBLISHED_ISO_REPOS_PATH, rh_repo.backend_identifier) sat_isos = get_repo_files(repo_path, extension='iso') self.assertGreater(len(result), 0) # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time']) # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll(timeout=600) # Verify all the ISOs are present on capsule capsule_isos = get_repo_files(repo_path, extension='iso', hostname=self.capsule_ip) self.assertGreater(len(result), 0) self.assertEqual(set(sat_isos), set(capsule_isos))
def setUpClass(cls): """Setup must ensure there is an Org with Golden Ticket enabled. Option 1) SQL:: UPDATE cp_owner SET content_access_mode = 'org_environment', content_access_mode_list='entitlement,org_environment' WHERE account='{org.label}'; Option 2) manifest:: Change manifest file as it looks like: Consumer: Name: ExampleCorp UUID: c319a1d8-4b30-44cd-b2cf-2ccba4b9a8db Content Access Mode: org_environment Type: satellite :steps: 1. Create a new organization. 2. Use either option 1 or option 2 (described above) to activate the Golden Ticket. 3. Create a Product and CV for org. 4. Add a repository pointing to a real repo which requires a RedHat subscription to access. 5. Create Content Host and assign that gated repos to it. 6. Create Host with no attached subscriptions. 7. Sync the gated repository. """ super(ContentAccessTestCase, cls).setUpClass() # Create Organization cls.org = entities.Organization().create() # upload organization manifest with org environment access enabled manifests.upload_manifest_locked( cls.org.id, manifests.clone(org_environment_access=True)) # Create repositories cls.repos = [ # Red Hat Enterprise Linux 7 { 'product': PRDS['rhel'], 'repository-set': REPOSET['rhel7'], 'repository': REPOS['rhel7']['name'], 'repository-id': REPOS['rhel7']['id'], 'releasever': REPOS['rhel7']['releasever'], 'arch': REPOS['rhel7']['arch'], 'cdn': True, }, # Red Hat Satellite Tools { 'product': PRDS['rhel'], 'repository-set': REPOSET['rhst7'], 'repository': REPOS['rhst7']['name'], 'repository-id': REPOS['rhst7']['id'], 'url': settings.sattools_repo['rhel7'], 'cdn': bool(settings.cdn or not settings.sattools_repo['rhel7']), }, ] cls.custom_product, cls.repos_info = setup_cdn_and_custom_repositories( cls.org.id, cls.repos) # Create a content view content_view = entities.ContentView( organization=cls.org, repository=[ entities.Repository(id=repo_info['id']) for repo_info in cls.repos_info ], ).create() # Publish the content view call_entity_method_with_timeout(content_view.publish, timeout=1500) cls.content_view = content_view.read()
def setUpClass(cls): """Steps required to create a Atomic host on libvirt 1. Creates new Organization and Location. 2. Creates new life-cycle environment. 3. Creates new product and sync RH Atomic OSTree repository. 4. Creates new content-view by associating RH Atomic repository. 5. Publish and promote the content-view to next environment. 6. Search for smart-proxy and associate location. 7. Search for existing domain or create new otherwise. Associate org, location and dns proxy. 8. Search for '192.168.100.0' network and associate org, location, dns/dhcp/tftp proxy, and if its not there then creates new. 9. Search for existing compute-resource with 'libvirt' provider and associate org.location, and if its not there then creates new. 10. Search 'Kickstart default' partition table and RH Atomic OS along with PXE templates. 11. Associates org, location and OS with provisioning and PXE templates 12. Search for x86_64 architecture 13. Associate arch, partition table, provisioning/PXE templates with OS 14. Search for existing Atomic media or create new otherwise and associate org/location 15. Create new host group with all required entities """ super(AtomicHostTestCase, cls).setUpClass() # Create a new Organization and Location cls.org = entities.Organization().create() cls.org_name = cls.org.name cls.loc = entities.Location(organization=[cls.org]).create() cls.loc_name = cls.loc.name # Create a new Life-Cycle environment cls.lc_env = entities.LifecycleEnvironment( organization=cls.org ).create() cls.rh_ah_repo = { 'name': REPOS['rhaht']['name'], 'product': PRDS['rhah'], 'reposet': REPOSET['rhaht'], 'basearch': None, 'releasever': None, } with manifests.clone() as manifest: upload_manifest(cls.org.id, manifest.content) # Enables the RedHat repo and fetches it's Id. cls.repo_id = enable_rhrepo_and_fetchid( basearch=cls.rh_ah_repo['basearch'], # OrgId is passed as data in API hence str org_id=str(cls.org.id), product=cls.rh_ah_repo['product'], repo=cls.rh_ah_repo['name'], reposet=cls.rh_ah_repo['reposet'], releasever=cls.rh_ah_repo['releasever'], ) # Sync repository with custom timeout call_entity_method_with_timeout( entities.Repository(id=cls.repo_id).sync, timeout=1500) cls.cv = entities.ContentView(organization=cls.org).create() cls.cv.repository = [entities.Repository(id=cls.repo_id)] cls.cv = cls.cv.update(['repository']) cls.cv.publish() cls.cv = cls.cv.read() promote(cls.cv.version[0], cls.lc_env.id) # Search for SmartProxy, and associate location cls.proxy = entities.SmartProxy().search( query={ u'search': u'name={0}'.format( settings.server.hostname ) } )[0].read() cls.proxy.location.append(cls.loc) cls.proxy.organization.append(cls.org) cls.proxy = cls.proxy.update(['organization', 'location']) # Search for existing domain or create new otherwise. Associate org, # location and dns to it _, _, domain = settings.server.hostname.partition('.') cls.domain = entities.Domain().search( query={ u'search': u'name="{0}"'.format(domain) } ) if len(cls.domain) > 0: cls.domain = cls.domain[0].read() cls.domain.location.append(cls.loc) cls.domain.organization.append(cls.org) cls.domain.dns = cls.proxy cls.domain = cls.domain.update(['dns', 'location', 'organization']) else: cls.domain = entities.Domain( dns=cls.proxy, location=[cls.loc], organization=[cls.org], ).create() cls.domain_name = cls.domain.name # Search if subnet is defined with given network. # If so, just update its relevant fields otherwise, # Create new subnet network = settings.vlan_networking.subnet subnet = entities.Subnet().search( query={u'search': u'network={0}'.format(network)} ) if len(subnet) > 0: cls.subnet = subnet[0].read() cls.subnet.domain.append(cls.domain) cls.subnet.location.append(cls.loc) cls.subnet.organization.append(cls.org) cls.subnet.dns = cls.proxy cls.subnet.dhcp = cls.proxy cls.subnet.ipam = 'DHCP' cls.subnet.tftp = cls.proxy cls.subnet.discovery = cls.proxy cls.subnet = cls.subnet.update([ 'domain', 'discovery', 'dhcp', 'dns', 'ipam', 'location', 'organization', 'tftp', ]) else: # Create new subnet cls.subnet = entities.Subnet( name=gen_string('alpha'), network=network, mask=settings.vlan_networking.netmask, domain=[cls.domain], location=[cls.loc], organization=[cls.org], dns=cls.proxy, dhcp=cls.proxy, ipam='DHCP', tftp=cls.proxy, discovery=cls.proxy ).create() # Search if Libvirt compute-resource already exists # If so, just update its relevant fields otherwise, # Create new compute-resource with 'libvirt' provider. resource_url = u'qemu+ssh://root@{0}/system'.format( settings.compute_resources.libvirt_hostname ) comp_res = [ res for res in entities.LibvirtComputeResource().search() if res.provider == 'Libvirt' and res.url == resource_url ] if len(comp_res) > 0: cls.computeresource = entities.LibvirtComputeResource( id=comp_res[0].id).read() cls.computeresource.location.append(cls.loc) cls.computeresource.organization.append(cls.org) cls.computeresource = cls.computeresource.update([ 'location', 'organization']) else: # Create Libvirt compute-resource cls.computeresource = entities.LibvirtComputeResource( name=gen_string('alpha'), provider=u'libvirt', url=resource_url, set_console_password=False, display_type=u'VNC', location=[cls.loc.id], organization=[cls.org.id], ).create() # Get the Partition table ID cls.ptable = entities.PartitionTable().search( query={ u'search': u'name="{0}"'.format(DEFAULT_PTABLE) } )[0].read() cls.ptable.location.append(cls.loc) cls.ptable.organization.append(cls.org) cls.ptable = cls.ptable.update(['location', 'organization']) # Get the OS ID os = entities.OperatingSystem().search(query={ u'search': u'name="RedHat_Enterprise_Linux_Atomic_Host"' }) if len(os) > 0: cls.os = os[0].read() else: cls.os = entities.OperatingSystem( name='RedHat_Enterprise_Linux_Atomic_Host', family='Redhat', major=RHEL_7_MAJOR_VERSION, ).create() # update the provisioning templates with OS, Org and Location cls.templates = [] for template_name in [DEFAULT_ATOMIC_TEMPLATE, DEFAULT_PXE_TEMPLATE]: template = entities.ConfigTemplate().search( query={ u'search': u'name="{0}"'.format(template_name) } )[0].read() template.operatingsystem.append(cls.os) template.organization.append(cls.org) template.location.append(cls.loc) template = template.update( ['location', 'operatingsystem', 'organization'] ) cls.templates.append(template) # Get the arch ID cls.arch = entities.Architecture().search( query={u'search': u'name="x86_64"'} )[0] # Get the ostree installer URL ostree_path = settings.ostree.ostree_installer # Get the Media media = entities.Media().search(query={ u'search': u'path={0}'.format(ostree_path) }) if len(media) > 0: cls.media = media[0].read() cls.media.location.append(cls.loc) cls.media.organization.append(cls.org) cls.media = cls.media.update(['location', 'organization']) else: cls.media = entities.Media( organization=[cls.org], location=[cls.loc], os_family='Redhat', path_=ostree_path ).create() # Update the OS to associate arch, ptable, templates cls.os.architecture = [cls.arch] cls.os.ptable = [cls.ptable] cls.os.config_template = cls.templates cls.os.medium = [cls.media] cls.os = cls.os.update([ 'architecture', 'config_template', 'ptable', 'medium', ]) # Create Hostgroup cls.host_group = entities.HostGroup( architecture=cls.arch, domain=cls.domain.id, subnet=cls.subnet.id, lifecycle_environment=cls.lc_env.id, content_view=cls.cv.id, location=[cls.loc.id], name=gen_string('alpha'), medium=cls.media, operatingsystem=cls.os.id, organization=[cls.org.id], ptable=cls.ptable.id, ).create()
def setUpClass(cls): """Steps required to create a Atomic host on libvirt 1. Creates new Organization and Location. 2. Creates new life-cycle environment. 3. Creates new product and sync RH Atomic OSTree repository. 4. Creates new content-view by associating RH Atomic repository. 5. Publish and promote the content-view to next environment. 6. Search for smart-proxy and associate location. 7. Search for existing domain or create new otherwise. Associate org, location and dns proxy. 8. Search for '192.168.100.0' network and associate org, location, dns/dhcp/tftp proxy, and if its not there then creates new. 9. Search for existing compute-resource with 'libvirt' provider and associate org.location, and if its not there then creates new. 10. Search 'Kickstart default' partition table and RH Atomic OS along with PXE templates. 11. Associates org, location and OS with provisioning and PXE templates 12. Search for x86_64 architecture 13. Associate arch, partition table, provisioning/PXE templates with OS 14. Search for existing Atomic media or create new otherwise and associate org/location 15. Create new host group with all required entities """ super(AtomicHostTestCase, cls).setUpClass() # Create a new Organization and Location cls.org = entities.Organization().create() cls.org_name = cls.org.name cls.loc = entities.Location(organization=[cls.org]).create() cls.loc_name = cls.loc.name # Create a new Life-Cycle environment cls.lc_env = entities.LifecycleEnvironment( organization=cls.org ).create() cls.rh_ah_repo = { 'name': REPOS['rhaht']['name'], 'product': PRDS['rhah'], 'reposet': REPOSET['rhaht'], 'basearch': None, 'releasever': None, } with manifests.clone() as manifest: upload_manifest(cls.org.id, manifest.content) # Enables the RedHat repo and fetches it's Id. cls.repo_id = enable_rhrepo_and_fetchid( basearch=cls.rh_ah_repo['basearch'], # OrgId is passed as data in API hence str org_id=str(cls.org.id), product=cls.rh_ah_repo['product'], repo=cls.rh_ah_repo['name'], reposet=cls.rh_ah_repo['reposet'], releasever=cls.rh_ah_repo['releasever'], ) # Sync repository with custom timeout call_entity_method_with_timeout( entities.Repository(id=cls.repo_id).sync, timeout=1500) cls.cv = entities.ContentView(organization=cls.org).create() cls.cv.repository = [entities.Repository(id=cls.repo_id)] cls.cv = cls.cv.update(['repository']) cls.cv.publish() cls.cv = cls.cv.read() promote(cls.cv.version[0], cls.lc_env.id) # Search for SmartProxy, and associate location cls.proxy = entities.SmartProxy().search( query={ u'search': u'name={0}'.format( settings.server.hostname ) } )[0].read() cls.proxy.location.append(cls.loc) cls.proxy.organization.append(cls.org) cls.proxy = cls.proxy.update(['organization', 'location']) # Search for existing domain or create new otherwise. Associate org, # location and dns to it _, _, domain = settings.server.hostname.partition('.') cls.domain = entities.Domain().search( query={ u'search': u'name="{0}"'.format(domain) } ) if len(cls.domain) > 0: cls.domain = cls.domain[0].read() cls.domain.location.append(cls.loc) cls.domain.organization.append(cls.org) cls.domain.dns = cls.proxy cls.domain = cls.domain.update(['dns', 'location', 'organization']) else: cls.domain = entities.Domain( dns=cls.proxy, location=[cls.loc], organization=[cls.org], ).create() cls.domain_name = cls.domain.name # Search if subnet is defined with given network. # If so, just update its relevant fields otherwise, # Create new subnet network = settings.vlan_networking.subnet subnet = entities.Subnet().search( query={u'search': u'network={0}'.format(network)} ) if len(subnet) > 0: cls.subnet = subnet[0].read() cls.subnet.domain.append(cls.domain) cls.subnet.location.append(cls.loc) cls.subnet.organization.append(cls.org) cls.subnet.dns = cls.proxy cls.subnet.dhcp = cls.proxy cls.subnet.ipam = 'DHCP' cls.subnet.tftp = cls.proxy cls.subnet.discovery = cls.proxy cls.subnet = cls.subnet.update([ 'domain', 'discovery', 'dhcp', 'dns', 'ipam', 'location', 'organization', 'tftp', ]) else: # Create new subnet cls.subnet = entities.Subnet( name=gen_string('alpha'), network=network, mask=settings.vlan_networking.netmask, domain=[cls.domain], location=[cls.loc], organization=[cls.org], dns=cls.proxy, dhcp=cls.proxy, ipam='DHCP', tftp=cls.proxy, discovery=cls.proxy ).create() # Search if Libvirt compute-resource already exists # If so, just update its relevant fields otherwise, # Create new compute-resource with 'libvirt' provider. resource_url = u'qemu+ssh://root@{0}/system'.format( settings.compute_resources.libvirt_hostname ) comp_res = [ res for res in entities.LibvirtComputeResource().search() if res.provider == 'Libvirt' and res.url == resource_url ] if len(comp_res) > 0: cls.computeresource = entities.LibvirtComputeResource( id=comp_res[0].id).read() cls.computeresource.location.append(cls.loc) cls.computeresource.organization.append(cls.org) cls.computeresource = cls.computeresource.update([ 'location', 'organization']) else: # Create Libvirt compute-resource cls.computeresource = entities.LibvirtComputeResource( name=gen_string('alpha'), provider=u'libvirt', url=resource_url, set_console_password=False, display_type=u'VNC', location=[cls.loc.id], organization=[cls.org.id], ).create() # Get the Partition table ID cls.ptable = entities.PartitionTable().search( query={ u'search': u'name="{0}"'.format(DEFAULT_PTABLE) } )[0].read() cls.ptable.location.append(cls.loc) cls.ptable.organization.append(cls.org) cls.ptable = cls.ptable.update(['location', 'organization']) # Get the OS ID os = entities.OperatingSystem().search(query={ u'search': u'name="RedHat_Enterprise_Linux_Atomic_Host"' }) if len(os) > 0: cls.os = os[0].read() else: cls.os = entities.OperatingSystem( name='RedHat_Enterprise_Linux_Atomic_Host', family='Redhat', major=RHEL_7_MAJOR_VERSION, ).create() # update the provisioning templates with OS, Org and Location cls.templates = [] for template_name in [DEFAULT_ATOMIC_TEMPLATE, DEFAULT_PXE_TEMPLATE]: template = entities.ConfigTemplate().search( query={ u'search': u'name="{0}"'.format(template_name) } )[0].read() template.operatingsystem.append(cls.os) template.organization.append(cls.org) template.location.append(cls.loc) template = template.update( ['location', 'operatingsystem', 'organization'] ) cls.templates.append(template) # Get the arch ID cls.arch = entities.Architecture().search( query={u'search': u'name="x86_64"'} )[0] # Get the ostree installer URL ostree_path = settings.ostree.ostree_installer # Get the Media media = entities.Media().search(query={ u'search': u'path={0}'.format(ostree_path) }) if len(media) > 0: cls.media = media[0].read() cls.media.location.append(cls.loc) cls.media.organization.append(cls.org) cls.media = cls.media.update(['location', 'organization']) else: cls.media = entities.Media( organization=[cls.org], location=[cls.loc], os_family='Redhat', path_=ostree_path ).create() # Update the OS to associate arch, ptable, templates cls.os.architecture = [cls.arch] cls.os.ptable = [cls.ptable] cls.os.config_template = cls.templates cls.os.medium = [cls.media] cls.os = cls.os.update([ 'architecture', 'config_template', 'ptable', 'medium', ]) # Create Hostgroup cls.host_group = entities.HostGroup( architecture=cls.arch, domain=cls.domain.id, subnet=cls.subnet.id, lifecycle_environment=cls.lc_env.id, content_view=cls.cv.id, location=[cls.loc.id], name=gen_string('alpha'), medium=cls.media, operatingsystem=cls.os.id, organization=[cls.org.id], ptable=cls.ptable.id, ).create()
def test_positive_iso_library_sync(self, module_manifest_org, capsule_configured): """Ensure RH repo with ISOs after publishing to Library is synchronized to capsule automatically :id: 221a2d41-0fef-46dd-a804-fdedd7187163 :customerscenario: true :BZ: 1303102, 1480358, 1303103, 1734312 :expectedresults: ISOs are present on external capsule :CaseLevel: System """ # Enable & sync RH repository with ISOs rh_repo_id = enable_rhrepo_and_fetchid( basearch='x86_64', org_id=module_manifest_org.id, product=constants.PRDS['rhsc'], repo=constants.REPOS['rhsc7_iso']['name'], reposet=constants.REPOSET['rhsc7_iso'], releasever=None, ) rh_repo = entities.Repository(id=rh_repo_id).read() call_entity_method_with_timeout(rh_repo.sync, timeout=2500) # Find "Library" lifecycle env for specific organization lce = entities.LifecycleEnvironment( organization=module_manifest_org).search( query={'search': f'name={constants.ENVIRONMENT}'})[0] # Associate the lifecycle environment with the capsule capsule_configured.nailgun_capsule.content_add_lifecycle_environment( data={'environment_id': lce.id}) result = capsule_configured.nailgun_capsule.content_lifecycle_environments( ) assert len(result['results']) >= 1 assert lce.id in [ capsule_lce['id'] for capsule_lce in result['results'] ] # Create a content view with the repository cv = entities.ContentView(organization=module_manifest_org, repository=[rh_repo]).create() # Publish new version of the content view cv.publish() cv = cv.read() assert len(cv.version) == 1 # Verify ISOs are present on satellite sat_isos = get_repo_files_by_url(rh_repo.full_path, extension='iso') assert len(sat_isos) == 4 # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule_configured.nailgun_capsule.content_get_sync() assert len(sync_status['active_sync_tasks'] ) >= 1 or sync_status['last_sync_time'] # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll(timeout=600) # Verify all the ISOs are present on capsule caps_path = ( f'{capsule_configured.url}/pulp/content/{module_manifest_org.label}/{lce.label}' f'/{cv.label}/content/dist/rhel/server/7/7Server/x86_64/sat-capsule/6.4/iso/' ) caps_isos = get_repo_files_by_url(caps_path, extension='iso') assert len(caps_isos) == 4 assert set(sat_isos) == set(caps_isos)
def test_positive_iso_library_sync(self): """Ensure RH repo with ISOs after publishing to Library is synchronized to capsule automatically :id: 221a2d41-0fef-46dd-a804-fdedd7187163 :customerscenario: true :BZ: 1303102, 1480358, 1303103 :expectedresults: ISOs are present on external capsule :CaseLevel: System """ # Create organization, product, enable & sync RH repository with ISOs org = entities.Organization(smart_proxy=[self.capsule_id]).create() with manifests.clone() as manifest: upload_manifest(org.id, manifest.content) rh_repo_id = enable_rhrepo_and_fetchid( basearch='x86_64', org_id=org.id, product=PRDS['rhsc'], repo=REPOS['rhsc7_iso']['name'], reposet=REPOSET['rhsc7_iso'], releasever=None, ) rh_repo = entities.Repository(id=rh_repo_id).read() call_entity_method_with_timeout(rh_repo.sync, timeout=2500) capsule = entities.Capsule(id=self.capsule_id).read() # Find "Library" lifecycle env for specific organization lce = entities.LifecycleEnvironment(organization=org).search(query={ 'search': 'name={}'.format(ENVIRONMENT) })[0] # Associate the lifecycle environment with the capsule capsule.content_add_lifecycle_environment(data={ 'environment_id': lce.id, }) result = capsule.content_lifecycle_environments() self.assertGreaterEqual(len(result['results']), 1) self.assertIn( lce.id, [capsule_lce['id'] for capsule_lce in result['results']]) # Create a content view with the repository cv = entities.ContentView( organization=org, repository=[rh_repo], ).create() # Publish new version of the content view cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 1) # Verify ISOs are present on satellite repo_path = os.path.join( PULP_PUBLISHED_ISO_REPOS_PATH, rh_repo.backend_identifier) sat_isos = get_repo_files(repo_path, extension='iso') self.assertGreater(len(result), 0) # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time'] ) # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll(timeout=600) # Verify all the ISOs are present on capsule capsule_isos = get_repo_files( repo_path, extension='iso', hostname=self.capsule_ip) self.assertGreater(len(result), 0) self.assertEqual(set(sat_isos), set(capsule_isos))
def setUpClass(cls): """Setup must ensure there is an Org with Golden Ticket enabled. Option 1) SQL:: UPDATE cp_owner SET content_access_mode = 'org_environment', content_access_mode_list='entitlement,org_environment' WHERE account='{org.label}'; Option 2) manifest:: Change manifest file as it looks like: Consumer: Name: ExampleCorp UUID: c319a1d8-4b30-44cd-b2cf-2ccba4b9a8db Content Access Mode: org_environment Type: satellite :steps: 1. Create a new organization. 2. Use either option 1 or option 2 (described above) to activate the Golden Ticket. 3. Create a Product and CV for org. 4. Add a repository pointing to a real repo which requires a RedHat subscription to access. 5. Create Content Host and assign that gated repos to it. 6. Create Host with no attached subscriptions. 7. Sync the gated repository. """ super(ContentAccessTestCase, cls).setUpClass() # Create Organization cls.org = entities.Organization().create() # upload organization manifest with org environment access enabled manifests.upload_manifest_locked( cls.org.id, manifests.clone(org_environment_access=True) ) # Create repositories cls.repos = [ # Red Hat Enterprise Linux 7 { 'product': PRDS['rhel'], 'repository-set': REPOSET['rhel7'], 'repository': REPOS['rhel7']['name'], 'repository-id': REPOS['rhel7']['id'], 'releasever': REPOS['rhel7']['releasever'], 'arch': REPOS['rhel7']['arch'], 'cdn': True, }, # Red Hat Satellite Tools { 'product': PRDS['rhel'], 'repository-set': REPOSET['rhst7'], 'repository': REPOS['rhst7']['name'], 'repository-id': REPOS['rhst7']['id'], 'url': settings.sattools_repo['rhel7'], 'cdn': bool( settings.cdn or not settings.sattools_repo['rhel7']), }, ] cls.custom_product, cls.repos_info = setup_cdn_and_custom_repositories( cls.org.id, cls.repos) # Create a content view content_view = entities.ContentView( organization=cls.org, repository=[entities.Repository(id=repo_info['id']) for repo_info in cls.repos_info], ).create() # Publish the content view call_entity_method_with_timeout(content_view.publish, timeout=1500) cls.content_view = content_view.read()
def setUp(self): """Creates the pre-requisites for the Incremental updates that used per each test""" super(IncrementalUpdateTestCase, self).setUp() # Create content view that will be used filtered erratas self.rhel_6_partial_cv = entities.ContentView( organization=self.org, name=gen_alpha(), repository=[self.rhva_6_repo, self.rhel6_sat6tools_repo] ).create() # Create a content view filter to filter out errata rhel_6_partial_cvf = entities.ErratumContentViewFilter( content_view=self.rhel_6_partial_cv, type='erratum', name='rhel_6_partial_cv_filter', repository=[self.rhva_6_repo] ).create() # Create a content view filter rule - filtering out errata in the last # 365 days start_date = (date.today() - timedelta(days=365)).strftime('%Y-%m-%d') entities.ContentViewFilterRule( content_view_filter=rhel_6_partial_cvf, types=['security', 'enhancement', 'bugfix'], start_date=start_date, end_date=date.today().strftime('%Y-%m-%d') ).create() # Publish content view and re-read it self.rhel_6_partial_cv.publish() self.rhel_6_partial_cv = self.rhel_6_partial_cv.read() # Promote content view to 'DEV' and 'QE' assert len(self.rhel_6_partial_cv.version) == 1 for env in (self.dev_lce, self.qe_lce): promote(self.rhel_6_partial_cv.version[0], env.id) # Create host collection self.rhel_6_partial_hc = entities.HostCollection( organization=self.org, name=gen_alpha(), max_hosts=5).create() # Create activation key for content view kwargs = {'organization': self.org, 'environment': self.qe_lce.id} rhel_6_partial_ak = entities.ActivationKey( name=gen_alpha(), content_view=self.rhel_6_partial_cv, host_collection=[self.rhel_6_partial_hc], **kwargs ).create() # Assign subscription to activation key. Fetch available subscriptions subs = entities.Subscription(organization=self.org).search() assert len(subs) > 0 # Add subscription to activation key sub_found = False for sub in subs: if sub.read_json()['product_name'] == DEFAULT_SUBSCRIPTION_NAME: rhel_6_partial_ak.add_subscriptions(data={ u'subscription_id': sub.id }) sub_found = True assert sub_found # Enable product content in activation key rhel_6_partial_ak.content_override(data={'content_override': { u'content_label': REPOS['rhst6']['id'], u'value': u'1' }}) # Create client machine and register it to satellite with # rhel_6_partial_ak self.vm = VirtualMachine(distro=DISTRO_RHEL6, tag='incupdate') self.addCleanup(vm_cleanup, self.vm) self.setup_vm(self.vm, rhel_6_partial_ak.name, self.org.label) self.vm.enable_repo(REPOS['rhva6']['id']) timestamp = datetime.utcnow() self.vm.run('yum install -y {0}'.format(REAL_0_RH_PACKAGE)) # Find the content host and ensure that tasks started by package # installation has finished host = entities.Host().search( query={'search': 'name={}'.format(self.vm.hostname)}) wait_for_tasks( search_query='label = Actions::Katello::Host::UploadPackageProfile' ' and resource_id = {}' ' and started_at >= "{}"'.format( host[0].id, timestamp) ) # Force host to generate or refresh errata applicability call_entity_method_with_timeout(host[0].errata_applicability, timeout=600)
def create_activation_key_for_client_registration(ak_name, client_os, org, environment, sat_state): """Creates Activation key for client registration :param str ak_name: Activation key name :param str client_os: rhel6/rhel7 :param nailgun.entities.Organization org: Organization :param nailgun.entities.Environment environment: Environment :param str sat_state: pre or post :return nailgun.entities.ActivationKey: Activation key """ client_os = client_os.upper() from_ver = settings.upgrade.from_version rhel_prod_name = 'scenarios_rhel{}_prod'.format(client_os[-1]) rhel_repo_name = '{}_repo'.format(rhel_prod_name) rhel_url = settings.rhel7_os if rhel_url is None: raise ValueError('The RHEL Repo URL environment variable for OS {} ' 'is not provided!'.format(client_os)) rhel_prod = entities.Product(name=rhel_prod_name, organization=org.id).create() if sat_state.lower() == 'pre' and from_ver in ['6.1', '6.2']: rhel_repo = entities.Repository(name=rhel_repo_name, product=rhel_prod, url=rhel_url, content_type='yum').create() else: rhel_repo = entities.Repository( name=rhel_repo_name, product=rhel_prod, url=rhel_url, content_type='yum', verify_ssl_on_sync=False, ).create() call_entity_method_with_timeout(rhel_repo.sync, timeout=1400) if sat_state.lower() == 'pre': product_name = 'Red Hat Enterprise Linux Server' repo_name = 'Red Hat Satellite Tools {0} for RHEL {1} Server RPMs x86_64'.format( from_ver, client_os[-1]) tools_prod = entities.Product(organization=org.id).search( query={ 'per_page': 1000, 'search': 'name="{}"'.format(product_name) })[0] tools_repo = entities.Repository( organization=org.id, product=tools_prod).search(query={ 'per_page': 1000, 'search': 'name="{}"'.format(repo_name) })[0] elif sat_state.lower() == 'post': product_name = 'scenarios_tools_product' tools_repo_url = settings.sattools_repo[client_os.lower()] if tools_repo_url is None: raise ValueError('The Tools Repo URL environment variable for ' 'OS {} is not provided!'.format( client_os.lower())) repo_name = '{}_repo'.format(product_name) tools_prod = entities.Product(organization=org.id).search( query={'search': 'name={}'.format(product_name)}) if not tools_prod: tools_prod = entities.Product(name=product_name, organization=org.id).create() tools_repo = entities.Repository(name=repo_name, product=tools_prod, url=tools_repo_url, content_type='yum').create() tools_repo.sync() else: tools_repo = entities.Repository( organization=org.id, product=tools_prod).search( query={'search': 'name={}'.format(repo_name)}) tools_cv = entities.ContentView(name=ak_name + '_cv', label=ak_name + '_cv', organization=org.id).create() tools_cv.repository = [tools_repo, rhel_repo] tools_cv = tools_cv.update(['repository']) tools_cv.publish() tools_cv = tools_cv.read() # Published CV with new version # Promote CV cvv = entities.ContentViewVersion( id=max([cvv.id for cvv in tools_cv.version])).read() cvv.promote(data={'environment_id': environment.id, 'force': False}) tools_ak = entities.ActivationKey(name=ak_name, content_view=tools_cv, organization=org.id, environment=environment).create() if sat_state == 'pre': tools_sub = 'Red Hat Satellite Employee Subscription' tools_content = 'rhel-{0}-server-satellite-tools-{1}-rpms'.format( client_os[-1], from_ver) else: tools_sub = tools_prod.name tools_subscription = entities.Subscription(organization=org.id).search( query={ 'search': 'name="{}"'.format(tools_sub), 'per_page': 1000 })[0] rhel_subscription = entities.Subscription(organization=org.id).search( query={ 'search': 'name={}'.format(rhel_prod.name), 'per_page': 1000 })[0] tools_ak.add_subscriptions(data={'subscription_id': tools_subscription.id}) if sat_state == 'pre': tools_ak.content_override(data={ 'content_override': { 'content_label': tools_content, 'value': '1' } }) tools_ak.add_subscriptions(data={'subscription_id': rhel_subscription.id}) return tools_ak
def setUp(self): """Creates the pre-requisites for the Incremental updates that used per each test""" super(IncrementalUpdateTestCase, self).setUp() # Create content view that will be used filtered erratas self.rhel_6_partial_cv = entities.ContentView( organization=self.org, name=gen_alpha(), repository=[self.rhva_6_repo, self.rhel6_sat6tools_repo]).create() # Create a content view filter to filter out errata rhel_6_partial_cvf = entities.ErratumContentViewFilter( content_view=self.rhel_6_partial_cv, type='erratum', name='rhel_6_partial_cv_filter', repository=[self.rhva_6_repo]).create() # Create a content view filter rule - filtering out errata in the last # 365 days start_date = (date.today() - timedelta(days=365)).strftime('%Y-%m-%d') entities.ContentViewFilterRule( content_view_filter=rhel_6_partial_cvf, types=['security', 'enhancement', 'bugfix'], start_date=start_date, end_date=date.today().strftime('%Y-%m-%d')).create() # Publish content view and re-read it self.rhel_6_partial_cv.publish() self.rhel_6_partial_cv = self.rhel_6_partial_cv.read() # Promote content view to 'DEV' and 'QE' assert len(self.rhel_6_partial_cv.version) == 1 for env in (self.dev_lce, self.qe_lce): promote(self.rhel_6_partial_cv.version[0], env.id) # Create host collection self.rhel_6_partial_hc = entities.HostCollection(organization=self.org, name=gen_alpha(), max_hosts=5).create() # Create activation key for content view kwargs = {'organization': self.org, 'environment': self.qe_lce.id} rhel_6_partial_ak = entities.ActivationKey( name=gen_alpha(), content_view=self.rhel_6_partial_cv, host_collection=[self.rhel_6_partial_hc], **kwargs).create() # Assign subscription to activation key. Fetch available subscriptions subs = entities.Subscription(organization=self.org).search() assert len(subs) > 0 # Add subscription to activation key sub_found = False for sub in subs: if sub.read_json()['product_name'] == DEFAULT_SUBSCRIPTION_NAME: rhel_6_partial_ak.add_subscriptions( data={u'subscription_id': sub.id}) sub_found = True assert sub_found # Enable product content in activation key rhel_6_partial_ak.content_override( data={ 'content_override': { u'content_label': REPOS['rhst6']['id'], u'value': u'1' } }) # Create client machine and register it to satellite with # rhel_6_partial_ak self.vm = VirtualMachine(distro=DISTRO_RHEL6, tag='incupdate') self.addCleanup(vm_cleanup, self.vm) self.setup_vm(self.vm, rhel_6_partial_ak.name, self.org.label) self.vm.enable_repo(REPOS['rhva6']['id']) timestamp = datetime.utcnow() self.vm.run('yum install -y {0}'.format(REAL_0_RH_PACKAGE)) # Find the content host and ensure that tasks started by package # installation has finished host = entities.Host().search( query={'search': 'name={}'.format(self.vm.hostname)}) wait_for_tasks( search_query='label = Actions::Katello::Host::UploadPackageProfile' ' and resource_id = {}' ' and started_at >= "{}"'.format(host[0].id, timestamp)) # Force host to generate or refresh errata applicability call_entity_method_with_timeout(host[0].errata_applicability, timeout=600)