Example #1
0
    def test_delete_with_scans(self):
        """Delete a Source used by a scan."""
        cred = Credential(name='cred2', username='******',
                          password='******')
        cred.save()
        source = Source(name='cred_source',
                        source_type=Source.NETWORK_SOURCE_TYPE,
                        hosts=['1.2.3.4'])
        source.save()
        source.credentials.add(cred)
        source.save()

        scan = Scan(name='test_scan',
                    scan_type=ScanTask.SCAN_TYPE_CONNECT)
        scan.save()
        scan.sources.add(source)

        url = reverse('source-detail', args=(source.id,))
        response = self.client.delete(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        response_json = response.json()
        self.assertEqual(
            response_json['detail'],
            messages.SOURCE_DELETE_NOT_VALID_W_SCANS)
        self.assertEqual(response_json['scans'][0]['name'], 'test_scan')
Example #2
0
 def test_hostcred_delete_view(self):
     """Tests the delete view set of the Credential API."""
     cred = Credential(name='cred2', username='******', password='******')
     cred.save()
     url = reverse('cred-detail', args=(cred.pk, ))
     resp = self.client.delete(url, format='json')
     self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT)
Example #3
0
class SatelliteFactoryTest(TestCase):
    """Tests Satellite factory functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               cred_type=Credential.SATELLITE_CRED_TYPE,
                               username='******',
                               password='******',
                               become_password=None,
                               become_method=None,
                               become_user=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=443, hosts='["1.2.3.4"]')
        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, scan_type=ScanTask.SCAN_TYPE_CONNECT)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_create_sat_none(self):
        """Test the method to fail to create a Sat interface."""
        satellite_version = None
        api_version = 1
        api = create(satellite_version, api_version, self.scan_task)
        self.assertEqual(api, None)

    def test_create_sat5(self):
        """Test the method to create a Sat 5 interface."""
        satellite_version = SATELLITE_VERSION_5
        api_version = 1
        api = create(satellite_version, api_version, self.scan_task)
        self.assertEqual(api.__class__, SatelliteFive)

    def test_create_sat6_v1(self):
        """Test the method to create a Sat 6 interface."""
        satellite_version = SATELLITE_VERSION_6
        api_version = 1
        api = create(satellite_version, api_version, self.scan_task)
        self.assertEqual(api.__class__, SatelliteSixV1)

    def test_create_sat6_v2(self):
        """Test the method to create a Sat 6 interface."""
        satellite_version = SATELLITE_VERSION_6
        api_version = 2
        api = create(satellite_version, api_version, self.scan_task)
        self.assertEqual(api.__class__, SatelliteSixV2)

    def test_create_sat6_unknown(self):
        """Test the method to create a Sat 6 interface."""
        satellite_version = SATELLITE_VERSION_6
        api_version = 9
        api = create(satellite_version, api_version, self.scan_task)
        self.assertEqual(api, None)
Example #4
0
class VCenterUtilsTest(TestCase):
    """Tests VCenter utils functions."""

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(
            name='cred1',
            username='******',
            password='******',
            become_password=None,
            ssh_keyfile=None)
        self.cred.save()

        options = SourceOptions(disable_ssl=True)
        options.save()

        self.source = Source(
            name='source1',
            port=22,
            hosts='["1.2.3.4"]')
        self.source.options = options
        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_INSPECT,
                                  source=self.source, sequence_number=2)
        self.scan_task.save()

        self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        self.scan_job.save()
        self.scan_job.tasks.add(self.scan_task)
        self.conn_results = JobConnectionResult()
        self.conn_results.save()
        self.scan_job.connection_results = self.conn_results
        self.scan_job.save()

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_vcenter_connect(self):
        """Test the connection method."""
        mock_vcenter = Mock()
        with patch('scanner.vcenter.utils.SmartConnectNoSSL',
                   return_value=mock_vcenter) as mock_smart_connect:
            vcenter = vcenter_connect(self.scan_task)
            self.assertEqual(mock_vcenter, vcenter)
            mock_smart_connect.assert_called_once_with(
                host=ANY, user=ANY, pwd=ANY, port=ANY)
Example #5
0
    def test_cred_delete_with_source(self):
        """Tests delete when cred used by source."""
        cred = Credential(name='cred2', username='******', password='******')
        cred.save()
        source = Source(name='cred_source',
                        source_type=Source.NETWORK_SOURCE_TYPE,
                        hosts=['1.2.3.4'])
        source.save()
        source.credentials.add(cred)
        source.save()

        url = reverse('cred-detail', args=(cred.pk, ))
        resp = self.client.delete(url, format='json')
        self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
        response_json = resp.json()
        self.assertEqual(response_json['detail'],
                         messages.CRED_DELETE_NOT_VALID_W_SOURCES)
        self.assertEqual(response_json['sources'][0]['name'], 'cred_source')
    def setUp(self):
        """Create test case setup."""
        cred = Credential(name='cred1',
                          username='******',
                          password='******',
                          become_password=None,
                          ssh_keyfile=None)
        cred.save()

        source = Source(name='source1', port=22, hosts='["1.2.3.4"]')

        source.save()
        source.credentials.add(cred)

        self.scan_job, self.scan_task = create_scan_job(
            source, ScanTask.SCAN_TYPE_INSPECT)

        self.connect_scan_task = self.scan_task.prerequisites.first()
        self.connect_scan_task.update_stats('TEST_VC.', sys_count=5)
        self.connect_scan_task.complete()

        # Create task runner
        self.runner = InspectTaskRunner(scan_job=self.scan_job,
                                        scan_task=self.scan_task)
Example #7
0
class NetworkInspectScannerTest(TestCase):
    """Tests network inspect scan task class."""

    # pylint: disable=too-many-instance-attributes, protected-access
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               ssh_keyfile=None,
                               become_method=None,
                               become_user=None,
                               become_password=None)
        self.cred.save()

        hc_serializer = CredentialSerializer(self.cred)
        self.cred_data = hc_serializer.data

        self.source = Source(name='source1', port=22, hosts='["1.2.3.4"]')
        self.source.save()
        self.source.credentials.add(self.cred)

        self.host_list = [('1.2.3.4', self.cred_data)]

        # setup scan options

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_INSPECT)

        self.connect_scan_task = self.scan_task.prerequisites.first()
        self.connect_scan_task.update_stats('TEST NETWORK CONNECT.',
                                            sys_failed=0)

        success_sys = SystemConnectionResult(
            name='1.2.3.4',
            credential=self.cred,
            status=SystemConnectionResult.SUCCESS)
        success_sys.save()
        failed_sys = SystemConnectionResult(
            name='1.1.1.2', status=SystemConnectionResult.FAILED)
        failed_sys.save()
        conn_result = self.connect_scan_task.connection_result
        conn_result.systems.add(success_sys)
        conn_result.systems.add(failed_sys)
        conn_result.save()

        self.connect_scan_task.update_stats('TEST_VC.',
                                            sys_count=2,
                                            sys_failed=1,
                                            sys_scanned=1)
        self.connect_scan_task.complete()

        self.scan_task.update_stats('TEST NETWORK INSPECT.', sys_failed=0)

        self.fact_endpoint = 'http://testserver' + reverse('facts-list')

        self.scan_job.save()

        scan_data_log.disable_log_for_test()

    def test_scan_inventory(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        connection_port = source['port']
        inventory_dict = _construct_scan_inventory(self.host_list,
                                                   connection_port, 50)
        expected = {
            'all': {
                'children': {
                    'group_0': {
                        'hosts': {
                            '1.2.3.4': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.4'
                            }
                        }
                    }
                },
                'vars': {
                    'ansible_port': 22
                }
            }
        }

        self.assertEqual(inventory_dict[1], expected)

    def test_scan_inventory_grouping(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        inventory_dict = _construct_scan_inventory([('1.2.3.1', cred),
                                                    ('1.2.3.2', cred),
                                                    ('1.2.3.3', cred),
                                                    ('1.2.3.4', cred)],
                                                   connection_port, 1)
        expected = {
            'all': {
                'children': {
                    'group_0': {
                        'hosts': {
                            '1.2.3.1': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.1'
                            }
                        }
                    },
                    'group_1': {
                        'hosts': {
                            '1.2.3.2': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.2'
                            }
                        }
                    },
                    'group_2': {
                        'hosts': {
                            '1.2.3.3': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.3'
                            }
                        }
                    },
                    'group_3': {
                        'hosts': {
                            '1.2.3.4': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.4'
                            }
                        }
                    }
                },
                'vars': {
                    'ansible_port': 22
                }
            }
        }

        self.assertEqual(inventory_dict[1], expected)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_failed)
    def test_inspect_scan_failure(self, mock_run):
        """Test scan flow with mocked manager and failure."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)

        # Init for unit test as run is not called
        scanner.connect_scan_task = self.connect_scan_task
        with self.assertRaises(AnsibleError):
            scanner._inspect_scan(self.host_list)
            mock_run.assert_called()

    @patch('scanner.network.inspect.InspectTaskRunner._inspect_scan',
           side_effect=mock_scan_error)
    def test_inspect_scan_error(self, mock_scan):
        """Test scan flow with mocked manager and failure."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        scan_task_status = scanner.run()
        mock_scan.assert_called_with(self.host_list)
        self.assertEqual(scan_task_status[1], ScanTask.FAILED)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_success)
    def test_inspect_scan_fail_no_facts(self, mock_run):
        """Test running a inspect scan with mocked connection."""
        expected = ([('1.2.3.4', {'name': 'cred1'})], [])
        mock_run.return_value = expected
        with requests_mock.Mocker() as mocker:
            mocker.post(self.fact_endpoint, status_code=201, json={'id': 1})
            scanner = InspectTaskRunner(self.scan_job, self.scan_task)
            scan_task_status = scanner.run()
            mock_run.assert_called_with(ANY)
            self.assertEqual(scan_task_status[1], ScanTask.FAILED)

    def test_populate_callback(self):
        """Test the population of the callback object for inspect scan."""
        callback = InspectResultCallback(scan_task=self.scan_task)
        host = Mock()
        host.name = '1.2.3.4'
        task = Mock(args={'_raw_params': 'command line'})
        result = Mock(_host=host, _result={'rc': 3}, _task=task)

        callback.v2_runner_on_unreachable(result)

    def test_ssh_crash(self):
        """Simulate an ssh crash."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__),
                         '../../../test_util/crash.py'))
        _, result = scanner._inspect_scan(self.host_list,
                                          base_ssh_executable=path)
        self.assertEqual(result, ScanTask.FAILED)

    def test_ssh_hang(self):
        """Simulate an ssh hang."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__),
                         '../../../test_util/hang.py'))
        scanner._inspect_scan(self.host_list,
                              roles=['redhat_release'],
                              base_ssh_executable=path,
                              ssh_timeout='0.1s')
Example #8
0
class SatelliteFiveTest(TestCase):
    """Tests Satellite 5 functions."""

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(
            name='cred1',
            cred_type=Credential.SATELLITE_CRED_TYPE,
            username='******',
            password='******',
            become_password=None,
            become_method=None,
            become_user=None,
            ssh_keyfile=None)
        self.cred.save()

        self.source = Source(
            name='source1',
            port=443,
            hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_INSPECT)

        self.api = SatelliteFive(self.scan_task)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    @patch('xmlrpc.client.ServerProxy')
    def test_host_count(self, mock_serverproxy):
        """Test the method host_count."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.list_user_systems.return_value = ['sys1', 'sys2', 'sys3']
        systems_count = self.api.host_count()
        self.assertEqual(systems_count, 3)

    @patch('xmlrpc.client.ServerProxy')
    def test_host_count_with_err(self, mock_serverproxy):
        """Test the method host_count with error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.host_count()

    @patch('xmlrpc.client.ServerProxy')
    def test_hosts(self, mock_serverproxy):
        """Test the method hosts."""
        systems = [{'name': 'sys1'},
                   {'name': 'sys2'},
                   {'name': 'sys3'}]
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.list_user_systems.return_value = systems
        systems_count = self.api.host_count()
        hosts = self.api.hosts()
        self.assertEqual(systems_count, 3)
        self.assertEqual(len(hosts), 3)
        self.assertEqual(hosts, ['sys1', 'sys2', 'sys3'])

    @patch('xmlrpc.client.ServerProxy')
    def test_hosts_with_err(self, mock_serverproxy):
        """Test the method hosts with error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.hosts()

    @patch('xmlrpc.client.ServerProxy')
    def test_host_details_virt_host(self, mock_serverproxy):
        """Test host_details method with mock data for virt host."""
        expected = {'uuid': 1, 'name': 'sys1', 'hostname': 'sys1_hostname',
                    'last_checkin_time': '', 'registration_time': 'datetime',
                    'architecture': 'x86', 'kernel_version': 'kernel',
                    'cores': 2, 'num_sockets': 2, 'os_release': '7server',
                    'entitlements': [{'name': 'ent1'}],
                    'ip_addresses': ['1.2.3.4'],
                    'mac_addresses': ['1:a:2:b:3:c'], 'virtual': 'hypervisor',
                    'num_virtual_guests': 3, 'is_virtualized': False}
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.get_uuid.return_value = ''
        cpu = {'arch': 'x86', 'count': 2, 'socket_count': 2}
        client.system.get_cpu.return_value = cpu
        system_details = {'hostname': 'sys1_hostname', 'release': '7server'}
        client.system.get_details.return_value = system_details
        client.system.get_running_kernel.return_value = 'kernel'
        client.system.get_entitlements.return_value = ['ent1']
        net_devices = [{'interface': 'eth0', 'ip': '1.2.3.4',
                        'hardware_address': '1:a:2:b:3:c'}]
        client.system.get_network_devices.return_value = net_devices
        client.system.get_registration_date.return_value = 'datetime'
        virt = {1: {'id': 1, 'num_virtual_guests': 3}}
        details = self.api.host_details(host_id=1, host_name='sys1',
                                        last_checkin='', virtual_hosts=virt,
                                        virtual_guests={}, physical_hosts=[])
        self.assertEqual(details, expected)

    @patch('xmlrpc.client.ServerProxy')
    def test_host_details_virt_guest(self, mock_serverproxy):
        """Test host_details method with mock data for virt guest."""
        expected = {'uuid': 1, 'name': 'sys1', 'hostname': 'sys1_hostname',
                    'last_checkin_time': '', 'registration_time': 'datetime',
                    'architecture': 'x86', 'kernel_version': 'kernel',
                    'cores': 2, 'num_sockets': 2, 'os_release': '7server',
                    'entitlements': [{'name': 'ent1'}],
                    'ip_addresses': ['1.2.3.4'],
                    'mac_addresses': ['1:a:2:b:3:c'],
                    'is_virtualized': True, 'virtual_host': 2,
                    'virtual_host_name': 'sys2'}
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.get_uuid.return_value = ''
        cpu = {'arch': 'x86', 'count': 2, 'socket_count': 2}
        client.system.get_cpu.return_value = cpu
        system_details = {'hostname': 'sys1_hostname', 'release': '7server'}
        client.system.get_details.return_value = system_details
        client.system.get_running_kernel.return_value = 'kernel'
        client.system.get_entitlements.return_value = ['ent1']
        net_devices = [{'interface': 'eth0', 'ip': '1.2.3.4',
                        'hardware_address': '1:a:2:b:3:c'}]
        client.system.get_network_devices.return_value = net_devices
        client.system.get_registration_date.return_value = 'datetime'
        virt = {2: {'uuid': 2, 'name': 'sys2', 'num_virtual_guests': 3}}
        details = self.api.host_details(host_id=1, host_name='sys1',
                                        last_checkin='', virtual_hosts=virt,
                                        virtual_guests={1: 2},
                                        physical_hosts=[])
        self.assertEqual(details, expected)

    def test_host_details_skip(self):
        """Test host_details method for already captured data."""
        # pylint: disable=no-member
        sys_result = SystemInspectionResult(
            name='sys1',
            status=SystemInspectionResult.SUCCESS)
        sys_result.save()
        inspect_result = self.scan_task.inspection_result
        inspect_result.systems.add(sys_result)
        inspect_result.save()
        virt = {2: {'uuid': 2, 'name': 'sys2', 'num_virtual_guests': 3}}
        detail = self.api.host_details(host_id=1, host_name='sys1',
                                       last_checkin='', virtual_hosts=virt,
                                       virtual_guests={1: 2},
                                       physical_hosts=[])
        self.assertEqual(len(inspect_result.systems.all()), 1)
        self.assertEqual(detail, {})

    @patch('xmlrpc.client.ServerProxy')
    def test_host_details_with_err(self, mock_serverproxy):
        """Test the host details with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        virt = {2: {'uuid': 2, 'name': 'sys2', 'num_virtual_guests': 3}}
        details = self.api.host_details(host_id=1, host_name='sys1',
                                        last_checkin='',
                                        virtual_hosts=virt,
                                        virtual_guests={1: 2},
                                        physical_hosts=[])
        inspect_result = self.scan_task.inspection_result
        self.assertEqual(len(inspect_result.systems.all()), 1)
        sys_result = inspect_result.systems.all().first()
        self.assertEqual(sys_result.status, SystemInspectionResult.FAILED)
        self.assertEqual(details, {})

    @patch('xmlrpc.client.ServerProxy')
    def test_virtual_guests_with_err(self, mock_serverproxy):
        """Test the virtual_guests method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.virtual_guests(1)

    @patch('xmlrpc.client.ServerProxy')
    def test_virtual_guests(self, mock_serverproxy):
        """Test the virtual_guests method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        guests = [{'id': 2}]
        client.system.list_virtual_guests.return_value = guests
        virt_guests = self.api.virtual_guests(1)
        self.assertEqual(virt_guests, ({2: 1}, 1))

    @patch('xmlrpc.client.ServerProxy')
    def test_virtual_hosts_with_err(self, mock_serverproxy):
        """Test the virtual_hosts method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.virtual_hosts()

    @patch('xmlrpc.client.ServerProxy')
    def test_virtual_hosts(self, mock_serverproxy):
        """Test the virtual_hosts method."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        guests = [{'id': 2}]
        client.system.list_virtual_guests.return_value = guests
        hosts = [{'id': 1, 'name': 'host1'}]
        client.system.list_virtual_hosts.return_value = hosts
        client.system.get_uuid.return_value = ''
        virtual_hosts, virtual_guests = self.api.virtual_hosts()
        virt_host = {1: {'id': 1, 'name': 'host1',
                         'uuid': 1, 'num_virtual_guests': 1}}
        virt_guest = {2: 1}
        self.assertEqual(virtual_hosts, virt_host)
        self.assertEqual(virtual_guests, virt_guest)

    @patch('xmlrpc.client.ServerProxy')
    def test_physical_hosts_with_err(self, mock_serverproxy):
        """Test the phyiscal_hosts method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.physical_hosts()

    @patch('xmlrpc.client.ServerProxy')
    def test_physical_hosts(self, mock_serverproxy):
        """Test the physical_hosts method."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        hosts = [{'id': 1, 'name': 'host1'}]
        client.system.list_physical_systems.return_value = hosts
        phyiscal_hosts = self.api.physical_hosts()
        self.assertEqual(phyiscal_hosts, [1])

    @patch('xmlrpc.client.ServerProxy')
    def test_hosts_facts_with_err(self, mock_serverproxy):
        """Test the hosts_facts method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.hosts_facts()

    @patch('xmlrpc.client.ServerProxy')
    def test_hosts_facts(self, mock_serverproxy):
        """Test the hosts_facts method."""
        detail_value = {}
        systems = [{'id': 1, 'name': 'sys1'}]
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.list_user_systems.return_value = systems
        hosts_return_value = ({}, {})
        with patch.object(SatelliteFive, 'virtual_hosts',
                          return_value=hosts_return_value) as mock_vhosts:
            with patch.object(SatelliteFive, 'physical_hosts',
                              return_value=[]) as mock_physical:
                with patch.object(SatelliteFive,
                                  'host_details',
                                  return_value=detail_value) as mock_detail:
                    self.api.hosts_facts()
                    mock_vhosts.assert_called_once_with()
                    mock_physical.assert_called_once_with()
                    mock_detail.assert_called_once_with(ANY, ANY, ANY,
                                                        ANY, ANY, ANY)
Example #9
0
class SatelliteSixV2Test(TestCase):
    """Tests Satellite 6 v2 functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               cred_type=Credential.SATELLITE_CRED_TYPE,
                               username='******',
                               password='******',
                               become_password=None,
                               become_method=None,
                               become_user=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=443, hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_INSPECT)
        self.scan_task.update_stats('TEST_SAT.', sys_scanned=0)
        self.api = SatelliteSixV2(self.scan_job, self.scan_task)
        job_conn_result = JobConnectionResult()
        job_conn_result.save()
        connection_results = TaskConnectionResult(
            job_connection_result=job_conn_result)
        connection_results.save()
        self.api.connect_scan_task.connection_result = connection_results
        self.api.connect_scan_task.connection_result.save()

        conn_result = self.api.connect_scan_task.connection_result
        sys_result = SystemConnectionResult(
            name='sys1_1',
            status=SystemInspectionResult.SUCCESS,
            task_connection_result=conn_result)
        sys_result.save()
        self.api.connect_scan_task.save()

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_host_count(self):
        """Test the method host_count."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=200, json=jsonresult)
            systems_count = self.api.host_count()
            self.assertEqual(systems_count, 3)

    def test_host_count_with_err(self):
        """Test the method host_count with error."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.host_count()

    def test_hosts(self):
        """Test the method hosts."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1',
                    'id': 1
                }, {
                    'name': 'sys2',
                    'id': 2
                }, {
                    'name': 'sys3',
                    'id': 3
                }],
                'per_page':
                100,
                'total':
                3
            }
            mocker.get(url, status_code=200, json=jsonresult)
            systems_count = self.api.host_count()
            hosts = self.api.hosts()
            self.assertEqual(systems_count, 3)
            self.assertEqual(len(hosts), 3)
            self.assertEqual(hosts, ['sys1_1', 'sys2_2', 'sys3_3'])

    def test_hosts_with_err(self):
        """Test the method hosts with error."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.hosts()

    def test_processing_fields_with_err(self):
        """Test the post_processing with error."""
        host_field_url = 'https://{sat_host}:{port}/api/v2/hosts/{host_id}'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=host_field_url,
                                sat_host='1.2.3.4',
                                host_id=1)
            mocker.get(url, status_code=500)
            result = request_host_details(
                self.scan_task, {
                    'job_id': self.scan_job.id,
                    'task_sequence_number': self.scan_task.id,
                    'scan_type': self.scan_task.scan_type,
                    'source_type': self.scan_task.source.source_type,
                    'source_name': self.scan_task.source.name
                }, 1, 'sys', url, url, {})
            expected = {
                'unique_name': 'sys_1',
                'system_inspection_result': 'failed',
                'host_fields_response': {},
                'host_subscriptions_response': {}
            }
            self.assertEqual(result, expected)
            process_results(self.api, [result], 1)
            inspect_results = self.scan_task.inspection_result.systems.all()
            sys_1_result = inspect_results.filter(name='sys_1').first()
            self.assertEqual(sys_1_result.name, 'sys_1')
            self.assertEqual(sys_1_result.status, 'failed')

    def test_host_fields(self):
        """Test the method host_fields."""
        host_field_url = 'https://{sat_host}:{port}/api/v2/hosts/{host_id}'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=host_field_url,
                                sat_host='1.2.3.4',
                                host_id=1)
            jsonresult = {
                'architecture_id': 1,
                'architecture_name': 'x86_64',
                'operatingsystem_name': 'RedHat 7.4',
                'uuid': None,
                'created_at': '2017-12-04 13:19:57 UTC',
                'updated_at': '2017-12-04 13:21:47 UTC',
                'organization_name': 'ACME',
                'location_name': 'Raleigh',
                'name': 'mac52540071bafe.prov.lan',
                'virtual_host': {
                    'uuid': '100',
                    'name': 'vhost1'
                },
                'virtual_guests': [{
                    'name': 'foo'
                }],
                'content_facet_attributes': {
                    'id': 11,
                    'katello_agent_installed': False
                },
                'subscription_facet_attributes': {
                    'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
                    'last_checkin': '2018-01-04 17:36:07 UTC',
                    'registered_at': '2017-12-04 13:33:52 UTC',
                    'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
                    'virtual_host': {
                        'uuid': '100',
                        'name': 'vhost1'
                    },
                    'virtual_guests': [{
                        'name': 'foo'
                    }],
                },
                'facts': {
                    'memorysize_mb': '992.45',
                    'memorysize': '992.45 MB',
                    'hostname': 'fdi',
                    'type': 'Other',
                    'architecture': 'x86_64',
                    'is_virtual': 'true',
                    'virtual': 'kvm',
                    'net::interface::ipv4_address': '192.168.99.123',
                    'net::interface::mac_address': 'fe80::5054:ff:fe24:946e',
                },
            }
            mocker.get(url, status_code=200, json=jsonresult)
            host_info = host_fields(2, jsonresult)
            expected = {
                'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
                'hostname': 'mac52540071bafe.prov.lan',
                'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
                'registration_time': '2017-12-04 13:33:52 UTC',
                'last_checkin_time': '2018-01-04 17:36:07 UTC',
                'katello_agent_installed': False,
                'os_release': 'RedHat 7.4',
                'organization': 'ACME',
                'virtual_host_uuid': '100',
                'virtual_host_name': 'vhost1',
                'virt_type': None,
                'kernel_version': None,
                'architecture': None,
                'is_virtualized': None,
                'cores': None,
                'num_sockets': None,
                'num_virtual_guests': 1,
                'virtual': 'hypervisor',
                'location': 'Raleigh',
                'ip_addresses': ['192.168.99.123'],
                'mac_addresses': ['fe80::5054:ff:fe24:946e'],
                'os_name': 'RedHat',
                'os_version': '7.4'
            }
            self.assertEqual(host_info, expected)

    def test_get_https_with_err(self):
        """Test the host subscriptons method with bad status code."""
        sub_url = 'https://{sat_host}:{port}/' \
            'api/v2/hosts/{host_id}/subscriptions'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=sub_url, sat_host='1.2.3.4', host_id=1)
            mocker.get(url, status_code=500)
            result = request_host_details(
                self.scan_task, {
                    'job_id': self.scan_job.id,
                    'task_sequence_number': self.scan_task.id,
                    'scan_type': self.scan_task.scan_type,
                    'source_type': self.scan_task.source.source_type,
                    'source_name': self.scan_task.source.name
                }, 1, 'sys', url, url, {})

            expected = {
                'unique_name': 'sys_1',
                'system_inspection_result': 'failed',
                'host_fields_response': {},
                'host_subscriptions_response': {}
            }
            self.assertEqual(result, expected)

    def test_processing_subs_err_nojson(self):
        """Test the flow of post processing with bad code and not json."""
        sub_url = 'https://{sat_host}:{port}/' \
            'api/v2/hosts/{host_id}/subscriptions'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=sub_url, sat_host='1.2.3.4', host_id=1)
            mocker.get(url, status_code=404, text='error message')
            result = request_host_details(
                self.scan_task, {
                    'job_id': self.scan_job.id,
                    'task_sequence_number': self.scan_task.id,
                    'scan_type': self.scan_task.scan_type,
                    'source_type': self.scan_task.source.source_type,
                    'source_name': self.scan_task.source.name
                }, 1, 'sys', url, url, {})

            process_results(self.api, [result], 1)
            inspect_results = self.scan_task.inspection_result.systems.all()
            sys_1_result = inspect_results.filter(name='sys_1').first()
            self.assertEqual(sys_1_result.name, 'sys_1')
            self.assertEqual(sys_1_result.status, 'failed')

    def test_host_not_subscribed(self):
        """Test the host subscriptons method for not subscribed error."""
        sub_url = 'https://{sat_host}:{port}/' \
            'api/v2/hosts/{host_id}/subscriptions'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=sub_url, sat_host='1.2.3.4', host_id=1)
            err_msg = {
                'displayMessage':
                'Host has not been registered '
                'with subscription-manager',
                'errors':
                ['Host has not been registered'
                 ' with subscription-manager']
            }  # noqa
            mocker.get(url, status_code=400, json=err_msg)
            result = request_host_details(
                self.scan_task, {
                    'job_id': self.scan_job.id,
                    'task_sequence_number': self.scan_task.id,
                    'scan_type': self.scan_task.scan_type,
                    'source_type': self.scan_task.source.source_type,
                    'source_name': self.scan_task.source.name
                }, 1, 'sys', url, url, {})

        process_results(self.api, [result], 1)
        inspect_results = self.scan_task.inspection_result.systems.all()
        sys_1_result = inspect_results.filter(name='sys_1').first()
        self.assertEqual(sys_1_result.name, 'sys_1')
        self.assertEqual(sys_1_result.status, 'failed')

    def test_host_subscriptons(self):
        """Test the host subscriptons method."""
        sub_url = 'https://{sat_host}:{port}/' \
            'api/v2/hosts/{host_id}/subscriptions'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=sub_url, sat_host='1.2.3.4', host_id=1)
            jsonresult = {
                'results': [{
                    'amount': 1,
                    'name': 'Satellite Tools 6.3',
                    'start_date': '2017-12-01 14:50:59 UTC',
                    'end_date': '2047-11-24 14:50:59 UTC',
                    'product_name': 'Satellite Tools 6.3',
                }, {
                    'quantity_consumed': 1,
                    'name': 'Employee SKU',
                    'start_date': '2016-03-24 04:00:00 UTC',
                    'end_date': '2022-01-01 04:59:59 UTC',
                    'account_number': 1212729,
                    'contract_number': 10913844,
                    'type': 'ENTITLEMENT_DERIVED',
                    'product_name': 'Employee SKU',
                }]
            }
            mocker.get(url, status_code=200, json=jsonresult)
            subs = host_subscriptions(jsonresult)
            expected = {
                'entitlements': [{
                    'derived_entitlement': False,
                    'name': 'Satellite Tools 6.3',
                    'amount': 1,
                    'account_number': None,
                    'contract_number': None,
                    'start_date': '2017-12-01 14:50:59 UTC',
                    'end_date': '2047-11-24 14:50:59 UTC'
                }, {
                    'derived_entitlement': True,
                    'name': 'Employee SKU',
                    'amount': 1,
                    'account_number': 1212729,
                    'contract_number': 10913844,
                    'start_date': '2016-03-24 04:00:00 UTC',
                    'end_date': '2022-01-01 04:59:59 UTC'
                }]
            }
            self.assertEqual(subs, expected)

    def test_post_processing_err(self):
        """Test error flow & check that a failed system is marked."""
        response = {
            'unique_name': 'sys_1',
            'system_inspection_result': SystemInspectionResult.FAILED,
            'host_fields_response': {},
            'host_subscriptions_response': {}
        }
        process_results(self.api, [response], 1)
        inspect_results = self.scan_task.inspection_result.systems.all()
        sys_1_result = inspect_results.filter(name='sys_1').first()
        self.assertEqual(sys_1_result.name, 'sys_1')
        self.assertEqual(sys_1_result.status, 'failed')

    def test_post_processing(self):
        """Test process_results method with mock data."""
        fields_return_value = {
            'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
            'hostname': 'mac52540071bafe.prov.lan',
            'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
            'registration_time': '2017-12-04 13:33:52 UTC',
            'last_checkin_time': '2018-01-04 17:36:07 UTC',
            'katello_agent_installed': False,
            'os_name': 'RedHat 7.4',
            'organization': 'ACME',
            'virtual_host_uuid': '100',
            'virtual_host_name': 'vhost1',
            'virt_type': None,
            'kernel_version': None,
            'architecture': None,
            'is_virtualized': None,
            'cores': None,
            'num_sockets': None,
            'num_virtual_guests': 1,
            'virtual': 'hypervisor',
            'location': 'Raleigh',
            'ip_addresses': ['192.168.99.123'],
            'ipv6_addresses': ['fe80::5054:ff:fe24:946e']
        }
        subs_return_value = {
            'entitlements': [{
                'derived_entitlement': False,
                'name': 'Satellite Tools 6.3',
                'amount': 1,
                'account_number': None,
                'contract_number': None,
                'start_date': '2017-12-01 14:50:59 UTC',
                'end_date': '2047-11-24 14:50:59 UTC'
            }, {
                'derived_entitlement': True,
                'name': 'Employee SKU',
                'amount': 1,
                'account_number': 1212729,
                'contract_number': 10913844,
                'start_date': '2016-03-24 04:00:00 UTC',
                'end_date': '2022-01-01 04:59:59 UTC'
            }]
        }
        expected = {
            'uuid':
            '00c7a108-48ec-4a97-835c-aa3369777f64',
            'hostname':
            'mac52540071bafe.prov.lan',
            'registered_by':
            'sat-r220-07.lab.eng.rdu2.redhat.com',
            'registration_time':
            '2017-12-04 13:33:52 UTC',
            'last_checkin_time':
            '2018-01-04 17:36:07 UTC',
            'katello_agent_installed':
            False,
            'os_name':
            'RedHat 7.4',
            'organization':
            'ACME',
            'virtual_host_uuid':
            '100',
            'virtual_host_name':
            'vhost1',
            'num_virtual_guests':
            1,
            'virtual':
            'hypervisor',
            'location':
            'Raleigh',
            'ip_addresses': ['192.168.99.123'],
            'ipv6_addresses': ['fe80::5054:ff:fe24:946e'],
            'entitlements': [{
                'derived_entitlement': False,
                'name': 'Satellite Tools 6.3',
                'amount': 1,
                'account_number': None,
                'contract_number': None,
                'start_date': '2017-12-01 14:50:59 UTC',
                'end_date': '2047-11-24 14:50:59 UTC'
            }, {
                'derived_entitlement': True,
                'name': 'Employee SKU',
                'amount': 1,
                'account_number': 1212729,
                'contract_number': 10913844,
                'start_date': '2016-03-24 04:00:00 UTC',
                'end_date': '2022-01-01 04:59:59 UTC'
            }]
        }
        with patch('scanner.satellite.six.host_fields',
                   return_value=fields_return_value) as mock_fields:
            with patch('scanner.satellite.six.host_subscriptions',
                       return_value=subs_return_value) as mock_subs:
                result = {
                    'unique_name': 'sys_1',
                    'system_inspection_result': SystemInspectionResult.SUCCESS,
                    'host_fields_response': fields_return_value,
                    'host_subscriptions_response': subs_return_value
                }
                process_results(self.api, [result], 1)
                inspect_results = \
                    self.scan_task.inspection_result.systems.all()
                sys_1_result = inspect_results.filter(name='sys_1').first()
                self.assertEqual(sys_1_result.name, 'sys_1')
                self.assertEqual(sys_1_result.status, 'success')
                result = {}
                for fact in sys_1_result.facts.all():
                    result[fact.name] = json.loads(fact.value)
                self.assertEqual(result, expected)
                mock_fields.assert_called_once_with(ANY, ANY)
                mock_subs.assert_called_once_with(ANY)
                mock_fields.assert_called_once_with(ANY, ANY)
                mock_subs.assert_called_once_with(ANY)

    def test_hosts_facts_with_err(self):
        """Test the hosts_facts method."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4')
            mocker.get(url, status_code=500)
            with self.assertRaises(SatelliteException):
                self.api.hosts_facts(Value('i', ScanJob.JOB_RUN))

    @patch('multiprocessing.pool.Pool.starmap',
           return_value=[{
               'unique_name': 'sys_1',
               'system_inspection_result': 'success',
               'host_fields_response': {},
               'host_subscriptions_response': {}
           }])
    def test_hosts_facts(self, mock_pool):
        """Test the hosts_facts method."""
        scan_options = ScanOptions(max_concurrency=10)
        scan_options.save()
        scan_job, scan_task = create_scan_job(self.source,
                                              ScanTask.SCAN_TYPE_INSPECT,
                                              scan_name='test_62',
                                              scan_options=scan_options)
        scan_task.update_stats('TEST_SAT.', sys_scanned=0)
        api = SatelliteSixV2(scan_job, scan_task)
        job_conn_result = JobConnectionResult()
        job_conn_result.save()
        connection_results = TaskConnectionResult(
            job_connection_result=job_conn_result)
        connection_results.save()
        api.connect_scan_task.connection_result = connection_results
        api.connect_scan_task.connection_result.save()

        sys_result = SystemConnectionResult(
            name='sys1_1',
            status=SystemInspectionResult.SUCCESS,
            task_connection_result=api.connect_scan_task.connection_result)
        sys_result.save()
        api.connect_scan_task.save()
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4')
            jsonresult = {
                'total': 1,
                'subtotal': 1,
                'page': 1,
                'per_page': 100,
                'results': [{
                    'id': 10,
                    'name': 'sys10'
                }]
            }  # noqa
            mocker.get(url, status_code=200, json=jsonresult)
            api.hosts_facts(Value('i', ScanJob.JOB_RUN))
            inspect_result = scan_task.inspection_result
            self.assertEqual(len(inspect_result.systems.all()), 1)
Example #10
0
class InspectTaskRunnerTest(TestCase):
    """Tests Satellite connect capabilities."""

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(
            name='cred1',
            cred_type=Credential.SATELLITE_CRED_TYPE,
            username='******',
            password='******')
        self.cred.save()

        self.source = Source(
            name='source1',
            port=443,
            hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_INSPECT,
                                  source=self.source, sequence_number=2,
                                  start_time=datetime.utcnow())
        self.scan_task.save()
        self.scan_task.update_stats('TEST_SAT.', sys_scanned=0)

        self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT)
        self.scan_job.save()
        self.scan_job.tasks.add(self.scan_task)
        self.conn_results = JobConnectionResult()
        self.conn_results.save()
        self.scan_job.connection_results = self.conn_results

        self.conn_result = TaskConnectionResult(
            scan_task=self.scan_task, source=self.source)
        self.conn_result.save()

        conn_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT,
                             source=self.source, sequence_number=1,
                             start_time=datetime.utcnow())
        conn_task.complete()
        self.scan_task.prerequisites.add(conn_task)
        self.inspect_results = JobInspectionResult()
        self.inspect_results.save()
        self.scan_job.inspection_results = self.inspect_results

        self.scan_job.save()

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_run_failed_prereq(self):
        """Test the running connect task with no source options."""
        self.scan_task.prerequisites.all().delete()
        conn_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT,
                             source=self.source, sequence_number=1)
        conn_task.status = ScanTask.FAILED
        conn_task.save()
        self.scan_task.prerequisites.add(conn_task)
        task = InspectTaskRunner(self.scan_job, self.scan_task)
        status = task.run()

        self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_no_source_options(self):
        """Test the running connect task with no source options."""
        task = InspectTaskRunner(self.scan_job, self.scan_task)
        status = task.run()

        self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat5_bad_status(self):
        """Test the running connect task for Satellite 5."""
        options = SourceOptions(
            satellite_version=SourceOptions.SATELLITE_VERSION_5)
        options.save()
        self.source.options = options
        self.source.save()
        task = InspectTaskRunner(self.scan_job, self.scan_task)
        with patch('scanner.satellite.connect.utils.status',
                   return_value=(401, None)) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat6_bad_status(self):
        """Test the running connect task for Sat 6 with bad status."""
        options = SourceOptions(
            satellite_version=SourceOptions.SATELLITE_VERSION_62)
        options.save()
        self.source.options = options
        self.source.save()
        task = InspectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(401, None)) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat6_bad_api_version(self):
        """Test the running connect task for Sat6 with bad api version."""
        options = SourceOptions(
            satellite_version=SourceOptions.SATELLITE_VERSION_62)
        options.save()
        self.source.options = options
        self.source.save()
        task = InspectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(200, 3)) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_conn_err(self):
        """Test the running connect task with connection error."""
        options = SourceOptions(
            satellite_version=SourceOptions.SATELLITE_VERSION_62)
        options.save()
        self.source.options = options
        self.source.save()
        task = InspectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_conn_exception) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_sat_err(self):
        """Test the running connect task with satellite error."""
        options = SourceOptions(
            satellite_version=SourceOptions.SATELLITE_VERSION_62)
        options.save()
        self.source.options = options
        self.source.save()
        task = InspectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_sat_exception) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_timeout(self):
        """Test the running connect task with timeout error."""
        options = SourceOptions(
            satellite_version=SourceOptions.SATELLITE_VERSION_62)
        options.save()
        self.source.options = options
        self.source.save()
        task = InspectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_timeout_error) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_excep(self):
        """Test the running connect task with general exception."""
        options = SourceOptions(
            satellite_version=SourceOptions.SATELLITE_VERSION_62)
        options.save()
        self.source.options = options
        self.source.save()
        task = InspectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_exception) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_sat(self):
        """Test the running connect task with satellite."""
        options = SourceOptions(
            satellite_version=SourceOptions.SATELLITE_VERSION_62)
        options.save()
        self.source.options = options
        self.source.save()
        task = InspectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(200, 2)) as mock_sat_status:
            with patch.object(SatelliteSixV2, 'hosts_facts') as mock_facts:
                status = task.run()
                mock_sat_status.assert_called_once_with(ANY, ANY)
                mock_facts.assert_called_once_with()
                self.assertEqual(status[1], ScanTask.COMPLETED)
class NetworkInspectScannerTest(TestCase):
    """Tests network inspect scan task class."""

    # pylint: disable=too-many-instance-attributes, protected-access
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               ssh_keyfile=None,
                               become_method=None,
                               become_user=None,
                               become_password=None)
        self.cred.save()

        hc_serializer = CredentialSerializer(self.cred)
        self.cred_data = hc_serializer.data

        # setup source for scan
        self.source = Source(name='source1', port=22, hosts='["1.2.3.4"]')
        self.source.save()
        self.source.credentials.add(self.cred)

        self.host_list = [('1.2.3.4', self.cred_data)]

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_INSPECT)

        self.connect_scan_task = self.scan_task.prerequisites.first()
        self.connect_scan_task.update_stats('TEST NETWORK CONNECT.',
                                            sys_failed=0)

        conn_result = self.connect_scan_task.connection_result
        success_sys = SystemConnectionResult(
            name='1.2.3.4',
            credential=self.cred,
            status=SystemConnectionResult.SUCCESS,
            task_connection_result=conn_result)
        success_sys.save()
        failed_sys = SystemConnectionResult(
            name='1.1.1.2',
            status=SystemConnectionResult.FAILED,
            task_connection_result=conn_result)
        failed_sys.save()
        conn_result.save()

        self.connect_scan_task.update_stats('TEST_VC.',
                                            sys_count=2,
                                            sys_failed=1,
                                            sys_scanned=1)
        self.connect_scan_task.complete()

        self.scan_task.update_stats('TEST NETWORK INSPECT.', sys_failed=0)

        self.fact_endpoint = 'http://testserver' + reverse('reports-list')

        self.scan_job.save()
        self.stop_states = [
            ScanJob.JOB_TERMINATE_CANCEL, ScanJob.JOB_TERMINATE_PAUSE
        ]
        self.interrupt = Mock(value=ScanJob.JOB_RUN)

    def test_scan_inventory(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        connection_port = source['port']
        inventory_dict = _construct_scan_inventory(self.host_list,
                                                   connection_port, 50)
        expected = {
            'all': {
                'children': {
                    'group_0': {
                        'hosts': {
                            '1.2.3.4': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.4'
                            }
                        }
                    }
                },
                'vars': {
                    'ansible_port': 22
                }
            }
        }

        self.assertEqual(inventory_dict[1], expected)

    def test_scan_inventory_grouping(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        inventory_dict = _construct_scan_inventory([('1.2.3.1', cred),
                                                    ('1.2.3.2', cred),
                                                    ('1.2.3.3', cred),
                                                    ('1.2.3.4', cred)],
                                                   connection_port, 1)
        expected = {
            'all': {
                'children': {
                    'group_0': {
                        'hosts': {
                            '1.2.3.1': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.1'
                            }
                        }
                    },
                    'group_1': {
                        'hosts': {
                            '1.2.3.2': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.2'
                            }
                        }
                    },
                    'group_2': {
                        'hosts': {
                            '1.2.3.3': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.3'
                            }
                        }
                    },
                    'group_3': {
                        'hosts': {
                            '1.2.3.4': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.4'
                            }
                        }
                    }
                },
                'vars': {
                    'ansible_port': 22
                }
            }
        }

        self.assertEqual(inventory_dict[1], expected)

    @patch('ansible_runner.run')
    def test_inspect_scan_failure(self, mock_run):
        """Test scan flow with mocked manager and failure."""
        mock_run.side_effect = AnsibleRunnerException()
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        scanner.connect_scan_task = self.connect_scan_task
        with self.assertRaises(AnsibleRunnerException):
            scanner._inspect_scan(Value('i', ScanJob.JOB_RUN), self.host_list)
            mock_run.assert_called()

    @patch('scanner.network.inspect.InspectTaskRunner._inspect_scan')
    def test_inspect_scan_error(self, mock_scan):
        """Test scan flow with mocked manager and failure."""
        mock_scan.side_effect = AnsibleRunnerException()
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        scan_task_status = scanner.run(Value('i', ScanJob.JOB_RUN))
        mock_scan.assert_called_with(ANY, self.host_list)
        self.assertEqual(scan_task_status[1], ScanTask.FAILED)

    @patch('ansible_runner.run')
    def test_inspect_scan_fail_no_facts(self, mock_run):
        """Test running a inspect scan with mocked connection."""
        mock_run.return_value.status = 'successful'
        with requests_mock.Mocker() as mocker:
            mocker.post(self.fact_endpoint, status_code=201, json={'id': 1})
            scanner = InspectTaskRunner(self.scan_job, self.scan_task)
            scanner.connect_scan_task = self.connect_scan_task
            scan_task_status = scanner.run(Value('i', ScanJob.JOB_RUN))
            mock_run.assert_called()
            self.assertEqual(scan_task_status[1], ScanTask.FAILED)

    def test_ssh_crash(self):
        """Simulate an ssh crash."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), 'test_util/crash.py'))
        _, result = scanner._inspect_scan(Value('i', ScanJob.JOB_RUN),
                                          self.host_list,
                                          base_ssh_executable=path)
        self.assertEqual(result, ScanTask.COMPLETED)

    def test_ssh_hang(self):
        """Simulate an ssh hang."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), 'test_util/hang.py'))
        scanner._inspect_scan(Value('i', ScanJob.JOB_RUN),
                              self.host_list,
                              base_ssh_executable=path,
                              ssh_timeout='0.1s')

    @patch('ansible_runner.run')
    def test_scan_with_options(self, mock_run):
        """Setup second scan with scan and source options."""
        # setup source with paramiko option for scan
        source_options = SourceOptions()
        source_options.save()
        self.source = Source(name='source2',
                             port=22,
                             options=source_options,
                             hosts='["1.2.3.4"]')
        self.source.save()
        self.source.credentials.add(self.cred)

        # setup scan with options
        extended = ExtendedProductSearchOptions()
        extended.save()
        scan_options = ScanOptions(enabled_extended_product_search=extended)
        scan_options.save()

        self.scan_job, self.scan_task = create_scan_job(
            self.source,
            ScanTask.SCAN_TYPE_INSPECT,
            'scan2',
            scan_options=scan_options)

        # run scan
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)

        scanner.connect_scan_task = self.connect_scan_task
        scanner._inspect_scan(Value('i', ScanJob.JOB_RUN), self.host_list)
        mock_run.assert_called()

    def test_populate_callback(self):
        """Test the population of the callback object for inspect scan."""
        callback = InspectResultCallback(scan_task=self.scan_task,
                                         manager_interrupt=self.interrupt)
        # cleaned unused variabled from event_dict
        event_dict = {
            'runner_ident': 'f2100bac-7d64-43d2-8e6a-022c6f5104ac',
            'event': 'runner_on_unreachable',
            'event_data': {
                'play': 'group_0',
                'play_pattern': ' group_0 ',
                'task': 'test if user has sudo cmd',
                'task_action': 'raw',
                'role': 'check_dependencies',
                'host': '1.2.3.4',
                'res': {
                    'unreachable': True,
                    'msg': 'Failed to connect to the host via ssh: ',
                    'changed': False
                },
                'pid': 2210
            }
        }
        callback.task_on_unreachable(event_dict)

    def test_run_manager_interupt(self):
        """Test manager interupt for inspect run method."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        terminate = Value('i', ScanJob.JOB_TERMINATE_CANCEL)
        scan_task_status = scanner.run(terminate)
        self.assertEqual(scan_task_status[1], ScanTask.CANCELED)

    @patch('scanner.network.inspect.InspectTaskRunner._obtain_discovery_data')
    def test_no_reachable_host(self, discovery):
        """Test no reachable host."""
        discovery.return_value = [], [], [], []
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        scan_task_status = scanner.run(Value('i', ScanJob.JOB_RUN))
        self.assertEqual(scan_task_status[1], ScanTask.FAILED)

    def test_cancel_inspect(self):
        """Test cancel of inspect."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        with self.assertRaises(NetworkCancelException):
            scanner.connect_scan_task = self.connect_scan_task
            scanner._inspect_scan(Value('i', ScanJob.JOB_TERMINATE_CANCEL),
                                  self.host_list)

    def test_pause_inspect(self):
        """Test pause of inspect."""
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        with self.assertRaises(NetworkPauseException):
            scanner.connect_scan_task = self.connect_scan_task
            scanner._inspect_scan(Value('i', ScanJob.JOB_TERMINATE_PAUSE),
                                  self.host_list)

    @patch('ansible_runner.run')
    @patch('scanner.network.inspect.settings.ANSIBLE_LOG_LEVEL', '1')
    def test_modifying_log_level(self, mock_run):
        """Test modifying the log level."""
        mock_run.return_value.status = 'successful'
        scanner = InspectTaskRunner(self.scan_job, self.scan_task)
        scanner._inspect_scan(Value('i', ScanJob.JOB_RUN), self.host_list)
        mock_run.assert_called()
        calls = mock_run.mock_calls
        # Check to see if the parameter was passed into the runner.run()
        self.assertIn('verbosity=1', str(calls[0]))
Example #12
0
class SatelliteUtilsTest(TestCase):
    """Tests Satellite utils functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               cred_type=Credential.SATELLITE_CRED_TYPE,
                               username='******',
                               password='******',
                               become_password=None,
                               become_method=None,
                               become_user=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=443, hosts='["1.2.3.4"]')
        self.source.save()
        self.source.credentials.add(self.cred)
        self.options = SourceOptions(ssl_cert_verify=False)
        self.options.save()
        self.source.options = self.options
        self.source.save()

        self.scan_job, self.scan_task = create_scan_job(
            self.source, scan_type=ScanTask.SCAN_TYPE_CONNECT)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_get_credential(self):
        """Test the method to extract credential."""
        cred = get_credential(self.scan_task)
        self.assertEqual(cred, self.cred)

    def test_get_connect_data(self):
        """Test method to get connection data from task."""
        host, port, user, password = get_connect_data(self.scan_task)
        self.assertEqual(host, '1.2.3.4')
        self.assertEqual(port, 443)
        self.assertEqual(user, 'username')
        self.assertEqual(password, 'password')

    def test_construct_url(self):
        """Test method to construct satellite url."""
        expected = 'https://1.2.3.4:443/api/status'
        status_url = 'https://{sat_host}:{port}/api/status'
        url = construct_url(status_url, '1.2.3.4')
        self.assertEqual(url, expected)

    def test_execute_request(self):
        """Test the method to execute a request against a satellite server."""
        status_url = 'https://{sat_host}:{port}/api/status'
        with requests_mock.Mocker() as mocker:
            url = construct_url(status_url, '1.2.3.4')
            jsonresult = {'api_version': 2}
            mocker.get(url, status_code=200, json=jsonresult)
            response, formatted_url = execute_request(self.scan_task,
                                                      status_url)
            self.assertEqual(url, formatted_url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.json(), jsonresult)

    @patch('scanner.satellite.utils._status6',
           return_value=(200, SATELLITE_VERSION_6, SATELLITE_VERSION_6))
    def test_status_sat6(self, mock_status5):
        """Test a patched status request to Satellite 6 server."""
        status_code, api_version, satellite_version = status(self.scan_task)
        self.assertEqual(status_code, 200)
        self.assertEqual(api_version, SATELLITE_VERSION_6)
        self.assertEqual(satellite_version, SATELLITE_VERSION_6)
        mock_status5.assert_called_once_with(ANY)

    @patch('xmlrpc.client.ServerProxy')
    def test_status5(self, mock_serverproxy):
        """Test a successful status request to Satellite 5 server."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        status_code, api_version, satellite_version = _status5(self.scan_task)
        self.assertEqual(status_code, 200)
        self.assertEqual(api_version, SATELLITE_VERSION_5)
        self.assertEqual(satellite_version, SATELLITE_VERSION_5)

    @patch('xmlrpc.client.ServerProxy')
    def test_status5_xmlfault(self, mock_serverproxy):
        """Test a successful status request to Satellite 5 server."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            _status5(self.scan_task)
            mock_serverproxy.auth.login.assert_called_once_with(ANY, ANY)

    @patch('xmlrpc.client.ServerProxy')
    def test_status(self, mock_serverproxy):
        """Test a successful status request to Satellite server."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with requests_mock.Mocker() as mocker:
            status_url = 'https://{sat_host}:{port}/api/status'
            url = construct_url(status_url, '1.2.3.4')
            jsonresult = {'api_version': 2}
            mocker.get(url, status_code=200, json=jsonresult)
            status_code, api_version, satellite_version = \
                status(self.scan_task)
            self.assertEqual(status_code, 200)
            self.assertEqual(api_version, 2)
            self.assertEqual(satellite_version, SATELLITE_VERSION_6)

    @patch('xmlrpc.client.ServerProxy')
    def test_status_error(self, mock_serverproxy):
        """Test a error status request to Satellite server."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with requests_mock.Mocker() as mocker:
            status_url = 'https://{sat_host}:{port}/api/status'
            url = construct_url(status_url, '1.2.3.4')
            jsonresult = {'api_version': 2}
            mocker.get(url, status_code=401, json=jsonresult)
            with self.assertRaises(SatelliteAuthException):
                status(self.scan_task)
                mock_serverproxy.auth.login.assert_called_once_with(ANY, ANY)

    def test_data_map(self):
        """Test a mapping of data from a response dictionary."""
        map_dict = {'id': 'uuid', 'color': 'new::color'}
        data = {'uuid': '100', 'new::color': 'blue', 'key': 'value'}
        expected = {'id': '100', 'color': 'blue'}
        mapped = data_map(map_dict, data)
        self.assertEqual(mapped, expected)

    def test_get_sat5_client(self):
        """Test the sat5 client helper."""
        client, user, password = get_sat5_client(self.scan_task)
        self.assertIsNotNone(client)
        self.assertEqual(user, 'username')
        self.assertEqual(password, 'password')

    def test_validate_task_stats(self):
        """Test validate task stats no errors."""
        validate_task_stats(self.scan_task)

    def test_validate_task_stats_error(self):
        """Test validate task stats errors."""
        with self.assertRaises(SatelliteException):
            self.scan_task.increment_stats('TEST', increment_sys_count=True)
            validate_task_stats(self.scan_task)
class NetworkConnectTaskRunnerTest(TestCase):
    """Tests against the ConnectTaskRunner class and functions."""

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(
            name='cred1',
            username='******',
            password='******',
            ssh_keyfile='keyfile',
            become_method='sudo',
            become_user='******',
            become_password='******')
        self.cred.save()

        # Source with excluded hosts
        self.source = Source(
            name='source1',
            hosts='["1.2.3.4", "1.2.3.5"]',
            exclude_hosts='["1.2.3.5", "1.2.3.6"]',
            source_type='network',
            port=22)
        self.source.save()
        self.source.credentials.add(self.cred)
        self.source.save()

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_CONNECT)

        self.scan_task.update_stats('TEST NETWORK CONNECT.', sys_failed=0)

        # Source without excluded hosts
        self.source2 = Source(
            name='source2',
            hosts='["1.2.3.4"]',
            source_type='network',
            port=22)
        self.source2.save()
        self.source2.credentials.add(self.cred)
        self.source2.save()

        self.scan_job2, self.scan_task2 = create_scan_job(
            self.source2, ScanTask.SCAN_TYPE_CONNECT, 'source2',)

        self.scan_task2.update_stats('TEST NETWORK CONNECT.', sys_failed=0)

        # Scans with options & no excluded hosts
        source_options = SourceOptions(use_paramiko=True)
        source_options.save()
        self.source3 = Source(
            name='source3',
            hosts='["1.2.3.4","1.2.3.5","1.2.3.6"]',
            source_type='network',
            port=22,
            options=source_options)
        self.source3.save()
        self.source3.credentials.add(self.cred)
        self.source3.save()

        scan_options = ScanOptions(max_concurrency=2)
        scan_options.save()

        self.scan_job3, self.scan_task3 = create_scan_job(
            self.source3, ScanTask.SCAN_TYPE_CONNECT, 'source3', scan_options)
        self.scan_task3.update_stats('TEST NETWORK CONNECT.', sys_failed=0)
        self.concurrency = ScanOptions.get_default_forks()

    def test_construct_vars(self):
        """Test constructing ansible vars dictionary."""
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        vars_dict = _construct_vars(22, cred)
        expected = {'ansible_become_pass': '******',
                    'ansible_port': 22,
                    'ansible_ssh_pass': '******',
                    'ansible_ssh_private_key_file': 'keyfile',
                    'ansible_user': '******',
                    'ansible_become_method': 'sudo',
                    'ansible_become_user': '******'}
        self.assertEqual(vars_dict, expected)

    def test_get_exclude_host(self):
        """Test get_exclude_hosts() method."""
        assert self.source.get_exclude_hosts() != []
        assert self.source3.get_exclude_hosts() == []

    # Tests for source1 (has hosts and excluded host)
    def test_result_store(self):
        """Test ConnectResultStore."""
        result_store = ConnectResultStore(self.scan_task)

        self.assertEqual(result_store.remaining_hosts(), ['1.2.3.4'])
        self.assertEqual(result_store.scan_task.systems_count, 1)
        self.assertEqual(result_store.scan_task.systems_scanned, 0)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

        result_store.record_result('1.2.3.4', self.source, self.cred,
                                   SystemConnectionResult.UNREACHABLE)

        self.assertEqual(result_store.remaining_hosts(), [])
        self.assertEqual(result_store.scan_task.systems_count, 1)
        self.assertEqual(result_store.scan_task.systems_scanned, 0)
        self.assertEqual(result_store.scan_task.systems_unreachable, 1)

    def test_connect_inventory(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        path = '/path/to/executable.py'
        ssh_timeout = '0.1s'
        ssh_args = ['--executable=' + path,
                    '--timeout=' + ssh_timeout,
                    'ssh']
        _, inventory_dict = _construct_connect_inventory(hosts, cred,
                                                         connection_port,
                                                         1,
                                                         exclude_hosts,
                                                         ssh_executable=path,
                                                         ssh_args=ssh_args)
        # pylint: disable=line-too-long
        expected = {'all':
                    {'children':
                     {'group_0':
                      {'hosts':
                       {'1.2.3.4':
                        {'ansible_host': '1.2.3.4',
                         'ansible_ssh_executable':
                         '/path/to/executable.py',
                         'ansible_ssh_common_args': '--executable=/path/to/executable.py --timeout=0.1s ssh'}}}},  # noqa
                     'vars':
                     {'ansible_port': 22,
                      'ansible_user': '******',
                      'ansible_ssh_pass': '******',
                      'ansible_ssh_private_key_file': 'keyfile',
                      'ansible_become_pass': '******',
                      'ansible_become_method': 'sudo',
                      'ansible_become_user': '******'}}}
        self.assertEqual(inventory_dict, expected)

    @patch('ansible_runner.run')
    @patch('scanner.network.connect._handle_ssh_passphrase',
           side_effect=mock_handle_ssh)
    def test_connect_failure(self, mock_run, mock_ssh_pass):
        """Test connect flow with mocked manager and failure."""
        mock_run.side_effect = AnsibleRunnerException('Fail')
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        with self.assertRaises(AnsibleRunnerException):
            _connect(Value('i', ScanJob.JOB_RUN),
                     self.scan_task, hosts, Mock(), self.cred,
                     connection_port, self.concurrency,
                     exclude_hosts)
            mock_run.assert_called()
            mock_ssh_pass.assert_called()

    @patch('ansible_runner.run')
    def test_connect(self, mock_run):
        """Test connect flow with mocked manager."""
        mock_run.return_value.status = 'successful'
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        _connect(Value('i', ScanJob.JOB_RUN),
                 self.scan_task, hosts, Mock(), self.cred,
                 connection_port, self.concurrency,
                 exclude_hosts)
        mock_run.assert_called()

    @patch('ansible_runner.run')
    def test_connect_ssh_crash(self, mock_run):
        """Simulate an ssh crash."""
        mock_run.return_value.status = 'successful'
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__),
                         'test_util/crash.py'))
        _connect(Value('i', ScanJob.JOB_RUN), self.scan_task,
                 hosts, Mock(), self.cred, connection_port,
                 self.concurrency, exclude_hosts,
                 base_ssh_executable=path)
        mock_run.assert_called()

    @patch('ansible_runner.run')
    def test_connect_ssh_hang(self, mock_run):
        """Simulate an ssh hang."""
        mock_run.return_value.status = 'successful'
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__),
                         'test_util/hang.py'))
        _connect(
            Value('i', ScanJob.JOB_RUN),
            self.scan_task,
            hosts,
            Mock(), self.cred, connection_port,
            self.concurrency,
            exclude_hosts,
            base_ssh_executable=path,
            ssh_timeout='0.1s')
        mock_run.assert_called()

    @patch('ansible_runner.run')
    def test_connect_runner(self, mock_run):
        """Test running a connect scan with mocked connection."""
        mock_run.return_value.status = 'successful'
        scanner = ConnectTaskRunner(self.scan_job, self.scan_task)
        result_store = MockResultStore(['1.2.3.4'])
        _, result = scanner.run_with_result_store(
            Value('i', ScanJob.JOB_RUN), result_store)
        self.assertEqual(result, ScanTask.COMPLETED)

    # Similar tests as above modified for source2 (Does not have exclude hosts)
    def test_result_store_src2(self):
        """Test ConnectResultStore."""
        result_store = ConnectResultStore(self.scan_task3)
        hosts = ['1.2.3.4', '1.2.3.5', '1.2.3.6']
        self.assertCountEqual(result_store.remaining_hosts(), hosts)
        self.assertEqual(result_store.scan_task.systems_count, 3)
        self.assertEqual(result_store.scan_task.systems_scanned, 0)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

        host = hosts.pop()
        result_store.record_result(host, self.source2, self.cred,
                                   SystemConnectionResult.SUCCESS)

        self.assertCountEqual(result_store.remaining_hosts(), hosts)
        self.assertEqual(result_store.scan_task.systems_count, 3)
        self.assertEqual(result_store.scan_task.systems_scanned, 1)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

        host = hosts.pop()
        # Check failure without cred
        result_store.record_result(host, self.source2, None,
                                   SystemConnectionResult.FAILED)
        self.assertCountEqual(result_store.remaining_hosts(), hosts)
        self.assertEqual(result_store.scan_task.systems_count, 3)
        self.assertEqual(result_store.scan_task.systems_scanned, 1)
        self.assertEqual(result_store.scan_task.systems_failed, 1)

        host = hosts.pop()
        # Check failure with cred
        result_store.record_result(host, self.source2, self.cred,
                                   SystemConnectionResult.FAILED)
        self.assertCountEqual(result_store.remaining_hosts(), hosts)
        self.assertEqual(result_store.scan_task.systems_count, 3)
        self.assertEqual(result_store.scan_task.systems_scanned, 1)
        self.assertEqual(result_store.scan_task.systems_failed, 2)

    def test_connect_inventory_src2(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        _, inventory_dict = _construct_connect_inventory(hosts, cred,
                                                         connection_port, 1)
        expected = {'all':
                    {'children':
                     {'group_0':
                      {'hosts':
                       {'1.2.3.4':
                        {'ansible_host': '1.2.3.4'}}}},
                     'vars':
                     {'ansible_port': 22,
                      'ansible_user': '******',
                      'ansible_ssh_pass': '******',
                      'ansible_ssh_private_key_file': 'keyfile',
                      'ansible_become_pass': '******',
                      'ansible_become_method': 'sudo',
                      'ansible_become_user': '******'}}}
        self.assertEqual(inventory_dict, expected)

    @patch('ansible_runner.run')
    @patch('scanner.network.connect._handle_ssh_passphrase',
           side_effect=mock_handle_ssh)
    def test_connect_failure_src2(self, mock_run, mock_ssh_pass):
        """Test connect flow with mocked manager and failure."""
        mock_run.side_effect = AnsibleRunnerException('Fail')
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        with self.assertRaises(AnsibleRunnerException):
            _connect(Value('i', ScanJob.JOB_RUN), self.scan_task,
                     hosts, Mock(), self.cred, connection_port,
                     self.concurrency)
            mock_run.assert_called()
            mock_ssh_pass.assert_called()

    @patch('ansible_runner.run')
    def test_connect_src2(self, mock_run):
        """Test connect flow with mocked manager."""
        mock_run.return_value.status = 'successful'
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        _connect(Value('i', ScanJob.JOB_RUN), self.scan_task,
                 hosts, Mock(), self.cred, connection_port,
                 self.concurrency)
        mock_run.assert_called()

    @patch('ansible_runner.run')
    def test_connect_runner_error(self, mock_run):
        """Test connect flow with mocked manager."""
        mock_run.side_effect = AnsibleRunnerException('Fail')
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        with self.assertRaises(AnsibleRunnerException):
            _connect(Value('i', ScanJob.JOB_RUN), self.scan_task,
                     hosts, Mock(), self.cred, connection_port,
                     self.concurrency)
            mock_run.assert_called()

    @patch('ansible_runner.run')
    def test_connect_runner_src2(self, mock_run):
        """Test running a connect scan with mocked connection."""
        mock_run.return_value.status = 'successful'
        scanner = ConnectTaskRunner(self.scan_job3, self.scan_task3)
        result_store = MockResultStore(['1.2.3.4'])
        _, result = scanner.run_with_result_store(
            Value('i', ScanJob.JOB_RUN), result_store)
        self.assertEqual(result, ScanTask.COMPLETED)

    @patch('ansible_runner.run')
    def test_connect_paramiko(self, mock_run):
        """Test connect with paramiko."""
        mock_run.return_value.status = 'successful'
        serializer = SourceSerializer(self.source3)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        _connect(Value('i', ScanJob.JOB_RUN),
                 self.scan_task, hosts, Mock(), self.cred,
                 connection_port, self.concurrency)
        mock_run.assert_called()

    @patch('ansible_runner.run')
    @patch('scanner.network.connect.settings.ANSIBLE_LOG_LEVEL', '1')
    def test_modifying_log_level(self, mock_run):
        """Test modifying the log level."""
        mock_run.return_value.status = 'successful'
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        _connect(Value('i', ScanJob.JOB_RUN),
                 self.scan_task, hosts, Mock(), self.cred,
                 connection_port, self.concurrency)
        mock_run.assert_called()
        calls = mock_run.mock_calls
        # Check to see if the parameter was passed into the runner.run()
        self.assertIn('verbosity=1', str(calls[0]))

    @patch('ansible_runner.run')
    @patch('scanner.network.connect.settings.DJANGO_SECRET_PATH', 'None')
    def test_secret_file_fail(self, mock_run):
        """Test modifying the log level."""
        mock_run.side_effect = AnsibleRunnerException()
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        with self.assertRaises(AnsibleRunnerException):
            _connect(Value('i', ScanJob.JOB_RUN),
                     self.scan_task, hosts, Mock(), self.cred,
                     connection_port, self.concurrency)
            mock_run.assert_called()

    @patch('ansible_runner.run')
    def test_unexpected_runner_response(self, mock_run):
        """Test unexpected runner response."""
        mock_run.return_value.status = 'unknown'
        scanner = ConnectTaskRunner(self.scan_job, self.scan_task)
        result_store = MockResultStore(['1.2.3.4'])
        conn_dict = scanner.run_with_result_store(
            Value('i', ScanJob.JOB_RUN), result_store)
        self.assertEqual(conn_dict[1], ScanTask.FAILED)

    @patch('scanner.network.connect.ConnectTaskRunner.run_with_result_store')
    def test_cancel_connect(self, mock_run):
        """Test cancel of connect."""
        # Test cancel at _connect level
        serializer = SourceSerializer(self.source3)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        with self.assertRaises(NetworkCancelException):
            _connect(Value('i', ScanJob.JOB_TERMINATE_CANCEL),
                     self.scan_task, hosts, Mock(), self.cred,
                     connection_port, self.concurrency)
        # Test cancel at run() level
        mock_run.side_effect = NetworkCancelException()
        scanner = ConnectTaskRunner(self.scan_job3, self.scan_task3)
        _, scan_result = scanner.run(Value('i', ScanJob.JOB_RUN))
        self.assertEqual(scan_result, ScanTask.CANCELED)

    @patch('scanner.network.connect.ConnectTaskRunner.run_with_result_store')
    def test_pause_connect(self, mock_run):
        """Test pause of connect."""
        # Test cancel at _connect level
        serializer = SourceSerializer(self.source3)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        with self.assertRaises(NetworkPauseException):
            _connect(Value('i', ScanJob.JOB_TERMINATE_PAUSE),
                     self.scan_task, hosts, Mock(), self.cred,
                     connection_port, self.concurrency)
        # Test cancel at run() level
        mock_run.side_effect = NetworkPauseException()
        scanner = ConnectTaskRunner(self.scan_job3, self.scan_task3)
        _, scan_result = scanner.run(Value('i', ScanJob.JOB_RUN))
        self.assertEqual(scan_result, ScanTask.PAUSED)

    def test_run_manager_interupt(self):
        """Test manager interupt for run method."""
        scanner = ConnectTaskRunner(self.scan_job, self.scan_task)
        conn_dict = scanner.run(Value('i', ScanJob.JOB_TERMINATE_CANCEL))
        self.assertEqual(conn_dict[1], ScanTask.CANCELED)

    @patch('scanner.network.connect.ConnectTaskRunner.run_with_result_store')
    def test_run_success_return_connect(self, mock_run):
        """Test pause of connect."""
        # Test cancel at run() level
        mock_run.side_effect = [[None, ScanTask.COMPLETED]]
        scanner = ConnectTaskRunner(self.scan_job3, self.scan_task3)
        _, scan_result = scanner.run(Value('i', ScanJob.JOB_RUN))
        self.assertEqual(scan_result, ScanTask.COMPLETED)

    @patch('scanner.network.connect._connect')
    def test_connect_exception(self, mock_run):
        """Test pause of connect."""
        # Test cancel at run() level
        mock_run.side_effect = AnsibleRunnerException('fail')
        scanner = ConnectTaskRunner(self.scan_job3, self.scan_task3)
        _, scan_result = scanner.run(Value('i', ScanJob.JOB_RUN))
        self.assertEqual(scan_result, ScanTask.FAILED)

    @patch('ansible_runner.run')
    def test_empty_hosts(self, mock_run):
        """Test running a connect scan with mocked connection."""
        mock_run.return_value.status = 'successful'
        scanner = ConnectTaskRunner(self.scan_job, self.scan_task)
        result_store = MockResultStore([])
        _, result = scanner.run_with_result_store(
            Value('i', ScanJob.JOB_RUN), result_store)
        self.assertEqual(result, ScanTask.COMPLETED)
Example #14
0
class NetworkConnectTaskRunnerTest(TestCase):
    """Tests against the ConnectTaskRunner class and functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               sudo_password='******',
                               ssh_keyfile='keyfile')
        self.cred.save()

        self.source = Source(name='source1', port=22)
        self.source.save()
        self.source.credentials.add(self.cred)

        self.host = HostRange(host_range='1.2.3.4', source_id=self.source.id)
        self.host.save()

        self.source.hosts.add(self.host)

        self.scan_task = ScanTask(source=self.source,
                                  scan_type=ScanTask.SCAN_TYPE_CONNECT)
        self.scan_task.systems_failed = 0
        self.scan_task.save()

        self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT)
        self.scan_job.save()
        self.scan_job.sources.add(self.source)
        self.scan_job.tasks.add(self.scan_task)
        scan_options = ScanOptions()
        scan_options.save()
        self.scan_job.options = scan_options
        self.scan_job.save()

        self.conn_results = ConnectionResults(scan_job=self.scan_job)
        self.conn_results.save()

    def test_construct_vars(self):
        """Test constructing ansible vars dictionary."""
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        vars_dict = _construct_vars(22, cred)
        expected = {
            'ansible_become_pass': '******',
            'ansible_port': 22,
            'ansible_ssh_pass': '******',
            'ansible_ssh_private_key_file': 'keyfile',
            'ansible_user': '******'
        }
        self.assertEqual(vars_dict, expected)

    def test_populate_callback(self):
        """Test the population of the callback object."""
        callback = ResultCallback(scan_task=self.scan_task)
        host = Mock(name='1.2.3.4')
        result = Mock(_host=host, _results={'rc': 0})
        callback.v2_runner_on_ok(result)
        self.assertTrue(len(callback.results) == 1)
        callback.v2_runner_on_failed(result)
        self.assertTrue(len(callback.results) == 2)
        callback.v2_runner_on_unreachable(result)
        self.assertTrue(len(callback.results) == 3)

    def test_process_connect_callback(self):
        """Test callback processing logic."""
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        callback = ResultCallback()
        success_result = {'host': '1.2.3.4', 'result': {'rc': 0}}
        failed_result = {'host': '1.2.3.5', 'result': {'rc': 1}}
        failed_result_format = {'host': '1.2.3.6'}
        callback.results.append(success_result)
        callback.results.append(failed_result)
        callback.results.append(failed_result_format)
        success, failed = _process_connect_callback(callback, cred)
        del cred['password']
        self.assertEqual(success, [('1.2.3.4', cred)])
        self.assertEqual(failed, ['1.2.3.5', '1.2.3.6'])

    def test_connect_inventory(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        inventory_dict = construct_connect_inventory(hosts, cred,
                                                     connection_port)
        expected = {
            'all': {
                'hosts': {
                    '1.2.3.4': None
                },
                'vars': {
                    'ansible_become_pass': '******',
                    'ansible_port': 22,
                    'ansible_ssh_pass': '******',
                    'ansible_ssh_private_key_file': 'keyfile',
                    'ansible_user': '******'
                }
            }
        }
        self.assertEqual(inventory_dict, expected)

    def test_construct_error(self):
        """Test the creation of different errors."""
        error = _construct_error(TaskQueueManager.RUN_FAILED_HOSTS)
        self.assertEqual(error.message, ANSIBLE_FAILED_HOST_ERR_MSG)
        error = _construct_error(TaskQueueManager.RUN_UNREACHABLE_HOSTS)
        self.assertEqual(error.message, ANSIBLE_UNREACHABLE_HOST_ERR_MSG)
        error = _construct_error(TaskQueueManager.RUN_FAILED_BREAK_PLAY)
        self.assertEqual(error.message, ANSIBLE_PLAYBOOK_ERR_MSG)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_failed)
    @patch('scanner.network.connect._handle_ssh_passphrase',
           side_effect=mock_handle_ssh)
    def test_connect_failure(self, mock_run, mock_ssh_pass):
        """Test connect flow with mocked manager and failure."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        with self.assertRaises(AnsibleError):
            connect(hosts, cred, connection_port)
            mock_run.assert_called()
            mock_ssh_pass.assert_called()

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_success)
    def test_connect(self, mock_run):
        """Test connect flow with mocked manager."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        connected, failed = connect(hosts, cred, connection_port)
        self.assertEqual(connected, [])
        self.assertEqual(failed, [])
        mock_run.assert_called_with(ANY)

    @patch('scanner.network.connect.connect')
    def test_discovery(self, mock_connect):
        """Test running a discovery scan with mocked connection."""
        expected = ([('1.2.3.4', {'id': '1'})], [])
        mock_connect.return_value = expected
        scanner = ConnectTaskRunner(self.scan_job, self.scan_task,
                                    self.conn_results)
        conn_dict = scanner.run()
        mock_connect.assert_called_with(ANY, ANY, 22, forks=50)
        self.assertEqual(conn_dict, ScanTask.COMPLETED)

    def test_store_discovery_success(self):
        """Test running a discovery scan _store_connect_result."""
        scanner = ConnectTaskRunner(self.scan_job, self.scan_task,
                                    self.conn_results)
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        connected = [('1.2.3.4', cred)]
        failed = ['1.2.3.5']
        expected = {'1.2.3.4': {'name': 'cred1'}, '1.2.3.5': None}
        # pylint: disable=protected-access
        result = scanner._store_connect_result(connected, failed)
        self.assertEqual(len(result), len(expected))
        self.assertIn('1.2.3.5', result)
        self.assertIsNone(result['1.2.3.5'])
Example #15
0
class HostScannerTest(TestCase):
    """Tests against the HostScanner class and functions."""

    # pylint: disable=too-many-instance-attributes
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               sudo_password=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=22)
        self.source.save()
        self.source.credentials.add(self.cred)

        self.host = HostRange(host_range='1.2.3.4', source_id=self.source.id)
        self.host.save()

        self.source.hosts.add(self.host)

        self.connect_scan_task = ScanTask(source=self.source,
                                          scan_type=ScanTask.SCAN_TYPE_CONNECT,
                                          status=ScanTask.COMPLETED)
        self.connect_scan_task.systems_failed = 0
        self.connect_scan_task.save()

        self.inspect_scan_task = ScanTask(source=self.source,
                                          scan_type=ScanTask.SCAN_TYPE_INSPECT)
        self.inspect_scan_task.systems_failed = 0
        self.inspect_scan_task.save()
        self.inspect_scan_task.prerequisites.add(self.connect_scan_task)
        self.inspect_scan_task.save()

        self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        self.scan_job.save()

        self.scan_job.tasks.add(self.connect_scan_task)
        self.scan_job.tasks.add(self.inspect_scan_task)
        scan_options = ScanOptions()
        scan_options.save()
        self.scan_job.options = scan_options
        self.scan_job.save()

        self.fact_endpoint = 'http://testserver' + reverse('facts-list')

        self.conn_results = ConnectionResults(scan_job=self.scan_job)
        self.conn_results.save()

        self.conn_result = ConnectionResult(scan_task=self.connect_scan_task,
                                            source=self.source)
        self.conn_result.save()

        success_sys = SystemConnectionResult(
            name='1.2.3.4',
            credential=self.cred,
            status=SystemConnectionResult.SUCCESS)
        success_sys.save()
        failed_sys = SystemConnectionResult(
            name='1.1.1.2', status=SystemConnectionResult.FAILED)
        failed_sys.save()
        self.conn_result.systems.add(success_sys)
        self.conn_result.systems.add(failed_sys)
        self.conn_result.save()
        self.conn_results.results.add(self.conn_result)
        self.conn_results.save()

        self.inspect_results = InspectionResults(scan_job=self.scan_job)
        self.inspect_results.save()

    def test_scan_inventory(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        inventory_dict = construct_scan_inventory([('1.2.3.4', cred)],
                                                  connection_port, 50)
        expected = {
            'all': {
                'children': {
                    'group_0': {
                        'hosts': {
                            '1.2.3.4': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.4'
                            }
                        }
                    }
                },
                'vars': {
                    'ansible_port': 22
                }
            }
        }

        self.assertEqual(inventory_dict[1], expected)

    def test_scan_inventory_grouping(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        inventory_dict = construct_scan_inventory([('1.2.3.1', cred),
                                                   ('1.2.3.2', cred),
                                                   ('1.2.3.3', cred),
                                                   ('1.2.3.4', cred)],
                                                  connection_port, 1)
        expected = {
            'all': {
                'children': {
                    'group_0': {
                        'hosts': {
                            '1.2.3.1': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.1'
                            }
                        }
                    },
                    'group_1': {
                        'hosts': {
                            '1.2.3.2': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.2'
                            }
                        }
                    },
                    'group_2': {
                        'hosts': {
                            '1.2.3.3': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.3'
                            }
                        }
                    },
                    'group_3': {
                        'hosts': {
                            '1.2.3.4': {
                                'ansible_user': '******',
                                'ansible_ssh_pass': '******',
                                'ansible_host': '1.2.3.4'
                            }
                        }
                    }
                },
                'vars': {
                    'ansible_port': 22
                }
            }
        }

        self.assertEqual(inventory_dict[1], expected)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_failed)
    def test_inspect_scan_failure(self, mock_run):
        """Test scan flow with mocked manager and failure."""
        scanner = InspectTaskRunner(self.scan_job, self.inspect_scan_task,
                                    self.inspect_results)

        # Init for unit test as run is not called
        scanner.connect_scan_task = self.connect_scan_task
        with self.assertRaises(AnsibleError):
            scanner.inspect_scan()
            mock_run.assert_called()

    @patch('scanner.network.inspect.InspectTaskRunner.inspect_scan',
           side_effect=mock_scan_error)
    def test_inspect_scan_error(self, mock_scan):
        """Test scan flow with mocked manager and failure."""
        scanner = InspectTaskRunner(self.scan_job, self.inspect_scan_task,
                                    self.inspect_results)
        scan_task_status = scanner.run()
        mock_scan.assert_called_with()
        self.assertEqual(scan_task_status, ScanTask.FAILED)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_success)
    def test_inspect_scan_fail_no_facts(self, mock_run):
        """Test running a inspect scan with mocked connection."""
        expected = ([('1.2.3.4', {'name': 'cred1'})], [])
        mock_run.return_value = expected
        with requests_mock.Mocker() as mocker:
            mocker.post(self.fact_endpoint, status_code=201, json={'id': 1})
            scanner = InspectTaskRunner(self.scan_job, self.inspect_scan_task,
                                        self.inspect_results)
            scan_task_status = scanner.run()
            mock_run.assert_called_with(ANY)
            self.assertEqual(scan_task_status, ScanTask.FAILED)

    def test_populate_callback(self):
        """Test the population of the callback object for inspect scan."""
        callback = ResultCallback(scan_task=self.inspect_scan_task,
                                  inspect_results=self.inspect_results)
        host = Mock()
        host.name = '1.2.3.4'
        result = Mock(_host=host, _results={'rc': 3})

        callback.v2_runner_on_unreachable(result)
class ConnectTaskRunnerTest(TestCase):
    """Tests against the ConnectTaskRunner class and functions."""

    runner = None

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(
            name='cred1',
            username='******',
            password='******',
            become_password=None,
            ssh_keyfile=None)
        self.cred.save()

        self.source = Source(
            name='source1',
            port=22,
            hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_CONNECT)

        # Create runner
        self.runner = ConnectTaskRunner(scan_job=self.scan_job,
                                        scan_task=self.scan_task)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_store_connect_data(self):
        """Test the connection data method."""
        vm_names = ['vm1', 'vm2']
        # pylint: disable=protected-access
        self.runner._store_connect_data(vm_names, self.cred,
                                        self.source)
        self.assertEqual(
            len(self.scan_job.connection_results.task_results.all()), 1)

    def test_get_vm_names(self):
        """Test the get vm names method."""
        objects = [
            vim.ObjectContent(
                obj=vim.VirtualMachine('vm-1'),
                propSet=[vim.DynamicProperty(name='name', val='vm1')]
            ),
            vim.ObjectContent(
                obj=vim.VirtualMachine('vm-2'),
                propSet=[vim.DynamicProperty(name='name', val='vm2')]
            ),
        ]

        content = Mock()
        content.rootFolder = vim.Folder('group-d1')
        content.propertyCollector.RetrievePropertiesEx(ANY).token = None
        content.propertyCollector.RetrievePropertiesEx(ANY).objects = objects

        vm_names = get_vm_names(content)
        self.assertTrue(isinstance(vm_names, list))
        self.assertEqual(vm_names, ['vm1', 'vm2'])

    def test_connect(self):
        """Test the VCenter connect method."""
        with patch('scanner.vcenter.connect.vcenter_connect',
                   return_value=Mock()) as mock_vcenter_connect:
            with patch('scanner.vcenter.connect.get_vm_names',
                       return_value=['vm1', 'vm2', 'vm2']) as mock_names:
                vm_names = self.runner.connect()
                self.assertEqual(vm_names, ['vm1', 'vm2', 'vm2'])
                mock_vcenter_connect.assert_called_once_with(ANY)
                mock_names.assert_called_once_with(ANY)

    def test_get_result_none(self):
        """Test get result method when no results exist."""
        results = self.scan_task.get_result().systems.first()
        self.assertEqual(results, None)

    def test_get_result(self):
        """Test get result method when results exist."""
        conn_result = self.scan_task.connection_result
        results = self.scan_task.get_result()
        self.assertEqual(results, conn_result)

    def test_failed_run(self):
        """Test the run method."""
        with patch.object(ConnectTaskRunner, 'connect',
                          side_effect=invalid_login) as mock_connect:
            status = self.runner.run(Value('i', ScanJob.JOB_RUN))
            self.assertEqual(ScanTask.FAILED, status[1])
            mock_connect.assert_called_once_with()

    def test_unreachable_run(self):
        """Test the run method with unreachable."""
        with patch.object(ConnectTaskRunner, 'connect',
                          side_effect=unreachable_host) as mock_connect:
            status = self.runner.run(Value('i', ScanJob.JOB_RUN))
            self.assertEqual(ScanTask.FAILED, status[1])
            mock_connect.assert_called_once_with()

    def test_run(self):
        """Test the run method."""
        with patch.object(ConnectTaskRunner, 'connect',
                          return_value=['vm1', 'vm2']) as mock_connect:
            status = self.runner.run(Value('i', ScanJob.JOB_RUN))
            self.assertEqual(ScanTask.COMPLETED, status[1])
            mock_connect.assert_called_once_with()

    def test_cancel(self):
        """Test the run method with cancel."""
        status = self.runner.run(Value('i', ScanJob.JOB_TERMINATE_CANCEL))
        self.assertEqual(ScanTask.CANCELED, status[1])

    def test_pause(self):
        """Test the run method with pause."""
        status = self.runner.run(Value('i', ScanJob.JOB_TERMINATE_PAUSE))
        self.assertEqual(ScanTask.PAUSED, status[1])
Example #17
0
class InspectTaskRunnerTest(TestCase):
    """Tests against the InspectTaskRunner class and functions."""

    runner = None

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               become_password=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=22, hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.conn_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT,
                                  source=self.source,
                                  sequence_number=1,
                                  start_time=datetime.utcnow())
        self.conn_task.update_stats('TEST_VC.', sys_count=5)
        self.conn_task.complete()

        self.scan_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_INSPECT,
                                  source=self.source,
                                  sequence_number=2,
                                  start_time=datetime.utcnow())
        self.scan_task.save()

        self.scan_task.prerequisites.add(self.conn_task)
        self.scan_task.save()

        self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        self.scan_job.save()
        self.scan_job.tasks.add(self.scan_task)
        self.inspect_results = JobInspectionResult()
        self.inspect_results.save()
        self.scan_job.inspection_results = self.inspect_results
        self.scan_job.save()
        self.runner = InspectTaskRunner(scan_job=self.scan_job,
                                        scan_task=self.scan_task)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_get_nics(self):
        """Test the get_nics method."""
        guest = Mock()
        nics = []
        for k in range(0, 2):
            nic = Mock()
            network = Mock()
            nic.network = network
            nic.macAddress = 'mac' + str(k)
            ip_config = Mock()
            ip_addr = Mock()
            ip_addr.ipAddress = 'ip' + str(k)
            addresses = [ip_addr]
            ip_config.ipAddress = addresses
            nic.ipConfig = ip_config
            nics.append(nic)
        guest.net = nics
        mac_addresses, ip_addresses = get_nics(guest)
        self.assertEqual(mac_addresses, ['mac0', 'mac1'])
        self.assertEqual(ip_addresses, ['ip0', 'ip1'])

    def test__none(self):
        """Test get result method when no results exist."""
        results = self.runner.get_result()
        self.assertEqual(results, None)

    def test_get_result(self):
        """Test get results method when results exist."""
        inspect_result = TaskInspectionResult(source=self.source,
                                              scan_task=self.scan_task)
        inspect_result.save()
        self.inspect_results.results.add(inspect_result)
        self.inspect_results.save()
        results = self.runner.get_result()
        self.assertEqual(results, inspect_result)

    # pylint: disable=too-many-locals
    def test_get_vm_info(self):
        """Test the get vm info method."""
        data_center = 'dc1'
        cluster = 'cluster1'
        host = Mock()
        host_sum = Mock()
        host_config = Mock()
        host_config.name = 'host1'
        host_sum.config = host_config
        host_hard = Mock()
        host_hard.numCpuCores = 12
        host_hard.numCpuThreads = 24
        host_sum.hardware = host_hard
        host.summary = host_sum
        virtual_machine = Mock()
        summary = Mock()
        config = Mock()
        runtime = Mock()
        sum_guest = Mock()
        config.name = 'vm1'
        config.uuid = '1111'
        config.memorySizeMB = 1024
        config.numCpu = 2
        config.guestFullName = 'Red Hat 7'
        runtime.powerState = 'powerOn'
        sum_guest.hostName = 'hostname'
        summary.config = config
        summary.runtime = runtime
        summary.guest = sum_guest

        virtual_machine.summary = summary
        self.scan_task.update_stats('TEST_VC.',
                                    sys_count=5,
                                    sys_failed=0,
                                    sys_scanned=0)
        getnics = (['00:50:56:9e:09:8c'], ['1.2.3.4'])
        inspect_result = TaskInspectionResult(source=self.scan_task.source,
                                              scan_task=self.scan_task)
        inspect_result.save()
        self.inspect_results.results.add(inspect_result)
        self.inspect_results.save()
        with patch('scanner.vcenter.inspect.get_nics', return_value=getnics):
            self.runner.inspect_result = inspect_result
            self.runner.get_vm_info(data_center, cluster, host,
                                    virtual_machine)

            inspect_result = TaskInspectionResult.objects.filter(
                scan_task=self.scan_task.id).first()
            sys_results = inspect_result.systems.all()
            expected_facts = {
                'vm.cluster': 'cluster1',
                'vm.cpu_count': 2,
                'vm.datacenter': 'dc1',
                'vm.dns_name': 'hostname',
                'vm.host.cpu_cores': 12,
                'vm.host.cpu_count': 2,
                'vm.host.cpu_threads': 24,
                'vm.host.name': 'host1',
                'vm.ip_addresses': ['1.2.3.4'],
                'vm.mac_addresses': ['00:50:56:9e:09:8c'],
                'vm.memory_size': 1,
                'vm.name': 'vm1',
                'vm.os': 'Red Hat 7',
                'vm.state': 'powerOn',
                'vm.uuid': '1111'
            }
            sys_fact = {}
            for raw_fact in sys_results.first().facts.all():
                # Must read as JSON as this is what task.py does
                sys_fact[raw_fact.name] = json.loads(raw_fact.value)

            self.assertEqual(1, len(sys_results))
            self.assertEqual('vm1', sys_results.first().name)
            self.assertEqual(expected_facts, sys_fact)

    # pylint: disable=too-many-locals
    def test_recurse_datacenter(self):
        """Test the recurse_datacenter method."""
        inspect_result = TaskInspectionResult(source=self.scan_task.source,
                                              scan_task=self.scan_task)
        inspect_result.save()
        sys_result = SystemInspectionResult(
            name='vm1', status=SystemInspectionResult.SUCCESS)
        sys_result.save()
        inspect_result.systems.add(sys_result)
        inspect_result.save()
        self.inspect_results.results.add(inspect_result)
        self.inspect_results.save()
        vcenter = Mock()
        content = Mock()
        root_folder = Mock()
        child_entity = []
        for k in range(0, 2):
            child = Mock()
            child.name = 'dc' + str(k)
            host_folder = Mock()
            clusters = []
            for j in range(0, 1):
                cluster = Mock()
                cluster.name = 'cluster' + str(j)
                host = Mock()
                h_summary = Mock(name='h_summary')
                h_config = Mock(name='h_config')
                h_config.name = 'host1'
                h_summary.config = h_config
                host.summary = h_summary
                virtual_machine = Mock(name='vm')
                virtual_machine.summary.config.name = 'host1'
                host.vm = [virtual_machine]
                hosts = [host]
                cluster.host = hosts
                clusters.append(cluster)
            host_folder.childEntity = clusters
            child.hostFolder = host_folder
            child_entity.append(child)
        root_folder.childEntity = child_entity
        content.rootFolder = root_folder
        vcenter.RetrieveContent = Mock(return_value=content)
        with patch.object(InspectTaskRunner,
                          'get_vm_info') as mock_get_vm_info:
            self.runner.inspect_result = inspect_result
            self.runner.recurse_datacenter(vcenter)
            mock_get_vm_info.assert_called_with(ANY, ANY, ANY, ANY)

    def test_inspect(self):
        """Test the inspect method."""
        with patch('scanner.vcenter.inspect.vcenter_connect',
                   return_value=Mock()) as mock_vcenter_connect:
            with patch.object(InspectTaskRunner,
                              'recurse_datacenter') as mock_recurse:
                self.runner.connect_scan_task = self.conn_task
                self.runner.inspect()
                mock_vcenter_connect.assert_called_once_with(ANY)
                mock_recurse.assert_called_once_with(ANY)

    def test_failed_run(self):
        """Test the run method."""
        with patch.object(InspectTaskRunner,
                          'inspect',
                          side_effect=invalid_login) as mock_connect:
            status = self.runner.run()
            self.assertEqual(ScanTask.FAILED, status[1])
            mock_connect.assert_called_once_with()

    def test_prereq_failed(self):
        """Test the run method."""
        self.conn_task.status = ScanTask.FAILED
        self.conn_task.save()
        status = self.runner.run()
        self.assertEqual(ScanTask.FAILED, status[1])

    def test_run(self):
        """Test the run method."""
        with patch.object(InspectTaskRunner, 'inspect') as mock_connect:
            status = self.runner.run()
            self.assertEqual(ScanTask.COMPLETED, status[1])
            mock_connect.assert_called_once_with()
class TestConnectResultCallback(TestCase):
    """Test ConnectResultCallback."""
    def setUp(self):
        """Set up required for tests."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               ssh_keyfile='keyfile',
                               become_method='sudo',
                               become_user='******',
                               become_password='******')
        self.cred.save()

        self.source = Source(name='source1',
                             hosts='["1.2.3.4", "1.2.3.5", "1.2.3.6"]',
                             source_type='network',
                             port=22)
        self.source.save()
        self.source.credentials.add(self.cred)
        self.source.save()

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_CONNECT)
        self.interrupt = Mock(value=ScanJob.JOB_RUN)

    def test_task_on_ok(self):
        """Test the callback on ok."""
        results_store = ConnectResultStore(self.scan_task)
        self.interrupt.return_value.value = ScanJob.JOB_RUN
        callback = ConnectResultCallback(results_store, self.cred, self.source,
                                         self.interrupt)
        events = []
        events.append(build_event(host='1.2.3.4', event='runner_on_ok'))
        events.append(
            build_event(host='1.2.3.5', return_code=1, event='runner_on_ok'))
        events.append(
            build_event(host='1.2.3.6', return_code=None,
                        event='runner_on_ok'))
        for event in events:
            callback.event_callback(event)
        self.assertEqual(callback.result_store.scan_task.systems_count, 3)
        self.assertEqual(callback.result_store.scan_task.systems_scanned, 1)
        self.assertEqual(callback.result_store.scan_task.systems_failed, 0)

    def test_task_on_failed(self):
        """Test the callback on failed."""
        results_store = ConnectResultStore(self.scan_task)
        callback = ConnectResultCallback(results_store, self.cred, self.source,
                                         self.interrupt)
        events = []
        events.append(build_event(host='1.2.3.4', event='runner_on_failed'))
        events.append(
            build_event(host='1.2.3.5',
                        event='runner_on_failed',
                        stderr='permission denied'))
        for event in events:
            callback.event_callback(event)
        self.assertEqual(callback.result_store.scan_task.systems_failed, 0)
        self.assertEqual(callback.result_store.scan_task.systems_count, 3)

    def test_task_on_unreachable(self):
        """Test the callback on unreachable."""
        results_store = ConnectResultStore(self.scan_task)
        callback = ConnectResultCallback(results_store, self.cred, self.source,
                                         self.interrupt)
        events = []
        events.append(
            build_event(host='1.2.3.4', event='runner_on_unreachable'))
        events.append(
            build_event(host='1.2.3.5',
                        event='runner_on_unreachable',
                        msg='permission denied'))
        for event in events:
            callback.event_callback(event)
        self.assertEqual(callback.result_store.scan_task.systems_failed, 0)
        self.assertEqual(callback.result_store.scan_task.systems_unreachable,
                         1)
        self.assertEqual(callback.result_store.scan_task.systems_count, 3)

    def test_exceptions_for_tasks(self):
        """Test exception for each task."""
        results_store = None
        callback = ConnectResultCallback(results_store, self.cred, self.source,
                                         self.interrupt)
        events = []
        events.append(build_event(host='1.2.3.4', event='runner_on_ok'))
        events.append(build_event(host='1.2.3.4', event='runner_on_failed'))
        events.append(
            build_event(host='1.2.3.4', event='runner_on_unreachable'))
        for event in events:
            with self.assertRaises(Exception):
                callback.event_callback(event)

    def test_unknown_event_response(self):
        """Test unknown event response."""
        results_store = ConnectResultStore(self.scan_task)
        callback = ConnectResultCallback(results_store, self.cred, self.source,
                                         self.interrupt)
        event = build_event(host='1.2.3.4', event='runner_on_unknown_event')
        callback.event_callback(event)

    def test_empty_host(self):
        """Test unknown event response."""
        results_store = ConnectResultStore(self.scan_task)
        callback = ConnectResultCallback(results_store, self.cred, self.source,
                                         self.interrupt)
        event = build_event(host=None, event='runner_on_ok')
        callback.event_callback(event)

    def test_cancel_event(self):
        """Test cancel event response."""
        # Test continue state
        results_store = ConnectResultStore(self.scan_task)
        callback = ConnectResultCallback(results_store, self.cred, self.source,
                                         self.interrupt)
        result = callback.cancel_callback()
        self.assertEqual(result, False)
        # Test cancel state
        for stop_value in STOP_STATES.values():
            self.interrupt = Mock(value=stop_value)
            callback = ConnectResultCallback(results_store, self.cred,
                                             self.source, self.interrupt)
            self.assertEqual(callback.interrupt.value, stop_value)
            result = callback.cancel_callback()
            self.assertEqual(result, True)
class NetworkConnectTaskRunnerTest(TestCase):
    """Tests against the ConnectTaskRunner class and functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               ssh_keyfile='keyfile',
                               become_method='sudo',
                               become_user='******',
                               become_password='******')
        self.cred.save()

        # Source with excluded hosts
        self.source = Source(name='source1',
                             hosts='["1.2.3.4", "1.2.3.5"]',
                             exclude_hosts='["1.2.3.5", "1.2.3.6"]',
                             source_type='network',
                             port=22)
        self.source.save()
        self.source.credentials.add(self.cred)
        self.source.save()

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_CONNECT)

        self.scan_task.update_stats('TEST NETWORK CONNECT.', sys_failed=0)

        # Source without excluded hosts
        self.source2 = Source(name='source2',
                              hosts='["1.2.3.4"]',
                              source_type='network',
                              port=22)
        self.source2.save()
        self.source2.credentials.add(self.cred)
        self.source2.save()

        self.scan_job2, self.scan_task2 = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_CONNECT, 'source2')

        self.scan_task2.update_stats('TEST NETWORK CONNECT.', sys_failed=0)

    def test_construct_vars(self):
        """Test constructing ansible vars dictionary."""
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        vars_dict = _construct_vars(22, cred)
        expected = {
            'ansible_become_pass': '******',
            'ansible_port': 22,
            'ansible_ssh_pass': '******',
            'ansible_ssh_private_key_file': 'keyfile',
            'ansible_user': '******',
            'ansible_become_method': 'sudo',
            'ansible_become_user': '******'
        }
        self.assertEqual(vars_dict, expected)

    def test_get_exclude_host(self):
        """Test get_exclude_hosts() method."""
        assert self.source.get_exclude_hosts() != []
        assert self.source2.get_exclude_hosts() == []

    # Tests for source1 (has hosts and excluded host)
    def test_result_store(self):
        """Test ConnectResultStore."""
        result_store = ConnectResultStore(self.scan_task)

        self.assertEqual(result_store.remaining_hosts(), ['1.2.3.4'])
        self.assertEqual(result_store.scan_task.systems_count, 1)
        self.assertEqual(result_store.scan_task.systems_scanned, 0)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

        result_store.record_result('1.2.3.4', self.source, self.cred,
                                   SystemConnectionResult.SUCCESS)

        self.assertEqual(result_store.remaining_hosts(), [])
        self.assertEqual(result_store.scan_task.systems_count, 1)
        self.assertEqual(result_store.scan_task.systems_scanned, 1)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

    def test_connect_inventory(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        path = '/path/to/executable.py'
        ssh_timeout = '0.1s'
        ssh_args = ['--executable=' + path, '--timeout=' + ssh_timeout, 'ssh']
        _, inventory_dict = _construct_connect_inventory(hosts,
                                                         cred,
                                                         connection_port,
                                                         1,
                                                         exclude_hosts,
                                                         ssh_executable=path,
                                                         ssh_args=ssh_args)
        # pylint: disable=line-too-long
        expected = {
            'all': {
                'children': {
                    'group_0': {
                        'hosts': {
                            '1.2.3.4': {
                                'ansible_host':
                                '1.2.3.4',
                                'ansible_ssh_executable':
                                '/path/to/executable.py',
                                'ansible_ssh_common_args':
                                '--executable=/path/to/executable.py --timeout=0.1s ssh'
                            }
                        }
                    }
                },  # noqa
                'vars': {
                    'ansible_port': 22,
                    'ansible_user': '******',
                    'ansible_ssh_pass': '******',
                    'ansible_ssh_private_key_file': 'keyfile',
                    'ansible_become_pass': '******',
                    'ansible_become_method': 'sudo',
                    'ansible_become_user': '******'
                }
            }
        }
        self.assertEqual(inventory_dict, expected)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_failed)
    @patch('scanner.network.connect._handle_ssh_passphrase',
           side_effect=mock_handle_ssh)
    def test_connect_failure(self, mock_run, mock_ssh_pass):
        """Test connect flow with mocked manager and failure."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        with self.assertRaises(AnsibleError):
            _connect(Value('i', ScanJob.JOB_RUN), self.scan_task, hosts,
                     Mock(), self.cred, connection_port, exclude_hosts)
            mock_run.assert_called()
            mock_ssh_pass.assert_called()

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_success)
    def test_connect(self, mock_run):
        """Test connect flow with mocked manager."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        _connect(Value('i', ScanJob.JOB_RUN), self.scan_task, hosts, Mock(),
                 self.cred, connection_port, exclude_hosts)
        mock_run.assert_called_with(ANY)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_success)
    def test_connect_ssh_crash(self, mock_run):
        """Simulate an ssh crash."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__),
                         '../../../test_util/crash.py'))
        _connect(Value('i', ScanJob.JOB_RUN),
                 self.scan_task,
                 hosts,
                 Mock(),
                 self.cred,
                 connection_port,
                 exclude_hosts,
                 base_ssh_executable=path)
        mock_run.assert_called_with(ANY)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_success)
    def test_connect_ssh_hang(self, mock_run):
        """Simulate an ssh hang."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        exclude_hosts = source['exclude_hosts']
        connection_port = source['port']
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__),
                         '../../../test_util/hang.py'))
        _connect(Value('i', ScanJob.JOB_RUN),
                 self.scan_task,
                 hosts,
                 Mock(),
                 self.cred,
                 connection_port,
                 exclude_hosts,
                 base_ssh_executable=path,
                 ssh_timeout='0.1s')
        mock_run.assert_called_with(ANY)

    @patch('scanner.network.connect._connect')
    def test_connect_runner(self, mock_connect):
        """Test running a connect scan with mocked connection."""
        scanner = ConnectTaskRunner(self.scan_job, self.scan_task)
        result_store = MockResultStore(['1.2.3.4'])
        conn_dict = scanner.run_with_result_store(Value('i', ScanJob.JOB_RUN),
                                                  result_store)
        mock_connect.assert_called_with(ANY,
                                        self.scan_task,
                                        ANY,
                                        ANY,
                                        ANY,
                                        22,
                                        False,
                                        forks=50)
        self.assertEqual(conn_dict[1], ScanTask.COMPLETED)

    # Similar tests as above modified for source2 (Does not have exclude hosts)
    def test_result_store_src2(self):
        """Test ConnectResultStore."""
        result_store = ConnectResultStore(self.scan_task2)

        self.assertEqual(result_store.remaining_hosts(), ['1.2.3.4'])
        self.assertEqual(result_store.scan_task.systems_count, 1)
        self.assertEqual(result_store.scan_task.systems_scanned, 0)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

        result_store.record_result('1.2.3.4', self.source2, self.cred,
                                   SystemConnectionResult.SUCCESS)

        self.assertEqual(result_store.remaining_hosts(), [])
        self.assertEqual(result_store.scan_task.systems_count, 1)
        self.assertEqual(result_store.scan_task.systems_scanned, 1)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

    def test_connect_inventory_src2(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        _, inventory_dict = _construct_connect_inventory(
            hosts, cred, connection_port, 1)
        expected = {
            'all': {
                'children': {
                    'group_0': {
                        'hosts': {
                            '1.2.3.4': {
                                'ansible_host': '1.2.3.4'
                            }
                        }
                    }
                },
                'vars': {
                    'ansible_port': 22,
                    'ansible_user': '******',
                    'ansible_ssh_pass': '******',
                    'ansible_ssh_private_key_file': 'keyfile',
                    'ansible_become_pass': '******',
                    'ansible_become_method': 'sudo',
                    'ansible_become_user': '******'
                }
            }
        }
        self.assertEqual(inventory_dict, expected)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_failed)
    @patch('scanner.network.connect._handle_ssh_passphrase',
           side_effect=mock_handle_ssh)
    def test_connect_failure_src2(self, mock_run, mock_ssh_pass):
        """Test connect flow with mocked manager and failure."""
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        with self.assertRaises(AnsibleError):
            _connect(Value('i', ScanJob.JOB_RUN), self.scan_task, hosts,
                     Mock(), self.cred, connection_port)
            mock_run.assert_called()
            mock_ssh_pass.assert_called()

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_success)
    def test_connect_src2(self, mock_run):
        """Test connect flow with mocked manager."""
        serializer = SourceSerializer(self.source2)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        _connect(Value('i', ScanJob.JOB_RUN), self.scan_task, hosts, Mock(),
                 self.cred, connection_port)
        mock_run.assert_called_with(ANY)

    @patch('scanner.network.connect._connect')
    def test_connect_runner_src2(self, mock_connect):
        """Test running a connect scan with mocked connection."""
        scanner = ConnectTaskRunner(self.scan_job2, self.scan_task2)
        result_store = MockResultStore(['1.2.3.4'])
        conn_dict = scanner.run_with_result_store(Value('i', ScanJob.JOB_RUN),
                                                  result_store)
        mock_connect.assert_called_with(ANY,
                                        self.scan_task2,
                                        ANY,
                                        ANY,
                                        ANY,
                                        22,
                                        False,
                                        forks=50)
        self.assertEqual(conn_dict[1], ScanTask.COMPLETED)
Example #20
0
class InspectTaskRunnerTest(TestCase):
    """Tests against the InspectTaskRunner class and functions."""

    runner = None

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               sudo_password=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=22)
        self.source.save()
        self.source.credentials.add(self.cred)

        self.host = HostRange(host_range='1.2.3.4', source_id=self.source.id)
        self.host.save()

        self.source.hosts.add(self.host)

        self.scan_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_INSPECT,
                                  source=self.source,
                                  sequence_number=2)
        self.scan_task.save()

        self.conn_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT,
                                  source=self.source,
                                  sequence_number=1)
        self.conn_task.systems_count = 5
        self.conn_task.status = ScanTask.COMPLETED
        self.conn_task.save()
        self.scan_task.prerequisites.add(self.conn_task)
        self.scan_task.save()

        self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        self.scan_job.save()
        self.scan_job.tasks.add(self.scan_task)
        self.inspect_results = InspectionResults(scan_job=self.scan_job)
        self.inspect_results.save()
        self.runner = InspectTaskRunner(scan_job=self.scan_job,
                                        scan_task=self.scan_task,
                                        inspect_results=self.inspect_results)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_get_nics(self):
        """Test the get_nics method."""
        guest = Mock()
        nics = []
        for k in range(0, 2):
            nic = Mock()
            network = Mock()
            nic.network = network
            nic.macAddress = 'mac' + str(k)
            ip_config = Mock()
            ip_addr = Mock()
            ip_addr.ipAddress = 'ip' + str(k)
            addresses = [ip_addr]
            ip_config.ipAddress = addresses
            nic.ipConfig = ip_config
            nics.append(nic)
        guest.net = nics
        mac_addresses, ip_addresses = get_nics(guest)
        self.assertEqual(mac_addresses, ['mac0', 'mac1'])
        self.assertEqual(ip_addresses, ['ip0', 'ip1'])

    def test_vmsummary(self):
        """Test the vmsummary method."""
        summary = Mock()
        guest = Mock()
        config = Mock()
        runtime = Mock()
        sum_guest = Mock()
        config.uuid = '1111'
        config.memorySizeMB = 1024
        config.numCpu = 2
        config.guestFullName = 'Red Hat 7'
        runtime.powerState = 'powerOn'
        sum_guest.hostName = 'hostname'
        summary.config = config
        summary.runtime = runtime
        summary.guest = sum_guest
        with patch('scanner.vcenter.inspect.get_nics',
                   return_value=(['mac1'], ['ip1'])) as mock_get_nics:
            expected = {
                'cpu': '2',
                'hostname': 'hostname',
                'ip_address': 'ip1',
                'mac': 'mac1',
                'mem': '1.0',
                'ostype': 'Red Hat 7',
                'state': 'powerOn',
                'uuid': '1111'
            }
            vm_summary = vmsummary(summary, guest)
            mock_get_nics.assert_called_once_with(ANY)
            self.assertEqual(vm_summary, expected)

    def test_get_results_none(self):
        """Test get results method when no results exist."""
        results = self.runner.get_results()
        self.assertEqual(results, None)

    def test_get_results(self):
        """Test get results method when results exist."""
        inspect_result = InspectionResult(source=self.source,
                                          scan_task=self.scan_task)
        inspect_result.save()
        self.inspect_results.results.add(inspect_result)
        self.inspect_results.save()
        results = self.runner.get_results()
        self.assertEqual(results, inspect_result)

    def test_get_vm_info(self):
        """Test the get vm info method."""
        data_center = 'dc1'
        cluster = 'cluster1'
        host = 'host1'
        virtual_machine = Mock()
        summary = Mock()
        config = Mock()
        config.name = 'vm1'
        summary.config = config
        virtual_machine.summary = summary
        vm_summary = {
            'cpu': '2',
            'hostname': 'hostname',
            'ip_address': 'ip1',
            'mac': 'mac1',
            'mem': '1.0',
            'ostype': 'Red Hat 7',
            'state': 'powerOn',
            'uuid': '1111'
        }
        with patch('scanner.vcenter.inspect.vmsummary',
                   return_value=vm_summary):
            self.scan_task.systems_count = 5
            self.scan_task.systems_failed = 0
            self.scan_task.systems_scanned = 0
            self.scan_task.save()
            self.runner.get_vm_info(data_center, cluster, host,
                                    virtual_machine)

    # pylint: disable=too-many-locals
    def test_recurse_datacenter(self):
        """Test the recurse_datacenter method."""
        vcenter = Mock()
        content = Mock()
        root_folder = Mock()
        child_entity = []
        for k in range(0, 2):
            child = Mock()
            child.name = 'dc' + str(k)
            host_folder = Mock()
            clusters = []
            for j in range(0, 1):
                cluster = Mock()
                cluster.name = 'cluster' + str(j)
                host = Mock()
                h_summary = Mock()
                h_config = Mock()
                h_config.name = 'host1'
                h_summary.config = h_config
                host.summary = h_summary
                host.vm = [Mock()]
                hosts = [host]
                cluster.host = hosts
                clusters.append(cluster)
            host_folder.childEntity = clusters
            child.hostFolder = host_folder
            child_entity.append(child)
        root_folder.childEntity = child_entity
        content.rootFolder = root_folder
        vcenter.RetrieveContent = Mock(return_value=content)
        with patch.object(InspectTaskRunner,
                          'get_vm_info') as mock_get_vm_info:
            self.runner.recurse_datacenter(vcenter)
            mock_get_vm_info.assert_called_with(ANY, ANY, ANY, ANY)

    def test_inspect(self):
        """Test the inspect method."""
        with patch('scanner.vcenter.inspect.vcenter_connect',
                   return_value=Mock()) as mock_vcenter_connect:
            with patch.object(InspectTaskRunner,
                              'recurse_datacenter') as mock_recurse:
                self.runner.connect_scan_task = self.conn_task
                self.runner.inspect()
                mock_vcenter_connect.assert_called_once_with(ANY)
                mock_recurse.assert_called_once_with(ANY)

    def test_failed_run(self):
        """Test the run method."""
        with patch.object(InspectTaskRunner,
                          'inspect',
                          side_effect=invalid_login) as mock_connect:
            status = self.runner.run()
            self.assertEqual(ScanTask.FAILED, status)
            mock_connect.assert_called_once_with()

    def test_prereq_failed(self):
        """Test the run method."""
        self.conn_task.status = ScanTask.FAILED
        self.conn_task.save()
        status = self.runner.run()
        self.assertEqual(ScanTask.FAILED, status)

    def test_run(self):
        """Test the run method."""
        with patch.object(InspectTaskRunner, 'inspect') as mock_connect:
            status = self.runner.run()
            self.assertEqual(ScanTask.COMPLETED, status)
            mock_connect.assert_called_once_with()
class NetworkConnectTaskRunnerTest(TestCase):
    """Tests against the ConnectTaskRunner class and functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               ssh_keyfile='keyfile',
                               become_method='sudo',
                               become_user='******',
                               become_password='******')
        self.cred.save()

        self.source = Source(name='source1', port=22)
        self.source.save()
        self.source.credentials.add(self.cred)

        self.source.hosts = '["1.2.3.4"]'
        self.source.save()

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_CONNECT)

        self.scan_task.update_stats('TEST NETWORK CONNECT.', sys_failed=0)

    def test_construct_vars(self):
        """Test constructing ansible vars dictionary."""
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        vars_dict = _construct_vars(22, cred)
        expected = {
            'ansible_become_pass': '******',
            'ansible_port': 22,
            'ansible_ssh_pass': '******',
            'ansible_ssh_private_key_file': 'keyfile',
            'ansible_user': '******',
            'ansible_become_method': 'sudo',
            'ansible_become_user': '******'
        }
        self.assertEqual(vars_dict, expected)

    def test_result_store(self):
        """Test ConnectResultStore."""
        result_store = ConnectResultStore(self.scan_task)

        self.assertEqual(result_store.remaining_hosts(), ['1.2.3.4'])
        self.assertEqual(result_store.scan_task.systems_count, 1)
        self.assertEqual(result_store.scan_task.systems_scanned, 0)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

        result_store.record_result('1.2.3.4', self.source, self.cred,
                                   SystemConnectionResult.SUCCESS)

        self.assertEqual(result_store.remaining_hosts(), [])
        self.assertEqual(result_store.scan_task.systems_count, 1)
        self.assertEqual(result_store.scan_task.systems_scanned, 1)
        self.assertEqual(result_store.scan_task.systems_failed, 0)

    def test_connect_inventory(self):
        """Test construct ansible inventory dictionary."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        inventory_dict = construct_connect_inventory(hosts, cred,
                                                     connection_port)
        expected = {
            'all': {
                'hosts': {
                    '1.2.3.4': None
                },
                'vars': {
                    'ansible_become_pass': '******',
                    'ansible_port': 22,
                    'ansible_ssh_pass': '******',
                    'ansible_ssh_private_key_file': 'keyfile',
                    'ansible_user': '******',
                    'ansible_become_method': 'sudo',
                    'ansible_become_user': '******'
                }
            }
        }
        self.assertEqual(inventory_dict, expected)

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_failed)
    @patch('scanner.network.connect._handle_ssh_passphrase',
           side_effect=mock_handle_ssh)
    def test_connect_failure(self, mock_run, mock_ssh_pass):
        """Test connect flow with mocked manager and failure."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        with self.assertRaises(AnsibleError):
            connect(hosts, Mock(), cred, connection_port)
            mock_run.assert_called()
            mock_ssh_pass.assert_called()

    @patch('scanner.network.utils.TaskQueueManager.run',
           side_effect=mock_run_success)
    def test_connect(self, mock_run):
        """Test connect flow with mocked manager."""
        serializer = SourceSerializer(self.source)
        source = serializer.data
        hosts = source['hosts']
        connection_port = source['port']
        hc_serializer = CredentialSerializer(self.cred)
        cred = hc_serializer.data
        connect(hosts, Mock(), cred, connection_port)
        mock_run.assert_called_with(ANY)

    @patch('scanner.network.connect.connect')
    def test_connect_runner(self, mock_connect):
        """Test running a connect scan with mocked connection."""
        scanner = ConnectTaskRunner(self.scan_job, self.scan_task)
        result_store = MockResultStore(['1.2.3.4'])
        conn_dict = scanner.run_with_result_store(result_store)
        mock_connect.assert_called_with(ANY, ANY, ANY, 22, forks=50)
        self.assertEqual(conn_dict[1], ScanTask.COMPLETED)
Example #22
0
class InspectTaskRunnerTest(TestCase):
    """Tests Satellite connect capabilities."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               cred_type=Credential.SATELLITE_CRED_TYPE,
                               username='******',
                               password='******')
        self.cred.save()

        self.source = Source(name='source1', port=443, hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def create_scan_job(self):
        """Create scan job for tests."""
        scan_job, inspect_task = create_scan_job(self.source,
                                                 ScanTask.SCAN_TYPE_INSPECT)

        inspect_task.update_stats('TEST_SAT.', sys_scanned=0)
        return scan_job, inspect_task

    def test_run_failed_prereq(self):
        """Test the running connect task with no source options."""
        scan_job, inspect_task = self.create_scan_job()
        connect_task = inspect_task.prerequisites.first()
        connect_task.status = ScanTask.FAILED
        connect_task.save()
        task = InspectTaskRunner(scan_job, inspect_task)
        status = task.run(Value('i', ScanJob.JOB_RUN))

        self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat5_bad_status(self):
        """Test the running connect task for Satellite 5."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)
        with patch('scanner.satellite.connect.utils.status',
                   return_value=(401, None,
                                 SATELLITE_VERSION_5)) as mock_sat_status:
            status = task.run(Value('i', ScanJob.JOB_RUN))
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat6_bad_status(self):
        """Test the running connect task for Sat 6 with bad status."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(401, None,
                                 SATELLITE_VERSION_6)) as mock_sat_status:
            status = task.run(Value('i', ScanJob.JOB_RUN))
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat6_bad_api_version(self):
        """Test the running connect task for Sat6 with bad api version."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(200, 3,
                                 SATELLITE_VERSION_6)) as mock_sat_status:
            status = task.run(Value('i', ScanJob.JOB_RUN))
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_conn_err(self):
        """Test the running connect task with connection error."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_conn_exception) as mock_sat_status:
            status = task.run(Value('i', ScanJob.JOB_RUN))
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_auth_err(self):
        """Test the running connect task with satellite auth error."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_sat_auth_exception) as mock_sat_status:
            status = task.run(Value('i', ScanJob.JOB_RUN))
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_sat_err(self):
        """Test the running connect task with satellite error."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_sat_exception) as mock_sat_status:
            status = task.run(Value('i', ScanJob.JOB_RUN))
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_timeout(self):
        """Test the running connect task with timeout error."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_timeout_error) as mock_sat_status:
            status = task.run(Value('i', ScanJob.JOB_RUN))
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_excep(self):
        """Test the running connect task with general exception."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_exception) as mock_sat_status:
            with self.assertRaises(Exception):
                status = task.run(Value('i', ScanJob.JOB_RUN))
                mock_sat_status.assert_called_once_with(ANY)
                self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_sat(self):
        """Test the running connect task with satellite."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(200, 2,
                                 SATELLITE_VERSION_6)) as mock_sat_status:
            with patch.object(SatelliteSixV2, 'hosts_facts') as mock_facts:
                status = task.run(Value('i', ScanJob.JOB_RUN))
                mock_sat_status.assert_called_once_with(ANY)
                mock_facts.assert_called_once_with(ANY)
                self.assertEqual(status[1], ScanTask.COMPLETED)

    def test_run_with_sat_cancel(self):
        """Test the running connect task with satellite cancelled."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        status = task.run(Value('i', ScanJob.JOB_TERMINATE_CANCEL))
        self.assertEqual(status[1], ScanTask.CANCELED)

    def test_run_with_sat_pause(self):
        """Test the running connect task with satellite paused."""
        scan_job, inspect_task = self.create_scan_job()
        task = InspectTaskRunner(scan_job, inspect_task)

        status = task.run(Value('i', ScanJob.JOB_TERMINATE_PAUSE))
        self.assertEqual(status[1], ScanTask.PAUSED)
Example #23
0
class TestProcess(TestCase):
    """Test the process() infrastructure."""

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(
            name='cred1',
            username='******',
            password='******',
            ssh_keyfile='keyfile',
            become_method='sudo',
            become_user='******',
            become_password='******')
        self.cred.save()

        self.source = Source(
            name='source1',
            port=22)
        self.source.save()
        self.source.credentials.add(self.cred)

        self.source.hosts = '["1.2.3.4"]'
        self.source.save()

        self.scan_task = ScanTask(
            source=self.source, scan_type=ScanTask.SCAN_TYPE_INSPECT)
        self.scan_task.save()

    def test_not_result_no_processing(self):
        """Test a value that is not a task result, and needs no processing."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            NOT_TASK_RESULT_KEY, 'foo',
                            HOST), 'foo')

    def test_not_result_sudo_error(self):
        """Test a value that is not a task result, but is a sudo error."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            NOT_TASK_RESULT_KEY, process.SUDO_ERROR,
                            HOST), process.NO_DATA)

    def test_processing_bad_input(self):
        """Test a key that is not a task result, but needs processing."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            TEST_KEY, 'foo', HOST),
            process.NO_DATA)

    def test_no_processing(self):
        """Test a key that doesn't need to be processed."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            NOT_A_KEY, ansible_result(process.NO_DATA),
                            HOST),
            ansible_result(process.NO_DATA))

    def test_simple_processor(self):
        """Test a key whose processor succeeds."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            TEST_KEY, ansible_result(process.NO_DATA),
                            HOST), 1)

    def test_missing_dependency(self):
        """Test a key whose processor is missing a dependency."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            DEPENDENT_KEY, ansible_result(process.NO_DATA),
                            HOST), process.NO_DATA)

    def test_satisfied_dependency(self):
        """Test a key whose processor has a dependency, which is present."""
        self.assertEqual(
            process.process(self.scan_task,
                            {DEPENDENT_KEY: ansible_result('')},
                            NO_PROCESSOR_KEY, 'result',
                            HOST),
            'result')

    def test_skipped_task(self):
        """Test a task that Ansible skipped."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            TEST_KEY, {'skipped': True},
                            HOST), process.NO_DATA)

    def test_task_errored(self):
        """Test a task that errored on the remote machine."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            TEST_KEY, ansible_result('error!', rc=1),
                            HOST),
            process.NO_DATA)

    def test_processor_errored(self):
        """Test a task where the processor itself errors."""
        self.assertEqual(
            process.process(self.scan_task, {},
                            PROCESSOR_ERROR_KEY, ansible_result(''),
                            HOST),
            process.NO_DATA)
Example #24
0
class ConnectTaskRunnerTest(TestCase):
    """Tests Satellite connect capabilities."""

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(
            name='cred1',
            cred_type=Credential.SATELLITE_CRED_TYPE,
            username='******',
            password='******',
            become_password=None,
            become_method=None,
            become_user=None,
            ssh_keyfile=None)
        self.cred.save()

        self.source = Source(
            name='source1',
            port=443,
            hosts='["1.2.3.4"]')
        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_CONNECT)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_run_sat5_bad_status(self):
        """Test the running connect task for Satellite 5."""
        task = ConnectTaskRunner(self.scan_job, self.scan_task)
        with patch('scanner.satellite.connect.utils.status',
                   return_value=(401,
                                 None,
                                 SATELLITE_VERSION_5)) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat6_bad_status(self):
        """Test the running connect task for Sat 6 with bad status."""
        task = ConnectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(401,
                                 None,
                                 SATELLITE_VERSION_6)) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat6_bad_api_version(self):
        """Test the running connect task for Sat6 with bad api version."""
        task = ConnectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(200,
                                 3,
                                 SATELLITE_VERSION_6)) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_conn_err(self):
        """Test the running connect task with connection error."""
        task = ConnectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_conn_exception) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_sat_err(self):
        """Test the running connect task with satellite error."""
        task = ConnectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_sat_exception) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_auth_err(self):
        """Test the running connect task with satellite auth error."""
        task = ConnectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_sat_auth_exception) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_timeout_err(self):
        """Test the running connect task with timeout error."""
        task = ConnectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   side_effect=mock_timeout_error) as mock_sat_status:
            status = task.run()
            mock_sat_status.assert_called_once_with(ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_sat6_v2(self):
        """Test the running connect task for Sat6 with api version 2."""
        task = ConnectTaskRunner(self.scan_job, self.scan_task)

        with patch('scanner.satellite.connect.utils.status',
                   return_value=(200,
                                 2,
                                 SATELLITE_VERSION_6)) as mock_sat_status:
            with patch.object(SatelliteSixV2, 'host_count',
                              return_value=1) as mock_host_count:
                with patch.object(SatelliteSixV2, 'hosts',
                                  return_value=['sys1']) as mock_hosts:
                    status = task.run()
                    mock_sat_status.assert_called_once_with(ANY)
                    mock_host_count.assert_called_once_with()
                    mock_hosts.assert_called_once_with()
                    self.assertEqual(status[1], ScanTask.COMPLETED)
Example #25
0
class ConnectTaskRunnerTest(TestCase):
    """Tests against the ConnectTaskRunner class and functions."""

    runner = None

    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               username='******',
                               password='******',
                               become_password=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=22, hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_CONNECT)

        # Create runner
        self.runner = ConnectTaskRunner(scan_job=self.scan_job,
                                        scan_task=self.scan_task)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_store_connect_data(self):
        """Test the connection data method."""
        vm_names = ['vm1', 'vm2']
        # pylint: disable=protected-access
        self.runner._store_connect_data(vm_names, self.cred, self.source)
        self.assertEqual(
            len(self.scan_job.connection_results.task_results.all()), 1)

    def test_get_vm_names(self):
        """Test the get vm names method."""
        children = []
        for ident in range(1, 3):
            name = 'vm' + str(ident)
            config = Mock()
            config.name = name
            summary = Mock()
            summary.config = config
            child = Mock()
            child.summary = summary
            children.append(child)
        vm_container_view = Mock(view=children)
        vm_names = get_vm_names(vm_container_view)
        self.assertTrue(isinstance(vm_names, list))
        self.assertEqual(vm_names, ['vm1', 'vm2'])

    def test_get_vm_container(self):
        """Get the VM container."""
        vcenter = Mock()
        content = Mock()
        content.rootFolder = Mock()
        view_manager = Mock()
        container_view = Mock()
        view_manager.CreateContainerView = Mock(return_value=container_view)
        content.viewManager = view_manager
        vcenter.RetrieveContent = Mock(return_value=content)
        c_view = get_vm_container(vcenter)
        self.assertEqual(c_view, container_view)

    def test_connect(self):
        """Test the VCenter connect method."""
        with patch('scanner.vcenter.connect.vcenter_connect',
                   return_value=Mock()) as mock_vcenter_connect:
            with patch('scanner.vcenter.connect.get_vm_container',
                       return_value=Mock()) as mock_get_vm_container:
                with patch('scanner.vcenter.connect.get_vm_names',
                           return_value=['vm1', 'vm2']) as mock_names:
                    vm_names = self.runner.connect()
                    self.assertEqual(vm_names, set(['vm1', 'vm2']))
                    mock_vcenter_connect.assert_called_once_with(ANY)
                    mock_get_vm_container.assert_called_once_with(ANY)
                    mock_names.assert_called_once_with(ANY)

    def test_get_result_none(self):
        """Test get result method when no results exist."""
        results = self.scan_task.get_result().systems.first()
        self.assertEqual(results, None)

    def test_get_result(self):
        """Test get result method when results exist."""
        conn_result = self.scan_task.connection_result
        results = self.scan_task.get_result()
        self.assertEqual(results, conn_result)

    def test_failed_run(self):
        """Test the run method."""
        with patch.object(ConnectTaskRunner,
                          'connect',
                          side_effect=invalid_login) as mock_connect:
            status = self.runner.run()
            self.assertEqual(ScanTask.FAILED, status[1])
            mock_connect.assert_called_once_with()

    def test_unreachable_run(self):
        """Test the run method with unreachable."""
        with patch.object(ConnectTaskRunner,
                          'connect',
                          side_effect=unreachable_host) as mock_connect:
            status = self.runner.run()
            self.assertEqual(ScanTask.FAILED, status[1])
            mock_connect.assert_called_once_with()

    def test_run(self):
        """Test the run method."""
        with patch.object(ConnectTaskRunner,
                          'connect',
                          return_value=['vm1', 'vm2']) as mock_connect:
            status = self.runner.run()
            self.assertEqual(ScanTask.COMPLETED, status[1])
            mock_connect.assert_called_once_with()
Example #26
0
class SatelliteSixV1Test(TestCase):
    """Tests Satellite 6 v1 functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               cred_type=Credential.SATELLITE_CRED_TYPE,
                               username='******',
                               password='******',
                               become_password=None,
                               become_method=None,
                               become_user=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=443, hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_INSPECT)

        self.api = SatelliteSixV1(self.scan_job, self.scan_task)
        job_conn_result = JobConnectionResult()
        job_conn_result.save()
        connection_results = TaskConnectionResult(
            job_connection_result=job_conn_result)
        connection_results.save()
        self.api.connect_scan_task.connection_result = connection_results
        self.api.connect_scan_task.connection_result.save()

        conn_result = self.api.connect_scan_task.connection_result
        sys_result = SystemConnectionResult(
            name='sys1_1',
            status=SystemInspectionResult.SUCCESS,
            task_connection_result=conn_result)
        sys_result.save()
        self.api.connect_scan_task.save()

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_get_orgs(self):
        """Test the method to get orgs."""
        orgs_url = 'https://{sat_host}:{port}/katello/api/v2/organizations'
        with requests_mock.Mocker() as mocker:
            url = construct_url(orgs_url, '1.2.3.4')
            jsonresult = {
                'results': [{
                    'id': 1
                }, {
                    'id': 7
                }, {
                    'id': 8
                }],
                'per_page': 100
            }
            mocker.get(url, status_code=200, json=jsonresult)
            orgs = self.api.get_orgs()
            orgs2 = self.api.get_orgs()
            self.assertEqual(orgs, [1, 7, 8])
            self.assertEqual(orgs, orgs2)

    def test_get_orgs_with_err(self):
        """Test the method to get orgs with err."""
        orgs_url = 'https://{sat_host}:{port}/katello/api/v2/organizations'
        with requests_mock.Mocker() as mocker:
            url = construct_url(orgs_url, '1.2.3.4')
            jsonresult = {
                'results': [{
                    'id': 1
                }, {
                    'id': 7
                }, {
                    'id': 8
                }],
                'per_page': 100
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.get_orgs()

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_host_count(self, mock_get_orgs):
        """Test the method host_count."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=200, json=jsonresult)
            systems_count = self.api.host_count()
            self.assertEqual(systems_count, 3)

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_host_count_with_err(self, mock_get_orgs):
        """Test the method host_count with err."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.host_count()

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_hosts(self, mock_get_orgs):
        """Test the method hosts."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1',
                    'id': 1
                }, {
                    'name': 'sys2',
                    'id': 2
                }, {
                    'name': 'sys3',
                    'id': 3
                }],
                'per_page':
                100,
                'total':
                3
            }
            mocker.get(url, status_code=200, json=jsonresult)
            systems_count = self.api.host_count()
            hosts = self.api.hosts()
            self.assertEqual(systems_count, 3)
            self.assertEqual(len(hosts), 3)
            self.assertEqual(hosts, ['sys1_1', 'sys2_2', 'sys3_3'])

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_hosts_with_err(self, mock_get_orgs):
        """Test the method hosts."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.hosts()

    def test_host_fields(self):
        """Test the method host_fields."""
        host_field_url = 'https://{sat_host}:{port}/api/v2/hosts/{host_id}'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=host_field_url,
                                sat_host='1.2.3.4',
                                host_id=1)
            jsonresult = {
                'architecture_id': 1,
                'architecture_name': 'x86_64',
                'operatingsystem_name': 'RedHat 7.4',
                'uuid': None,
                'created_at': '2017-12-04 13:19:57 UTC',
                'updated_at': '2017-12-04 13:21:47 UTC',
                'organization_name': 'ACME',
                'location_name': 'Raleigh',
                'name': 'mac52540071bafe.prov.lan',
                'virtual_host': {
                    'uuid': '100',
                    'name': 'vhost1'
                },
                'virtual_guests': [{
                    'name': 'foo'
                }],
                'content_facet_attributes': {
                    'id': 11,
                    'katello_agent_installed': False
                },
                'subscription_facet_attributes': {
                    'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
                    'last_checkin': '2018-01-04 17:36:07 UTC',
                    'registered_at': '2017-12-04 13:33:52 UTC',
                    'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
                    'virtual_host': {
                        'uuid': '100',
                        'name': 'vhost1'
                    },
                    'virtual_guests': [{
                        'name': 'foo'
                    }],
                },
                'facts': {
                    'memorysize_mb': '992.45',
                    'memorysize': '992.45 MB',
                    'hostname': 'fdi',
                    'type': 'Other',
                    'architecture': 'x86_64',
                    'is_virtual': 'true',
                    'virtual': 'kvm',
                    'net.interface.ipv4_address': '192.168.99.123',
                    'net.interface.mac_address': 'fe80::5054:ff:fe24:946e',
                },
            }
            mocker.get(url, status_code=200, json=jsonresult)
            host_info = host_fields(1, jsonresult)
            expected = {
                'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
                'hostname': 'mac52540071bafe.prov.lan',
                'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
                'registration_time': '2017-12-04 13:33:52 UTC',
                'last_checkin_time': '2018-01-04 17:36:07 UTC',
                'katello_agent_installed': False,
                'os_release': 'RedHat 7.4',
                'organization': 'ACME',
                'virtual_host_uuid': '100',
                'virtual_host_name': 'vhost1',
                'virt_type': None,
                'kernel_version': None,
                'architecture': None,
                'is_virtualized': None,
                'cores': None,
                'num_sockets': None,
                'num_virtual_guests': 1,
                'virtual': 'hypervisor',
                'location': 'Raleigh',
                'ip_addresses': ['192.168.99.123'],
                'mac_addresses': ['fe80::5054:ff:fe24:946e'],
                'os_name': 'RedHat',
                'os_version': '7.4'
            }
            self.assertEqual(host_info, expected)

    def test_prepare_host_s61(self):
        """Test the prepare host method for satellite 6.1."""
        url1 = \
            'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems/{host_id}'
        url2 = \
            'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems/{host_id}/subscriptions'
        expected = [(self.scan_task, {
            'job_id': self.scan_job.id,
            'task_sequence_number': self.scan_task.sequence_number,
            'scan_type': self.scan_task.scan_type,
            'source_type': self.scan_task.source.source_type,
            'source_name': self.scan_task.source.name
        }, 1, 'sys', url1, url2, {
            'host': {
                'id': 1,
                'name': 'sys'
            },
            'port': '443',
            'user': self.cred.username,
            'password': self.cred.password,
            'ssl_cert_verify': True
        })]
        host = {'id': 1, 'name': 'sys'}
        chunk = [host]
        port = '443'
        user = self.cred.username
        password = self.cred.password
        connect_data_return_value = host, port, user, password
        with patch('scanner.satellite.utils.get_connect_data',
                   return_value=connect_data_return_value) as mock_connect:
            host_params = SatelliteSixV1.prepare_host(self.api, chunk)
            self.assertEqual(expected, host_params)
            mock_connect.assert_called_once_with(ANY)

    def test_request_host_details_err(self):
        """Test request_host_details for error mark a failed system."""
        host_field_url = 'https://{sat_host}:{port}/api/v2/hosts/{host_id}'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=host_field_url,
                                sat_host='1.2.3.4',
                                host_id=1)
            mocker.get(url, status_code=500)
            result = request_host_details(
                self.scan_task, {
                    'job_id': self.scan_job.id,
                    'task_sequence_number': self.scan_task.id,
                    'scan_type': self.scan_task.scan_type,
                    'source_type': self.scan_task.source.source_type,
                    'source_name': self.scan_task.source.name
                }, 1, 'sys', url, url, {})

            expected = {
                'unique_name': 'sys_1',
                'system_inspection_result': 'failed',
                'host_fields_response': {},
                'host_subscriptions_response': {}
            }
            self.assertEqual(result, expected)
            inspect_result = self.scan_task.inspection_result
            self.assertEqual(len(inspect_result.systems.all()), 0)

    def test_post_processing(self):
        """Test process_results method with mock data."""
        fields_return_value = {
            'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
            'hostname': 'mac52540071bafe.prov.lan',
            'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
            'registration_time': '2017-12-04 13:33:52 UTC',
            'last_checkin_time': '2018-01-04 17:36:07 UTC',
            'katello_agent_installed': False,
            'os_name': 'RedHat 7.4',
            'organization': 'ACME',
            'virtual_host_uuid': '100',
            'virtual_host_name': 'vhost1',
            'virt_type': None,
            'kernel_version': None,
            'architecture': None,
            'is_virtualized': None,
            'cores': None,
            'num_sockets': None,
            'num_virtual_guests': 1,
            'virtual': 'hypervisor',
            'location': 'Raleigh',
            'ip_addresses': ['192.168.99.123'],
            'ipv6_addresses': ['fe80::5054:ff:fe24:946e']
        }
        subs_return_value = {
            'entitlements': [{
                'derived_entitlement': False,
                'name': 'Satellite Tools 6.3',
                'amount': 1,
                'account_number': None,
                'contract_number': None,
                'start_date': '2017-12-01 14:50:59 UTC',
                'end_date': '2047-11-24 14:50:59 UTC'
            }, {
                'derived_entitlement': True,
                'name': 'Employee SKU',
                'amount': 1,
                'account_number': 1212729,
                'contract_number': 10913844,
                'start_date': '2016-03-24 04:00:00 UTC',
                'end_date': '2022-01-01 04:59:59 UTC'
            }]
        }
        expected = {
            'uuid':
            '00c7a108-48ec-4a97-835c-aa3369777f64',
            'hostname':
            'mac52540071bafe.prov.lan',
            'registered_by':
            'sat-r220-07.lab.eng.rdu2.redhat.com',
            'registration_time':
            '2017-12-04 13:33:52 UTC',
            'last_checkin_time':
            '2018-01-04 17:36:07 UTC',
            'katello_agent_installed':
            False,
            'os_name':
            'RedHat 7.4',
            'organization':
            'ACME',
            'virtual_host_uuid':
            '100',
            'virtual_host_name':
            'vhost1',
            'num_virtual_guests':
            1,
            'virtual':
            'hypervisor',
            'location':
            'Raleigh',
            'ip_addresses': ['192.168.99.123'],
            'ipv6_addresses': ['fe80::5054:ff:fe24:946e'],
            'entitlements': [{
                'derived_entitlement': False,
                'name': 'Satellite Tools 6.3',
                'amount': 1,
                'account_number': None,
                'contract_number': None,
                'start_date': '2017-12-01 14:50:59 UTC',
                'end_date': '2047-11-24 14:50:59 UTC'
            }, {
                'derived_entitlement': True,
                'name': 'Employee SKU',
                'amount': 1,
                'account_number': 1212729,
                'contract_number': 10913844,
                'start_date': '2016-03-24 04:00:00 UTC',
                'end_date': '2022-01-01 04:59:59 UTC'
            }]
        }

        self.scan_task.save()
        self.scan_task.update_stats('TEST_SAT.', sys_scanned=0)
        with patch('scanner.satellite.six.host_fields',
                   return_value=fields_return_value) as mock_fields:
            with patch('scanner.satellite.six.host_subscriptions',
                       return_value=subs_return_value) as mock_subs:
                result = {
                    'unique_name': 'sys_1',
                    'system_inspection_result': SystemInspectionResult.SUCCESS,
                    'host_fields_response': fields_return_value,
                    'host_subscriptions_response': subs_return_value
                }
                process_results(self.api, [result], 1)
                inspect_results = \
                    self.scan_task.inspection_result.systems.all()
                sys_1_result = inspect_results.filter(name='sys_1').first()
                self.assertEqual(sys_1_result.name, 'sys_1')
                self.assertEqual(sys_1_result.status, 'success')
                result = {}
                for fact in sys_1_result.facts.all():
                    result[fact.name] = json.loads(fact.value)
                self.assertEqual(result, expected)
                mock_fields.assert_called_once_with(ANY, ANY)
                mock_subs.assert_called_once_with(ANY)

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_hosts_facts_with_err(self, mock_get_orgs):
        """Test the hosts_facts method."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            mocker.get(url, status_code=500)
            with self.assertRaises(SatelliteException):
                self.api.hosts_facts(Value('i', ScanJob.JOB_RUN))

    @patch('multiprocessing.pool.Pool.starmap',
           return_value=[{
               'unique_name': 'sys_1',
               'system_inspection_result': 'failed',
               'host_fields_response': {},
               'host_subscriptions_response': {}
           }])
    def test_hosts_facts(self, mock_pool):
        """Test the method hosts."""
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with patch.object(SatelliteSixV1, 'get_orgs', return_value=[1]):
            with patch('scanner.satellite.six.request_host_details',
                       return_value={}):
                with requests_mock.Mocker() as mocker:
                    url = construct_url(url=hosts_url,
                                        sat_host='1.2.3.4',
                                        org_id=1)
                    jsonresult = {
                        'results': [{
                            'uuid': '1',
                            'name': 'sys1'
                        }, {
                            'uuid': '2',
                            'name': 'sys2'
                        }, {
                            'uuid': '3',
                            'name': 'sys3'
                        }],
                        'per_page':
                        100,
                        'total':
                        3
                    }
                    mocker.get(url, status_code=200, json=jsonresult)
                    self.api.hosts_facts(Value('i', ScanJob.JOB_RUN))
                    inspect_result = self.scan_task.inspection_result
                    self.assertEqual(len(inspect_result.systems.all()), 1)
Example #27
0
class SatelliteSixV2Test(TestCase):
    """Tests Satellite 6 v2 functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               cred_type=Credential.SATELLITE_CRED_TYPE,
                               username='******',
                               password='******',
                               become_password=None,
                               become_method=None,
                               become_user=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=443, hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_INSPECT)
        self.scan_task.update_stats('TEST_SAT.', sys_scanned=0)
        self.api = SatelliteSixV2(self.scan_task)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_host_count(self):
        """Test the method host_count."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=200, json=jsonresult)
            systems_count = self.api.host_count()
            self.assertEqual(systems_count, 3)

    def test_host_count_with_err(self):
        """Test the method host_count with error."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.host_count()

    def test_hosts(self):
        """Test the method hosts."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=200, json=jsonresult)
            systems_count = self.api.host_count()
            hosts = self.api.hosts()
            self.assertEqual(systems_count, 3)
            self.assertEqual(len(hosts), 3)
            self.assertEqual(hosts, ['sys1', 'sys2', 'sys3'])

    def test_hosts_with_err(self):
        """Test the method hosts with error."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.hosts()

    def test_host_fields_with_err(self):
        """Test the method host_fields with error."""
        host_field_url = 'https://{sat_host}:{port}/api/v2/hosts/{host_id}'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=host_field_url,
                                sat_host='1.2.3.4',
                                host_id=1)
            mocker.get(url, status_code=500)
            with self.assertRaises(SatelliteException):
                host_fields(self.scan_task, 2, host_field_url, None, 1)

    def test_host_fields(self):
        """Test the method host_fields."""
        host_field_url = 'https://{sat_host}:{port}/api/v2/hosts/{host_id}'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=host_field_url,
                                sat_host='1.2.3.4',
                                host_id=1)
            jsonresult = {
                'architecture_id': 1,
                'architecture_name': 'x86_64',
                'operatingsystem_name': 'RedHat 7.4',
                'uuid': None,
                'created_at': '2017-12-04 13:19:57 UTC',
                'updated_at': '2017-12-04 13:21:47 UTC',
                'organization_name': 'ACME',
                'location_name': 'Raleigh',
                'name': 'mac52540071bafe.prov.lan',
                'virtual_host': {
                    'uuid': '100',
                    'name': 'vhost1'
                },
                'virtual_guests': [{
                    'name': 'foo'
                }],
                'content_facet_attributes': {
                    'id': 11,
                    'katello_agent_installed': False
                },
                'subscription_facet_attributes': {
                    'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
                    'last_checkin': '2018-01-04 17:36:07 UTC',
                    'registered_at': '2017-12-04 13:33:52 UTC',
                    'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
                    'virtual_host': {
                        'uuid': '100',
                        'name': 'vhost1'
                    },
                    'virtual_guests': [{
                        'name': 'foo'
                    }],
                },
                'facts': {
                    'memorysize_mb': '992.45',
                    'memorysize': '992.45 MB',
                    'hostname': 'fdi',
                    'type': 'Other',
                    'architecture': 'x86_64',
                    'is_virtual': 'true',
                    'virtual': 'kvm',
                    'net::interface::ipv4_address': '192.168.99.123',
                    'net::interface::mac_address': 'fe80::5054:ff:fe24:946e',
                },
            }
            mocker.get(url, status_code=200, json=jsonresult)
            host_info = host_fields(self.scan_task, 2, host_field_url, None, 1)
            expected = {
                'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
                'hostname': 'mac52540071bafe.prov.lan',
                'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
                'registration_time': '2017-12-04 13:33:52 UTC',
                'last_checkin_time': '2018-01-04 17:36:07 UTC',
                'katello_agent_installed': False,
                'os_release': 'RedHat 7.4',
                'organization': 'ACME',
                'virtual_host': '100',
                'virtual_host_name': 'vhost1',
                'virt_type': None,
                'kernel_version': None,
                'architecture': None,
                'is_virtualized': None,
                'cores': None,
                'num_sockets': None,
                'num_virtual_guests': 1,
                'virtual': 'hypervisor',
                'location': 'Raleigh',
                'ip_addresses': ['192.168.99.123'],
                'mac_addresses': ['fe80::5054:ff:fe24:946e'],
                'os_name': 'RedHat',
                'os_version': '7.4'
            }
            self.assertEqual(host_info, expected)

    def test_host_subs_with_err(self):
        """Test the host subscriptons method with bad status code."""
        sub_url = 'https://{sat_host}:{port}/' \
            'api/v2/hosts/{host_id}/subscriptions'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=sub_url, sat_host='1.2.3.4', host_id=1)
            mocker.get(url, status_code=500)
            with self.assertRaises(SatelliteException):
                host_subscriptions(self.scan_task, sub_url, None, 1)

    def test_host_subs_err_nojson(self):
        """Test the host subscriptons method with bad code and not json."""
        sub_url = 'https://{sat_host}:{port}/' \
            'api/v2/hosts/{host_id}/subscriptions'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=sub_url, sat_host='1.2.3.4', host_id=1)
            mocker.get(url, status_code=404, text='error message')
            subs = host_subscriptions(self.scan_task, sub_url, None, 1)
            self.assertEqual(subs, {'entitlements': []})

    def test_host_not_subscribed(self):
        """Test the host subscriptons method for not subscribed error."""
        sub_url = 'https://{sat_host}:{port}/' \
            'api/v2/hosts/{host_id}/subscriptions'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=sub_url, sat_host='1.2.3.4', host_id=1)
            err_msg = {
                'displayMessage':
                'Host has not been registered '
                'with subscription-manager',
                'errors':
                ['Host has not been registered'
                 ' with subscription-manager']
            }  # noqa
            mocker.get(url, status_code=400, json=err_msg)
            subs = host_subscriptions(self.scan_task, sub_url, None, 1)
            self.assertEqual(subs, {'entitlements': []})

    def test_host_subscriptons(self):
        """Test the host subscriptons method."""
        sub_url = 'https://{sat_host}:{port}/' \
            'api/v2/hosts/{host_id}/subscriptions'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=sub_url, sat_host='1.2.3.4', host_id=1)
            jsonresult = {
                'results': [{
                    'amount': 1,
                    'name': 'Satellite Tools 6.3',
                    'start_date': '2017-12-01 14:50:59 UTC',
                    'end_date': '2047-11-24 14:50:59 UTC',
                    'product_name': 'Satellite Tools 6.3',
                }, {
                    'quantity_consumed': 1,
                    'name': 'Employee SKU',
                    'start_date': '2016-03-24 04:00:00 UTC',
                    'end_date': '2022-01-01 04:59:59 UTC',
                    'account_number': 1212729,
                    'contract_number': 10913844,
                    'type': 'ENTITLEMENT_DERIVED',
                    'product_name': 'Employee SKU',
                }]
            }
            mocker.get(url, status_code=200, json=jsonresult)
            subs = host_subscriptions(self.scan_task, sub_url, None, 1)
            expected = {
                'entitlements': [{
                    'derived_entitlement': False,
                    'name': 'Satellite Tools 6.3',
                    'amount': 1,
                    'account_number': None,
                    'contract_number': None,
                    'start_date': '2017-12-01 14:50:59 UTC',
                    'end_date': '2047-11-24 14:50:59 UTC'
                }, {
                    'derived_entitlement': True,
                    'name': 'Employee SKU',
                    'amount': 1,
                    'account_number': 1212729,
                    'contract_number': 10913844,
                    'start_date': '2016-03-24 04:00:00 UTC',
                    'end_date': '2022-01-01 04:59:59 UTC'
                }]
            }
            self.assertEqual(subs, expected)

    def test_host_details_err(self):
        """Test host_details method for error mark a failed system."""
        with patch('scanner.satellite.six.host_fields',
                   side_effect=mock_sat_exception) as mock_fields:
            detail = self.api.host_details(1, 'sys1')
            inspect_result = self.scan_task.inspection_result
            self.assertEqual(len(inspect_result.systems.all()), 1)
            sys_result = inspect_result.systems.all().first()
            self.assertEqual(sys_result.status, SystemInspectionResult.FAILED)
            self.assertEqual(detail, {})
            mock_fields.assert_called_once_with(ANY, ANY, ANY, ANY, ANY)

    def test_host_details(self):
        """Test host_details method with mock data."""
        fields_return_value = {
            'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
            'hostname': 'mac52540071bafe.prov.lan',
            'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
            'registration_time': '2017-12-04 13:33:52 UTC',
            'last_checkin_time': '2018-01-04 17:36:07 UTC',
            'katello_agent_installed': False,
            'os_name': 'RedHat 7.4',
            'organization': 'ACME',
            'virtual_host': '100',
            'virtual_host_name': 'vhost1',
            'virt_type': None,
            'kernel_version': None,
            'architecture': None,
            'is_virtualized': None,
            'cores': None,
            'num_sockets': None,
            'num_virtual_guests': 1,
            'virtual': 'hypervisor',
            'location': 'Raleigh',
            'ip_addresses': ['192.168.99.123'],
            'ipv6_addresses': ['fe80::5054:ff:fe24:946e']
        }
        subs_return_value = {
            'entitlements': [{
                'derived_entitlement': False,
                'name': 'Satellite Tools 6.3',
                'amount': 1,
                'account_number': None,
                'contract_number': None,
                'start_date': '2017-12-01 14:50:59 UTC',
                'end_date': '2047-11-24 14:50:59 UTC'
            }, {
                'derived_entitlement': True,
                'name': 'Employee SKU',
                'amount': 1,
                'account_number': 1212729,
                'contract_number': 10913844,
                'start_date': '2016-03-24 04:00:00 UTC',
                'end_date': '2022-01-01 04:59:59 UTC'
            }]
        }
        expected = {
            'uuid':
            '00c7a108-48ec-4a97-835c-aa3369777f64',
            'hostname':
            'mac52540071bafe.prov.lan',
            'registered_by':
            'sat-r220-07.lab.eng.rdu2.redhat.com',
            'registration_time':
            '2017-12-04 13:33:52 UTC',
            'last_checkin_time':
            '2018-01-04 17:36:07 UTC',
            'katello_agent_installed':
            False,
            'os_name':
            'RedHat 7.4',
            'organization':
            'ACME',
            'virtual_host':
            '100',
            'virtual_host_name':
            'vhost1',
            'virt_type':
            None,
            'kernel_version':
            None,
            'architecture':
            None,
            'is_virtualized':
            None,
            'cores':
            None,
            'num_sockets':
            None,
            'num_virtual_guests':
            1,
            'virtual':
            'hypervisor',
            'location':
            'Raleigh',
            'ip_addresses': ['192.168.99.123'],
            'ipv6_addresses': ['fe80::5054:ff:fe24:946e'],
            'entitlements': [{
                'derived_entitlement': False,
                'name': 'Satellite Tools 6.3',
                'amount': 1,
                'account_number': None,
                'contract_number': None,
                'start_date': '2017-12-01 14:50:59 UTC',
                'end_date': '2047-11-24 14:50:59 UTC'
            }, {
                'derived_entitlement': True,
                'name': 'Employee SKU',
                'amount': 1,
                'account_number': 1212729,
                'contract_number': 10913844,
                'start_date': '2016-03-24 04:00:00 UTC',
                'end_date': '2022-01-01 04:59:59 UTC'
            }]
        }
        with patch('scanner.satellite.six.host_fields',
                   return_value=fields_return_value) as mock_fields:
            with patch('scanner.satellite.six.host_subscriptions',
                       return_value=subs_return_value) as mock_subs:
                details = self.api.host_details(host_id=1, host_name='sys1')
                self.assertEqual(details, expected)
                mock_fields.assert_called_once_with(ANY, ANY, ANY, ANY, ANY)
                mock_subs.assert_called_once_with(ANY, ANY, ANY, ANY)

    def test_host_details_skip(self):
        """Test host_details method for already captured data."""
        # pylint: disable=no-member
        sys_result = SystemInspectionResult(
            name='sys1', status=SystemInspectionResult.SUCCESS)
        sys_result.save()
        inspect_result = self.scan_task.inspection_result
        inspect_result.systems.add(sys_result)
        inspect_result.save()
        detail = self.api.host_details(1, 'sys1')
        self.assertEqual(len(inspect_result.systems.all()), 1)
        self.assertEqual(detail, {})

    def test_hosts_facts_with_err(self):
        """Test the hosts_facts method."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4')
            mocker.get(url, status_code=500)
            with self.assertRaises(SatelliteException):
                self.api.hosts_facts()

    def test_hosts_facts(self):
        """Test the hosts_facts method."""
        hosts_url = 'https://{sat_host}:{port}/api/v2/hosts'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4')
            jsonresult = {
                'total': 1,
                'subtotal': 1,
                'page': 1,
                'per_page': 100,
                'results': [{
                    'id': 10,
                    'name': 'sys10'
                }]
            }  # noqa
            mocker.get(url, status_code=200, json=jsonresult)
            detail_return_value = {}
            with patch.object(SatelliteSixV2,
                              'host_details',
                              return_value=detail_return_value) as mock_detail:
                self.api.hosts_facts()
                mock_detail.assert_called_once_with(ANY, ANY)
Example #28
0
class SatelliteFiveTest(TestCase):
    """Tests Satellite 5 functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               cred_type=Credential.SATELLITE_CRED_TYPE,
                               username='******',
                               password='******',
                               become_password=None,
                               become_method=None,
                               become_user=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=443, hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_job, self.scan_task = create_scan_job(
            self.source, ScanTask.SCAN_TYPE_INSPECT)

        self.api = SatelliteFive(self.scan_job, self.scan_task)
        connection_results = TaskConnectionResult()
        connection_results.save()
        self.api.connect_scan_task.connection_result = connection_results
        self.api.connect_scan_task.connection_result.save()

        sys_result = SystemConnectionResult(
            name='sys1_1', status=SystemInspectionResult.SUCCESS)
        sys_result.save()
        self.api.connect_scan_task.connection_result.systems.add(sys_result)
        self.api.connect_scan_task.connection_result.save()
        self.api.connect_scan_task.save()

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    @patch('xmlrpc.client.ServerProxy')
    def test_host_count(self, mock_serverproxy):
        """Test the method host_count."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.list_user_systems.return_value = ['sys1', 'sys2', 'sys3']
        systems_count = self.api.host_count()
        self.assertEqual(systems_count, 3)

    @patch('xmlrpc.client.ServerProxy')
    def test_host_count_with_err(self, mock_serverproxy):
        """Test the method host_count with error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.host_count()

    @patch('xmlrpc.client.ServerProxy')
    def test_hosts(self, mock_serverproxy):
        """Test the method hosts."""
        systems = [{
            'name': 'sys1',
            'id': 1
        }, {
            'name': 'sys2',
            'id': 2
        }, {
            'name': 'sys3',
            'id': 3
        }]
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.list_user_systems.return_value = systems
        systems_count = self.api.host_count()
        hosts = self.api.hosts()
        self.assertEqual(systems_count, 3)
        self.assertEqual(len(hosts), 3)
        self.assertEqual(hosts, ['sys1_1', 'sys2_2', 'sys3_3'])

    @patch('xmlrpc.client.ServerProxy')
    def test_hosts_with_err(self, mock_serverproxy):
        """Test the method hosts with error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.hosts()

    @patch('xmlrpc.client.ServerProxy')
    def test_host_details_virt_host(self, mock_serverproxy):
        """Test host_details method with mock data for virt host."""
        expected = {
            'uuid': 1,
            'name': 'sys1',
            'hostname': 'sys1_hostname',
            'last_checkin_time': '',
            'registration_time': 'datetime',
            'architecture': 'x86',
            'kernel_version': 'kernel',
            'cores': 2,
            'num_sockets': 2,
            'os_release': '7server',
            'entitlements': [{
                'name': 'ent1'
            }],
            'ip_addresses': ['1.2.3.4'],
            'mac_addresses': ['1:a:2:b:3:c'],
            'virtual': 'hypervisor',
            'num_virtual_guests': 3,
            'is_virtualized': False
        }
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.get_uuid.return_value = ''
        cpu = {'arch': 'x86', 'count': 2, 'socket_count': 2}
        client.system.get_cpu.return_value = cpu
        system_details = {'hostname': 'sys1_hostname', 'release': '7server'}
        client.system.get_details.return_value = system_details
        client.system.get_running_kernel.return_value = 'kernel'
        client.system.get_entitlements.return_value = ['ent1']
        net_devices = [{
            'interface': 'eth0',
            'ip': '1.2.3.4',
            'hardware_address': '1:a:2:b:3:c'
        }]
        client.system.get_network_devices.return_value = net_devices
        client.system.get_registration_date.return_value = 'datetime'
        virt = {1: {'id': 1, 'num_virtual_guests': 3}}

        logging_options = {
            'job_id': self.scan_job.id,
            'task_sequence_number': self.scan_task.sequence_number,
            'scan_type': self.scan_task.scan_type,
            'source_type': self.scan_task.source.source_type,
            'source_name': self.scan_task.source.name
        }
        raw_result = request_host_details(host_id=1,
                                          host_name='sys1',
                                          last_checkin='',
                                          scan_task=self.scan_task,
                                          request_options={},
                                          logging_options=logging_options)
        self.api.process_results([raw_result], virt, {1: 2}, [])
        inspect_results = \
            self.scan_task.inspection_result.systems.all()
        sys_1_result = inspect_results.filter(name='sys1_1').first()
        self.assertEqual(sys_1_result.name, 'sys1_1')
        self.assertEqual(sys_1_result.status, 'success')
        result = {}
        for fact in sys_1_result.facts.all():
            result[fact.name] = json.loads(fact.value)
        self.assertEqual(result, expected)

    @patch('xmlrpc.client.ServerProxy')
    def test_host_details_virt_guest(self, mock_serverproxy):
        """Test host_details method with mock data for virt guest."""
        expected = {
            'uuid': 1,
            'name': 'sys1',
            'hostname': 'sys1_hostname',
            'last_checkin_time': '',
            'registration_time': 'datetime',
            'architecture': 'x86',
            'kernel_version': 'kernel',
            'cores': 2,
            'num_sockets': 2,
            'os_release': '7server',
            'entitlements': [{
                'name': 'ent1'
            }],
            'ip_addresses': ['1.2.3.4'],
            'mac_addresses': ['1:a:2:b:3:c'],
            'is_virtualized': True,
            'virtual_host': 2,
            'virtual_host_name': 'sys2'
        }
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.get_uuid.return_value = ''
        cpu = {'arch': 'x86', 'count': 2, 'socket_count': 2}
        client.system.get_cpu.return_value = cpu
        system_details = {'hostname': 'sys1_hostname', 'release': '7server'}
        client.system.get_details.return_value = system_details
        client.system.get_running_kernel.return_value = 'kernel'
        client.system.get_entitlements.return_value = ['ent1']
        net_devices = [{
            'interface': 'eth0',
            'ip': '1.2.3.4',
            'hardware_address': '1:a:2:b:3:c'
        }]
        client.system.get_network_devices.return_value = net_devices
        client.system.get_registration_date.return_value = 'datetime'
        virt = {2: {'uuid': 2, 'name': 'sys2', 'num_virtual_guests': 3}}
        raw_result = request_host_details(host_id=1,
                                          host_name='sys1',
                                          last_checkin='',
                                          scan_task=self.scan_task,
                                          request_options={},
                                          logging_options=None)
        self.api.process_results([raw_result], virt, {1: 2}, [])
        inspect_results = \
            self.scan_task.inspection_result.systems.all()
        sys_1_result = inspect_results.filter(name='sys1_1').first()
        self.assertEqual(sys_1_result.name, 'sys1_1')
        self.assertEqual(sys_1_result.status, 'success')
        result = {}
        for fact in sys_1_result.facts.all():
            result[fact.name] = json.loads(fact.value)
        self.assertEqual(result, expected)

    def test_prepare_host_s5(self):
        """Test the prepare host method for satellite 5."""
        expected = [(1, 'sys', '', self.scan_task, {
            'host': {
                'id': 1,
                'name': 'sys',
                'last_checkin': ''
            },
            'port': '443',
            'user': self.cred.username,
            'password': self.cred.password,
            'ssl_cert_verify': True
        }, {
            'job_id': self.scan_job.id,
            'task_sequence_number': self.scan_task.sequence_number,
            'scan_type': self.scan_task.scan_type,
            'source_type': self.scan_task.source.source_type,
            'source_name': self.scan_task.source.name
        })]
        host = {'id': 1, 'name': 'sys', 'last_checkin': ''}
        chunk = [host]
        port = '443'
        user = self.cred.username
        password = self.cred.password
        connect_data_return_value = host, port, user, password
        with patch('scanner.satellite.utils.get_connect_data',
                   return_value=connect_data_return_value) as mock_connect:
            host_params = self.api.prepare_host(chunk)
            self.assertEqual(expected, host_params)
            mock_connect.assert_called_once_with(ANY)

    @patch('xmlrpc.client.ServerProxy')
    def test_host_details_with_err(self, mock_serverproxy):
        """Test the host details with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        virt = {2: {'uuid': 2, 'name': 'sys2', 'num_virtual_guests': 3}}
        raw_result = request_host_details(host_id=2,
                                          host_name='sys2',
                                          last_checkin='',
                                          scan_task=self.scan_task,
                                          request_options={},
                                          logging_options=None)

        self.api.process_results([raw_result], virt, {1: 2}, [])
        inspect_results = \
            self.scan_task.inspection_result.systems.all()
        sys_1_result = inspect_results.filter(name='sys2_2').first()
        self.assertEqual(sys_1_result.name, 'sys2_2')
        self.assertEqual(sys_1_result.status, 'failed')
        result = {}
        for fact in sys_1_result.facts.all():
            result[fact.name] = json.loads(fact.value)
        self.assertEqual(result, {})

    @patch('xmlrpc.client.ServerProxy')
    def test_virtual_guests_with_err(self, mock_serverproxy):
        """Test the virtual_guests method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.virtual_guests(1)

    @patch('xmlrpc.client.ServerProxy')
    def test_virtual_guests(self, mock_serverproxy):
        """Test the virtual_guests method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        guests = [{'id': 2}]
        client.system.list_virtual_guests.return_value = guests
        virt_guests = self.api.virtual_guests(1)
        self.assertEqual(virt_guests, ({2: 1}, 1))

    @patch('xmlrpc.client.ServerProxy')
    def test_virtual_hosts_with_err(self, mock_serverproxy):
        """Test the virtual_hosts method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.virtual_hosts()

    @patch('xmlrpc.client.ServerProxy')
    def test_virtual_hosts(self, mock_serverproxy):
        """Test the virtual_hosts method."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        guests = [{'id': 2}]
        client.system.list_virtual_guests.return_value = guests
        hosts = [{'id': 1, 'name': 'host1'}]
        client.system.list_virtual_hosts.return_value = hosts
        client.system.get_uuid.return_value = ''
        virtual_hosts, virtual_guests = self.api.virtual_hosts()
        virt_host = {
            1: {
                'id': 1,
                'name': 'host1',
                'uuid': 1,
                'num_virtual_guests': 1
            }
        }
        virt_guest = {2: 1}
        self.assertEqual(virtual_hosts, virt_host)
        self.assertEqual(virtual_guests, virt_guest)

    @patch('xmlrpc.client.ServerProxy')
    def test_physical_hosts_with_err(self, mock_serverproxy):
        """Test the phyiscal_hosts method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.physical_hosts()

    @patch('xmlrpc.client.ServerProxy')
    def test_physical_hosts(self, mock_serverproxy):
        """Test the physical_hosts method."""
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        hosts = [{'id': 1, 'name': 'host1'}]
        client.system.list_physical_systems.return_value = hosts
        phyiscal_hosts = self.api.physical_hosts()
        self.assertEqual(phyiscal_hosts, [1])

    @patch('xmlrpc.client.ServerProxy')
    def test_hosts_facts_with_err(self, mock_serverproxy):
        """Test the hosts_facts method with an error."""
        client = mock_serverproxy.return_value
        client.auth.login.side_effect = mock_xml_fault
        with self.assertRaises(SatelliteException):
            self.api.hosts_facts(Value('i', ScanJob.JOB_RUN))

    @patch('multiprocessing.pool.Pool.starmap',
           return_value=[{
               'host_name':
               'sys10',
               'last_checkin':
               '',
               'host_id':
               1,
               'cpu': {},
               'uuid':
               1,
               'system_details': {},
               'kernel':
               '',
               'subs': [],
               'network_devices': [],
               'registration_date':
               '',
               'system_inspection_result':
               SystemInspectionResult.SUCCESS
           }])
    @patch('xmlrpc.client.ServerProxy')
    def test_hosts_facts(self, mock_serverproxy, mock_pool):
        """Test the hosts_facts method."""
        # pylint: disable=unused-argument
        systems = [{'id': 1, 'name': 'sys1'}]
        client = mock_serverproxy.return_value
        client.auth.login.return_value = 'key'
        client.auth.logout.return_value = 'key'
        client.system.list_user_systems.return_value = systems
        hosts_return_value = ({}, {})
        with patch.object(SatelliteFive,
                          'virtual_hosts',
                          return_value=hosts_return_value) as mock_vhosts:
            with patch.object(SatelliteFive, 'physical_hosts',
                              return_value=[]) as mock_physical:
                self.api.hosts_facts(Value('i', ScanJob.JOB_RUN))
                inspect_result = self.scan_task.inspection_result
                self.assertEqual(len(inspect_result.systems.all()), 1)
                mock_vhosts.assert_called_once_with()
                mock_physical.assert_called_once_with()
Example #29
0
class SatelliteSixV1Test(TestCase):
    """Tests Satellite 6 v1 functions."""
    def setUp(self):
        """Create test case setup."""
        self.cred = Credential(name='cred1',
                               cred_type=Credential.SATELLITE_CRED_TYPE,
                               username='******',
                               password='******',
                               become_password=None,
                               become_method=None,
                               become_user=None,
                               ssh_keyfile=None)
        self.cred.save()

        self.source = Source(name='source1', port=443, hosts='["1.2.3.4"]')

        self.source.save()
        self.source.credentials.add(self.cred)

        self.scan_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT,
                                  source=self.source,
                                  sequence_number=1,
                                  start_time=datetime.utcnow())
        self.scan_task.save()

        self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT)
        self.scan_job.save()
        self.scan_job.tasks.add(self.scan_task)
        self.conn_results = JobConnectionResult()
        self.conn_results.save()
        self.scan_job.connection_results = self.conn_results
        self.scan_job.save()
        self.conn_result = TaskConnectionResult(scan_task=self.scan_task,
                                                source=self.source)
        self.conn_result.save()

        self.inspect_result = TaskInspectionResult(scan_task=self.scan_task,
                                                   source=self.source)
        self.inspect_result.save()

        self.api = SatelliteSixV1(self.scan_task, self.conn_result,
                                  self.inspect_result)

    def tearDown(self):
        """Cleanup test case setup."""
        pass

    def test_get_orgs(self):
        """Test the method to get orgs."""
        orgs_url = 'https://{sat_host}:{port}/katello/api/v2/organizations'
        with requests_mock.Mocker() as mocker:
            url = construct_url(orgs_url, '1.2.3.4')
            jsonresult = {
                'results': [{
                    'id': 1
                }, {
                    'id': 7
                }, {
                    'id': 8
                }],
                'per_page': 100
            }
            mocker.get(url, status_code=200, json=jsonresult)
            orgs = self.api.get_orgs()
            orgs2 = self.api.get_orgs()
            self.assertEqual(orgs, [1, 7, 8])
            self.assertEqual(orgs, orgs2)

    def test_get_orgs_with_err(self):
        """Test the method to get orgs with err."""
        orgs_url = 'https://{sat_host}:{port}/katello/api/v2/organizations'
        with requests_mock.Mocker() as mocker:
            url = construct_url(orgs_url, '1.2.3.4')
            jsonresult = {
                'results': [{
                    'id': 1
                }, {
                    'id': 7
                }, {
                    'id': 8
                }],
                'per_page': 100
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.get_orgs()

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_host_count(self, mock_get_orgs):
        """Test the method host_count."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=200, json=jsonresult)
            systems_count = self.api.host_count()
            self.assertEqual(systems_count, 3)

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_host_count_with_err(self, mock_get_orgs):
        """Test the method host_count with err."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.host_count()

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_hosts(self, mock_get_orgs):
        """Test the method hosts."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=200, json=jsonresult)
            systems_count = self.api.host_count()
            hosts = self.api.hosts()
            self.assertEqual(systems_count, 3)
            self.assertEqual(len(hosts), 3)
            self.assertEqual(hosts, ['sys1', 'sys2', 'sys3'])

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_hosts_with_err(self, mock_get_orgs):
        """Test the method hosts."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            jsonresult = {
                'results': [{
                    'name': 'sys1'
                }, {
                    'name': 'sys2'
                }, {
                    'name': 'sys3'
                }],
                'per_page': 100,
                'total': 3
            }
            mocker.get(url, status_code=500, json=jsonresult)
            with self.assertRaises(SatelliteException):
                self.api.hosts()

    def test_host_fields(self):
        """Test the method host_fields."""
        host_field_url = 'https://{sat_host}:{port}/api/v2/hosts/{host_id}'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=host_field_url,
                                sat_host='1.2.3.4',
                                host_id=1)
            jsonresult = {
                'architecture_id': 1,
                'architecture_name': 'x86_64',
                'operatingsystem_name': 'RedHat 7.4',
                'uuid': None,
                'created_at': '2017-12-04 13:19:57 UTC',
                'updated_at': '2017-12-04 13:21:47 UTC',
                'organization_name': 'ACME',
                'location_name': 'Raleigh',
                'name': 'mac52540071bafe.prov.lan',
                'virtual_host': {
                    'uuid': '100',
                    'name': 'vhost1'
                },
                'virtual_guests': [{
                    'name': 'foo'
                }],
                'content_facet_attributes': {
                    'id': 11,
                    'katello_agent_installed': False
                },
                'subscription_facet_attributes': {
                    'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
                    'last_checkin': '2018-01-04 17:36:07 UTC',
                    'registered_at': '2017-12-04 13:33:52 UTC',
                    'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
                    'virtual_host': {
                        'uuid': '100',
                        'name': 'vhost1'
                    },
                    'virtual_guests': [{
                        'name': 'foo'
                    }],
                },
                'facts': {
                    'memorysize_mb': '992.45',
                    'memorysize': '992.45 MB',
                    'hostname': 'fdi',
                    'type': 'Other',
                    'architecture': 'x86_64',
                    'is_virtual': 'true',
                    'virtual': 'kvm',
                    'net.interface.ipv4_address': '192.168.99.123',
                    'net.interface.mac_address': 'fe80::5054:ff:fe24:946e',
                },
            }
            mocker.get(url, status_code=200, json=jsonresult)
            host_info = host_fields(self.scan_task, 1, host_field_url, None, 1)
            expected = {
                'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
                'hostname': 'mac52540071bafe.prov.lan',
                'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
                'registration_time': '2017-12-04 13:33:52 UTC',
                'last_checkin_time': '2018-01-04 17:36:07 UTC',
                'katello_agent_installed': False,
                'os_release': 'RedHat 7.4',
                'organization': 'ACME',
                'virtual_host': '100',
                'virtual_host_name': 'vhost1',
                'virt_type': None,
                'kernel_version': None,
                'architecture': None,
                'is_virtualized': None,
                'cores': None,
                'num_sockets': None,
                'num_virtual_guests': 1,
                'virtual': 'hypervisor',
                'location': 'Raleigh',
                'ip_addresses': ['192.168.99.123'],
                'mac_addresses': ['fe80::5054:ff:fe24:946e'],
                'os_name': 'RedHat',
                'os_version': '7.4'
            }
            self.assertEqual(host_info, expected)

    def test_host_details_skip(self):
        """Test host_details method for already captured data."""
        sys_result = SystemInspectionResult(
            name='sys1', status=SystemInspectionResult.SUCCESS)
        sys_result.save()
        self.inspect_result.systems.add(sys_result)
        self.inspect_result.save()
        detail = self.api.host_details(1, 1, 'sys1')
        self.assertEqual(len(self.inspect_result.systems.all()), 1)
        self.assertEqual(detail, {})

    def test_host_details(self):
        """Test host_details method with mock data."""
        fields_return_value = {
            'uuid': '00c7a108-48ec-4a97-835c-aa3369777f64',
            'hostname': 'mac52540071bafe.prov.lan',
            'registered_by': 'sat-r220-07.lab.eng.rdu2.redhat.com',
            'registration_time': '2017-12-04 13:33:52 UTC',
            'last_checkin_time': '2018-01-04 17:36:07 UTC',
            'katello_agent_installed': False,
            'os_name': 'RedHat 7.4',
            'organization': 'ACME',
            'virtual_host': '100',
            'virtual_host_name': 'vhost1',
            'virt_type': None,
            'kernel_version': None,
            'architecture': None,
            'is_virtualized': None,
            'cores': None,
            'num_sockets': None,
            'num_virtual_guests': 1,
            'virtual': 'hypervisor',
            'location': 'Raleigh',
            'ip_addresses': ['192.168.99.123'],
            'ipv6_addresses': ['fe80::5054:ff:fe24:946e']
        }
        subs_return_value = {
            'entitlements': [{
                'derived_entitlement': False,
                'name': 'Satellite Tools 6.3',
                'amount': 1,
                'account_number': None,
                'contract_number': None,
                'start_date': '2017-12-01 14:50:59 UTC',
                'end_date': '2047-11-24 14:50:59 UTC'
            }, {
                'derived_entitlement': True,
                'name': 'Employee SKU',
                'amount': 1,
                'account_number': 1212729,
                'contract_number': 10913844,
                'start_date': '2016-03-24 04:00:00 UTC',
                'end_date': '2022-01-01 04:59:59 UTC'
            }]
        }
        expected = {
            'uuid':
            '00c7a108-48ec-4a97-835c-aa3369777f64',
            'hostname':
            'mac52540071bafe.prov.lan',
            'registered_by':
            'sat-r220-07.lab.eng.rdu2.redhat.com',
            'registration_time':
            '2017-12-04 13:33:52 UTC',
            'last_checkin_time':
            '2018-01-04 17:36:07 UTC',
            'katello_agent_installed':
            False,
            'os_name':
            'RedHat 7.4',
            'organization':
            'ACME',
            'virtual_host':
            '100',
            'virtual_host_name':
            'vhost1',
            'virt_type':
            None,
            'kernel_version':
            None,
            'architecture':
            None,
            'is_virtualized':
            None,
            'cores':
            None,
            'num_sockets':
            None,
            'num_virtual_guests':
            1,
            'virtual':
            'hypervisor',
            'location':
            'Raleigh',
            'ip_addresses': ['192.168.99.123'],
            'ipv6_addresses': ['fe80::5054:ff:fe24:946e'],
            'entitlements': [{
                'derived_entitlement': False,
                'name': 'Satellite Tools 6.3',
                'amount': 1,
                'account_number': None,
                'contract_number': None,
                'start_date': '2017-12-01 14:50:59 UTC',
                'end_date': '2047-11-24 14:50:59 UTC'
            }, {
                'derived_entitlement': True,
                'name': 'Employee SKU',
                'amount': 1,
                'account_number': 1212729,
                'contract_number': 10913844,
                'start_date': '2016-03-24 04:00:00 UTC',
                'end_date': '2022-01-01 04:59:59 UTC'
            }]
        }

        self.scan_task.save()
        self.scan_task.update_stats('TEST_SAT.', sys_scanned=0)
        with patch('scanner.satellite.six.host_fields',
                   return_value=fields_return_value) as mock_fields:
            with patch('scanner.satellite.six.host_subscriptions',
                       return_value=subs_return_value) as mock_subs:
                details = self.api.host_details(org_id=1,
                                                host_id=1,
                                                host_name='sys1')
                self.assertEqual(details, expected)
                mock_fields.assert_called_once_with(ANY, ANY, ANY, ANY, ANY)
                mock_subs.assert_called_once_with(ANY, ANY, ANY, ANY)

    @patch('scanner.satellite.six.SatelliteSixV1.get_orgs')
    def test_hosts_facts_with_err(self, mock_get_orgs):
        """Test the hosts_facts method."""
        mock_get_orgs.return_value = [1]
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with requests_mock.Mocker() as mocker:
            url = construct_url(url=hosts_url, sat_host='1.2.3.4', org_id=1)
            mocker.get(url, status_code=500)
            with self.assertRaises(SatelliteException):
                self.api.hosts_facts()

    def test_hosts_facts(self):
        """Test the method hosts."""
        hosts_url = 'https://{sat_host}:{port}/katello/api' \
            '/v2/organizations/{org_id}/systems'
        with patch.object(SatelliteSixV1, 'get_orgs',
                          return_value=[1]) as mock_get_orgs:
            with patch.object(SatelliteSixV1, 'host_details',
                              return_value={}) as mock_host_details:
                with requests_mock.Mocker() as mocker:
                    url = construct_url(url=hosts_url,
                                        sat_host='1.2.3.4',
                                        org_id=1)
                    jsonresult = {
                        'results': [{
                            'uuid': '1',
                            'name': 'sys1'
                        }, {
                            'uuid': '2',
                            'name': 'sys2'
                        }, {
                            'uuid': '3',
                            'name': 'sys3'
                        }],
                        'per_page':
                        100,
                        'total':
                        3
                    }
                    mocker.get(url, status_code=200, json=jsonresult)
                    self.api.hosts_facts()
                    mock_get_orgs.assert_called_once_with()
                    mock_host_details.assert_called_with(ANY, ANY, ANY)