From a091b144feb51ad643c6652219974ed389b693aa Mon Sep 17 00:00:00 2001 From: yoneyan Date: Sun, 15 Sep 2024 17:01:58 +0900 Subject: [PATCH] =?UTF-8?q?#43=20DB=E6=83=85=E5=A0=B1=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=99=82=E3=81=ABSlack=E9=80=9A=E7=9F=A5=E3=81=99=E3=82=8B?= =?UTF-8?q?=E6=A9=9F=E8=83=BD=E3=81=AE=E5=AE=9F=E8=A3=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- custom_auth/signals.py | 55 ++++++++++++++++++++---------- dsbd/notify.py | 77 ++++++++++++++++++++++++++++++++++++------ dsbd/settings.py | 1 + dsbd/utils.py | 30 ++++++++++++++++ ip/apps.py | 3 ++ ip/signals.py | 44 ++++++++++++++++++++++++ noc/apps.py | 3 ++ noc/signals.py | 18 ++++++++++ notice/apps.py | 3 ++ notice/signals.py | 18 ++++++++++ router/apps.py | 3 ++ router/signals.py | 31 +++++++++++++++++ service/apps.py | 3 ++ service/signals.py | 31 +++++++++++++++++ ticket/signals.py | 26 ++++++-------- 15 files changed, 302 insertions(+), 44 deletions(-) create mode 100644 dsbd/utils.py create mode 100644 ip/signals.py create mode 100644 noc/signals.py create mode 100644 notice/signals.py create mode 100644 router/signals.py create mode 100644 service/signals.py diff --git a/custom_auth/signals.py b/custom_auth/signals.py index 696fd53..3cbc269 100644 --- a/custom_auth/signals.py +++ b/custom_auth/signals.py @@ -1,9 +1,8 @@ from django.db.models.signals import post_save, pre_delete, pre_save from django.dispatch import receiver -from custom_auth.models import Group, User -from custom_auth.tool import SignalTool -from dsbd.notify import notify_db_save +from custom_auth.models import Group, User, UserGroup +from dsbd.notify import notify_delete_db, notify_insert_db, notify_update_db @receiver(pre_save, sender=User) @@ -17,26 +16,48 @@ def user_model_pre_save(sender, instance, **kwargs): @receiver(post_save, sender=User) def post_user(sender, instance, created, **kwargs): if created: - text = SignalTool().get_create_user(True, instance) - notify_db_save(table_name="User", type=0, data=text) - else: - text = SignalTool().get_update_user(instance._pre_save_instance, instance) - notify_db_save(table_name="User", type=1, data=text) + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_insert_db(model_name=sender.__name__, instance=instance) @receiver(pre_delete, sender=User) def delete_user(sender, instance, **kwargs): - text = SignalTool().get_create_user(False, instance) - notify_db_save(table_name="User", type=2, data=text) + notify_delete_db(model_name=sender.__name__, instance=instance) @receiver(post_save, sender=Group) -def update_group(sender, instance, created, **kwargs): - # 審査OKステータス変更時にサービス追加許可にする - if instance.is_pass and not instance.allow_service_add: +def post_group(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + + notify_update_db(model_name=sender.__name__, instance=instance) + # 審査NG => 審査OKの場合にサービス追加とJPNIC追加を出来るようにする + if not instance._pre_save_instance.is_pass and instance.is_pass: instance.allow_service_add = True - instance.save(update_fields=["allow_service_add"]) - # 審査NGステータス変更時にサービス追加拒否設定にする - if not instance.is_pass and instance.allow_service_add: + instance.allow_jpnic_add = True + instance.save(update_fields=["allow_service_add", "allow_jpnic_add"]) + # Statusが1以外の場合はサービス追加とJPNIC追加を禁止する + if instance.status != 1: instance.allow_service_add = False - instance.save(update_fields=["allow_service_add"]) + instance.allow_jpnic_add = False + instance.save(update_fields=["allow_service_add", "allow_jpnic_add"]) + + +@receiver(pre_delete, sender=Group) +def delete_group(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) + + +@receiver(post_save, sender=UserGroup) +def post_user_group(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_insert_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=UserGroup) +def delete_user_group(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) diff --git a/dsbd/notify.py b/dsbd/notify.py index fb99067..c836c7d 100644 --- a/dsbd/notify.py +++ b/dsbd/notify.py @@ -1,23 +1,78 @@ from django.conf import settings from slack_sdk import WebhookClient +from dsbd.utils import get_admin_history_url, get_admin_url -def notify_db_save(table_name="", type=0, data=""): - event_name = "create" - color = "good" - match type: - case 1: - event_name = "update" - case 2: - event_name = "delete" - color = "danger" + +def notify_delete_db(model_name: str, instance): + admin_history_url = get_admin_history_url(instance) + + message = f"レコードが削除されました:\n{instance}" + client = WebhookClient(settings.SLACK_WEBHOOK_LOG) + client.send( + attachments=[ + { + "color": "danger", + "title": "[%s]" % f"{model_name}", + "text": f"{message}\n管理画面(履歴): {admin_history_url}", + } + ], + ) + + +def notify_insert_db(model_name: str, instance): + admin_url = get_admin_url(instance) + admin_history_url = get_admin_history_url(instance) + + message = f"新しいレコードが登録されました:\n{instance}" client = WebhookClient(settings.SLACK_WEBHOOK_LOG) client.send( - text="[%s(%s)]" % (table_name, event_name), - attachments=[{"color": color, "title": "[%s(%s)]" % (table_name, event_name), "text": "%s" % (data,)}], + attachments=[ + { + "color": "good", + "title": "[%s]" % f"{model_name}", + "text": f"{message}\n管理画面: {admin_url}\n管理画面(履歴): {admin_history_url}", + } + ], ) +def notify_update_db(model_name: str, instance): + admin_url = get_admin_url(instance) + admin_history_url = get_admin_history_url(instance) + + history = instance.history.all() + if history.count() < 2: + return # 履歴が2つ未満の場合は差分がないため、何もしない + + latest = history.first() # 最新の履歴 + previous = history[1] # 直前の履歴 + + changes = [] + + # フィールドごとの差分を確認 + for field in instance._meta.fields: + field_name = field.name + old_value = getattr(previous, field_name, None) + new_value = getattr(latest, field_name, None) + + if old_value != new_value: + changes.append(f"{field_name}: {old_value} -> {new_value}") + + if changes: + message = f"モデル '{instance}' の以下のフィールドが変更されました:\n" + "\n".join(changes) + client = WebhookClient(settings.SLACK_WEBHOOK_LOG) + client.send( + attachments=[ + { + "color": "good", + "title": "[%s]" % f"{model_name}", + "text": f"{message}\n管理画面: {admin_url}\n管理画面(履歴): {admin_history_url}", + } + ], + ) + + def notice_payment(metadata_type="", event_type="", data=None): client = WebhookClient(settings.SLACK_WEBHOOK_LOG) client.send( diff --git a/dsbd/settings.py b/dsbd/settings.py index ee54e8e..d1722cc 100644 --- a/dsbd/settings.py +++ b/dsbd/settings.py @@ -193,6 +193,7 @@ def _import_ldap_group_type(group_type_name): LOGIN_REDIRECT_URL = "/" DOMAIN_URL = os.environ.get("DOMAIN_URL", "http://localhost:8000") +ADMIN_DOMAIN_URL = os.environ.get("ADMIN_DOMAIN_URL", "http://localhost:8001") USER_LOGIN_VERIFY_EMAIL_EXPIRED_HOURS = os.environ.get("USER_LOGIN_VERIFY_EMAIL_EXPIRED_HOURS", 1) USER_LOGIN_VERIFY_EMAIL_EXPIRED_MINUTES = os.environ.get("USER_LOGIN_VERIFY_EMAIL_EXPIRED_MINUTES", 10) diff --git a/dsbd/utils.py b/dsbd/utils.py new file mode 100644 index 0000000..8e759dc --- /dev/null +++ b/dsbd/utils.py @@ -0,0 +1,30 @@ +from django.conf import settings +from django.urls import reverse + + +def get_admin_url(instance) -> str: + """ + 任意のモデルインスタンスの管理ページURLを生成する。 + """ + model_name = instance._meta.model_name + app_label = instance._meta.app_label + admin_url = reverse(f"admin:{app_label}_{model_name}_change", args=[instance.pk]) + + # フルURLにするために現在のサイトドメインを取得 + full_admin_url = f"{settings.ADMIN_DOMAIN_URL}{admin_url}" + + return full_admin_url + + +def get_admin_history_url(instance) -> str: + """ + 任意のモデルインスタンスの管理ページURLを生成する。 + """ + model_name = instance._meta.model_name + app_label = instance._meta.app_label + admin_url = reverse(f"admin:{app_label}_{model_name}_history", args=[instance.pk]) + + # フルURLにするために現在のサイトドメインを取得 + admin_history_url = f"{settings.ADMIN_DOMAIN_URL}{admin_url}" + + return admin_history_url diff --git a/ip/apps.py b/ip/apps.py index 2cd3d87..362c754 100644 --- a/ip/apps.py +++ b/ip/apps.py @@ -4,3 +4,6 @@ class CustomAdmin(AppConfig): name = "ip" verbose_name = "IP" + + def ready(self): + from . import signals # noqa diff --git a/ip/signals.py b/ip/signals.py new file mode 100644 index 0000000..bea9ba2 --- /dev/null +++ b/ip/signals.py @@ -0,0 +1,44 @@ +from django.db.models.signals import post_save, pre_delete +from django.dispatch import receiver + +from dsbd.notify import notify_delete_db, notify_insert_db, notify_update_db +from ip.models import IP, IPJPNICUser, JPNICUser + + +@receiver(post_save, sender=JPNICUser) +def post_jpnic_user(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=JPNICUser) +def delete_jpnic_user(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) + + +@receiver(post_save, sender=IP) +def post_ip(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=IP) +def delete_ip(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) + + +@receiver(post_save, sender=IPJPNICUser) +def post_ip_jpnic_user(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=IPJPNICUser) +def delete_ip_jpnic_user(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) diff --git a/noc/apps.py b/noc/apps.py index fd8e3c3..d83f964 100644 --- a/noc/apps.py +++ b/noc/apps.py @@ -4,3 +4,6 @@ class CustomAdmin(AppConfig): name = "noc" verbose_name = "NOC" + + def ready(self): + from . import signals # noqa diff --git a/noc/signals.py b/noc/signals.py new file mode 100644 index 0000000..f738ef0 --- /dev/null +++ b/noc/signals.py @@ -0,0 +1,18 @@ +from django.db.models.signals import post_save, pre_delete +from django.dispatch import receiver + +from dsbd.notify import notify_delete_db, notify_insert_db, notify_update_db +from noc.models import NOC + + +@receiver(post_save, sender=NOC) +def post_noc(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=NOC) +def delete_noc(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) diff --git a/notice/apps.py b/notice/apps.py index 89cafc9..febc65c 100644 --- a/notice/apps.py +++ b/notice/apps.py @@ -4,3 +4,6 @@ class Notice(AppConfig): name = "notice" verbose_name = "通知" + + def ready(self): + from . import signals # noqa diff --git a/notice/signals.py b/notice/signals.py new file mode 100644 index 0000000..b5c8cb3 --- /dev/null +++ b/notice/signals.py @@ -0,0 +1,18 @@ +from django.db.models.signals import post_save, pre_delete +from django.dispatch import receiver + +from dsbd.notify import notify_delete_db, notify_insert_db, notify_update_db +from notice.models import Notice + + +@receiver(post_save, sender=Notice) +def post_notice(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=Notice) +def delete_notice(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) diff --git a/router/apps.py b/router/apps.py index 9b31c20..974b048 100644 --- a/router/apps.py +++ b/router/apps.py @@ -4,3 +4,6 @@ class CustomAdmin(AppConfig): name = "router" verbose_name = "Router" + + def ready(self): + from . import signals # noqa diff --git a/router/signals.py b/router/signals.py new file mode 100644 index 0000000..668a2fe --- /dev/null +++ b/router/signals.py @@ -0,0 +1,31 @@ +from django.db.models.signals import post_save, pre_delete +from django.dispatch import receiver + +from dsbd.notify import notify_delete_db, notify_insert_db, notify_update_db +from router.models import TunnelIP, TunnelRouter + + +@receiver(post_save, sender=TunnelRouter) +def post_tunnel_router(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=TunnelRouter) +def delete_tunnel_router(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) + + +@receiver(post_save, sender=TunnelIP) +def post_tunnel_ip(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=TunnelIP) +def delete_tunnel_ip(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) diff --git a/service/apps.py b/service/apps.py index e1c140e..6c3247b 100644 --- a/service/apps.py +++ b/service/apps.py @@ -4,3 +4,6 @@ class CustomAdmin(AppConfig): name = "service" verbose_name = "Service" + + def ready(self): + from . import signals # noqa diff --git a/service/signals.py b/service/signals.py new file mode 100644 index 0000000..1506630 --- /dev/null +++ b/service/signals.py @@ -0,0 +1,31 @@ +from django.db.models.signals import post_save, pre_delete +from django.dispatch import receiver + +from dsbd.notify import notify_delete_db, notify_insert_db, notify_update_db +from service.models import Connection, Service + + +@receiver(post_save, sender=Service) +def post_service(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=Service) +def delete_service(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) + + +@receiver(post_save, sender=Connection) +def post_connection(sender, instance, created, **kwargs): + if created: + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) + + +@receiver(pre_delete, sender=Connection) +def delete_connection(sender, instance, **kwargs): + notify_delete_db(model_name=sender.__name__, instance=instance) diff --git a/ticket/signals.py b/ticket/signals.py index cc73717..72536b1 100644 --- a/ticket/signals.py +++ b/ticket/signals.py @@ -4,9 +4,9 @@ from django.dispatch import receiver from django.template.loader import render_to_string -from dsbd.notify import notify_db_save +from dsbd.notify import notify_delete_db, notify_insert_db, notify_update_db from ticket.models import Chat, Ticket -from ticket.tool import SignalTool, get_user_lists +from ticket.tool import get_user_lists @receiver(pre_save, sender=Ticket) @@ -20,17 +20,14 @@ def ticket_model_pre_save(sender, instance, **kwargs): @receiver(post_save, sender=Ticket) def post_ticket(sender, instance, created, **kwargs): if created: - text = SignalTool().get_create_ticket(True, instance) - notify_db_save(table_name="Ticket", type=0, data=text) - else: - text = SignalTool().get_update_ticket(instance._pre_save_instance, instance) - notify_db_save(table_name="Ticket", type=1, data=text) + notify_insert_db(model_name=sender.__name__, instance=instance) + return + notify_update_db(model_name=sender.__name__, instance=instance) @receiver(pre_delete, sender=Ticket) def delete_ticket(sender, instance, **kwargs): - text = SignalTool().get_create_ticket(False, instance) - notify_db_save(table_name="Ticket", type=2, data=text) + notify_delete_db(model_name=sender.__name__, instance=instance) @receiver(pre_save, sender=Chat) @@ -44,8 +41,7 @@ def chat_model_pre_save(sender, instance, **kwargs): @receiver(post_save, sender=Chat) def post_chat(sender, instance, created, **kwargs): if created: - text = SignalTool().get_create_chat(True, instance) - notify_db_save(table_name="Chat", type=0, data=text) + notify_insert_db(model_name=sender.__name__, instance=instance) subject = "[HomeNOC Dashboard System]新着のメッセージがあります" for user_list in get_user_lists(instance.ticket): message = render_to_string( @@ -58,12 +54,10 @@ def post_chat(sender, instance, created, **kwargs): }, ) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [user_list.email], fail_silently=False) - else: - text = SignalTool().get_update_chat(instance._pre_save_instance, instance) - notify_db_save(table_name="Chat", type=1, data=text) + return + notify_update_db(model_name=sender.__name__, instance=instance) @receiver(pre_delete, sender=Chat) def delete_chat(sender, instance, **kwargs): - text = SignalTool().get_create_chat(False, instance) - notify_db_save(table_name="Chat", type=2, data=text) + notify_delete_db(model_name=sender.__name__, instance=instance)