Remove host insights view

This commit is contained in:
Bill Nottingham
2021-05-21 00:18:04 -04:00
parent b6ced2b8dc
commit f460f70513
13 changed files with 2 additions and 854 deletions

View File

@@ -503,13 +503,6 @@ class Host(CommonModelNameNotUnique, RelatedJobsMixin):
null=True,
help_text=_('The date and time ansible_facts was last modified.'),
)
insights_system_id = models.TextField(
blank=True,
default=None,
null=True,
db_index=True,
help_text=_('Red Hat Insights host unique identifier.'),
)
objects = HostManager()

View File

@@ -845,23 +845,6 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
continue
host.ansible_facts = ansible_facts
host.ansible_facts_modified = now()
ansible_local = ansible_facts.get('ansible_local', {}).get('insights', {})
ansible_facts = ansible_facts.get('insights', {})
ansible_local_system_id = ansible_local.get('system_id', None) if isinstance(ansible_local, dict) else None
ansible_facts_system_id = ansible_facts.get('system_id', None) if isinstance(ansible_facts, dict) else None
if ansible_local_system_id:
print("Setting local {}".format(ansible_local_system_id))
logger.debug(
"Insights system_id {} found for host <{}, {}> in"
" ansible local facts".format(ansible_local_system_id, host.inventory.id, host.name)
)
host.insights_system_id = ansible_local_system_id
elif ansible_facts_system_id:
logger.debug(
"Insights system_id {} found for host <{}, {}> in"
" insights facts".format(ansible_local_system_id, host.inventory.id, host.name)
)
host.insights_system_id = ansible_facts_system_id
host.save()
system_tracking_logger.info(
'New fact for inventory {} host {}'.format(smart_str(host.inventory.name), smart_str(host.name)),

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +0,0 @@
import json
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(dir_path, 'insights_hosts.json')) as data_file:
TEST_INSIGHTS_HOSTS = json.load(data_file)
with open(os.path.join(dir_path, 'insights.json')) as data_file:
TEST_INSIGHTS_PLANS = json.load(data_file)
with open(os.path.join(dir_path, 'insights_remediations.json')) as data_file:
TEST_INSIGHTS_REMEDIATIONS = json.load(data_file)['data']

View File

@@ -1,13 +0,0 @@
{
"total": 1,
"count": 1,
"page": 1,
"per_page": 50,
"results": [
{
"id": "11111111-1111-1111-1111-111111111111",
"insights_id": "22222222-2222-2222-2222-222222222222",
"updated": "2019-03-19T21:59:09.213151-04:00"
}
]
}

View File

@@ -1,33 +0,0 @@
{
"data": [
{
"id": "9197ba55-0abc-4028-9bbe-269e530f8bd5",
"name": "Fix Critical CVEs",
"created_by": {
"username": "jharting@redhat.com",
"first_name": "Jozef",
"last_name": "Hartinger"
},
"created_at": "2018-12-05T08:19:36.641Z",
"updated_by": {
"username": "jharting@redhat.com",
"first_name": "Jozef",
"last_name": "Hartinger"
},
"updated_at": "2018-12-05T08:19:36.641Z",
"issue_count": 0,
"system_count": 0,
"needs_reboot": true
}
],
"meta": {
"count": 0,
"total": 0
},
"links": {
"first": null,
"last": null,
"next": null,
"previous": null
}
}

View File

@@ -1,145 +0,0 @@
from collections import namedtuple
import pytest
import requests
from awx.api.versioning import reverse
@pytest.mark.django_db
class TestHostInsights:
def test_insights_bad_host(self, get, hosts, user, mocker):
mocker.patch.object(requests.Session, 'get')
host = hosts(host_count=1)[0]
url = reverse('api:host_insights', kwargs={'pk': host.pk})
response = get(url, user('admin', True))
assert response.data['error'] == 'This host is not recognized as an Insights host.'
assert response.status_code == 404
def test_insights_host_missing_from_insights(self, get, hosts, insights_credential, user, mocker):
class Response:
status_code = 200
content = "{'results': []}"
def json(self):
return {'results': []}
mocker.patch.object(requests.Session, 'get', return_value=Response())
host = hosts(host_count=1)[0]
host.insights_system_id = '123e4567-e89b-12d3-a456-426655440000'
host.inventory.insights_credential = insights_credential
host.inventory.save()
host.save()
url = reverse('api:host_insights', kwargs={'pk': host.pk})
response = get(url, user('admin', True))
assert response.data['error'] == ('Could not translate Insights system ID 123e4567-e89b-12d3-a456-426655440000' ' into an Insights platform ID.')
assert response.status_code == 404
def test_insights_no_credential(self, get, hosts, user, mocker):
mocker.patch.object(requests.Session, 'get')
host = hosts(host_count=1)[0]
host.insights_system_id = '123e4567-e89b-12d3-a456-426655440000'
host.save()
url = reverse('api:host_insights', kwargs={'pk': host.pk})
response = get(url, user('admin', True))
assert response.data['error'] == 'The Insights Credential for "test-inv" was not found.'
assert response.status_code == 404
@pytest.mark.parametrize(
"status_code, exception, error, message",
[
(
502,
requests.exceptions.SSLError,
'SSLError while trying to connect to https://myexample.com/whocares/me/',
None,
),
(
504,
requests.exceptions.Timeout,
'Request to https://myexample.com/whocares/me/ timed out.',
None,
),
(502, requests.exceptions.RequestException, 'booo!', 'Unknown exception booo! while trying to GET https://myexample.com/whocares/me/'),
],
)
def test_insights_exception(self, get, hosts, insights_credential, user, mocker, status_code, exception, error, message):
mocker.patch.object(requests.Session, 'get', side_effect=exception(error))
host = hosts(host_count=1)[0]
host.insights_system_id = '123e4567-e89b-12d3-a456-426655440000'
host.inventory.insights_credential = insights_credential
host.inventory.save()
host.save()
url = reverse('api:host_insights', kwargs={'pk': host.pk})
response = get(url, user('admin', True))
assert response.data['error'] == message or error
assert response.status_code == status_code
def test_insights_unauthorized(self, get, hosts, insights_credential, user, mocker):
Response = namedtuple('Response', 'status_code content')
mocker.patch.object(requests.Session, 'get', return_value=Response(401, 'mock 401 err msg'))
host = hosts(host_count=1)[0]
host.insights_system_id = '123e4567-e89b-12d3-a456-426655440000'
host.inventory.insights_credential = insights_credential
host.inventory.save()
host.save()
url = reverse('api:host_insights', kwargs={'pk': host.pk})
response = get(url, user('admin', True))
assert response.data['error'] == ("Unauthorized access. Please check your Insights Credential username and password.")
assert response.status_code == 502
def test_insights_bad_status(self, get, hosts, insights_credential, user, mocker):
Response = namedtuple('Response', 'status_code content')
mocker.patch.object(requests.Session, 'get', return_value=Response(500, 'mock 500 err msg'))
host = hosts(host_count=1)[0]
host.insights_system_id = '123e4567-e89b-12d3-a456-426655440000'
host.inventory.insights_credential = insights_credential
host.inventory.save()
host.save()
url = reverse('api:host_insights', kwargs={'pk': host.pk})
response = get(url, user('admin', True))
assert response.data['error'].startswith("Failed to access the Insights API at URL")
assert "Server responded with 500 status code and message mock 500 err msg" in response.data['error']
assert response.status_code == 502
def test_insights_bad_json(self, get, hosts, insights_credential, user, mocker):
class Response:
status_code = 200
content = 'booo!'
def json(self):
raise ValueError("we do not care what this is")
mocker.patch.object(requests.Session, 'get', return_value=Response())
host = hosts(host_count=1)[0]
host.insights_system_id = '123e4567-e89b-12d3-a456-426655440000'
host.inventory.insights_credential = insights_credential
host.inventory.save()
host.save()
url = reverse('api:host_insights', kwargs={'pk': host.pk})
response = get(url, user('admin', True))
assert response.data['error'].startswith("Expected JSON response from Insights at URL")
assert 'insights_id=123e4567-e89b-12d3-a456-426655440000' in response.data['error']
assert response.data['error'].endswith("but instead got booo!")
assert response.status_code == 502

View File

@@ -71,7 +71,7 @@ def test_finish_job_fact_cache_with_existing_data(job, hosts, inventory, mocker,
for h in hosts:
h.save = mocker.Mock()
ansible_facts_new = {"foo": "bar", "insights": {"system_id": "updated_by_scan"}}
ansible_facts_new = {"foo": "bar"}
filepath = os.path.join(fact_cache, hosts[1].name)
with open(filepath, 'w') as f:
f.write(json.dumps(ansible_facts_new))
@@ -90,31 +90,9 @@ def test_finish_job_fact_cache_with_existing_data(job, hosts, inventory, mocker,
assert host.ansible_facts == {"a": 1, "b": 2}
assert host.ansible_facts_modified is None
assert hosts[1].ansible_facts == ansible_facts_new
assert hosts[1].insights_system_id == "updated_by_scan"
hosts[1].save.assert_called_once_with()
def test_finish_job_fact_cache_with_malformed_fact(job, hosts, inventory, mocker, tmpdir):
fact_cache = os.path.join(tmpdir, 'facts')
modified_times = {}
job.start_job_fact_cache(fact_cache, modified_times, 0)
for h in hosts:
h.save = mocker.Mock()
for h in hosts:
filepath = os.path.join(fact_cache, h.name)
with open(filepath, 'w') as f:
json.dump({'ansible_local': {'insights': 'this is an unexpected error from ansible'}}, f)
new_modification_time = time.time() + 3600
os.utime(filepath, (new_modification_time, new_modification_time))
job.finish_job_fact_cache(fact_cache, modified_times)
for h in hosts:
assert h.insights_system_id is None
def test_finish_job_fact_cache_with_bad_data(job, hosts, inventory, mocker, tmpdir):
fact_cache = os.path.join(tmpdir, 'facts')
modified_times = {}

View File

@@ -1,26 +0,0 @@
# Copyright (c) 2017 Ansible Tower by Red Hat
# All Rights Reserved.
from awx.main.utils.insights import filter_insights_api_response
from awx.main.tests.data.insights import TEST_INSIGHTS_HOSTS, TEST_INSIGHTS_PLANS, TEST_INSIGHTS_REMEDIATIONS
def test_filter_insights_api_response():
actual = filter_insights_api_response(TEST_INSIGHTS_HOSTS['results'][0], TEST_INSIGHTS_PLANS, TEST_INSIGHTS_REMEDIATIONS)
assert actual['last_check_in'] == '2019-03-19T21:59:09.213151-04:00'
assert len(actual['reports']) == 5
assert len(actual['reports'][0]['maintenance_actions']) == 1
assert actual['reports'][0]['maintenance_actions'][0]['name'] == "Fix Critical CVEs"
rule = actual['reports'][0]['rule']
assert rule['severity'] == 'WARN'
assert rule['description'] == ("Kernel vulnerable to side-channel attacks in modern microprocessors (CVE-2017-5715/Spectre)")
assert rule['category'] == 'Security'
assert rule['summary'] == (
"A vulnerability was discovered in modern microprocessors supported by the kernel,"
" whereby an unprivileged attacker can use this flaw to bypass restrictions to gain read"
" access to privileged memory.\nThe issue was reported as [CVE-2017-5715 / Spectre]"
"(https://access.redhat.com/security/cve/CVE-2017-5715).\n"
)

View File

@@ -1,39 +0,0 @@
# Copyright (c) 2017 Ansible Tower by Red Hat
# All Rights Reserved.
# Old Insights API -> New API
#
# last_check_in is missing entirely, is now provided by a different endpoint
# reports[] -> []
# reports[].rule.{description,summary} -> [].rule.{description,summary}
# reports[].rule.category -> [].rule.category.name
# reports[].rule.severity (str) -> [].rule.total_risk (int)
# reports[].rule.{ansible,ansible_fix} appears to be unused
# reports[].maintenance_actions[] missing entirely, is now provided
# by a different Insights endpoint
def filter_insights_api_response(platform_info, reports, remediations):
severity_mapping = {1: 'INFO', 2: 'WARN', 3: 'ERROR', 4: 'CRITICAL'}
new_json = {
'platform_id': platform_info['id'],
'last_check_in': platform_info.get('updated'),
'reports': [],
}
for rep in reports:
new_report = {'rule': {}, 'maintenance_actions': remediations}
rule = rep.get('rule') or {}
for k in ['description', 'summary']:
if k in rule:
new_report['rule'][k] = rule[k]
if 'category' in rule:
new_report['rule']['category'] = rule['category']['name']
if rule.get('total_risk') in severity_mapping:
new_report['rule']['severity'] = severity_mapping[rule['total_risk']]
new_json['reports'].append(new_report)
return new_json