From b5763f078d9d70e65a43d60e1844e17ee3542ac5 Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Fri, 5 Sep 2014 14:02:14 -0400 Subject: [PATCH] Add relaunch capability to a job. fill in related links for various serializers --- awx/api/serializers.py | 2 ++ awx/api/urls.py | 3 ++- awx/api/views.py | 27 ++++++++++++++++++++++++++- awx/main/models/jobs.py | 5 +++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index f44d33f9b1..3b30eca8bb 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1233,6 +1233,7 @@ class JobTemplateSerializer(UnifiedJobTemplateSerializer, JobOptionsSerializer): jobs = reverse('api:job_template_jobs_list', args=(obj.pk,)), schedules = reverse('api:job_template_schedules_list', args=(obj.pk,)), activity_stream = reverse('api:job_template_activity_stream_list', args=(obj.pk,)), + launch = reverse('api:job_template_launch', args=(obj.pk,)), )) if obj.host_config_key: res['callback'] = reverse('api:job_template_callback', args=(obj.pk,)) @@ -1264,6 +1265,7 @@ class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer): res['start'] = reverse('api:job_start', args=(obj.pk,)) if obj.can_cancel or True: res['cancel'] = reverse('api:job_cancel', args=(obj.pk,)) + res['relaunch'] = reverse('api:job_relaunch', args=(obj.pk,)) return res def from_native(self, data, files): diff --git a/awx/api/urls.py b/awx/api/urls.py index 2d4770d63f..a9a60826de 100644 --- a/awx/api/urls.py +++ b/awx/api/urls.py @@ -130,7 +130,7 @@ permission_urls = patterns('awx.api.views', job_template_urls = patterns('awx.api.views', url(r'^$', 'job_template_list'), url(r'^(?P[0-9]+)/$', 'job_template_detail'), - url(r'^(?P[0-9]+)launch/$', 'job_template_launch'), + url(r'^(?P[0-9]+)/launch/$', 'job_template_launch'), url(r'^(?P[0-9]+)/jobs/$', 'job_template_jobs_list'), url(r'^(?P[0-9]+)/callback/$', 'job_template_callback'), url(r'^(?P[0-9]+)/schedules/$', 'job_template_schedules_list'), @@ -142,6 +142,7 @@ job_urls = patterns('awx.api.views', url(r'^(?P[0-9]+)/$', 'job_detail'), url(r'^(?P[0-9]+)/start/$', 'job_start'), url(r'^(?P[0-9]+)/cancel/$', 'job_cancel'), + url(r'^(?P[0-9]+)/relaunch/$', 'job_relaunch'), url(r'^(?P[0-9]+)/job_host_summaries/$', 'job_job_host_summaries_list'), url(r'^(?P[0-9]+)/job_events/$', 'job_job_events_list'), url(r'^(?P[0-9]+)/job_plays/$', 'job_job_plays_list'), diff --git a/awx/api/views.py b/awx/api/views.py index f1a4d810e9..e6b547ce66 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1349,7 +1349,7 @@ class JobTemplateLaunch(GenericAPIView): data['ask_variables_on_launch'] = obj.ask_variables_on_launch return Response(data) - def post(self, request, *args, **obj): + def post(self, request, *args, **kwargs): obj = self.get_object() if not request.user.can_access(self.model, 'start', obj): raise PermissionDenied() @@ -1598,6 +1598,31 @@ class JobCancel(GenericAPIView): else: return self.http_method_not_allowed(request, *args, **kwargs) +class JobRelaunch(GenericAPIView): + + model = Job + + def get(self, request, *args, **kwargs): + obj = self.get_object() + data = {} + data['passwords_needed_to_start'] = obj.passwords_needed_to_start + data['ask_variables_on_launch'] = obj.ask_variables_on_launch + return Response(data) + + def post(self, request, *args, **kwargs): + obj = self.get_object() + if not request.user.can_access(self.model, 'start', obj): + raise PermissionDenied() + new_job = obj.copy() + result = new_job.signal_start(**request.DATA) + if not result: + data = dict(passwords_needed_to_start=obj.passwords_needed_to_start) + return Response(data, status=status.HTTP_400_BAD_REQUEST) + else: + data = dict(job=new_job.id) + return Response(data, status=status.HTTP_202_ACCEPTED) + + class BaseJobHostSummariesList(SubListAPIView): model = JobHostSummary diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 5a21c1bc68..e5642c498a 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -366,6 +366,11 @@ class Job(UnifiedJob, JobOptions): dependencies.append(source.create_inventory_update(launch_type='dependency')) return dependencies + def copy(self): + presets = {} + for kw in self.job_template._get_unified_job_field_names(): + presets[kw] = getattr(self, kw) + return self.job_template.create_unified_job(**presets) class JobHostSummary(CreatedModifiedModel): '''