Cisco IOS-XE RESTCONFについて：YANGモデルからセキュリティまで


## 📚 はじめに

ネットワーク管理の効率化やヒューマンエラーの削減を目指していませんか？  
本記事では、RESTCONFを活用してCisco IOS-XEデバイスの設定を自動化する方法を解説します。この記事を読むことで、RESTCONFの基礎からセキュリティ強化、実践的なユースケースまで体系的に学べます。

---

### 🎯 **この記事で学べること**

1. RESTCONFとYANGモデルの基本概念  
2. 実践的なPythonコードによるRESTCONF操作  
3. セキュアな設定とエラーハンドリングの実装方法  
4. トラブルシューティングと自動復旧の手法  

---

## 🔍 **RESTCONFとYANGモデルの基礎**

### **RESTCONFとは？**

RESTCONFは、ネットワーク機器の設定や状態をHTTPで管理するためのプロトコルです。  
その特徴は以下の通りです：

| 特徴                         | 説明                                     |
|------------------------------|------------------------------------------|
| **HTTPベース**               | GET/POST/PUT/DELETEで操作可能            |
| **標準化されたデータモデル** | YANGを用いてデータを構造化              |
| **JSON/XML形式のデータ**     | 機械的に読み書きしやすい形式でデータを送受信 |

---

### **RESTCONFとYANGの関係**

RESTCONFは、YANGで定義されたデータモデルを操作するためのAPIです。  
以下は、GigabitEthernet1インターフェースの説明を取得する例です：

```bash
curl -X GET -H "Accept: application/yang-data+json" \
    -u admin:password \
    https://192.168.1.1:443/restconf/data/Cisco-IOS-XE-native:native/interface/GigabitEthernet1
```

この操作により、YANGモデルに基づいた設定がJSON形式で返されます。

---

### **YANGモデルの基本構造**

YANGは階層構造を持つデータモデリング言語です。以下の要素を使用します：

| 要素          | 説明                   |
|---------------|------------------------|
| **container** | 複数の要素をまとめる   |
| **list**      | 繰り返し可能な要素     |
| **leaf**      | 単一の値を表す要素     |
| **leaf-list** | リスト形式の単一値群   |

以下はインターフェースのYANGモデル例です：

```yang
module cisco-interface {
    container interfaces {
        list interface {
            key "name";
            leaf name {
                type string;
                description "インターフェース名";
            }
            leaf description {
                type string;
                description "インターフェースの説明";
            }
        }
    }
}
```

RESTCONFを使えば、このモデルを操作して設定を取得・更新できます。

---

## ⚙️ **PythonでRESTCONFを実装**

以下は、Pythonを用いてRESTCONFでCisco IOS-XEデバイスを操作する方法です。

### **RESTCONFクライアントの実装**

#### コード例

```python
import requests
from requests.auth import HTTPBasicAuth
import logging

# ロギング設定
logging.basicConfig(level=logging.INFO)

class RestconfClient:
    def __init__(self, host: str, username: str, password: str, port: int = 443):
        self.base_url = f"https://{host}:{port}/restconf"
        self.auth = HTTPBasicAuth(username, password)
        self.headers = {
            "Accept": "application/yang-data+json",
            "Content-Type": "application/yang-data+json"
        }
        self.session = requests.Session()
        self.session.auth = self.auth
        self.session.headers.update(self.headers)
        self.session.verify = False  # 本番環境では適切な証明書を使用

    def get_interface(self, interface_name: str):
        """インターフェース設定を取得"""
        url = f"{self.base_url}/data/Cisco-IOS-XE-native:native/interface/{interface_name}"
        response = self.session.get(url)
        response.raise_for_status()
        return response.json()

    def update_interface(self, interface_name: str, config: dict):
        """インターフェース設定を更新"""
        url = f"{self.base_url}/data/Cisco-IOS-XE-native:native/interface/{interface_name}"
        response = self.session.patch(url, json=config)
        response.raise_for_status()
        logging.info(f"インターフェース {interface_name} の設定を更新しました")
```

---

### **コードの使用例**

```python
client = RestconfClient("192.168.1.1", "admin", "password")

# 設定を取得
current_config = client.get_interface("GigabitEthernet1")
print("現在の設定:", current_config)

# 設定を更新
new_config = {
    "Cisco-IOS-XE-native:GigabitEthernet1": {
        "description": "Updated description"
    }
}
client.update_interface("GigabitEthernet1", new_config)
```

---

## 🔒 **セキュリティ強化の実践**

### **資格情報の安全な管理**

資格情報は環境変数や`.env`ファイルで管理しましょう。

#### 環境変数を使用する例：
```python
import os

USERNAME = os.getenv("RESTCONF_USER", "default_user")
PASSWORD = os.getenv("RESTCONF_PASS", "default_pass")
```

#### `.env`ファイルを活用する例：
- **`.env`ファイルの例：**
  ```
  RESTCONF_USER=admin
  RESTCONF_PASS=securepassword
  ```
- **Pythonコードで読み込む：**
  ```python
  from dotenv import load_dotenv
  load_dotenv()
  ```

---

### **証明書の検証**

本番環境では信頼できるCAの証明書を使いましょう。

```python
session.verify = "/etc/ssl/certs/ca-bundle.crt"  # 信頼できるCAの証明書
```

---

## 📊 **実践的なユースケース**

### **複数デバイスへの一括設定変更**

以下のクラスで、複数デバイスに対して設定を一括更新できます：

```python
class BulkConfigManager:
    def __init__(self, devices: list):
        self.clients = [
            RestconfClient(device['host'], device['username'], device['password'])
            for device in devices
        ]

    def update_all_interfaces(self, config: dict):
        for client in self.clients:
            client.update_interface("GigabitEthernet1", config)
```

---

## 🔍 **トラブルシューティングと自動復旧**

### **エラーコード別の対処法**

| ステータスコード | 意味                  | 対処法                      |
|------------------|-----------------------|-----------------------------|
| 401              | 認証エラー            | 資格情報を確認              |
| 404              | リソースが見つからない| URLやリソース名を確認       |
| 500              | サーバー内部エラー    | デバイスの状態を確認        |

---

### **設定のバックアップと復元**

#### バックアップ例：
```python
def backup_running_config(client: RestconfClient, file_path: str):
    config = client.get_interface("running-config")
    with open(file_path, "w") as file:
        json.dump(config, file)
    print(f"バックアップを保存しました: {file_path}")
```

#### 復元例：
```python
def restore_running_config(client: RestconfClient, file_path: str):
    with open(file_path, "r") as file:
        config = json.load(file)
    client.update_interface("running-config", config)
    print("設定を復元しました")
```

---

## 📈 **まとめ**

本記事では、RESTCONFとYANGモデルの基礎、Pythonによる操作方法、セキュリティ強化、トラブルシューティング、ユースケースまで幅広く解説しました。

次のステップとして：
1. Cisco IOS-XEデバイスでRESTCONFを有効化。
2. 本記事のPythonコードを動作確認。
3. 独自ユースケースに合わせてコードを拡張。

さらに、[Cisco DevNet](https://developer.cisco.com/)で公式資料を参照し、知識を深めてください！