Просмотр исходного кода

Closes #8171: Populate next available address when cloning an IP

jeremystretch 3 лет назад
Родитель
Сommit
277c2ff869
2 измененных файлов с 29 добавлено и 0 удалено
  1. 1 0
      docs/release-notes/version-3.3.md
  2. 28 0
      netbox/ipam/models/ip.py

+ 1 - 0
docs/release-notes/version-3.3.md

@@ -25,6 +25,7 @@
 * [#5303](https://github.com/netbox-community/netbox/issues/5303) - A virtual machine may be assigned to a site and/or cluster
 * [#7120](https://github.com/netbox-community/netbox/issues/7120) - Add `termination_date` field to Circuit
 * [#7744](https://github.com/netbox-community/netbox/issues/7744) - Add `status` field to Location
+* [#8171](https://github.com/netbox-community/netbox/issues/8171) - Populate next available address when cloning an IP
 * [#8222](https://github.com/netbox-community/netbox/issues/8222) - Enable the assignment of a VM to a specific host device within a cluster
 * [#8471](https://github.com/netbox-community/netbox/issues/8471) - Add `status` field to Cluster
 * [#8495](https://github.com/netbox-community/netbox/issues/8495) - Enable custom field grouping

+ 28 - 0
netbox/ipam/models/ip.py

@@ -857,6 +857,25 @@ class IPAddress(NetBoxModel):
             address__net_host=str(self.address.ip)
         ).exclude(pk=self.pk)
 
+    def get_next_available_ip(self):
+        """
+        Return the next available IP address within this IP's network (if any)
+        """
+        if self.address and self.address.broadcast:
+            start_ip = self.address.ip + 1
+            end_ip = self.address.broadcast - 1
+            if start_ip <= end_ip:
+                available_ips = netaddr.IPSet(netaddr.IPRange(start_ip, end_ip))
+                available_ips -= netaddr.IPSet([
+                    address.ip for address in IPAddress.objects.filter(
+                        vrf=self.vrf,
+                        address__gt=self.address,
+                        address__net_contained_or_equal=self.address.cidr
+                    ).values_list('address', flat=True)
+                ])
+                if available_ips:
+                    return next(iter(available_ips))
+
     def clean(self):
         super().clean()
 
@@ -907,6 +926,15 @@ class IPAddress(NetBoxModel):
 
         super().save(*args, **kwargs)
 
+    def clone(self):
+        attrs = super().clone()
+
+        # Populate the address field with the next available IP (if any)
+        if next_available_ip := self.get_next_available_ip():
+            attrs['address'] = next_available_ip
+
+        return attrs
+
     def to_objectchange(self, action):
         objectchange = super().to_objectchange(action)
         objectchange.related_object = self.assigned_object