From 82f5072c7d0a14a42cd819d7bda91457b1ae8b5e Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Mon, 12 Aug 2019 15:08:15 -0400 Subject: [PATCH] add support for Accept:application/json to /api/v2/metrics see: https://github.com/ansible/awx/issues/4144 --- awx/api/renderers.py | 14 ++++++++++++++ awx/api/views/metrics.py | 3 ++- awxkit/awxkit/api/pages/metrics.py | 12 ++---------- awxkit/awxkit/api/pages/page.py | 4 ++-- awxkit/requirements.txt | 1 - 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/awx/api/renderers.py b/awx/api/renderers.py index abf67ea351..06a6c9ce1d 100644 --- a/awx/api/renderers.py +++ b/awx/api/renderers.py @@ -2,6 +2,7 @@ # All Rights Reserved. from django.utils.safestring import SafeText +from prometheus_client.parser import text_string_to_metric_families # Django REST Framework from rest_framework import renderers @@ -103,3 +104,16 @@ class AnsiTextRenderer(PlainTextRenderer): class AnsiDownloadRenderer(PlainTextRenderer): format = "ansi_download" + + +class PrometheusJSONRenderer(renderers.JSONRenderer): + + def render(self, data, accepted_media_type=None, renderer_context=None): + parsed_metrics = text_string_to_metric_families(data) + data = {} + for family in parsed_metrics: + for sample in family.samples: + data[sample[0]] = {"labels": sample[1], "value": sample[2]} + return super(PrometheusJSONRenderer, self).render( + data, accepted_media_type, renderer_context + ) diff --git a/awx/api/views/metrics.py b/awx/api/views/metrics.py index 2c15c4e8c8..092e36efde 100644 --- a/awx/api/views/metrics.py +++ b/awx/api/views/metrics.py @@ -31,9 +31,10 @@ class MetricsView(APIView): swagger_topic = 'Metrics' renderer_classes = [renderers.PlainTextRenderer, + renderers.PrometheusJSONRenderer, renderers.BrowsableAPIRenderer,] - def get(self, request, format='txt'): + def get(self, request): ''' Show Metrics Details ''' if (request.user.is_superuser or request.user.is_system_auditor): return Response(metrics().decode('UTF-8')) diff --git a/awxkit/awxkit/api/pages/metrics.py b/awxkit/awxkit/api/pages/metrics.py index 195296d3ac..2e3cafaafd 100644 --- a/awxkit/awxkit/api/pages/metrics.py +++ b/awxkit/awxkit/api/pages/metrics.py @@ -1,5 +1,3 @@ -from prometheus_client.parser import text_string_to_metric_families - from awxkit.api.resources import resources from . import base from . import page @@ -8,14 +6,8 @@ from . import page class Metrics(base.Base): def get(self, **query_parameters): - request = self.connection.get(self.endpoint, query_parameters) - self.page_identity(request, ignore_json_errors=True) - parsed_metrics = text_string_to_metric_families(request.text) - data = {} - for family in parsed_metrics: - for sample in family.samples: - data[sample[0]] = {"labels": sample[1], "value": sample[2]} - request.json = lambda: data + request = self.connection.get(self.endpoint, query_parameters, + headers={'Accept': 'application/json'}) return self.page_identity(request) diff --git a/awxkit/awxkit/api/pages/page.py b/awxkit/awxkit/api/pages/page.py index 19d6a2736f..a88c9e36bd 100644 --- a/awxkit/awxkit/api/pages/page.py +++ b/awxkit/awxkit/api/pages/page.py @@ -172,7 +172,7 @@ class Page(object): resp.status_code = 200 return cls(r=resp) - def page_identity(self, response, request_json=None, ignore_json_errors=False): + def page_identity(self, response, request_json=None): """Takes a `requests.Response` and returns a new __item_class__ instance if the request method is not a get, or returns a __class__ instance if the request path is different than the caller's `endpoint`. @@ -191,7 +191,7 @@ class Page(object): data = response.json() except ValueError as e: # If there was no json to parse data = dict() - if (response.text and not ignore_json_errors) or response.status_code not in (200, 202, 204): + if response.text or response.status_code not in (200, 202, 204): text = response.text if len(text) > 1024: text = text[:1024] + '... <<< Truncated >>> ...' diff --git a/awxkit/requirements.txt b/awxkit/requirements.txt index 35b5195ccd..ee3930f7dc 100644 --- a/awxkit/requirements.txt +++ b/awxkit/requirements.txt @@ -1,7 +1,6 @@ PyYAML>=5.1 cryptography flake8 -prometheus-client python-dateutil requests termcolor