def destroy(self, request, *args, **kwargs): domain = self.get_object() if domain.service and (domain.service.client.billing_settings. suspend_instead_of_terminate or reseller_suspend_instead_of_terminate( client=domain.service.client)): if domain.status in [ DomainStatus.active, DomainStatus.pending_transfer, DomainStatus.pending, DomainStatus.grace, DomainStatus.expired, ]: with transaction.atomic(): domain.status = DomainStatus.cancelled domain.save() domain.service.status = ServiceStatus.suspended return Response( { 'detail': _('Suspend instead of terminate is enabled for the client, domain canceled.' ) }, status=status.HTTP_202_ACCEPTED) return Response( { 'detail': _('Suspend instead of terminate is enabled for the client, domain not deleted.' ) }, status=status.HTTP_403_FORBIDDEN) return super().destroy(request, *args, **kwargs)
def perform_destroy(self, client): activity_helper.add_current_activity_params(client_name=client.name) if client.billing_settings.suspend_instead_of_terminate or reseller_suspend_instead_of_terminate( client=client): return self.suspend(self.request, client.pk) client.status = ClientStatus.deleting client.save() delete_all_resources = (self.request.query_params.get( 'delete_cloud_resources', None) in ('true', 'True', '1') or self.request.data.get( 'delete_cloud_resources', None) in ('true', 'True', '1')) user = self.request.user core_tasks.terminate_client.delay( client_id=client.id, user_id=user.id, delete_all_resources=delete_all_resources, ) reseller_delete_client.send(sender=__name__, user=user, user_id=user.id, client_name=client.name, client_id=client.id, username=user.username, request=self.request) return Response({'detail': _('Client delete scheduled')}, status=rest_status.HTTP_202_ACCEPTED)
def destroy(self, request, *args, **kwargs): service = self.get_object() if service.client.billing_settings.suspend_instead_of_terminate or reseller_suspend_instead_of_terminate( client=service.client, ): if self.request.query_params.get('delete_associated_resources', 'false') == 'true': tasks.suspend_service.delay( service_id=service.id, reason=ServiceSuspendType.SUSPEND_REASON_TERMINATE_DISABLED, suspend_type=ServiceSuspendType.staff, ) return Response( { 'detail': _('Suspend instead of terminate is enabled for the client. Suspending service.') }, status=status.HTTP_202_ACCEPTED ) else: return Response( {'detail': _('Suspend instead of terminate is enabled for the client, service not deleted.')}, status=status.HTTP_403_FORBIDDEN ) else: if self.request.query_params.get('delete_associated_resources', 'false') == 'true': billing_module = module_factory.get_module_instance(service=service) delete_task = billing_module.prepare_delete_task(service=service, user_id=request.user.id) celery.chain( delete_task, tasks.delete_service_from_database.si(service_id=service.id) ).apply_async() return Response( {'detail': _('Delete in progress.')}, status=status.HTTP_202_ACCEPTED ) else: if service.status in [ ServiceStatus.terminated, ServiceStatus.canceled, ServiceStatus.pending, ServiceStatus.fraud ]: tasks.delete_service_from_database.si(service_id=service.id).apply_async() return Response( {'detail': _('Delete in progress.')}, status=status.HTTP_202_ACCEPTED ) else: return Response( { 'detail': _('Cannot delete service with active resources, terminate service first.') }, status=status.HTTP_403_FORBIDDEN )
def process_cancellation_requests(self): svc_filter = self.client.services.active().non_free() cancellable_services = svc_filter.filter( cancellation_request__cancellation_type=CancellationTypes. END_OF_CYCLE, next_due_date__lte=utcnow()) for s in cancellable_services: if self.billing_settings.suspend_instead_of_terminate or reseller_suspend_instead_of_terminate( client=self.client, ): service_tasks.suspend_service.delay( s.pk, reason=ServiceSuspendType.SUSPEND_REASON_UNSPECIFIED, suspend_type=ServiceSuspendType.staff) else: service_tasks.terminate_service.delay( s.pk, cancellation_request_id=s.cancellation_request.pk) self.summary.update_cancelled_services_count(1)
def terminate(self, request, pk): service = self.get_object() # type: Service if service.status not in [ServiceStatus.active, ServiceStatus.suspended]: return Response( { 'detail': _('Service is not active or suspended') }, status=status.HTTP_403_FORBIDDEN, ) if service.client.billing_settings.suspend_instead_of_terminate or reseller_suspend_instead_of_terminate( client=service.client, ): if service.status == ServiceStatus.active: tasks.suspend_service.delay( service_id=service.id, reason=ServiceSuspendType.SUSPEND_REASON_TERMINATE_DISABLED, suspend_type=ServiceSuspendType.staff, ) return Response( { 'detail': _('Suspend instead of terminate is enabled for the client. Suspending service.') }, status=status.HTTP_202_ACCEPTED, ) else: return Response( { 'detail': _( 'Suspend instead of terminate is enabled for the client and service is not active.' ) }, status=status.HTTP_202_ACCEPTED, ) else: tasks.terminate_service.delay(pk, user_id=request.user.pk) return Response( { 'detail': _('Terminate in progress') }, status=status.HTTP_202_ACCEPTED, )
def terminate_client(self, client_id: int, user_id: Optional[int] = None, delete_all_resources: Optional[bool] = False): del self # unused client = Client.objects.get(id=client_id) # type: Client if client.billing_settings.suspend_instead_of_terminate or reseller_suspend_instead_of_terminate( client=client): raise Exception( 'Terminate client called when suspend instead of terminate is true' ) # delete all services for client delete_services_tasks = [] for service in client.services.all(): billing_module = module_factory.get_module_instance(service=service) if delete_all_resources: delete_services_tasks.append( celery.chain( billing_module.prepare_delete_task(service=service, user_id=user_id), service_tasks.delete_service_from_database.si( service_id=service.id))) else: delete_services_tasks.append( service_tasks.delete_service_from_database.si( service_id=service.id)) if len(delete_services_tasks): final_chord = celery.group( delete_services_tasks) | delete_client_from_database.si( client_id=client_id) celery.chain(final_chord).apply_async() else: delete_client_from_database.delay(client_id=client_id)
def process_client_suspended_services(self): # will set auto terminate date and terminate suspended services that exceeded that date if not (self.billing_settings.suspend_instead_of_terminate or reseller_suspend_instead_of_terminate(client=self.client, )): LOG.info('Processing client suspended services') terminate_service_tasks = list() suspended_services = Service.objects.filter( client=self.client, status=ServiceStatus.suspended) now = utcnow() termination_date = now + timedelta( hours=self.billing_settings.auto_terminate_delay_hours) for service in suspended_services: if not service.auto_terminate_date: service.auto_terminate_date = termination_date service.save() else: if service.auto_terminate_date < now: terminate_service_tasks.append( service_tasks.terminate_service.s(service.id)) if self.billing_settings.auto_terminate_notification_template: variables = { 'terminated_service_id': service.id, 'terminated_service_display_name': service.display_name, } notifier.critical( client=self.client, name=self.billing_settings. auto_terminate_notification_template, variables=variables) if len(terminate_service_tasks): self.summary.update_auto_terminated_services_count( count=len(terminate_service_tasks)) celery.group(terminate_service_tasks).apply_async()
def terminate_service(self, service_id, cancellation_request_id=None, **kwargs): del self, kwargs # unused service = Service.objects.get(pk=service_id) service_module = module_factory.get_module_instance(service=service) if service.client.billing_settings.suspend_instead_of_terminate or reseller_suspend_instead_of_terminate( client=service.client, ): LOG.info('Suspend instead of terminate is active, will suspend the service {}'.format(service_id)) result = service_module.suspend( service=service, reason=ServiceSuspendType.SUSPEND_REASON_TERMINATE_DISABLED, suspend_type=ServiceSuspendType.staff ) if result: service.set_suspended( reason=ServiceSuspendType.SUSPEND_REASON_TERMINATE_DISABLED, suspend_type=ServiceSuspendType.staff ) else: LOG.info('Service will be terminated: {}'.format(service_id)) service_module.prepare_delete_task(service=service).apply() service.set_terminated(cancellation_request_id=cancellation_request_id) return service.id
def get_suspend_instead_of_terminate(client: Client): return client.billing_settings.suspend_instead_of_terminate or reseller_suspend_instead_of_terminate( client=client, )