mirror of
https://github.com/ZwareBear/awx.git
synced 2026-04-21 07:21:49 -05:00
Merge pull request #6300 from chrismeyersfsu/feature-insights_proxy
insights proxy
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user