Skip to content

Commit

Permalink
Handle Satellite errors on a per system basis. Closes #792.
Browse files Browse the repository at this point in the history
  • Loading branch information
chambridge committed Feb 22, 2018
1 parent ea0afc2 commit 4663113
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 40 deletions.
27 changes: 17 additions & 10 deletions quipucords/scanner/satellite/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,36 @@ def record_conn_result(self, name, credential):
name, increment_sys_scanned=True)

@transaction.atomic
def record_inspect_result(self, name, facts):
def record_inspect_result(self, name, facts,
status=SystemInspectionResult.SUCCESS):
"""Record a new result.
:param name: The host name
:param facts: The dictionary of facts
:param status: The status of the inspection
"""
sys_result = SystemInspectionResult(
name=name,
status=SystemInspectionResult.SUCCESS)
status=status)
sys_result.save()

for key, val in facts.items():
if val is not None:
final_value = json.dumps(val)
stored_fact = RawFact(name=key, value=final_value)
stored_fact.save()
sys_result.facts.add(stored_fact)
if status == SystemInspectionResult.SUCCESS:
for key, val in facts.items():
if val is not None:
final_value = json.dumps(val)
stored_fact = RawFact(name=key, value=final_value)
stored_fact.save()
sys_result.facts.add(stored_fact)

self.inspect_scan_task.inspection_result.systems.add(sys_result)
self.inspect_scan_task.inspection_result.save()

self.inspect_scan_task.increment_stats(
name, increment_sys_scanned=True)
if status == SystemInspectionResult.SUCCESS:
self.inspect_scan_task.increment_stats(
name, increment_sys_scanned=True)
else:
self.inspect_scan_task.increment_stats(
name, increment_sys_failed=True)

def host_count(self):
"""Obtain the count of managed hosts."""
Expand Down
13 changes: 9 additions & 4 deletions quipucords/scanner/satellite/five.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import logging
import xmlrpc.client
from api.models import SystemInspectionResult
from scanner.satellite.api import SatelliteInterface, SatelliteException
from scanner.satellite import utils

Expand Down Expand Up @@ -187,12 +188,16 @@ def host_details(self, host_id, host_name, last_checkin,
details[VIRTUAL_HOST_NAME] = virtual_host.get(NAME)

client.auth.logout(key)

self.record_inspect_result(host_name, details)
logger.debug('host_id=%s, host_details=%s',
host_id, details)
except xmlrpc.client.Fault as xml_error:
raise SatelliteException(str(xml_error))
error_message = 'Satellite error encountered: %s\n' % xml_error
self.record_inspect_result(host_name, details,
status=SystemInspectionResult.FAILED)
logger.error(error_message)

self.record_inspect_result(host_name, details)
logger.debug('host_id=%s, host_details=%s',
host_id, details)
return details

def virtual_guests(self, virtual_host_id):
Expand Down
52 changes: 31 additions & 21 deletions quipucords/scanner/satellite/six.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import logging
import requests
from api.models import SystemInspectionResult
from scanner.satellite.api import SatelliteInterface, SatelliteException
from scanner.satellite import utils

Expand Down Expand Up @@ -403,16 +404,21 @@ def host_details(self, org_id, host_id, host_name):
host_name)
return details

details.update(host_fields(self.inspect_scan_task, 1,
HOSTS_FIELDS_V1_URL,
org_id, host_id))
details.update(host_subscriptions(self.inspect_scan_task,
HOSTS_SUBS_V1_URL,
org_id, host_id))

self.record_inspect_result(host_name, details)
logger.debug('host_id=%s, host_details=%s',
host_id, details)
try:
details.update(host_fields(self.inspect_scan_task, 1,
HOSTS_FIELDS_V1_URL,
org_id, host_id))
details.update(host_subscriptions(self.inspect_scan_task,
HOSTS_SUBS_V1_URL,
org_id, host_id))
self.record_inspect_result(host_name, details)
logger.debug('host_id=%s, host_details=%s',
host_id, details)
except SatelliteException as sat_error:
error_message = 'Satellite error encountered: %s\n' % sat_error
self.record_inspect_result(host_name, details,
status=SystemInspectionResult.FAILED)
logger.error(error_message)
return details

def hosts_facts(self):
Expand Down Expand Up @@ -512,17 +518,21 @@ def host_details(self, host_id, host_name):
logger.debug('Results already captured for host_name=%s',
host_name)
return details

details.update(host_fields(self.inspect_scan_task, 2,
HOSTS_FIELDS_V2_URL,
None, host_id))
details.update(host_subscriptions(self.inspect_scan_task,
HOSTS_SUBS_V2_URL,
None, host_id))

self.record_inspect_result(host_name, details)
logger.debug('host_id=%s, host_details=%s',
host_id, details)
try:
details.update(host_fields(self.inspect_scan_task, 2,
HOSTS_FIELDS_V2_URL,
None, host_id))
details.update(host_subscriptions(self.inspect_scan_task,
HOSTS_SUBS_V2_URL,
None, host_id))
self.record_inspect_result(host_name, details)
logger.debug('host_id=%s, host_details=%s',
host_id, details)
except SatelliteException as sat_error:
error_message = 'Satellite error encountered: %s\n' % sat_error
self.record_inspect_result(host_name, details,
status=SystemInspectionResult.FAILED)
logger.error(error_message)
return details

def hosts_facts(self):
Expand Down
15 changes: 10 additions & 5 deletions quipucords/scanner/satellite/tests_sat_five.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,16 @@ 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})
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})
inspect_result = self.scan_task.inspection_result
self.assertEqual(len(inspect_result.systems.all()), 1)
sys_result = inspect_result.systems.all().first()
self.assertEqual(sys_result.status, SystemInspectionResult.FAILED)
self.assertEqual(details, {})

@patch('xmlrpc.client.ServerProxy')
def test_virtual_guests_with_err(self, mock_serverproxy):
Expand Down
30 changes: 30 additions & 0 deletions quipucords/scanner/satellite/tests_sat_six.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
from scanner.test_util import create_scan_job


# pylint: disable=unused-argument
def mock_sat_exception(param1, param2, param3, param4, param5):
"""Mock method to throw satellite error."""
raise SatelliteException()


# pylint: disable=too-many-instance-attributes
class SatelliteSixV1Test(TestCase):
"""Tests Satellite 6 v1 functions."""
Expand Down Expand Up @@ -233,6 +239,18 @@ def test_host_details_skip(self):
self.assertEqual(len(inspect_result.systems.all()), 1)
self.assertEqual(detail, {})

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

def test_host_details(self):
"""Test host_details method with mock data."""
fields_return_value = {
Expand Down Expand Up @@ -614,6 +632,18 @@ def test_host_subscriptons(self):
'end_date': '2022-01-01 04:59:59 UTC'}]}
self.assertEqual(subs, expected)

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

def test_host_details(self):
"""Test host_details method with mock data."""
fields_return_value = {
Expand Down

0 comments on commit 4663113

Please sign in to comment.