diff --git a/awx/api/views/__init__.py b/awx/api/views/__init__.py index 92eaa04598..b494986ac8 100644 --- a/awx/api/views/__init__.py +++ b/awx/api/views/__init__.py @@ -751,27 +751,18 @@ class ProjectNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView): relationship = 'notification_templates_any' -class ProjectNotificationTemplatesStartedList(SubListCreateAttachDetachAPIView): +class ProjectNotificationTemplatesStartedList(ProjectNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.Project relationship = 'notification_templates_started' -class ProjectNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): +class ProjectNotificationTemplatesErrorList(ProjectNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.Project relationship = 'notification_templates_error' -class ProjectNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): +class ProjectNotificationTemplatesSuccessList(ProjectNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.Project relationship = 'notification_templates_success' @@ -2643,27 +2634,18 @@ class JobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView): relationship = 'notification_templates_any' -class JobTemplateNotificationTemplatesStartedList(SubListCreateAttachDetachAPIView): +class JobTemplateNotificationTemplatesStartedList(JobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.JobTemplate relationship = 'notification_templates_started' -class JobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): +class JobTemplateNotificationTemplatesErrorList(JobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.JobTemplate relationship = 'notification_templates_error' -class JobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): +class JobTemplateNotificationTemplatesSuccessList(JobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.JobTemplate relationship = 'notification_templates_success' @@ -3259,27 +3241,18 @@ class WorkflowJobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachA relationship = 'notification_templates_any' -class WorkflowJobTemplateNotificationTemplatesStartedList(SubListCreateAttachDetachAPIView): +class WorkflowJobTemplateNotificationTemplatesStartedList(WorkflowJobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.WorkflowJobTemplate relationship = 'notification_templates_started' -class WorkflowJobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): +class WorkflowJobTemplateNotificationTemplatesErrorList(WorkflowJobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.WorkflowJobTemplate relationship = 'notification_templates_error' -class WorkflowJobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): +class WorkflowJobTemplateNotificationTemplatesSuccessList(WorkflowJobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.WorkflowJobTemplate relationship = 'notification_templates_success' @@ -3444,27 +3417,18 @@ class SystemJobTemplateNotificationTemplatesAnyList(SubListCreateAttachDetachAPI relationship = 'notification_templates_any' -class SystemJobTemplateNotificationTemplatesStartedList(SubListCreateAttachDetachAPIView): +class SystemJobTemplateNotificationTemplatesStartedList(SystemJobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.SystemJobTemplate relationship = 'notification_templates_started' -class SystemJobTemplateNotificationTemplatesErrorList(SubListCreateAttachDetachAPIView): +class SystemJobTemplateNotificationTemplatesErrorList(SystemJobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.SystemJobTemplate relationship = 'notification_templates_error' -class SystemJobTemplateNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView): +class SystemJobTemplateNotificationTemplatesSuccessList(SystemJobTemplateNotificationTemplatesAnyList): - model = models.NotificationTemplate - serializer_class = serializers.NotificationTemplateSerializer - parent_model = models.SystemJobTemplate relationship = 'notification_templates_success' diff --git a/awx/main/models/notifications.py b/awx/main/models/notifications.py index 0b036d3783..8f16cf4af8 100644 --- a/awx/main/models/notifications.py +++ b/awx/main/models/notifications.py @@ -7,6 +7,7 @@ import logging from django.db import models from django.conf import settings from django.core.mail.message import EmailMessage +from django.db import connection from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import smart_str, force_text @@ -240,12 +241,16 @@ class JobNotificationMixin(object): notification_template_type = 'started' else: notification_template_type = 'error' - all_notification_templates = set(notification_templates.get(notification_template_type, []) + notification_templates.get('any', [])) - if len(all_notification_templates): - try: - (notification_subject, notification_body) = getattr(self, 'build_notification_%s_message' % status_str)() - except AttributeError: - raise NotImplementedError("build_notification_%s_message() does not exist" % status_str) + all_notification_templates = set(notification_templates.get(notification_template_type, [])) + if status_str != 'running': + all_notification_templates.update(notification_templates.get('any', [])) + try: + (notification_subject, notification_body) = getattr(self, 'build_notification_%s_message' % status_str)() + except AttributeError: + raise NotImplementedError("build_notification_%s_message() does not exist" % status_str) + + def send_it(): send_notifications.delay([n.generate_notification(notification_subject, notification_body).id for n in all_notification_templates], job_id=self.id) + connection.on_commit(send_it) diff --git a/awx/main/scheduler/task_manager.py b/awx/main/scheduler/task_manager.py index 46181b8b02..75c0544ff6 100644 --- a/awx/main/scheduler/task_manager.py +++ b/awx/main/scheduler/task_manager.py @@ -233,6 +233,7 @@ class TaskManager(): else: if type(task) is WorkflowJob: task.status = 'running' + task.send_notification_templates('running') # <---- logger.debug('Transitioning %s to running status.', task.log_format) schedule_task_manager() elif not task.supports_isolation() and rampart_group.controller_id: @@ -587,4 +588,4 @@ class TaskManager(): # Operations whose queries rely on modifications made during the atomic scheduling session for wfj in WorkflowJob.objects.filter(id__in=finished_wfjs): - wfj.send_notification_templates('started' if wfj.status == 'running' else ('succeeded' if wfj.status == 'successful' else 'failed')) + wfj.send_notification_templates('succeeded' if wfj.status == 'successful' else 'failed') diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 7aba377381..d73737a4b3 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -314,7 +314,7 @@ def send_notifications(notification_list, job_id=None): update_fields = ['status', 'notifications_sent'] try: sent = notification.notification_template.send(notification.subject, notification.body) - notification.status = "successful" or "running" + notification.status = "successful" notification.notifications_sent = sent except Exception as e: logger.error("Send Notification Failed {}".format(e)) @@ -1115,8 +1115,6 @@ class BaseTask(object): self.instance = self.update_model(pk, status='running', start_args='') # blank field to remove encrypted passwords - self.instance.send_notification_templates("running") - self.instance.websocket_emit_status("running") status, rc = 'error', None extra_update_fields = {} @@ -1133,6 +1131,7 @@ class BaseTask(object): try: isolated = self.instance.is_isolated() + self.instance.send_notification_templates("running") self.pre_run_hook(self.instance) if self.instance.cancel_flag: self.instance = self.update_model(self.instance.pk, status='canceled') diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index 2915a65aa1..0a84f754a5 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -378,6 +378,7 @@ class TestGenericRun(): job.status = 'running' job.cancel_flag = True job.websocket_emit_status = mock.Mock() + job.send_notification_templates = mock.Mock() task = tasks.RunJob() task.update_model = mock.Mock(wraps=update_model_wrapper) @@ -536,6 +537,7 @@ class TestAdhocRun(TestJobExecution): def test_options_jinja_usage(self, adhoc_job, adhoc_update_model_wrapper): adhoc_job.module_args = '{{ ansible_ssh_pass }}' adhoc_job.websocket_emit_status = mock.Mock() + adhoc_job.send_notification_templates = mock.Mock() task = tasks.RunAdHocCommand() task.update_model = mock.Mock(wraps=adhoc_update_model_wrapper)