YANGを使いこなす! (5) モデルを拡張してみよう

# 今回やること
[YANGを使いこなす! Index](https://qiita.com/corestate55/items/70defe12f20f1e282fc0)

YANG チュートリアル [Augment · mbj4668/pyang Wiki](https://github.com/mbj4668/pyang/wiki/Augment) の話です。これは内容ざっと紹介するくらいですね。でもデータモデルの拡張 (augment) は YANG によるモデル定義ではよく使われる機能なので知っておく必要があります。

# モデルの拡張

YANG 云々の話の前に、先にこれまで使っていた Turing Machine のモデルを再掲。
![Turing Machine Model](https://qiita-image-store.s3.amazonaws.com/0/154230/aab0be05-a986-7f19-a568-749187b89e3b.png)

これをこういうモデルに拡張しよう、という話をしています。
![2-Tape Turing Machine Model](https://qiita-image-store.s3.amazonaws.com/0/154230/65ecafe3-e925-742f-cc18-f41355dce92a.png)


# YANG モデルの拡張

拡張されたモデルはこれ → [pyang/second\-tape\.yang at master · mbj4668/pyang](https://github.com/mbj4668/pyang/blob/master/doc/tutorial/examples/second-tape.yang) です。見るとわかる通り

* 従来の Turing Machine のモデルを inport する
* `augment` で拡張したい部分(path)を指定する
* 新しく leaf や container を足す

ということをやっています。新しい 2-Tape Turing Machine のモデルを Tree 形式で表示してみましょう。

```
corestate55@ytut:~/yang-tutorial/data$ pyang -f tree  second-tape.yang turing-machine.yang
module: turing-machine
  +--rw turing-machine
     +--ro state                  state-index
     +--ro head-position          cell-index
     +--ro tape
     |  +--ro cell* [coord]
     |     +--ro coord     cell-index
     |     +--ro symbol?   tape-symbol
     +--rw transition-function
     |  +--rw delta* [label]
     |     +--rw label     string
     |     +--rw input
     |     |  +--rw state          state-index
     |     |  +--rw symbol         tape-symbol
     |     |  +--rw t2:symbol-2?   tm:tape-symbol         <= 拡張
     |     +--rw output
     |        +--rw state?            state-index
     |        +--rw symbol?           tape-symbol
     |        +--rw head-move?        head-dir
     |        +--rw t2:symbol-2?      tm:tape-symbol      <= 拡張
     |        +--rw t2:head-move-2?   tm:head-dir         <= 拡張
     +--ro t2:head-position-2?    tm:cell-index           <= 拡張
     +--ro t2:tape-2                                      <= 拡張
        +--ro t2:cell* [coord]                            <= 拡張
           +--ro t2:coord     cell-index                  <= 拡張
           +--ro t2:symbol?   tape-symbol                 <= 拡張

  rpcs:
    +---x initialize
    |  +---w input
    |     +---w tape-content?        string
    |     +---w t2:tape-content-2?   string               <= 拡張
    +---x run

  notifications:
    +---n halted
       +--ro state    state-index
```

2-Tape Turing Machine の全体のモデルは上の通りになります。上の出力の中に、namespace `t2` になっているところが `second-tape.yang` で拡張 (augment) した部分ですね (ぱっとわかりにくいので「拡張」で書き込んであります)。今回の場合、最初に与えられるものはこの YANG モデルなので、上に掲載したモデル図はここから描きおこしたものになります。つまり、拡張された YANG データモデルから、操作対象としてどういうモデルを想定しているのかを読み解く必要がある。

* かわらないもの
    * Tape, Cell などのコンポーネント (type) はかわらない
    * State はふえない
* かわるもの
    * Tape, Tape Head がふえる
    * それにともなって、状態遷移表へのインプット・アウトプットの項目が増える
    * 初期状態で与えるテープデータが 2 本分になる

というのをもとに図を書くとああなると。

# モデルをどう読むか

ここからはちょっと主観的・個人的意見の話になってくるのですが…。

「操作対象(実体)」と「どういうモデルになっているか」を相互に対応づけて考えられる必要があります。データモデル定義だけ見て、自分が何に対して・どういう操作をしようとしているのか、それが「適切な操作・適切なデータかどうか」判断できるでしょうか? という問題ですね。もともと「ネットワーク機器に対する操作」が念頭にあるわけで、これを取り上げましょうか。実際に自分が業務の中でデバイスを使う際にはどういったことを考えているのかちょっと分解してみましょう。

* 自分が作りたい(操作したい)システム全体/ネットワーク全体がどう振る舞ってほしいのか
* そのために、個々のデバイスでどういう機能・ふるまいを要求しているのか
* いま操作対象とする個々のデバイスに望んだ機能・ふるまいをしてもらうために、どういう操作で、どんなデータを与えるのか
    * 狙った動きをしていることをどうやって確認するのか

……という話を考えるはずです。YANG データモデルの出番は、この中のうち、デバイスに対して行える操作とそのときに必要なデータ形式を定義する、というだけなんですよね。形式を定義するものであって、自分がやりたいことに対して「適切」な操作/データかどうか、という話ではありません。道具立てだけです。その道具の使い方を「判断」するためには、データモデル定義で想定されている「操作対象のモデル」は何か、操作対象がどう表現されているのか、自分がやりたいことに対してそのモデルをどう操作したら良いか、という理解や解釈が必要になります。

ぐだぐだ書いていますが、要するに、その「モデルの理解や解釈」が難しいよね、ということです。最初にチュートリアルの全体像って出した図の、この実体とモデルの間に引いた矢印点線・実体との関係性のところ。

![Model--Target Mapping](https://qiita-image-store.s3.amazonaws.com/0/154230/fb763248-e0d2-bd50-b82d-a1563c9542fd.png)

ネットワークエンジニアであれば、そのネットワーク機器がなんでこういうモデルを定義しているのかを理解・解釈できるかどうか、という話が重要になります。(と、書いてみて思ったけど別にこれ YANG が云々とか関係なくて、従来の CLI 操作の時だって同じだね……。) Turing Machine の話も、自分は「そもそも Turing Machine って何だっけ」から入らないとよくわからなかったので、操作対象それ自体に対する理解が必要だなあという話を最後に改めて書いて [(2) 動かしてみる](https://qiita.com/corestate55/items/d5c1e1b6457d2aa53217) の冒頭へつなげておきます。

## オマケ: YANG to UML

モデルの話が出たのでついでに。pyang で [PlantUML](http://plantuml.com/) 用の UML 図を出すこともできます。YANG ファイルからモデルを考える場合こうしたアプローチも役に立つかもしれません。

### PlantUML のインストール

```
corestate55@ytut:~$ sudo apt install plantuml
```

### Turing Machine の クラス図

```
corestate55@ytut:~/yang-tutorial/data$ pyang --format=uml -o turing-machine.puml turing-machine.yang 
corestate55@ytut:~/yang-tutorial/data$ plantuml turing-machine.puml
```
![UML Class Diagram of Turing Machine](https://qiita-image-store.s3.amazonaws.com/0/154230/4ed65a00-9884-111c-aeef-fbb951b198bd.png)

### 2-Tape Turing Machine のクラス図

```
corestate55@ytut:~/yang-tutorial/data$ pyang --format=uml -o second-tape.puml second-tape.yang turing-machine.yang
corestate55@ytut:~/yang-tutorial/data$ plantuml second-tape.puml
```
![UML Class Diagram of 2-Tape Turing Machine](https://qiita-image-store.s3.amazonaws.com/0/154230/759dd7f4-19f4-ed66-d898-f1f4de80136b.png)