- nutzbare Hostbereiche aus der CIDR-Maske erzeugen - Netzwerk- und Broadcastadressen bei IPv4 ausschließen - Abgleich-Aktion in die IP-Bereichsliste verschieben - Gerät oder VM in der IP-Adressansicht anzeigen - Bestandsabgleich für IP-Bereiche ergänzen - Plugin-Version auf 1.2.0 erhöhen
68 lines
2.2 KiB
Python
68 lines
2.2 KiB
Python
import ipaddress
|
|
import logging
|
|
|
|
from django.db import transaction
|
|
from ipam.models import IPRange
|
|
from netbox.plugins import get_plugin_config
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def network_for_address(address):
|
|
"""Return the canonical network encoded by an IPAddress.address value."""
|
|
return ipaddress.ip_interface(str(address)).network
|
|
|
|
|
|
def _tenant_from_ip(ip):
|
|
tenant = getattr(ip, "tenant", None)
|
|
if tenant is not None:
|
|
return tenant
|
|
assigned = getattr(ip, "assigned_object", None)
|
|
parent = (
|
|
getattr(assigned, "parent_object", None)
|
|
or getattr(assigned, "device", None)
|
|
or getattr(assigned, "virtual_machine", None)
|
|
or assigned
|
|
)
|
|
return getattr(parent, "tenant", None)
|
|
|
|
|
|
@transaction.atomic
|
|
def ensure_range_for_ip(ip, *, config=None):
|
|
"""Get or create the usable-host IPRange represented by an IP and its mask."""
|
|
settings = config or {
|
|
key: get_plugin_config("netbox_better_ips", key)
|
|
for key in ("range_status", "inherit_tenant", "ignore_host_prefixes")
|
|
}
|
|
network = network_for_address(ip.address)
|
|
if settings.get("ignore_host_prefixes", True) and network.prefixlen == network.max_prefixlen:
|
|
return None, False
|
|
|
|
first = int(network.network_address)
|
|
last = int(network.broadcast_address)
|
|
if network.version == 4 and network.prefixlen < 31:
|
|
first += 1
|
|
last -= 1
|
|
elif network.version == 6 and network.prefixlen < 127:
|
|
first += 1
|
|
|
|
start_address = f"{ipaddress.ip_address(first)}/{network.prefixlen}"
|
|
end_address = f"{ipaddress.ip_address(last)}/{network.prefixlen}"
|
|
lookup = {
|
|
"start_address": start_address,
|
|
"end_address": end_address,
|
|
"vrf_id": ip.vrf_id,
|
|
}
|
|
existing = IPRange.objects.filter(**lookup).first()
|
|
if existing:
|
|
return existing, False
|
|
|
|
defaults = {"status": settings.get("range_status", "active")}
|
|
if settings.get("inherit_tenant", True):
|
|
defaults["tenant"] = _tenant_from_ip(ip)
|
|
|
|
ip_range, created = IPRange.objects.get_or_create(defaults=defaults, **lookup)
|
|
if created:
|
|
logger.info("Created missing IP range %s for IP address %s", ip_range, ip)
|
|
return ip_range, created
|