0

Allocate Next Available IP

by
Published today

Reserve the next free IP address(es) in a prefix and create them, optionally assigned to a device interface. Returns the created IP address(es).

Script netbox Verified

The script

Submitted by hugo989 Python3
Verified 3 hours ago
1
# py312
2
# requirements:
3
# pynetbox==7.9.0
4

5

6
from typing import List, Literal, Optional, TypedDict
7

8
import pynetbox
9

10

11
class netbox(TypedDict):
12
    url: str
13
    token: str
14

15

16
DynSelect_prefix_id = str
17

18

19
def api(auth: netbox):
20
    # pynetbox adds /api itself; the resource URL may already end with it.
21
    return pynetbox.api(
22
        auth["url"].rstrip("/").removesuffix("/api"), token=auth["token"]
23
    )
24

25

26
def keep(**fields):
27
    # The run form sends "" / [] / {} for untouched fields: drop them.
28
    return {k: v for k, v in fields.items() if v not in (None, "", [], {})}
29

30

31
def options(endpoint, key="id", **filters):
32
    return [
33
        {"value": str(getattr(r, key)), "label": r.display}
34
        for r in endpoint.filter(brief=1, limit=1000, offset=0, **filters)
35
    ]
36

37

38
# Dropdown of the instance's prefixes.
39
def prefix_id(auth: netbox):
40
    return options(api(auth).ipam.prefixes)
41

42

43
def main(
44
    auth: netbox,
45
    prefix_id: DynSelect_prefix_id,
46
    count: Optional[int] = None,
47
    status: Optional[
48
        Literal["active", "reserved", "deprecated", "dhcp", "slaac"]
49
    ] = None,
50
    dns_name: Optional[str] = None,
51
    description: Optional[str] = None,
52
    interface_id: Optional[int] = None,
53
    tags: Optional[List[str]] = None,
54
    custom_fields: Optional[dict] = None,
55
):
56
    """
57
    Allocate Next Available IP
58
    Reserve the next free IP address(es) in a prefix and create them, optionally assigned to a device interface. Returns the created IP address(es).
59
    """
60
    prefix = api(auth).ipam.prefixes.get(int(prefix_id))
61
    if prefix is None:
62
        raise ValueError(f"No prefix with id {prefix_id}")
63
    ip = keep(
64
        status=status,
65
        dns_name=dns_name,
66
        description=description,
67
        assigned_object_type="dcim.interface" if interface_id else None,
68
        assigned_object_id=interface_id,
69
        tags=[{"slug": s} for s in tags or []],
70
        custom_fields=custom_fields,
71
    )
72
    # NetBox allocates one IP for an object body, one per item for a list.
73
    n = count or 1
74
    if n == 1:
75
        return dict(prefix.available_ips.create(ip))
76
    return [dict(r) for r in prefix.available_ips.create([ip] * n)]
77