Example #1
0
    def test_positive_update_os_by_name(self):
        """A host can be updated with a new operating system. Use
        entities names for association

        @id: bd48887f-3db3-47b0-8231-de58884efe57

        @assert: A host is updated and the operating system matches

        @CaseLevel: Integration
        """
        new_os = make_os({
            'architectures': self.host_args.architecture.name,
            'partition-tables': self.host[
                'operating-system']['partition-table'],
        })
        Medium.add_operating_system({
            'name': self.host_args.medium.name,
            'operatingsystem': new_os['title'],
        })
        Host.update({
            'name': self.host['name'],
            'operatingsystem': new_os['title'],
        })
        self.host = Host.info({'name': self.host['name']})
        self.assertEqual(
            self.host['operating-system']['operating-system'], new_os['title'])
Example #2
0
    def _capsule_cleanup(self):
        """make the necessary cleanup in case of a crash"""
        if self._subscribed:
            # use try except to unregister the host, in case of host not
            # reachable (or any other failure), the capsule is not deleted and
            # this failure will hide any prior failure.
            try:
                self.unregister()
            except Exception as exp:
                logger.error('Failed to unregister the host: {0}\n{1}'.format(
                    self.hostname, exp.message))

        if self._capsule_hostname:
            # do cleanup as using a static hostname that can be reused by
            # other tests and organizations
            try:
                # try to delete the hostname first
                Host.delete({'name': self._capsule_hostname})
                # try delete the capsule
                # note: if the host was not registered the capsule does not
                # exist yet
                Capsule.delete({'name': self._capsule_hostname})
            except Exception as exp:
                # do nothing, only log the exception
                # as maybe that the host was not registered or setup does not
                # reach that stage
                # or maybe that the capsule was not registered or setup does
                # not reach that stage
                logger.error('Failed to cleanup the host: {0}\n{1}'.format(
                    self.hostname, exp.message))
Example #3
0
    def test_positive_update_domain_by_name(self):
        """A host can be updated with a new domain. Use entities names
        for association

        @id: 9b4fb1b9-a226-4b8a-bfaf-1121de7df5bc

        @assert: A host is updated and the domain matches

        @CaseLevel: Integration
        """
        new_domain = make_domain({
            'location': self.host_args.location.name,
            'organization': self.host_args.organization.name,
        })
        Host.update({
            'domain': new_domain['name'],
            'name': self.host['name'],
        })
        self.host = Host.info({
            'name': '{0}.{1}'.format(
                self.host['name'].split('.')[0],
                new_domain['name'],
            )
        })
        self.assertEqual(self.host['network']['domain'], new_domain['name'])
Example #4
0
    def test_positive_update_parameter_by_host_id(self):
        """Update existing host parameter by specifying host ID.

        @id: 56c43ab4-7fb0-44f5-9d54-107d3c1011bf

        @Assert: Host parameter was successfully updated with new value.

        """
        name = gen_string('alphanumeric').lower()
        old_value = gen_string('alphanumeric')
        Host.set_parameter({
            'host-id': self.host['id'],
            'name': name,
            'value': old_value,
        })
        for new_value in valid_data_list():
            with self.subTest(new_value):
                Host.set_parameter({
                    'host-id': self.host['id'],
                    'name': name,
                    'value': new_value,
                })
                self.host = Host.info({'id': self.host['id']})
                self.assertIn(name, self.host['parameters'].keys())
                self.assertEqual(new_value, self.host['parameters'][name])
Example #5
0
    def test_positive_update_parameter_by_host_name(self):
        """Update existing host parameter by specifying host name.

        @Feature: Hosts

        @Assert: Host parameter was successfully updated with new value.

        """
        name = gen_string('alphanumeric').lower()
        old_value = gen_string('alphanumeric')
        Host.set_parameter({
            'host': self.host['name'],
            'name': name,
            'value': old_value,
        })
        for new_value in valid_data_list():
            with self.subTest(new_value):
                Host.set_parameter({
                    'host': self.host['name'],
                    'name': name,
                    'value': new_value,
                })
                self.host = Host.info({'id': self.host['id']})
                self.assertIn(name, self.host['parameters'].keys())
                self.assertEqual(new_value, self.host['parameters'][name])
Example #6
0
    def test_positive_update_name_by_name(self):
        """A host can be updated with a new random name. Use name to
        access the host

        @feature: Hosts

        @assert: A host is updated and the name matches
        """
        for new_name in valid_hosts_list():
            with self.subTest(new_name):
                Host.update({
                    'name': self.host['name'],
                    'new-name': new_name,
                })
                self.host = Host.info({
                    'name': u'{0}.{1}'
                            .format(new_name, self.host['domain']).lower()
                })
                self.assertEqual(
                    u'{0}.{1}'.format(
                        new_name,
                        self.host['domain'],
                    ).lower(),
                    self.host['name'],
                )
    def test_positive_rename_content_host_cli(self):
        """Content Hosts renamed in UI affects entity in the application
        entirely, so name looks different through CLI too

        :id: a64c7815-269b-45d0-9032-38df550d6cd9

        :steps:
            1.  Rename a host from 'Content-hosts' page
            2.  View host under content-hosts
            3.  View host using command line interface

        :expectedresults: Host changed its name both in UI and CLI

        :BZ: 1417953

        :CaseLevel: System
        """
        new_name = gen_string('alphanumeric').lower()
        with VirtualMachine(distro=DISTRO_RHEL7) as vm:
            vm.install_katello_ca()
            vm.register_contenthost(self.org_.label, lce='Library')
            self.assertTrue(vm.subscribed)
            host = Host.info({'name': vm.hostname})
            with Session(self) as session:
                session.nav.go_to_select_org(self.org_.name)
                self.contenthost.update(
                    vm.hostname,
                    new_name=new_name,
                )
                self.assertIsNotNone(self.contenthost.search(new_name))
            self.assertEqual(Host.info({'id': host['id']})['name'], new_name)
Example #8
0
    def test_positive_create_using_libvirt_without_mac(self):
        """Create a libvirt host and not specify a MAC address.

        @Feature: Hosts

        @Assert: Host is created
        """
        compute_resource = entities.LibvirtComputeResource(
            url='qemu+ssh://root@{0}/system'.format(
                settings.compute_resources.libvirt_hostname
            )
        ).create()
        host = entities.Host()
        host.create_missing()
        result = Host.create({
            u'architecture-id': host.architecture.id,
            u'compute-resource-id': compute_resource.id,
            u'domain-id': host.domain.id,
            u'environment-id': host.environment.id,
            u'interface': 'type=network',
            u'location-id': host.location.id,  # pylint:disable=no-member
            u'medium-id': host.medium.id,
            u'name': host.name,
            u'operatingsystem-id': host.operatingsystem.id,
            # pylint:disable=no-member
            u'organization-id': host.organization.id,
            u'partition-table-id': host.ptable.id,
            u'puppet-proxy-id': self.puppet_proxy['id'],
            u'root-pass': host.root_pass,
        })
        self.assertEqual(result['name'], host.name + '.' + host.domain.name)
        Host.delete({'id': result['id']})
    def test_positive_list_parameters_by_host_id(self):
        """List all the parameters included in specific Host by its id.

        @id: 79050de6-b894-4a88-b155-32bf488b692c

        @assert: Parameters listed for specific Host.

        @CaseLevel: Integration
        """
        sc_param_id = self.sc_params_ids_list.pop()
        SmartClassParameter.update({
            'id': sc_param_id,
            'override': 1,
        })
        sc_param = SmartClassParameter.info({
            'puppet-class': 'ntp',
            'id': sc_param_id,
        })
        self.assertEqual(sc_param['override'], True)
        host = entities.Host(organization=self.org['id']).create()
        Host.update({
            u'name': host.name,
            u'environment': self.env['name'],
            u'puppet-classes': self.puppet_class['name'],
        })
        host_sc_params_list = Host.sc_params({u'host-id': host.id})
        self.assertGreater(len(host_sc_params_list), 0)
Example #10
0
    def test_positive_run_default_job_template_by_ip(self):
        """Run default template on host connected by ip

        :id: 811c7747-bec6-4a2d-8e5c-b5045d3fbc0d

        :expectedresults: Verify the job was successfully ran against the host
        """
        # set connecting to host via ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        invocation_command = make_job_invocation({
            'job-template': 'Run Command - SSH Default',
            'inputs': 'command="ls"',
            'search-query': "name ~ {0}".format(self.client.hostname),
        })
        try:
            self.assertEqual(invocation_command['success'], u'1')
        except AssertionError:
            result = 'host output: {0}'.format(
                ' '.join(JobInvocation.get_output({
                    'id': invocation_command[u'id'],
                    'host': self.client.hostname})
                    )
                )
            raise AssertionError(result)
    def test_positive_list_parameters_by_host_name(self):
        """List all the parameters included in specific Host by its name.

        @id: a8165746-3480-4875-8931-b20ebec241dc

        @assert: Parameters listed for specific Host.

        @CaseLevel: Integration
        """
        sc_param_id = self.sc_params_ids_list.pop()
        SmartClassParameter.update({
            'id': sc_param_id,
            'override': 1,
        })
        sc_param = SmartClassParameter.info({
            'puppet-class': self.puppet_class['name'],
            'id': sc_param_id,
        })
        self.assertEqual(sc_param['override'], True)
        host = entities.Host(organization=self.org['id']).create()
        Host.update({
            u'name': host.name,
            u'environment': self.env['name'],
            u'puppet-classes': self.puppet_class['name'],
        })
        host_sc_params_list = Host.sc_params({u'host': host.name})
        self.assertGreater(len(host_sc_params_list), 0)
Example #12
0
    def test_positive_run_custom_job_template_by_ip(self):
        """Run custom template on host connected by ip

        :id: 9740eb1d-59f5-42b2-b3ab-659ca0202c74

        :expectedresults: Verify the job was successfully ran against the host
        """
        # set connecting to host via ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        template_name = gen_string('alpha', 7)
        make_job_template({
            u'organizations': self.org.name,
            u'name': template_name,
            u'file': TEMPLATE_FILE
        })
        invocation_command = make_job_invocation({
            'job-template': template_name,
            'search-query': "name ~ {0}".format(self.client.hostname),
        })
        try:
            self.assertEqual(invocation_command['success'], u'1')
        except AssertionError:
            result = 'host output: {0}'.format(
                ' '.join(JobInvocation.get_output({
                    'id': invocation_command[u'id'],
                    'host': self.client.hostname})
                    )
                )
            raise AssertionError(result)
Example #13
0
    def test_positive_install_multiple_packages_with_a_job_by_ip(self):
        """Run job to install several packages on host by ip

        :id: 8b73033f-83c9-4024-83c3-5e442a79d320

        :expectedresults: Verify the packages were successfully installed
            on host
        """
        # set connecting to host by ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        packages = ["cow", "dog", "lion"]
        # Create a custom repo
        repo = entities.Repository(
            content_type='yum',
            product=entities.Product(organization=self.org).create(),
            url=FAKE_0_YUM_REPO,
        ).create()
        repo.sync()
        prod = repo.product.read()
        subs = entities.Subscription().search(
            query={'search': 'name={0}'.format(prod.name)}
        )
        self.assertGreater(
            len(subs), 0, 'No subscriptions matching the product returned'
        )

        ak = entities.ActivationKey(
            organization=self.org,
            content_view=self.org.default_content_view,
            environment=self.org.library
        ).create()
        ak.add_subscriptions(data={'subscriptions': [{'id': subs[0].id}]})
        self.client.register_contenthost(
            org=self.org.label, activation_key=ak.name
        )

        invocation_command = make_job_invocation({
            'job-template': 'Install Package - Katello SSH Default',
            'inputs': 'package={0} {1} {2}'.format(*packages),
            'search-query': "name ~ {0}".format(self.client.hostname),
        })
        try:
            self.assertEqual(invocation_command['success'], u'1')
        except AssertionError:
            result = 'host output: {0}'.format(
                ' '.join(JobInvocation.get_output({
                    'id': invocation_command[u'id'],
                    'host': self.client.hostname})
                    )
                )
            raise AssertionError(result)
        result = ssh.command(
            "rpm -q {0}".format(" ".join(packages)),
            hostname=self.client.ip_addr
        )
        self.assertEqual(result.return_code, 0)
Example #14
0
    def test_negative_update_os(self):
        """A host can not be updated with a operating system, which is
        not associated with host's medium

        @id: ff13d2af-e54a-4daf-a24d-7ec930b4fbbe

        @assert: A host is not updated

        @CaseLevel: Integration
        """
        new_arch = make_architecture({
            'location': self.host_args.location.name,
            'organization': self.host_args.organization.name,
        })
        new_os = make_os({
            'architectures': new_arch['name'],
            'partition-tables': self.host[
                'operating-system']['partition-table'],
        })
        with self.assertRaises(CLIReturnCodeError):
            Host.update({
                'architecture': new_arch['name'],
                'id': self.host['id'],
                'operatingsystem': new_os['title'],
            })
        self.host = Host.info({'id': self.host['id']})
        self.assertNotEqual(
            self.host['operating-system']['operating-system'], new_os['title'])
Example #15
0
    def test_positive_update_arch_by_id(self):
        """A host can be updated with a new architecture. Use entities
        ids for association

        @id: a4546fd6-997a-44e4-853a-eac235ea87b0

        @assert: A host is updated and the architecture matches

        @CaseLevel: Integration
        """
        new_arch = make_architecture({
            'location-id': self.host_args.location.id,
            'organization-id': self.host_args.organization.id,
        })
        OperatingSys.add_architecture({
            'architecture-id': new_arch['id'],
            'id': self.host_args.operatingsystem.id,
        })
        Host.update({
            'architecture-id': new_arch['id'],
            'id': self.host['id'],
        })
        self.host = Host.info({'id': self.host['id']})
        self.assertEqual(
            self.host['operating-system']['architecture'], new_arch['name'])
Example #16
0
    def test_positive_update_medium_by_id(self):
        """A host can be updated with a new medium. Use entities ids for
        association

        @id: 899f1eef-07a9-4227-848a-92e377a8d55c

        @assert: A host is updated and the medium matches

        @CaseLevel: Integration
        """
        new_medium = make_medium({
            'location-id': self.host_args.location.id,
            'organization-id': self.host_args.organization.id,
        })
        Medium.add_operating_system({
            'id': new_medium['id'],
            'operatingsystem-id': self.host_args.operatingsystem.id,
        })
        new_medium = Medium.info({'id': new_medium['id']})
        Host.update({
            'id': self.host['id'],
            'medium-id': new_medium['id'],
        })
        self.host = Host.info({'id': self.host['id']})
        self.assertEqual(
            self.host['operating-system']['medium'], new_medium['name'])
Example #17
0
    def test_positive_update_os_by_id(self):
        """A host can be updated with a new operating system. Use
        entities ids for association

        @id: 9ea88634-9c14-4519-be6e-fb163897efb7

        @assert: A host is updated and the operating system matches

        @CaseLevel: Integration
        """
        new_os = make_os({
            'architecture-ids': self.host_args.architecture.id,
            'partition-table-ids': self.host_args.ptable.id,
        })
        Medium.add_operating_system({
            'id': self.host_args.medium.id,
            'operatingsystem-id': new_os['id'],
        })
        Host.update({
            'id': self.host['id'],
            'operatingsystem-id': new_os['id'],
        })
        self.host = Host.info({'id': self.host['id']})
        self.assertEqual(
            self.host['operating-system']['operating-system'], new_os['title'])
Example #18
0
    def test_positive_update_arch_by_name(self):
        """A host can be updated with a new architecture. Use entities
        names for association

        @id: 92da3782-47db-4701-aaab-3ea974043d20

        @assert: A host is updated and the architecture matches

        @CaseLevel: Integration
        """
        new_arch = make_architecture({
            'location': self.host_args.location.name,
            'organization': self.host_args.organization.name,
        })
        OperatingSys.add_architecture({
            'architecture': new_arch['name'],
            'title': self.host_args.operatingsystem.title,
        })
        Host.update({
            'architecture': new_arch['name'],
            'name': self.host['name'],
        })
        self.host = Host.info({'name': self.host['name']})
        self.assertEqual(
            self.host['operating-system']['architecture'], new_arch['name'])
    def test_positive_run_custom_job_template(self):
        """Run a job template against a single host

        :id: 89b75feb-afff-44f2-a2bd-2ffe74b63ec7

        :Setup: Create a working job template.

        :Steps:

            1. Navigate to an individual host and click Run Job
            2. Select the job and appropriate template
            3. Run the job

        :expectedresults: Verify the job was successfully ran against the host

        :CaseLevel: System
        """
        jobs_template_name = gen_string('alpha')
        with VirtualMachine(
                distro=DISTRO_RHEL7,
                bridge=settings.vlan_networking.bridge
                ) as client:
            client.install_katello_ca()
            client.register_contenthost(self.organization.label, lce='Library')
            self.assertTrue(client.subscribed)
            add_remote_execution_ssh_key(client.ip_addr)
            Host.update({
                u'name': client.hostname,
                u'subnet-id': self.new_sub['id'],
            })
            with Session(self) as session:
                set_context(session, org=self.organization.name)
                make_job_template(
                    session,
                    name=jobs_template_name,
                    template_type='input',
                    template_content='<%= input("command") %>',
                    provider_type='SSH',
                )
                self.assertIsNotNone(
                    self.jobtemplate.search(jobs_template_name))
                self.jobtemplate.add_input(
                    jobs_template_name, 'command', required=True)
                self.hosts.click(self.hosts.search(client.hostname))
                status = self.job.run(
                    job_category='Miscellaneous',
                    job_template=jobs_template_name,
                    options_list=[{'name': 'command', 'value': 'ls'}]
                )
                # get job invocation id from the current url
                invocation_id = self.browser.current_url.rsplit('/', 1)[-1]
                self.assertTrue(
                        status,
                        'host output: {0}'.format(
                            ' '.join(JobInvocation.get_output({
                                'id': invocation_id,
                                'host': client.hostname})
                            )
                        )
                    )
Example #20
0
    def test_create_libvirt_without_mac(self):
        """@Test: Create a libvirt host and not specify a MAC address.

        @Feature: Hosts

        @Assert: Host is created

        """
        compute_resource = entities.LibvirtComputeResource(
            url='qemu+tcp://{0}:16509/system'.format(
                settings.server.hostname
            ),
        ).create()
        host = entities.Host()
        host.create_missing()
        Host.create({
            u'architecture-id': host.architecture.id,
            u'compute-resource-id': compute_resource.id,
            u'domain-id': host.domain.id,
            u'environment-id': host.environment.id,
            u'interface': 'type=network',
            u'location-id': host.location.id,  # pylint:disable=no-member
            u'medium-id': host.medium.id,
            u'name': host.name,
            u'operatingsystem-id': host.operatingsystem.id,
            u'organization-id': host.organization.id,  # pylint:disable=E1101
            u'partition-table-id': host.ptable.id,
            u'puppet-proxy-id': self.puppet_proxy['id'],
            u'root-pass': host.root_pass,
        })
Example #21
0
    def test_positive_update_medium_by_name(self):
        """A host can be updated with a new medium. Use entities names
        for association

        @id: f47edb02-d649-4ca8-94b2-0637ebdac2e8

        @assert: A host is updated and the medium matches

        @CaseLevel: Integration
        """
        new_medium = make_medium({
            'location': self.host_args.location.name,
            'organization': self.host_args.organization.name,
        })
        Medium.add_operating_system({
            'name': new_medium['name'],
            'operatingsystem': self.host_args.operatingsystem.title,
        })
        new_medium = Medium.info({'name': new_medium['name']})
        Host.update({
            'medium': new_medium['name'],
            'name': self.host['name'],
        })
        self.host = Host.info({'name': self.host['name']})
        self.assertEqual(
            self.host['operating-system']['medium'], new_medium['name'])
    def test_positive_run_reccuring_job(self, fixture_vmsetup, fixture_org):
        """Tests Ansible REX reccuring job runs successfully multiple times

        :id: 49b0d31d-58f9-47f1-aa5d-561a1dcb0d66

        :Steps:

            0. Create a VM and register to SAT and prepare for REX (ssh key)

            1. Run recurring Ansible Command job for the host

            2. Check the multiple job results at the host

        :expectedresults: multiple asserts along the code

        :caseautomation: automated

        :CaseLevel: System
        """
        self.org = fixture_org
        self.client = fixture_vmsetup
        # set connecting to host by ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        invocation_command = make_job_invocation({
            'job-template': 'Run Command - Ansible Default',
            'inputs': 'command="ls"',
            'search-query': "name ~ {0}".format(self.client.hostname),
            'cron-line': '* * * * *',  # every minute
            'max-iteration': 2,  # just two runs
        })
        JobInvocation.get_output({
            'id': invocation_command[u'id'],
            'host': self.client.hostname
        })
        try:
            assert invocation_command['status'] == u'queued'
        except AssertionError:
            result = 'host output: {0}'.format(
                ' '.join(JobInvocation.get_output({
                    'id': invocation_command[u'id'],
                    'host': self.client.hostname})
                    )
                )
            raise AssertionError(result)
        # Wait until the job runs
        pending_state = u'1'
        for _ in range(5):
            if pending_state != u'0':
                invocation_info = JobInvocation.info({
                    'id': invocation_command[u'id']})
                pending_state = invocation_info[u'pending']
                sleep(30)
        rec_logic = RecurringLogic.info({
            'id': invocation_command['recurring-logic-id']})
        assert rec_logic['state'] == u'finished'
        assert rec_logic['iteration'] == u'2'
Example #23
0
    def test_positive_chost_previous_env(self):
        """Check if the applicable errata are available from the content
        host's previous environment

        :id: 78110ba8-3942-46dd-8c14-bffa1dbd5195

        :Setup:

            1. Make sure multiple environments are present.
            2. Content host's previous environments have additional errata.

        :Steps: Go to Content Hosts -> Select content host -> Errata Tab ->
            Select Previous environments.

        :expectedresults: The errata from previous environments are displayed.

        :CaseLevel: System
        """
        with VirtualMachine(distro=DISTRO_RHEL7) as client:
                client.install_katello_ca()
                client.register_contenthost(
                    self.session_org.label,
                    self.activation_key.name,
                )
                self.assertTrue(client.subscribed)
                client.enable_repo(REPOS['rhst7']['id'])
                client.install_katello_agent()
                client.run(
                    'yum install -y {0}'.format(FAKE_1_CUSTOM_PACKAGE))
                last_env_id = max(
                    lce.id
                    for lce
                    in entities.LifecycleEnvironment(
                        organization=self.session_org).search()
                )
                new_env = entities.LifecycleEnvironment(
                    organization=self.session_org,
                    prior=last_env_id,
                ).create()
                cvv = ContentView.info({
                    'id': self.content_view.id})['versions'][-1]
                ContentView.version_promote({
                    'id': cvv['id'],
                    'organization-id': self.session_org.id,
                    'to-lifecycle-environment-id': new_env.id,
                })
                Host.update({
                    'name': client.hostname,
                    'lifecycle-environment-id': new_env.id,
                    'organization-id': self.session_org.id,
                })
                with Session(self):
                    self.assertIsNotNone(
                        self.contenthost.errata_search(
                            client.hostname,
                            CUSTOM_REPO_ERRATA_ID,
                            environment_name=self.env.name,
                        )
                    )
    def test_positive_run_job_effective_user_by_ip(self, fixture_vmsetup, fixture_org):
        """Run default job template as effective user on a host by ip

        :id: 0cd75cab-f699-47e6-94d3-4477d2a94bb7

        :expectedresults: Verify the job was successfully run under the
            effective user identity on host
        """
        self.org = fixture_org
        self.client = fixture_vmsetup
        # set connecting to host via ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        # create a user on client via remote job
        username = gen_string('alpha')
        filename = gen_string('alpha')
        make_user_job = make_job_invocation({
            'job-template': 'Run Command - SSH Default',
            'inputs': "command='useradd -m {0}'".format(username),
            'search-query': "name ~ {0}".format(self.client.hostname),
        })
        try:
            assert make_user_job[u'success'] == u'1'
        except AssertionError:
            result = 'host output: {0}'.format(
                ' '.join(JobInvocation.get_output({
                    'id': make_user_job[u'id'],
                    'host': self.client.hostname})
                    )
                )
            raise AssertionError(result)
        # create a file as new user
        invocation_command = make_job_invocation({
            'job-template': 'Run Command - SSH Default',
            'inputs': "command='touch /home/{0}/{1}'".format(
                username, filename),
            'search-query': "name ~ {0}".format(self.client.hostname),
            'effective-user': '******'.format(username),
        })
        try:
            assert invocation_command['success'] == u'1'
        except AssertionError:
            result = 'host output: {0}'.format(
                ' '.join(JobInvocation.get_output({
                    'id': invocation_command[u'id'],
                    'host': self.client.hostname})
                    )
                )
            raise AssertionError(result)
        # check the file owner
        result = ssh.command(
            '''stat -c '%U' /home/{0}/{1}'''.format(username, filename),
            hostname=self.client.ip_addr
        )
        # assert the file is owned by the effective user
        assert username == result.stdout[0]
Example #25
0
 def delete(cls, options=None):
     """Work around host unification not being completed in order to delete
     a content host which is now a host subscription.
     """
     # Replace content host id with host id if passed
     if 'host-id' in options:
         name = ContentHost.info({'id': options['host-id']})['name'].lower()
         options['host-id'] = Host.info({'name': name})['id']
     return Host.subscription_unregister(options)
    def test_positive_run_default_job_template_by_ip(self):
        """Run a job template on a host connected by ip

        :id: 9a90aa9a-00b4-460e-b7e6-250360ee8e4d

        :Setup: Use pre-defined job template.

        :Steps:

            1. Set remote_execution_connect_by_ip on host to true
            2. Navigate to an individual host and click Run Job
            3. Select the job and appropriate template
            4. Run the job

        :expectedresults: Verify the job was successfully ran against the host

        :CaseLevel: Integration
        """
        with VirtualMachine(
              distro=DISTRO_RHEL7,
              provisioning_server=settings.compute_resources.libvirt_hostname,
              bridge=settings.vlan_networking.bridge,
              ) as client:
            client.install_katello_ca()
            client.register_contenthost(self.organization.label, lce='Library')
            self.assertTrue(client.subscribed)
            add_remote_execution_ssh_key(client.ip_addr)
            Host.update({
                'name': client.hostname,
                'subnet-id': self.new_sub.id,
            })
            # connect to host by ip
            Host.set_parameter({
                'host': client.hostname,
                'name': 'remote_execution_connect_by_ip',
                'value': 'True',
            })
            with Session(self) as session:
                set_context(session, org=self.organization.name)
                self.hosts.click(self.hosts.search(client.hostname))
                status = self.job.run(
                    job_category='Commands',
                    job_template='Run Command - SSH Default',
                    options_list=[{'name': 'command', 'value': 'ls'}]
                )
                # get job invocation id from the current url
                invocation_id = self.browser.current_url.rsplit('/', 1)[-1]
                try:
                    self.assertTrue(status)
                except AssertionError:
                    result = 'host output: {0}'.format(
                            ' '.join(JobInvocation.get_output({
                                'id': invocation_id,
                                'host': client.hostname})
                            )
                        )
                    raise AssertionError(result)
    def test_positive_run_job_template_multiple_hosts(self):
        """Run a job template against multiple hosts

        :id: 7f1981cb-afcc-49b7-a565-7fef9aa8ddde

        :Setup: Create a working job template.

        :Steps:

            1. Navigate to the hosts page and select at least two hosts
            2. Click the "Select Action"
            3. Select the job and appropriate template
            4. Run the job

        :expectedresults: Verify the job was successfully ran against the hosts

        :CaseLevel: System
        """
        with VirtualMachine(
                distro=DISTRO_RHEL7,
                bridge=settings.vlan_networking.bridge
                ) as client:
            with VirtualMachine(
                    distro=DISTRO_RHEL7,
                    bridge=settings.vlan_networking.bridge
                    ) as client2:
                for vm in client, client2:
                    vm.install_katello_ca()
                    vm.register_contenthost(
                        self.organization.label, lce='Library')
                    self.assertTrue(vm.subscribed)
                    add_remote_execution_ssh_key(vm.ip_addr)
                    Host.update({
                        u'name': vm.hostname,
                        u'subnet-id': self.new_sub['id'],
                    })
                with Session(self) as session:
                    set_context(session, org=self.organization.name)
                    self.hosts.update_host_bulkactions(
                        [client.hostname, client2.hostname],
                        action='Run Job',
                        parameters_list=[{'command': 'ls'}],
                    )
                    strategy, value = locators['job_invocation.status']
                    if self.job.wait_until_element(
                            (strategy, value % 'succeeded'), 240) is not None:
                        status = True
                    else:
                        status = False
                    # get job invocation id from the current url
                    invocation_id = self.browser.current_url.rsplit('/', 1)[-1]
                    self.assertTrue(status, 'host output: {0}'.format(
                        ' '.join(JobInvocation.get_output({
                             'id': invocation_id,
                             'host': client.hostname
                         }))))
Example #28
0
    def test_positive_delete_by_name(self):
        """Create a host and then delete it by name.

        @id: 93f7504d-9a63-491f-8fdb-ed8017aefab9

        @Assert: Host is deleted
        """
        Host.delete({'name': self.host['name']})
        with self.assertRaises(CLIReturnCodeError):
            Host.info({'name': self.host['name']})
Example #29
0
    def test_positive_delete_by_name(self):
        """Create a host and then delete it by name.

        @Feature: Hosts

        @Assert: Host is deleted
        """
        Host.delete({'name': self.host['name']})
        with self.assertRaises(CLIReturnCodeError):
            Host.info({'name': self.host['name']})
Example #30
0
    def test_positive_delete_by_id(self):
        """Create a host and then delete it by id.

        @id: e687a685-ab8b-4c5f-97f9-e14d3ab52f29

        @Assert: Host is deleted
        """
        Host.delete({'id': self.host['id']})
        with self.assertRaises(CLIReturnCodeError):
            Host.info({'id': self.host['id']})
    def test_positive_run_job_template_multiple_hosts_by_ip(self):
        """Run a job template against multiple hosts by ip

        :id: c4439ec0-bb80-47f6-bc31-fa7193bfbeeb

        :Setup: Create a working job template.

        :Steps:

            1. Set remote_execution_connect_by_ip on hosts to true
            2. Navigate to the hosts page and select at least two hosts
            3. Click the "Select Action"
            4. Select the job and appropriate template
            5. Run the job

        :expectedresults: Verify the job was successfully ran against the hosts

        :CaseLevel: System
        """
        prov_server = settings.compute_resources.libvirt_hostname
        with VirtualMachine(
              distro=DISTRO_RHEL7,
              provisioning_server=prov_server,
              bridge=settings.vlan_networking.bridge,
              ) as client:
            with VirtualMachine(
                  distro=DISTRO_RHEL7,
                  provisioning_server=prov_server,
                  bridge=settings.vlan_networking.bridge,
                  ) as client2:
                for vm in client, client2:
                    vm.install_katello_ca()
                    vm.register_contenthost(
                        self.organization.label, lce='Library')
                    self.assertTrue(vm.subscribed)
                    add_remote_execution_ssh_key(vm.ip_addr)
                    Host.update({
                        'name': vm.hostname,
                        'subnet-id': self.new_sub.id,
                    })
                    # connect to host by ip
                    Host.set_parameter({
                        'host': vm.hostname,
                        'name': 'remote_execution_connect_by_ip',
                        'value': 'True',
                    })
                with Session(self) as session:
                    set_context(session, org=self.organization.name)
                    self.hosts.update_host_bulkactions(
                        [client.hostname, client2.hostname],
                        action='Schedule Remote Job',
                        parameters_list=[{'command': 'ls'}],
                    )
                    strategy, value = locators['job_invocation.status']
                    if self.job.wait_until_element(
                            (strategy, value % 'succeeded'), 240) is not None:
                        status = True
                    else:
                        status = False
                    # get job invocation id from the current url
                    invocation_id = self.browser.current_url.rsplit('/', 1)[-1]
                    try:
                        self.assertTrue(status)
                    except AssertionError:
                        result = 'host output: {0}'.format(
                                ' '.join(JobInvocation.get_output({
                                     'id': invocation_id,
                                     'host': client.hostname})
                                )
                            )
                        raise AssertionError(result)
Example #32
0
    def test_positive_restore_content_hosts_with_modified_subscription(self):
        """Restore content hosts subscription from an exported content host csv
        file with modified subscription.

        :id: d8ac08fe-24e0-41e7-b3d8-0ca13a702a64

        :customerscenario: true

        :steps:
            1. Setup activation key , lifecycle environment and content view
               with RH tools repository
            2. Setup hosts (minimum two) and subscribe them to activation key
            3. Attach RH subscription to the created content hosts
            4. Export the organization content hosts to a csv file
            5. Create a new csv file and modify the subscription with an other
               one (the new subscription must have other data than the default
               one)
            6. Import the new csv file to organization content hosts

        :expectedresults: content hosts restored with the new subscription

        :BZ: 1296978

        :CaseImportance: Critical
        """
        lce = make_lifecycle_environment({'organization-id': self.org['id']})
        activation_key = make_activation_key({
            'organization-id':
            self.org['id'],
            'lifecycle-environment-id':
            lce['id'],
        })
        ActivationKey.update({
            'organization-id': self.org['id'],
            'id': activation_key['id'],
            'auto-attach': 'false',
        })
        # Create RH tools repository and contents, this step should upload
        # the default manifest
        setup_org_for_a_rh_repo(
            {
                'product': PRDS['rhel'],
                'repository-set': REPOSET['rhst7'],
                'repository': REPOS['rhst7']['name'],
                'organization-id': self.org['id'],
                'lifecycle-environment-id': lce['id'],
                'activationkey-id': activation_key['id'],
            },
            force_use_cdn=True)
        # Export and download the organization subscriptions to prepare the new
        # subscription (The replacement of the default subscription)
        org_subs_csv_filename = 'subs_{0}.csv'.format(self.org['name'])
        org_subs_csv_remote_file_path = '/tmp/{0}'.format(
            org_subs_csv_filename)
        # export organization subscription to csv file
        CSV_.subscriptions({
            'export': True,
            'file': org_subs_csv_remote_file_path,
            'organization': self.org['name'],
        })
        # download the organization subscriptions
        org_subs_csv_local_file_path = os.path.join(tempfile.gettempdir(),
                                                    org_subs_csv_filename)
        download_file(org_subs_csv_remote_file_path,
                      org_subs_csv_local_file_path)
        _, org_subscriptions = self._read_csv_file(
            org_subs_csv_local_file_path)
        new_subscription = None
        for sub in org_subscriptions:
            if sub['Subscription Name'] == SATELLITE_SUBSCRIPTION_NAME:
                new_subscription = sub
                break
        self.assertIsNotNone(new_subscription)
        # retrieve the default subscription id
        org_subs = Subscription.list({u'organization-id': self.org['id']})
        default_subscription_id = None
        for sub in org_subs:
            if sub['name'] == DEFAULT_SUBSCRIPTION_NAME:
                default_subscription_id = sub['id']
                break
        self.assertIsNotNone(default_subscription_id,
                             msg='Default subscription not found')
        # create 2 Virtual machines
        with VirtualMachine() as client1, VirtualMachine() as client2:
            hosts = []
            for client in [client1, client2]:
                client.install_katello_ca()
                client.register_contenthost(
                    self.org['label'], activation_key=activation_key['name'])
                self.assertTrue(client.subscribed)
                host = Host.info({'name': client.hostname})
                hosts.append(host)
                Host.subscription_attach({
                    'host-id':
                    host['id'],
                    'subscription-id':
                    default_subscription_id,
                })
                host_subscriptions = ActivationKey.subscriptions(
                    {
                        'organization-id': self.org['id'],
                        'id': activation_key['id'],
                        'host-id': host['id'],
                    },
                    output_format='json')
                self.assertEqual(len(host_subscriptions), 1)
                self.assertEqual(host_subscriptions[0]['name'],
                                 DEFAULT_SUBSCRIPTION_NAME)
            # export the content host data to csv file
            chs_export_file_name = 'chs_export_{0}.csv'.format(
                self.org['label'])
            chs_export_remote_file_path = (
                '/tmp/{0}'.format(chs_export_file_name))
            CSV_.content_hosts({
                'export': True,
                'file': chs_export_remote_file_path,
                'organization': self.org['name'],
            })
            # download the csv file
            chs_export_local_file_path = os.path.join(tempfile.gettempdir(),
                                                      chs_export_file_name)
            download_file(chs_export_remote_file_path,
                          chs_export_local_file_path)
            # modify the content hosts subscription
            field_names, csv_data = self._read_csv_file(
                chs_export_local_file_path)
            # each client is represented by one row of data
            self.assertEqual(len(csv_data), 2)
            for row_data in csv_data:
                # The subscription is saved in the following format:
                # """<quantity>|<sku>|<name>|<contract>|<account>"""
                subscription_data = row_data['Subscriptions'].strip('"').split(
                    '|')
                # change the subscription SKU (looks like RH00001)
                subscription_data[1] = new_subscription['Subscription SKU']
                # change the name
                subscription_data[2] = new_subscription['Subscription Name']
                # change the contract number
                subscription_data[3] = new_subscription[
                    'Subscription Contract']
                # change the subscription account
                subscription_data[4] = new_subscription['Subscription Account']
                # modify the subscription data
                row_data['Subscriptions'] = '"{0}"'.format(
                    '|'.join(subscription_data))
            # generate a new csv file
            chs_import_file_name = 'chs_import_{0}.csv'.format(
                self.org['name'])
            chs_import_local_file_path = os.path.join(tempfile.gettempdir(),
                                                      chs_import_file_name)
            self._write_csv_file(chs_import_local_file_path, field_names,
                                 csv_data)
            # upload the file
            chs_import_remote_file_path = (
                '/tmp/{0}'.format(chs_import_file_name))
            upload_file(chs_import_local_file_path,
                        chs_import_remote_file_path)
            # import content hosts data from csv file
            CSV_.content_hosts({
                'file': chs_import_remote_file_path,
                'organization': self.org['name'],
            })
            for host in hosts:
                host_subscriptions = ActivationKey.subscriptions(
                    {
                        'organization-id': self.org['id'],
                        'id': activation_key['id'],
                        'host-id': host['id'],
                    },
                    output_format='json')
                self.assertEqual(len(host_subscriptions), 1)
                self.assertEqual(host_subscriptions[0]['name'],
                                 SATELLITE_SUBSCRIPTION_NAME)
                self.assertEqual(host_subscriptions[0]['contract'],
                                 new_subscription['Subscription Contract'])
                self.assertEqual(host_subscriptions[0]['account'],
                                 new_subscription['Subscription Account'])
Example #33
0
def test_positive_oscap_run_via_ansible_bz_1814988(
    module_org, default_proxy, content_view, lifecycle_env
):
    """End-to-End Oscap run via ansible

    :id: 375f8f08-9299-4d16-91f9-9426eeecb9c5

    :parametrized: yes

    :setup: scap content, scap policy, host group

    :steps:

        1. Create a valid scap content
        2. Import Ansible role theforeman.foreman_scap_client
        3. Import Ansible Variables needed for the role
        4. Create a scap policy with anisble as deploy option
        5. Associate the policy with a hostgroup
        6. Provision a host using the hostgroup
        7. Harden the host by remediating it with DISA STIG security policy
        8. Configure REX and associate the Ansible role to created host
        9. Play roles for the host

    :expectedresults: REX job should be success and ARF report should be sent to satellite

    :BZ: 1814988

    :CaseImportance: Critical
    """
    hgrp_name = gen_string('alpha')
    policy_name = gen_string('alpha')
    # Creates host_group for rhel7
    make_hostgroup(
        {
            'content-source-id': default_proxy,
            'name': hgrp_name,
            'organizations': module_org.name,
        }
    )
    # Creates oscap_policy.
    scap_id, scap_profile_id = fetch_scap_and_profile_id(
        OSCAP_DEFAULT_CONTENT['rhel7_content'], OSCAP_PROFILE['dsrhel7']
    )
    Ansible.roles_import({'proxy-id': default_proxy})
    Ansible.variables_import({'proxy-id': default_proxy})
    role_id = Ansible.roles_list({'search': 'foreman_scap_client'})[0].get('id')
    make_scap_policy(
        {
            'scap-content-id': scap_id,
            'hostgroups': hgrp_name,
            'deploy-by': 'ansible',
            'name': policy_name,
            'period': OSCAP_PERIOD['weekly'].lower(),
            'scap-content-profile-id': scap_profile_id,
            'weekday': OSCAP_WEEKDAY['friday'].lower(),
            'organizations': module_org.name,
        }
    )
    with VMBroker(nick=DISTRO_RHEL7, host_classes={'host': ContentHost}) as vm:
        host_name, _, host_domain = vm.hostname.partition('.')
        vm.install_katello_ca()
        vm.register_contenthost(module_org.name, ak_name[DISTRO_RHEL7])
        assert vm.subscribed
        Host.set_parameter(
            {
                'host': vm.hostname.lower(),
                'name': 'remote_execution_connect_by_ip',
                'value': 'True',
            }
        )
        vm.configure_rhel_repo(settings.rhel7_repo)
        # Harden the rhel7 client with DISA STIG security policy
        vm.run('yum install -y scap-security-guide')
        vm.run(
            'oscap xccdf eval --remediate --profile xccdf_org.ssgproject.content_profile_stig '
            '--fetch-remote-resources --results-arf results.xml '
            '/usr/share/xml/scap/ssg/content/ssg-rhel7-ds.xml',
        )
        add_remote_execution_ssh_key(vm.ip_addr)
        Host.update(
            {
                'name': vm.hostname.lower(),
                'lifecycle-environment': lifecycle_env.name,
                'content-view': content_view.name,
                'hostgroup': hgrp_name,
                'openscap-proxy-id': default_proxy,
                'organization': module_org.name,
                'ansible-role-ids': role_id,
            }
        )
        job_id = Host.ansible_roles_play({'name': vm.hostname.lower()})[0].get('id')
        wait_for_tasks(
            f'resource_type = JobInvocation and resource_id = {job_id} and action ~ "hosts job"'
        )
        try:
            result = JobInvocation.info({'id': job_id})['success']
            assert result == '1'
        except AssertionError:
            output = ' '.join(JobInvocation.get_output({'id': job_id, 'host': vm.hostname}))
            result = f'host output: {output}'
            raise AssertionError(result)
        result = vm.run('cat /etc/foreman_scap_client/config.yaml | grep profile')
        assert result.status == 0
        # Runs the actual oscap scan on the vm/clients and
        # uploads report to Internal Capsule.
        vm.execute_foreman_scap_client()
        # Assert whether oscap reports are uploaded to
        # Satellite6.
        result = Arfreport.list({'search': f'host={vm.hostname.lower()}'})
        assert result is not None
Example #34
0
def test_positive_oscap_run_with_tailoring_file_and_capsule(
    module_org, default_proxy, content_view, lifecycle_env, puppet_env
):
    """End-to-End Oscap run with tailoring files and default capsule via puppet

    :id: 346946ad-4f62-400e-9390-81817006048c

    :setup: scap content, scap policy, tailoring file, host group

    :steps:

        1. Create a valid scap content
        2. Upload a valid tailoring file
        3. Create a scap policy
        4. Associate scap content with it's tailoring file
        5. Associate the policy with a hostgroup
        6. Provision a host using the hostgroup
        7. Puppet should configure and fetch the scap content
           and tailoring file

    :expectedresults: ARF report should be sent to satellite reflecting
                     the changes done via tailoring files

    :BZ: 1722475

    :CaseImportance: Critical
    """
    hgrp_name = gen_string('alpha')
    policy_name = gen_string('alpha')
    tailoring_file_name = gen_string('alpha')
    tailor_path = file_downloader(
        file_url=settings.oscap.tailoring_path, hostname=settings.server.hostname
    )[0]
    # Creates host_group.
    make_hostgroup(
        {
            'content-source': settings.server.hostname,
            'name': hgrp_name,
            'puppet-environment-id': puppet_env.id,
            'puppet-ca-proxy': settings.server.hostname,
            'puppet-proxy': settings.server.hostname,
            'organizations': module_org.name,
            'puppet-classes': puppet_classes,
        }
    )

    tailor_result = make_tailoringfile(
        {
            'name': tailoring_file_name,
            'scap-file': tailor_path,
            'organization': module_org.name,
        }
    )
    result = TailoringFiles.info({'name': tailoring_file_name})
    assert result['name'] == tailoring_file_name
    # Creates oscap_policy.
    scap_id, scap_profile_id = fetch_scap_and_profile_id(
        OSCAP_DEFAULT_CONTENT['rhel7_content'], OSCAP_PROFILE['security7']
    )
    make_scap_policy(
        {
            'scap-content-id': scap_id,
            'hostgroups': hgrp_name,
            'deploy-by': 'puppet',
            'name': policy_name,
            'period': OSCAP_PERIOD['weekly'].lower(),
            'scap-content-profile-id': scap_profile_id,
            'weekday': OSCAP_WEEKDAY['friday'].lower(),
            'tailoring-file-id': tailor_result['id'],
            'tailoring-file-profile-id': tailor_result['tailoring-file-profiles'][0]['id'],
            'organizations': module_org.name,
        }
    )
    # Creates vm's and runs openscap scan and uploads report to satellite6.
    with VMBroker(nick=DISTRO_RHEL7, host_classes={'host': ContentHost}) as vm:
        host_name, _, host_domain = vm.hostname.partition('.')
        vm.install_katello_ca()
        vm.register_contenthost(module_org.name, ak_name[DISTRO_RHEL7])
        assert vm.subscribed
        Host.update(
            {
                'name': vm.hostname.lower(),
                'lifecycle-environment': lifecycle_env.name,
                'content-view': content_view.name,
                'hostgroup': hgrp_name,
                'openscap-proxy-id': default_proxy,
                'organization': module_org.name,
                'puppet-environment-id': puppet_env.id,
            }
        )
        vm.configure_puppet(settings.rhel7_repo)
        result = vm.run('cat /etc/foreman_scap_client/config.yaml | grep profile')
        assert result.status == 0
        # Runs the actual oscap scan on the vm/clients and
        # uploads report to Internal Capsule.
        vm.execute_foreman_scap_client()
        # Assert whether oscap reports are uploaded to
        # Satellite6.
        arf_report = Arfreport.list({'search': f'host={vm.hostname.lower()}', 'per-page': 1})
        assert arf_report is not None
        Arfreport.delete({'id': arf_report[0].get('id')})
def tear_down(provisioning):
    """Delete the hosts to free the resources"""
    yield
    hosts = Host.list({'organization': provisioning.org_name})
    for host in hosts:
        Host.delete({'id': host['id']})
Example #36
0
    def test_positive_run_packages_and_services_job(self, fixture_vmsetup,
                                                    fixture_org):
        """Tests Ansible REX job can install packages and start services

        :id: 47ed82fb-77ca-43d6-a52e-f62bae5d3a42

        :Steps:

            0. Create a VM and register to SAT and prepare for REX (ssh key)

            1. Run Ansible Package job for the host to install a package

            2. Check the package is present at the host

            3. Run Ansible Service job for the host to start a service

            4. Check the service is started on the host

        :expectedresults: multiple asserts along the code

        :CaseAutomation: automated

        :CaseLevel: System

        :parametrized: yes
        """
        self.org = fixture_org
        self.client = fixture_vmsetup
        # set connecting to host by ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        packages = ["cow"]
        # Create a custom repo
        repo = entities.Repository(
            content_type='yum',
            product=entities.Product(organization=self.org).create(),
            url=FAKE_0_YUM_REPO,
        ).create()
        repo.sync()
        prod = repo.product.read()
        subs = entities.Subscription().search(
            query={'search': 'name={0}'.format(prod.name)})
        assert len(subs) > 0, 'No subscriptions matching the product returned'
        ak = entities.ActivationKey(
            organization=self.org,
            content_view=self.org.default_content_view,
            environment=self.org.library,
        ).create()
        ak.add_subscriptions(data={'subscriptions': [{'id': subs[0].id}]})
        self.client.register_contenthost(org=self.org.label,
                                         activation_key=ak.name)

        # install package
        invocation_command = make_job_invocation({
            'job-template':
            'Package Action - Ansible Default',
            'inputs':
            'state=latest, name={}'.format(*packages),
            'search-query':
            "name ~ {0}".format(self.client.hostname),
        })
        try:
            assert invocation_command['success'] == '1'
        except AssertionError:
            result = 'host output: {0}'.format(' '.join(
                JobInvocation.get_output({
                    'id': invocation_command['id'],
                    'host': self.client.hostname
                })))
            raise AssertionError(result)
        result = ssh.command("rpm -q {0}".format(*packages),
                             hostname=self.client.ip_addr)
        assert result.return_code == 0

        # start a service
        service = "postfix"
        ssh.command(
            "sed -i 's/^inet_protocols.*/inet_protocols = ipv4/' /etc/postfix/main.cf",
            hostname=self.client.ip_addr,
        )
        invocation_command = make_job_invocation({
            'job-template':
            'Service Action - Ansible Default',
            'inputs':
            'state=started, name={}'.format(service),
            'search-query':
            "name ~ {0}".format(self.client.hostname),
        })
        try:
            assert invocation_command['success'] == '1'
        except AssertionError:
            result = 'host output: {0}'.format(' '.join(
                JobInvocation.get_output({
                    'id': invocation_command['id'],
                    'host': self.client.hostname
                })))
            raise AssertionError(result)
        result = ssh.command("systemctl status {0}".format(service),
                             hostname=self.client.ip_addr)
        assert result.return_code == 0
Example #37
0
    def test_positive_run_effective_user_job(self, fixture_vmsetup,
                                             fixture_org):
        """Tests Ansible REX job having effective user runs successfully

        :id: a5fa20d8-c2bd-4bbf-a6dc-bf307b59dd8c

        :Steps:

            0. Create a VM and register to SAT and prepare for REX (ssh key)

            1. Run Ansible Command job for the host to create a user

            2. Run Ansible Command job using effective user

            3. Check the job result at the host is done under that user

        :expectedresults: multiple asserts along the code

        :CaseAutomation: automated

        :CaseLevel: System
        """
        self.org = fixture_org
        self.client = fixture_vmsetup
        # set connecting to host via ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        # create a user on client via remote job
        username = gen_string('alpha')
        filename = gen_string('alpha')
        make_user_job = make_job_invocation({
            'job-template':
            'Run Command - Ansible Default',
            'inputs':
            "command='useradd -m {0}'".format(username),
            'search-query':
            "name ~ {0}".format(self.client.hostname),
        })
        try:
            assert make_user_job[u'success'] == u'1'
        except AssertionError:
            result = 'host output: {0}'.format(' '.join(
                JobInvocation.get_output({
                    'id': make_user_job[u'id'],
                    'host': self.client.hostname
                })))
            raise AssertionError(result)
        # create a file as new user
        invocation_command = make_job_invocation({
            'job-template':
            'Run Command - Ansible Default',
            'inputs':
            "command='touch /home/{0}/{1}'".format(username, filename),
            'search-query':
            "name ~ {0}".format(self.client.hostname),
            'effective-user':
            '******'.format(username),
        })
        try:
            assert invocation_command['success'] == u'1'
        except AssertionError:
            result = 'host output: {0}'.format(' '.join(
                JobInvocation.get_output({
                    'id': invocation_command[u'id'],
                    'host': self.client.hostname
                })))
            raise AssertionError(result)
        # check the file owner
        result = ssh.command('''stat -c '%U' /home/{0}/{1}'''.format(
            username, filename),
                             hostname=self.client.ip_addr)
        # assert the file is owned by the effective user
        assert username == result.stdout[0], "file ownership mismatch"
Example #38
0
    def test_positive_oscap_run_with_tailoring_file_and_capsule(self):
        """ End-to-End Oscap run with tailoring files and default capsule via puppet

        :id: 346946ad-4f62-400e-9390-81817006048c

        :setup: scap content, scap policy, tailoring file, host group

        :steps:

            1. Create a valid scap content
            2. Upload a valid tailoring file
            3. Create a scap policy
            4. Associate scap content with it's tailoring file
            5. Associate the policy with a hostgroup
            6. Provision a host using the hostgroup
            7. Puppet should configure and fetch the scap content
               and tailoring file

        :expectedresults: ARF report should be sent to satellite reflecting
                         the changes done via tailoring files

        :BZ: 1722475

        :CaseImportance: Critical
        """
        if settings.rhel7_repo is None:
            self.skipTest('Missing configuration for rhel7_repo')
        rhel7_repo = settings.rhel7_repo
        hgrp7_name = gen_string('alpha')
        policy_values = {
            'content': self.rhel7_content,
            'hgrp': hgrp7_name,
            'policy': gen_string('alpha'),
            'profile': OSCAP_PROFILE['security7'],
        }
        vm_values = {
            'distro': DISTRO_RHEL7,
            'hgrp': hgrp7_name,
            'rhel_repo': rhel7_repo
        }
        tailoring_file_name = gen_string('alpha')
        tailor_path = file_downloader(file_url=settings.oscap.tailoring_path,
                                      hostname=settings.server.hostname)[0]
        # Creates host_group for rhel7
        make_hostgroup({
            'content-source-id': self.proxy_id,
            'name': hgrp7_name,
            'puppet-environment-id': self.puppet_env.id,
            'puppet-ca-proxy': self.config_env['sat6_hostname'],
            'puppet-proxy': self.config_env['sat6_hostname'],
            'organizations': self.config_env['org_name'],
        })

        tailor_result = make_tailoringfile({
            'name':
            tailoring_file_name,
            'scap-file':
            tailor_path,
            'organization':
            self.config_env['org_name'],
        })
        result = TailoringFiles.info({'name': tailoring_file_name})
        self.assertEqual(result['name'], tailoring_file_name)
        # Creates oscap_policy for rhel7.
        scap_id, scap_profile_id = self.fetch_scap_and_profile_id(
            policy_values.get('content'), policy_values.get('profile'))
        make_scap_policy({
            'scap-content-id':
            scap_id,
            'deploy-by':
            'puppet',
            'hostgroups':
            policy_values.get('hgrp'),
            'name':
            policy_values.get('policy'),
            'period':
            OSCAP_PERIOD['weekly'].lower(),
            'scap-content-profile-id':
            scap_profile_id,
            'weekday':
            OSCAP_WEEKDAY['friday'].lower(),
            'tailoring-file-id':
            tailor_result['id'],
            'tailoring-file-profile-id':
            tailor_result['tailoring-file-profiles'][0]['id'],
            'organizations':
            self.config_env['org_name'],
        })
        distro_os = vm_values.get('distro')
        with VirtualMachine(distro=distro_os) as vm:
            host_name, _, host_domain = vm.hostname.partition('.')
            vm.install_katello_ca()
            vm.register_contenthost(self.config_env['org_name'],
                                    self.config_env['ak_name'].get(distro_os))
            self.assertTrue(vm.subscribed)
            vm.configure_puppet(rhel7_repo)
            Host.update({
                'name': vm.hostname.lower(),
                'lifecycle-environment': self.config_env['env_name'],
                'content-view': self.config_env['cv_name'],
                'hostgroup': vm_values.get('hgrp'),
                'openscap-proxy-id': self.proxy_id,
                'organization': self.config_env['org_name'],
                'puppet-environment-id': self.puppet_env.id,
            })
            # Run "puppet agent -t" twice so that it detects it's,
            # satellite6 and fetch katello SSL certs.
            for _ in range(2):
                vm.run('puppet agent -t 2> /dev/null')
            result = vm.run(
                'cat /etc/foreman_scap_client/config.yaml | grep profile')
            self.assertEqual(result.return_code, 0)
            # Runs the actual oscap scan on the vm/clients and
            # uploads report to Internal Capsule.
            vm.execute_foreman_scap_client()
            # Assert whether oscap reports are uploaded to
            # Satellite6.
            self.assertIsNotNone(
                Arfreport.list(
                    {'search': 'host={0}'.format(vm.hostname.lower())}))
Example #39
0
    def test_positive_oscap_run_with_tailoring_file_with_ansible(self):
        """ End-to-End Oscap run with tailoring files via ansible

        :id: c7ea56eb-6cf1-4e79-8d6a-fb872d1bb804

        :setup: scap content, scap policy, tailoring file, host group

        :steps:

            1. Create a valid scap content
            2. Upload a valid tailoring file
            3. Import Ansible role theforeman.foreman_scap_client
            4. Import Ansible Variables needed for the role
            5. Create a scap policy with anisble as deploy option
            6. Associate scap content with it's tailoring file
            7. Associate the policy with a hostgroup
            8. Provision a host using the hostgroup
            9. Configure REX and associate the Ansible role to created host
            10. Play roles for the host

        :expectedresults: REX job should be success and ARF report should be sent to satellite
                         reflecting the changes done via tailoring files

        :BZ: 1716307

        :CaseImportance: Critical
        """
        if settings.rhel7_repo is None:
            self.skipTest('Missing configuration for rhel7_repo')
        rhel7_repo = settings.rhel7_repo
        hgrp7_name = gen_string('alpha')
        policy_values = {
            'content': self.rhel7_content,
            'hgrp': hgrp7_name,
            'policy': gen_string('alpha'),
            'profile': OSCAP_PROFILE['security7'],
        }
        vm_values = {
            'distro': DISTRO_RHEL7,
            'hgrp': hgrp7_name,
            'rhel_repo': rhel7_repo
        }
        tailoring_file_name = gen_string('alpha')
        tailor_path = file_downloader(file_url=settings.oscap.tailoring_path,
                                      hostname=settings.server.hostname)[0]
        # Creates host_group for rhel7
        make_hostgroup({
            'content-source-id': self.proxy_id,
            'name': hgrp7_name,
            'organizations': self.config_env['org_name'],
        })

        tailor_result = make_tailoringfile({
            'name':
            tailoring_file_name,
            'scap-file':
            tailor_path,
            'organization':
            self.config_env['org_name'],
        })
        result = TailoringFiles.info({'name': tailoring_file_name})
        self.assertEqual(result['name'], tailoring_file_name)
        # Creates oscap_policy for rhel7.
        scap_id, scap_profile_id = self.fetch_scap_and_profile_id(
            policy_values.get('content'), policy_values.get('profile'))
        Ansible.roles_import({'proxy-id': self.proxy_id})
        Ansible.variables_import({'proxy-id': self.proxy_id})
        role_id = Ansible.roles_list({'search':
                                      'foreman_scap_client'})[0].get('id')
        make_scap_policy({
            'scap-content-id':
            scap_id,
            'hostgroups':
            policy_values.get('hgrp'),
            'deploy-by':
            'ansible',
            'name':
            policy_values.get('policy'),
            'period':
            OSCAP_PERIOD['weekly'].lower(),
            'scap-content-profile-id':
            scap_profile_id,
            'weekday':
            OSCAP_WEEKDAY['friday'].lower(),
            'tailoring-file-id':
            tailor_result['id'],
            'tailoring-file-profile-id':
            tailor_result['tailoring-file-profiles'][0]['id'],
            'organizations':
            self.config_env['org_name'],
        })
        distro_os = vm_values.get('distro')
        with VirtualMachine(distro=distro_os) as vm:
            host_name, _, host_domain = vm.hostname.partition('.')
            vm.install_katello_ca()
            vm.register_contenthost(self.config_env['org_name'],
                                    self.config_env['ak_name'].get(distro_os))
            self.assertTrue(vm.subscribed)
            Host.set_parameter({
                'host': vm.hostname.lower(),
                'name': 'remote_execution_connect_by_ip',
                'value': 'True',
            })
            vm.configure_rhel_repo(settings.rhel7_repo)
            add_remote_execution_ssh_key(vm.ip_addr)
            Host.update({
                'name': vm.hostname.lower(),
                'lifecycle-environment': self.config_env['env_name'],
                'content-view': self.config_env['cv_name'],
                'hostgroup': vm_values.get('hgrp'),
                'openscap-proxy-id': self.proxy_id,
                'organization': self.config_env['org_name'],
                'ansible-role-ids': role_id,
            })
            job_id = Host.ansible_roles_play({'name': vm.hostname.lower()
                                              })[0].get('id')
            wait_for_tasks(
                "resource_type = JobInvocation and resource_id = {0} and "
                "action ~ \"hosts job\"".format(job_id))
            try:
                self.assertEqual(
                    JobInvocation.info({'id': job_id})['success'], '1')
            except AssertionError:
                result = 'host output: {0}'.format(' '.join(
                    JobInvocation.get_output({
                        'id': job_id,
                        'host': vm.hostname
                    })))
                raise AssertionError(result)
            result = vm.run(
                'cat /etc/foreman_scap_client/config.yaml | grep profile')
            self.assertEqual(result.return_code, 0)
            # Runs the actual oscap scan on the vm/clients and
            # uploads report to Internal Capsule.
            vm.execute_foreman_scap_client()
            # Assert whether oscap reports are uploaded to
            # Satellite6.
            self.assertIsNotNone(
                Arfreport.list(
                    {'search': 'host={0}'.format(vm.hostname.lower())}))
Example #40
0
    def test_positive_upload_to_satellite(self):
        """Perform end to end oscap test and upload reports via puppet

        :id: 17a0978d-64f9-44ad-8303-1f54ada08602

        :expectedresults: Oscap reports from rhel6 and rhel7 clients should be
            uploaded to satellite6 and be searchable.

        :CaseLevel: System

        :BZ: 1479413, 1722475
        """
        if settings.rhel6_repo is None:
            self.skipTest('Missing configuration for rhel6_repo')
        rhel6_repo = settings.rhel6_repo
        if settings.rhel7_repo is None:
            self.skipTest('Missing configuration for rhel7_repo')
        rhel7_repo = settings.rhel7_repo
        hgrp6_name = gen_string('alpha')
        hgrp7_name = gen_string('alpha')
        policy6_name = gen_string('alpha')
        policy7_name = gen_string('alpha')
        policy_values = [
            {
                'content': self.rhel6_content,
                'hgrp': hgrp6_name,
                'policy': policy6_name,
                'profile': OSCAP_PROFILE['security6'],
            },
            {
                'content': self.rhel7_content,
                'hgrp': hgrp7_name,
                'policy': policy7_name,
                'profile': OSCAP_PROFILE['security7'],
            },
        ]
        vm_values = [
            {
                'distro': DISTRO_RHEL6,
                'hgrp': hgrp6_name,
                'rhel_repo': rhel6_repo,
                'policy': policy6_name,
            },
            {
                'distro': DISTRO_RHEL7,
                'hgrp': hgrp7_name,
                'rhel_repo': rhel7_repo,
                'policy': policy7_name,
            },
        ]

        # Creates host_group for both rhel6 and rhel7
        for host_group in [hgrp6_name, hgrp7_name]:
            make_hostgroup({
                'content-source': self.config_env['sat6_hostname'],
                'name': host_group,
                'puppet-environment-id': self.puppet_env.id,
                'puppet-ca-proxy': self.config_env['sat6_hostname'],
                'puppet-proxy': self.config_env['sat6_hostname'],
                'organizations': self.config_env['org_name'],
            })
        # Creates oscap_policy for both rhel6 and rhel7.
        for value in policy_values:
            scap_id, scap_profile_id = self.fetch_scap_and_profile_id(
                value['content'], value['profile'])
            make_scap_policy({
                'scap-content-id': scap_id,
                'hostgroups': value['hgrp'],
                'deploy-by': 'puppet',
                'name': value['policy'],
                'period': OSCAP_PERIOD['weekly'].lower(),
                'scap-content-profile-id': scap_profile_id,
                'weekday': OSCAP_WEEKDAY['friday'].lower(),
                'organizations': self.config_env['org_name'],
            })
        # Creates two vm's each for rhel6 and rhel7, runs
        # openscap scan and uploads report to satellite6.
        for value in vm_values:
            with VirtualMachine(distro=value['distro']) as vm:
                host = vm.hostname
                host_name, _, host_domain = vm.hostname.partition('.')
                vm.install_katello_ca()
                vm.register_contenthost(
                    self.config_env['org_name'],
                    self.config_env['ak_name'].get(value['distro']))
                self.assertTrue(vm.subscribed)
                vm.configure_puppet(value['rhel_repo'])
                Host.update({
                    'name':
                    vm.hostname.lower(),
                    'lifecycle-environment':
                    self.config_env['env_name'],
                    'content-view':
                    self.config_env['cv_name'],
                    'hostgroup':
                    value['hgrp'],
                    'openscap-proxy-id':
                    self.proxy_id,
                    'organization':
                    self.config_env['org_name'],
                    'puppet-environment-id':
                    self.puppet_env.id,
                })

                # Run "puppet agent -t" twice so that it detects it's,
                # satellite6 and fetch katello SSL certs.
                for _ in range(2):
                    vm.run('puppet agent -t 2> /dev/null')
                result = vm.run(
                    'cat /etc/foreman_scap_client/config.yaml | grep profile')
                self.assertEqual(result.return_code, 0)
                # Runs the actual oscap scan on the vm/clients and
                # uploads report to Internal Capsule.
                vm.execute_foreman_scap_client()
                # Assert whether oscap reports are uploaded to
                # Satellite6.
                self.assertIsNotNone(
                    Arfreport.list({'search': 'host={0}'.format(host)}))
Example #41
0
    def test_positive_push_updated_content(self):
        """Perform end to end oscap test, and push the updated scap content via puppet
         after first run.

        :id: 7eb75ca5-2ea1-434e-bb43-1223fa4d8e9f

        :expectedresults: Satellite should push updated content to Clients and
            satellite should get updated reports

        :CaseLevel: System

        :BZ: 1420439, 1722475
        """
        if settings.rhel7_repo is None:
            self.skipTest('Missing configuration for rhel7_repo')
        rhel7_repo = settings.rhel7_repo
        content_update = OSCAP_DEFAULT_CONTENT['rhel_firefox']
        hgrp7_name = gen_string('alpha')
        policy_values = {
            'content': self.rhel7_content,
            'hgrp': hgrp7_name,
            'policy': gen_string('alpha'),
            'profile': OSCAP_PROFILE['security7'],
        }
        vm_values = {
            'distro': DISTRO_RHEL7,
            'hgrp': hgrp7_name,
            'rhel_repo': rhel7_repo
        }
        Scapcontent.update({
            'title': content_update,
            'organizations': self.config_env['org_name']
        })
        # Creates host_group for rhel7
        make_hostgroup({
            'content-source-id': self.proxy_id,
            'name': hgrp7_name,
            'puppet-environment-id': self.puppet_env.id,
            'puppet-ca-proxy': self.config_env['sat6_hostname'],
            'puppet-proxy': self.config_env['sat6_hostname'],
            'organizations': self.config_env['org_name'],
        })
        # Creates oscap_policy for rhel7.
        scap_id, scap_profile_id = self.fetch_scap_and_profile_id(
            policy_values.get('content'), policy_values.get('profile'))
        make_scap_policy({
            'scap-content-id': scap_id,
            'deploy-by': 'puppet',
            'hostgroups': policy_values.get('hgrp'),
            'name': policy_values.get('policy'),
            'period': OSCAP_PERIOD['weekly'].lower(),
            'scap-content-profile-id': scap_profile_id,
            'weekday': OSCAP_WEEKDAY['friday'].lower(),
            'organizations': self.config_env['org_name'],
        })
        # Creates two vm's each for rhel6 and rhel7, runs
        # openscap scan and uploads report to satellite6.
        distro_os = vm_values.get('distro')
        with VirtualMachine(distro=distro_os) as vm:
            # host = vm.hostname
            host_name, _, host_domain = vm.hostname.partition('.')
            vm.install_katello_ca()
            vm.register_contenthost(self.config_env['org_name'],
                                    self.config_env['ak_name'].get(distro_os))
            self.assertTrue(vm.subscribed)
            vm.configure_puppet(vm_values.get('rhel_repo'))
            Host.update({
                'name': vm.hostname.lower(),
                'lifecycle-environment': self.config_env['env_name'],
                'content-view': self.config_env['cv_name'],
                'hostgroup': vm_values.get('hgrp'),
                'openscap-proxy-id': self.proxy_id,
                'organization': self.config_env['org_name'],
                'puppet-environment-id': self.puppet_env.id,
            })
            # Run "puppet agent -t" twice so that it detects it's,
            # satellite6 and fetch katello SSL certs.
            for _ in range(2):
                vm.run('puppet agent -t 2> /dev/null')
            result = vm.run(
                'cat /etc/foreman_scap_client/config.yaml | grep content_path')
            self.assertEqual(result.return_code, 0)
            # Runs the actual oscap scan on the vm/clients and
            # uploads report to Internal Capsule.
            vm.execute_foreman_scap_client()
            # Assert whether oscap reports are uploaded to
            # Satellite6.
            arf_report = Arfreport.list({
                'search':
                'host={0}'.format(vm.hostname.lower()),
                'per-page':
                1
            })
            self.assertIsNotNone(arf_report)
            scap_id, scap_profile_id = self.fetch_scap_and_profile_id(
                OSCAP_DEFAULT_CONTENT['rhel_firefox'],
                OSCAP_PROFILE['firefox'])
            Scappolicy.update({
                'scap-content-id': scap_id,
                'deploy-by': 'puppet',
                'name': policy_values.get('policy'),
                'new-name': gen_string('alpha'),
                'period': OSCAP_PERIOD['weekly'].lower(),
                'scap-content-profile-id': scap_profile_id,
                'weekday': OSCAP_WEEKDAY['friday'].lower(),
                'organizations': self.config_env['org_name'],
            })
            Arfreport.delete({'id': arf_report[0].get('id')})
            for _ in range(2):
                vm.run('puppet agent -t 2> /dev/null')
            updated_result = vm.run(
                'cat /etc/foreman_scap_client/config.yaml | grep content_path')
            self.assertIsNot(result, updated_result)
            self.assertEqual(updated_result.return_code, 0)
            # Runs the actual oscap scan on the vm/clients and
            # uploads report to Internal Capsule.
            vm.execute_foreman_scap_client()
            self.assertIsNotNone(
                Arfreport.list(
                    {'search': 'host={0}'.format(vm.hostname.lower())}))
Example #42
0
    def test_positive_end_to_end(self):
        """Perform end to end smoke tests using RH and custom repos.

        1. Create a new user with admin permissions
        2. Using the new user from above
            1. Create a new organization
            2. Clone and upload manifest
            3. Create a new lifecycle environment
            4. Create a custom product
            5. Create a custom YUM repository
            6. Create a custom PUPPET repository
            7. Enable a Red Hat repository
            8. Synchronize the three repositories
            9. Create a new content view
            10. Associate the YUM and Red Hat repositories to new content view
            11. Add a PUPPET module to new content view
            12. Publish content view
            13. Promote content view to the lifecycle environment
            14. Create a new activation key
            15. Add the products to the activation key
            16. Create a new libvirt compute resource
            17. Create a new subnet
            18. Create a new domain
            19. Create a new hostgroup and associate previous entities to it
            20. Provision a client

        :id: 8c8b3ffa-0d54-436b-8eeb-1a3542e100a8

        :expectedresults: All tests should succeed and Content should be
            successfully fetched by client.
        """
        # step 1: Create a new user with admin permissions
        password = gen_alphanumeric()
        user = make_user({'admin': 'true', 'password': password})
        user['password'] = password

        # step 2.1: Create a new organization
        org = self._create(user, Org, {'name': gen_alphanumeric()})

        # step 2.2: Clone and upload manifest
        if self.fake_manifest_is_set:
            with manifests.clone() as manifest:
                ssh.upload_file(manifest.content, manifest.filename)
            Subscription.upload({
                'file': manifest.filename,
                'organization-id': org['id']
            })

        # step 2.3: Create a new lifecycle environment
        lifecycle_environment = self._create(
            user,
            LifecycleEnvironment,
            {
                'name': gen_alphanumeric(),
                'organization-id': org['id'],
                'prior': 'Library'
            },
        )

        # step 2.4: Create a custom product
        product = self._create(user, Product, {
            'name': gen_alphanumeric(),
            'organization-id': org['id']
        })
        repositories = []

        # step 2.5: Create custom YUM repository
        yum_repo = self._create(
            user,
            Repository,
            {
                'content-type': 'yum',
                'name': gen_alphanumeric(),
                'product-id': product['id'],
                'publish-via-http': 'true',
                'url': CUSTOM_RPM_REPO,
            },
        )
        repositories.append(yum_repo)

        # step 2.6: Create custom PUPPET repository
        puppet_repo = self._create(
            user,
            Repository,
            {
                'content-type': 'puppet',
                'name': gen_alphanumeric(),
                'product-id': product['id'],
                'publish-via-http': 'true',
                'url': FAKE_0_PUPPET_REPO,
            },
        )
        repositories.append(puppet_repo)

        # step 2.7: Enable a Red Hat repository
        if self.fake_manifest_is_set:
            RepositorySet.enable({
                'basearch': 'x86_64',
                'name': REPOSET['rhva6'],
                'organization-id': org['id'],
                'product': PRDS['rhel'],
                'releasever': '6Server',
            })
            rhel_repo = Repository.info({
                'name': REPOS['rhva6']['name'],
                'organization-id': org['id'],
                'product': PRDS['rhel'],
            })
            repositories.append(rhel_repo)

        # step 2.8: Synchronize the three repositories
        for repo in repositories:
            Repository.with_user(user['login'], user['password']).synchronize(
                {'id': repo['id']})

        # step 2.9: Create content view
        content_view = self._create(user, ContentView, {
            'name': gen_alphanumeric(),
            'organization-id': org['id']
        })

        # step 2.10: Associate the YUM and Red Hat repositories to new content
        # view
        repositories.remove(puppet_repo)
        for repo in repositories:
            ContentView.add_repository({
                'id': content_view['id'],
                'organization-id': org['id'],
                'repository-id': repo['id'],
            })

        # step 2.11: Add a PUPPET module to new content view
        result = PuppetModule.with_user(user['login'], user['password']).list({
            'repository-id':
            puppet_repo['id'],
            'per-page':
            False
        })
        ContentView.with_user(user['login'],
                              user['password']).puppet_module_add({
                                  'content-view-id':
                                  content_view['id'],
                                  'id':
                                  random.choice(result)['id']
                              })

        # step 2.12: Publish content view
        ContentView.with_user(user['login'], user['password']).publish(
            {'id': content_view['id']})

        # step 2.13: Promote content view to the lifecycle environment
        content_view = ContentView.with_user(
            user['login'], user['password']).info({'id': content_view['id']})
        self.assertEqual(len(content_view['versions']), 1)
        cv_version = ContentView.with_user(
            user['login'], user['password']).version_info(
                {'id': content_view['versions'][0]['id']})
        self.assertEqual(len(cv_version['lifecycle-environments']), 1)
        ContentView.with_user(user['login'],
                              user['password']).version_promote({
                                  'id':
                                  cv_version['id'],
                                  'to-lifecycle-environment-id':
                                  lifecycle_environment['id']
                              })
        # check that content view exists in lifecycle
        content_view = ContentView.with_user(
            user['login'], user['password']).info({'id': content_view['id']})
        self.assertEqual(len(content_view['versions']), 1)
        cv_version = ContentView.with_user(
            user['login'], user['password']).version_info(
                {'id': content_view['versions'][0]['id']})
        self.assertEqual(len(cv_version['lifecycle-environments']), 2)
        self.assertEqual(cv_version['lifecycle-environments'][-1]['id'],
                         lifecycle_environment['id'])

        # step 2.14: Create a new activation key
        activation_key = self._create(
            user,
            ActivationKey,
            {
                'content-view-id': content_view['id'],
                'lifecycle-environment-id': lifecycle_environment['id'],
                'name': gen_alphanumeric(),
                'organization-id': org['id'],
            },
        )

        # step 2.15: Add the products to the activation key
        subscription_list = Subscription.with_user(
            user['login'],
            user['password']).list({'organization-id': org['id']},
                                   per_page=False)
        for subscription in subscription_list:
            if subscription['name'] == DEFAULT_SUBSCRIPTION_NAME:
                ActivationKey.with_user(user['login'],
                                        user['password']).add_subscription({
                                            'id':
                                            activation_key['id'],
                                            'quantity':
                                            1,
                                            'subscription-id':
                                            subscription['id'],
                                        })

        # step 2.15.1: Enable product content
        if self.fake_manifest_is_set:
            ActivationKey.with_user(user['login'],
                                    user['password']).content_override({
                                        'content-label':
                                        AK_CONTENT_LABEL,
                                        'id':
                                        activation_key['id'],
                                        'organization-id':
                                        org['id'],
                                        'value':
                                        '1',
                                    })

        # BONUS: Create a content host and associate it with promoted
        # content view and last lifecycle where it exists
        content_host_name = gen_alphanumeric()
        content_host = Host.with_user(user['login'],
                                      user['password']).subscription_register({
                                          'content-view-id':
                                          content_view['id'],
                                          'lifecycle-environment-id':
                                          lifecycle_environment['id'],
                                          'name':
                                          content_host_name,
                                          'organization-id':
                                          org['id'],
                                      })

        content_host = Host.with_user(user['login'], user['password']).info(
            {'id': content_host['id']})
        # check that content view matches what we passed
        self.assertEqual(
            content_host['content-information']['content-view']['name'],
            content_view['name'])
        # check that lifecycle environment matches
        self.assertEqual(
            content_host['content-information']['lifecycle-environment']
            ['name'],
            lifecycle_environment['name'],
        )

        # step 2.16: Create a new libvirt compute resource
        self._create(
            user,
            ComputeResource,
            {
                'name':
                gen_alphanumeric(),
                'provider':
                'Libvirt',
                'url':
                'qemu+ssh://root@{0}/system'.format(
                    settings.compute_resources.libvirt_hostname),
            },
        )

        # step 2.17: Create a new subnet
        subnet = self._create(
            user,
            Subnet,
            {
                'name': gen_alphanumeric(),
                'network': gen_ipaddr(ip3=True),
                'mask': '255.255.255.0',
            },
        )

        # step 2.18: Create a new domain
        domain = self._create(user, Domain, {'name': gen_alphanumeric()})

        # step 2.19: Create a new hostgroup and associate previous entities to
        # it
        host_group = self._create(
            user,
            HostGroup,
            {
                'domain-id': domain['id'],
                'name': gen_alphanumeric(),
                'subnet-id': subnet['id']
            },
        )
        HostGroup.with_user(user['login'], user['password']).update({
            'id':
            host_group['id'],
            'organization-ids':
            org['id'],
            'content-view-id':
            content_view['id'],
            'lifecycle-environment-id':
            lifecycle_environment['id'],
        })

        # step 2.20: Provision a client
        self.client_provisioning(activation_key['name'], org['label'])
Example #43
0
    def test_pre_create_virt_who_configuration(self, form_data):
        """Create and deploy virt-who configuration.

        :id: preupgrade-a36cbe89-47a2-422f-9881-0f86bea0e24e

        :steps: In Preupgrade Satellite, Create and deploy virt-who configuration.

        :expectedresults:
            1. Config can be created and deployed by command.
            2. No error msg in /var/log/rhsm/rhsm.log.
            3. Report is sent to satellite.
            4. Virtual sku can be generated and attached.
        """
        default_loc_id = entities.Location().search(query={'search': f'name="{DEFAULT_LOC}"'})[0].id
        default_loc = entities.Location(id=default_loc_id).read()
        org = entities.Organization(name=ORG_DATA['name']).create()
        default_loc.organization.append(entities.Organization(id=org.id))
        default_loc.update(['organization'])
        with manifests.clone() as manifest:
            upload_manifest(org.id, manifest.content)
        form_data.update({'organization_id': org.id})
        vhd = entities.VirtWhoConfig(**form_data).create()
        assert vhd.status == 'unknown'
        command = get_configure_command(vhd.id, org=org.name)
        hypervisor_name, guest_name = deploy_configure_by_command(
            command, form_data['hypervisor_type'], debug=True, org=org.label
        )
        virt_who_instance = (
            entities.VirtWhoConfig(organization_id=org.id)
            .search(query={'search': f'name={form_data["name"]}'})[0]
            .status
        )
        assert virt_who_instance == 'ok'
        hosts = [
            (hypervisor_name, f'product_id={settings.virtwho.sku.vdc_physical} and type=NORMAL'),
            (guest_name, f'product_id={settings.virtwho.sku.vdc_physical} and type=STACK_DERIVED'),
        ]
        for hostname, sku in hosts:
            host = Host.list({'search': hostname})[0]
            subscriptions = Subscription.list({'organization-id': org.id, 'search': sku})
            vdc_id = subscriptions[0]['id']
            if 'type=STACK_DERIVED' in sku:
                for item in subscriptions:
                    if hypervisor_name.lower() in item['type']:
                        vdc_id = item['id']
                        break
            entities.HostSubscription(host=host['id']).add_subscriptions(
                data={'subscriptions': [{'id': vdc_id, 'quantity': 1}]}
            )
            result = (
                entities.Host(organization=org.id).search(query={'search': hostname})[0].read_json()
            )
            assert result['subscription_status_label'] == 'Fully entitled'

        scenario_dict = {
            self.__class__.__name__: {
                'hypervisor_name': hypervisor_name,
                'guest_name': guest_name,
            }
        }
        create_dict(scenario_dict)
Example #44
0
def test_positive_upload_to_satellite(
    module_org,
    default_proxy,
    content_view,
    lifecycle_env,
    puppet_env,
    distro,
):
    """Perform end to end oscap test, and push the updated scap content via puppet
     after first run.

    :id: 11fef620-6ee8-4768-a398-db8cede1fc14

    :parametrized: yes

    :expectedresults: Oscap reports from rhel6, rhel7 and rhel8 clients should be
        uploaded to Satellite and be searchable. Satellite should push updated
        content to Clients and satellite should get updated reports.

    :CaseLevel: System

    :BZ: 1479413, 1722475, 1420439, 1722475
    """
    hgrp_name = gen_string('alpha')
    policy_name = gen_string('alpha')
    if distro == 'rhel6':
        rhel_repo = settings.rhel6_repo
        profile1 = OSCAP_PROFILE['dsrhel6']
        profile2 = OSCAP_PROFILE['pcidss6']
        profile3 = OSCAP_PROFILE['usgcb']
    elif distro == 'rhel7':
        rhel_repo = settings.rhel7_repo
        profile1 = OSCAP_PROFILE['dsrhel7']
        profile2 = OSCAP_PROFILE['pcidss7']
        profile3 = OSCAP_PROFILE['ospp7']
    else:
        rhel_repo = settings.rhel8_repo
        profile1 = OSCAP_PROFILE['dsrhel8']
        profile2 = OSCAP_PROFILE['pcidss8']
        profile3 = OSCAP_PROFILE['ospp8']
    content = OSCAP_DEFAULT_CONTENT[f'{distro}_content']
    # Creates host_group.
    make_hostgroup(
        {
            'content-source': settings.server.hostname,
            'name': hgrp_name,
            'puppet-environment-id': puppet_env.id,
            'puppet-ca-proxy': settings.server.hostname,
            'puppet-proxy': settings.server.hostname,
            'organizations': module_org.name,
            'puppet-classes': puppet_classes,
        }
    )
    # Creates oscap_policy.
    scap_id, scap_profile_id = fetch_scap_and_profile_id(content, profile1)
    make_scap_policy(
        {
            'scap-content-id': scap_id,
            'hostgroups': hgrp_name,
            'deploy-by': 'puppet',
            'name': policy_name,
            'period': OSCAP_PERIOD['weekly'].lower(),
            'scap-content-profile-id': scap_profile_id,
            'weekday': OSCAP_WEEKDAY['friday'].lower(),
            'organizations': module_org.name,
        }
    )
    # Creates vm's and runs openscap scan and uploads report to satellite6.
    with VMBroker(nick=distro, host_classes={'host': ContentHost}) as vm:
        host_name, _, host_domain = vm.hostname.partition('.')
        vm.install_katello_ca()
        vm.register_contenthost(module_org.name, ak_name[distro])
        assert vm.subscribed
        Host.update(
            {
                'name': vm.hostname.lower(),
                'lifecycle-environment': lifecycle_env.name,
                'content-view': content_view.name,
                'hostgroup': hgrp_name,
                'openscap-proxy-id': default_proxy,
                'organization': module_org.name,
                'puppet-environment-id': puppet_env.id,
            }
        )

        SmartClassParameter.update(
            {
                'name': 'fetch_remote_resources',
                'override': 1,
                'parameter-type': 'boolean',
                'default-value': 'true',
                'puppet-class': 'foreman_scap_client',
            }
        )
        SmartClassParameter.add_matcher(
            {
                'smart-class-parameter': 'fetch_remote_resources',
                'match': f'fqdn={vm.hostname}',
                'value': 'true',
                'puppet-class': 'foreman_scap_client',
            }
        )

        vm.configure_puppet(rhel_repo)
        result = vm.run('cat /etc/foreman_scap_client/config.yaml | grep profile')
        assert result.status == 0
        # Runs the actual oscap scan on the vm/clients and
        # uploads report to Internal Capsule.
        vm.execute_foreman_scap_client()
        # Assert whether oscap reports are uploaded to
        # Satellite6.
        arf_report = Arfreport.list({'search': f'host={vm.hostname.lower()}', 'per-page': 1})
        assert arf_report is not None
        for profile in [profile2, profile3]:
            scap_id, scap_profile_id = fetch_scap_and_profile_id(content, profile)
            Scappolicy.update(
                {
                    'scap-content-id': scap_id,
                    'deploy-by': 'puppet',
                    'name': policy_name,
                    'period': OSCAP_PERIOD['weekly'].lower(),
                    'scap-content-profile-id': scap_profile_id,
                    'weekday': OSCAP_WEEKDAY['friday'].lower(),
                    'organization': module_org.name,
                }
            )
            for _ in range(2):
                vm.run('puppet agent -t 2> /dev/null')
            updated_result = vm.run('cat /etc/foreman_scap_client/config.yaml | grep content_path')
            assert result != updated_result
            assert updated_result.status == 0
            # Runs the actual oscap scan on the vm/clients and
            # uploads report to Internal Capsule.
            vm.execute_foreman_scap_client()
            result = Arfreport.list({'search': f'host={vm.hostname.lower()}'})
            assert result is not None
    def test_positive_run_scheduled_job_template_by_ip(self):
        """Schedule a job to be ran against a host by ip

        :id: 4387bed9-969d-45fb-80c2-b0905bb7f1bd

        :Setup: Use pre-defined job template.

        :Steps:

            1. Set remote_execution_connect_by_ip on host to true
            2. Navigate to an individual host and click Run Job
            3. Select the job and appropriate template
            4. Select "Schedule Future Job"
            5. Enter a desired time for the job to run
            6. Click submit

        :expectedresults:

            1. Verify the job was not immediately ran
            2. Verify the job was successfully ran after the designated time

        :CaseLevel: System
        """
        with VirtualMachine(
              distro=DISTRO_RHEL7,
              provisioning_server=settings.compute_resources.libvirt_hostname,
              bridge=settings.vlan_networking.bridge,
              ) as client:
            client.install_katello_ca()
            client.register_contenthost(self.organization.label, lce='Library')
            self.assertTrue(client.subscribed)
            add_remote_execution_ssh_key(client.ip_addr)
            Host.update({
                'name': client.hostname,
                'subnet-id': self.new_sub.id,
            })
            # connect to host by ip
            Host.set_parameter({
                'host': client.hostname,
                'name': 'remote_execution_connect_by_ip',
                'value': 'True',
            })
            with Session(self) as session:
                set_context(session, org=self.organization.name)
                self.hosts.click(self.hosts.search(client.hostname))
                plan_time = (
                        self.get_client_datetime() + timedelta(seconds=180)
                        ).strftime("%Y-%m-%d %H:%M")
                status = self.job.run(
                    job_category='Commands',
                    job_template='Run Command - SSH Default',
                    options_list=[{'name': 'command', 'value': 'ls'}],
                    schedule='future',
                    schedule_options=[
                        {'name': 'start_at', 'value': plan_time}],
                    result='queued to start executing in 1 minute'
                )
                self.assertTrue(status)
                strategy, value = locators['job_invocation.status']
                self.job.wait_until_element_is_not_visible(
                    (strategy, value % 'queued'), 95)
                if self.job.wait_until_element(
                        (strategy, value % 'succeeded'), 180) is not None:
                    status2 = True
                else:
                    status2 = False
                # get job invocation id from the current url
                invocation_id = self.browser.current_url.rsplit('/', 1)[-1]
                try:
                    self.assertTrue(status2)
                except AssertionError:
                    result = 'host output: {0}'.format(
                            ' '.join(JobInvocation.get_output({
                                'id': invocation_id,
                                'host': client.hostname})
                            )
                        )
                    raise AssertionError(result)
Example #46
0
    def test_positive_provision_rhev_with_host_group(self):
        """Provision a host on RHEV compute resource with
        the help of hostgroup.

        :Requirement: Computeresource RHV

        :CaseComponent: ComputeResources-RHEV

        :id: ba78868f-5cff-462f-a55d-f6aa4d11db52

        :setup: Hostgroup and provisioning setup like domain, subnet etc.

        :steps:

            1. Create a RHEV compute resource.
            2. Create a host on RHEV compute resource using the Hostgroup
            3. Use compute-attributes parameter to specify key-value parameters
               regarding the virtual machine.
            4. Provision the host.

        :expectedresults: The host should be provisioned with host group

        :CaseAutomation: automated
        """
        name = gen_string('alpha')
        rhv_cr = ComputeResource.create(
            {
                'name': name,
                'provider': 'Ovirt',
                'user': self.rhev_username,
                'password': self.rhev_password,
                'datacenter': self.rhev_datacenter,
                'url': self.rhev_url,
                'ovirt-quota': self.quota,
                'organizations': self.org_name,
                'locations': self.loc_name,
            }
        )
        self.assertEquals(rhv_cr['name'], name)
        host_name = gen_string('alpha').lower()
        host = make_host(
            {
                'name': f'{host_name}',
                'root-password': gen_string('alpha'),
                'organization': self.org_name,
                'location': self.loc_name,
                'pxe-loader': 'PXELinux BIOS',
                'hostgroup': self.config_env['host_group'],
                'compute-resource-id': rhv_cr.get('id'),
                'compute-attributes': "cluster={},"
                "cores=1,"
                "memory=1073741824,"
                "start=1".format(self.cluster_id),
                'ip': None,
                'mac': None,
                'interface': f"compute_name=nic1, compute_network={self.network_id}",
                'volume': "size_gb=10,"
                "storage_domain={},"
                "bootable=True".format(self.storage_id),
                'provision-method': 'build',
            }
        )
        hostname = '{}.{}'.format(host_name, self.config_env['domain'])
        self.assertEquals(hostname, host['name'])
        host_info = Host.info({'name': hostname})
        host_ip = host_info.get('network').get('ipv4-address')
        # Check on RHV, if VM exists
        self.assertTrue(self.rhv_api.does_vm_exist(hostname))
        # Get the information of created VM
        rhv_vm = self.rhv_api.get_vm(hostname)
        # Assert of Satellite mac address for VM and Mac of VM created is same
        self.assertEqual(host_info.get('network').get('mac'), rhv_vm.get_nics()[0].mac.address)
        # Start to run a ping check if network was established on VM
        with self.assertNotRaises(ProvisioningCheckError):
            host_provisioning_check(ip_addr=host_ip)
Example #47
0
def test_positive_generate_hostpkgcompare(local_org, local_ak,
                                          local_content_view,
                                          local_environment):
    """Generate 'Host - compare content hosts packages' report

    :id: 572fb387-86f2-40e2-b2df-e8ec26433610


    :setup: Installed Satellite with Organization, Activation key,
            Content View, Content Host, Subscriptions, and synced fake repo.

    :steps:
        1. hammer report-template generate --name 'Host - compare content hosts package' ...

    :expectedresults: report is scheduled and generated containing all the expected information
                      regarding host packages

    :CaseImportance: Medium

    :BZ: 1860430
    """
    # Add subscription to Satellite Tools repo to activation key
    setup_org_for_a_rh_repo({
        'product': PRDS['rhel'],
        'repository-set': REPOSET['rhst7'],
        'repository': REPOS['rhst7']['name'],
        'organization-id': local_org['id'],
        'content-view-id': local_content_view['id'],
        'lifecycle-environment-id': local_environment['id'],
        'activationkey-id': local_ak['id'],
    })
    setup_org_for_a_custom_repo({
        'url':
        FAKE_6_YUM_REPO,
        'organization-id':
        local_org['id'],
        'content-view-id':
        local_content_view['id'],
        'lifecycle-environment-id':
        local_environment['id'],
        'activationkey-id':
        local_ak['id'],
    })

    hosts_info = []
    with VMBroker(nick='rhel7', host_classes={'host': ContentHost},
                  _count=2) as hosts:
        for client in hosts:
            # Create RHEL hosts via broker and register content host
            client.install_katello_ca()
            # Register content host, install katello-agent
            client.register_contenthost(local_org['label'], local_ak['name'])
            assert client.subscribed
            hosts_info.append(Host.info({'name': client.hostname}))
            client.enable_repo(REPOS['rhst7']['id'])
            client.install_katello_agent()
        hosts_info.sort(key=lambda host: host['name'])

        host1, host2 = hosts_info
        Host.package_install({
            'host-id': host1['id'],
            'packages': FAKE_0_CUSTOM_PACKAGE_NAME
        })
        Host.package_install({
            'host-id': host1['id'],
            'packages': FAKE_1_CUSTOM_PACKAGE
        })
        Host.package_install({
            'host-id': host2['id'],
            'packages': FAKE_2_CUSTOM_PACKAGE
        })

        result = ReportTemplate.generate({
            'name':
            'Host - compare content hosts packages',
            'inputs':
            f'Host 1 = {host1["name"]}, '
            f'Host 2 = {host2["name"]}',
        })
        result.remove('')

        assert len(result) > 1
        headers = f'Package,{host1["name"]},{host2["name"]},Architecture,Status'
        assert headers == result[0]
        items = [item.split(',') for item in result[1:]]
        assert len(items)
        for item in items:
            assert len(item) == 5
            name, host1version, host2version, arch, status = item
            assert len(name)
            assert ((host1version == '-' and name in host2version)
                    or (name in host1version and host2version == '-')
                    or (name in host1version and name in host2version))
            assert arch in [
                'x86_64', 'i686', 's390x', 'ppc64', 'ppc64le', 'noarch'
            ]
            assert status in (
                'same version',
                f'{host1["name"]} only',
                f'{host2["name"]} only',
                f'lower in {host1["name"]}',
                f'greater in {host1["name"]}',
            )
            # test for specific installed packages
            if name == FAKE_0_CUSTOM_PACKAGE_NAME:
                assert status == f'{host1["name"]} only'
            if name == FAKE_1_CUSTOM_PACKAGE_NAME:
                assert (status == f'lower in {host1["name"]}'
                        or status == f'greater in {host2["name"]}')
Example #48
0
    def test_positive_install_multiple_packages_with_a_job_by_ip(
            self, fixture_vmsetup, fixture_org):
        """Run job to install several packages on host by ip

        :id: 8b73033f-83c9-4024-83c3-5e442a79d320

        :expectedresults: Verify the packages were successfully installed
            on host

        :parametrized: yes
        """
        self.org = fixture_org
        self.client = fixture_vmsetup
        # set connecting to host by ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        packages = ["cow", "dog", "lion"]
        # Create a custom repo
        repo = entities.Repository(
            content_type='yum',
            product=entities.Product(organization=self.org).create(),
            url=FAKE_0_YUM_REPO,
        ).create()
        repo.sync()
        prod = repo.product.read()
        subs = entities.Subscription().search(
            query={'search': 'name={0}'.format(prod.name)})
        assert len(subs) > 0, 'No subscriptions matching the product returned'

        ak = entities.ActivationKey(
            organization=self.org,
            content_view=self.org.default_content_view,
            environment=self.org.library,
        ).create()
        ak.add_subscriptions(data={'subscriptions': [{'id': subs[0].id}]})
        self.client.register_contenthost(org=self.org.label,
                                         activation_key=ak.name)

        invocation_command = make_job_invocation({
            'job-template':
            'Install Package - Katello SSH Default',
            'inputs':
            'package={0} {1} {2}'.format(*packages),
            'search-query':
            "name ~ {0}".format(self.client.hostname),
        })
        try:
            assert invocation_command['success'] == '1'
        except AssertionError:
            result = 'host output: {0}'.format(' '.join(
                JobInvocation.get_output({
                    'id': invocation_command['id'],
                    'host': self.client.hostname
                })))
            raise AssertionError(result)
        result = ssh.command("rpm -q {0}".format(" ".join(packages)),
                             hostname=self.client.ip_addr)
        assert result.return_code == 0
Example #49
0
    def test_positive_run_job_effective_user_by_ip(self, fixture_vmsetup,
                                                   fixture_org):
        """Run default job template as effective user on a host by ip

        :id: 0cd75cab-f699-47e6-94d3-4477d2a94bb7

        :BZ: 1451675

        :expectedresults: Verify the job was successfully run under the
            effective user identity on host
        """
        self.org = fixture_org
        self.client = fixture_vmsetup
        # set connecting to host via ip
        Host.set_parameter({
            'host': self.client.hostname,
            'name': 'remote_execution_connect_by_ip',
            'value': 'True',
        })
        # create a user on client via remote job
        username = gen_string('alpha')
        filename = gen_string('alpha')
        make_user_job = make_job_invocation({
            'job-template':
            'Run Command - SSH Default',
            'inputs':
            "command='useradd -m {0}'".format(username),
            'search-query':
            "name ~ {0}".format(self.client.hostname),
        })
        try:
            assert make_user_job[u'success'] == u'1'
        except AssertionError:
            result = 'host output: {0}'.format(' '.join(
                JobInvocation.get_output({
                    'id': make_user_job[u'id'],
                    'host': self.client.hostname
                })))
            raise AssertionError(result)
        # create a file as new user
        invocation_command = make_job_invocation({
            'job-template':
            'Run Command - SSH Default',
            'inputs':
            "command='touch /home/{0}/{1}'".format(username, filename),
            'search-query':
            "name ~ {0}".format(self.client.hostname),
            'effective-user':
            '******'.format(username),
        })
        try:
            assert invocation_command['success'] == u'1'
        except AssertionError:
            result = 'host output: {0}'.format(' '.join(
                JobInvocation.get_output({
                    'id': invocation_command[u'id'],
                    'host': self.client.hostname
                })))
            raise AssertionError(result)
        # check the file owner
        result = ssh.command('''stat -c '%U' /home/{0}/{1}'''.format(
            username, filename),
                             hostname=self.client.ip_addr)
        # assert the file is owned by the effective user
        assert username == result.stdout[0]
Example #50
0
def test_positive_cli_end_to_end(fake_manifest_is_set, rhel6_contenthost,
                                 default_sat):
    """Perform end to end smoke tests using RH and custom repos.

    1. Create a new user with admin permissions
    2. Using the new user from above
        1. Create a new organization
        2. Clone and upload manifest
        3. Create a new lifecycle environment
        4. Create a custom product
        5. Create a custom YUM repository
        6. Enable a Red Hat repository
        7. Synchronize the three repositories
        8. Create a new content view
        9. Associate the YUM and Red Hat repositories to new content view
        10. Publish content view
        11. Promote content view to the lifecycle environment
        12. Create a new activation key
        13. Add the products to the activation key
        14. Create a new libvirt compute resource
        15. Create a new subnet
        16. Create a new domain
        17. Create a new hostgroup and associate previous entities to it
        18. Provision a client  ** NOT CURRENTLY PROVISIONING

    :id: 8c8b3ffa-0d54-436b-8eeb-1a3542e100a8

    :expectedresults: All tests should succeed and Content should be
        successfully fetched by client.
    """
    # step 1: Create a new user with admin permissions
    password = gen_alphanumeric()
    user = make_user({'admin': 'true', 'password': password})
    user['password'] = password

    # step 2.1: Create a new organization
    org = _create(user, Org, {'name': gen_alphanumeric()})

    # step 2.2: Clone and upload manifest
    if fake_manifest_is_set:
        with manifests.clone() as manifest:
            ssh.upload_file(manifest.content, manifest.filename)
        Subscription.upload({
            'file': manifest.filename,
            'organization-id': org['id']
        })

    # step 2.3: Create a new lifecycle environment
    lifecycle_environment = _create(
        user,
        LifecycleEnvironment,
        {
            'name': gen_alphanumeric(),
            'organization-id': org['id'],
            'prior': 'Library'
        },
    )

    # step 2.4: Create a custom product
    product = _create(user, Product, {
        'name': gen_alphanumeric(),
        'organization-id': org['id']
    })
    repositories = []

    # step 2.5: Create custom YUM repository
    yum_repo = _create(
        user,
        Repository,
        {
            'content-type': 'yum',
            'name': gen_alphanumeric(),
            'product-id': product['id'],
            'publish-via-http': 'true',
            'url': CUSTOM_RPM_REPO,
        },
    )
    repositories.append(yum_repo)

    # step 2.6: Enable a Red Hat repository
    if fake_manifest_is_set:
        RepositorySet.enable({
            'basearch': 'x86_64',
            'name': REPOSET['rhva6'],
            'organization-id': org['id'],
            'product': PRDS['rhel'],
            'releasever': '6Server',
        })
        rhel_repo = Repository.info({
            'name': REPOS['rhva6']['name'],
            'organization-id': org['id'],
            'product': PRDS['rhel'],
        })
        repositories.append(rhel_repo)

    # step 2.7: Synchronize the three repositories
    for repo in repositories:
        Repository.with_user(user['login'],
                             user['password']).synchronize({'id': repo['id']})

    # step 2.8: Create content view
    content_view = _create(user, ContentView, {
        'name': gen_alphanumeric(),
        'organization-id': org['id']
    })

    # step 2.9: Associate the YUM and Red Hat repositories to new content view
    for repo in repositories:
        ContentView.add_repository({
            'id': content_view['id'],
            'organization-id': org['id'],
            'repository-id': repo['id'],
        })

    # step 2.10: Publish content view
    ContentView.with_user(user['login'],
                          user['password']).publish({'id': content_view['id']})

    # step 2.11: Promote content view to the lifecycle environment
    content_view = ContentView.with_user(user['login'], user['password']).info(
        {'id': content_view['id']})
    assert len(content_view['versions']) == 1
    cv_version = ContentView.with_user(user['login'],
                                       user['password']).version_info({
                                           'id':
                                           content_view['versions'][0]['id']
                                       })
    assert len(cv_version['lifecycle-environments']) == 1
    ContentView.with_user(user['login'], user['password']).version_promote({
        'id':
        cv_version['id'],
        'to-lifecycle-environment-id':
        lifecycle_environment['id']
    })
    # check that content view exists in lifecycle
    content_view = ContentView.with_user(user['login'], user['password']).info(
        {'id': content_view['id']})
    assert len(content_view['versions']) == 1
    cv_version = ContentView.with_user(user['login'],
                                       user['password']).version_info({
                                           'id':
                                           content_view['versions'][0]['id']
                                       })
    assert len(cv_version['lifecycle-environments']) == 2
    assert cv_version['lifecycle-environments'][-1][
        'id'] == lifecycle_environment['id']

    # step 2.12: Create a new activation key
    activation_key = _create(
        user,
        ActivationKey,
        {
            'content-view-id': content_view['id'],
            'lifecycle-environment-id': lifecycle_environment['id'],
            'name': gen_alphanumeric(),
            'organization-id': org['id'],
        },
    )

    # step 2.13: Add the products to the activation key
    subscription_list = Subscription.with_user(
        user['login'], user['password']).list({'organization-id': org['id']},
                                              per_page=False)
    for subscription in subscription_list:
        if subscription['name'] == DEFAULT_SUBSCRIPTION_NAME:
            ActivationKey.with_user(user['login'],
                                    user['password']).add_subscription({
                                        'id':
                                        activation_key['id'],
                                        'quantity':
                                        1,
                                        'subscription-id':
                                        subscription['id'],
                                    })

    # step 2.13.1: Enable product content
    if fake_manifest_is_set:
        ActivationKey.with_user(user['login'],
                                user['password']).content_override({
                                    'content-label':
                                    AK_CONTENT_LABEL,
                                    'id':
                                    activation_key['id'],
                                    'organization-id':
                                    org['id'],
                                    'value':
                                    '1',
                                })

    # BONUS: Create a content host and associate it with promoted
    # content view and last lifecycle where it exists
    content_host_name = gen_alphanumeric()
    content_host = Host.with_user(user['login'],
                                  user['password']).subscription_register({
                                      'content-view-id':
                                      content_view['id'],
                                      'lifecycle-environment-id':
                                      lifecycle_environment['id'],
                                      'name':
                                      content_host_name,
                                      'organization-id':
                                      org['id'],
                                  })

    content_host = Host.with_user(user['login'], user['password']).info(
        {'id': content_host['id']})
    # check that content view matches what we passed
    assert content_host['content-information']['content-view'][
        'name'] == content_view['name']

    # check that lifecycle environment matches
    assert (content_host['content-information']['lifecycle-environment']
            ['name'] == lifecycle_environment['name'])

    # step 2.14: Create a new libvirt compute resource
    _create(
        user,
        ComputeResource,
        {
            'name': gen_alphanumeric(),
            'provider': 'Libvirt',
            'url':
            f'qemu+ssh://root@{settings.libvirt.libvirt_hostname}/system',
        },
    )

    # step 2.15: Create a new subnet
    subnet = _create(
        user,
        Subnet,
        {
            'name': gen_alphanumeric(),
            'network': gen_ipaddr(ip3=True),
            'mask': '255.255.255.0',
        },
    )

    # step 2.16: Create a new domain
    domain = _create(user, Domain, {'name': gen_alphanumeric()})

    # step 2.17: Create a new hostgroup and associate previous entities to it
    host_group = _create(
        user,
        HostGroup,
        {
            'domain-id': domain['id'],
            'name': gen_alphanumeric(),
            'subnet-id': subnet['id']
        },
    )
    HostGroup.with_user(user['login'], user['password']).update({
        'id':
        host_group['id'],
        'organization-ids':
        org['id'],
        'content-view-id':
        content_view['id'],
        'lifecycle-environment-id':
        lifecycle_environment['id'],
    })

    # step 2.18: Provision a client
    # TODO this isn't provisioning through satellite as intended
    # Note it wasn't well before the change that added this todo
    rhel6_contenthost.install_katello_ca(default_sat)
    # Register client with foreman server using act keys
    rhel6_contenthost.register_contenthost(org['label'],
                                           activation_key['name'])
    assert rhel6_contenthost.subscribed
    # Install rpm on client
    package_name = 'python-kitchen'
    result = rhel6_contenthost.execute(f'yum install -y {package_name}')
    assert result.status == 0
    # Verify that the package is installed by querying it
    result = rhel6_contenthost.run(f'rpm -q {package_name}')
    assert result.status == 0
Example #51
0
    def test_positive_provision_vmware_with_host_group(self):
        """Provision a host on vmware compute resource with
        the help of hostgroup.

        :Requirement: Computeresource Vmware

        :CaseComponent: ComputeResources-VMWare

        :id: ae4d5949-f0e6-44ca-93b6-c5241a02b64b

        :setup:

            1. Vaild vmware hostname ,credentials.
            2. Configure provisioning setup.
            3. Configure host group setup.

        :steps:

            1. Go to "Hosts --> New host".
            2. Assign the host group to the host.
            3. Select the Deploy on as vmware Compute Resource.
            4. Provision the host.

        :expectedresults: The host should be provisioned with host group

        :CaseAutomation: Automated

        :CaseLevel: System
        """
        cr_name = gen_string('alpha')
        vmware_cr = make_compute_resource(
            {
                'name': cr_name,
                'organizations': self.org_name,
                'locations': self.loc_name,
                'provider': FOREMAN_PROVIDERS['vmware'],
                'server': self.vmware_server,
                'user': self.vmware_username,
                'password': self.vmware_password,
                'datacenter': self.vmware_datacenter,
            }
        )
        self.assertEquals(vmware_cr['name'], cr_name)
        host_name = gen_string('alpha').lower()
        host = make_host(
            {
                'name': f'{host_name}',
                'root-password': gen_string('alpha'),
                'organization': self.org_name,
                'location': self.loc_name,
                'hostgroup': self.config_env['host_group'],
                'pxe-loader': 'PXELinux BIOS',
                'compute-resource-id': vmware_cr.get('id'),
                'compute-attributes': "cpus=2,"
                "corespersocket=2,"
                "memory_mb=4028,"
                "cluster={},"
                "path=/Datacenters/{}/vm/QE,"
                "guest_id=rhel7_64Guest,"
                "scsi_controller_type=VirtualLsiLogicController,"
                "hardware_version=Default,"
                "start=1".format(VMWARE_CONSTANTS['cluster'], self.vmware_datacenter),
                'ip': None,
                'mac': None,
                'interface': "compute_network={},"
                "compute_type=VirtualVmxnet3".format(self.vmware_net_id),
                'volume': "name=Hard disk,"
                "size_gb=10,"
                "thin=true,"
                "eager_zero=false,"
                "datastore={}".format(VMWARE_CONSTANTS['datastore'].split()[0]),
                'provision-method': 'build',
            }
        )
        hostname = '{}.{}'.format(host_name, self.config_env['domain'])
        self.assertEquals(hostname, host['name'])
        # Check on Vmware, if VM exists
        self.assertTrue(self.vmware_api.does_vm_exist(hostname))
        host_info = Host.info({'name': hostname})
        host_ip = host_info.get('network').get('ipv4-address')
        # Start to run a ping check if network was established on VM
        with self.assertNotRaises(ProvisioningCheckError):
            host_provisioning_check(ip_addr=host_ip)
Example #52
0
def test_positive_oscap_run_via_ansible(
    module_org, default_proxy, content_view, lifecycle_env, distro
):
    """End-to-End Oscap run via ansible

    :id: c7ea56eb-6cf1-4e79-8d6a-fb872d1bb804

    :parametrized: yes

    :setup: scap content, scap policy, host group

    :steps:

        1. Create a valid scap content
        2. Import Ansible role theforeman.foreman_scap_client
        3. Import Ansible Variables needed for the role
        4. Create a scap policy with anisble as deploy option
        5. Associate the policy with a hostgroup
        6. Provision a host using the hostgroup
        7. Configure REX and associate the Ansible role to created host
        8. Play roles for the host

    :expectedresults: REX job should be success and ARF report should be sent to satellite

    :BZ: 1716307

    :CaseImportance: Critical
    """
    if distro == 'rhel7':
        rhel_repo = settings.rhel7_repo
        profile = OSCAP_PROFILE['security7']
    else:
        rhel_repo = settings.rhel8_repo
        profile = OSCAP_PROFILE['ospp8']
    content = OSCAP_DEFAULT_CONTENT[f'{distro}_content']
    hgrp_name = gen_string('alpha')
    policy_name = gen_string('alpha')
    # Creates host_group for rhel7
    make_hostgroup(
        {
            'content-source-id': default_proxy,
            'name': hgrp_name,
            'organizations': module_org.name,
        }
    )
    # Creates oscap_policy.
    scap_id, scap_profile_id = fetch_scap_and_profile_id(content, profile)
    Ansible.roles_import({'proxy-id': default_proxy})
    Ansible.variables_import({'proxy-id': default_proxy})
    role_id = Ansible.roles_list({'search': 'foreman_scap_client'})[0].get('id')
    make_scap_policy(
        {
            'scap-content-id': scap_id,
            'hostgroups': hgrp_name,
            'deploy-by': 'ansible',
            'name': policy_name,
            'period': OSCAP_PERIOD['weekly'].lower(),
            'scap-content-profile-id': scap_profile_id,
            'weekday': OSCAP_WEEKDAY['friday'].lower(),
            'organizations': module_org.name,
        }
    )
    with VMBroker(nick=distro, host_classes={'host': ContentHost}) as vm:
        host_name, _, host_domain = vm.hostname.partition('.')
        vm.install_katello_ca()
        vm.register_contenthost(module_org.name, ak_name[distro])
        assert vm.subscribed
        Host.set_parameter(
            {
                'host': vm.hostname.lower(),
                'name': 'remote_execution_connect_by_ip',
                'value': 'True',
            }
        )
        vm.configure_rhel_repo(rhel_repo)
        add_remote_execution_ssh_key(vm.ip_addr)
        Host.update(
            {
                'name': vm.hostname.lower(),
                'lifecycle-environment': lifecycle_env.name,
                'content-view': content_view.name,
                'hostgroup': hgrp_name,
                'openscap-proxy-id': default_proxy,
                'organization': module_org.name,
                'ansible-role-ids': role_id,
            }
        )
        job_id = Host.ansible_roles_play({'name': vm.hostname.lower()})[0].get('id')
        wait_for_tasks(
            f'resource_type = JobInvocation and resource_id = {job_id} and action ~ "hosts job"'
        )
        try:
            result = JobInvocation.info({'id': job_id})['success']
            assert result == '1'
        except AssertionError:
            output = ' '.join(JobInvocation.get_output({'id': job_id, 'host': vm.hostname}))
            result = f'host output: {output}'
            raise AssertionError(result)
        result = vm.run('cat /etc/foreman_scap_client/config.yaml | grep profile')
        assert result.status == 0
        # Runs the actual oscap scan on the vm/clients and
        # uploads report to Internal Capsule.
        vm.execute_foreman_scap_client()
        # Assert whether oscap reports are uploaded to
        # Satellite6.
        result = Arfreport.list({'search': f'host={vm.hostname.lower()}'})
        assert result is not None
Example #53
0
    def test_positive_provision_pxe_host_with_parameters(self):
        """Provision the pxe-based BIOS discovered host with host parameters from cli using
        SYSLINUX loader

        :id: 4b315fe1-2eba-4e59-bd0a-9d16ce319ce2

        :Setup:
            1. Create a BIOS VM and set it to boot from a network

        :steps:
            1. Build a default PXE template
            2. Configure HostGroup to be used for provisioning the discovered host
               after discovery
            3. PXE Boot the VM (from Network)
            4. Wait for Host to be discovered by Satellite
            5. Provision the discovered host with host parameters

        :expectedresults:
            1. Ensure host appeared in Discovered Hosts on satellite
            2. Ensure the host is provisioned with correct and all the host parameters
               given during provisioning
            3. Ensure the discovered host is no more available to provision

        :CaseImportance: High

        :BZ: 1572947
        """
        param1_key, param1_value = gen_string('alpha'), gen_string(
            'alphanumeric')
        param2_key, param2_value = gen_string('alpha'), gen_string(
            'alphanumeric')
        host_params = [
            '{}={}, {}={}'.format(param1_key, param1_value, param2_key,
                                  param2_value)
        ]
        if not self.configured_env:
            self.__class__.configured_env = configure_env_for_provision(
                org=self.org, loc=self.loc)
        with LibvirtGuest() as pxe_host:
            hostname = pxe_host.guest_name
            discovered_host = self._assertdiscoveredhost(hostname)
            self.assertIsNotNone(discovered_host)
            DiscoveredHost.provision({
                'name':
                discovered_host['name'],
                'hostgroup':
                self.configured_env['hostgroup']['name'],
                'root-password':
                gen_string('alphanumeric'),
                'parameters':
                host_params,
            })
            provisioned_host = Host.info({
                'name':
                '{}.{}'.format(discovered_host['name'],
                               self.configured_env['domain']['name'])
            })
            self.assertEqual(
                provisioned_host['parameters'][str(param1_key).lower()],
                param1_value)
            self.assertEqual(
                provisioned_host['parameters'][str(param2_key).lower()],
                param2_value)
            with self.assertRaises(CLIReturnCodeError):
                DiscoveredHost.info({'id': discovered_host['id']})
Example #54
0
 def tearDown(self):
     """Delete the host to free the resources"""
     super().tearDown()
     hosts = Host.list({'organization': self.org_name})
     for host in hosts:
         Host.delete({'id': host['id']})
def test_positive_provision_vmware_with_host_group_bootdisk(
        vmware, provisioning, tear_down, vmware_cr):
    """Provision a bootdisk based host on VMWare compute resource.

    :Requirement: Computeresource Vmware

    :CaseComponent: ComputeResources-VMWare

    :id: bc5f457d-c29a-4c62-bbdc-af8f4f813519

    :bz: 1679225

    :setup:

        1. Vaild VMWare hostname, credentials.
        2. Configure provisioning setup.
        3. Configure host group setup.

    :steps: Using Hammer CLI, Provision a VM on VMWare with hostgroup and
        provisioning method as `bootdisk`.

    :expectedresults: The host should be provisioned with provisioning type bootdisk

    :CaseAutomation: Automated

    :CaseLevel: System
    """
    host_name = gen_string('alpha').lower()
    host = make_host({
        'name':
        f'{host_name}',
        'root-password':
        gen_string('alpha'),
        'organization':
        provisioning.org_name,
        'location':
        provisioning.loc_name,
        'hostgroup':
        provisioning.config_env['host_group'],
        'pxe-loader':
        'PXELinux BIOS',
        'compute-resource-id':
        vmware_cr.get('id'),
        'content-source-id':
        '1',
        'compute-attributes':
        "cpus=2,"
        "corespersocket=2,"
        "memory_mb=4028,"
        "cluster={},"
        "path=/Datacenters/{}/vm/QE,"
        "guest_id=rhel7_64Guest,"
        "scsi_controllers=`type=VirtualLsiLogicController,key=1000',"
        "hardware_version=Default,"
        "start=1".format(VMWARE_CONSTANTS['cluster'],
                         vmware.vmware_datacenter),
        "ip":
        None,
        "mac":
        None,
        'interface':
        "compute_network={},"
        "compute_type=VirtualVmxnet3".format(vmware.vmware_net_id),
        'volume':
        "name=Hard disk,"
        "size_gb=10,"
        "thin=true,"
        "eager_zero=false,"
        "datastore={}".format(VMWARE_CONSTANTS['datastore'].split()[0]),
        'provision-method':
        'bootdisk',
    })
    hostname = '{}.{}'.format(host_name, provisioning.config_env['domain'])
    assert hostname == host['name']
    # Check on Vmware, if VM exists
    assert vmware.vmware_api.does_vm_exist(hostname)
    host_info = Host.info({'name': hostname})
    host_ip = host_info.get('network').get('ipv4-address')
    # Start to run a ping check if network was established on VM
    host_provisioning_check(ip_addr=host_ip)
Example #56
0
    def test_positive_provision_pxe_host_with_bios_syslinux(self):
        """Provision the pxe-based BIOS discovered host from cli using SYSLINUX
        loader

        :id: b5385fe3-d532-4373-af64-5492275ff8d4

        :Setup:
            1. Create a BIOS VM and set it to boot from a network
            2. for getting more detailed info from FDI, remaster the image to
               have ssh enabled

        :steps:
            1. Build a default PXE template
            2. Run assertion step #1
            3. Boot the VM (from NW)
            4. Run assertion steps #2-4
            5. Provision the discovered host
            6. Run assertion steps #5-9

        :expectedresults: Host should be provisioned successfully
            1. [TBD] Ensure the tftpboot files are updated

              1.1 Ensure fdi-image files have been placed under tftpboot/boot/
              1.2 Ensure the 'default' pxelinux config has been placed under
              tftpboot/pxelinux.cfg/
              1.3 Ensure the discovery section exists inside pxelinux config,
              it leads to the FDI kernel and the ONTIMEOUT is set to discovery

            2. [TBD] Ensure PXE handoff goes as expected (tcpdump -p tftp)
            3. [TBD] Ensure FDI loaded and successfully sent out facts

                3.1 ping vm
                3.2 ssh to the VM and read the logs (if ssh enabled)
                3.3 optionally sniff the HTTP traffic coming from the host

            4. Ensure host appeared in Discovered Hosts on satellite
            5. [TBD] Ensure the tftpboot files are updated for the hosts mac
            6. [TBD] Ensure PXE handoff goes as expected (tcpdump -p tftp)
            7. [TBD] Optionally ensure anaconda loaded and the installation
               finished
            8. [TBD] Ensure the host is provisioned with correct attributes
            9. Ensure the entry from discovered host list disappeared

        :CaseLevel: System
        """
        # fixme: assertion #1
        if not self.configured_env:
            self.__class__.configured_env = configure_env_for_provision(
                org=self.org, loc=self.loc)
        with LibvirtGuest() as pxe_host:
            hostname = pxe_host.guest_name
            # fixme: assertion #2-3
            # assertion #4
            discovered_host = self._assertdiscoveredhost(hostname)
            self.assertIsNotNone(discovered_host)
            # Provision just discovered host
            DiscoveredHost.provision({
                'name':
                discovered_host['name'],
                'hostgroup':
                self.configured_env['hostgroup']['name'],
                'root-password':
                gen_string('alphanumeric'),
            })
            # fixme: assertion #5-8
            provisioned_host = Host.info({
                'name':
                '{0}.{1}'.format(discovered_host['name'],
                                 self.configured_env['domain']['name'])
            })
            # assertion #8
            self.assertEqual(provisioned_host['network']['subnet'],
                             self.configured_env['subnet']['name'])
            self.assertEqual(
                provisioned_host['operating-system']['partition-table'],
                self.configured_env['ptable']['name'])
            self.assertEqual(
                provisioned_host['operating-system']['operating-system'],
                self.configured_env['os']['title'])
            # assertion #9
            with self.assertRaises(CLIReturnCodeError):
                DiscoveredHost.info({'id': discovered_host['id']})
Example #57
0
def test_positive_configure_cloud_connector(session, default_sat,
                                            subscribe_satellite,
                                            fixture_enable_receptor_repos):
    """Install Cloud Connector through WebUI button

    :id: 67e45cfe-31bb-51a8-b88f-27918c68f32e

    :Steps:

        1. Navigate to Configure > Inventory Upload
        2. Click Configure Cloud Connector
        3. Open the started job and wait until it is finished

    :expectedresults: The Cloud Connector has been installed and the service is running

    :CaseLevel: Integration

    :CaseComponent: RHCloud-CloudConnector

    :CaseImportance: Medium

    :assignee: lhellebr

    :BZ: 1818076
    """
    # Copy foreman-proxy user's key to root@localhost user's authorized_keys
    default_sat.add_rex_key(satellite=default_sat)

    # Set Host parameter source_display_name to something random.
    # To avoid 'name has already been taken' error when run multiple times
    # on a machine with the same hostname.
    host_id = Host.info({'name': default_sat.hostname})['id']
    Host.set_parameter({
        'host-id': host_id,
        'name': 'source_display_name',
        'value': gen_string('alpha')
    })

    with session:
        if session.cloudinventory.is_cloud_connector_configured():
            pytest.skip(
                'Cloud Connector has already been configured on this system. '
                'It is possible to reconfigure it but then the test would not really '
                'check if everything is correctly configured from scratch. Skipping.'
            )
        session.cloudinventory.configure_cloud_connector()

    template_name = 'Configure Cloud Connector'
    invocation_id = (entities.JobInvocation().search(
        query={'search': f'description="{template_name}"'})[0].id)
    wait_for(
        lambda: entities.JobInvocation(id=invocation_id).read().status_label in
        ["succeeded", "failed"],
        timeout="1500s",
    )

    result = JobInvocation.get_output({
        'id': invocation_id,
        'host': default_sat.hostname
    })
    logger.debug(f"Invocation output>>\n{result}\n<<End of invocation output")
    # if installation fails, it's often due to missing rhscl repo -> print enabled repos
    repolist = default_sat.execute('yum repolist')
    logger.debug(f"Repolist>>\n{repolist}\n<<End of repolist")

    assert entities.JobInvocation(id=invocation_id).read().status == 0
    assert 'project-receptor.satellite_receptor_installer' in result
    assert 'Exit status: 0' in result
    # check that there is one receptor conf file and it's only readable
    # by the receptor user and root
    result = default_sat.execute(
        'stat /etc/receptor/*/receptor.conf --format "%a:%U"')
    assert all(filestats == '400:foreman-proxy'
               for filestats in result.stdout.strip().split('\n'))
    result = default_sat.execute('ls -l /etc/receptor/*/receptor.conf | wc -l')
    assert int(result.stdout.strip()) >= 1
    def test_positive_run_custom_job_template_by_ip(self):
        """Run a job template on a host connected by ip

        :id: e283ae09-8b14-4ce1-9a76-c1bbd511d58c

        :Setup: Create a working job template.

        :Steps:

            1. Set remote_execution_connect_by_ip on host to true
            2. Navigate to an individual host and click Run Job
            3. Select the job and appropriate template
            4. Run the job

        :expectedresults: Verify the job was successfully ran against the host

        :CaseLevel: System
        """
        jobs_template_name = gen_string('alpha')
        with VirtualMachine(
              distro=DISTRO_RHEL7,
              provisioning_server=settings.compute_resources.libvirt_hostname,
              bridge=settings.vlan_networking.bridge,
              ) as client:
            client.install_katello_ca()
            client.register_contenthost(self.organization.label, lce='Library')
            self.assertTrue(client.subscribed)
            add_remote_execution_ssh_key(client.ip_addr)
            Host.update({
                'name': client.hostname,
                'subnet-id': self.new_sub.id,
            })
            # connect to host by ip
            Host.set_parameter({
                'host': client.hostname,
                'name': 'remote_execution_connect_by_ip',
                'value': 'True',
            })
            with Session(self) as session:
                set_context(session, org=self.organization.name)
                make_job_template(
                    session,
                    name=jobs_template_name,
                    template_type='input',
                    template_content='<%= input("command") %>',
                    provider_type='SSH',
                )
                self.assertIsNotNone(
                    self.jobtemplate.search(jobs_template_name))
                self.jobtemplate.add_input(
                    jobs_template_name, 'command', required=True)
                self.hosts.click(self.hosts.search(client.hostname))
                status = self.job.run(
                    job_category='Miscellaneous',
                    job_template=jobs_template_name,
                    options_list=[{'name': 'command', 'value': 'ls'}]
                )
                # get job invocation id from the current url
                invocation_id = self.browser.current_url.rsplit('/', 1)[-1]
                try:
                    self.assertTrue(status)
                except AssertionError:
                    result = 'host output: {0}'.format(
                            ' '.join(JobInvocation.get_output({
                                'id': invocation_id,
                                'host': client.hostname})
                            )
                        )
                    raise AssertionError(result)
Example #59
0
    def test_positive_generate_hostpkgcompare(self):
        """Generate 'Host - compare content hosts packages' report

        :id: 572fb387-86f2-40e2-b2df-e8ec26433610


        :setup: Installed Satellite with Organization, Activation key,
                Content View, Content Host, Subscriptions, and synced fake repo.

        :steps:
            1. hammer report-template generate --name 'Host - compare content hosts package' ...

        :expectedresults: report is scheduled and generated containing all the expected information
                          regarding host packages

        :CaseImportance: Medium

        :BZ: 1860430
        """
        # Add subscription to Satellite Tools repo to activation key
        setup_org_for_a_rh_repo(
            {
                'product': PRDS['rhel'],
                'repository-set': REPOSET['rhst7'],
                'repository': REPOS['rhst7']['name'],
                'organization-id': self.setup_org['id'],
                'content-view-id': self.setup_content_view['id'],
                'lifecycle-environment-id': self.setup_env['id'],
                'activationkey-id': self.setup_new_ak['id'],
            }
        )

        hosts = []
        for i in [0, 1]:
            # Create VM and register content host
            client = VirtualMachine(distro=DISTRO_RHEL7)
            client.create()
            self.addCleanup(vm_cleanup, client)
            client.install_katello_ca()
            # Register content host, install katello-agent
            client.register_contenthost(self.setup_org['label'], self.setup_new_ak['name'])
            self.assertTrue(client.subscribed)
            hosts.append(Host.info({'name': client.hostname}))
            client.enable_repo(REPOS['rhst7']['id'])
            client.install_katello_agent()
        hosts.sort(key=lambda host: host['name'])

        host1, host2 = hosts
        Host.package_install({'host-id': host1['id'], 'packages': FAKE_0_CUSTOM_PACKAGE_NAME})
        Host.package_install({'host-id': host1['id'], 'packages': FAKE_1_CUSTOM_PACKAGE})
        Host.package_install({'host-id': host2['id'], 'packages': FAKE_2_CUSTOM_PACKAGE})

        result = ReportTemplate.generate(
            {
                'name': 'Host - compare content hosts packages',
                'inputs': f"Host 1 = {host1['name']}, " f"Host 2 = {host2['name']}",
            }
        )
        result.remove('')

        self.assertGreater(len(result), 1)
        headers = f'Package,{host1["name"]},{host2["name"]},Architecture,Status'
        self.assertEqual(headers, result[0])
        items = [item.split(',') for item in result[1:]]
        self.assertGreater(len(items), 0)
        for item in items:
            self.assertEqual(len(item), 5)
            name, host1version, host2version, arch, status = item
            self.assertGreater(len(name), 0)
            assert (
                (host1version == '-' and name in host2version)
                or (name in host1version and host2version == '-')
                or (name in host1version and name in host2version)
            )
            self.assertIn(arch, ['x86_64', 'i686', 's390x', 'ppc64', 'ppc64le', 'noarch'])
            assert status in (
                'same version',
                f'{host1["name"]} only',
                f'{host2["name"]} only',
                f'lower in {host1["name"]}',
                f'greater in {host1["name"]}',
            )
            # test for specific installed packages
            if name == FAKE_0_CUSTOM_PACKAGE_NAME:
                assert status == f'{host1["name"]} only'
            if name == FAKE_1_CUSTOM_PACKAGE_NAME:
                assert (
                    status == f'lower in {host1["name"]}'
                    or status == f'greater in {host2["name"]}'
                )
Example #60
0
    def test_positive_provision_pxeless_bios_syslinux(self):
        """Provision and discover the pxe-less BIOS host from cli using SYSLINUX
        loader

        :id: ae7f3ce2-e66e-44dc-85cb-0c3c4782cbb1

        :Setup:
            1. Craft the FDI with remaster the image to have ssh enabled

        :Steps:
            1. Create a BIOS VM and set it to boot from the FDI
            2. Run assertion steps #1-2
            3. Provision the discovered host using PXELinux loader
            4. Run assertion steps #3-7

        :expectedresults: Host should be provisioned successfully
            1. [TBD] Ensure FDI loaded and successfully sent out facts

               1.1 ping vm
               1.2 ssh to the VM and read the logs (if ssh enabled)
               1.3 optionally sniff the HTTP traffic coming from the host

            2. Ensure host appeared in Discovered Hosts on satellite
            3. [TBD] Ensure the kexec was successful (e.g. the kexec request
               result in production.log)
            4. [TBD] Ensure anaconda loaded and the installation finished
            5. [TBD] Ensure the host is provisioned with correct attributes
            6. Ensure the host is created in Hosts
            7. Ensure the entry from discovered host list disappeared

        :CaseLevel: System
        """
        if not self.configured_env:
            self.__class__.configured_env = configure_env_for_provision(
                org=self.org, loc=self.loc)
        with LibvirtGuest(boot_iso=True) as pxe_host:
            hostname = pxe_host.guest_name
            # fixme: assertion #1
            discovered_host = self._assertdiscoveredhost(hostname)
            self.assertIsNotNone(discovered_host)
            # Provision just discovered host
            DiscoveredHost.provision({
                'name':
                discovered_host['name'],
                'hostgroup':
                self.configured_env['hostgroup']['name'],
                'root-password':
                gen_string('alphanumeric'),
            })
            # fixme: assertion #2-5
            provisioned_host = Host.info({
                'name':
                '{0}.{1}'.format(discovered_host['name'],
                                 self.configured_env['domain']['name'])
            })
            self.assertEqual(provisioned_host['network']['subnet'],
                             self.configured_env['subnet']['name'])
            self.assertEqual(
                provisioned_host['operating-system']['partition-table'],
                self.configured_env['ptable']['name'])
            self.assertEqual(
                provisioned_host['operating-system']['operating-system'],
                self.configured_env['os']['title'])
            # Check that provisioned host is not in the list of discovered
            # hosts anymore
            with self.assertRaises(CLIReturnCodeError):
                DiscoveredHost.info({'id': discovered_host['id']})