【ネットワーク入門】YANGモジュール設定の基本３選

## 1. YANGノード

### 1-1. Leaf Nodes

  リーフノードは単一の値を持つノードです。
  例えば「ホスト名」や「IPアドレス」など、1つの情報だけを格納します。

  ```.yang
  leaf host-name {
    type string;
    description "このシステムのホスト名";
  }
  ```

  ここでは`host-name`という名前のリーフノードがあり、値は文字列（string）です。

---

### 1-2. Leaf-list Nodes

  リーフリストは同じ型の値が複数並ぶリスト（配列）です。

  ```.yang
  leaf-list domain-search {
    type string;
    description "検索するドメイン名のリスト";
  }
  ```

  これは「検索するドメイン名」などを複数持つことができます。

  ```.xml
  <domain-search>high.example.com</domain-search>
  <domain-search>low.example.com</domain-search>
  <domain-search>everywhere.example.com</domain-search>
  ```

  この例では「3つのドメイン名がリストとして格納されている」ことを表します。

---

### 1-3. Container Nodes

  コンテナノードは複数のノードをまとめて階層的に管理するためのノードです。
  中に複数の子ノード（leafやleaf-list、listなど）を持てます。
  
  ```.yang
  container system {
    container login {
      leaf message {
        type string;
        description "ログインメッセージ";
      }
    }
  }
  ```

  `system`というコンテナの中に、さらに`login`というコンテナがあり、その中に`message`というリーフノードが入っています。

  ```.xml
  <system>
    <login>
      <message>Good morning, Dave</message>
    </login>
  </system>
  ```

  この例では階層構造で情報を整理しています。


---

### 1-4. List Nodes

  Listノードは複数のレコード（項目）を持つことができ、それぞれのレコードはキーで一意に識別されます。

  ```.yang
  list user {
    key "name";
    leaf name { type string; }
    leaf full-name { type string; }
    leaf class { type string; }
  }
  ```

  ここでは`user`リストがあり、`name`をキーとして複数のユーザー情報を管理しています。

  ```.xml
  <user>
    <name>glocks</name>
    <full-name>Goldie Locks</full-name>
    <class>intruder</class>
  </user>
  <user>
    <name>snowey</name>
    <full-name>Snow White</full-name>
    <class>free-loader</class>
  </user>
  ```

  この例では`user`リストに2つのユーザーが登録されています。

**補足**
 * `key`はリスト内で一意の値を持つフィールド。
 * リストの各エントリーは独立したノードセット。

## 2. YANGの基本データ型

| 型名            | 説明                | 具体例                                 |
| ------------- | ----------------- | ----------------------------------- |
| `string`      | 文字列               | `"hello"`                |
| `boolean`     | 真偽値（true / false） | `true`, `false`                     |
| `int8`        | 8ビット符号付き整数        | `-128` 〜 `127`                      |
| `int16`       | 16ビット符号付き整数       | `-32768` 〜 `32767`                  |
| `int32`       | 32ビット符号付き整数       | `-2,147,483,648` 〜 `2,147,483,647`  |
| `int64`       | 64ビット符号付き整数       | 大きな整数値                              |
| `uint8`       | 8ビット符号なし整数        | `0` 〜 `255`                         |
| `uint16`      | 16ビット符号なし整数       | `0` 〜 `65535`                       |
| `uint32`      | 32ビット符号なし整数       | `0` 〜 `4,294,967,295`               |
| `uint64`      | 64ビット符号なし整数       | 大きな正の整数                             |
| `decimal64`   | 固定小数点数（精度指定可）     | `3.14159`                           |
| `enumeration` | 列挙型（指定した文字列から選択）  | `enum { "up"; "down"; "testing"; }` |

---

### 2-1. YANGの特殊データ型

基本型だけでなく、YANGには特殊な用途に使うデータ型もあります。

| 型名                    | 説明             |                                 
| --------------------- | ----------------- |
| `leafref`             | 他のノードを参照する型     |
| `identityref`         | 定義済みのidentity値を参照 |
| `instance-identifier` | YANGノードのパスを表す     | 
| `bits`                | ビットの集合            |
| `union`               | 複数の型のどれかを許可   |

---

### 2-2. 特殊フォーマット型の特徴

YANGではさらに、値が「あるかないか」だけ判定する型やバイナリデータも扱えます。

| 型名       | 説明               | 例                       |
| -------- | ---------------- | ----------------------- |
| `binary` | バイナリデータ          | バイナリblob                |
| `empty`  | 値がなく、存在/非存在のみで判定 | オプションのフラグのように使う         |
| `enum`   | 列挙型（選択肢）         | `up`, `down`, `testing` |

---

### 2-3.データ型に制約をつける

YANGではデータ型に対して「制約」をつけて、より厳密にルールを決められます。

* **pattern**
  正規表現で文字列の形式を制限。
  例：IPv4アドレスの形式チェック
* **range**
  数値の範囲を指定。
  例：`range "1..65535"`
* **length**
  文字列の長さを制限。
  例：`length "1..255"`
* **mandatory**
  値の必須指定。

## 3. 整合性制約

### 3-1. when

`when`は、「ある条件が満たされたときだけ、その設定項目が使える」というルールを作る仕組みです。

```.yang
leaf a {
  type boolean;
}
leaf b {
  type string;
  when "../a = 'true'";
}
```

`b` の設定は `a` が `true`（オン）のときだけ「存在できる」。
`a` が `false`（オフ）になると、`b` の設定は自動的に消されます。

---

### 3-2. must

`must` は「必ず守らなければならない条件」を書きます。

```.yang
container interface {
  leaf ifType {
    type enumeration {
      enum ethernet;
      enum atm;
    }
  }
  leaf ifMTU {
    type uint32;
  }
  must "ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)" {
    error-message "An ethernet MTU must be 1500";
  }
}
```

この条件は、「`ifType` が `ethernet` の場合は必ず `ifMTU` が1500であること」を強制しています。

**補足**

* `must`の中はXPath形式の論理式で条件を書く
* `error-message`は違反時に表示されるメッセージ

---
### 3-3. unique

`unique` は「複数の設定の中で特定の値の組み合わせが重複してはいけない」というルールです。

```.yang
list server {
  key "name";
  unique "ip port";

  leaf name {
    type string;
  }
  leaf ip {
    type inet:ip-address;
  }
  leaf port {
    type inet:port-number;
  }
}
```

この例では、「IPアドレスとポート番号の組み合わせが重複しない」ことを保証します。

---

### 3-4. leafref

`leafref` は「参照先が必ず存在すること」を保証します。

```.yang
leaf friend-name {
  type leafref {
    path "/contacts/name";
  }
}
```

このようにすると、`friend-name` に設定できる値は必ず `/contacts/name` に存在する値だけになります。

## 参考文献

・[YANG公式仕様書（IETF RFC 7950）](https://tools.ietf.org/html/rfc7950)