Files

83 lines
3.3 KiB
Python
Raw Permalink Normal View History

2025-08-27 09:55:55 +02:00
import logging
from functools import wraps
from django.db.models import Model
from django_proxmox_mikrotik.configs import MIKROTIK_READONLY, MikrotikConfig, PROXMOX_READONLY, ProxmoxConfig
def readonly(func):
"""Decorator to temporarily enable READONLY for both Proxmox and Mikrotik"""
@wraps(func)
def wrapper(*args, **kwargs):
pm_initial = ProxmoxConfig.READONLY
mk_initial = MikrotikConfig.READONLY
ProxmoxConfig.READONLY = True
MikrotikConfig.READONLY = True
logging.debug(f"READONLY: Setting ProxmoxConfig.READONLY from {pm_initial} to {ProxmoxConfig.READONLY} "
f"and MikrotikConfig.READONLY from {mk_initial} to {MikrotikConfig.READONLY} for {func.__name__}")
try:
return func(*args, **kwargs)
finally:
logging.debug(f"READONLY: Resetting ProxmoxConfig.READONLY from {pm_initial} to {ProxmoxConfig.READONLY} "
f"and MikrotikConfig.READONLY from {mk_initial} to {MikrotikConfig.READONLY} for {func.__name__}")
ProxmoxConfig.READONLY = PROXMOX_READONLY
MikrotikConfig.READONLY = MIKROTIK_READONLY
return wrapper
def force_write(func):
"""Decorator to temporarily disable READONLY for both Proxmox and Mikrotik"""
@wraps(func)
def wrapper(*args, **kwargs):
pm_initial = ProxmoxConfig.READONLY
mk_initial = MikrotikConfig.READONLY
ProxmoxConfig.READONLY = False
MikrotikConfig.READONLY = False
logging.debug(f"FORCE WRITE: Setting ProxmoxConfig.READONLY from {pm_initial} to {ProxmoxConfig.READONLY} "
f"and MikrotikConfig.READONLY from {mk_initial} to {MikrotikConfig.READONLY} for {func.__name__}")
try:
return func(*args, **kwargs)
finally:
logging.debug(f"FORCE WRITE: Resetting ProxmoxConfig.READONLY from {pm_initial} to {ProxmoxConfig.READONLY} "
f"and MikrotikConfig.READONLY from {mk_initial} to {MikrotikConfig.READONLY} for {func.__name__}")
ProxmoxConfig.READONLY = PROXMOX_READONLY
MikrotikConfig.READONLY = MIKROTIK_READONLY
return wrapper
def skip_signal(signaltype='post_save', **kwargs):
"""This should be used as decorator for signal handlers to prevent recursion.
Mostly used for post_save and post_delete.
The signaltype is just for logging."""
def _decorator(signal_handler):
@wraps(signal_handler)
def _wrapper(sender, instance: Model, **kwargs):
if getattr(instance, '_skip_signal', False):
logging.debug(
f'Skip signal handler for {signaltype} : {signal_handler.__name__} - {sender.__name__} - {instance.__class__.__name__}')
return
instance._skip_signal = True
try:
return signal_handler(sender, instance, **kwargs)
finally:
try:
del instance._skip_signal
except AttributeError:
logging.debug(
f'{instance.__class__.__name__} instance has no attribute "_skip_signal" - could not delete it.')
except Exception as e:
logging.exception('WTF????', str(e))
return _wrapper
return _decorator