infrahub-converting-netbox-device-types について
同梱の Python スクリプトとマッピングプロファイルで、NetBox のデバイスタイプ YAML を再利用可能な Infrahub オブジェクトテンプレートに変換するスキルです。公開ライブラリや NetBox のエクスポートからモデルを取り込み、対象スキーマで表現できないデータも報告します。
主な機能
- 01デバイスタイプ YAML を Infrahub テンプレートへ変換
- 02モジュールタイプとコンポーネントポートに対応
- 03スキーマ別プロファイルによるフィールド対応付け
- 04NetBox インスタンスからデバイスタイプをエクスポート
- 05変換範囲レポートの生成
活用シーン
- 01ベンダーのデバイスモデルで Infrahub を初期化
- 02ラボトポロジー用のデバイスタイプを変換
- 03ライブラリやスキーマの変更後に再変換
- 04独自 Infrahub スキーマ向けのマッピング作成
インストール
コマンドをコピーしてターミナルで実行します。
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.mdexamples.mdextending-your-schema.mdgenerators-module-ports.mdreference.mdrules/_sections.mdcoverage-report-unmapped.mdformat-template-objects.mdmapping-fallback-sources.mdmapping-profile-driven.mdmapping-shared-relationships.mdnaming-template-names.mdoutput-load-order.mdworkflow-schema-prerequisites.mdworkflow-use-the-bundled-scripts.mdscripts/materialize_module_ports.gqlmaterialize_module_ports.pynetbox_export_device_types.pynetbox_to_infrahub_templates.pyscripts/mappings/_template.ymlschema-library-module-ports.ymlschema-library-modules.ymlschema-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 のファイル 1 つから、Infrahub の成果物が3 つ作成されます。これは、NetBox ではまとめて保持される情報を、Infrahub が分割するためです。
| NetBox | Infrahub | 理由 |
|---|---|---|
manufacturer: Cisco | OrganizationManufacturer オブジェクト | メーカーは独立したオブジェクトです |
model、part_number、u_height、weight | DcimDeviceType オブジェクト | テンプレートにはモデルデータがありません |
interfaces: とその他のコンポーネントリスト | TemplateDcimDevice + コンポーネントテンプレート | 再利用可能な設計図です |
テンプレートはデバイスタイプにリンクするため、テンプレートからデバイスを作成すると、モデルも自動的に関連付けられます。
モジュールタイプは 2 つ目の入力ファミリーです。ラインカード、PSU、トランシーバーなどが、兄弟ディレクトリの module-types/ に含まれます。slug を持たないため、コンバーターはこの特徴で 2 つを区別でき、混在するツリーも一度の処理で変換できます。これらも同じ分割方式(モジュールタイプオブジェクトと、任意のモジュールテンプレート)に従い、04_module_types.yml / 05_module_templates.yml に出力されます。ここでできることを過度に約束する前に、extending-your-schema.md をお読みください。モジュールのポートはモジュールテンプレートにのみ変換されます。また、標準の schema-library の DcimModule はモジュールテンプレートを生成しません。schema-library-modules.yml ではスキップされたものとして報告されます。DcimModule に generate_template: true を設定すると、schema-library-module-ports.yml によってポートが取り込まれます。
モジュールポート名には NetBox の {module} トークンが含まれますが、変換時には解決できません。ベイの位置は、モジュールが取り付けられて初めて判明するためです。ポートをモジュールテンプレート上の DcimModulePort 宣言としてインポートすると、同梱のジェネレーターが取り付けられたモジュールごとにトークンを解決し、インターフェースポートから実際のデバイスインターフェースを作成します。コンソールポートにはスキーマでコンソールインターフェースの種類が必要で、電源ポートは宣言のままになります。generators-module-ports.md をご覧ください。
このワークフローで予想外のことが起きる原因のほとんどは、次の 3 つの事実にあります。前提とせず、説明してください。
Template*の種類は生成されるもので、記述するものではありません。 ノードにgenerate_template: trueを設定すると生成されます。設定しなければ存在しません。- コンポーネントテンプレートは
Componentリレーションシップからのみ作成されます。Attributeリレーションシップは、実際のオブジェクトを参照し続けます。 - モデルデータはテンプレートではなく、デバイスタイプに保持されます。 そのため、ファイルは 3 つになり、この順序で扱います。
Infrahub のデータモデルを初めて知る方、または誰かに説明する方は、concepts.md で Infrahub のドキュメントへのリンクとともに解説しています。
ルールのカテゴリ
| 優先度 | カテゴリ | 接頭辞 | 説明 |
|---|---|---|---|
| CRITICAL | ワークフロー | workflow- | まず generate_template を有効にする必要があります。同梱スクリプトが処理を行います |
| CRITICAL | マッピング | mapping- | 名前はスキーマから取得し、推測しません。競合するフィールドでは優先順位を宣言します |
| CRITICAL | 形式 | format- | エンベロープ、Template<Kind>、ネストされたコンポーネント |
| HIGH | 命名 | naming- | スラッグベース、親の名前空間付き、一意 |
| HIGH | カバレッジ | coverage- | 変換されなかったものを報告します |
| MEDIUM | 出力 | output- | 3 つのファイル、読み込み順序、ブランチ優先 |
完全なインデックス:rules/_sections.md。
ワークフロー
1. スキーマでテンプレートが生成されることを確認する
Template* 種別が存在するのは、ノードで
generate_template: true が宣言されている場合のみです。
どちらかと決めつけず、対象のスキーマを確認してください。変換を実行しても何も読み込まれない原因として、これが最もよくあります。
OpsMill schema-library では、バージョンによって異なります。v2 以降では
base/dcim.yml の DcimDevice で有効になっていますが、v2 より前ではこの行は
コメントアウトされた状態で提供されていました。カスタムスキーマでは通常、追加する必要があります。
こちらをお読みください。
有効になっていない場合は、黙って変更せず、その変更について説明してください。このフラグを設定すると、
TemplateDcimDevice と、各 Component リレーションシップのコンポーネントテンプレートが生成されます。これは追加のみの変更であり、種別を表示するにはスキーマを再読み込みする必要があります。
有効化するとユーザーの信頼できる情報源に手を加えることになるため、判断はユーザーに委ねてください。1 行の差分を提示し、決定してもらいましょう。
ドキュメント: オブジェクトテンプレートの概要 · スキーマの作成と読み込み
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 を読みながら、種別ごと、属性ごとに内容を記入してください。
こちらとreference.mdで、両側のフィールドをすべて確認してください。1 つの Infrahub 属性に対して 2 つの NetBox フィールドが候補となる場合(description と comments、インターフェースの label と description など)、どちらか一方を選んでもう一方を失うのではなく、fallback で優先順位を指定してください。こちらを参照してください。
不足していると結論づける前に、その不足を補えるノードがすでにないか確認してください。 コンソールポートはインターフェースの汎用種別を継承するノードとしてモデル化されていることが多く、その場合はデバイスの既存の interfaces
リレーションシップを利用できるため、スキーマ変更はまったく不要で、プロファイルへのエントリーだけで済みます。2 つのリストが 1 つのリレーションシップを共有する場合は、
rules/mapping-shared-relationships.md をお読みください。ここを誤ると、より大きなリストが黙って破棄されます。
extending-your-schema.md には、schema-library と infrahub-demo-dc がすでに提供している内容が記載されています。
3. 入力を取得する
デバイスの型がどこにあるかに応じて、2 つのソースがあります。
稼働中の 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 を指定すると、デバイスが 1 台以上あるデバイス型と、モジュールが 1 個以上あるモジュール型だけが残ります。実際のインスタンスでは、カタログ全体よりもはるかに小さく、関連性の高い集合になります。
正常に取り込めなかった項目はすべて報告されます。ライブラリ形式では保持できない 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 を除外してください。
コンバーターはファイル、ディレクトリ(再帰的に走査)、およびグロブを受け付けます。
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 を持つデバイス型が 2 つあると、コンバーターは処理を拒否し、該当するペアをすべて一覧表示します。テンプレートはモデル名でデバイス型を指定するため、両方を読み込むと、一方が他方をエラーなしで上書きします。公開ライブラリには、複数のベンダー間で共有されているものが少数あります。入力から同じモデル名のものを 1 つだけ残してください。
生成されたファイルを書き込んだり手作業で編集したりする前に、rules/format-template-objects.md を読んでください。エンベロープ、Template<Kind> の分割、{kind, data} のコンポーネントラッパーが、出力を読み込み可能にする要素です。また、コンポーネント名は親の名前空間に含めない限りデバイス型間で衝突するため、rules/naming-template-names.md も読んでください。
5. カバレッジレポートを読み、失われる内容を説明し、修正方法を提示する
一般的なスキーマでは、各 NetBox ファイルの大部分を 格納する場所がありません。レポートを開き、回答では次の点を示します。
- 失われる内容のうち、最も大きなものを挙げる — どのコンポーネントリストと どのフィールドが対象かを、件数とともに示します。 レポートがあると伝えるだけでは不十分です。
- スキーマに格納できなかった理由を説明する。
「
console-portsはスキップされました」では、 コンポーネントテンプレートがComponentの関係からのみ生成されることを 知らない人には、次に何をすればよいか分かりません。 理由を説明してください。 - 具体的な修正方法を提示する。 ドロップされたフィールドは1つの 属性を追加し、スキップされたリストはノードと Component/Parent のペアを追加します。どちらも追加による対応です。 extending-your-schema.mdには、 ケースごとに動作する YAML があり、スキーマライブラリの拡張機能で すでに対応できるものも記載されています。
提案はしますが、相手のスキーマを一方的に書き換えてはいけません。 これは相手の信頼できる情報源に対する移行作業です。
rules/coverage-report-unmapped.md を読んでください。
該当する場合、名前を挙げて指摘する価値のあるケースが2つあります。
- モジュラーシャーシ — ポートがモジュールベイにあるため、
公開済みのデバイスタイプ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 |
| テンプレートとプロファイルの併用 | https://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 |
| リレーションシップ(コンポーネントと属性) | https://docs.infrahub.app/schema/relationships |
| ジェネリックと継承 | https://docs.infrahub.app/schema/generics-and-inheritance |
| フォークせずにスキーマを拡張する | https://docs.infrahub.app/schema/extensions |
| スキーマの読み込み | https://docs.infrahub.app/schema/create-and-load |
| スキーマのマイグレーションとそのリスク | https://docs.infrahub.app/schema/migration |
| スキーマプロパティのリファレンス | https://docs.infrahub.app/reference/schema/node |
| プロファイルとテンプレートの比較 | https://docs.infrahub.app/profiles/overview |
| ゼロからのスキーマ作成(チュートリアル) | https://docs.infrahub.app/academy/tutorials/build-your-first-schema |
ジェネレーター(インストール後の{module}の解決) | https://docs.infrahub.app/generators/overview |