From 4e1a2ba20bc30a675b551841a7ebb7b7f1ad0690 Mon Sep 17 00:00:00 2001 From: rmanach Date: Sat, 23 Sep 2023 14:27:08 +0200 Subject: [PATCH] fix events url + check on deployment manager + refactor send event --- deployment/channel.py | 46 ++++++++++++++++++++++++++++++++++++-- deployment/tasks.py | 52 ++++++------------------------------------- deployment/urls.py | 8 +++---- deployment/views.py | 27 +++++----------------- 4 files changed, 61 insertions(+), 72 deletions(-) diff --git a/deployment/channel.py b/deployment/channel.py index 7730fd9..7bf9336 100644 --- a/deployment/channel.py +++ b/deployment/channel.py @@ -1,6 +1,48 @@ +from django.contrib.auth.models import User +from django_eventstream import send_event from django_eventstream.channelmanager import DefaultChannelManager +from deployment.models import Deployment + + +def parse_channel(channel: str) -> tuple[str] | None: + parts = channel.lstrip("deployment_").split("_") + if len_part := len(parts): + if len_part == 1: + return (parts[0], "") + if len_part == 2: + return (parts[0], parts[1]) + return + class DeploymentChannelManager(DefaultChannelManager): - def can_read_channel(self, user, channel): - return user is not None and user.is_authenticated + def can_read_channel(self, user: User, channel: str): + match parse_channel(channel): + case (user_id, ""): + return user_id == user.id or user.is_superuser + case (user_id, _): + # TODO(rmanach): check if the deployment belongs to the user + return user_id == user.id or user.is_superuser + return False + + +class Event: + @staticmethod + def send_details(deployment: Deployment, progress: int): + send_event( + f"deployment_{deployment.user.id}_{deployment.id}", + "message", + { + "id": deployment.id, + "status": deployment.status, + "progress": progress, + }, + ) + + @staticmethod + def send(deployment: Deployment): + send_event( + f"deployment_{deployment.user.id}", + "message", + {"id": deployment.id, "status": deployment.status}, + ) diff --git a/deployment/tasks.py b/deployment/tasks.py index c230c26..f801e77 100644 --- a/deployment/tasks.py +++ b/deployment/tasks.py @@ -4,8 +4,8 @@ from uuid import UUID from celery import shared_task from celery.contrib.abortable import AbortableTask -from django_eventstream import send_event +from deployment.channel import Event from deployment.models import Deployment, Type, Status @@ -32,15 +32,7 @@ class DeploymentTask(AbortableTask): self.update_state(meta={"progress": progress}) self.deploy.status = status - send_event( - f"deployment-{self.deploy.id}", - "message", - { - "id": self.deploy.id, - "status": self.deploy.status, - "progress": progress, - }, - ) + Event.send_details(self.deploy, progress) def run_medium(self): progress = 62 @@ -56,15 +48,7 @@ class DeploymentTask(AbortableTask): self.update_state(meta={"progress": progress}) self.deploy.status = status - send_event( - f"deployment-{self.deploy.id}", - "message", - { - "id": self.deploy.id, - "status": self.deploy.status, - "progress": progress, - }, - ) + Event.send_details(self.deploy, progress) def run_large(self): progress = 0 @@ -72,33 +56,15 @@ class DeploymentTask(AbortableTask): for i in self.try_exec(6): progress = i * 20 self.update_state(meta={"progress": progress}) - if progress != 100: - send_event( - f"deployment-{self.deploy.id}", - "message", - { - "id": self.deploy.id, - "status": self.deploy.status - if i != 5 - else Status.SUCCESS.name, - "progress": progress, - }, - ) + if i != 5: + Event.send_details(self.deploy, progress) except Exception as e: self.deploy.status = Status.FAILED.name self.deploy.error = e else: self.deploy.status = Status.SUCCESS.name - send_event( - f"deployment-{self.deploy.id}", - "message", - { - "id": self.deploy.id, - "status": self.deploy.status, - "progress": progress, - }, - ) + Event.send_details(self.deploy, progress) @property def progress(self): @@ -125,11 +91,7 @@ class DeploymentTask(AbortableTask): self.deploy.task_id = None self.deploy.save() - send_event( - "deployment", - "message", - {"id": self.deploy.id, "status": self.deploy.status}, - ) + Event.send(self.deploy) @shared_task(base=DeploymentTask, bind=True, ignore_result=True) diff --git a/deployment/urls.py b/deployment/urls.py index 574bfd2..8d73b6e 100644 --- a/deployment/urls.py +++ b/deployment/urls.py @@ -10,14 +10,14 @@ urlpatterns = [ path("/deploy", deploy, name="deployment-launch"), path("/abort", abort, name="deployment-abort"), path( - "events/", + "events//", include(django_eventstream.urls), - {"channels": ["deployment"]}, + {"format-channels": ["deployment_{user_id}"]}, name="deployment-events", ), path( - "/events/", + "events///", include(django_eventstream.urls), - {"format-channels": ["deployment-{deployment_id}"]}, + {"format-channels": ["deployment_{user_id}_{deployment_id}"]}, ), ] diff --git a/deployment/views.py b/deployment/views.py index 403e711..e995f95 100644 --- a/deployment/views.py +++ b/deployment/views.py @@ -9,8 +9,8 @@ from django.http import ( HttpResponseBadRequest, ) from django.shortcuts import render, get_object_or_404 -from django_eventstream import send_event +from deployment.channel import Event from deployment.forms import DeploymentForm from deployment.models import Deployment, Status from deployment.tasks import deploy as launch_deploy @@ -30,8 +30,8 @@ def index(request): "deployment/board.html", { "page_obj": page_obj, - "range_pages": [i + 1 for i in range(page_obj.paginator.num_pages)], - "url": "events/", + "range_pages": (i + 1 for i in range(page_obj.paginator.num_pages)), + "url": f"events/{request.user.id}/", }, ) @@ -74,23 +74,8 @@ def abort(request, deployment_id): deployment.task_id = None deployment.save() - # first event in details - send_event( - f"deployment-{deployment.id}", - "message", - { - "id": deployment.id, - "status": deployment.status, - "progress": progress, - }, - ) - - # global event - send_event( - "deployment", - "message", - {"id": deployment.id, "status": deployment.status}, - ) + Event.send_details(deployment, progress) + Event.send(deployment) return HttpResponseRedirect(f"/deployment/{deployment.id}") @@ -118,7 +103,7 @@ def details(request, deployment_id): return render( request, "deployment/details.html", - {"deployment": deployment, "url": f"{deployment.id}/events/"}, + {"deployment": deployment, "url": f"events/{request.user.id}/{deployment.id}/"}, )