mirror of
https://github.com/ZwareBear/awx.git
synced 2026-05-17 07:48:39 -05:00
Add API endpoints for workflow approvals
This commit is contained in:
+61
-10
@@ -50,16 +50,16 @@ from awx.main.constants import (
|
||||
CENSOR_VALUE,
|
||||
)
|
||||
from awx.main.models import (
|
||||
ActivityStream, AdHocCommand, AdHocCommandEvent, Credential,
|
||||
CredentialInputSource, CredentialType, CustomInventoryScript,
|
||||
Group, Host, Instance, InstanceGroup, Inventory, InventorySource,
|
||||
InventoryUpdate, InventoryUpdateEvent, Job, JobEvent, JobHostSummary,
|
||||
JobLaunchConfig, JobNotificationMixin, JobTemplate, Label, Notification,
|
||||
NotificationTemplate, OAuth2AccessToken, OAuth2Application, Organization,
|
||||
Project, ProjectUpdate, ProjectUpdateEvent, RefreshToken, Role, Schedule,
|
||||
StdoutMaxBytesExceeded, SystemJob, SystemJobEvent, SystemJobTemplate,
|
||||
Team, UnifiedJob, UnifiedJobTemplate, WorkflowJob, WorkflowJobNode,
|
||||
WorkflowJobTemplate, WorkflowJobTemplateNode
|
||||
ActivityStream, AdHocCommand, AdHocCommandEvent, Credential, CredentialInputSource,
|
||||
CredentialType, CustomInventoryScript, Group, Host, Instance,
|
||||
InstanceGroup, Inventory, InventorySource, InventoryUpdate,
|
||||
InventoryUpdateEvent, Job, JobEvent, JobHostSummary, JobLaunchConfig,
|
||||
JobNotificationMixin, JobTemplate, Label, Notification, NotificationTemplate,
|
||||
OAuth2AccessToken, OAuth2Application, Organization, Project,
|
||||
ProjectUpdate, ProjectUpdateEvent, RefreshToken, Role, Schedule,
|
||||
SystemJob, SystemJobEvent, SystemJobTemplate, Team, UnifiedJob,
|
||||
UnifiedJobTemplate, WorkflowApproval, WorkflowApprovalTemplate, WorkflowJob,
|
||||
WorkflowJobNode, WorkflowJobTemplate, WorkflowJobTemplateNode, StdoutMaxBytesExceeded
|
||||
)
|
||||
from awx.main.models.base import VERBOSITY_CHOICES, NEW_JOB_TYPE_CHOICES
|
||||
from awx.main.models.rbac import (
|
||||
@@ -681,6 +681,8 @@ class UnifiedJobTemplateSerializer(BaseSerializer):
|
||||
serializer_class = SystemJobTemplateSerializer
|
||||
elif isinstance(obj, WorkflowJobTemplate):
|
||||
serializer_class = WorkflowJobTemplateSerializer
|
||||
elif isinstance(obj, WorkflowApprovalTemplate):
|
||||
serializer_class = WorkflowApprovalTemplateSerializer
|
||||
return serializer_class
|
||||
|
||||
def to_representation(self, obj):
|
||||
@@ -782,6 +784,8 @@ class UnifiedJobSerializer(BaseSerializer):
|
||||
serializer_class = SystemJobSerializer
|
||||
elif isinstance(obj, WorkflowJob):
|
||||
serializer_class = WorkflowJobSerializer
|
||||
elif isinstance(obj, WorkflowApproval):
|
||||
serializer_class = WorkflowApprovalSerializer
|
||||
return serializer_class
|
||||
|
||||
def to_representation(self, obj):
|
||||
@@ -838,6 +842,8 @@ class UnifiedJobListSerializer(UnifiedJobSerializer):
|
||||
serializer_class = SystemJobListSerializer
|
||||
elif isinstance(obj, WorkflowJob):
|
||||
serializer_class = WorkflowJobListSerializer
|
||||
elif isinstance(obj, WorkflowApproval):
|
||||
serializer_class = WorkflowApprovalListSerializer
|
||||
return serializer_class
|
||||
|
||||
def to_representation(self, obj):
|
||||
@@ -3395,6 +3401,51 @@ class WorkflowJobCancelSerializer(WorkflowJobSerializer):
|
||||
fields = ('can_cancel',)
|
||||
|
||||
|
||||
class WorkflowApprovalSerializer(UnifiedJobSerializer):
|
||||
|
||||
class Meta:
|
||||
model = WorkflowApproval
|
||||
fields = ('*', 'result_stdout', '-controller_node', '-execution_node',)
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(WorkflowApprovalSerializer, self).get_related(obj)
|
||||
|
||||
if obj.workflow_approval_template:
|
||||
res['workflow_approval_template'] = self.reverse('api:workflow_approval_template_detail',
|
||||
kwargs={'pk': obj.workflow_approval_template.pk})
|
||||
res['notifications'] = self.reverse('api:workflow_approval_notifications_list', kwargs={'pk': obj.pk})
|
||||
return res
|
||||
|
||||
def get_result_stdout(self, obj):
|
||||
return obj.result_stdout
|
||||
|
||||
|
||||
class WorkflowApprovalListSerializer(WorkflowApprovalSerializer, UnifiedJobListSerializer):
|
||||
|
||||
class Meta:
|
||||
fields = ('*', '-execution_node', '-controller_node',)
|
||||
|
||||
|
||||
class WorkflowApprovalTemplateSerializer(UnifiedJobTemplateSerializer):
|
||||
|
||||
class Meta:
|
||||
model = WorkflowApprovalTemplate
|
||||
fields = ('*',)
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(WorkflowApprovalTemplateSerializer, self).get_related(obj)
|
||||
if 'last_job' in res:
|
||||
del res['last_job']
|
||||
|
||||
res.update(dict(
|
||||
jobs = self.reverse('api:workflow_approval_template_jobs_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_started = self.reverse('api:workflow_approval_template_notification_templates_started_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_success = self.reverse('api:workflow_approval_template_notification_templates_success_list', kwargs={'pk': obj.pk}),
|
||||
notification_templates_error = self.reverse('api:workflow_approval_template_notification_templates_error_list', kwargs={'pk': obj.pk}),
|
||||
))
|
||||
return res
|
||||
|
||||
|
||||
class LaunchConfigurationBaseSerializer(BaseSerializer):
|
||||
scm_branch = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
||||
job_type = serializers.ChoiceField(allow_blank=True, allow_null=True, required=False, default=None,
|
||||
|
||||
@@ -71,6 +71,8 @@ from .instance import urls as instance_urls
|
||||
from .instance_group import urls as instance_group_urls
|
||||
from .oauth2 import urls as oauth2_urls
|
||||
from .oauth2_root import urls as oauth2_root_urls
|
||||
from .workflow_approval_template import urls as workflow_approval_template_urls
|
||||
from .workflow_approval import urls as workflow_approval_urls
|
||||
|
||||
|
||||
v2_urls = [
|
||||
@@ -131,8 +133,11 @@ v2_urls = [
|
||||
url(r'^unified_job_templates/$', UnifiedJobTemplateList.as_view(), name='unified_job_template_list'),
|
||||
url(r'^unified_jobs/$', UnifiedJobList.as_view(), name='unified_job_list'),
|
||||
url(r'^activity_stream/', include(activity_stream_urls)),
|
||||
url(r'^workflow_approval_templates/', include(workflow_approval_template_urls)),
|
||||
url(r'^workflow_approval/', include(workflow_approval_urls)),
|
||||
]
|
||||
|
||||
|
||||
app_name = 'api'
|
||||
urlpatterns = [
|
||||
url(r'^$', ApiRootView.as_view(), name='api_root_view'),
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2017 Ansible, Inc.
|
||||
# All Rights Reserved.
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from awx.api.views import (
|
||||
WorkflowApprovalList,
|
||||
WorkflowApprovalDetail,
|
||||
WorkflowApprovalNotificationsList,
|
||||
)
|
||||
|
||||
|
||||
urls = [
|
||||
url(r'^$', WorkflowApprovalList.as_view(), name='workflow_approval_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/$', WorkflowApprovalDetail.as_view(), name='workflow_approval_detail'),
|
||||
url(r'^(?P<pk>[0-9]+)/approve/$', WorkflowApprovalDetail.as_view(), name='approved_workflow'),
|
||||
url(r'^(?P<pk>[0-9]+)/reject/$', WorkflowApprovalDetail.as_view(), name='rejected_workflow'),
|
||||
url(r'^(?P<pk>[0-9]+)/notifications/$', WorkflowApprovalNotificationsList.as_view(), name='workflow_approval_notifications_list'),
|
||||
]
|
||||
|
||||
__all__ = ['urls']
|
||||
@@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2017 Ansible, Inc.
|
||||
# All Rights Reserved.
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from awx.api.views import (
|
||||
WorfklowApprovalTemplateList,
|
||||
WorfklowApprovalTemplateDetail,
|
||||
WorkflowApprovalTemplateJobsList,
|
||||
WorkflowApprovalTemplateNotificationTemplatesErrorList,
|
||||
WorkflowApprovalTemplateNotificationTemplatesStartedList,
|
||||
WorkflowApprovalTemplateNotificationTemplatesSuccessList,
|
||||
)
|
||||
|
||||
|
||||
urls = [
|
||||
url(r'^$', WorfklowApprovalTemplateList.as_view(), name='workflow_approval_template_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/$', WorfklowApprovalTemplateDetail.as_view(), name='workflow_approval_template_detail'),
|
||||
url(r'^(?P<pk>[0-9]+)/approvals/$', WorkflowApprovalTemplateJobsList.as_view(), name='workflow_approval_template_jobs_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/notification_templates_started/$', WorkflowApprovalTemplateNotificationTemplatesStartedList.as_view(),
|
||||
name='workflow_approval_template_notification_templates_started_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', WorkflowApprovalTemplateNotificationTemplatesErrorList.as_view(),
|
||||
name='workflow_approval_template_notification_templates_error_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', WorkflowApprovalTemplateNotificationTemplatesSuccessList.as_view(),
|
||||
name='workflow_approval_template_notification_templates_success_list'),
|
||||
]
|
||||
|
||||
__all__ = ['urls']
|
||||
@@ -4405,3 +4405,97 @@ for attr, value in list(locals().items()):
|
||||
name = camelcase_to_underscore(attr)
|
||||
view = value.as_view()
|
||||
setattr(this_module, name, view)
|
||||
|
||||
|
||||
class WorfklowApprovalTemplateList(ListAPIView):
|
||||
|
||||
model = models.WorkflowApprovalTemplate
|
||||
serializer_class = serializers.WorkflowApprovalTemplateSerializer
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not request.user.is_superuser and not request.user.is_system_auditor:
|
||||
raise PermissionDenied(_("Superuser privileges needed."))
|
||||
return super(WorfklowApprovalTemplateList, self).get(request, *args, **kwargs)
|
||||
|
||||
|
||||
class WorfklowApprovalTemplateDetail(RetrieveAPIView):
|
||||
|
||||
model = models.WorkflowApprovalTemplate
|
||||
serializer_class = serializers.WorkflowApprovalTemplateSerializer
|
||||
|
||||
|
||||
class WorkflowApprovalTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView):
|
||||
|
||||
model = models.NotificationTemplate
|
||||
serializer_class = serializers.NotificationTemplateSerializer
|
||||
parent_model = models.WorkflowApprovalTemplate
|
||||
|
||||
|
||||
class WorkflowApprovalTemplateNotificationTemplatesStartedList(WorkflowApprovalTemplateNotificationTemplatesAnyList):
|
||||
|
||||
relationship = 'notification_templates_started'
|
||||
|
||||
|
||||
class WorkflowApprovalTemplateNotificationTemplatesErrorList(WorkflowApprovalTemplateNotificationTemplatesAnyList):
|
||||
|
||||
relationship = 'notification_templates_error'
|
||||
|
||||
|
||||
class WorkflowApprovalTemplateNotificationTemplatesSuccessList(WorkflowApprovalTemplateNotificationTemplatesAnyList):
|
||||
|
||||
relationship = 'notification_templates_success'
|
||||
|
||||
|
||||
class WorkflowApprovalTemplateLaunch(GenericAPIView):
|
||||
|
||||
model = models.WorkflowApprovalTemplate
|
||||
obj_permission_type = 'start'
|
||||
serializer_class = serializers.EmptySerializer
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
return Response({})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
new_job = obj.create_unified_job(extra_vars=request.data.get('extra_vars', {}))
|
||||
new_job.signal_start()
|
||||
data = OrderedDict()
|
||||
data['workflow_approval'] = new_job.id
|
||||
data.update(serializers.WorkflowApprovalSerializer(new_job, context=self.get_serializer_context()).to_representation(new_job))
|
||||
headers = {'Location': new_job.get_absolute_url(request)}
|
||||
return Response(data, status=status.HTTP_201_CREATED, headers=headers)
|
||||
|
||||
|
||||
class WorkflowApprovalTemplateJobsList(SubListAPIView):
|
||||
|
||||
model = models.WorkflowApproval
|
||||
serializer_class = serializers.WorkflowApprovalListSerializer
|
||||
parent_model = models.WorkflowApprovalTemplate
|
||||
relationship = 'approvals'
|
||||
parent_key = 'workflow_approval_template'
|
||||
|
||||
|
||||
class WorkflowApprovalList(ListCreateAPIView):
|
||||
|
||||
model = models.WorkflowApproval
|
||||
serializer_class = serializers.WorkflowApprovalListSerializer
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not request.user.is_superuser and not request.user.is_system_auditor:
|
||||
raise PermissionDenied(_("Superuser privileges needed."))
|
||||
return super(WorkflowApprovalList, self).get(request, *args, **kwargs)
|
||||
|
||||
|
||||
class WorkflowApprovalDetail(UnifiedJobDeletionMixin, RetrieveDestroyAPIView):
|
||||
|
||||
model = models.WorkflowApproval
|
||||
serializer_class = serializers.WorkflowApprovalSerializer
|
||||
|
||||
|
||||
class WorkflowApprovalNotificationsList(SubListAPIView):
|
||||
|
||||
model = models.Notification
|
||||
serializer_class = serializers.NotificationSerializer
|
||||
parent_model = models.WorkflowApproval
|
||||
relationship = 'notifications'
|
||||
search_fields = ('subject', 'notification_type', 'body',)
|
||||
|
||||
@@ -124,6 +124,8 @@ class ApiVersionRootView(APIView):
|
||||
data['activity_stream'] = reverse('api:activity_stream_list', request=request)
|
||||
data['workflow_job_templates'] = reverse('api:workflow_job_template_list', request=request)
|
||||
data['workflow_jobs'] = reverse('api:workflow_job_list', request=request)
|
||||
data['workflow_approval_templates'] = reverse('api:workflow_approval_template_list', request=request)
|
||||
data['workflow_approval'] = reverse('api:workflow_approval_list', request=request)
|
||||
data['workflow_job_template_nodes'] = reverse('api:workflow_job_template_node_list', request=request)
|
||||
data['workflow_job_nodes'] = reverse('api:workflow_job_node_list', request=request)
|
||||
return Response(data)
|
||||
|
||||
Reference in New Issue
Block a user