mcpField
N
netbox-asset-lifecycle

netbox-asset-lifecycle

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

关于 netbox-asset-lifecycle

netbox-asset-lifecycle 是一项技能,介绍如何通过 REST 和 GraphQL API 使用 NetBox Asset Lifecycle 的采购与备件工作流。它强调核对实时 API 和版本,因为功能与端点可能变化。

主要功能

  1. 01采购生命周期 API 指南
  2. 02BOM 生成与范围规则
  3. 03货运与备件安装工作流
  4. 04实时架构与版本核验
  5. 05REST 和 GraphQL 端点参考

适用场景

  1. 01在 NetBox 中构建采购工作流
  2. 02从货运安装计划中的设备
  3. 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.md
status-transitions.md
workflow-greenfield.md
workflow-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 及其采购/备品工作流。不涵盖:

前提条件: 你要采购的设备必须已存在于 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 令牌;v1 Token <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_* 权限。
  • 通用关系(行项目 / 备件 / 分配 / 资产所指向的设备)通过两个字段写入:一个 *_type ContentType({"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 不受规则约束,可自由设置。

模型状态值默认初始状态
BOMdraft、approved、ordered、fulfilled、cancelleddraft
PurchaseOrderdraft、approved、ordered、fulfilled、cancelleddraft
Shipmentprepared、shipped、received、cancelled、returned、lostprepared 或 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→对象可追溯性)。

操作请求所需权限返回
生成 BOMPOST 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=jsonview_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。

  1. 供应商(+ 可选账户)
    POST vendors/          {"name": "Acme Networks", "code": "ACME"}
    POST vendor-accounts/  {"vendor": <vendor_id>, "account_number": "ACC-001"}
    
  2. 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"}
    
  3. 采购订单 + 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"}
    
  4. 货运 + 货运行项目(创建时状态设为 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}
    
  5. 收货: PATCH shipments/<ship_id>/ {"status": "received", "date_received": "..."},然后 PATCH shipment-line-items/<id>/ {"qty_received": 16}。
  6. 安装: 对 BOM 上的每项资产(GET assets/?bom_id=<bom_id>&installed__isnull=true),执行 POST assets/<id>/install/ {"shipment": <ship_id>},然后 PATCH DCIM 对象自身的 status/serial。
  7. 结单: 将 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 的默认视图。

反模式

  1. 使用 0.2 时代的路径/字段。 bom-objects/ → assets/;资产上的 spare_item → spares_pool。在 0.3 中,这两者都会返回 404/400。
  2. 手动编写行项目来替代生成。 编写范围规则并调用 POST boms/<id>/generate/。手动行项目仅用于个别情况;自动生成的行不可变,且每次生成时都会重建。
  3. 伪造安装操作。 切勿 PATCH assets/<id>/ {"shipment": …} 或手动减少 spare-items/<id>/ quantity——请使用 assets/<id>/install/,它会验证货运/备件、原子性地扣减库存,并写入 installed。切勿在安装前将 DCIM 对象 PATCH 为 active;应在安装后执行。
  4. 跳过必需的父项。 PO 需要 bom + vendor;Shipment 需要 purchase_order + courier + tracking_number;行项目需要其父项 + bom_line_item。
  5. 非法的状态跳转或初始状态。 draft→ordered、将 shipment 创建为 received 等默认会返回 400。使用 status-choices/ 查询可用值,并使用 status-transition-rules/ 允许新的状态跳转或初始状态。
  6. 在 PO 变为 ordered 之前下单。 创建 shipment 前,先设置 order_id 并将 PO 状态改为 ordered——只有已下单的 PO 才会在 UI 中显示 Create Shipment。
  7. 编辑已锁定的子项。 只有在 BOM 状态为 draft 时,范围规则和 BOM 行项目才可写入;只有在 PO 状态为 draft 时,PO 行项目才可写入;父项归档后,所有子项都会锁定。先恢复状态(如果规则允许),或先取消归档。
  8. 状态为 received 但未指定目的地。 shipment 在没有 site 和/或 location 时无法进入 received 状态 → 400。
  9. 账户/位置/日期不匹配。 vendor_account.vendor 必须等于 PO 的 vendor;courier_account.courier 必须等于 Shipment 的 courier;location.site 必须等于 site;date_expected/date_received 不得早于 date_shipped。
  10. 唯一性限制。 BOM name;Vendor/Courier name(如果设置了 code,则 code 也必须唯一);(vendor, account_number);设置后需唯一的 (vendor, order_id);(courier, tracking_number);(purchase_order, bom_line_item);SparesPool name;SpareItem asset_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)。
  11. 通用关联使用了错误的内容类型。 行项目、备件和分配关联的是类型模型(dcim.devicetype/moduletype/racktype 或 netbox_asset_lifecycle.cabletype);资产关联的是实例模型(dcim.device/rack/module/cable)。
  12. 安装时变体不匹配。 只有在规范化后 item_type、item_id 和 variant 完全匹配时,备件才能满足资产需求。对于已设置 airflow 的计划设备,应为其备货 {"airflow":"front-to-rear"} 变体的备件;{} 无法与其匹配。
  13. 误以为收货会激活库存。 并非如此——安装是独立步骤,会关联资产;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;REST bom-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 时保留备件。

参考资料

评论

支持 Markdown