mcpField
I
infrahub-converting-netbox-device-types

infrahub-converting-netbox-device-types

github.com/opsmill云与 DevOps2741 次安装1 天前更新
代码仓库

关于 infrahub-converting-netbox-device-types

此技能使用内置 Python 脚本和映射配置,将 NetBox 设备类型 YAML 转为可复用的 Infrahub 对象模板。适用于从公开库或 NetBox 导出导入设备模型,并报告目标 Schema 无法承载的数据。

主要功能

  1. 01将设备类型 YAML 转为 Infrahub 模板
  2. 02支持模块类型和组件端口
  3. 03通过 Schema 专用配置映射字段
  4. 04从 NetBox 实例导出设备类型
  5. 05生成转换覆盖率报告

适用场景

  1. 01用厂商设备型号初始化 Infrahub
  2. 02为实验室拓扑转换指定设备类型
  3. 03在库或 Schema 更新后重新转换
  4. 04为自定义 Infrahub Schema 编写映射

安装

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

$npx skills add https://github.com/opsmill/infrahub-skills --skill infrahub-converting-netbox-device-types

安装后在 Claude Code 中输入/infrahub-converting-netbox-device-types确认已加载。

包含的文件

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

concepts.md
examples.md
extending-your-schema.md
generators-module-ports.md
reference.md
rules/
_sections.md
coverage-report-unmapped.md
format-template-objects.md
mapping-fallback-sources.md
mapping-profile-driven.md
mapping-shared-relationships.md
naming-template-names.md
output-load-order.md
workflow-schema-prerequisites.md
workflow-use-the-bundled-scripts.md
scripts/
materialize_module_ports.gql
materialize_module_ports.py
netbox_export_device_types.py
netbox_to_infrahub_templates.py
scripts/mappings/
_template.yml
schema-library-module-ports.yml
schema-library-modules.yml
schema-library.yml

详细介绍

NetBox 设备类型转换器

概述

将 NetBox 设备类型 YAML(netbox-community/devicetype-library 使用的格式,可在 NetBox Data Exchange 浏览)转换为 Infrahub 对象模板:可复用的蓝图,用于创建已预先配置好所有端口的设备。

转换由捆绑的 Python 脚本完成,无需手动操作。手动转换一台 48 端口交换机意味着要转录 48 个几乎相同的代码块,而该库包含数千种设备类型。脚本精准且可重复;本技能旨在帮助你将脚本指向正确的架构,并解读它提供的信息。

项目上下文

目标架构文件: !find . -name "*.yml" -path "*schema*" 2>/dev/null | head -10

现有映射配置: !find . -name "*.yml" -path "*mappings*" 2>/dev/null | head -10

使用场景

  • 使用 NetBox 库中的厂商设备型号为新的 Infrahub 实例填充数据
  • 为特定项目或实验室拓扑转换少量设备类型
  • 在上游库或本地架构发生变化后重新运行转换
  • 构建将 NetBox 字段绑定到自定义 Infrahub 架构的映射配置

不适用于让 NetBox 和 Infrahub 实时保持同步——这需要使用单独的产品 infrahub-sync。本技能用于转换已发布库中的设备类型定义,或从运行中的 NetBox 单次导出的设备类型定义。

转换的结构

一个 NetBox 文件会变成 三 个 Infrahub 工件, 因为 Infrahub 会拆分 NetBox 保持在一起的内容:

NetBoxInfrahub原因
manufacturer: CiscoOrganizationManufacturer 对象制造商是一等对象
model、part_number、u_height、weightDcimDeviceType 对象模板不包含型号数据
interfaces: 和其他组件列表TemplateDcimDevice + 组件模板可复用的蓝图

模板会关联到设备类型,因此根据模板创建设备时,也会一并关联其型号。

模块类型是第二类输入,包括线路卡、电源模块和收发器,位于同级的 module-types/ 目录中。它们没有 slug,转换器正是据此区分两类输入,因此可以一次性转换混合目录树。它们遵循相同的拆分方式(模块类型对象,以及可选的模块模板),并输出到 04_module_types.yml / 05_module_templates.yml。在对此作出任何承诺之前,请先阅读 extending-your-schema.md:模块端口只能转换到模块模板上,而 stock schema-library 的 DcimModule 不会生成模块模板。使用 schema-library-modules.yml 时,这些端口会报告为已跳过;当 DcimModule 设置了 generate_template: true 后,schema-library-module-ports.yml 才会包含它们。

模块端口名称带有 NetBox 的 {module} 标记,任何转换都无法解析它——只有在安装模块后才能知道插槽位置。端口作为模块模板上的 DcimModulePort 声明导入后,捆绑的生成器会针对每个已安装的模块解析该标记,并根据接口端口创建实际的设备接口。控制台端口需要架构中包含控制台接口类型,而电源端口仍保持为声明。请参阅 generators-module-ports.md。

几乎所有意外情况都由以下三个事实造成——应当解释它们,而不是想当然:

  1. Template* 类型是生成的,而非手动编写的。 在节点上设置 generate_template: true 会创建这些类型; 如果未设置,它们就不存在。
  2. 组件模板只来自 Component 关系。 Attribute 关系仍指向实际对象。
  3. 型号数据位于设备类型上,而非模板上。 这就是为什么需要按此顺序使用三个文件。

如果你刚接触 Infrahub 的数据模型,或正要向他人讲解它,请参阅 concepts.md,其中对此有介绍,并附有 Infrahub 文档链接。

规则类别

优先级类别前缀说明
CRITICAL工作流workflow-必须先启用 generate_template;捆绑的脚本会完成相关工作
CRITICAL映射mapping-名称来自架构,绝不猜测;冲突字段会声明优先级
CRITICAL格式format-信封、Template<Kind>、嵌套组件
HIGH命名naming-基于 slug、使用父级命名空间、保持唯一
HIGH覆盖范围coverage-报告未转换的内容
MEDIUM输出output-三个文件、加载顺序、分支优先

完整索引:rules/_sections.md。

工作流

1. 确认架构会生成模板

只有在节点声明了 generate_template: true 时,才会存在 Template* 类型。请检查目标架构, 不要想当然地认为该选项已启用或未启用——这是转换后什么也没有加载的最常见原因。

在 OpsMill schema-library 中,答案取决于版本:v2 及更高版本在 base/dcim.yml 中的 DcimDevice 上启用了该选项,而 v2 之前的版本中该行 被注释掉了。自定义架构通常需要自行添加。

请阅读 rules/workflow-schema-prerequisites.md。

如果未启用,请说明更改内容,不要悄悄修改:该标志会为每个 Component 关系生成 TemplateDcimDevice 和组件模板;这是增量添加,并且必须重新加载 架构,这些类型才会出现。启用该选项会修改用户的事实来源,因此应由用户决定—— 展示单行差异,让他们自行选择。

文档: 对象模板概览 · 创建并加载架构

2. 选择或编写映射配置文件

转换器通过配置文件将 NetBox 字段绑定到 Infrahub 属性,因此不会猜测名称。

  • 使用 OpsMill schema-library?请从 scripts/mappings/schema-library.yml 开始;如果还需要模块类型,请使用 scripts/mappings/schema-library-modules.yml;如果还需要模块端口,请使用 scripts/mappings/schema-library-module-ports.yml(参见 generators-module-ports.md)。
  • 使用自定义架构?请将 scripts/mappings/_template.yml 复制到工作目录(例如 ./mappings/my-schema.yml,切勿放在 $SKILL 中, 因为重新安装插件时该目录会被清空),然后逐个类型、逐个属性地阅读架构 YAML并填写配置。

请阅读 rules/mapping-profile-driven.md 和 reference.md,了解双方的完整字段清单。如果两个 NetBox 字段 争用同一个 Infrahub 属性——例如 description 与 comments,接口的 label 与 description——请用 fallback 声明优先级,而不是只选一个并丢弃另一个;参见 rules/mapping-fallback-sources.md。

在认定某项缺失之前,请先检查是否已有节点可以填补空缺。 控制台端口通常 建模为继承接口通用类型的节点;在这种情况下,它会沿用设备现有的 interfaces 关系,完全不需要修改架构——只需添加配置文件条目即可。如果两个列表共用一个关系, 请阅读 rules/mapping-shared-relationships.md: 弄错会悄无声息地丢弃较大的列表。 extending-your-schema.md 列出了 schema-library 和 infrahub-demo-dc 已提供的内容。

3. 获取输入

根据设备类型文件的位置,有两个来源。

从运行中的 NetBox 获取。 某个用户自己实例中的目录通常才是他们真正想导入的内容,而且它与已发布的库并不相同。scripts/netbox_export_device_types.py 通过 REST API 读取运行中的实例,并写入库文件格式:

pip install 'pynetbox>=7.0' pyyaml   # NetBox's client, and the file writer
# SKILL is this skill's own directory, wherever it is installed
SKILL=/path/to/infrahub-converting-netbox-device-types
export NETBOX_TOKEN=...
python "$SKILL/scripts/netbox_export_device_types.py" \
  --url https://netbox.example.com \
  --in-use \
  --module-types \
  --output-dir ./netbox-export

请留在用户的工作目录中,并使用脚本的完整路径。 $SKILL 是此技能的安装位置;对于插件安装,它位于 ~/.claude/plugins/cache/ 下,而重新安装插件会清空该目录。从那里运行会将导出文件、克隆的库和生成的 YAML 都放在该目录中,下一次更新就会删除用户的数据。以下命令读取或写入的所有内容(./netbox-export、devicetype-library/、./generated)都相对于用户当前所在的位置。

--in-use 只保留至少关联一个设备的设备类型,以及至少关联一个模块的模块类型。在真实实例中,这比整个目录小得多,也更符合实际需求。

脚本会报告所有未能顺利转换的内容:NetBox 中存在但库格式无法承载的字段、NetBox 未设置但库格式要求的字段、该 NetBox 版本中不存在的端点、清理后发生冲突的文件名,以及版本早于 4.5 的 NetBox 所使用的前端口结构。转换前请阅读此列表,就像加载前阅读转换覆盖率报告一样。

这只是一次性快照导出到文件,并非同步。持续复制数据请使用单独的产品 infrahub-sync。

从已发布的库获取。 如果要为尚未收录的厂商型号建立初始数据,请克隆上游仓库,但要使用稀疏克隆。普通的 --depth 1 克隆会拉取 1.6 GB 数据,其中几乎全是转换器不会读取的机柜立面图。将范围限制为定义文件即可获取 11,500 多种设备类型和 2,000 多种模块类型,约占 60 MB:

git clone --depth 1 --filter=blob:none --sparse \
  https://github.com/netbox-community/devicetype-library.git
git -C devicetype-library sparse-checkout set device-types module-types

如果只需要设备,请从该列表中移除 module-types。

转换器接受文件、目录(递归遍历)和 glob 模式。

4. 运行转换器

请运行转换器,不要自行重写。两个脚本都包含手写等效实现会悄然丢失的正确性保障,而且出错时看起来像成功:YAML 有效、没有错误、没有覆盖率报告,但数据有误。请阅读 rules/workflow-use-the-bundled-scripts.md。 如果某个架构不适用,应该使用映射配置文件,而不是换一个脚本。

python "$SKILL/scripts/netbox_to_infrahub_templates.py" \
  devicetype-library/device-types/Cisco/ \
  --mapping "$SKILL/scripts/mappings/schema-library.yml" \
  --output-dir ./generated \
  --report ./generated/coverage-report.md

对于实时导出的数据,请将其导出目录传给转换器。它会同时遍历 device-types/ 和 module-types/,因此需要能映射两者的配置文件:

python "$SKILL/scripts/netbox_to_infrahub_templates.py" \
  ./netbox-export/ \
  --mapping "$SKILL/scripts/mappings/schema-library-modules.yml" \
  --output-dir ./generated \
  --report ./generated/coverage-report.md

退出码:0 表示已转换,1 表示配置文件无效或输入格式错误,2 表示未匹配到文件。

如果两个设备类型的 model 相同,转换器会拒绝处理并列出所有冲突对。模板使用设备类型的 model 来标识设备类型,因此同时加载两者会让其中一个覆盖另一个,而且不会报错;已发布的库中有少数此类冲突,涉及多个厂商。请勿将每组冲突中的两者都包含在输入中。

写入或手动编辑任何生成的文件前,请阅读 rules/format-template-objects.md ——其中的封装结构、Template<Kind> 划分,以及 {kind, data} 组件包装器,是确保输出可加载的关键——并阅读 rules/naming-template-names.md,因为除非使用所属父级为组件命名空间前缀,否则不同设备类型中的组件名称会发生冲突。

5. 阅读覆盖报告,解释缺失项并提供修复方案

对于典型的架构,每个 NetBox 文件中都有很大一部分无处可去。打开报告,并在 回复中:

  1. 指出缺失最多的内容——哪些组件列表 和哪些字段,以及对应数量。不要只说 存在一份报告。
  2. 解释架构为何无法容纳这些内容。 仅仅说“跳过了 console-ports”,对不了解组件模板 仅从 Component 关系生成的人来说,无法采取行动。请说明原因。
  3. 提供具体的修复方案。 被丢弃的字段只需添加一个 属性;被跳过的列表则需要添加一个节点,以及一对 Component/Parent。两者都属于增量修改。 extending-your-schema.md 提供了各个案例的可用 YAML,包括哪些 架构库扩展已涵盖其中一部分。

提出建议——不要擅自重写对方的架构。这是一次 针对其真实数据源的迁移。

请阅读 rules/coverage-report-unmapped.md。

适用时,值得点名指出的两个案例:

  • 模块化机框——其端口位于模块 插槽中,因此有 414 种已发布设备类型(3.6%)声明了插槽但没有接口, 转换后会成为没有接口的模板。在架构库 v2 中,插槽本身也会转换(TemplateDcimModuleBay), 这样空模板就能变得有用;schema-library-modules.yml 配置 会映射它们。在 v2 之前的版本中,或在没有插槽节点的架构中, 它们仍会被报告为跳过。请参阅 extending-your-schema.md。
  • 控制台端口通常只需更改配置,而不是架构——如果架构将其建模为 继承接口通用类型的节点,它们就已经通过 interfaces 关系导入。
6. 加载到分支
infrahubctl branch create netbox-import
for file in generated/0*.yml; do
  infrahubctl object load "$file" --branch netbox-import
done

加载顺序遵循依赖顺序——先制造商,再设备类型, 然后是模板。请阅读 rules/output-load-order.md。 切勿将批量导入直接加载到默认 分支。

扩展转换器

优先调整映射配置——它无需修改 Python,就能涵盖新的 类型、重命名的属性、额外的组件列表和条件值。只有遇到真正的新 机制(尚不存在的转换类型)时,才修改脚本。向脚本添加 特定于架构的特殊情况,会导致它无法再为其他人正常工作。

其测试位于 tests/scripts/test_netbox_to_infrahub_templates.py, 而模块端口生成器的测试位于 tests/scripts/test_materialize_module_ports.py。任何修改后都要运行 这些测试:

uv run invoke test

参考资料

文件何时阅读
concepts.md不熟悉 Infrahub 模型,或需要解释它时
reference.md § 从正在运行的 NetBox 导出设备类型位于正在运行的 NetBox 中:查看标志、身份验证,以及导出报告的内容
extending-your-schema.md将报告中的缺失项转化为架构变更
generators-module-ports.md模块端口作为声明导入,且需要将 {module} 标记解析为实际设备接口时
reference.md查找 NetBox 字段或其对应的 Infrahub 字段
examples.md需要转换、配置或架构补丁的完整示例时
rules/应用或检查特定规则
../infrahub-managing-objects/rules/value-profiles-templates.md手动编写模板,或选择配置还是模板时
../infrahub-managing-schemas/rules/relationship-component-parent.md添加生成模板所依据的组件关系时

Infrahub 文档

解释概念时请链接到这些页面——用户点击链接后学到的是相关功能,而不仅仅是这种转换。

主题页面
对象模板是什么https://docs.infrahub.app/object-templates/overview
启用和使用对象模板https://docs.infrahub.app/object-templates/use
模板与 Profileshttps://docs.infrahub.app/object-templates/with-profiles
每个对象的唯一值https://docs.infrahub.app/object-templates/allocate-resources-from-pools
节点和属性https://docs.infrahub.app/schema/nodes-and-attributes
关系(Component 与 Attribute)https://docs.infrahub.app/schema/relationships
Generics 与继承https://docs.infrahub.app/schema/generics-and-inheritance
在不派生 Schema 的情况下扩展它https://docs.infrahub.app/schema/extensions
加载 Schemahttps://docs.infrahub.app/schema/create-and-load
Schema 迁移及其风险https://docs.infrahub.app/schema/migration
Schema 属性参考https://docs.infrahub.app/reference/schema/node
Profiles 与模板的区别https://docs.infrahub.app/profiles/overview
从头开始创建 Schema(教程)https://docs.infrahub.app/academy/tutorials/build-your-first-schema
生成器(安装后解析 {module})https://docs.infrahub.app/generators/overview

评论

支持 Markdown