Merge pull request #6300 from chrismeyersfsu/feature-insights_proxy

insights proxy
This commit is contained in:
Chris Meyers
2017-05-26 14:17:04 -04:00
committed by GitHub
16 changed files with 346 additions and 18 deletions

View File

@@ -1114,7 +1114,8 @@ class InventorySerializer(BaseSerializerWithVariables):
fields = ('*', 'organization', 'kind', 'host_filter', 'variables', 'has_active_failures',
'total_hosts', 'hosts_with_active_failures', 'total_groups',
'groups_with_active_failures', 'has_inventory_sources',
'total_inventory_sources', 'inventory_sources_with_failures')
'total_inventory_sources', 'inventory_sources_with_failures',
'insights_credential',)
def get_related(self, obj):
res = super(InventorySerializer, self).get_related(obj)
@@ -1135,6 +1136,8 @@ class InventorySerializer(BaseSerializerWithVariables):
object_roles = self.reverse('api:inventory_object_roles_list', kwargs={'pk': obj.pk}),
instance_groups = self.reverse('api:inventory_instance_groups_list', kwargs={'pk': obj.pk}),
))
if obj.insights_credential:
res['insights_credential'] = self.reverse('api:credential_detail', kwargs={'pk': obj.insights_credential.pk})
if obj.organization:
res['organization'] = self.reverse('api:organization_detail', kwargs={'pk': obj.organization.pk})
return res
@@ -1208,6 +1211,8 @@ class HostSerializer(BaseSerializerWithVariables):
ad_hoc_command_events = self.reverse('api:host_ad_hoc_command_events_list', kwargs={'pk': obj.pk}),
fact_versions = self.reverse('api:host_fact_versions_list', kwargs={'pk': obj.pk}),
))
if self.version > 1:
res['insights'] = self.reverse('api:host_insights', kwargs={'pk': obj.pk})
if obj.inventory:
res['inventory'] = self.reverse('api:inventory_detail', kwargs={'pk': obj.inventory.pk})
if obj.last_job:

View File

@@ -120,6 +120,7 @@ host_urls = patterns('awx.api.views',
#url(r'^(?P<pk>[0-9]+)/single_fact/$', 'host_single_fact_view'),
url(r'^(?P<pk>[0-9]+)/fact_versions/$', 'host_fact_versions_list'),
url(r'^(?P<pk>[0-9]+)/fact_view/$', 'host_fact_compare_view'),
url(r'^(?P<pk>[0-9]+)/insights/$', 'host_insights'),
)
group_urls = patterns('awx.api.views',

View File

@@ -13,6 +13,7 @@ import socket
import subprocess
import sys
import logging
import requests
from base64 import b64encode
from collections import OrderedDict
@@ -70,7 +71,8 @@ from awx.conf.license import get_license, feature_enabled, feature_exists, Licen
from awx.main.models import * # noqa
from awx.main.utils import * # noqa
from awx.main.utils import (
callback_filter_out_ansible_extra_vars
callback_filter_out_ansible_extra_vars,
decrypt_field,
)
from awx.main.utils.filters import SmartFilter
@@ -2067,6 +2069,58 @@ class HostFactCompareView(SystemTrackingEnforcementMixin, SubDetailAPIView):
return Response(self.serializer_class(instance=fact_entry).data)
class HostInsights(GenericAPIView):
model = Host
serializer_class = EmptySerializer
new_in_320 = True
new_in_api_v2 = True
def _extract_insights_creds(self, credential):
return (credential.inputs['username'], decrypt_field(credential, 'password'))
def _get_insights(self, url, username, password):
session = requests.Session()
session.auth = requests.auth.HTTPBasicAuth(username, password)
headers = {'Content-Type': 'application/json'}
return session.get(url, headers=headers, timeout=120)
def get_insights(self, url, username, password):
try:
res = self._get_insights(url, username, password)
except requests.exceptions.SSLError:
return (dict(error=_('SSLError while trying to connect to {}').format(url)), status.HTTP_500_INTERNAL_SERVER_ERROR)
except requests.exceptions.Timeout:
return (dict(error=_('Request to {} timed out.').format(url)), status.HTTP_504_GATEWAY_TIMEOUT)
except requests.exceptions.RequestException as e:
return (dict(error=_('Unkown exception {} while trying to GET {}').format(e, url)), status.HTTP_500_INTERNAL_SERVER_ERROR)
if res.status_code != 200:
return (dict(error=_('Failed to gather reports and maintenance plans from Insights API at URL {}. Server responded with {} status code and message {}').format(url, res.status_code, res.content)), status.HTTP_500_INTERNAL_SERVER_ERROR)
try:
return (dict(insights_content=res.json()), status.HTTP_200_OK)
except ValueError:
return (dict(error=_('Expected JSON response from Insights but instead got {}').format(res.content)), status.HTTP_500_INTERNAL_SERVER_ERROR)
def get(self, request, *args, **kwargs):
host = self.get_object()
cred = None
if host.insights_system_id is None:
return Response(dict(error=_('This host is not recognized as an Insights host.')), status=status.HTTP_404_NOT_FOUND)
if host.inventory and host.inventory.insights_credential:
cred = host.inventory.insights_credential
else:
return Response(dict(error=_('No Insights Credential found for the Inventory, "{}", that this host belongs to.').format(host.inventory.name)), status=status.HTTP_404_NOT_FOUND)
url = settings.INSIGHTS_URL_BASE + '/r/insights/v3/systems/{}/reports/'.format(host.insights_system_id)
(username, password) = self._extract_insights_creds(cred)
(msg, err_code) = self.get_insights(url, username, password)
return Response(msg, status=err_code)
class GroupList(ListCreateAPIView):
model = Group