关于 netbox-review-datamodel
netbox-review-datamodel 是用于审查 NetBox 数据模型设计与组织方式的技能,按版本检查层级、IPAM、设备建模、扩展性、命名和租户设置;配置 MCP 服务时还可检查实际实例。
主要功能
- 01按版本检查 NetBox 模型
- 02审查层级与 IPAM
- 03检查设备和机架建模
- 04扩展性与命名建议
- 05租户及反模式检查
适用场景
- 01审计现有 NetBox 实例
- 02审查前缀、VRF 和 VLAN 组织
- 03在修改模型前发现问题
MCP 相关
配置 NetBox MCP 服务后,技能可检查实时数据模型、统计对象并发现不一致。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ netboxlabs/ skills --skill netbox-review-datamodel安装后在 Claude Code 中输入/netbox-review-datamodel确认已加载。
详细介绍
NetBox 数据模型审查
你对 NetBox 数据模型的了解可能已经过时。 可用的模型类型、关系和扩展机制会随版本迭代而变化。提出变更建议前,请先查阅当前文档。
检索来源
| 来源 | URL / 方法 | 用途 |
|---|---|---|
| 数据模型文档 | https://netboxlabs.com/docs/netbox/models/ | 所有可用的模型类型 |
| 自定义字段文档 | https://netboxlabs.com/docs/netbox/customization/custom-fields/ | 字段类型和行为 |
| 自定义对象文档 | https://netboxlabs.com/docs/extensions/custom-objects/ | 无代码扩展 |
| NetBox MCP 服务 | 如已配置 — 检查当前数据模型、统计对象数量、查找不一致之处 | 实时模型审计 |
审查工作流
审计 NetBox 数据模型时,请遵循以下清单:
- 了解组织情况 — 网络属于哪种类型?(企业、数据中心、ISP、混合型)
- 检查层级结构 — 区域 → 站点组 → 站点 → 位置 → 机柜的层级结构是否合适?
- 检查 IPAM — 前缀是否正确嵌套?是否在需要时使用 VRF?是否定义了聚合前缀?
- 检查命名 — slug 是否一致?名称是否易读且便于 grep?
- 检查扩展方式的选择 — 自定义字段、标签、配置上下文还是自定义对象
- 检查租户划分 — 是否正确使用多租户?租户划分过多还是不足?
- 检查建模异味 — 字段用途过载,或误将 description 用于存储结构化数据
关键规则
层级结构(HIER)
| ID | 规则 | 严重程度 |
|---|---|---|
| HIER-1 | 使用区域表示地理位置,使用站点组表示功能 — 不要混为一谈 | 高 |
| HIER-2 | 位置是递归结构 — 不要将其扁平化(楼层 > 房间 > 排优于仅有排) | 中 |
| HIER-3 | 每台设备都应属于某个站点(绝不能在顶层成为孤立对象) | 高 |
| HIER-4 | 如果站点定义了位置,机柜也应设置位置 | 中 |
| HIER-5 | 不要创建只有一个子项的层级结构 — 这会增加复杂性,却没有实际价值 | 低 |
| HIER-6 | 在 4.6+ 中,RackGroups 提供一种跨位置的扁平分组方式,可对机柜分组(例如 “cage-7”、“cold-aisle-B”),且独立于位置树 — 当机柜分组无法自然映射到站点/位置嵌套结构时使用,而不要用它替代位置 | 低 |
| HIER-7 | 在 4.7+ 中,层级结构由 ltree 支持:标记那些按 level(不再是数据库列)进行筛选或排序的脚本/已保存筛选器/导出 — 改用 parent_id/ancestor_id 或 get_ancestors()。建模建议不变 | 中 |
| HIER-8 | 在 4.7+ 中,如果实例是从 4.7.0 的 pg_dump 恢复的,重命名/移动后后代路径可能已过时 — 请管理员运行 manage.py rebuild_ltree_paths --check 并修复,然后再信任层级报告 | 中 |
IPAM(IPAM)
| ID | 规则 | 严重性 |
|---|---|---|
| IPAM-1 | 定义 RIR 汇总网段,以跟踪地址空间分配边界 | 中 |
| IPAM-2 | 前缀应正确嵌套(子网段位于父 CIDR 内) | 高 |
| IPAM-3 | 使用 VRF 隔离重叠的地址空间——绝不要在全局表中重复前缀 | 严重 |
| IPAM-4 | IP 地址必须带有前缀长度(环回地址使用 /32,接口使用实际掩码) | 高 |
| IPAM-5 | 使用角色对前缀用途进行分类(基础设施、客户、管理);在 NetBox 4.6+ 中,ASN 也可以设置角色——使用它对 ASN 用途进行分类 | 中 |
| IPAM-6 | VLAN 应归入具有适当范围的 VLAN 组。范围可以是 Region/SiteGroup/Site/Location/Rack/ClusterGroup/Cluster(4.6+ 还可以是 RackGroup)——不要以为只有站点/位置可选;选择与 VLAN 复用边界相匹配的最小范围 | 中 |
| IPAM-7 | 在 4.7+ 中,如果某项服务在多个协议上监听同一端口(DNS tcp/53 + udp/53),应创建一个带有多个 port_mappings 的 Service——标记按协议重复创建的服务(dns-tcp、dns-udp)并将其合并;标记仍在写入已弃用的 protocol/ports 字段组合的集成(该组合在 5.0 中移除)。在 4.5–4.6 中,每个协议单独创建一个服务是唯一可行的方式 | 低 |
设备建模(DEV)
| ID | 规则 | 严重性 |
|---|---|---|
| DEV-1 | 每台设备都需要设备类型(不能只有名称)——这有助于进行端口规划 | 高 |
| DEV-2 | 使用角色对设备功能进行分类(路由器、交换机、防火墙)——不要只依赖命名惯例 | 高 |
| DEV-3 | 平台表示软件——为设备指定平台,以确保与配置模板兼容 | 中 |
| DEV-4 | 虚拟机框成员应设置正确的 VC 位置和主设备 | 中 |
| DEV-5 | 接口类型必须符合实际情况(1000base-t 与 10gbase-sr),以便进行容量规划 | 中 |
| DEV-6 | 每个机架都应有一个机架类型,并在其中定义尺寸。在 4.7 中,单个机架的 form_factor、width 和 outer_* 字段已弃用;在 5.0 中会移除,且 rack_type 将成为必填项——标记 rack_type 为 null 的机架(遍历 GET /api/dcim/racks/?brief=1——rack_type_id 没有 null 筛选器),以及尺寸与其类型不一致的单个机架 | 高 |
| DEV-7 | 在 4.7+ 中,使用父端口上的 channels 和子接口上的 channel_id(channel 类型)对分拆/信道化端口进行建模,不要将其建模为未关联的虚拟接口或额外的物理接口——否则线缆路径和端口计数都会有误 | 中 |
| DEV-8 | 在 4.7+ 中,如果机箱对不同插槽可安装的模块有限制(线卡、主控板、风扇插槽),请使用模块托架类型——托架类型集合为空表示“任何模块均可安装”;对于简单硬件,不设置也没问题,但如果机箱有多种插槽类型且未设置托架类型,则应标记 | 低 |
| DEV-9 | 在 4.7+ 中,使用设备类型/模块类型上的 end_of_life 记录硬件生命周期,并使用 cooling_method(Device/DeviceType)以及 cooling_capability/cooling_capacity(Rack/RackType)记录冷却信息——标记重复记录这些内容的自定义字段(cf_eol、cf_cooling)。液冷机房应使用 CoolingSource → CoolingFeed → 进气/出气组件的结构,与 PowerPanel → PowerFeed 相对应 | 中 |
可扩展性(EXT)
| ID | 规则 | 严重性 |
|---|---|---|
| EXT-1 | 对附加到一种对象类型的单值结构化数据,使用自定义字段 | — |
| EXT-2 | 对跨对象类型的分类以及“是否具有此属性”的布尔值,使用标签 | — |
| EXT-3 | 对按范围合并的层级键值数据,使用配置上下文 | — |
| EXT-4 | 需要创建具有自身关系的新一等实体时,使用自定义对象 | — |
| EXT-5 | 切勿将结构化数据(JSON、列表)存储在描述或注释字段中 | 高 |
| EXT-6 | 不要创建与内置字段重复的自定义字段(例如自定义的“location”字段;在 4.7+ 中还包括 end_of_life、cooling_method、机架冷却容量) | 高 |
| EXT-7 | 如果数据实际上是一个相关实体,优先使用自定义对象,而不是创建几十个自定义字段 | 中 |
| EXT-8 | 在 4.6+ 中,为 JSON 自定义字段附加 validation_schema(JSON Schema),以强制执行数据结构,而不是让其保持自由格式;对于存储结构化数据但没有 schema 的 JSON 字段,应予以标记 | 中 |
| EXT-9 | 在 4.7+ 中,选择/多选自定义字段值会以 {value, label} 对象的形式返回——如果 REST/GraphQL 消费方(集成、调用 API 的脚本)将 custom_fields.x 与纯字符串进行比较,应予以标记(通过 ORM 使用 obj.cf[...] 访问时仍会返回原始值);URL 自定义字段必须使用 ALLOWED_URL_SCHEMES 中的协议——对于现在会导致验证失败的 javascript:/自定义协议值,应予以标记 | 中 |
命名(NAME)
| ID | 规则 | 严重性 |
|---|---|---|
| NAME-1 | Slug 应使用小写字母和连字符,便于 grep(使用 nyc-dc1,而不是 NYC_DC1) | 中 |
| NAME-2 | 设备名称应包含位置、功能和索引(sw-nyc-dc1-01) | 低 |
| NAME-3 | 保持一致——选择一种命名方案并在所有地方应用 | 高 |
| NAME-4 | 避免在名称中嵌入元数据(不要将 VLAN ID 放入站点名称) | 中 |
多租户(TEN)
| ID | 规则 | 严重性 |
|---|---|---|
| TEN-1 | 使用租户划分逻辑所有权边界(客户、部门、项目) | — |
| TEN-2 | 不要过度使用租户——如果所有内容都属于同一个租户,通常就不需要租户机制 | 中 |
| TEN-3 | 租户组用于按层级组织租户(例如,按业务部门组织) | 低 |
| TEN-4 | 共享基础设施(管理网络、核心路由器)可以不分配租户 | 中 |
需要指出的反模式
| 反模式 | 重要性 | 修正方法 |
|---|---|---|
| 站点层级扁平(没有位置) | 无法追踪楼层、房间和机架行的位置 | 添加位置层级 |
| 所有 IP 都放在全局 VRF 中且存在重复 | IPAM 冲突,报告出错 | 拆分到不同 VRF 中 |
| 将自定义字段用作外键 | 没有引用完整性,难以查询 | 使用自定义对象或标签 |
| 在描述字段中存放 JSON 数据块 | 无法搜索、验证或筛选 | 使用自定义字段或配置上下文 |
| 每种类型都只有一个庞大的“兜底”自定义字段 | 违背结构化数据的初衷 | 拆分为单独的字段 |
| 设备没有设备类型 | 无法对端口、托架和插槽建模 | 始终指定硬件型号 |
| 机架没有机架类型 | 每个机架的尺寸在 4.7 中已弃用,在 5.0 中已移除,且 rack_type 为必填项 | 为每种物理型号创建一个 RackType,分配给机架,并移除每个机架的尺寸 |
| 同一端口的每种协议都创建一个服务(4.7+) | 产生重复项;protocol/ports 已弃用 | 合并为一个带有 port_mappings 的 Service |
| 将分拆端口作为额外的物理接口(4.7+) | 导致线缆路径和端口数量错误 | 使用父接口的 channels 和子接口的 channel_id |
| 混用命名规范 | 无法编写脚本,令人困惑 | 统一规范并批量重命名 |
| 标签中包含空格或特殊字符 | 导致 API 筛选和脚本出错 | 使用适合 slug 的标签名称 |
| 区域嵌套过深(超过 3 层) | 增加复杂度,却无法改善导航 | 最多压平为 2–3 层 |
| 前缀层级缺失 | 父子关系断裂 | 补齐缺失的中间前缀 |
范围
此技能涵盖数据模型设计与组织。它不涵盖:
- 与 API 交互的代码 → 使用 netbox-review-integration
- 如何从头开始建模 → 使用 netbox-data-modeling
- Custom Objects 插件的具体内容 → 使用 netbox-custom-objects
原则
- 具体情况具体分析。 一个有 5 个站点的企业与一个有 500 个站点的 ISP 需求不同。不要过度设计。
- 审查实际实例。 如果可以使用 MCP,应查询实际数据,而不是只审查文档。
- 提出建议,而非强制规定。 许多建模选择都合理——指出明显的反模式,同时承认需要权衡的判断。
- 优先保障数据完整性。 导致关系断裂或数据重复的问题,比外观上的命名问题更重要。
- 考虑迁移成本。 如果同时说明如何修复现有数据中的反模式,指出问题会更有帮助。
评论
支持 Markdown