diff --git a/awx/api/views.py b/awx/api/views.py index 3845d9c5e5..10746c8c37 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1458,6 +1458,10 @@ class JobTemplateLaunch(GenericAPIView): status=status.HTTP_400_BAD_REQUEST) if obj.credential is None and ('credential' not in request.DATA and 'credential_id' not in request.DATA): return Response(dict(errors="Credential not provided"), status=status.HTTP_400_BAD_REQUEST) + if obj.project is None or not obj.project.active: + return Response(dict(errors="Job Template Project is missing or undefined"), status=status.HTTP_400_BAD_REQUEST) + if obj.inventory is None or not obj.inventory.active: + return Response(dict(errors="Job Template Inventory is missing or undefined"), status=status.HTTP_400_BAD_REQUEST) new_job = obj.create_unified_job(**request.DATA) result = new_job.signal_start(**request.DATA) if not result: diff --git a/awx/main/tests/jobs.py b/awx/main/tests/jobs.py index c03c2ca5a3..a532d7f27c 100644 --- a/awx/main/tests/jobs.py +++ b/awx/main/tests/jobs.py @@ -1038,6 +1038,7 @@ class JobTemplateTest(BaseJobTestMixin, django.test.TestCase): project = self.proj_dev.pk, playbook = self.proj_dev.playbooks[0], ) + with self.current_user(self.user_sue): response = self.post(url, data, expect=201) detail_url = reverse('api:job_template_detail', @@ -1073,6 +1074,28 @@ class JobTemplateTest(BaseJobTestMixin, django.test.TestCase): with self.current_user(self.user_sue): response = self.post(no_launch_url, {}, expect=400) + # Job Templates without projects can not be launched + with self.current_user(self.user_sue): + data['name'] = "missing proj" + response = self.post(url, data, expect=201) + jt = JobTemplate.objects.get(pk=response['id']) + jt.project = None + jt.save() + launch_url = reverse('api:job_template_launch', + args=(response['id'],)) + self.post(launch_url, {}, expect=400) + + # Job Templates without inventory can not be launched + with self.current_user(self.user_sue): + data['name'] = "missing inv" + response = self.post(url, data, expect=201) + jt = JobTemplate.objects.get(pk=response['id']) + jt.inventory = None + jt.save() + launch_url = reverse('api:job_template_launch', + args=(response['id'],)) + self.post(launch_url, {}, expect=400) + class JobTest(BaseJobTestMixin, django.test.TestCase): def test_get_job_list(self):