1
- from django .db .models .signals import post_delete
1
+ from dcim .models import Device
2
+ from django .core .exceptions import ValidationError
3
+ from django .db .models .signals import post_delete , pre_save
2
4
from django .dispatch import receiver
5
+ from ipam .models import IPAddress
3
6
7
+ from netbox_cmdb import protect
4
8
from netbox_cmdb .models .bgp import BGPSession
5
9
6
10
@@ -13,3 +17,60 @@ def clean_device_bgp_sessions(sender, instance, **kwargs):
13
17
if instance .peer_b :
14
18
b = instance .peer_b
15
19
b .delete ()
20
+
21
+
22
+ @receiver (pre_save , sender = Device )
23
+ def protect_from_device_name_change (sender , instance , ** kwargs ):
24
+ """Prevents any name changes for dcim.Device if there is a CMDB object linked to it.
25
+
26
+ Some models in the CMDB depends on NetBox Device native model.
27
+ If one changes the Device name, it might affect the CMDB as a side effect, and could cause
28
+ unwanted configuration changes.
29
+ """
30
+
31
+ if not instance .pk :
32
+ return
33
+
34
+ current = Device .objects .get (pk = instance .pk )
35
+
36
+ if current .name == instance .name :
37
+ return
38
+
39
+ for model , fields in protect .MODELS_LINKED_TO_DEVICE .items ():
40
+ if not fields :
41
+ continue
42
+
43
+ for field in fields :
44
+ filter = {field : instance }
45
+ if model .objects .filter (** filter ).exists ():
46
+ raise ValidationError (
47
+ f"Device name cannot be changed because it is linked to: { model } ."
48
+ )
49
+
50
+
51
+ @receiver (pre_save , sender = IPAddress )
52
+ def protect_from_ip_address_change (sender , instance , ** kwargs ):
53
+ """Prevents any name changes for ipam.IPAddress if there is a CMDB object linked to it.
54
+
55
+ Some models in the CMDB depends on NetBox IPAddress native model.
56
+ If one changes the address, it might affect the CMDB as a side effect, and could cause
57
+ unwanted configuration changes.
58
+ """
59
+ if not instance .pk :
60
+ return
61
+
62
+ current = IPAddress .objects .get (pk = instance .pk )
63
+
64
+ if current .address .ip == instance .address .ip :
65
+ return
66
+
67
+ for model , fields in protect .MODELS_LINKED_TO_IP_ADDRESS .items ():
68
+ if not fields :
69
+ continue
70
+
71
+ for field in fields :
72
+ filter = {field : instance }
73
+ if model .objects .filter (** filter ).exists ():
74
+ raise ValidationError (
75
+ f"IP address cannot be changed because it is linked to: { model } ."
76
+ )
0 commit comments