예제 #1
0
    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()
예제 #2
0
    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(self.host_list)
        mock_run.assert_called_with(ANY)
예제 #3
0
    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)
예제 #4
0
    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_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT,
                                  source=self.source,
                                  sequence_number=1)
        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()
예제 #5
0
 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 = ConnectTaskRunner(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)
예제 #6
0
    def test_run_with_except(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 = ConnectTaskRunner(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)
예제 #7
0
    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)
예제 #8
0
    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_job, self.scan_task = create_scan_job(
            self.source, scan_type=ScanTask.SCAN_TYPE_INSPECT)
예제 #9
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)
예제 #10
0
    def create(self, validated_data):
        """Create a source."""
        name = validated_data.get('name')
        check_for_existing_name(Source.objects, name,
                                _(messages.SOURCE_NAME_ALREADY_EXISTS % name))

        if 'source_type' not in validated_data:
            error = {'source_type': [_(messages.SOURCE_TYPE_REQ)]}
            raise ValidationError(error)
        source_type = validated_data.get('source_type')
        credentials = validated_data.pop('credentials')
        hosts_list = validated_data.pop('hosts', None)
        exclude_hosts_list = validated_data.pop('exclude_hosts', None)
        port = None
        if 'port' in validated_data:
            port = validated_data['port']

        options = validated_data.pop('options', None)

        if source_type == Source.NETWORK_SOURCE_TYPE:
            if credentials:
                for cred in credentials:
                    SourceSerializer.check_credential_type(source_type, cred)
            if port is None:
                validated_data['port'] = 22

        elif source_type == Source.VCENTER_SOURCE_TYPE:
            if port is None:
                validated_data['port'] = 443
            if hosts_list and len(hosts_list) != 1:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            if hosts_list and '[' in hosts_list[0]:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            if exclude_hosts_list is not None:
                error = {
                    'exclude_hosts': [_(messages.VC_EXCLUDE_HOSTS_INCLUDED)]
                }
                raise ValidationError(error)
            if credentials and len(credentials) > 1:
                error = {'credentials': [_(messages.VC_ONE_CRED)]}
                raise ValidationError(error)
            if credentials and len(credentials) == 1:
                SourceSerializer.check_credential_type(source_type,
                                                       credentials[0])
        elif source_type == Source.SATELLITE_SOURCE_TYPE:
            if port is None:
                validated_data['port'] = 443
            if hosts_list and len(hosts_list) != 1:
                error = {'hosts': [_(messages.SAT_ONE_HOST)]}
                raise ValidationError(error)
            if hosts_list and '[' in hosts_list[0]:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            if exclude_hosts_list is not None:
                error = {
                    'exclude_hosts': [_(messages.SAT_EXCLUDE_HOSTS_INCLUDED)]
                }
                raise ValidationError(error)
            if credentials and len(credentials) > 1:
                error = {'credentials': [_(messages.SAT_ONE_CRED)]}
                raise ValidationError(error)
            if credentials and len(credentials) == 1:
                SourceSerializer.check_credential_type(source_type,
                                                       credentials[0])

        source = Source.objects.create(**validated_data)

        if options:
            SourceSerializer.validate_opts(options, source_type)
            options = SourceOptions.objects.create(**options)
            options.save()
            source.options = options
        elif not options and source_type == Source.SATELLITE_SOURCE_TYPE:
            options = SourceOptions()
            options.ssl_cert_verify = True
            options.save()
            source.options = options
        elif not options and source_type == Source.VCENTER_SOURCE_TYPE:
            options = SourceOptions()
            options.ssl_cert_verify = True
            options.save()
            source.options = options

        source.hosts = json.dumps(hosts_list)
        if exclude_hosts_list:
            source.exclude_hosts = json.dumps(exclude_hosts_list)

        for credential in credentials:
            source.credentials.add(credential)

        source.save()
        return source
예제 #11
0
    def create(self, validated_data):
        """Create a source."""
        name = validated_data.get('name')
        check_for_existing_name(Source.objects, name,
                                _(messages.SOURCE_NAME_ALREADY_EXISTS % name))

        if 'source_type' not in validated_data:
            error = {'source_type': [_(messages.SOURCE_TYPE_REQ)]}
            raise ValidationError(error)
        source_type = validated_data.get('source_type')
        credentials = validated_data.pop('credentials')
        hosts_list = validated_data.pop('hosts', None)
        port = None
        if 'port' in validated_data:
            port = validated_data['port']

        options = validated_data.pop('options', None)

        if source_type == Source.NETWORK_SOURCE_TYPE:
            if credentials:
                for cred in credentials:
                    SourceSerializer.check_credential_type(source_type, cred)
            if port is None:
                validated_data['port'] = 22
        elif source_type == Source.VCENTER_SOURCE_TYPE:
            if port is None:
                validated_data['port'] = 443
            if hosts_list and len(hosts_list) != 1:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            elif hosts_list and '[' in hosts_list[0]:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            if credentials and len(credentials) > 1:
                error = {'credentials': [_(messages.VC_ONE_CRED)]}
                raise ValidationError(error)
            elif credentials and len(credentials) == 1:
                SourceSerializer.check_credential_type(source_type,
                                                       credentials[0])
        elif source_type == Source.SATELLITE_SOURCE_TYPE:
            if port is None:
                validated_data['port'] = 443
            if hosts_list and len(hosts_list) != 1:
                error = {'hosts': [_(messages.SAT_ONE_HOST)]}
                raise ValidationError(error)
            elif hosts_list and '[' in hosts_list[0]:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            if credentials and len(credentials) > 1:
                error = {'credentials': [_(messages.SAT_ONE_CRED)]}
                raise ValidationError(error)
            elif credentials and len(credentials) == 1:
                SourceSerializer.check_credential_type(source_type,
                                                       credentials[0])

        source = Source.objects.create(**validated_data)

        if options:
            if source_type == Source.SATELLITE_SOURCE_TYPE:
                if options.get('ssl_cert_verify') is None:
                    options['ssl_cert_verify'] = True
            if (source_type == Source.VCENTER_SOURCE_TYPE
                    and options.get('ssl_cert_verify') is None):
                options['ssl_cert_verify'] = True
            if source_type == Source.NETWORK_SOURCE_TYPE and \
                    bool(options):
                invalid_options = ', '.join([key for key in options.keys()])
                error = {
                    'options': [
                        _(messages.NET_SSL_OPTIONS_NOT_ALLOWED %
                          invalid_options)
                    ]
                }
                raise ValidationError(error)

            options = SourceOptions.objects.create(**options)
            options.save()
            source.options = options
        elif not options and source_type == Source.SATELLITE_SOURCE_TYPE:
            options = SourceOptions()
            options.ssl_cert_verify = True
            options.save()
            source.options = options
        elif not options and source_type == Source.VCENTER_SOURCE_TYPE:
            options = SourceOptions()
            options.ssl_cert_verify = True
            options.save()
            source.options = options

        source.hosts = json.dumps(hosts_list)

        for credential in credentials:
            source.credentials.add(credential)

        source.save()
        return source
예제 #12
0
    def create(self, validated_data):
        """Create a source."""
        SourceSerializer.check_for_existing_name(
            name=validated_data.get('name'))

        if 'source_type' not in validated_data:
            error = {'source_type': [_(messages.SOURCE_TYPE_REQ)]}
            raise ValidationError(error)
        source_type = validated_data.get('source_type')
        credentials = validated_data.pop('credentials')
        hosts_list = validated_data.pop('hosts', None)
        port = None
        if 'port' in validated_data:
            port = validated_data['port']

        options = validated_data.pop('options', None)

        if source_type == Source.NETWORK_SOURCE_TYPE:
            if credentials:
                for cred in credentials:
                    SourceSerializer.check_credential_type(source_type, cred)
            if port is None:
                validated_data['port'] = 22
        elif source_type == Source.VCENTER_SOURCE_TYPE:
            if port is None:
                validated_data['port'] = 443
            if hosts_list and len(hosts_list) != 1:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            elif hosts_list and '[' in hosts_list[0]:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            if credentials and len(credentials) > 1:
                error = {'credentials': [_(messages.VC_ONE_CRED)]}
                raise ValidationError(error)
            elif credentials and len(credentials) == 1:
                SourceSerializer.check_credential_type(source_type,
                                                       credentials[0])
        elif source_type == Source.SATELLITE_SOURCE_TYPE:
            if port is None:
                validated_data['port'] = 443
            if hosts_list and len(hosts_list) != 1:
                error = {'hosts': [_(messages.SAT_ONE_HOST)]}
                raise ValidationError(error)
            elif hosts_list and '[' in hosts_list[0]:
                error = {'hosts': [_(messages.VC_ONE_HOST)]}
                raise ValidationError(error)
            if credentials and len(credentials) > 1:
                error = {'credentials': [_(messages.SAT_ONE_CRED)]}
                raise ValidationError(error)
            elif credentials and len(credentials) == 1:
                SourceSerializer.check_credential_type(source_type,
                                                       credentials[0])

        source = Source.objects.create(**validated_data)

        if options:
            if source_type == Source.SATELLITE_SOURCE_TYPE:
                if not options.get('satellite_version'):
                    options['satellite_version'] = \
                        SourceOptions.SATELLITE_VERSION_62
                if options.get('ssl_cert_verify') is None:
                    options['ssl_cert_verify'] = True
            if (source_type == Source.VCENTER_SOURCE_TYPE
                    and options.get('ssl_cert_verify') is None):
                options['ssl_cert_verify'] = True

            options = SourceOptions.objects.create(**options)
            options.save()
            source.options = options
        elif not options and source_type == Source.SATELLITE_SOURCE_TYPE:
            options = SourceOptions()
            options.satellite_version = SourceOptions.SATELLITE_VERSION_62
            options.ssl_cert_verify = True
            options.save()
            source.options = options
        elif not options and source_type == Source.VCENTER_SOURCE_TYPE:
            options = SourceOptions()
            options.satellite_version = None
            options.ssl_cert_verify = True
            options.save()
            source.options = options

        source.hosts = json.dumps(hosts_list)

        for credential in credentials:
            source.credentials.add(credential)

        source.save()
        return source
    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()