mcpField
N
netbox-api-integration

netbox-api-integration

github.com/netboxlabs云与 DevOps2156 次安装2 周前更新
代码仓库

关于 netbox-api-integration

面向编写 NetBox 集成的开发者,整理 REST 与 GraphQL API 的认证、查询、批量操作和性能实践,并涵盖版本差异与数据建模。

主要功能

  1. 01REST 与 GraphQL 查询实践
  2. 02令牌认证与版本注意事项
  3. 03分页和批量写入模式
  4. 04过滤、并发与性能优化
  5. 05NetBox 对象依赖与建模

适用场景

  1. 01编写 NetBox API 集成代码
  2. 02处理大型数据集的分页查询
  3. 03安全地批量创建或更新对象

MCP 相关

介绍在已配置 NetBox MCP server 或 NetBox Platform MCP 时,如何查询实时实例以核实字段、过滤器和对象状态。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/netboxlabs/skills --skill netbox-api-integration

安装后在 Claude Code 中输入/netbox-api-integration确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
authentication.md
branching-patterns.md
data-modeling.md
diode-integration.md
graphql-patterns.md
performance.md
rest-api-patterns.md

详细介绍

NetBox API 集成

与 NetBox REST 和 GraphQL API 集成的模式和实践。涵盖身份验证、查询、批量操作、性能优化、数据建模和集成工具。

目标版本: NetBox 4.5–4.7(当前版本:4.7.3)。v2 令牌需要 4.5+;REST 游标分页、ETag/If-Match 和 add_tags/remove_tags 需要 4.6+;?background=true、逐对象批量错误以及 {value, label} 选择型自定义字段从 4.7 开始支持。请参阅版本说明。 范围: 仅限 API 集成——不包括插件开发、自定义脚本或 NetBox 管理。

你对 NetBox API 的了解可能已经过时。 分页行为、筛选表达式、令牌格式和 GraphQL 功能会随版本变化。查询具体 API 细节时,优先检索,而非依赖预训练知识。

检索来源

来源URL / 方法用途
NetBox REST API 文档https://netboxlabs.com/docs/netbox/integrations/rest-api/端点、筛选、分页
NetBox GraphQL 文档https://netboxlabs.com/docs/netbox/integrations/graphql-api/查询语法、架构
pynetbox 仓库https://github.com/netbox-community/pynetboxSDK 方法、变更日志
NetBox MCP 服务如已配置——查询实时实例,以验证对象架构和当前状态字段名称、可用筛选条件、对象是否存在
NetBox Platform MCP如已配置——针对实时 NetBox Cloud/Enterprise 进行完整 CRUD 验证端到端验证

首先:验证连接

编写集成代码前,请确认 NetBox 实例可访问,且令牌有效:

curl -s -H "Authorization: Bearer $NETBOX_TOKEN" "$NETBOX_URL/api/status/" | python -m json.tool

你应会看到包含 netbox-version 的 JSON 响应。如果收到 403,说明令牌权限不足。如果连接被拒绝,请检查 URL。


身份验证

NetBox 4.5+ 使用 v2 令牌。v1 令牌自 4.6 起已弃用,并将在 5.0 中移除。

# v2 token (recommended)
headers = {"Authorization": "Bearer nbt_abc123.xxxxxxxxxxxxxxxx"}

# v1 token (legacy — deprecated 4.6, removed 5.0; migrate before 5.0)
headers = {"Authorization": "Token 0123456789abcdef01234567"}

v2 令牌要求在 NetBox 服务端配置中设置 API_TOKEN_PEPPERS。自动创建令牌时,请使用令牌配置端点(POST /api/users/tokens/provision/)。明文值位于创建/配置响应的 token 字段中(key 仅是公开标识符),且只返回一次(4.6.1+)——请立即保存;之后只会存储哈希值。

NetBox 4.7+: 创建时 token 为只读字段——服务端始终生成明文值,并忽略客户端提供的值。切勿使用 ?background=true 创建令牌:4.7.0/4.7.1 会将明文记录在作业结果中(任何拥有 core.view_job 权限的人都能读取);4.7.2 则会以 400 拒绝请求。请运行 ≥ 4.7.2,并轮换以此方式创建的任何令牌。现在,通过 POST /api/extras/scripts/<id>/ 运行自定义脚本,需要使用启用了写入权限的令牌。

令牌迁移、IP 限制和配置详情,请参阅 references/authentication.md。

REST API 基础

始终进行分页
def get_all(api_url, endpoint, headers, limit=100):
    results, url = [], f"{api_url}/{endpoint}/?limit={limit}"
    while url:
        data = requests.get(url, headers=headers).json()
        results.extend(data["results"])
        url = data.get("next")
    return results

NetBox 4.6+——游标分页。 对于大型数据集,请传入 ?start=<pk>&limit=<n>,而不是 offset。此方式会返回 id >= start 的对象,并按 PK 排序。迭代时,将下一次请求的 start 设为最后一个结果的 id + 1;持续跟进 next,直到其为 null。注意事项:同时使用 start 和 offset → 400;游标模式下 count 始终为 null;previous 始终为 null(仅支持向前翻页)。如需获取总数 count 或向后翻页,请使用偏移分页。

使用 PATCH,而非 PUT

PATCH 只更新指定字段。PUT 会替换整个对象——未提供的字段可能会被清空。

并发控制与标签(NetBox 4.6+)
  • 乐观并发控制(ETag / If-Match)。 详情视图响应(针对单个对象的 GET/POST/PATCH/PUT)会返回一个弱 ETag 标头。后续发送 PATCH/PUT 时,通过 If-Match: <etag> 将其传回;如果对象期间发生了变化,服务端会以 412 Precondition Failed 拒绝请求,并返回当前 ETag。If-Match: * 仅断言对象存在。省略该标头会继续采用后写入者胜出的行为。在多写入方集成中使用它,可防止更新丢失。
  • 部分编辑标签(add_tags / remove_tags)。 只写字段,用于添加或移除指定标签,而不替换整个 tags 集合;多个客户端各自拥有一部分标签时,可安全并发操作。限制:不能在同一请求中与 tags 一起使用;remove_tags 仅可用于更新(不能用于创建);同一标签不能同时出现在两个列表中。
批量操作使用列表端点

没有单独的批量端点。向列表端点 POST/PATCH/DELETE 一个 JSON 数组。所有批量操作都是原子性的(全部成功或全部失败)。

# Bulk create
requests.post(f"{API_URL}/dcim/devices/", headers=headers, json=[device1, device2])

# Bulk update (each object must include "id")
requests.patch(f"{API_URL}/dcim/devices/", headers=headers, json=[{"id": 1, "status": "active"}])

# Bulk delete
requests.delete(f"{API_URL}/dcim/devices/", headers=headers, json=[{"id": 1}, {"id": 2}])

NetBox 4.7+:批量写入失败时,会返回 {"detail": "...", "errors": [...]},其中每个失败对象对应一个条目——创建操作为 {"index": N, "errors": {...}},更新/删除操作为 {"id": N, "errors": {...}}——因此只需修正这些对象并重新提交(整个批次仍会回滚)。添加 ?background=true 可将大型批量写入作为任务运行:你会收到 202 和 {"job": {"id", "url", "status"}},验证会延后至工作进程执行;你必须轮询 job.url 并检查 data.status_code。请参阅 references/rest-api-patterns.md。

关键性能规则
  1. 在设备/VM 列表中精简 config_context。 在 4.5–4.6 中,每次请求都会针对每个对象渲染它——始终发送 ?omit=config_context(4.5.2+;在该版本中,?exclude=config_context 效果相同),可提速 10–100 倍。在 4.7.0–4.7.2 中,它会预先渲染、缓存并始终加载——?fields=、?brief=True 或 ?omit=config_context 只能缩减负载。在 4.7.3+ 中,这些参数会再次跳过数据库注解和缓存列,因此精简仍有性能收益(低于 4.6,但确实有效)。?exclude= 在所有 4.7.x 版本中都是静默无效操作——请使用 ?omit=config_context,以确保跨版本兼容
  2. 使用 ?brief=True 获取下拉选项和引用列表(响应大小约减少 90%)
  3. 使用 ?fields= 选择特定字段
  4. 避免在大规模场景中使用 ?q= 搜索过滤器——请使用 name__ic= 等特定过滤器
过滤

使用查找表达式进行服务端过滤:

表达式示例说明
__icname__ic=core包含(不区分大小写)
__iswname__isw=sw-以……开头
__gte/__ltevid__gte=100数值范围
__isnullprimary_ip4__isnull=false空值检查
__nstatus__n=offline不等于
cf_ 前缀cf_environment=production自定义字段过滤器

完整的 REST API 参考(包括过滤表达式、字段选择、排序、嵌套序列化器、OPTIONS 发现和错误处理),请参阅 references/rest-api-patterns.md。

GraphQL 基础知识

每个列表查询都必须分页
query {
  device_list(pagination: {limit: 100, offset: 0}) {
    name
    status
    site { name }
  }
}
每个嵌套层级都必须分页
# Nested lists must also have limits
site_list(pagination: {limit: 10}) {
  devices(pagination: {limit: 50}) {
    interfaces(pagination: {limit: 100}) { name }
  }
}
关键规则
  • 使用查询优化器——对生产环境至关重要。在实际案例中,评分从 20,500 降至 17。
  • 只请求需要的字段——不要过度获取数据
  • 将深度控制在 ≤ 3,绝不要超过 5
  • 使用 filters: 参数在服务端筛选
  • 性能方面优先使用 ID 筛选,而非名称筛选(可避免 JOIN)
  • 根据生产数据校准优化器,以获得准确的评分

NetBox 4.5+:使用本地筛选字段(例如,在 interface_list 上使用 site),而不是深层嵌套的筛选路径。

NetBox 4.5.2+:基于游标的分页已正式发布。传入 pagination: {start: N, limit: M}——返回 id >= start 的记录,并按 PK 排序。将下一页的 start 设为上一页最后一条记录的 id + 1。(省略 start 时会回退到偏移量分页。)这取代了旧的 filters: {id__gte: N} 深度分页变通方案;该方案仅在 4.5.2 之前的版本中需要。

NetBox 4.7+:custom_fields 中的单选/多选值会解析为 {value, label} 对象(与 REST 相同)。服务筛选器为扁平的列表值(port_mappings、protocol、port、port__gt/gte/lt/lte),且 ServiceProtocolEnum 成员为 TCP/UDP/SCTP(没有 ROLE_ 前缀)。请参阅 references/graphql-patterns.md。

GraphQL 分页默认行为(与 REST 不同):

  • 完全省略 pagination 会返回所有匹配记录。
  • pagination 未指定 limit 时,会采用 Strawberry Django 的默认值 100(而非 REST 的默认值 50)。
  • pagination: {limit: 0} 会返回 0 条记录——这与 REST 的 ?limit=0(返回所有记录)正好相反。
  • MAX_PAGE_SIZE(默认值为 1000)会限制 limit 的上限。NetBox 4.6.1+ 还会在服务端强制执行 GRAPHQL_MAX_QUERY_DEPTH,因此过深的查询可能会被直接拒绝,而不只是运行缓慢。
GraphQL 与 REST 的选择
使用场景使用方式
单个对象的 CRUDREST
批量创建/更新/删除REST(GraphQL 仅支持读取)
在一次请求中获取相关数据GraphQL
CI/CD 脚本REST
灵活的报告GraphQL

有关 GraphQL 的完整参考(包括分页策略、深度管理、避免扇出、复杂度预算和查询优化器),请参阅 references/graphql-patterns.md。

性能

影响最大的优化:

优化影响
从列表中移除 config_context(?omit=config_context,4.5.2+;?exclude= 仅适用于 4.5–4.6,在所有 4.7.x 版本中均会被忽略)在 4.5–4.6 上快 10–100 倍;在 4.7.0–4.7.2 上仅减少响应负载(数据已缓存);在 4.7.3+ 上还会跳过再次执行数据库注解
列表使用 ?brief=True响应体缩小约 90%
避免在大规模场景下使用 ?q=速度提升数个数量级
并行执行互不依赖的请求线性提速
使用具体筛选器,而非通用搜索使用针对索引优化的查询

有关异步分页、缓存策略、并行请求模式和基础设施注意事项,请参阅 references/performance.md。

数据建模

依赖顺序

对象必须按以下顺序创建:组织 → 站点 → DCIM 前置条件 → 机架 → 设备 → IPAM → 虚拟化 → 电路 → 连接。

设备所需的 device_type、role 和 site 必须先存在。使用 Diode 可跳过手动排序。

关键层级
  • 站点:区域 → 站点组 → 站点 → 位置(递归)→ 机架 → 设备
  • IPAM:RIR → 聚合地址段 → 前缀(分层)→ IP 地址;VRF 用于划分前缀/IP 的作用域
自然键、自定义字段、标签、租户
  • 按 name/slug 查询,而非数字 ID,让代码更易读
  • 自定义字段使用 cf_ 前缀进行筛选。(4.7) 选择/多选值读取为 {"value": "prod", "label": "Production"}——比较 cf["x"]["value"],写入时使用原始值(回传该对象会导致验证失败)
  • 标签可用于跨对象类型分类
  • 租户提供逻辑资源隔离

完整的依赖顺序、层级关系图,以及自定义字段、标签和租户隔离模式,请参阅 references/data-modeling.md。

集成工具

pynetbox(Python 客户端)

当前版本:7.9.0(2026-10-08;首个声明支持 NetBox 4.7 的版本;要求 Python 3.12+)。在 4.7 上使用 ≥ 7.9.0:该版本会展平 {value, label} 选择型自定义字段,并且更新时只发送已更改的自定义字段,因此保存包含多选自定义字段的对象可以成功(7.8.0 可能会失败)。7.9.0 还支持在 create、save()、update() 和 delete()(包括批量操作)中传入 changelog_message=,并将更多列表字段(object_types、permissions、groups、路由目标、配置上下文范围)作为集合进行比较,因此重新排序不再触发 PATCH。

import pynetbox
nb = pynetbox.api("https://netbox.example.com", token="nbt_abc123.xxxxxxxxxxxxxxxx",
                  pagination="cursor")  # 7.8+: keyset paging on NetBox 4.6+; falls back to offset on older servers

devices = nb.dcim.devices.filter(site="nyc-dc1", status="active")  # Auto-paginated
device = nb.dcim.devices.get(name="switch-01")
device.status = "planned"
device.save()  # Uses PATCH
  • pagination="cursor" 为顺序执行(会忽略 threading=True),不能与 ordering 组合使用,并且 len(record_set) 会额外产生一次计数请求。
  • 来自 pynetbox.extensions(7.8+)的 extensions=[BranchingExtension] / [CustomObjectsExtension] 可添加类型化记录和插件操作——参阅 Branching。
  • 在 NetBox 4.7 上,选择字段的 record.custom_fields["x"] 是一个 {"value", "label"} 字典。
Diode(数据摄取)

对于批量摄取,请使用 Diode,而不是直接使用 API。按名称指定依赖项——Diode 会自动解析或创建它们。无需安排依赖顺序。

from netboxlabs.diode.sdk import DiodeClient
from netboxlabs.diode.sdk.ingester import Device, Entity

with DiodeClient(target="grpc://diode.example.com:8080/diode",
                 app_name="discovery", app_version="1.0.0") as client:
    device = Device(name="switch-01", device_type="Catalyst 9300",
                    manufacturer="Cisco", site="NYC-DC1", role="Access Switch")
    client.ingest([Entity(device=device)])

适用 Diode 的场景:网络发现、批量迁移、创建大量相关对象的脚本。 适用 REST/GraphQL 的场景:读取数据、单个对象 CRUD、复杂查询。

批量摄取、嵌套对象、试运行模式、身份验证和受支持的实体类型,请参阅 references/diode-integration.md。

Webhook

配置 NetBox 通过 webhook 推送更改。务必验证 X-Hook-Signature 标头(HMAC-SHA512)。事件包括 created、updated、deleted,并附带完整对象数据和更改前/后的快照。

更改跟踪

查询 extras.object_changes 获取审计记录——其中包括时间戳、操作、用户以及更改前/后的数据。

分支(插件)

需要 netbox-branching 插件——NetBox 4.7 使用 v1.2.x,NetBox 4.4–4.6 使用 v1.1.x。插件设置和工作流: netbox-branching。

生命周期:创建 → 等待(PROVISIONING→READY)→ 工作 → 同步 → 合并

  • 上下文标头:X-NetBox-Branch: {schema_id}——使用 8 个字符的 schema_id,而非名称或数字 ID
  • 异步操作:同步/合并/还原会返回 Job 对象——轮询 job["url"],直到 status == "completed"
  • 试运行:所有异步操作都接受 {"commit": false} 进行验证
  • pynetbox 7.8+:pynetbox.api(..., extensions=[BranchingExtension]) 提供 branch.sync()/merge()/revert()(返回 Job 记录;存在冲突时会在确认前于 exc.error 中返回 409),并且 with nb.activate_branch(branch): 会自动为你设置标头

完整的分支生命周期、上下文标头用法、异步作业轮询和会话封装模式,请参阅 references/branching-patterns.md。

版本说明

NetBox 4.7.3(2026-10-13)
  • 在设备/VM 列表或详情读取中使用 ?omit=config_context、不带 ?fields=,或使用 ?brief=True,会再次跳过 config-context 数据库注释和缓存列(#23288;?exclude= 仍然不起作用);现在 ?background=true 批量写入会将请求标头和查询字符串一并传给工作进程,因此 X-NetBox-Branch 会生效(#23247——在 4.7.0–4.7.2 中该标头会被丢弃,写入会落到 main)。请运行 ≥ 4.7.3:4.7.0/4.7.1 会将令牌明文泄露到作业结果中;4.7.3 增加了与分支兼容的后台写入和跳过 config-context 的优化。
NetBox 4.7(2026-09-02;运行 ≥ 4.7.3)
  • 在所有 4.7.x 版本中,?exclude=config_context 都会被静默忽略;设备/VM 上的 config_context 会预先渲染并缓存。在 4.7.0–4.7.2 中,它总会被加载(?fields=、?omit=config_context、?brief=True 只会缩减载荷);在 4.7.3+ 中,这些参数还会跳过数据库操作。
  • 选择/多选自定义字段读取时会返回 {value, label}(REST + GraphQL);写入时使用原始值。
  • 批量写入:?background=true → 202 + 作业(轮询作业;带有 If-Match 时返回 400,没有工作进程时返回 503);批量创建/更新失败时会按对象返回 errors。批量操作仍然是全有或全无。在分支内,4.7.0–4.7.2 会丢弃 X-NetBox-Branch(写入会落到 main)——4.7.3+ 则会传递该标头。
  • 令牌:创建时 token 为只读;/api/users/tokens/ 不接受 ?background=true(4.7.2——更早的 4.7.x 会将明文泄露到作业结果中);通过 REST 执行脚本需要启用写入权限的令牌。
  • 服务:protocol/ports → port_mappings(["tcp/53", "udp/53"]);旧的成对字段已弃用,将在 5.0 移除;protocol__ic 风格和 port__empty 查询已移除。参见 references/data-modeling.md。
  • Interface/VMInterface 的 mac_address 可写入(创建或更新主 MAC);MACAddress.is_primary 为只读。
  • 新增端点:dcim/cooling-sources|cooling-feeds|cooling-intakes|cooling-outflows|cooling-intake-templates|cooling-outflow-templates/、dcim/module-bay-types/。新增字段:end_of_life(DeviceType/ModuleType)、channels/channel_id(Interface)、Job.execution_time、Webhook.timeout、CustomField.status/nulls_first。
  • 升级前提(PostgreSQL 15+、ltree、Redis 6+)以及耗时较长的 MPTT→ltree 迁移详见 netbox-administration。
NetBox 4.6
  • REST 游标分页(?start=)、ETag/If-Match、add_tags/remove_tags;v1 令牌已弃用(5.0 移除);明文令牌仅返回一次(4.6.1+);服务器端强制执行 GRAPHQL_MAX_QUERY_DEPTH(4.6.1+);VM 的 cluster 可选。

外部参考

评论

支持 Markdown