mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 16:51:11 +03:00
add workflow relaunch
This commit is contained in:
parent
14ce50c845
commit
8cda12c020
@ -2252,6 +2252,7 @@ class WorkflowJobSerializer(LabelsListMixin, UnifiedJobSerializer):
|
||||
res['workflow_nodes'] = reverse('api:workflow_job_workflow_nodes_list', args=(obj.pk,))
|
||||
res['labels'] = reverse('api:workflow_job_label_list', args=(obj.pk,))
|
||||
res['activity_stream'] = reverse('api:workflow_job_activity_stream_list', args=(obj.pk,))
|
||||
res['relaunch'] = reverse('api:workflow_job_relaunch', args=(obj.pk,))
|
||||
if obj.can_cancel or True:
|
||||
res['cancel'] = reverse('api:workflow_job_cancel', args=(obj.pk,))
|
||||
return res
|
||||
|
@ -272,7 +272,6 @@ workflow_job_template_urls = patterns('awx.api.views',
|
||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'workflow_job_template_notification_templates_success_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'workflow_job_template_access_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/labels/$', 'workflow_job_template_label_list'),
|
||||
# url(r'^(?P<pk>[0-9]+)/cancel/$', 'workflow_job_template_cancel'),
|
||||
)
|
||||
|
||||
workflow_job_urls = patterns('awx.api.views',
|
||||
@ -281,6 +280,7 @@ workflow_job_urls = patterns('awx.api.views',
|
||||
url(r'^(?P<pk>[0-9]+)/workflow_nodes/$', 'workflow_job_workflow_nodes_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/labels/$', 'workflow_job_label_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/cancel/$', 'workflow_job_cancel'),
|
||||
url(r'^(?P<pk>[0-9]+)/relaunch/$', 'workflow_job_relaunch'),
|
||||
url(r'^(?P<pk>[0-9]+)/notifications/$', 'workflow_job_notifications_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'workflow_job_activity_stream_list'),
|
||||
)
|
||||
|
@ -2987,6 +2987,25 @@ class WorkflowJobTemplateLaunch(RetrieveAPIView):
|
||||
return Response(data, status=status.HTTP_201_CREATED)
|
||||
|
||||
|
||||
class WorkflowJobRelaunch(GenericAPIView):
|
||||
|
||||
model = WorkflowJob
|
||||
serializer_class = EmptySerializer
|
||||
is_job_start = True
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
return Response({})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
new_workflow_job = obj.create_relaunch_workflow_job()
|
||||
result = new_workflow_job.signal_start()
|
||||
|
||||
data = WorkflowJobSerializer(new_workflow_job, context=self.get_serializer_context()).data
|
||||
headers = {'Location': new_workflow_job.get_absolute_url()}
|
||||
return Response(data, status=status.HTTP_201_CREATED, headers=headers)
|
||||
|
||||
|
||||
# TODO:
|
||||
class WorkflowJobTemplateWorkflowNodesList(SubListCreateAPIView):
|
||||
|
||||
|
@ -1630,9 +1630,16 @@ class WorkflowJobAccess(BaseAccess):
|
||||
return self.user.is_superuser
|
||||
return self.user in obj.workflow_job_template.admin_role
|
||||
|
||||
# TODO: add support for relaunching workflow jobs
|
||||
def can_start(self, obj, validate_license=True):
|
||||
return False
|
||||
if validate_license:
|
||||
self.check_license()
|
||||
if obj.survey_enabled:
|
||||
self.check_license(feature='surveys')
|
||||
|
||||
if self.user.is_superuser:
|
||||
return True
|
||||
|
||||
return (obj.workflow_job_template and self.user in obj.workflow_job_template.execute_role)
|
||||
|
||||
def can_cancel(self, obj):
|
||||
if not obj.can_cancel:
|
||||
|
@ -455,6 +455,10 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin):
|
||||
def _global_timeout_setting(self):
|
||||
return 'DEFAULT_JOB_TIMEOUT'
|
||||
|
||||
@classmethod
|
||||
def _get_unified_job_template_class(cls):
|
||||
return JobTemplate
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('api:job_detail', args=(self.pk,))
|
||||
|
||||
|
@ -357,7 +357,6 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio
|
||||
dest_field.add(*list(src_field_value.all().values_list('id', flat=True)))
|
||||
return unified_job
|
||||
|
||||
|
||||
def copy_unified_jt(self):
|
||||
'''
|
||||
Create a copy of this unified job template.
|
||||
@ -585,6 +584,13 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
||||
def _get_parent_field_name(cls):
|
||||
return 'unified_job_template' # Override in subclasses.
|
||||
|
||||
@classmethod
|
||||
def _get_unified_job_template_class(cls):
|
||||
'''
|
||||
Return subclass of UnifiedJobTemplate that applies to this unified job.
|
||||
'''
|
||||
raise NotImplementedError # Implement in subclass.
|
||||
|
||||
def _global_timeout_setting(self):
|
||||
"Override in child classes, None value indicates this is not configurable"
|
||||
return None
|
||||
@ -699,6 +705,36 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
||||
pass
|
||||
super(UnifiedJob, self).delete()
|
||||
|
||||
def copy_unified_job(self):
|
||||
'''
|
||||
Create a copy of this unified job.
|
||||
'''
|
||||
unified_job_class = self.__class__
|
||||
unified_jt_class = self._get_unified_job_template_class()
|
||||
create_kwargs = {}
|
||||
m2m_fields = {}
|
||||
for field_name in unified_jt_class._get_unified_job_field_names():
|
||||
# Foreign keys can be specified as field_name or field_name_id.
|
||||
id_field_name = '%s_id' % field_name
|
||||
if hasattr(self, id_field_name):
|
||||
value = getattr(self, id_field_name)
|
||||
if hasattr(value, 'id'):
|
||||
value = value.id
|
||||
create_kwargs[id_field_name] = value
|
||||
elif hasattr(self, field_name):
|
||||
field_obj = self._meta.get_field_by_name(field_name)[0]
|
||||
# Many to Many can be specified as field_name
|
||||
if isinstance(field_obj, models.ManyToManyField):
|
||||
m2m_fields[field_name] = getattr(self, field_name)
|
||||
else:
|
||||
create_kwargs[field_name] = getattr(self, field_name)
|
||||
unified_job = unified_job_class(**create_kwargs)
|
||||
unified_job.save()
|
||||
for field_name, src_field_value in m2m_fields.iteritems():
|
||||
dest_field = getattr(unified_job, field_name)
|
||||
dest_field.add(*list(src_field_value.all().values_list('id', flat=True)))
|
||||
return unified_job
|
||||
|
||||
def result_stdout_raw_handle(self, attempt=0):
|
||||
"""Return a file-like object containing the standard out of the
|
||||
job's result.
|
||||
|
@ -322,6 +322,12 @@ class WorkflowJobOptions(BaseModel):
|
||||
node_links = self._create_workflow_nodes(old_node_list, user=user)
|
||||
self._inherit_node_relationships(old_node_list, node_links)
|
||||
|
||||
def create_relaunch_workflow_job(self):
|
||||
self.launch_type = 'relaunch'
|
||||
new_workflow_job = self.copy_unified_job()
|
||||
new_workflow_job.copy_nodes_from_original(original=self)
|
||||
return new_workflow_job
|
||||
|
||||
|
||||
class WorkflowJobTemplate(UnifiedJobTemplate, WorkflowJobOptions, SurveyJobTemplateMixin, ResourceMixin):
|
||||
class Meta:
|
||||
@ -424,6 +430,11 @@ class WorkflowJobTemplate(UnifiedJobTemplate, WorkflowJobOptions, SurveyJobTempl
|
||||
return new_wfjt
|
||||
|
||||
|
||||
# Stub in place because of old migraitons, can remove if migraitons are squashed
|
||||
class WorkflowJobInheritNodesMixin(object):
|
||||
pass
|
||||
|
||||
|
||||
class WorkflowJob(UnifiedJob, WorkflowJobOptions, SurveyJobMixin, JobNotificationMixin):
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
@ -446,6 +457,10 @@ class WorkflowJob(UnifiedJob, WorkflowJobOptions, SurveyJobMixin, JobNotificatio
|
||||
def _get_parent_field_name(cls):
|
||||
return 'workflow_job_template'
|
||||
|
||||
@classmethod
|
||||
def _get_unified_job_template_class(cls):
|
||||
return WorkflowJobTemplate
|
||||
|
||||
def _has_failed(self):
|
||||
return False
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user