Skip to content

Commit 8157f0d

Browse files
committed
add script to patch ipranges with mark_populate=true
1 parent def9984 commit 8157f0d

File tree

2 files changed

+111
-1
lines changed

2 files changed

+111
-1
lines changed

internal/controller/iprangeclaim_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func (r *IpRangeClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request
138138
}
139139

140140
err = r.EventStatusRecorder.Report(ctx, o, netboxv1.ConditionIpRangeAssignedTrue, corev1.EventTypeNormal,
141-
nil, fmt.Sprintf(" , assigned ip range: %s-%s", ipRangeModel.StartAddress, ipRangeModel.EndAddress))
141+
nil, fmt.Sprintf(" assigned ip range: %s-%s", ipRangeModel.StartAddress, ipRangeModel.EndAddress))
142142
if err != nil {
143143
return ctrl.Result{}, err
144144
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# When updating to NetBox Version v4.3 or newer this script
2+
# can be used to patch the mark-populated field of the IP ranges in Netbox
3+
# which contain '// managed by netbox-operator' in the description
4+
# (v4.2 NetBox verisions are not compatible with the IP range claim controller)
5+
6+
import argparse
7+
import os
8+
import pynetbox
9+
import requests
10+
from pprint import pprint
11+
12+
NETBOX_API = os.getenv("NETBOX_API", "http://netbox")
13+
TOKEN = os.getenv("NETBOX_TOKEN", "0123456789abcdef0123456789abcdef01234567")
14+
CA_CERT = os.getenv("CA_CERT")
15+
MANAGED_MARKER = "// managed by netbox-operator"
16+
17+
18+
def main():
19+
parser = argparse.ArgumentParser(
20+
description="List IP ranges managed by netbox-operator and optionally mark them as populated."
21+
)
22+
parser.add_argument(
23+
"--mark-populated",
24+
action="store_true",
25+
help="If set, patch the 'mark_populated' custom field of matching IP ranges to true.",
26+
)
27+
parser.add_argument(
28+
"--limit",
29+
type=int,
30+
default=None,
31+
help="Maximum number of IP ranges to process (for pagination). If not set, all matches are processed.",
32+
)
33+
parser.add_argument(
34+
"--offset",
35+
type=int,
36+
default=0,
37+
help="Number of matching IP ranges to skip before processing (for pagination). Default: 0.",
38+
)
39+
parser.add_argument(
40+
"--not-populated-only",
41+
action="store_true",
42+
help="If set, only show/patch IP ranges where mark_populated is false.",
43+
)
44+
args = parser.parse_args()
45+
46+
try:
47+
nb = pynetbox.api(
48+
NETBOX_API,
49+
token=TOKEN,
50+
)
51+
52+
# Configure SSL verification if CA cert is provided
53+
if CA_CERT:
54+
session = requests.Session()
55+
session.verify = CA_CERT
56+
nb.http_session = session
57+
print(f"Using CA certificate: {CA_CERT}")
58+
59+
except pynetbox.RequestError as e:
60+
pprint(e.error)
61+
raise SystemExit(f"Failed to connect to NetBox at {NETBOX_API}")
62+
63+
print(f"Connected to NetBox API at {NETBOX_API}")
64+
65+
api_limit = args.limit or 1000
66+
ip_ranges = nb.ipam.ip_ranges.filter(limit=api_limit, offset=args.offset)
67+
68+
managed_ranges = []
69+
for ip_range in ip_ranges:
70+
description = ip_range.description or ""
71+
if MANAGED_MARKER not in description:
72+
continue
73+
74+
if args.not_populated_only:
75+
if getattr(ip_range, "mark_populated", False):
76+
continue
77+
78+
prefix_part = description.split("//")[0].strip()
79+
managed_ranges.append((ip_range, prefix_part))
80+
81+
if not managed_ranges:
82+
print("No matching IP ranges found.")
83+
return
84+
85+
total = len(managed_ranges)
86+
87+
if total == 1000:
88+
print("Warning - pagination limit reached, use the offset flag to query more IP ranges")
89+
90+
print(f"Showing {len(managed_ranges)} of {total} matching IP range(s) (offset={args.offset}, limit={args.limit or '1000'}):\n")
91+
92+
for ip_range, prefix_part in managed_ranges:
93+
print(f"[id={ip_range.id}] {ip_range.start_address} - {ip_range.end_address}: {prefix_part} (mark_populated={ip_range.mark_populated})")
94+
95+
if args.mark_populated:
96+
print(f"\nMarking {len(managed_ranges)} IP range(s) as populated...")
97+
for ip_range, _ in managed_ranges:
98+
try:
99+
ip_range.mark_populated = True
100+
ip_range.save()
101+
print(f" ✓ Patched IP range {ip_range.id}")
102+
except pynetbox.RequestError as e:
103+
pprint(e.error)
104+
print(f" ✗ Failed to patch IP range {ip_range.id}")
105+
106+
print("Done.")
107+
108+
109+
if __name__ == "__main__":
110+
main()

0 commit comments

Comments
 (0)