From 319394442a5444c83351e8424d1b8f2e1825e0c2 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Fri, 4 Dec 2015 11:20:05 -0500 Subject: [PATCH] store yaml output, test to cover bug, and docs update --- awx/api/templates/api/job_template_launch.md | 9 ++++---- awx/main/models/jobs.py | 4 +++- awx/main/tests/jobs/job_launch.py | 24 +++++++++++++++++++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/awx/api/templates/api/job_template_launch.md b/awx/api/templates/api/job_template_launch.md index 90846940a8..1dddde4210 100644 --- a/awx/api/templates/api/job_template_launch.md +++ b/awx/api/templates/api/job_template_launch.md @@ -18,10 +18,11 @@ The response will include the following fields: associated with the job template. If not then one should be supplied when launching the job (boolean, read-only) -Make a POST request to this resource to launch the job_template. If any -passwords or variables are required, they must be passed via POST data. -If `credential_needed_to_start` is `True` then the `credential` field is -required as well. +Make a POST request to this resource to launch the job_template. If any +passwords or extra variables (extra_vars) are required, they must be passed +via POST data, with extra_vars given as a YAML or JSON string and escaped +parentheses. If `credential_needed_to_start` is `True` then the `credential` +field is required as well. If successful, the response status code will be 202. If any required passwords are not provided, a 400 status code will be returned. If the job cannot be diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index ebc6a0fa78..51f577bac5 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -4,6 +4,7 @@ # Python import hmac import json +import yaml import logging # Django @@ -304,7 +305,8 @@ class JobTemplate(UnifiedJobTemplate, JobOptions): kwargs_extra_vars = json.loads(kwargs_extra_vars) except Exception: try: - yaml.safe_load(kwargs_extra_vars) + kwargs_extra_vars = yaml.safe_load(kwargs_extra_vars) + assert type(kwargs_extra_vars) is dict except: kwargs_extra_vars = {} else: diff --git a/awx/main/tests/jobs/job_launch.py b/awx/main/tests/jobs/job_launch.py index b0a0a35abe..66a0ca5a72 100644 --- a/awx/main/tests/jobs/job_launch.py +++ b/awx/main/tests/jobs/job_launch.py @@ -11,6 +11,7 @@ from django.core.urlresolvers import reverse # AWX from awx.main.models import * # noqa from .base import BaseJobTestMixin +import yaml __all__ = ['JobTemplateLaunchTest', 'JobTemplateLaunchPasswordsTest'] @@ -70,6 +71,28 @@ class JobTemplateLaunchTest(BaseJobTestMixin, django.test.TestCase): j = Job.objects.get(pk=response['job']) self.assertTrue(j.status == 'new') + def test_launch_extra_vars_json(self): + # Sending extra_vars as a JSON string, implicit credentials + with self.current_user(self.user_sue): + data = dict(extra_vars = '{\"a\":3}') + response = self.post(self.launch_url, data, expect=202) + j = Job.objects.get(pk=response['job']) + ev_dict = yaml.load(j.extra_vars) + self.assertIn('a', ev_dict) + if 'a' in ev_dict: + self.assertEqual(ev_dict['a'], 3) + + def test_launch_extra_vars_yaml(self): + # Sending extra_vars as a JSON string, implicit credentials + with self.current_user(self.user_sue): + data = dict(extra_vars = 'a: 3') + response = self.post(self.launch_url, data, expect=202) + j = Job.objects.get(pk=response['job']) + ev_dict = yaml.load(j.extra_vars) + self.assertIn('a', ev_dict) + if 'a' in ev_dict: + self.assertEqual(ev_dict['a'], 3) + def test_credential_explicit(self): # Explicit, credential with self.current_user(self.user_sue): @@ -195,4 +218,3 @@ class JobTemplateLaunchPasswordsTest(BaseJobTestMixin, django.test.TestCase): with self.current_user(self.user_sue): response = self.post(self.launch_url, {'ssh_password': ''}, expect=400) self.assertIn('ssh_password', response['passwords_needed_to_start']) -