diff --git a/awx/api/views.py b/awx/api/views.py index b04454918d..03caa2c37b 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -2092,23 +2092,26 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView): data['credential'] = None for v in obj.variables_needed_to_start: extra_vars.setdefault(v, u'') - ask_for_field_dict = dict( - extra_vars=obj.ask_variables_on_launch, - limit=obj.ask_limit_on_launch, - job_tags=obj.ask_tags_on_launch, - skip_tags=obj.ask_tags_on_launch, - job_type=obj.ask_job_type_on_launch, - inventory=obj.ask_inventory_on_launch - ) - for field in ask_for_field_dict: - if not ask_for_field_dict[field]: + ask_for_vars_dict = obj._ask_for_vars_dict() + for field in ask_for_vars_dict: + if not ask_for_vars_dict[field]: data.pop(field, None) elif field == 'extra_vars': data[field] = extra_vars + elif field == 'inventory': + inv_obj = getattr(obj, field) + if inv_obj in ('', None): + data[field] = None + else: + data[field] = inv_obj.id + else: + data[field] = getattr(obj, field) return data def post(self, request, *args, **kwargs): obj = self.get_object() + if not request.user.can_access(self.model, 'start', obj): + raise PermissionDenied() if 'credential' not in request.data and 'credential_id' in request.data: request.data['credential'] = request.data['credential_id'] @@ -2139,22 +2142,16 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView): kv.update(passwords) new_job = obj.create_unified_job(**kv) - - if not request.user.can_access(Job, 'start', new_job): - new_job.delete() - raise PermissionDenied() - result = new_job.signal_start(**kv) if not result: data = dict(passwords_needed_to_start=new_job.passwords_needed_to_start) new_job.delete() return Response(data, status=status.HTTP_400_BAD_REQUEST) else: - data = dict(job=new_job.id) - serializer = JobSerializer(new_job) - data['job_data'] = serializer.data + data = JobSerializer(new_job).data + data['job'] = new_job.id data['ignored_fields'] = ignored_fields - return Response(data, status=status.HTTP_202_ACCEPTED) + return Response(data, status=status.HTTP_201_CREATED) class JobTemplateSchedulesList(SubListCreateAttachDetachAPIView): diff --git a/awx/main/access.py b/awx/main/access.py index 565a9be47f..b250f9b40b 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -766,7 +766,7 @@ class JobTemplateAccess(BaseAccess): self.check_license() if obj.job_type == PERM_INVENTORY_SCAN: self.check_license(feature='system_tracking') - if obj.survey_enabled: + if getattr(obj, 'survey_enabled', None): self.check_license(feature='surveys') # Super users can start any job diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 3abdb29c8e..4d4c321d5e 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -378,32 +378,9 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin): kwargs['extra_vars'] = json.dumps(extra_vars) return kwargs - def _accept_or_ignore_job_kwargs(self, **kwargs): - # Sort the runtime fields allowed and disallowed by job template - ignored_fields = {} - prompted_fields = {} - - if 'extra_vars' in kwargs: - prompted_fields['extra_vars'] = {} - ignored_fields['extra_vars'] = {} - if self.ask_variables_on_launch: - # Accept all extra_vars if the flag is set - prompted_fields['extra_vars'] = kwargs['extra_vars'] - else: - if self.survey_enabled: - # Accept vars defined in the survey and no others - survey_vars = [question['variable'] for question in self.survey_spec['spec']] - for key in kwargs['extra_vars']: - if key in survey_vars: - prompted_fields['extra_vars'][key] = kwargs['extra_vars'][key] - else: - ignored_fields['extra_vars'][key] = kwargs['extra_vars'][key] - else: - # No survey & prompt flag is false - ignore all - ignored_fields['extra_vars'] = kwargs['extra_vars'] - - # Fields which all follow the same pattern - ask_for_field_dict = dict( + def _ask_for_vars_dict(self): + return dict( + extra_vars=self.ask_variables_on_launch, limit=self.ask_limit_on_launch, job_tags=self.ask_tags_on_launch, skip_tags=self.ask_tags_on_launch, @@ -411,13 +388,33 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin): inventory=self.ask_inventory_on_launch ) - for field in ask_for_field_dict: + def _accept_or_ignore_job_kwargs(self, **kwargs): + # Sort the runtime fields allowed and disallowed by job template + ignored_fields = {} + prompted_fields = {} + + ask_for_vars_dict = self._ask_for_vars_dict() + + for field in ask_for_vars_dict: if field in kwargs: - if ask_for_field_dict[field]: + if field == 'extra_vars': + prompted_fields[field] = {} + ignored_fields[field] = {} + if ask_for_vars_dict[field]: prompted_fields[field] = kwargs[field] else: - ignored_fields[field] = kwargs[field] + if field == 'extra_vars' and self.survey_enabled: + # Accept vars defined in the survey and no others + survey_vars = [question['variable'] for question in self.survey_spec['spec']] + for key in kwargs[field]: + if key in survey_vars: + prompted_fields[field][key] = kwargs[field][key] + else: + ignored_fields[field][key] = kwargs[field][key] + else: + ignored_fields[field] = kwargs[field] + # Special case to ignore inventory if it is a scan job if prompted_fields.get('job_type', None) == 'scan' or self.job_type == 'scan': if 'inventory' in prompted_fields: ignored_fields['inventory'] = prompted_fields.pop('inventory')