Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] Notification filter on state disable all notifications #743

Merged
merged 3 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions profiles/forms/instance_notification_form.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.forms import MultipleChoiceField, SelectMultiple
from django.forms import TypedMultipleChoiceField, SelectMultiple

from Squest.utils.squest_model_form import SquestModelForm
from profiles.models import InstanceNotification
Expand All @@ -10,10 +10,11 @@ class Meta:
model = InstanceNotification
fields = ["name", "services", "instance_states", "when"]

instance_states = MultipleChoiceField(label="Instance states",
required=False,
choices=InstanceState.choices,
widget=SelectMultiple(attrs={'class': 'form-control'}))
instance_states = TypedMultipleChoiceField(label="Instance states",
coerce=int,
required=False,
choices=InstanceState.choices,
widget=SelectMultiple(attrs={'class': 'form-control'}))

def __init__(self, user, *args, **kwargs):
# get arguments from instance
Expand Down
11 changes: 6 additions & 5 deletions profiles/forms/request_notification_form.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.forms import MultipleChoiceField, SelectMultiple
from django.forms import TypedMultipleChoiceField, SelectMultiple

from Squest.utils.squest_model_form import SquestModelForm
from profiles.models.request_notification import RequestNotification
Expand All @@ -10,10 +10,11 @@ class Meta:
model = RequestNotification
fields = ["name", "services", "operations", "request_states", "when"]

request_states = MultipleChoiceField(label="Request states",
required=False,
choices=RequestState.choices,
widget=SelectMultiple(attrs={'class': 'form-control'}))
request_states = TypedMultipleChoiceField(label="Request states",
coerce=int,
required=False,
choices=RequestState.choices,
widget=SelectMultiple(attrs={'class': 'form-control'}))

def __init__(self, user, *args, **kwargs):
# get arguments from instance
Expand Down
52 changes: 52 additions & 0 deletions profiles/migrations/0023_notificationstatefield.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generated by Django 4.2.6 on 2023-12-05 15:00

from django.db import migrations, models;

def update_state_field(apps, schema_editor):
InstanceNotification = apps.get_model('profiles', 'InstanceNotification')
RequestNotification = apps.get_model('profiles', 'RequestNotification')
for notification in InstanceNotification.objects.all():
notification.instance_states_tmp = list(map(int, notification.instance_states))
notification.save()
for notification in RequestNotification.objects.all():
notification.request_states_tmp = list(map(int, notification.request_states))
notification.save()


class Migration(migrations.Migration):

dependencies = [
('profiles', '0022_alter_permission_options'),
]

operations = [
migrations.AddField(
model_name='instancenotification',
name='instance_states_tmp',
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name='requestnotification',
name='request_states_tmp',
field=models.JSONField(blank=True, default=list),
),
migrations.RunPython(update_state_field),
migrations.RemoveField(
model_name='instancenotification',
name='instance_states',
),
migrations.RemoveField(
model_name='requestnotification',
name='request_states',
),
migrations.RenameField(
model_name='instancenotification',
old_name='instance_states_tmp',
new_name='instance_states',
),
migrations.RenameField(
model_name='requestnotification',
old_name='request_states_tmp',
new_name='request_states',
),
]
7 changes: 2 additions & 5 deletions profiles/models/instance_notification.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.db.models import CASCADE, ForeignKey, CharField
from django.db.models import CASCADE, ForeignKey, JSONField
from django.urls import reverse_lazy
from django_mysql.models import ListCharField

from Squest.utils.ansible_when import AnsibleWhen
from profiles.models.notification_filter import NotificationFilter
Expand All @@ -15,9 +14,7 @@ class InstanceNotification(NotificationFilter):
related_name="instance_notification_filters",
related_query_name="instance_notification_filter",
)
instance_states = ListCharField(base_field=CharField(max_length=50),
size=15,
max_length=(15 * 50 + 14))
instance_states = JSONField(default=list, blank=True)

def is_authorized(self, instance):
if self.instance_states and instance.state not in self.instance_states:
Expand Down
7 changes: 2 additions & 5 deletions profiles/models/request_notification.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.db.models import CASCADE, ForeignKey, ManyToManyField, CharField
from django.db.models import CASCADE, ForeignKey, ManyToManyField, JSONField
from django.urls import reverse_lazy
from django_mysql.models import ListCharField

from Squest.utils.ansible_when import AnsibleWhen
from profiles.models.notification_filter import NotificationFilter
Expand All @@ -15,9 +14,7 @@ class RequestNotification(NotificationFilter):
related_name="request_notification_filters",
related_query_name="request_notification_filter",
)
request_states = ListCharField(base_field=CharField(max_length=50),
size=15,
max_length=(15 * 50 + 14))
request_states = JSONField(default=list, blank=True)
operations = ManyToManyField(
"service_catalog.Operation",
blank=True,
Expand Down
6 changes: 5 additions & 1 deletion service_catalog/api/views/job_template_sync.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging

from django_celery_results.models import TaskResult
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
Expand All @@ -6,11 +8,12 @@
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from service_catalog import tasks
from service_catalog.api.serializers import TaskResultSerializer
from service_catalog.models import TowerServer, JobTemplate

logger = logging.getLogger(__name__)


class JobTemplateSync(APIView):
permission_classes = [IsAuthenticated]
Expand All @@ -23,6 +26,7 @@ def post(self, request, tower_server_id, job_template_id=None):
job_template = get_object_or_404(JobTemplate, id=job_template_id, tower_server=tower_server.id)
if not request.user.has_perm('service_catalog.sync_towerserver', tower_server):
raise PermissionDenied
logger.debug(f'Celery task: "towerserver_sync" will be send with tower_id: {tower_server.id} and job_template_id: {job_template_id}')
task = tasks.towerserver_sync.delay(tower_server.id, job_template_id)
task_result = TaskResult(task_id=task.task_id)
task_result.save()
Expand Down
24 changes: 10 additions & 14 deletions service_catalog/forms/email_template_form.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging

from django.contrib.auth.models import User
from django.forms import MultipleChoiceField, SelectMultiple
from django.forms import TypedMultipleChoiceField, SelectMultiple

from Squest.utils.ansible_when import AnsibleWhen
from Squest.utils.squest_form import SquestForm
Expand All @@ -10,26 +10,20 @@
from service_catalog.mail_utils import send_template_email
from service_catalog.models import EmailTemplate, InstanceState, Service, Instance


logger = logging.getLogger(__name__)


class EmailTemplateForm(SquestModelForm):

instance_states = MultipleChoiceField(label="Instance states",
required=False,
choices=InstanceState.choices,
widget=SelectMultiple(attrs={'class': 'form-control'}))
instance_states = TypedMultipleChoiceField(label="Instance states",
coerce=int,
required=False,
choices=InstanceState.choices,
widget=SelectMultiple(attrs={'class': 'form-control'}))

class Meta:
model = EmailTemplate
fields = ["name", "email_title", "html_content", "services", "instance_states", "quota_scopes", "when"]

def clean_instance_states(self):
data = self.cleaned_data["instance_states"]
data_as_int = [int(el) for el in data]
return data_as_int


class EmailTemplateSendForm(SquestForm):

Expand Down Expand Up @@ -60,8 +54,9 @@ def __init__(self, *args, **kwargs):

limit_users = User.objects.filter(instance__in=qs_instance).distinct()

self.fields["users"] = MultipleChoiceField(
self.fields["users"] = TypedMultipleChoiceField(
label="User emails",
coerce=int,
required=True,
choices=User.objects.all().values_list("id", "username"),
initial=list(limit_users.values_list("id", flat=True)),
Expand All @@ -80,5 +75,6 @@ def when_render(when, instance):

def save(self):
user_id_list = self.cleaned_data.get('users')
logger.info(f"Sending email template name '{self.email_template.name}' to users: '{self.cleaned_data.get('users')}'")
logger.info(
f"Sending email template name '{self.email_template.name}' to users: '{self.cleaned_data.get('users')}'")
send_template_email(self.email_template, user_id_list)
44 changes: 37 additions & 7 deletions service_catalog/mail_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def _apply_when_filter_instance(user_qs, squest_object):
user_qs = _exclude_user_without_email(user_qs)
if user_qs.filter(profile__instance_notification_enabled=False).exists():
logger.info(f"The following users have disabled their instance notification. They won't be notified:"
f'{linesep.join(f" - {user.username}" for user in user_qs.filter(profile__instance_notification_enabled=False))}')
f'{linesep.join(f" - {user.username}" for user in user_qs.filter(profile__instance_notification_enabled=False))}')
for user in user_qs.exclude(profile__instance_notification_enabled=False):
if user.profile.is_notification_authorized_for_instance(squest_object):
user_emails.append(user.email)
Expand All @@ -52,7 +52,7 @@ def _apply_when_filter_request(user_qs, squest_object):
user_qs = _exclude_user_without_email(user_qs)
if user_qs.filter(profile__request_notification_enabled=False).exists():
logger.info(f"The following users have disabled their request notification. They won't be notified:"
f'{linesep.join(user.username for user in user_qs.filter(profile__request_notification_enabled=False))}')
f'{linesep.join(user.username for user in user_qs.filter(profile__request_notification_enabled=False))}')
for user in user_qs.exclude(profile__request_notification_enabled=False):
if user.profile.is_notification_authorized_for_request(squest_object):
user_emails.append(user.email)
Expand Down Expand Up @@ -120,9 +120,14 @@ def send_mail_request_update(target_request, user_applied_state=None, message=No
html_content = html_template.render(context)
if receiver_email_list is None:
receiver_email_list = _get_receivers_for_request(target_request)
headers = _get_headers(subject)
logger.debug(
f'Celery task: "send_email" will be send with subject: {subject}, plain_text: {plain_text}, html_template: '
f'{html_content}, from_email: {DEFAULT_FROM_EMAIL}, receivers: None, bcc: {receiver_email_list}, '
f'reply_to: None, headers: {headers}')
tasks.send_email.delay(subject, plain_text, html_content, DEFAULT_FROM_EMAIL,
bcc=receiver_email_list,
headers=_get_headers(subject))
headers=headers)


def send_mail_new_support_message(message):
Expand All @@ -136,6 +141,11 @@ def send_mail_new_support_message(message):
html_template = get_template(template_name)
html_content = html_template.render(context)
receiver_email_list = _get_receivers_for_support_message(message)
headers = _get_headers(subject)
logger.debug(
f'Celery task: "send_email" will be send with subject: {subject}, plain_text: {plain_text}, html_template: '
f'{html_content}, from_email: {DEFAULT_FROM_EMAIL}, receivers: None, bcc: {receiver_email_list}, '
f'reply_to: None, headers: {headers}')
tasks.send_email.delay(subject, plain_text, html_content, DEFAULT_FROM_EMAIL,
bcc=receiver_email_list,
headers=_get_headers(subject))
Expand All @@ -151,9 +161,14 @@ def send_mail_support_is_closed(support):
html_template = get_template(template_name)
html_content = html_template.render(context)
receiver_email_list = _get_receivers_for_support(support)
headers = _get_headers(subject)
logger.debug(
f'Celery task: "send_email" will be send with subject: {subject}, plain_text: {plain_text}, html_template: '
f'{html_content}, from_email: {DEFAULT_FROM_EMAIL}, receivers: None, bcc: {receiver_email_list}, '
f'reply_to: None, headers: {headers}')
tasks.send_email.delay(subject, plain_text, html_content, DEFAULT_FROM_EMAIL,
bcc=receiver_email_list,
headers=_get_headers(subject))
headers=headers)


def send_mail_new_comment_on_request(message):
Expand All @@ -166,9 +181,14 @@ def send_mail_new_comment_on_request(message):
html_template = get_template(template_name)
html_content = html_template.render(context)
receiver_email_list = _get_receivers_for_request_message(message)
headers = _get_headers(subject)
logger.debug(
f'Celery task: "send_email" will be send with subject: {subject}, plain_text: {plain_text}, html_template: '
f'{html_content}, from_email: {DEFAULT_FROM_EMAIL}, receivers: None, bcc: {receiver_email_list}, '
f'reply_to: None, headers: {headers}')
tasks.send_email.delay(subject, plain_text, html_content, DEFAULT_FROM_EMAIL,
bcc=receiver_email_list,
headers=_get_headers(subject))
headers=headers)


def send_email_request_canceled(target_request, user_applied_state=None):
Expand All @@ -192,9 +212,14 @@ def send_email_request_canceled(target_request, user_applied_state=None):
html_template = get_template(template_name)
html_content = html_template.render(context)
receiver_email_list = _get_receivers_for_request(target_request)
headers = _get_headers(subject)
logger.debug(
f'Celery task: "send_email" will be send with subject: {subject}, plain_text: {plain_text}, html_template: '
f'{html_content}, from_email: {DEFAULT_FROM_EMAIL}, receivers: None, bcc: {receiver_email_list}, '
f'reply_to: None, headers: {headers}')
tasks.send_email.delay(subject, plain_text, html_content, DEFAULT_FROM_EMAIL,
bcc=receiver_email_list,
headers=_get_headers(subject))
headers=headers)


def send_template_email(email_template, user_id_list):
Expand All @@ -213,6 +238,11 @@ def send_template_email(email_template, user_id_list):
'current_site': settings.SQUEST_HOST}
html_template = get_template(template_name)
html_content = html_template.render(context)
headers = _get_headers(subject)
logger.debug(
f'Celery task: "send_email" will be send with subject: {subject}, plain_text: {plain_text}, html_template: '
f'{html_content}, from_email: {DEFAULT_FROM_EMAIL}, receivers: None, bcc: {user_emails}, reply_to: None, '
f'headers: {headers}')
tasks.send_email.delay(subject, plain_text, html_content, DEFAULT_FROM_EMAIL,
bcc=user_emails,
headers=_get_headers(subject))
headers=headers)
4 changes: 4 additions & 0 deletions service_catalog/views/tower_server.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.http import JsonResponse, HttpResponseNotAllowed
Expand All @@ -15,6 +16,8 @@
from service_catalog.tables.job_template_tables import JobTemplateTable
from service_catalog.tables.tower_server_tables import TowerServerTable

logger = logging.getLogger(__name__)


class TowerServerListView(SquestListView):
table_class = TowerServerTable
Expand Down Expand Up @@ -62,6 +65,7 @@ def towerserver_sync(request, tower_id, pk=None):
tower_server = get_object_or_404(TowerServer, pk=tower_id)
if not request.user.has_perm('service_catalog.sync_towerserver', tower_server):
raise PermissionDenied
logger.debug(f'Celery task: "towerserver_sync" will be send with tower_id: {tower_id} and job_template_id: {pk}')
task = tasks.towerserver_sync.delay(tower_id, pk)
task_result = TaskResult(task_id=task.task_id)
task_result.save()
Expand Down
Loading