Fix job template callback view to accept URL-encoded form data.

This commit is contained in:
Chris Church
2016-03-04 16:36:02 -05:00
parent 5759db1229
commit 60b6b6bfea
3 changed files with 28 additions and 8 deletions

View File

@@ -32,6 +32,7 @@ from django.http import HttpResponse
# Django REST Framework # Django REST Framework
from rest_framework.exceptions import PermissionDenied, ParseError from rest_framework.exceptions import PermissionDenied, ParseError
from rest_framework.parsers import FormParser
from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
@@ -2005,6 +2006,7 @@ class JobTemplateCallback(GenericAPIView):
model = JobTemplate model = JobTemplate
permission_classes = (JobTemplateCallbackPermission,) permission_classes = (JobTemplateCallbackPermission,)
serializer_class = EmptySerializer serializer_class = EmptySerializer
parser_classes = api_settings.DEFAULT_PARSER_CLASSES + [FormParser]
@csrf_exempt @csrf_exempt
@transaction.non_atomic_requests @transaction.non_atomic_requests

View File

@@ -11,6 +11,7 @@ import shutil
import sys import sys
import tempfile import tempfile
import time import time
import urllib
from multiprocessing import Process from multiprocessing import Process
from subprocess import Popen from subprocess import Popen
import re import re
@@ -463,6 +464,8 @@ class BaseTestMixin(QueueTestMixin, MockCommonlySlowTestMixin):
response = method(url, json.dumps(data), 'application/json') response = method(url, json.dumps(data), 'application/json')
elif data_type == 'yaml': elif data_type == 'yaml':
response = method(url, yaml.safe_dump(data), 'application/yaml') response = method(url, yaml.safe_dump(data), 'application/yaml')
elif data_type == 'form':
response = method(url, urllib.urlencode(data), 'application/x-www-form-urlencoded')
else: else:
self.fail('Unsupported data_type %s' % data_type) self.fail('Unsupported data_type %s' % data_type)
else: else:

View File

@@ -803,6 +803,21 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
self.assertEqual(job.hosts.count(), 1) self.assertEqual(job.hosts.count(), 1)
self.assertEqual(job.hosts.all()[0], host) self.assertEqual(job.hosts.all()[0], host)
# Create the job itself using URL-encoded form data instead of JSON.
result = self.post(url, data, expect=202, remote_addr=host_ip, data_type='form')
# Establish that we got back what we expect, and made the changes
# that we expect.
self.assertTrue('Location' in result.response, result.response)
self.assertEqual(jobs_qs.count(), 2)
job = jobs_qs[0]
self.assertEqual(urlparse.urlsplit(result.response['Location']).path,
job.get_absolute_url())
self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, host.name)
self.assertEqual(job.hosts.count(), 1)
self.assertEqual(job.hosts.all()[0], host)
# Run the callback job again with extra vars and verify their presence # Run the callback job again with extra vars and verify their presence
data.update(dict(extra_vars=dict(key="value"))) data.update(dict(extra_vars=dict(key="value")))
result = self.post(url, data, expect=202, remote_addr=host_ip) result = self.post(url, data, expect=202, remote_addr=host_ip)
@@ -853,9 +868,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
if host_ip: if host_ip:
break break
self.assertTrue(host) self.assertTrue(host)
self.assertEqual(jobs_qs.count(), 2)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 3) self.assertEqual(jobs_qs.count(), 3)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 4)
job = jobs_qs[0] job = jobs_qs[0]
self.assertEqual(job.launch_type, 'callback') self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, host.name) self.assertEqual(job.limit, host.name)
@@ -878,9 +893,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
if host_ip: if host_ip:
break break
self.assertTrue(host) self.assertTrue(host)
self.assertEqual(jobs_qs.count(), 3)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 4) self.assertEqual(jobs_qs.count(), 4)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 5)
job = jobs_qs[0] job = jobs_qs[0]
self.assertEqual(job.launch_type, 'callback') self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, host.name) self.assertEqual(job.limit, host.name)
@@ -892,9 +907,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
host_qs = host_qs.filter(variables__icontains='ansible_ssh_host') host_qs = host_qs.filter(variables__icontains='ansible_ssh_host')
host = host_qs[0] host = host_qs[0]
host_ip = host.variables_dict['ansible_ssh_host'] host_ip = host.variables_dict['ansible_ssh_host']
self.assertEqual(jobs_qs.count(), 4)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 5) self.assertEqual(jobs_qs.count(), 5)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 6)
job = jobs_qs[0] job = jobs_qs[0]
self.assertEqual(job.launch_type, 'callback') self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, host.name) self.assertEqual(job.limit, host.name)
@@ -926,9 +941,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase):
host_ip = list(ips)[0] host_ip = list(ips)[0]
break break
self.assertTrue(host) self.assertTrue(host)
self.assertEqual(jobs_qs.count(), 5)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 6) self.assertEqual(jobs_qs.count(), 6)
self.post(url, data, expect=202, remote_addr=host_ip)
self.assertEqual(jobs_qs.count(), 7)
job = jobs_qs[0] job = jobs_qs[0]
self.assertEqual(job.launch_type, 'callback') self.assertEqual(job.launch_type, 'callback')
self.assertEqual(job.limit, ':&'.join([job_template.limit, host.name])) self.assertEqual(job.limit, ':&'.join([job_template.limit, host.name]))