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)
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)
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
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)
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')
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)
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)
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)
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)
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')
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)
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()
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)
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
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
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')
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
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)
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)
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)
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)
class InspectTaskRunnerTest(TestCase): """Tests against the InspectTaskRunner class and functions.""" runner = None def setUp(self): """Create test case setup.""" self.cred = Credential(name='cred1', username='******', password='******', become_password=None, ssh_keyfile=None) self.cred.save() self.source = Source(name='source1', port=22, hosts='["1.2.3.4"]') self.source.save() self.source.credentials.add(self.cred) self.conn_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT, source=self.source, sequence_number=1, start_time=datetime.utcnow()) self.conn_task.update_stats('TEST_VC.', sys_count=5) self.conn_task.complete() self.scan_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_INSPECT, source=self.source, sequence_number=2, start_time=datetime.utcnow()) self.scan_task.save() self.scan_task.prerequisites.add(self.conn_task) self.scan_task.save() self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT) self.scan_job.save() self.scan_job.tasks.add(self.scan_task) self.inspect_results = JobInspectionResult() self.inspect_results.save() self.scan_job.inspection_results = self.inspect_results self.scan_job.save() self.runner = InspectTaskRunner(scan_job=self.scan_job, scan_task=self.scan_task) def tearDown(self): """Cleanup test case setup.""" pass def test_get_nics(self): """Test the get_nics method.""" guest = Mock() nics = [] for k in range(0, 2): nic = Mock() network = Mock() nic.network = network nic.macAddress = 'mac' + str(k) ip_config = Mock() ip_addr = Mock() ip_addr.ipAddress = 'ip' + str(k) addresses = [ip_addr] ip_config.ipAddress = addresses nic.ipConfig = ip_config nics.append(nic) guest.net = nics mac_addresses, ip_addresses = get_nics(guest) self.assertEqual(mac_addresses, ['mac0', 'mac1']) self.assertEqual(ip_addresses, ['ip0', 'ip1']) def test__none(self): """Test get result method when no results exist.""" results = self.runner.get_result() self.assertEqual(results, None) def test_get_result(self): """Test get results method when results exist.""" inspect_result = TaskInspectionResult(source=self.source, scan_task=self.scan_task) inspect_result.save() self.inspect_results.results.add(inspect_result) self.inspect_results.save() results = self.runner.get_result() self.assertEqual(results, inspect_result) # pylint: disable=too-many-locals def test_get_vm_info(self): """Test the get vm info method.""" data_center = 'dc1' cluster = 'cluster1' host = Mock() host_sum = Mock() host_config = Mock() host_config.name = 'host1' host_sum.config = host_config host_hard = Mock() host_hard.numCpuCores = 12 host_hard.numCpuThreads = 24 host_sum.hardware = host_hard host.summary = host_sum virtual_machine = Mock() summary = Mock() config = Mock() runtime = Mock() sum_guest = Mock() config.name = 'vm1' config.uuid = '1111' config.memorySizeMB = 1024 config.numCpu = 2 config.guestFullName = 'Red Hat 7' runtime.powerState = 'powerOn' sum_guest.hostName = 'hostname' summary.config = config summary.runtime = runtime summary.guest = sum_guest virtual_machine.summary = summary self.scan_task.update_stats('TEST_VC.', sys_count=5, sys_failed=0, sys_scanned=0) getnics = (['00:50:56:9e:09:8c'], ['1.2.3.4']) inspect_result = TaskInspectionResult(source=self.scan_task.source, scan_task=self.scan_task) inspect_result.save() self.inspect_results.results.add(inspect_result) self.inspect_results.save() with patch('scanner.vcenter.inspect.get_nics', return_value=getnics): self.runner.inspect_result = inspect_result self.runner.get_vm_info(data_center, cluster, host, virtual_machine) inspect_result = TaskInspectionResult.objects.filter( scan_task=self.scan_task.id).first() sys_results = inspect_result.systems.all() expected_facts = { 'vm.cluster': 'cluster1', 'vm.cpu_count': 2, 'vm.datacenter': 'dc1', 'vm.dns_name': 'hostname', 'vm.host.cpu_cores': 12, 'vm.host.cpu_count': 2, 'vm.host.cpu_threads': 24, 'vm.host.name': 'host1', 'vm.ip_addresses': ['1.2.3.4'], 'vm.mac_addresses': ['00:50:56:9e:09:8c'], 'vm.memory_size': 1, 'vm.name': 'vm1', 'vm.os': 'Red Hat 7', 'vm.state': 'powerOn', 'vm.uuid': '1111' } sys_fact = {} for raw_fact in sys_results.first().facts.all(): # Must read as JSON as this is what task.py does sys_fact[raw_fact.name] = json.loads(raw_fact.value) self.assertEqual(1, len(sys_results)) self.assertEqual('vm1', sys_results.first().name) self.assertEqual(expected_facts, sys_fact) # pylint: disable=too-many-locals def test_recurse_datacenter(self): """Test the recurse_datacenter method.""" inspect_result = TaskInspectionResult(source=self.scan_task.source, scan_task=self.scan_task) inspect_result.save() sys_result = SystemInspectionResult( name='vm1', status=SystemInspectionResult.SUCCESS) sys_result.save() inspect_result.systems.add(sys_result) inspect_result.save() self.inspect_results.results.add(inspect_result) self.inspect_results.save() vcenter = Mock() content = Mock() root_folder = Mock() child_entity = [] for k in range(0, 2): child = Mock() child.name = 'dc' + str(k) host_folder = Mock() clusters = [] for j in range(0, 1): cluster = Mock() cluster.name = 'cluster' + str(j) host = Mock() h_summary = Mock(name='h_summary') h_config = Mock(name='h_config') h_config.name = 'host1' h_summary.config = h_config host.summary = h_summary virtual_machine = Mock(name='vm') virtual_machine.summary.config.name = 'host1' host.vm = [virtual_machine] hosts = [host] cluster.host = hosts clusters.append(cluster) host_folder.childEntity = clusters child.hostFolder = host_folder child_entity.append(child) root_folder.childEntity = child_entity content.rootFolder = root_folder vcenter.RetrieveContent = Mock(return_value=content) with patch.object(InspectTaskRunner, 'get_vm_info') as mock_get_vm_info: self.runner.inspect_result = inspect_result self.runner.recurse_datacenter(vcenter) mock_get_vm_info.assert_called_with(ANY, ANY, ANY, ANY) def test_inspect(self): """Test the inspect method.""" with patch('scanner.vcenter.inspect.vcenter_connect', return_value=Mock()) as mock_vcenter_connect: with patch.object(InspectTaskRunner, 'recurse_datacenter') as mock_recurse: self.runner.connect_scan_task = self.conn_task self.runner.inspect() mock_vcenter_connect.assert_called_once_with(ANY) mock_recurse.assert_called_once_with(ANY) def test_failed_run(self): """Test the run method.""" with patch.object(InspectTaskRunner, 'inspect', side_effect=invalid_login) as mock_connect: status = self.runner.run() self.assertEqual(ScanTask.FAILED, status[1]) mock_connect.assert_called_once_with() def test_prereq_failed(self): """Test the run method.""" self.conn_task.status = ScanTask.FAILED self.conn_task.save() status = self.runner.run() self.assertEqual(ScanTask.FAILED, status[1]) def test_run(self): """Test the run method.""" with patch.object(InspectTaskRunner, 'inspect') as mock_connect: status = self.runner.run() self.assertEqual(ScanTask.COMPLETED, status[1]) mock_connect.assert_called_once_with()
class 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)
class InspectTaskRunnerTest(TestCase): """Tests against the InspectTaskRunner class and functions.""" runner = None def setUp(self): """Create test case setup.""" self.cred = Credential(name='cred1', username='******', password='******', sudo_password=None, ssh_keyfile=None) self.cred.save() self.source = Source(name='source1', port=22) self.source.save() self.source.credentials.add(self.cred) self.host = HostRange(host_range='1.2.3.4', source_id=self.source.id) self.host.save() self.source.hosts.add(self.host) self.scan_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_INSPECT, source=self.source, sequence_number=2) self.scan_task.save() self.conn_task = ScanTask(scan_type=ScanTask.SCAN_TYPE_CONNECT, source=self.source, sequence_number=1) self.conn_task.systems_count = 5 self.conn_task.status = ScanTask.COMPLETED self.conn_task.save() self.scan_task.prerequisites.add(self.conn_task) self.scan_task.save() self.scan_job = ScanJob(scan_type=ScanTask.SCAN_TYPE_INSPECT) self.scan_job.save() self.scan_job.tasks.add(self.scan_task) self.inspect_results = InspectionResults(scan_job=self.scan_job) self.inspect_results.save() self.runner = InspectTaskRunner(scan_job=self.scan_job, scan_task=self.scan_task, inspect_results=self.inspect_results) def tearDown(self): """Cleanup test case setup.""" pass def test_get_nics(self): """Test the get_nics method.""" guest = Mock() nics = [] for k in range(0, 2): nic = Mock() network = Mock() nic.network = network nic.macAddress = 'mac' + str(k) ip_config = Mock() ip_addr = Mock() ip_addr.ipAddress = 'ip' + str(k) addresses = [ip_addr] ip_config.ipAddress = addresses nic.ipConfig = ip_config nics.append(nic) guest.net = nics mac_addresses, ip_addresses = get_nics(guest) self.assertEqual(mac_addresses, ['mac0', 'mac1']) self.assertEqual(ip_addresses, ['ip0', 'ip1']) def test_vmsummary(self): """Test the vmsummary method.""" summary = Mock() guest = Mock() config = Mock() runtime = Mock() sum_guest = Mock() config.uuid = '1111' config.memorySizeMB = 1024 config.numCpu = 2 config.guestFullName = 'Red Hat 7' runtime.powerState = 'powerOn' sum_guest.hostName = 'hostname' summary.config = config summary.runtime = runtime summary.guest = sum_guest with patch('scanner.vcenter.inspect.get_nics', return_value=(['mac1'], ['ip1'])) as mock_get_nics: expected = { 'cpu': '2', 'hostname': 'hostname', 'ip_address': 'ip1', 'mac': 'mac1', 'mem': '1.0', 'ostype': 'Red Hat 7', 'state': 'powerOn', 'uuid': '1111' } vm_summary = vmsummary(summary, guest) mock_get_nics.assert_called_once_with(ANY) self.assertEqual(vm_summary, expected) def test_get_results_none(self): """Test get results method when no results exist.""" results = self.runner.get_results() self.assertEqual(results, None) def test_get_results(self): """Test get results method when results exist.""" inspect_result = InspectionResult(source=self.source, scan_task=self.scan_task) inspect_result.save() self.inspect_results.results.add(inspect_result) self.inspect_results.save() results = self.runner.get_results() self.assertEqual(results, inspect_result) def test_get_vm_info(self): """Test the get vm info method.""" data_center = 'dc1' cluster = 'cluster1' host = 'host1' virtual_machine = Mock() summary = Mock() config = Mock() config.name = 'vm1' summary.config = config virtual_machine.summary = summary vm_summary = { 'cpu': '2', 'hostname': 'hostname', 'ip_address': 'ip1', 'mac': 'mac1', 'mem': '1.0', 'ostype': 'Red Hat 7', 'state': 'powerOn', 'uuid': '1111' } with patch('scanner.vcenter.inspect.vmsummary', return_value=vm_summary): self.scan_task.systems_count = 5 self.scan_task.systems_failed = 0 self.scan_task.systems_scanned = 0 self.scan_task.save() self.runner.get_vm_info(data_center, cluster, host, virtual_machine) # pylint: disable=too-many-locals def test_recurse_datacenter(self): """Test the recurse_datacenter method.""" vcenter = Mock() content = Mock() root_folder = Mock() child_entity = [] for k in range(0, 2): child = Mock() child.name = 'dc' + str(k) host_folder = Mock() clusters = [] for j in range(0, 1): cluster = Mock() cluster.name = 'cluster' + str(j) host = Mock() h_summary = Mock() h_config = Mock() h_config.name = 'host1' h_summary.config = h_config host.summary = h_summary host.vm = [Mock()] hosts = [host] cluster.host = hosts clusters.append(cluster) host_folder.childEntity = clusters child.hostFolder = host_folder child_entity.append(child) root_folder.childEntity = child_entity content.rootFolder = root_folder vcenter.RetrieveContent = Mock(return_value=content) with patch.object(InspectTaskRunner, 'get_vm_info') as mock_get_vm_info: self.runner.recurse_datacenter(vcenter) mock_get_vm_info.assert_called_with(ANY, ANY, ANY, ANY) def test_inspect(self): """Test the inspect method.""" with patch('scanner.vcenter.inspect.vcenter_connect', return_value=Mock()) as mock_vcenter_connect: with patch.object(InspectTaskRunner, 'recurse_datacenter') as mock_recurse: self.runner.connect_scan_task = self.conn_task self.runner.inspect() mock_vcenter_connect.assert_called_once_with(ANY) mock_recurse.assert_called_once_with(ANY) def test_failed_run(self): """Test the run method.""" with patch.object(InspectTaskRunner, 'inspect', side_effect=invalid_login) as mock_connect: status = self.runner.run() self.assertEqual(ScanTask.FAILED, status) mock_connect.assert_called_once_with() def test_prereq_failed(self): """Test the run method.""" self.conn_task.status = ScanTask.FAILED self.conn_task.save() status = self.runner.run() self.assertEqual(ScanTask.FAILED, status) def test_run(self): """Test the run method.""" with patch.object(InspectTaskRunner, 'inspect') as mock_connect: status = self.runner.run() self.assertEqual(ScanTask.COMPLETED, status) mock_connect.assert_called_once_with()
class 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)
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': [] } })
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)
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 }
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)
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)