NW図 as Code(6) drawthe.netを試す
drawthe.net
drawthe.netはこちらで公開されているツールです。
ネットワーク図を描くことにフォーカスして作られているみたいです。
ここのSpine-Leaf構成とか、ここのNTPトポロジとか見た目がすごく綺麗です。
結果
作成した物理ネットワーク構成図を示します。
図の元になったコードはこちらです。drawthe.netのインプットデータはYAMLです。
diagram:
fill: "white"
gridLines: false
rows: 4
columns: 4
title:
color: black
text: on-premises datacenter example
subText: ""
version: 0.1
author: takai404
logoUrl: null
# Set defaults for icons, groups, connections
iconDefaults: &iconDefaults
color: black
fill: "none"
stroke: "none"
connectionDefaults: &connectionDefaults
color: "red"
stroke: "orange"
strokeWidth: 3
icons:
router0:
<<: *iconDefaults
iconFamily: cisco
icon: router
x: 1
y: 3
router1:
<<: *iconDefaults
iconFamily: cisco
icon: router
x: "+1"
l3sw0:
<<: *iconDefaults
iconFamily: cisco
icon: layer3switch
x: "-1"
y: "-1"
firewall0:
<<: *iconDefaults
iconFamily: cisco
icon: firewall
x: "-1"
lb0:
<<: *iconDefaults
iconFamily: cisco
icon: localdirector
y: "-1"
l3sw1:
<<: *iconDefaults
iconFamily: cisco
icon: layer3switch
x: "+2"
y: "+1"
firewall1:
<<: *iconDefaults
iconFamily: cisco
icon: firewall
x: "+1"
lb1:
<<: *iconDefaults
iconFamily: cisco
icon: localdirector
y: "-1"
l2sw0:
<<: *iconDefaults
iconFamily: cisco
icon: workgroupswitch
x: "-2"
l2sw1:
<<: *iconDefaults
iconFamily: cisco
icon: workgroupswitch
x: "+1"
host1:
<<: *iconDefaults
iconFamily: cisco
icon: fileserver
x: "-1"
y: "-1"
host2:
<<: *iconDefaults
iconFamily: cisco
icon: fileserver
x: "+1"
connections:
- { <<: *connectionDefaults, endpoints: ["router0:e0", "router1:e0"] }
- { <<: *connectionDefaults, endpoints: ["router0:e2", "l3sw0:e2"] }
- { <<: *connectionDefaults, endpoints: ["router1:e2", "l3sw1:e2"] }
- { <<: *connectionDefaults, endpoints: ["l3sw0:e0,e1", "l3sw1:e0,e1"], strokeWidth: 8 }
- { <<: *connectionDefaults, endpoints: ["l3sw0:e3", "firewall0:e0"] }
- { <<: *connectionDefaults, endpoints: ["l3sw1:e3", "firewall1:e0"] }
- { <<: *connectionDefaults, endpoints: ["l3sw0:e4", "lb0:e0"] }
- { <<: *connectionDefaults, endpoints: ["l3sw1:e4", "lb1:e0"] }
- { <<: *connectionDefaults, endpoints: ["l2sw0:e0,e1", "l2sw1:e0,e1"], strokeWidth: 8 }
- { <<: *connectionDefaults, endpoints: ["l3sw0:e5", "l2sw0:e2"] }
- { <<: *connectionDefaults, endpoints: ["l3sw1:e5", "l2sw1:e2"] }
- { <<: *connectionDefaults, endpoints: ["l2sw0:e3", "host1:eth0"] }
- { <<: *connectionDefaults, endpoints: ["l2sw0:e4", "host2:eth0"] }
- { <<: *connectionDefaults, endpoints: ["l2sw1:e3", "host1:eth1"] }
- { <<: *connectionDefaults, endpoints: ["l2sw1:e4", "host2:eth1"] }
利用方法
公開されているファイル群をgit cloneすると使えるようになるみたいなのですが、オンラインで編集できるサイトが提供されているのでこちらを利用させてもらいましょう。
drawthe.netの描き方
drawthe.netはPlauntUMLやGraphvizとは違って、以下の特徴があります。
- アイコンを置いて、アイコン間に線を引く
- アイコンの配置場所はX座標、Y座標で自分で指定する
アイコンの配置
http://go.drawthe.net/ の右上のiconsボタンを押すと、利用できるアイコンの一覧が見れます。
Ciscoアイコンはこんな感じです。
左ペインの文字列を全部消して、以下を入力してCtrl+Enterを押します。
icons:
router0:
color: black
fill: "none"
stroke: "none"
iconFamily: cisco
icon: router
x: 1
y: 3
右ペインが以下のように変わります。
- 描画エリアはデフォルトでは10マス × 10マスのオレンジ背景です。
- この描画エリアにciscoのrouterアイコンを座標(X, Y) = (1, 3)に置きます。
- アイコンには"router0"というラベルを付けます。色はblack。
- アイコンの周りの枠なし(stroke: "none")、色塗りなし(fill: "none")
アイコンの座標指定
アイコンをもう一個追加します。以下の通り書き足してCtrl+Enterです。
icons:
router0:
color: black
fill: "none"
stroke: "none"
iconFamily: cisco
icon: router
x: 1
y: 3
router1:
color: black
fill: "none"
stroke: "none"
iconFamily: cisco
icon: router
x: "+1"
router0の右にrouter1が追加されているはずです。
router1のX座標は「x: "+1"」としました。これは「さっきのアイコンのX座標に1を加算しろ」という意味です。
router1のY座標は指定していません。これは「さっきのアイコンのY座標と同じ」という意味です。
「x: "+1"」の部分を「x: +1」とすると期待通りの動きをしません。おそらくYAMLパーサがxを整数と判断して「x: 1」と同じ意味(相対座標ではなくて絶対座標)と解釈しているのでしょう。
drawthe.netのオンラインエディタを使う上での注意点は文法エラーがあったときにエラーメッセージが出ないことです。右ペインの図も変化しないので、エラーが起きているのか自分の書き足したコードでは図に変化がないのかが分からないです。
とりあえずちょっとコードを編集したら即座にCtrl+Enterを押しまくって図に反映されるか確認しましょう。
drawthe.netの問題ではないのですが、YAMLはスペース文字が1個多かったり少なかったりするだけで文法エラーになります。
なんかおかしいなと思ったらYAMLの文法チェッカーにかけてみましょう。
YAMLの短縮
このままほかのアイコンを追加していってもいいのですが、colorとかiconFamilyとか同じことをコピペとは言えども何度も書くと面倒くさいし、行が増えて見づらいですよね。
YAMLにはアンカーとエイリアスという仕様があり、繰り返し要素にアンカーで名前を付けて、後からエイリアスで参照することができます。
icons:
router0:
color: black
fill: "none"
stroke: "none"
iconFamily: cisco
icon: router
x: 1
y: 3
router1:
color: black
fill: "none"
stroke: "none"
iconFamily: cisco
icon: router
x: "+1"
上記のYAMLと下記のYAMLは同じ意味です。
iconDefaults: &iconDefaults
color: black
fill: "none"
stroke: "none"
icons:
router0:
<<: *iconDefaults
iconFamily: cisco
icon: router
x: 1
y: 3
router1:
<<: *iconDefaults
iconFamily: cisco
icon: router
x: "+1"
color, fill, strokeというキーを持つ「iconDefaults」という名前のマップを定義しています。
「&iconDefaults」でこのマップに「iconDefaults」という名前のアンカーを付けています。
router0, router1では「<<」でマップをマージしています。マージ対象のマップは「*iconDefaults」です。「*iconDefaults」はエイリアス参照で、「iconDefaults」という名前のアンカーを参照する、という意味です。
慣れてくると同じ「iconDefaults」という名前を付けた方が分かりやすいのですが、名前は何でもいいです。以下の書き方の方が理解しやすいかもしれないです。TEKITO_NA_NAMAE(適当な名前)は誰にも使われない名前なので何でもいいです。&KURIKAESHIで繰り返し箇所を定義、*KURIKAESHIでそれを参照です。
TEKITO_NA_NAMAE: &KURIKAESHI
color: black
fill: "none"
stroke: "none"
icons:
router0:
<<: *KURIKAESHI
iconFamily: cisco
icon: router
x: 1
y: 3
router1:
<<: *KURIKAESHI
iconFamily: cisco
icon: router
x: "+1"
背景、タイトルの指定
背景がオレンジだと目がチカチカするので、白にします。今回の図は10マスも要らないので4 × 4にしました。
あと、図を描く上で本質的ではないのですが、title(のtext)を定義しないと、オンラインエディタで画像のダウンロードができないので、titleも決めてあげます。
l3sw0アイコンも配置しました。router1の座標と比べてX座標が"-1"(1マス左)、Y座標が"-1"(1マス下)です。
diagram:
fill: "white"
rows: 4
columns: 4
title:
color: black
text: on-premises datacenter example
subText: ""
version: 0.1
author: takai404
logoUrl: null
iconDefaults: &iconDefaults
color: black
fill: "none"
stroke: "none"
icons:
router0:
<<: *iconDefaults
iconFamily: cisco
icon: router
x: 1
y: 3
router1:
<<: *iconDefaults
iconFamily: cisco
icon: router
x: "+1"
l3sw0:
<<: *iconDefaults
iconFamily: cisco
icon: layer3switch
x: "-1"
y: "-1"
ケーブル
以下を追加します。
connectionDefaults: &connectionDefaults
color: "red"
stroke: "orange"
strokeWidth: 3
connections:
- { <<: *connectionDefaults, endpoints: ["router0:e0", "router1:e0"] }
- { <<: *connectionDefaults, endpoints: ["router0:e2", "l3sw0:e2"] }
「endpoints: ["router0", "router1"]」でrouter0とrouter1の間にケーブルを引くことができます。
「endpoints: ["router0:e0", "router1:e0"]」とすることで、このケーブルの両端に「e0」、「e0」というラベルを付けることができます。
{}と[]はマップとシーケンスを1行で書くYAMLの記法です。以下と同じ意味です。
connections:
-
<<: *connectionDefaults
endpoints:
- "router0:e0"
- "router1:e0"
-
<<: *connectionDefaults
endpoints:
- "router0:e2"
- "l3sw0:e2"
このままアイコンとケーブルを追加していくと冒頭の「結果」で示したコードとネットワーク図が出来上がります。
制限
アイコン間にケーブルを2本引くことはできないようです。EtherChannelをうまく表現できないですね。
ケーブルを太くしてラベルに["l3sw0:e0,e1", "l3sw1:e0,e1"]と書くことでそれっぽく表現しています。
Discussion