关于 infrahub-managing-schemas
为设计和构建 Infrahub Schema 提供指导,面向数据建模及维护现有 Schema 的开发者。内容涵盖节点、泛型、属性、关系及下游用途的 YAML 定义。
主要功能
- 01定义节点与抽象泛型
- 02建模属性和关系
- 03配置显示与层级属性
- 04规划供下游使用的扩展
- 05格式化、校验并部署 Schema
适用场景
- 01设计新的领域数据模型
- 02扩展或重构现有 Schema 文件
- 03排查 Schema 校验错误
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ opsmill/ infrahub-skills --skill infrahub-managing-schemas安装后在 Claude Code 中输入/infrahub-managing-schemas确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples.mdreference.mdrules/_sections.md_template.mdattribute-branch-agnostic.mdattribute-computed-jinja2.mdattribute-defaults-and-types.mddisplay-human-friendly-id.mddisplay-menu-placement.mddisplay-order-by-scope.mddisplay-order-weight.mdextension-artifact-target.mdextension-cross-file.mdextension-file-object.mdextension-object-profile.mdextension-object-template.mdformat-schema-files.mdgeneric-membership-is-a-published-interface.mdhierarchy-setup.mdmigration-state-absent.mdnaming-conventions.mdrelationship-cardinality-consequences.mdrelationship-component-parent.mdrelationship-defaults.mdrelationship-identifiers.mdrelationship-on-delete.mdrelationship-peer-kind.mdreuse-evaluate-per-generic.mdreuse-verify-kind-availability.mduniqueness-constraints.md详细介绍
Infrahub 架构创建工具
概述
为设计和构建 Infrahub 架构提供专家指导。架构是 YAML 文件,用于定义节点(具体类型)、泛型(抽象基类型)、属性、关系和扩展。
项目上下文
此项目中的现有架构:
!find . -name "*.yml" -path "*/schemas/*" -o -name "*schema*" -name "*.yml" 2>/dev/null | head -20
Infrahub 配置(如果存在):
!cat .infrahub.yml 2>/dev/null || echo "No .infrahub.yml found"
如果调用时带有参数(例如,/infrahub:managing-schemas Ipam Vlan VlanGroup),请将第一个参数用作命名空间,其余参数用作节点名称。
适用场景
- 设计新的数据模型或架构节点
- 为现有架构添加属性或关系
- 设置分层位置树或组件/父级模式
- 配置显示属性(human_friendly_id、display_label)
- 迁移或重构现有架构
- 调试架构验证错误
规则类别
| 优先级 | 类别 | 前缀 | 说明 |
|---|---|---|---|
| 严重 | 分支优先变更 | workflow- | 将架构加载到分支,而非默认分支 |
| 严重 | 命名 | naming- | 命名空间、节点和属性命名 |
| 严重 | 关系 | relationship- | ID、对端、组件/父级、on_delete |
| 高 | 属性 | attribute- | 默认值、下拉选项、计算型 Jinja2、分支无关、已弃用 |
| 高 | 层级结构 | hierarchy- | 分层泛型、父级/子级 |
| 高 | 显示 | display- | human_friendly_id、order_weight、order_by、菜单位置 |
| 中 | 扩展 | extension- | 通过 extensions 块跨文件扩展、制品目标 |
| 高 | 唯一性 | uniqueness- | 约束格式、必需关系及作用范围;泛型与具体类型 |
| 中 | 迁移 | migration- | 添加/移除属性,state: absent |
| 中 | 文件格式 | format- | 规范键顺序;infrahubctl schema format(离线) |
| 高 | 验证 | validation- | 加载时的字符串长度上限(description / label / identifier)、常见错误消息、预检查清单 |
| 高 | 复用 | reuse- | 建模前检查市场;引用某种类型前先确认其存在;按泛型采用,而非按文件采用 |
| 高 | 泛型成员资格 | generic- | 泛型的实现者集合是一种接口:加入成员会影响围绕该泛型的所有查询、约束和使用方 |
架构文件基础
---
# yaml-language-server: $schema=https://schema.infrahub.app/infrahub/schema/latest.json
version: "1.0"
generics: # Abstract base definitions (shared attributes/relationships)
- ...
nodes: # Concrete object types
- ...
extensions: # Add attributes/relationships to existing nodes from other files
nodes:
- ...
始终包含 $schema 注释,以启用 IDE 验证。
顶层只要求 version。
面向下游使用者进行设计
模式节点很少会孤立存在。在最终确定之前,请梳理项目其他部分将如何使用它,并添加这些功能所需的继承配置:
| 如果该节点将…… | 在模式中添加 | 参见 |
|---|---|---|
作为工件的目标(由 artifact_definition 引用的组成员) | 在具体节点上添加 inherit_from: [..., CoreArtifactTarget] | rules/extension-artifact-target.md |
作为生成器的目标(由 generator_definition 引用的组成员) | 在具体节点上添加 inherit_from: [..., CoreArtifactTarget] | rules/extension-artifact-target.md |
| 出现在自定义侧边栏菜单中 | 添加 include_in_menu: false,以免自动菜单重复显示手动添加的条目 | ../infrahub-managing-menus/rules/schema-integration.md |
| 可作为对象模板克隆(节点及其组件子节点) | 添加 generate_template: true | rules/extension-object-template.md |
| 为多个实例提供共享的默认值 | 添加 generate_profile: true(以及 Profile 实例) | rules/extension-object-profile.md |
| 存储上传的文件(PDF、图片、Visio、KMZ、合同等) | 在具体节点上添加 inherit_from: [..., CoreFileObject] | rules/extension-file-object.md |
| 在 UI 列表和 API 中以稳定的名称显示 | 添加 human_friendly_id 和 display_label | rules/display-human-friendly-id.md |
这项检查决定了一个模式是仅仅“能通过验证”,还是能“在更广泛的项目中真正发挥作用”。跳过这一步会迫使你在下游功能接入后进行模式迁移——届时数据已经加载。
当任务涉及多项技能(模式 + 转换、模式 + 菜单等)时,应一并加载这些技能的规则,而不要将它们视为互不相关的边界。
面向更低成本层的设计
选择合适的 schema,可以避免在下游使用 Python 或非规范化数据。schema 是以最低成本做好这件事的地方——之后再修复,就意味着要迁移已加载的数据。添加字段或节点前,请检查是否已有内置功能或结构特性可以满足需求:
| 信号 | 成本更低的层 | 参见规则 |
|---|---|---|
| 从头开始构建任何领域(市场发布的 schema 远不止 DCIM/位置/组织——还包括路由、安全、计算等众多领域) | 搜索整个市场并复用已发布的 schema:infrahubctl marketplace get <ns>/<name>,然后使用 inherit_from。采用 schema 会带来依赖,并非没有代价:请确认该类型的层级,并记录来源 | yagni-reuse-existing-marketplace-schema、reuse-verify-kind-availability、reuse-evaluate-per-generic |
将值复制到一个可通过遍历关系到达的节点上(已有 device.location.region.code,却又添加 region_code) | 通过间接关系遍历;让使用方沿着关系访问 | yagni-denormalized-vs-indirect-relationship |
| 多个同级节点重复相同的属性和关系 | 提取通用类型并使用 inherit_from 继承 | yagni-duplicate-shape-not-extracted-to-generic |
| 定义自定义 IP 地址/前缀节点 | 使用 inherit_from 继承内置基元(BuiltinIPAddress、BuiltinIPPrefix)。VLAN 基元由市场发布,并非核心内置项,因此在建立对等关系前请先确认 | yagni-custom-domain-primitives-instead-of-builtin、reuse-verify-kind-availability |
一个 Attribute 与一个 cardinality: one 关系配对,但对端没有逆向关系 | 声明匹配的逆向关系,让使用方在查询中筛选,而非在 Python 中筛选 | yagni-missing-inverse-forces-python-filter |
| Profile 承载的单个值在所有对象间都不会变化 | 使用属性的 default_value——只有在值会变化或需要集中重新调整时,Profile 才值得付出相应成本 | yagni-profile-over-default |
| 为共享实时值而使用 Object Template,或为克隆节点的子组件而使用 Profile | 根据意图选择工具:Profile 共享实时值,Object Template 克隆结构 | yagni-template-profile-confusion |
在尚无 Profile 或模板会使用相关功能时,就启用 generate_profile/generate_template | 等默认值/克隆工作流实际存在时再启用此标记 | yagni-unused-generate-flag |
这些是 schema 层面的对应建议,与 checks、transforms 和 generators 技能中的“编写 Python 之前”指导相呼应。仓库审计器会将这些问题标记为建议性的修复成本发现;在设计阶段发现并处理,可以避免问题本身,也能避免之后迁移数据。
工作流
创建或修改 schema 时,请按以下步骤操作:
- 收集需求 — 确定节点类型、 节点属性以及它们之间的关系。 询问层级结构、下拉列表和显示需求。
- 先检查 Marketplace — 从头开始建模
任何领域之前,先搜索整个 Infrahub
Marketplace,并在有适用的已发布架构时复用:
infrahubctl marketplace get <namespace>/<name>,然后通过inherit_from继承拉取的 通用类型,仅添加特定于站点的属性。 发现方式、集合(-c)、气隙环境下的备用方案 以及所需 SDK 版本见 ../infrahub-common/marketplace-reference.md。 应逐个通用类型评估已发布文件,而不是把它视为一个整体, 并记录所复用内容的来源 (rules/reuse-evaluate-per-generic.md)。 在依赖任何继承或对等类型之前,先确认它们在干净实例上确实存在。Core/Builtin前缀只是一种惯例,并非保证; 平台核心中也没有位置类型 (rules/reuse-verify-kind-availability.md)。 - 阅读相关规则 — 阅读
rules/naming-conventions.md
了解命名限制,
阅读 rules/attribute-defaults-and-types.md
了解属性种类和默认值,并阅读
rules/relationship-identifiers.md
了解双向关系设置。如果任何节点继承自通用类型,也要阅读
rules/relationship-peer-kind.md:
关系的对等类型由声明该关系的通用类型固定,任何实现者都无法缩小范围。
因此,决定哪些关系放在通用类型上是此时做出的一次性选择,
不能留到以后。你即将编写的每个
cardinality: one也都是写入时的数据约束,而不仅仅是结构定义; 因此应在选择时阅读 rules/relationship-cardinality-consequences.md, 不要等加载失败后再读。 - 构建架构 YAML — 从
$schema注释和version: "1.0"开始。先定义通用类型 (如有),再定义节点。按照第 3 步中的规则处理命名、显示和关系。 如果节点加入的通用类型已有实现者,应将该inherit_from行视为对已发布接口的更改:它会通过schema check,不会产生迁移,但仍会改变所有针对该通用类型的查询、 约束和使用方所能获取的结果。请参阅 rules/generic-membership-is-a-published-interface.md。 - 审查下游使用方 — 检查上文“为下游使用方设计”中的表格。
如果任何节点将成为构件或生成器目标,立即在其
inherit_from中添加CoreArtifactTarget, 参见 rules/extension-artifact-target.md。 稍后再添加会迫使已加载数据进行架构迁移。 - 配置显示属性 — 按照
rules/display-human-friendly-id.md
和 rules/display-order-weight.md
设置
human_friendly_id、display_label和order_weight。如果某个类型需要默认列表顺序,请按照 rules/display-order-by-scope.md 设置order_by——在通用类型上设置时,它只能解析该通用类型自身声明的字段。 - 格式化文件 — 提交前按规范顺序排列键,以保持差异精简。
如果你的
infrahubctl提供了infrahubctl schema format,就运行它 (离线运行,无需服务器);否则手动按顺序编写。请参阅 rules/format-schema-files.md。 - 在分支上验证并推出 — 运行
infrahubctl schema check,并按照 validation.md 和 rules/validation-common-errors.md 修复错误。然后在专用分支上应用更改,不要在默认分支上操作 (按惯例默认分支名为main,但可以重命名):运行infrahubctl branch create <name>→schema check --branch <name>→schema load --branch <name>;确认效果符合预期后,再通过提议的 更改进行合并。架构加载会立即对已加载数据运行迁移,因此在共享服务器上, 默认分支既不能预览,也无法逐步撤销;分支则可以。请参阅 rules/workflow-branch-first.md。 默认分支只适合本地的一次性临时实例。
值得了解的生产模式
七种常见模式——计算型 Jinja2 属性、 cascade 与 no-action 删除、菜单可见性、 分支无关的身份标识、制品目标、对象 模板和文件对象——记录在 examples.md 的开头。 在最终确定架构前,请先阅读这些内容;从头构建时很容易 忽略其中任何一种模式,而数据加载后再补上 代价高昂。
参考资料
- reference.md -- 节点、泛型、属性和关系的完整属性 表
- examples.md -- 生产代码仓库中的完整架构模式
- validation.md --
infrahubctl命令、迁移策略和 预验证清单 - ../infrahub-common/infrahub-yml-reference.md -- .infrahub.yml 项目配置
- ../infrahub-common/marketplace-reference.md
-- 复用已发布的市场架构和集合
(
infrahubctl marketplace get/list/search/show,气隙环境) - ../infrahub-common/rules/ -- 所有技能共用的规则 (git 集成、缓存)
- ../infrahub-common/rules/workflow-information-priority.md
-- 优先参考技能内容;遇到确实的知识缺口时,如何查阅
docs.infrahub.app(例如删除节点) - rules/ -- 按类别 前缀划分的单项规则