diff --git a/awx/api/views.py b/awx/api/views.py index 333f2427ae..02a10451d8 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -32,6 +32,7 @@ from django.http import HttpResponse # Django REST Framework from rest_framework.exceptions import PermissionDenied, ParseError +from rest_framework.parsers import FormParser from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.response import Response from rest_framework.settings import api_settings @@ -2005,6 +2006,7 @@ class JobTemplateCallback(GenericAPIView): model = JobTemplate permission_classes = (JobTemplateCallbackPermission,) serializer_class = EmptySerializer + parser_classes = api_settings.DEFAULT_PARSER_CLASSES + [FormParser] @csrf_exempt @transaction.non_atomic_requests diff --git a/awx/main/tests/base.py b/awx/main/tests/base.py index 93bac00948..a0387079b6 100644 --- a/awx/main/tests/base.py +++ b/awx/main/tests/base.py @@ -11,6 +11,7 @@ import shutil import sys import tempfile import time +import urllib from multiprocessing import Process from subprocess import Popen import re @@ -463,6 +464,8 @@ class BaseTestMixin(QueueTestMixin, MockCommonlySlowTestMixin): response = method(url, json.dumps(data), 'application/json') elif data_type == '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: self.fail('Unsupported data_type %s' % data_type) else: diff --git a/awx/main/tests/old/jobs/jobs_monolithic.py b/awx/main/tests/old/jobs/jobs_monolithic.py index 1d36972245..9234f57a2b 100644 --- a/awx/main/tests/old/jobs/jobs_monolithic.py +++ b/awx/main/tests/old/jobs/jobs_monolithic.py @@ -803,6 +803,21 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase): self.assertEqual(job.hosts.count(), 1) 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 data.update(dict(extra_vars=dict(key="value"))) result = self.post(url, data, expect=202, remote_addr=host_ip) @@ -853,9 +868,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase): if host_ip: break 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.post(url, data, expect=202, remote_addr=host_ip) + self.assertEqual(jobs_qs.count(), 4) job = jobs_qs[0] self.assertEqual(job.launch_type, 'callback') self.assertEqual(job.limit, host.name) @@ -878,9 +893,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase): if host_ip: break 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.post(url, data, expect=202, remote_addr=host_ip) + self.assertEqual(jobs_qs.count(), 5) job = jobs_qs[0] self.assertEqual(job.launch_type, 'callback') 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 = host_qs[0] 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.post(url, data, expect=202, remote_addr=host_ip) + self.assertEqual(jobs_qs.count(), 6) job = jobs_qs[0] self.assertEqual(job.launch_type, 'callback') self.assertEqual(job.limit, host.name) @@ -926,9 +941,9 @@ class JobTemplateCallbackTest(BaseJobTestMixin, django.test.LiveServerTestCase): host_ip = list(ips)[0] break 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.post(url, data, expect=202, remote_addr=host_ip) + self.assertEqual(jobs_qs.count(), 7) job = jobs_qs[0] self.assertEqual(job.launch_type, 'callback') self.assertEqual(job.limit, ':&'.join([job_template.limit, host.name]))