Tóm tắt: NetBox có REST API tại /api/ (ví dụ /api/dcim/devices/), xác thực bằng API token trong header Authorization. pynetbox bọc API thành object: nb.dcim.devices.get(...), .filter(...), .create(...), sửa thuộc tính rồi .save(). Tham số filter chính là query string của REST API, nên thử bằng curl hoặc trang /api/ trên trình duyệt trước. Dùng NetBox làm inventory cho Ansible: Ansible inventory từ NetBox.
Luồng hoạt động
flowchart LR A["Script / pynetbox"] -->|"Authorization: Token ..."| B["NetBox /api/"] B --> C["dcim: devices, interfaces"] B --> D["ipam: ip-addresses, prefixes"] C --> E["Record object"] D --> E E -->|"sửa + save()"| B
Cấu hình
Token
Tạo token trong UI: User → API Tokens → Add (bỏ tick Write enabled nếu script chỉ đọc). Lưu vào biến môi trường, không ghi vào code.
export NETBOX_URL=https://netbox.example.com
export NETBOX_TOKEN='***'NetBox 4.5 bổ sung token v2 (dạng nbt_..., gửi bằng Authorization: Bearer <token>); token kiểu cũ vẫn dùng Authorization: Token <token>. Kiểm tra loại token trên giao diện, và dùng pynetbox bản mới nếu dùng token v2.
REST API bằng curl
H=(-H "Authorization: Token $NETBOX_TOKEN" -H "Accept: application/json")
# Device theo tên
curl -s "${H[@]}" "$NETBOX_URL/api/dcim/devices/?name=pe1-hni" | jq '.results[0] | {id, name, primary_ip4}'
# Interface của device, chỉ lấy tên + description
curl -s "${H[@]}" "$NETBOX_URL/api/dcim/interfaces/?device=pe1-hni&limit=1000" \
| jq -r '.results[] | [.name, .description] | @tsv'
# Đổi description (PATCH theo id)
curl -s -X PATCH "${H[@]}" -H "Content-Type: application/json" \
"$NETBOX_URL/api/dcim/interfaces/123/" -d '{"description": "to-pe2-hcm"}'| Endpoint | Nội dung |
|---|---|
/api/dcim/devices/ |
Device (filter: name, site, role, platform, status, tag) |
/api/dcim/interfaces/ |
Interface (filter: device, device_id, name, type) |
/api/ipam/ip-addresses/ |
IP (filter: address, device, interface_id, vrf) |
/api/ipam/prefixes/ |
Prefix; /api/ipam/prefixes/<id>/available-ips/ để cấp IP trống |
/api/dcim/sites/, /api/dcim/platforms/ |
Site, platform |
/api/status/ |
Phiên bản NetBox, kiểm tra token |
Danh sách trả về có count, next, results; mặc định phân trang (limit, offset). Nhiều giá trị cùng filter là OR: ?site=hni&site=hcm.
pynetbox: đọc
import os
import pynetbox
nb = pynetbox.api(os.environ["NETBOX_URL"], token=os.environ["NETBOX_TOKEN"])
# nb.http_session.verify = "/etc/ssl/certs/internal-ca.pem" # CA nội bộ
dev = nb.dcim.devices.get(name="pe1-hni") # 1 object hoặc None; nhiều kết quả → lỗi
print(dev.id, dev.platform, dev.primary_ip4)
for d in nb.dcim.devices.filter(site="hni", status="active"):
print(d.name, d.primary_ip4.address if d.primary_ip4 else "-")
for i in nb.dcim.interfaces.filter(device="pe1-hni"):
print(i.name, i.description, i.enabled)
for ip in nb.ipam.ip_addresses.filter(device="pe1-hni"):
print(ip.address, ip.assigned_object)
print(nb.dcim.devices.count(site="hni")).filter() tự đi hết các trang. Thuộc tính liên kết (dev.site, dev.platform) là object con, in ra thấy tên, truy cập .slug/.id khi cần so sánh.
pynetbox: ghi
intf = nb.dcim.interfaces.get(device="pe1-hni", name="GigabitEthernet0/0/0/1")
intf.description = "to-pe2-hcm"
intf.save() # PATCH các field đã đổi, trả True/False
dev = nb.dcim.devices.get(name="pe1-hni")
dev.update({"comments": "CHG-1234"}) # cập nhật nhiều field một lần
ip = nb.ipam.ip_addresses.create(
address="192.0.2.0/31",
status="active",
assigned_object_type="dcim.interface",
assigned_object_id=intf.id,
description="p2p pe1-pe2",
)
# Cấp IP trống tiếp theo trong prefix
pfx = nb.ipam.prefixes.get(prefix="198.51.100.0/24")
new_ip = pfx.available_ips.create({"description": "loopback mới"})Khi đồng bộ dữ liệu từ thiết bị lên NetBox, so sánh trước rồi mới save() để changelog NetBox không đầy bản ghi vô nghĩa. Chạy thử trên NetBox lab, hoặc dùng token chỉ đọc để test phần đọc.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
403 Invalid token / Authentication credentials were not provided |
Token sai, hết hạn, sai kiểu header (Token vs Bearer) |
Thử curl $NETBOX_URL/api/status/ với header, kiểm tra token trong UI |
403 You do not have permission khi ghi |
Token không bật Write enabled hoặc user thiếu permission | Bật write cho token, cấp object permission |
ValueError: get() returned more than a single result |
.get() khớp nhiều object |
Thêm filter (site, device) hoặc dùng .filter() |
.get() trả None |
Sai tên/slug, filter theo slug nhưng truyền name | Kiểm tra bằng /api/...?name= trên trình duyệt |
SSLError: certificate verify failed |
NetBox dùng CA nội bộ | nb.http_session.verify = "/path/ca.pem" |
RequestError 400 khi tạo IP |
Thiếu field bắt buộc hoặc assigned_object_type sai |
Đọc thông báo lỗi trong response, xem schema tại /api/schema/swagger-ui/ |
| Filter bị bỏ qua, trả về tất cả | Tên filter không tồn tại (tuỳ phiên bản, NetBox có thể bỏ qua tham số lạ thay vì báo lỗi) | Đối chiếu filter trong API docs của đúng phiên bản |
Tham khảo
- NetBox REST API
- pynetbox documentation
- jq cheatsheet để xử lý JSON trả về