mirror of
https://github.com/ansible/awx.git
synced 2024-10-30 22:21:13 +03:00
Set up approval notifications to send
This commit is contained in:
parent
6be2d84adb
commit
13450fdbf9
@ -3495,7 +3495,7 @@ class WorkflowApprovalTemplateSerializer(UnifiedJobTemplateSerializer):
|
|||||||
# Placeholder...
|
# Placeholder...
|
||||||
res.update(dict(
|
res.update(dict(
|
||||||
jobs = self.reverse('api:workflow_approval_template_jobs_list', kwargs={'pk': obj.pk}),
|
jobs = self.reverse('api:workflow_approval_template_jobs_list', kwargs={'pk': obj.pk}),
|
||||||
approval_notifications = self.reverse('api:workflow_approval_template_notification_list', kwargs={'pk': obj.pk}),
|
approval_notification_templates = self.reverse('api:workflow_approval_template_notification_list', kwargs={'pk': obj.pk}),
|
||||||
))
|
))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -3291,7 +3291,7 @@ class WorkflowJobTemplateNotificationTemplatesSuccessList(WorkflowJobTemplateNot
|
|||||||
|
|
||||||
class WorkflowJobTemplateNotificationTemplatesApprovalList(WorkflowJobTemplateNotificationTemplatesAnyList):
|
class WorkflowJobTemplateNotificationTemplatesApprovalList(WorkflowJobTemplateNotificationTemplatesAnyList):
|
||||||
|
|
||||||
relationship = 'approval_notifications'
|
relationship = 'notification_templates_approvals'
|
||||||
|
|
||||||
|
|
||||||
class WorkflowJobTemplateAccessList(ResourceAccessList):
|
class WorkflowJobTemplateAccessList(ResourceAccessList):
|
||||||
@ -4473,7 +4473,7 @@ class WorkflowApprovalTemplateNotificationTemplatesList(SubListCreateAttachDetac
|
|||||||
|
|
||||||
class WorkflowApprovalNotificationTemplatesList(WorkflowApprovalTemplateNotificationTemplatesList):
|
class WorkflowApprovalNotificationTemplatesList(WorkflowApprovalTemplateNotificationTemplatesList):
|
||||||
|
|
||||||
relationship = 'approval_notifications'
|
relationship = 'notification_templates_approvals'
|
||||||
|
|
||||||
|
|
||||||
class WorkflowApprovalList(ListCreateAPIView):
|
class WorkflowApprovalList(ListCreateAPIView):
|
||||||
|
@ -197,7 +197,7 @@ class OrganizationNotificationTemplatesSuccessList(OrganizationNotificationTempl
|
|||||||
|
|
||||||
class OrganizationNotificationTemplatesApprovalList(OrganizationNotificationTemplatesAnyList):
|
class OrganizationNotificationTemplatesApprovalList(OrganizationNotificationTemplatesAnyList):
|
||||||
|
|
||||||
relationship = 'approval_notifications'
|
relationship = 'notification_templates_approvals'
|
||||||
|
|
||||||
|
|
||||||
class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
|
class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 2.2.4 on 2019-09-03 19:25
|
# Generated by Django 2.2.4 on 2019-09-04 18:23
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
@ -12,13 +12,13 @@ class Migration(migrations.Migration):
|
|||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='organization',
|
model_name='organization',
|
||||||
name='approval_notifications',
|
name='notification_templates_approvals',
|
||||||
field=models.ManyToManyField(blank=True, related_name='organization_approval_notifications', to='main.NotificationTemplate'),
|
field=models.ManyToManyField(blank=True, related_name='organization_notification_templates_for_approvals', to='main.NotificationTemplate'),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='unifiedjobtemplate',
|
model_name='unifiedjobtemplate',
|
||||||
name='approval_notifications',
|
name='notification_templates_approvals',
|
||||||
field=models.ManyToManyField(blank=True, related_name='unifiedjobtemplate_approval_notifications', to='main.NotificationTemplate'),
|
field=models.ManyToManyField(blank=True, related_name='unifiedjobtemplate_notification_templates_for_approvals', to='main.NotificationTemplate'),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
|
@ -463,7 +463,6 @@ class JobNotificationMixin(object):
|
|||||||
|
|
||||||
def send_notification_templates(self, status):
|
def send_notification_templates(self, status):
|
||||||
from awx.main.tasks import send_notifications # avoid circular import
|
from awx.main.tasks import send_notifications # avoid circular import
|
||||||
# Placeholder... Adding "pending" status here for approvals.
|
|
||||||
if status not in ['pending', 'running', 'succeeded', 'failed']:
|
if status not in ['pending', 'running', 'succeeded', 'failed']:
|
||||||
raise ValueError(_("status must be either pending, running, succeeded or failed"))
|
raise ValueError(_("status must be either pending, running, succeeded or failed"))
|
||||||
try:
|
try:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.db import models
|
from django.db import connection, models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
@ -577,6 +577,13 @@ class WorkflowJob(UnifiedJob, WorkflowJobOptions, SurveyJobMixin, JobNotificatio
|
|||||||
for node in self.workflow_job_nodes.all().select_related('job'):
|
for node in self.workflow_job_nodes.all().select_related('job'):
|
||||||
if node.job is None:
|
if node.job is None:
|
||||||
node_job_description = 'no job.'
|
node_job_description = 'no job.'
|
||||||
|
elif type(node.unified_job_template) is WorkflowApprovalTemplate:
|
||||||
|
if node.job.status == 'pending':
|
||||||
|
node_job_description = 'APPROVE THIS!!!'
|
||||||
|
if node.job.status == 'successful':
|
||||||
|
node_job_description = 'THIS GOT APPROVED!!!'
|
||||||
|
if node.job.status == 'failed':
|
||||||
|
node_job_description = 'DENIED!!!'
|
||||||
else:
|
else:
|
||||||
node_job_description = ('job #{0}, "{1}", which finished with status {2}.'
|
node_job_description = ('job #{0}, "{1}", which finished with status {2}.'
|
||||||
.format(node.job.id, node.job.name, node.job.status))
|
.format(node.job.id, node.job.name, node.job.status))
|
||||||
@ -647,40 +654,6 @@ class WorkflowApprovalTemplate(UnifiedJobTemplate):
|
|||||||
def get_absolute_url(self, request=None):
|
def get_absolute_url(self, request=None):
|
||||||
return reverse('api:workflow_approval_template_detail', kwargs={'pk': self.pk}, request=request)
|
return reverse('api:workflow_approval_template_detail', kwargs={'pk': self.pk}, request=request)
|
||||||
|
|
||||||
@property
|
|
||||||
def notification_templates(self):
|
|
||||||
base_notification_templates = NotificationTemplate.objects.all()
|
|
||||||
error_notification_templates = list(base_notification_templates
|
|
||||||
.filter(unifiedjobtemplate_notification_templates_for_errors__in=[self]))
|
|
||||||
started_notification_templates = list(base_notification_templates
|
|
||||||
.filter(unifiedjobtemplate_notification_templates_for_started__in=[self]))
|
|
||||||
success_notification_templates = list(base_notification_templates
|
|
||||||
.filter(unifiedjobtemplate_notification_templates_for_success__in=[self]))
|
|
||||||
return dict(error=list(error_notification_templates),
|
|
||||||
started=list(started_notification_templates),
|
|
||||||
success=list(success_notification_templates))
|
|
||||||
|
|
||||||
# base_notification_templates = NotificationTemplate.objects.all()
|
|
||||||
# approval_notification_templates = list(base_notification_templates
|
|
||||||
# .filter(unifiedjobtemplate_notification_templates_for_errors__in=[self]),
|
|
||||||
# base_notification_templates
|
|
||||||
# .filter(unifiedjobtemplate_notification_templates_for_started__in=[self]),
|
|
||||||
# base_notification_templates
|
|
||||||
# .filter(unifiedjobtemplate_notification_templates_for_success__in=[self]))
|
|
||||||
# return dict(approval=list(approval_notification_templates))
|
|
||||||
# Placeholder... Approval nodes don't have orgs!
|
|
||||||
# if self.project is not None and self.project.organization is None:
|
|
||||||
# error_notification_templates = set(error_notification_templates + list(base_notification_templates.filter(
|
|
||||||
# organization_notification_templates_for_errors=self.project.organization)))
|
|
||||||
# started_notification_templates = set(started_notification_templates + list(base_notification_templates.filter(
|
|
||||||
# organization_notification_templates_for_started=self.project.organization)))
|
|
||||||
# success_notification_templates = set(success_notification_templates + list(base_notification_templates.filter(
|
|
||||||
# organization_notification_templates_for_success=self.project.organization)))
|
|
||||||
# return dict(error=list(error_notification_templates),
|
|
||||||
# approval_notification_templates=list(needs_approval_notification_templates),
|
|
||||||
# success=list(success_notification_templates))
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def workflow_job_template(self):
|
def workflow_job_template(self):
|
||||||
return self.workflowjobtemplatenodes.first().workflow_job_template
|
return self.workflowjobtemplatenodes.first().workflow_job_template
|
||||||
@ -726,6 +699,7 @@ class WorkflowApproval(UnifiedJob, JobNotificationMixin):
|
|||||||
def approve(self, request=None):
|
def approve(self, request=None):
|
||||||
self.status = 'successful'
|
self.status = 'successful'
|
||||||
self.save()
|
self.save()
|
||||||
|
self.send_approval_notification(self.status)
|
||||||
self.websocket_emit_status(self.status)
|
self.websocket_emit_status(self.status)
|
||||||
schedule_task_manager()
|
schedule_task_manager()
|
||||||
return reverse('api:workflow_approval_approve', kwargs={'pk': self.pk}, request=request)
|
return reverse('api:workflow_approval_approve', kwargs={'pk': self.pk}, request=request)
|
||||||
@ -733,24 +707,27 @@ class WorkflowApproval(UnifiedJob, JobNotificationMixin):
|
|||||||
def deny(self, request=None):
|
def deny(self, request=None):
|
||||||
self.status = 'failed'
|
self.status = 'failed'
|
||||||
self.save()
|
self.save()
|
||||||
|
self.send_approval_notification(self.status)
|
||||||
self.websocket_emit_status(self.status)
|
self.websocket_emit_status(self.status)
|
||||||
schedule_task_manager()
|
schedule_task_manager()
|
||||||
return reverse('api:workflow_approval_deny', kwargs={'pk': self.pk}, request=request)
|
return reverse('api:workflow_approval_deny', kwargs={'pk': self.pk}, request=request)
|
||||||
|
|
||||||
# Placeholder...
|
def signal_start(self, **kwargs):
|
||||||
def approval_notification_data(self):
|
can_start = super(WorkflowApproval, self).signal_start(**kwargs)
|
||||||
result = super(WorkflowApproval, self).approval_notification_data()
|
self.send_approval_notification('running')
|
||||||
str_arr = ['Approval summary:', '']
|
return can_start
|
||||||
for node in self.workflow_job_nodes.all().select_related('job'):
|
|
||||||
if node.job is None:
|
|
||||||
node_job_description = 'no job.'
|
|
||||||
else:
|
|
||||||
node_job_description = ('job #{0}, "{1}", which finished with status {2}.'
|
|
||||||
.format(node.job.id, node.job.name, node.job.status))
|
|
||||||
str_arr.append("- node #{0} spawns {1}".format(node.id, node_job_description))
|
|
||||||
result['body'] = '\n'.join(str_arr)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
def send_approval_notification(self, status):
|
||||||
|
from awx.main.tasks import send_notifications # avoid circular import
|
||||||
|
for nt in self.workflow_job_template.notification_templates["approvals"]:
|
||||||
|
(notification_subject, notification_body) = self.workflow_job.build_notification_message(nt, status)
|
||||||
|
|
||||||
|
def send_it(local_nt=nt, local_subject=notification_subject, local_body=notification_body):
|
||||||
|
def _func():
|
||||||
|
send_notifications.delay([local_nt.generate_notification(local_subject, local_body).id],
|
||||||
|
job_id=self.id)
|
||||||
|
return _func
|
||||||
|
connection.on_commit(send_it())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def workflow_job_template(self):
|
def workflow_job_template(self):
|
||||||
|
@ -239,12 +239,6 @@ class TaskManager():
|
|||||||
task.send_notification_templates('running')
|
task.send_notification_templates('running')
|
||||||
logger.debug('Transitioning %s to running status.', task.log_format)
|
logger.debug('Transitioning %s to running status.', task.log_format)
|
||||||
schedule_task_manager()
|
schedule_task_manager()
|
||||||
# Placeholder...
|
|
||||||
elif type(task) is WorkflowApproval:
|
|
||||||
task.status = 'pending'
|
|
||||||
task.send_notification_templates('pending')
|
|
||||||
logger.debug('Transitioning %s to pending status.', task.log_format)
|
|
||||||
schedule_task_manager()
|
|
||||||
elif not task.supports_isolation() and rampart_group.controller_id:
|
elif not task.supports_isolation() and rampart_group.controller_id:
|
||||||
# non-Ansible jobs on isolated instances run on controller
|
# non-Ansible jobs on isolated instances run on controller
|
||||||
task.instance_group = rampart_group.controller
|
task.instance_group = rampart_group.controller
|
||||||
@ -539,6 +533,7 @@ class TaskManager():
|
|||||||
logger.warn(timeout_message)
|
logger.warn(timeout_message)
|
||||||
task.timed_out = True
|
task.timed_out = True
|
||||||
task.status = 'failed'
|
task.status = 'failed'
|
||||||
|
self.send_approval_notification(task.status)
|
||||||
task.websocket_emit_status(task.status)
|
task.websocket_emit_status(task.status)
|
||||||
task.job_explanation = timeout_message
|
task.job_explanation = timeout_message
|
||||||
task.save(update_fields=['status', 'job_explanation', 'timed_out'])
|
task.save(update_fields=['status', 'job_explanation', 'timed_out'])
|
||||||
|
Loading…
Reference in New Issue
Block a user