关于 netbox-asset-lifecycle
netbox-asset-lifecycle 是一项技能,介绍如何通过 REST 和 GraphQL API 使用 NetBox Asset Lifecycle 的采购与备件工作流。它强调核对实时 API 和版本,因为功能与端点可能变化。
主要功能
- 01采购生命周期 API 指南
- 02BOM 生成与范围规则
- 03货运与备件安装工作流
- 04实时架构与版本核验
- 05REST 和 GraphQL 端点参考
适用场景
- 01在 NetBox 中构建采购工作流
- 02从货运安装计划中的设备
- 03分配并安装备件库存
MCP 相关
该技能说明,如已配置 NetBox MCP 或 Platform MCP,可用于检查 asset-lifecycle 端点并核验实时架构。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ netboxlabs/ skills --skill netbox-asset-lifecycle安装后在 Claude Code 中输入/netbox-asset-lifecycle确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/data-model.mdstatus-transitions.mdworkflow-greenfield.mdworkflow-sparing.md详细介绍
NetBox Asset Lifecycle
NetBox Asset Lifecycle 是商业版 NetBox Labs 功能(NetBox Cloud / NetBox Enterprise),用于跟踪设备的采购生命周期——规划 → 物料清单 → 采购订单 → 发货 → 安装——并管理用于替换的备品库存。它基于你已在 NetBox DCIM 中建模的设备构建:规划中的机架、设备、模块和线缆汇总为物料清单,然后经过订购、发货、收货和安装,并可追溯每个已安装对象所对应的货件或备品来源。
你对 Asset Lifecycle 的了解可能已经过时。 这是一个早期(0.x)功能——v0.3.0 是一次破坏性版本更新,重命名了模型和 REST 端点;所有 0.2.x 及更早版本仅供评估。端点、字段和状态规则仍可能变化。请优先检索,而不是依赖预训练知识;生成代码前请验证实时 API。
版本说明: 此技能适用于插件 v0.3.x(v0.3.1,2026-08-20),运行于 NetBox 4.5.4–4.7。无法从 0.2.x 升级——迁移在 0.3.0 中重新初始化。有关 0.2→0.3 的重命名,请参阅版本说明。
检索来源
| 来源 | URL / 方法 | 用途 |
|---|---|---|
| Asset Lifecycle 文档 | https://netboxlabs.com/docs/asset-lifecycle/ | 功能、各模型字段参考、工作流、版本发布 |
| 版本说明 | .../asset-lifecycle/releases/ | 破坏性变更、最低 NetBox 版本 |
| NetBox DCIM 模型 | https://netboxlabs.com/docs/netbox/models/dcim/ | 核心 Device/Rack/Module/Cable 及类型模型 |
| 实时 API 架构 | GET /api/schema/(筛选 asset-lifecycle) | 正在运行的版本中的准确字段名和操作端点 |
| NetBox MCP / Platform MCP | 如已配置——列出/检查 asset-lifecycle 端点 | 验证实时端点和字段架构 |
首先:确认功能可用
确认实例已启用此功能、你的令牌有访问权限,并且使用的是 0.3 API:
curl -s -H "Authorization: Bearer $NETBOX_TOKEN" \
"$NETBOX_URL/api/plugins/asset-lifecycle/assets/?limit=1" | python -m json.tool
- 返回分页列表(可能为空)→ 功能已启用,v0.3+(存在
assets/)。 assets/返回 404,但boms/返回 200 → 安装的是 0.2.x;此技能前身中的bom-objects/端点和spare_item字段适用,且下文关于分配、归档或连接器字段的内容均不存在。boms/也返回 404 → 功能未启用。403 → 令牌缺少 asset-lifecycle 对象权限。
范围
此技能涵盖 asset-lifecycle REST/GraphQL API 及其采购/备品工作流。不涵盖:
- 站点/设备/IPAM 建模 → 使用 netbox-data-modeling
- 核心 REST/GraphQL 模式、身份验证、分页、批量操作 → 使用 netbox-api-integration
- 库存批量导入 → 使用 netbox-diode
前提条件: 你要采购的设备必须已存在于 NetBox DCIM 中,通常是已分配类型的 status=planned 对象(Device 的 device_type、Rack 的 rack_type、Cable 的 type)。Asset Lifecycle 不会创建规划中的 Device/Rack——它负责跟踪采购和安装。(唯一例外:从备品安装一个新对象。)
API 约定
- 基础 URL:
/api/plugins/asset-lifecycle/ - 身份验证:
Authorization: Bearer nbt_<key>.<secret>(v2 令牌;v1Token <key>在 v5.0 之前仍可使用)。标准 NetBox 分页(?limit=、?offset=)、?brief=true、?fields=、?q=搜索和__过滤查找均适用。 - 对象权限: 每个模型的标准
view_*/add_*/change_*/delete_*权限(例如netbox_asset_lifecycle.change_bom)。操作端点(generate/、install/)还需要令牌启用写入权限;对于安装操作,还需要对目标对象具有匹配的dcim.change_*/dcim.add_*权限。 - 通用关系(行项目 / 备件 / 分配 / 资产所指向的设备)通过两个字段写入:一个
*_typeContentType({"app_label": "dcim", "model": "devicetype"}或一个 pk),以及一个*_id整数。组合字段item/assigned_object只读。 - 嵌套外键可直接接受整数 pk。
variant是 JSON 对象,绝不会为 null (0.3.1)——对于“无变体”,请发送{}或省略该字段。保存时会删除空白属性,因此{"airflow": ""}会存储为{}。- 默认返回已归档对象;使用
?archived=false进行过滤。
快速参考
端点(位于 /api/plugins/asset-lifecycle/ 下) | 用途 |
|---|---|
boms/ · POST boms/<id>/generate/ | BOM 容器;将范围规则解析为资产和行项目 |
bom-scope-rules/ | 定义 BOM 范围的包含 / 排除过滤规则 |
bom-line-items/ | 类型 + 变体 + 数量行(自动生成或手动添加) |
assets/ · POST assets/<id>/install/ | 每个实例的规划对象 ↔ BOM 关联;从货运批次或备件安装 |
cable-types/ | 插件本地的线缆类型(type+profile+connector_a+connector_b) |
vendors/、vendor-accounts/ | 供应商和账户 |
purchase-orders/ · GET purchase-orders/<id>/export-line-items/?format= | 订单;将行项目导出为 json/csv/yaml |
po-line-items/ | 每个 BOM 行的订购数量和价格(仅当采购订单处于 draft 状态时可编辑) |
couriers/、courier-accounts/ | 货运公司(预置 UPS/FedEx/DHL)和账户 |
shipments/、shipment-line-items/ | 货运批次和行项目(qty_shipped / qty_received) |
spares-pools/、spare-items/ · POST spare-items/<id>/install/ | 预留库存;根据备件创建新的 DCIM 对象 |
spare-item-allocations/ | 每个库存池 + 项目 + 变体的最低 / 最高库存阈值 (0.3) |
status-transition-rules/ · GET .../status-choices/?object_type_id= | BOM/采购订单/货运批次的可编辑 FSM,包括初始状态 |
GraphQL:每个模型都可与核心类型一起通过 /graphql/ 查询——bom_list、purchase_order_list、shipment_list、asset_list、spare_item_list、spare_item_allocation_list 等。类型名称带有 AssetLifecycle 前缀 (0.3.1):AssetLifecycleBOM、AssetLifecyclePurchaseOrder、AssetLifecycleShipment、AssetLifecycleAsset、AssetLifecycleSpareItem,……
数据模型
完整对象关系图、每个模型的字段和唯一性约束,请参阅 references/data-model.md。构造请求或排查验证错误时请加载该文件。
Vendor ─ VendorAccount
│
BOM ─ BOMScopeRule / BOMLineItem / Asset (BOM rolls planned DCIM objects up into line items;
│ one Asset per matched planned object)
PurchaseOrder ─ POLineItem (PO requires a BOM + Vendor)
│
Shipment ─ ShipmentLineItem (Shipment requires a PO + Courier + tracking_number)
│
Asset.shipment ◄── install from shipment (records which delivery fulfilled the planned object)
Asset.spares_pool ◄── install from spare (records which pool it was drawn from)
SparesPool ─ SpareItem / SpareItemAllocation (reserve inventory + min/max stock thresholds)
BOM、PurchaseOrder 和 Shipment 均带有受规则约束的 status 和 archived 标志。
状态与转换规则
BOM、PO 或 Shipment 的状态变更只有在存在匹配的 StatusTransitionRule 时才允许;非法跳转会返回 400(Cannot transition from X to Y)。from_status 为空的规则是初始状态规则——它声明对象可以以某个状态创建;使用其他状态创建会返回 400(… is not a valid initial status)。SpareItem.status 不受规则约束,可自由设置。
| 模型 | 状态值 | 默认初始状态 |
|---|---|---|
| BOM | draft、approved、ordered、fulfilled、cancelled | draft |
| PurchaseOrder | draft、approved、ordered、fulfilled、cancelled | draft |
| Shipment | prepared、shipped、received、cancelled、returned、lost | prepared 或 shipped (0.3) |
| SpareItem(自由设置) | serviceable、damaged、missing | 任意 |
默认规则:BOM/PO 可在 draft ↔ approved ↔ ordered ↔ fulfilled 之间转换(另有 approved ↔ fulfilled);只能从 approved/ordered 单向取消。Shipment 可在 prepared ↔ shipped ↔ received 之间转换,也可在 shipped ↔ lost、lost ↔ received、received ↔ returned 之间转换;只能从 prepared/shipped 单向取消。默认情况下,不存在 draft → ordered、draft → fulfilled 或 draft → cancelled 转换。
# Discover valid status strings for an object type
GET status-transition-rules/status-choices/?object_type_id=<contenttype_id>
# Allow an otherwise-illegal jump by adding a rule first
POST status-transition-rules/
{"object_type": {"app_label":"netbox_asset_lifecycle","model":"purchaseorder"},
"from_status": "draft", "to_status": "ordered", "allow_reverse": false}
# Allow shipments to be created directly as "received" (initial-status rule)
POST status-transition-rules/
{"object_type": {"app_label":"netbox_asset_lifecycle","model":"shipment"},
"from_status": "", "to_status": "received"}
完整的默认规则集和特定模型的锁定条件(BOM“非当前”、PO order_id、已接收 Shipment 的站点、已归档)请参阅 references/status-transitions.md。状态变更返回 400 时,请加载该文件。
操作端点(过去仅限 UI 的步骤)
自 0.2.0 起,生成、安装和导出均提供 REST 端点;接收则通过普通字段编辑完成。请使用这些端点,不要手动重现其效果——这些端点会强制执行相关功能所需的数据完整性(汇总正确性、备件扣减、Shipment→对象可追溯性)。
| 操作 | 请求 | 所需权限 | 返回 |
|---|---|---|---|
| 生成 BOM | POST boms/<id>/generate/(空请求体) | change_bom;BOM 为 draft 且至少有 1 条启用的范围规则 | BOM(包含 last_generated、is_current=true);否则返回 400 |
| 从 Shipment 安装 | POST assets/<id>/install/ {"shipment": <id>} | change_asset + dcim.change_<model>;Shipment 为 received 且属于此 BOM 的 PO;Asset 尚未安装 | 设置了 shipment + installed 的 Asset |
| 从备件安装 | POST assets/<id>/install/ {"spare_item": <id>} | 同上;备件为 serviceable、quantity ≥ 1,且 item_type/item_id/variant 完全匹配 | 设置了 spares_pool + installed 的 Asset;备件 quantity 扣减;若并发耗尽则返回 409 |
| 从备件新建对象 | POST spare-items/<id>/install/ {<DCIM object fields>} | change_spareitem + dcim.add_<model>;备件为 serviceable、quantity ≥ 1;仅限设备/机架/模块类型 | 201 + 新建的 DCIM 对象;备件扣减 |
| 导出 PO 行项目 | GET purchase-orders/<id>/export-line-items/?format=json | view_purchaseorder | 文件内容(默认 json;也可用 csv、yaml) |
通过 REST 安装不会修改 DCIM 对象——它只关联 Asset,并在使用备件时扣减库存。之后请使用普通的 PATCH /api/dcim/devices/<id>/ {"status": "staged", "serial": "..."} 更新对象本身;UI 安装表单会在一次提交中完成这两项操作。
接收通过字段编辑完成:先执行 PATCH shipments/<id>/ {"status": "received", "site": <id>, "date_received": "..."}(进入 received 状态时必须提供 site 和/或 location),然后对每个行项目执行 PATCH shipment-line-items/<id>/ {"qty_received": N}——将 qty_received 设为低于 qty_shipped 是记录短缺/损坏的文档化方式。UI 中的 Mark Received 按钮只是对相同写入操作的批量表单。
绿地采购工作流
完整的分步说明、负载和验证备注请参阅 references/workflow-greenfield.md。
- 供应商(+ 可选账户)
POST vendors/ {"name": "Acme Networks", "code": "ACME"} POST vendor-accounts/ {"vendor": <vendor_id>, "account_number": "ACC-001"} - BOM + 范围规则 → 生成 → 审批。 编写范围规则,而非行项目;BOM 离开
draft后,范围规则和行项目即被锁定。POST boms/ {"name": "DC1 Spine Refresh"} # status defaults to draft POST bom-scope-rules/ {"bom": <bom_id>, "action": "include", "object_types": [{"app_label":"dcim","model":"device"}], "parameters": {"site_id":[3], "role_id":[5], "status":["planned"]}} POST boms/<bom_id>/generate/ GET bom-line-items/?bom_id=<bom_id> # collect line item ids PATCH boms/<bom_id>/ {"status": "approved"} - 采购订单 + PO 行项目(仅在
draft状态下可编辑行项目;要达到ordered/fulfilled状态,必须提供order_id;省略currency时会回退到插件设置中的default_currency):POST purchase-orders/ {"vendor": <vendor_id>, "vendor_account": <acct_id>, "bom": <bom_id>, "currency": "USD"} POST po-line-items/ {"purchase_order": <po_id>, "bom_line_item": <bli_id>, "qty_ordered": 16, "unit_price": "1200.00"} PATCH purchase-orders/<po_id>/ {"status": "approved"} PATCH purchase-orders/<po_id>/ {"order_id": "PO-7788", "status": "ordered"} - 货运 + 货运行项目(创建时状态设为
prepared或shipped;已预置 UPS/FedEx/DHL):POST shipments/ {"purchase_order": <po_id>, "courier": <courier_id>, "tracking_number": "1Z...", "status": "shipped", "site": <site_id>, "date_shipped": "2026-09-01", "date_expected": "2026-09-05"} POST shipment-line-items/ {"shipment": <ship_id>, "bom_line_item": <bli_id>, "qty_shipped": 16} - 收货:
PATCH shipments/<ship_id>/ {"status": "received", "date_received": "..."},然后PATCH shipment-line-items/<id>/ {"qty_received": 16}。 - 安装: 对 BOM 上的每项资产(
GET assets/?bom_id=<bom_id>&installed__isnull=true),执行POST assets/<id>/install/ {"shipment": <ship_id>},然后 PATCH DCIM 对象自身的status/serial。 - 结单: 将 PO 和 BOM 状态设为
fulfilled;也可以对货运、PO 和 BOM 执行PATCH … {"archived": true}。
存量环境备件工作流
完整详情请参阅 references/workflow-sparing.md。
POST spares-pools/ {"name": "HQ Cold Storage", "site": <site_id>, "location": <loc_id>}
POST spare-items/ {"pool": <pool_id>, "item_type": {"app_label":"dcim","model":"devicetype"},
"item_id": <devicetype_id>, "variant": {"airflow":"front-to-rear"},
"quantity": 5, "status": "serviceable"}
# Target stock level for that item in that pool (advisory; surfaces low/excess stock)
POST spare-item-allocations/ {"pool": <pool_id>, "item_type": {"app_label":"dcim","model":"devicetype"},
"item_id": <devicetype_id>, "variant": {"airflow":"front-to-rear"},
"min_quantity": 2, "max_quantity": 8}
GET spare-item-allocations/?pool_id=<pool_id> # read-only current_quantity / below_minimum / above_maximum / is_fulfilled
- 将
status设为damaged/missing,以标记库存审计差异(自由填写)。 - 序列化单件设备应设置
serial/asset_tag,并将quantity=1(quantity大于 1 时设置serial/asset_tag会被拒绝)。 - 使用库存中的备件替换计划内的故障设备:
POST assets/<id>/install/ {"spare_item": <id>}— 将备件数量减至 0(保留记录),并在资产上记录所属备件池。然后 PATCH DCIM 对象的状态。 - 使用备件部署全新对象(不涉及 BOM):
POST spare-items/<id>/install/ {"name": "...", "site": <id>, "role": <id>, "status": "active"}— 根据备件的类型、序列号、资产标签和型号创建 Device/Rack/Module。不能以这种方式安装 Cable。 - 只有
variant完全相同且状态为serviceable的项目才会计入分配;每个备件池对每个项目+型号只允许分配一次。
归档 (0.3)
BOM、PurchaseOrder 和 Shipment 都有可写的 archived 布尔值。对象处理完毕后(通常处于 fulfilled/cancelled/received 状态)将其归档,使其从列表视图中隐藏,但不删除对象:PATCH boms/<id>/ {"archived": true};设为 false 可取消归档。规则:
- 对象不能以
archived: true的状态创建——先创建,再归档。 - 对象归档后,其子对象拒绝写入(范围规则、行项目),且 UI 会将对象设为只读。编辑前请先取消归档。
- REST 默认会在列表中返回已归档对象;使用
?archived=false获取 UI 的默认视图。
反模式
- 使用 0.2 时代的路径/字段。
bom-objects/→assets/;资产上的spare_item→spares_pool。在 0.3 中,这两者都会返回 404/400。 - 手动编写行项目来替代生成。 编写范围规则并调用
POST boms/<id>/generate/。手动行项目仅用于个别情况;自动生成的行不可变,且每次生成时都会重建。 - 伪造安装操作。 切勿 PATCH
assets/<id>/ {"shipment": …}或手动减少spare-items/<id>/ quantity——请使用assets/<id>/install/,它会验证货运/备件、原子性地扣减库存,并写入installed。切勿在安装前将 DCIM 对象 PATCH 为active;应在安装后执行。 - 跳过必需的父项。 PO 需要
bom+vendor;Shipment 需要purchase_order+courier+tracking_number;行项目需要其父项 +bom_line_item。 - 非法的状态跳转或初始状态。
draft→ordered、将 shipment 创建为received等默认会返回 400。使用status-choices/查询可用值,并使用status-transition-rules/允许新的状态跳转或初始状态。 - 在 PO 变为
ordered之前下单。 创建 shipment 前,先设置order_id并将 PO 状态改为ordered——只有已下单的 PO 才会在 UI 中显示 Create Shipment。 - 编辑已锁定的子项。 只有在 BOM 状态为
draft时,范围规则和 BOM 行项目才可写入;只有在 PO 状态为draft时,PO 行项目才可写入;父项归档后,所有子项都会锁定。先恢复状态(如果规则允许),或先取消归档。 - 状态为
received但未指定目的地。 shipment 在没有site和/或location时无法进入received状态 → 400。 - 账户/位置/日期不匹配。
vendor_account.vendor必须等于 PO 的vendor;courier_account.courier必须等于 Shipment 的courier;location.site必须等于site;date_expected/date_received不得早于date_shipped。 - 唯一性限制。 BOM
name;Vendor/Couriername(如果设置了code,则code也必须唯一);(vendor, account_number);设置后需唯一的(vendor, order_id);(courier, tracking_number);(purchase_order, bom_line_item);SparesPoolname;SpareItemasset_tag(全局唯一)和(item_type, item_id, serial);非序列化 SpareItem(pool, item_type, item_id, variant, status);Allocation(pool, item_type, item_id, variant);CableType(type, profile, connector_a, connector_b)。 - 通用关联使用了错误的内容类型。 行项目、备件和分配关联的是类型模型(
dcim.devicetype/moduletype/racktype或netbox_asset_lifecycle.cabletype);资产关联的是实例模型(dcim.device/rack/module/cable)。 - 安装时变体不匹配。 只有在规范化后
item_type、item_id和variant完全匹配时,备件才能满足资产需求。对于已设置 airflow 的计划设备,应为其备货{"airflow":"front-to-rear"}变体的备件;{}无法与其匹配。 - 误以为收货会激活库存。 并非如此——安装是独立步骤,会关联资产;DCIM 对象的状态由你自行更新。
版本说明
插件 0.3.1(2026-08-20)— NetBox 4.5.4–4.7
- shipment 详情视图显示 BOM。
- GraphQL 类型/枚举添加了
AssetLifecycle…前缀(会破坏现有 GraphQL 查询)。 - BOM 行项目、备件项目和分配中的
variant不能再为 null。
插件 0.3.0(2026-06-29)— NetBox 4.5.4–4.6 — 破坏性变更
- 重新初始化迁移:不支持从 0.2.x 升级;更早的版本仅供评估。
BOMObject→Asset;RESTbom-objects/→assets/。Asset.spare_item→Asset.spares_pool(记录的是库存池,而非已消耗的单件备件)。- 新增:
SpareItemAllocation(spare-item-allocations/,最小/最大阈值);default_currency插件设置;CableType上的connector_a/connector_b;多个初始 shipment 状态(prepared或shipped);BOM/PO/Shipment 上的archived。
插件 0.2.x(2026-06)— NetBox 4.5.3–4.6(仅供评估)
- REST 操作
boms/<id>/generate/、assets/<id>/install/(作为bom-objects/)、spare-items/<id>/install/;GraphQL API;采购订单行项目导出;优先安装备件;非草稿 BOM 的范围规则已锁定;数量为 0 时保留备件。
参考资料
- references/data-model.md — 完整对象图、各模型字段、约束和筛选器。构造请求或解析验证错误时加载。
- references/status-transitions.md — 默认状态转换和初始状态规则集,以及每个模型特有的 400 锁定错误。遇到状态 400 错误时加载。
- references/workflow-greenfield.md — 完整的采购流程演练,包含请求载荷:生成、订购、发货、收货、安装、归档。
- references/workflow-sparing.md — 备件池、分配与库存警报、审计、从备件安装、从备件创建新对象。