Add support for capturing stdout associated with job events and ad hoc command events.

* New event types for stdout lines not associated with a callback event.
* New stdout, start_line, end_line and verbosity fields for job/ahc events.
* Callback plugins to wrap Ansible default/minimal stdout callbacks and embed callback event data using ANSI escape sequences.
* Callback plugin library to wrap ansible.display.Display class methods.
* Output filter to extract event data from stdout and create job/ahc events.
* Update stdout formats to strip new ANSI escape sequences.
This commit is contained in:
Chris Church
2016-10-22 00:15:49 -04:00
parent d253eabe5d
commit c18b6c1352
20 changed files with 1387 additions and 850 deletions

View File

@@ -10,8 +10,9 @@ import time
import socket
import sys
import logging
from base64 import b64encode
from base64 import b64encode, b64decode
from collections import OrderedDict
from HTMLParser import HTMLParser
# Django
from django.conf import settings
@@ -3050,21 +3051,6 @@ class GroupJobEventsList(BaseJobEventsList):
class JobJobEventsList(BaseJobEventsList):
parent_model = Job
authentication_classes = [TaskAuthentication] + api_settings.DEFAULT_AUTHENTICATION_CLASSES
permission_classes = (TaskPermission,)
# Post allowed for job event callback only.
def post(self, request, *args, **kwargs):
parent_obj = get_object_or_404(self.parent_model, pk=self.kwargs['pk'])
data = request.data.copy()
data['job'] = parent_obj.pk
serializer = self.get_serializer(data=data)
if serializer.is_valid():
self.instance = serializer.save()
headers = {'Location': serializer.data['url']}
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class JobJobPlaysList(BaseJobEventsList):
@@ -3455,25 +3441,8 @@ class HostAdHocCommandEventsList(BaseAdHocCommandEventsList):
class AdHocCommandAdHocCommandEventsList(BaseAdHocCommandEventsList):
parent_model = AdHocCommand
authentication_classes = [TaskAuthentication] + api_settings.DEFAULT_AUTHENTICATION_CLASSES
permission_classes = (TaskPermission,)
new_in_220 = True
# Post allowed for ad hoc event callback only.
def post(self, request, *args, **kwargs):
if request.user:
raise PermissionDenied()
parent_obj = get_object_or_404(self.parent_model, pk=self.kwargs['pk'])
data = request.data.copy()
data['ad_hoc_command'] = parent_obj
serializer = self.get_serializer(data=data)
if serializer.is_valid():
self.instance = serializer.save()
headers = {'Location': serializer.data['url']}
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AdHocCommandActivityStreamList(SubListAPIView):
@@ -3583,7 +3552,11 @@ class UnifiedJobStdout(RetrieveAPIView):
dark_bg = (content_only and dark) or (not content_only and (dark or not dark_val))
content, start, end, absolute_end = unified_job.result_stdout_raw_limited(start_line, end_line)
# Remove any ANSI escape sequences containing job event data.
content = re.sub(r'\x1b\[K(?:[A-Za-z0-9+/=]+\x1b\[\d+D)+\x1b\[K', '', content)
body = ansiconv.to_html(cgi.escape(content))
context = {
'title': get_view_name(self.__class__),
'body': mark_safe(body),