예제 #1
0
def _create_async_merge_report_job(details_report_data):
    """Retrieve merge report job status.

    :param details_report_data: Details report data to fingerprint
    :returns: Response for http request
    """
    has_errors, validation_result = validate_details_report_json(
        details_report_data)
    if has_errors:
        return Response(validation_result,
                        status=status.HTTP_400_BAD_REQUEST)

    # Create FC model and save data
    details_report = create_details_report(details_report_data)

    # Create new job to run

    merge_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_FINGERPRINT,
                        details_report=details_report)
    merge_job.save()
    merge_job.log_current_status()
    job_serializer = ScanJobSerializer(merge_job)
    response_data = job_serializer.data

    # start fingerprint job
    start_scan.send(sender=__name__, instance=merge_job)

    return Response(response_data, status=status.HTTP_201_CREATED)
예제 #2
0
def sync_merge_reports(request):
    """Merge reports synchronously."""
    # pylint: disable=too-many-locals
    error = {'reports': []}

    details_report_json = _convert_ids_to_json(request.data)

    has_errors, validation_result = validate_details_report_json(
        details_report_json, True)
    if has_errors:
        message = _(messages.REPORT_MERGE_NO_RESULTS % validation_result)
        error.get('reports').append(message)
        raise ValidationError(error)

    # Create FC model and save data
    details_report_json = _reconcile_source_versions(details_report_json)
    report_version = details_report_json.get('report_version', None)
    details_report = create_details_report(report_version, details_report_json)
    merge_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_FINGERPRINT,
                        details_report=details_report)
    merge_job.save()
    merge_job.queue()
    runner = ScanJobRunner(merge_job)
    runner.run()

    if merge_job.status != ScanTask.COMPLETED:
        raise Exception(merge_job.status_message)

    merge_job.refresh_from_db()
    details_report = DetailsReport.objects.get(pk=details_report.id)

    # Prepare REST response body
    serializer = DetailsReportSerializer(details_report)
    result = serializer.data
    return Response(result, status=status.HTTP_201_CREATED)
예제 #3
0
    def create(self, request, *args, **kwargs):
        """Create a source."""
        response = super().create(request, args, kwargs)

        # Modify json for response
        json_source = response.data
        format_source(json_source)

        # check to see if a connection scan was requested
        # through query parameter
        scan = request.query_params.get('scan', False)
        # If the scan was requested, create a connection scan
        if scan:
            if is_boolean(scan):
                if convert_to_boolean(scan):
                    # Grab the source id
                    source_id = response.data['id']
                    # Create the scan job
                    scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT)
                    scan_job.save()

                    # Add the source
                    scan_job.sources.add(source_id)
                    scan_job.save()

                    # Start the scan
                    start_scan.send(sender=self.__class__, instance=scan_job)
            else:
                error = {
                    'scan': [_(messages.SOURCE_CONNECTION_SCAN)]
                }
                raise ValidationError(error)
        return response
예제 #4
0
    def test_expand_scanjob(self):
        """Test view expand_scanjob."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        self.assertEqual(scan_job.status, ScanTask.CREATED)
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 0)

        # Queue job to run
        scan_job.queue()
        task = scan_job.tasks.all()[1]
        task.systems_count = 2
        task.systems_failed = 1
        task.systems_scanned = 1
        task.save()

        scan_job = ScanJob.objects.filter(pk=scan_job.id).first()

        json_scan = {'tasks': [{}]}
        expand_scanjob(scan_job, json_scan)

        self.assertEqual(json_scan.get('systems_count'), 2)
        self.assertEqual(json_scan.get('systems_failed'), 1)
        self.assertEqual(json_scan.get('systems_scanned'), 1)
예제 #5
0
    def test_expand_sys_conn_result(self):
        """Test view expand_sys_conn_result."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        self.assertEqual(scan_job.status, ScanTask.CREATED)
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 0)

        # Queue job to run
        scan_job.queue()

        conn_task = scan_job.tasks.first()

        conn_result = ConnectionResult(source=conn_task.source,
                                       scan_task=conn_task)
        conn_result.save()

        sys_result = SystemConnectionResult(
            name='Foo',
            credential=self.cred,
            status=SystemConnectionResult.SUCCESS)
        sys_result.save()
        conn_result.systems.add(sys_result)
        conn_result.save()

        result = expand_sys_conn_result(conn_result)
        self.assertEqual(result[0]['credential']['name'], 'cred1')
예제 #6
0
    def test_queue_task(self):
        """Test create queue state change."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        self.assertEqual(scan_job.status, ScanTask.CREATED)
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 0)

        # Queue job to run
        scan_job.queue()

        # Job should be in pending state
        self.assertEqual(scan_job.status, ScanTask.PENDING)

        # Queue should have created scan tasks
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 2)

        # Validate connect task created and correct
        connect_task = tasks[0]
        self.assertEqual(connect_task.scan_type, ScanTask.SCAN_TYPE_CONNECT)
        self.assertEqual(connect_task.status, ScanTask.PENDING)

        # Validate inspect task created and correct
        inspect_task = tasks[1]
        self.assertEqual(inspect_task.scan_type, ScanTask.SCAN_TYPE_INSPECT)
        self.assertEqual(inspect_task.status, ScanTask.PENDING)
예제 #7
0
    def create(self, request, *args, **kwargs):
        """Create a details report."""
        # pylint: disable=unused-argument
        # Validate incoming request body
        has_errors, validation_result = validate_details_report_json(
            request.data)
        if has_errors:
            return Response(validation_result,
                            status=status.HTTP_400_BAD_REQUEST)

        # Create FC model and save data
        details_report = create_details_report(request.data)
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_FINGERPRINT,
                           details_report=details_report)
        scan_job.save()
        scan_job.queue()
        runner = ScanJobRunner(scan_job)
        runner.run()

        if scan_job.status != ScanTask.COMPLETED:
            # pylint: disable=no-member
            error_json = {'error': scan_job.tasks.first().status_message}
            return Response(error_json, status=status.HTTP_400_BAD_REQUEST)

        scan_job = ScanJob.objects.get(pk=scan_job.id)
        details_report = DetailsReport.objects.get(pk=details_report.id)

        # Prepare REST response body
        serializer = self.get_serializer(details_report)
        result = serializer.data
        return Response(result, status=status.HTTP_201_CREATED)
예제 #8
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)
예제 #9
0
 def test_get_extra_vars(self):
     """Tests the get_extra_vars method with empty dict."""
     scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
     scan_job.save()
     scan_options = ScanOptions()
     scan_options.disable_optional_products = {}
     scan_options.save()
     scan_job.options = scan_options
     scan_job.save()
     extra_vars = scan_job.get_extra_vars()
     expected_vars = {
         'jboss_eap': True,
         'jboss_fuse': True,
         'jboss_brms': True
     }
     self.assertEqual(extra_vars, expected_vars)
예제 #10
0
    def test_expand_inspect_results(self):
        """Test view expand_inspect_results."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        self.assertEqual(scan_job.status, ScanTask.CREATED)
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 0)

        # Queue job to run
        scan_job.queue()

        inspect_task = scan_job.tasks.all()[1]

        inspect_results = JobInspectionResult()
        inspect_results.save()

        scan_job.inspection_results = inspect_results
        scan_job.save()

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

        inspect_results.results.add(inspect_result)
        inspect_results.save()

        sys_result = SystemInspectionResult(
            name='Foo', status=SystemConnectionResult.SUCCESS)
        sys_result.save()

        fact = RawFact(name='foo', value='"value"')
        fact.save()
        sys_result.facts.add(fact)
        sys_result.save()

        inspect_result.systems.add(sys_result)
        inspect_result.save()

        inspect_results_json = {'results': [{}]}
        expand_inspect_results(inspect_results, inspect_results_json)
        self.assertEqual(
            inspect_results_json['results'][0]['systems'][0]['facts'][0]
            ['name'], 'foo')
예제 #11
0
    def test_queue_task(self):
        """Test create queue state change."""
        # Cannot use util because its testing queue
        # Create scan configuration
        scan = Scan(name='test',
                    scan_type=ScanTask.SCAN_TYPE_INSPECT)
        scan.save()

        # Add source to scan
        scan.sources.add(self.source)

        options_to_use = ScanOptions()
        options_to_use.save()

        scan.options = options_to_use
        scan.save()

        # Create Job
        scan_job = ScanJob(scan=scan)
        scan_job.save()

        # Job in created state
        self.assertEqual(scan_job.status, ScanTask.CREATED)
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 0)

        # Queue job to run
        scan_job.queue()

        # Job should be in pending state
        self.assertEqual(scan_job.status, ScanTask.PENDING)

        # Queue should have created scan tasks
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 2)

        # Validate connect task created and correct
        connect_task = tasks[0]
        self.assertEqual(connect_task.scan_type, ScanTask.SCAN_TYPE_CONNECT)
        self.assertEqual(connect_task.status, ScanTask.PENDING)

        # Validate inspect task created and correct
        inspect_task = tasks[1]
        self.assertEqual(inspect_task.scan_type, ScanTask.SCAN_TYPE_INSPECT)
        self.assertEqual(inspect_task.status, ScanTask.PENDING)
예제 #12
0
    def test_start_task(self, start_scan):
        """Test start pending task."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        tasks = scan_job.tasks.all()

        # Queue job to run
        scan_job.queue()
        self.assertEqual(scan_job.status, ScanTask.PENDING)

        # Queue should have created scan tasks
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 1)

        # Start job
        scan_job.start()
예제 #13
0
    def create(self, request, *args, **kwargs):
        """Create a details report."""
        # pylint: disable=unused-argument
        # Validate incoming request body
        has_errors, validation_result = validate_details_report_json(
            request.data, True)
        if has_errors:
            return Response(validation_result,
                            status=status.HTTP_400_BAD_REQUEST)

        report_version = request.data.get('report_version', None)
        warn_deprecated = False
        if not report_version:
            warn_deprecated = True
            report_version = create_report_version()

        # Create FC model and save data
        details_report = create_details_report(create_report_version(),
                                               request.data)
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_FINGERPRINT,
                           details_report=details_report)
        scan_job.save()
        if warn_deprecated:
            scan_job.log_message(_(messages.FC_MISSING_REPORT_VERSION),
                                 log_level=logging.WARNING)

        scan_job.queue()
        runner = ScanJobRunner(scan_job)
        runner.run()

        if scan_job.status != ScanTask.COMPLETED:
            # pylint: disable=no-member
            error_json = {'error': scan_job.tasks.first().status_message}
            return Response(error_json, status=status.HTTP_400_BAD_REQUEST)

        scan_job = ScanJob.objects.get(pk=scan_job.id)
        details_report = DetailsReport.objects.get(pk=details_report.id)

        # Prepare REST response body
        serializer = self.get_serializer(details_report)
        result = serializer.data
        return Response(result, status=status.HTTP_201_CREATED)
예제 #14
0
파일: view.py 프로젝트: AllenBW/quipucords
    def create(self, request, *args, **kwargs):
        """Create a source."""
        response = super().create(request, args, kwargs)

        # Modify json for response
        json_source = response.data
        source_id = json_source.get('id')
        if not source_id or (source_id and not isinstance(source_id, int)):
            error = {'id': [_(messages.COMMON_ID_INV)]}
            raise ValidationError(error)

        get_object_or_404(self.queryset, pk=source_id)

        # Create expanded host cred JSON
        expand_credential(json_source)

        # check to see if a connection scan was requested
        # through query parameter
        scan = request.query_params.get('scan', False)
        # If the scan was requested, create a connection scan
        if scan:
            if is_boolean(scan):
                if convert_to_boolean(scan):
                    # Grab the source id
                    source_id = response.data['id']
                    # Define the scan options object
                    scan_options = ScanOptions()
                    scan_options.save()
                    # Create the scan job
                    scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT,
                                       options=scan_options)
                    scan_job.save()
                    # Add the source
                    scan_job.sources.add(source_id)
                    scan_job.save()
                    # Start the scan
                    start_scan.send(sender=self.__class__, instance=scan_job)
            else:
                error = {'scan': [_(messages.SOURCE_CONNECTION_SCAN)]}
                raise ValidationError(error)
        return response
예제 #15
0
def create_scan_job_two_tasks(source,
                              source2,
                              scan_type=ScanTask.SCAN_TYPE_CONNECT,
                              scan_name='test',
                              scan_options=None):
    """Create a new scan job with two sources.

    :param source: the source for the scan job
    :param sourc2: the second source for the scan job
    :param scan_type: Either connect or inspect
    :param scan_options: Job scan options
    :return: the scan job and task
    """
    # Create scan configuration
    scan = Scan(name=scan_name, scan_type=scan_type)
    scan.save()

    # Add source to scan
    if source is not None:
        scan.sources.add(source)
    if source2 is not None:
        scan.sources.add(source2)

    # Add options to scan
    if scan_options is not None:
        scan.options = scan_options
        scan.save()

    # Create Job
    scan_job = ScanJob(scan=scan)
    scan_job.save()

    scan_job.queue()

    # grab the scan tasks
    scan_tasks = scan_job.tasks.all()
    if scan_type == ScanTask.SCAN_TYPE_INSPECT:
        for task in scan_tasks:
            task.complete()

    return scan_job, scan_tasks
예제 #16
0
    def test_expand_conn_results(self):
        """Test view expand_conn_results."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        self.assertEqual(scan_job.status, ScanTask.CREATED)
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 0)

        # Queue job to run
        scan_job.queue()

        conn_task = scan_job.tasks.first()

        conn_results = JobConnectionResult()
        conn_results.save()
        scan_job.connection_results = conn_results
        scan_job.save()

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

        conn_results.results.add(conn_result)
        conn_results.save()

        sys_result = SystemConnectionResult(
            name='Foo',
            credential=self.cred,
            status=SystemConnectionResult.SUCCESS)
        sys_result.save()
        conn_result.systems.add(sys_result)
        conn_result.save()

        conn_results_json = {'results': [{}]}
        expand_conn_results(conn_results, conn_results_json)
        self.assertEqual(conn_results_json['results'][0]['systems'][0]['name'],
                         'Foo')
예제 #17
0
def create_scan_job(source,
                    scan_type=ScanTask.SCAN_TYPE_CONNECT,
                    scan_name='test',
                    scan_options=None):
    """Create a new scan job.

    :param source: the source for the scan job
    :param scan_type: Either connect or inspect
    :param scan_options: Job scan options
    :return: the scan job and task
    """
    # Create scan configuration
    scan = Scan(name=scan_name, scan_type=scan_type)
    scan.save()

    # Add source to scan
    if source is not None:
        scan.sources.add(source)

    # Add options to scan
    if scan_options is not None:
        scan.options = scan_options
        scan.save()

    # Create Job
    scan_job = ScanJob(scan=scan)
    scan_job.save()

    scan_job.queue()

    # pylint: disable=no-member
    scan_task = scan_job.tasks.first()
    if scan_type == ScanTask.SCAN_TYPE_INSPECT:
        scan_task.complete()
        scan_task = scan_job.tasks.filter(
            scan_type=ScanTask.SCAN_TYPE_INSPECT).first()

    return scan_job, scan_task
예제 #18
0
def sync_merge_reports(request):
    """Merge reports synchronously."""
    error = {
        'reports': []
    }
    reports = validate_merge_report(request.data)
    sources = []
    for report in reports:
        sources = sources + report.get_sources()

    details_report_json = {'sources': sources}
    has_errors, validation_result = validate_details_report_json(
        details_report_json)
    if has_errors:
        message = _(messages.REPORT_MERGE_NO_RESULTS % validation_result)
        error.get('reports').append(message)
        raise ValidationError(error)

    # Create FC model and save data
    details_report = create_details_report(details_report_json)
    scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_FINGERPRINT,
                       details_report=details_report)
    scan_job.save()
    scan_job.queue()
    runner = ScanJobRunner(scan_job)
    runner.run()

    if scan_job.status != ScanTask.COMPLETED:
        raise Exception(scan_job.status_message)

    scan_job = ScanJob.objects.get(pk=scan_job.id)
    details_report = DetailsReport.objects.get(pk=details_report.id)

    # Prepare REST response body
    serializer = DetailsReportSerializer(details_report)
    result = serializer.data
    return Response(result, status=status.HTTP_201_CREATED)
예제 #19
0
    def test_pause_restart_task(self, start_scan):
        """Test pause and restart task."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_CONNECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        tasks = scan_job.tasks.all()

        # Queue job to run
        scan_job.queue()
        self.assertEqual(scan_job.status, ScanTask.PENDING)

        # Queue should have created scan tasks
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 1)
        connect_task = scan_job.tasks.first()
        self.assertEqual(connect_task.status, ScanTask.PENDING)

        # Start job
        scan_job.start()
        self.assertEqual(scan_job.status, ScanTask.RUNNING)

        scan_job.pause()
        connect_task = scan_job.tasks.first()
        self.assertEqual(scan_job.status, ScanTask.PAUSED)
        self.assertEqual(connect_task.status, ScanTask.PAUSED)

        scan_job.restart()
        connect_task = scan_job.tasks.first()
        self.assertEqual(scan_job.status, ScanTask.RUNNING)
        self.assertEqual(connect_task.status, ScanTask.PENDING)

        scan_job.cancel()
        connect_task = scan_job.tasks.first()
        self.assertEqual(scan_job.status, ScanTask.CANCELED)
        self.assertEqual(connect_task.status, ScanTask.CANCELED)
예제 #20
0
    def test_expand_scanjob(self):
        """Test view expand_scanjob."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        self.assertEqual(scan_job.status, ScanTask.CREATED)
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 0)

        # Queue job to run
        scan_job.queue()
        task = scan_job.tasks.all()[1]
        task.update_stats('TEST_VC.', sys_count=2, sys_failed=1, sys_scanned=1)

        scan_job = ScanJob.objects.filter(pk=scan_job.id).first()
        serializer = ScanJobSerializer(scan_job)
        json_scan = serializer.data
        expand_scanjob(json_scan)

        self.assertEqual(json_scan.get('systems_count'), 2)
        self.assertEqual(json_scan.get('systems_failed'), 1)
        self.assertEqual(json_scan.get('systems_scanned'), 1)
예제 #21
0
    def test_queue_invalid_state_changes(self):
        """Test create queue failed."""
        scan_job = ScanJob(status=ScanTask.FAILED,
                           scan_type=ScanTask.SCAN_TYPE_INSPECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Queue job to run
        scan_job.queue()
        self.assertEqual(scan_job.status, ScanTask.FAILED)

        scan_job.complete()
        self.assertEqual(scan_job.status, ScanTask.FAILED)

        scan_job.pause()
        self.assertEqual(scan_job.status, ScanTask.FAILED)

        scan_job.start()
        self.assertEqual(scan_job.status, ScanTask.FAILED)

        scan_job.cancel()
        self.assertEqual(scan_job.status, ScanTask.FAILED)

        scan_job.restart()
        self.assertEqual(scan_job.status, ScanTask.FAILED)

        scan_job.fail()
        self.assertEqual(scan_job.status, ScanTask.FAILED)

        scan_job.status = ScanTask.CREATED
        scan_job.fail()
        self.assertEqual(scan_job.status, ScanTask.CREATED)

        scan_job.status = ScanTask.RUNNING
        scan_job.complete()
        self.assertEqual(scan_job.status, ScanTask.COMPLETED)
예제 #22
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()
예제 #23
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_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()
        self.conn_result = TaskConnectionResult(scan_task=self.scan_task,
                                                source=self.source)
        self.conn_result.save()

    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.conn_result)
        self.assertEqual(api, None)

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

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

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

    def test_create_sat6_unknown(self):
        """Test the method to create a Sat 6 interface."""
        satellite_version = SourceOptions.SATELLITE_VERSION_62
        api_version = 9
        api = create(satellite_version, api_version, self.scan_task,
                     self.conn_result)
        self.assertEqual(api, None)
예제 #24
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()
예제 #25
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_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT,
                                  source=self.source, sequence_number=1,
                                  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.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 = SatelliteFive(self.scan_task,
                                 self.conn_result,
                                 self.inspect_result)

    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={})
        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})
        self.assertEqual(details, 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()
        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})
        self.assertEqual(len(self.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
        with self.assertRaises(SatelliteException):
            virt = {2: {'uuid': 2, 'name': 'sys2', 'num_virtual_guests': 3}}
            self.api.host_details(host_id=1, host_name='sys1',
                                  last_checkin='', virtual_hosts=virt,
                                  virtual_guests={1: 2})

    @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 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
        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_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_return_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_hosts:
            with patch.object(SatelliteFive, 'host_details',
                              return_value=detail_return_value) as mock_detail:
                self.api.hosts_facts()
                mock_hosts.assert_called_once_with()
                mock_detail.assert_called_once_with(ANY, ANY, ANY, ANY, ANY)
예제 #26
0
    def test_details(self, start_scan):
        """Get ScanJob result details by primary key."""
        scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT)
        scan_job.save()
        scan_job.sources.add(self.source)

        # Job in created state
        self.assertEqual(scan_job.status, ScanTask.CREATED)
        tasks = scan_job.tasks.all()
        self.assertEqual(len(tasks), 0)

        # Queue job to run
        scan_job.queue()

        conn_task = scan_job.tasks.first()

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

        conn_result = ConnectionResult(source=conn_task.source,
                                       scan_task=conn_task)
        conn_result.save()

        conn_results.results.add(conn_result)
        conn_results.save()

        sys_result = SystemConnectionResult(
            name='Foo',
            credential=self.cred,
            status=SystemConnectionResult.SUCCESS)
        sys_result.save()
        conn_result.systems.add(sys_result)
        conn_result.save()

        inspect_task = scan_job.tasks.all()[1]

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

        inspect_result = InspectionResult(source=inspect_task.source,
                                          scan_task=inspect_task)
        inspect_result.save()

        inspect_results.results.add(inspect_result)
        inspect_results.save()

        sys_result = SystemInspectionResult(
            name='Foo', status=SystemConnectionResult.SUCCESS)
        sys_result.save()

        fact = RawFact(name='foo', value='value')
        fact.save()
        sys_result.facts.add(fact)
        sys_result.save()

        inspect_result.systems.add(sys_result)
        inspect_result.save()

        url = reverse('scanjob-detail', args=(scan_job.id, )) + 'results/'
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json_response = response.json()
        self.assertIn('connection_results', json_response)
        self.assertIn('inspection_results', json_response)

        self.assertEqual(
            json_response, {
                'connection_results': {
                    'scan_job': 1,
                    'results': []
                },
                'inspection_results': {
                    'scan_job': 1,
                    'results': []
                }
            })
예제 #27
0
class ScanTaskTest(TestCase):
    """Test the basic ScanJob infrastructure."""

    def setUp(self):
        """Create test setup."""
        management.call_command('flush', '--no-input')
        self.cred = Credential.objects.create(
            name='cred1',
            username='******',
            password='******',
            become_password=None,
            ssh_keyfile=None)
        self.cred_for_upload = self.cred.id

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

        # Create scan configuration
        scan = Scan(name='scan_name',
                    scan_type=ScanTask.SCAN_TYPE_CONNECT)
        scan.save()

        # Add source to scan
        scan.sources.add(self.source)

        # Create Job
        self.scan_job = ScanJob(scan=scan)
        self.scan_job.save()

    def test_successful_create(self):
        """Create a scan task and serialize it."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        serializer = ScanTaskSerializer(task)
        json_task = serializer.data
        self.assertEqual(
            {'sequence_number': 0,
             'source': 1,
             'scan_type': ScanTask.SCAN_TYPE_CONNECT,
             'status': 'pending',
             'status_message': messages.ST_STATUS_MSG_PENDING},
            json_task)

    def test_successful_start(self):
        """Create a scan task and start it."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        start_time = datetime.utcnow()
        task.start()
        task.save()
        self.assertEqual(messages.ST_STATUS_MSG_RUNNING,
                         task.status_message)
        self.assertEqual(task.status, ScanTask.RUNNING)
        self.assertEqual(start_time.replace(microsecond=0),
                         task.start_time.replace(microsecond=0))

    def test_successful_restart(self):
        """Create a scan task and restart it."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        task.restart()
        task.save()
        self.assertEqual(messages.ST_STATUS_MSG_RESTARTED,
                         task.status_message)
        self.assertEqual(task.status, ScanTask.PENDING)

    def test_successful_pause(self):
        """Create a scan task and pause it."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        task.pause()
        task.save()
        self.assertEqual(messages.ST_STATUS_MSG_PAUSED,
                         task.status_message)
        self.assertEqual(task.status, ScanTask.PAUSED)

    def test_successful_cancel(self):
        """Create a scan task and cancel it."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        end_time = datetime.utcnow()
        task.cancel()
        task.save()
        self.assertEqual(messages.ST_STATUS_MSG_CANCELED,
                         task.status_message)
        self.assertEqual(task.status, ScanTask.CANCELED)
        self.assertEqual(end_time.replace(microsecond=0),
                         task.end_time.replace(microsecond=0))

    def test_successful_complete(self):
        """Create a scan task and complete it."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        end_time = datetime.utcnow()
        task.complete('great')
        task.save()
        self.assertEqual('great',
                         task.status_message)
        self.assertEqual(task.status, ScanTask.COMPLETED)
        self.assertEqual(end_time.replace(microsecond=0),
                         task.end_time.replace(microsecond=0))

    def test_scantask_fail(self):
        """Create a scan task and fail it."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        # pylint: disable=invalid-name
        MSG = 'Test Fail.'
        end_time = datetime.utcnow()
        task.fail(MSG)
        task.save()
        self.assertEqual(MSG,
                         task.status_message)
        self.assertEqual(task.status, ScanTask.FAILED)
        self.assertEqual(end_time.replace(microsecond=0),
                         task.end_time.replace(microsecond=0))

    def test_scantask_increment(self):
        """Test scan task increment feature."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        # pylint: disable=invalid-name
        task.save()
        task.increment_stats('foo', increment_sys_count=True,
                             increment_sys_scanned=True,
                             increment_sys_failed=True,
                             increment_sys_unreachable=True)
        self.assertEqual(1, task.systems_count)
        self.assertEqual(1, task.systems_scanned)
        self.assertEqual(1, task.systems_failed)
        self.assertEqual(1, task.systems_unreachable)
        task.increment_stats('foo', increment_sys_count=True,
                             increment_sys_scanned=True,
                             increment_sys_failed=True,
                             increment_sys_unreachable=True)
        self.assertEqual(2, task.systems_count)
        self.assertEqual(2, task.systems_scanned)
        self.assertEqual(2, task.systems_failed)
        self.assertEqual(2, task.systems_unreachable)

    def test_scantask_reset_stats(self):
        """Test scan task reset stat feature."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        # pylint: disable=invalid-name
        task.save()
        task.increment_stats('foo', increment_sys_count=True,
                             increment_sys_scanned=True,
                             increment_sys_failed=True,
                             increment_sys_unreachable=True)
        self.assertEqual(1, task.systems_count)
        self.assertEqual(1, task.systems_scanned)
        self.assertEqual(1, task.systems_failed)
        self.assertEqual(1, task.systems_unreachable)
        task.reset_stats()
        self.assertEqual(None, task.systems_count)
        self.assertEqual(None, task.systems_scanned)
        self.assertEqual(None, task.systems_failed)
        self.assertEqual(None, task.systems_unreachable)

        systems_count,\
            systems_scanned,\
            systems_failed,\
            systems_unreachable = task.calculate_counts()

        self.assertEqual(systems_count, 0)
        self.assertEqual(systems_scanned, 0)
        self.assertEqual(systems_failed, 0)
        self.assertEqual(systems_unreachable, 0)

    def test_calculate_counts(self):
        """Test calculate counts."""
        task = ScanTask.objects.create(
            job=self.scan_job,
            source=self.source,
            scan_type=ScanTask.SCAN_TYPE_CONNECT,
            status=ScanTask.PENDING)
        # pylint: disable=invalid-name
        task.save()
        task.increment_stats('foo', increment_sys_count=True,
                             increment_sys_scanned=True,
                             increment_sys_failed=True,
                             increment_sys_unreachable=True)
        systems_count,\
            systems_scanned,\
            systems_failed,\
            systems_unreachable = task.calculate_counts()
        self.assertEqual(systems_count, 1)
        self.assertEqual(systems_scanned, 1)
        self.assertEqual(systems_failed, 1)
        self.assertEqual(systems_unreachable, 1)
예제 #28
0
    def setUp(self):
        """Create test setup."""
        management.call_command('flush', '--no-input')
        self.cred = Credential.objects.create(name='cred1',
                                              username='******',
                                              password='******',
                                              become_password=None,
                                              ssh_keyfile=None)
        self.cred.save()
        self.cred_for_upload = self.cred.id

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

        self.test1 = Scan(name='test1', scan_type=ScanTask.SCAN_TYPE_INSPECT)
        self.test1.save()
        self.test1.sources.add(self.source)
        self.test1.save()

        self.test2 = Scan(name='test2', scan_type=ScanTask.SCAN_TYPE_CONNECT)
        self.test2.save()
        self.test2.sources.add(self.source)
        self.test2.save()

        # self.test1 will not have a most_recent_scanjob, self.test2
        # will.
        job = ScanJob(scan=self.test2)
        job.save()
        job.sources.add(self.source)
        job.save()

        self.test2.most_recent_scanjob = job
        self.test2.save()

        results1 = [{
            'id':
            1,
            'name':
            'test1',
            'sources': [{
                'id': 1,
                'name': 'source1',
                'source_type': 'network'
            }],
            'scan_type':
            'inspect'
        }, {
            'id':
            2,
            'jobs': [{
                'id': 1
            }],
            'most_recent': {
                'id': 1,
                'scan_type': 'inspect',
                'status': 'created',
                'status_details': {
                    'job_status_message': 'Job is created.'
                }
            },
            'name':
            'test2',
            'sources': [{
                'id': 1,
                'name': 'source1',
                'source_type': 'network'
            }],
            'scan_type':
            'connect'
        }]
        self.expected = {
            'count': 2,
            'next': None,
            'previous': None,
            'results': results1
        }
예제 #29
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_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()

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

    def test_run_no_source_options(self):
        """Test the running connect task with no source options."""
        task = ConnectTaskRunner(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 = 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)

    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 = 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)

    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 = ConnectTaskRunner(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 = 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, 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 = 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, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    def test_run_with_timeout_err(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 = 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, ANY)
            self.assertEqual(status[1], ScanTask.FAILED)

    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)

    def test_run_sat6_v2(self):
        """Test the running connect task for Sat6 with api version 2."""
        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',
                   return_value=(200, 2)) 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, ANY)
                    mock_host_count.assert_called_once_with()
                    mock_hosts.assert_called_once_with()
                    self.assertEqual(status[1], ScanTask.COMPLETED)
예제 #30
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)