課題:Python を使用して RESTCONF に対し てプログラミングを行う

自分のコンピュータを設定する方法
自分のコンピュータでこのラボの作業を行うには、「Postman」という Chrome アプリケーションを
インストールする必要があります。
このラボの作業を行うには、事前設定済みの dCloud ラボを使用するか、自分のコンピュータを
設定する必要があります。詳細については、「Pre-Event Preparation(イベント前の準備)」およ
び「Lab Setup(ラボの設定)」の各モジュールを確認してください。
課題:Python を使用して RESTCONF に対し
てプログラミングを行う
このラーニング ラボでは、RESTCONF API を使用して、ネットワーク デバイスに対してプログラ
ミングを行う方法を学びます。この課題では、Postman と Python を使用して、CSR1000V の
RESTCONF を操作します。目標は、dCloud ラボ環境の CSR1000V でサブインターフェイスを
設定し、Spark Room にこの変更を投稿して、他のユーザに変更を通知することです。
目標
所要時間:45 分
•
•
Postman を使用して RESTCONF API およびサポート対象のモジュールを検出する。
Python を使用して、CSR1000V のインターフェイスを設定する。
前提条件
このラボでは、REST API をたたけるアプリケーションである Postman を使用します。Postman
は、コードを作成せずに API の仕組みを理解するのに適したツールです。
また、Python を使って設定を変更するスクリプトの作成、および設定の変更の自動化を行い
ます。
背景情報
•
Python に詳しくない場合には、モジュール 04 を必ず確認してください。このモジュール
では、Python の基本について説明しています。
DMI RESTCONF API をサポートするデバイスへアクセスする
•
これらのラボの演習には、CSR1000V(ホスト名は csr1000v)を必ず使用してください。
RESTCONF と連携する DMI エージェントを使用できます。
•
このラボでは、dCloud ラボ環境を使用します。自分のローカル ラップトップまたは
Ubuntu ホストを使用してこのラボの演習を行う場合は、「Lab Setup(ラボ設定)」および
「Pre-Event Preparation(イベント前の準備)」の各モジュールを見直してしてください。
ステップ 1:API のエントリおよびデバイスの capabilities
RESTCONF は、API およびサポート対象のモジュールを検出するためのエントリ ポイントとして
知られています。Postman を使用して、CSR1000V で RESTCONF API のエントリ ポイントを検
出します。このステップの目的は、RESTCONF API エントリ ポイントについて理解し、Python を
使用して RESTCONF API コールの作成を開始できるようにすることです。Postman は、この手
順を開始するのに最適なツールです。
最初に Postman のコレクションおよび環境設定をインポートします。このコレクションおよび環境
設定ファイルは、コード例とともにディレクトリ devnet-express-code-samples/module06 にあ
ります。RESTCONF コレクションには RESTCONF API コールのサンプルが含まれており、環
境設定には別のコレクションでも再利用しやすい変数例が含まれています。
1. Postman を開き、以下のようにして RESTCONF コレクションをインポートします。
A:[インポート(Import)] をクリックします。
B:以下の restconflab.json.postman_collection ファイルを選択します。
example directory for the mission to import the collection:
devnet-express-codesamples/module06/restconflab.json.postman_collection
2. Postman を開き、以下のようにして RESTCONF 環境設定をインポートします。
A:[環境なし(No environment)] ドロップダウンをクリックして、[環境の管理(Manage
Environments)] をクリックします。
B:[インポート(Import)] ボタンを選択し、以下のようにしてコレクションをインポートし
ます。
C - 以下のようにして、環境設定をインポートするため課題用のサンプルコードのディレ
クトリにある dCloud.postman_environment ファイルを選択します:/devnet-express-
code-samples/module06/dCloud.postman_environment
D:ドロップダウンで、[dCloud] 環境を選択します。
3. ここで Postman を開き、ボタンを以下の順序でクリックして、最初の RESTCONF API を
行います。
A:[コレクション(Collections)] 列で、[RESTCONF デモ(RESTCONF Demo)] コレクショ
ンをクリックします。
B:[トップレベルの REST リソースの読み取り(Read the top level REST resource)] コー
ルを選択します。
C:[ユーザ認証(Under Authorization)] で、[基本認証(Basic Auth)] タイプを選択し
ます。
D:ユーザ名およびパスワード フィールドには、すでに {{user}} および {{password}}
が設定されており、Postman 環境の値に置き換えられます。
E:[要求の更新(Update Requests)] ボタンをクリックします。
F:[送信(Send)] ボタンをクリックします。
4. [送信(Send)] ボタンをクリックすると、[本文(Body)] タブにデータが設定されます。
デバイスから返される JSON には、以下の要素が表示されています。
API のエントリ ポイント:/api
o 設定データ:/api/config
o operational データ:/api/operational
o running configuration データ:/api/running
o
トップ レベルの URI パスに加えて、いくつかの operations がリストされています。
これらは、設定を保存したり、表をクリアしたりするリモート プロシージャ コール
(RPC)です。
注:現在の RESTCONF エージェントでは、「running configuration」
(running)と「スタートアップ コンフィギュレーション」(config)は区別されま
せん。これは将来のリリースで対応される予定です。
これで API エントリ ポイントと running configuration の編集方法を理解したの
で、当該の URI 文字列の作成を開始できます。次のステップでは、サポート対
象の YANG データ モデルについて確認して、デバイスに対するプログラミング
方法を理解します。
5. Postman で、ボタンを以下の順序でクリックしてください。
A:[コレクション(Collections)] をクリックします。
B:[デバイスで実装されているモデルの読み取り(Read models implemented by the
device)] コールを選択します。
C:[ユーザ認証(Under Authorization)] で、[基本認証(Basic Auth)] タイプを選択し
ます。
D:ユーザ名およびパスワード フィールドに、それぞれ {{user}} と {{password}} が挿
入されていることを確認してください。これらは、Postman 環境の該当する値で置き換え
られます。
E:[要求の更新(Update Requests)] ボタンをクリックします。
F:[送信(Send)] ボタンをクリックします。
6. 返されたリストを確認すると、IOS XE デバイスによって実装されているすべての YANG
モジュールが表示されています。
上出来です。CSR1000V によって実装されているすべてのデバイス モデルを確認できます。サ
ポートされている YANG モデルを取得するには、もう 1 つの方法があります。具体的には、サ
ブインターフェイスの設定に使用される可能性があるモデルを確認することです。返されたリスト
には、ned.yang. というモデルがあるはずです。この YANG データ モデルは、多数の設定シ
ナリオにおいて IOS シンタックスをモデル化しているため、この演習で使用されます。
ラボの次のステップでは、インターフェイスの設定を取得して、Python のコーディング演習の別
の例を確認します。
ステップ 2:デバイスのインターフェイス リストを取得する
前のステップでは、API のエントリ ポイント(/api)と設定データのプレフィックス(config および
running)について学びました。また、デバイスで ned.yang モデルと ietf-interface.yang モ
デルがサポートされていることも確認しました。これらのいずれかのデータ モデルを使用して、
デバイスを設定することができます。
また、config と running のどちらの設定ポイントも、デバイスの設定を変更します。
1. それでは、デバイスからインターフェイス リストを取得しましょう。デバイスに関して必要
な情報を取得するには、以下の手順に従います。この手順に従うことで、Python で API
コールを作成できます。このシナリオでは、このタスクのために etf-interfaces.yang
モデルを使用します。
A:[コレクション(Collections)] をクリックします。
B:[インターフェイス名の IETF インターフェイス リストの読み取り(Read ietf-interfaces
list of interfaces names)] コールを選択します。
C:[ユーザ認証(Under Authorization)] で、[基本認証(Basic Auth)] タイプを選択し
ます。
D:ユーザ名およびパスワード フィールドには、{{user}} および {{password}} が設定
されており、Postman が環境設定から適切な値に置き換えていることを確認します。
E:[要求の更新(Update Requests)] ボタンをクリックします。
F:[送信(Send)] ボタンをクリックします。
2. [送信(Send)] ボタンをクリックすると、クエリ対象のデバイスが、把握しているインター
フェイスのリストを返します。
本文が示すように、このデバイスには 2 つの設定済みインターフェイスがあります。
3. 前のステップの出力に基づき、1 つのインターフェイス(たとえば、GigabitEthernet1)の
データを取得します。クエリ パラメータ ?deep、?shallow、および ?verbose を確認しま
す。Postman で URI ディレクトリを変更し、パラメータを追加してコールを再実行します。
以下の手順に従って、作業を完了します。
A:[コレクション(Collections)] をクリックします。
B:[IETF インターフェイスの 1 つのインターフェイスの読み取り(Read ietf-interfaces
single interface)] コールを選択します。
C:[ユーザ認証(Under Authorization)] で、[基本認証(Basic Auth)] タイプを選択し
ます。
D:ユーザ名およびパスワード フィールドには、{{user}} および {{password}} が設定
されており、Postman が環境設定から適切な値に置き換えていることを確認します。
E:[要求の更新(Update Requests)] ボタンをクリックします。
F:[送信(Send)] ボタンをクリックします。
?deep クエリは URI で指定されたインターフェイスの設定を表示します。この例では、
GigabitEthernet1 の設定です。別のインターフェイスに対して、他のクエリ パラメータを
使用してみましょう。出力例を以下に示します。
4. 他のモデルでも、同じデータが使用されています。たとえば、ned.yang モデルでは、イン
ターフェイスの設定データには、シスコのデータ モデリング固有の形式や、共通シナリオ
では現在モデル化されていないものも使用されています。それでは、ned.yang と ietfinterfaces.yang を比較してみましょう。以下の手順に従って、作業を完了します。
A:[コレクション(Collections)] をクリックします。
B:[ネイティブ デバイスの 1 つのインターフェイスの読み取り(Read native device single
interface)] コールを選択します。
C:[ユーザ認証(Under Authorization)] で、[基本認証(Basic Auth)] タイプを選択し
ます。
D:ユーザ名およびパスワード フィールドの {{user}} および {{password}} は、
Postman の環境設定から適切な値に置き換えられます。
E:[要求の更新(Update Requests)] ボタンをクリックします。
F:[送信(Send)] ボタンをクリックします。
?deep クエリは URI で指定されたインターフェイスの設定を表示することを思い出してく
ださい。この例では、GigabitEthernet1 の設定です。出力例を以下に示します。
ned.yang モデルは、インターフェイスに関する多数の詳細情報を提供します。
ここでは Postman を使用して、RESTCONF API を検出するテクニックを確認しました。次のラボ
の手順では、同じ API を対象に Python を使用してプログラミングを行います。
ステップ 3:RESTCONF を使用してインター
フェイスの設定を取得する
前のシンプルな例を基にして、デバイスの設定の特定部分を取得する方法を学びます。このシ
ナリオを検証するために、この例では Python を使用します。
このサンプルは devnet-express-code-samples/module06 ディレクトリにあります。
このラボのステップに対しては、2 つのアプローチ方法があります。get_interfaces.py という
スクリプトに、サンプルが用意されています。このスクリプトを確認し、各自のロジックに基づいて
スクリプトを再作成できます。また、コードを最初から作成することもできます。
get_interfaces.py
を作成、または確認する
この例では RESTCONF を使用して、CSR1000V の running configuration から設定済みのイン
ターフェイスを取得します。
ネットワーク デバイスの管理については、RESTCONF の主な原則を学んでおく必要があります。
まずは、ターミナルを開いて get_interfaces.py スクリプトを作成します(ロジックを最初から作
成する場合)。
任意のテキスト エディタを使用して、ソース コードを編集します。このスクリプト用のロジックを、
これから作成します。
Python のインタプリタをポイントし、必要なライブラリをインポー
トする
スクリプトを開始するには、スクリプトが Python インタプリタを見つけることができることを確認し
てください。Python への正しいパスを見つけるには、env を使用するのが最適です。次に、
RESTCONF API コールを実行するために requests をインポートし、後の手順で exit() メソッ
ドを呼び出すために sys をインポートします。
#!/usr/bin/env python
import requests
import sys
CSR1000V の操作に必要な名前および値を追加する
CSR1000V へのアクセス方法については、モジュール 03 で詳しく説明しています。NETCONF
および RESTCONF 用に使用される DMI エージェントは IP アドレス 198.18.133.218 を使用
する仮想サービス コンテナで実行されています。また、RESTCONF は、HTTP 接続にポート
8008 を使用します。RESTCONF API に対してはベーシック認証を使用する必要があるため、
このデータ用の名前および値を作成します。
HOST = '198.18.133.218:8008'
USER = 'admin'
PASS = 'C1sco12345'
CSR1000V からインターフェイス設定を取得するための関数を
作成する
次に、デバイスの設定を取得するための関数を作成します。ここではデータを取得するため、
requests Python パッケージに用意された get() メソッドを使用します。前の演習から、
/api/running/interfaces という URI 文字列を使用することが考えられます。これは、running
configuration からインターフェイス設定データを取得しているためです。また、前のラボの手順
で、/api が API エントリ ポイントとして機能することも学びました。必要な場合は、Postman を使
用してこのサンプル コードの一部を作成することもできます。
def get_configured_interfaces():
"""
Retrieving config data (interface) from RESTCONF.
"""
url = "http://{h}/api/running/interfaces".format(h=HOST)
# RESTCONF media types for REST API headers
headers = {'Content-Type': 'application/vnd.yang.data+json',
'Accept': 'application/vnd.yang.data+json'}
# this statement performs a GET on the specified url
response = requests.get(url, auth=(USER, PASS),
headers=headers, verify=False)
# return the json as text
return response.text
main() メソッドを作成して関数を呼び出し、結果を出力する
それでは、関数を呼び出しましょう。そのためには、main() メソッドを作成します。このシナリオ
では、デフォルトの Python 名 __name__ を使用して、main() メソッドがこのスクリプトの実行時
にのみ実行されるようにします。
def main():
"""
Simple main method calling our function.
"""
interfaces = get_configured_interfaces()
# print the json that is returned
print(interfaces)
if __name__ == '__main__':
sys.exit(main())
実際に試してみる
これは、この例の完全なソース コードです。ここでは、自分でこのコードを実行してみましょう。
#!/usr/bin/env python
import requests
import sys
HOST = '198.18.133.218:8008'
USER = 'admin'
PASS = 'C1sco12345'
def get_configured_interfaces():
"""
Retrieving config data (interface) from RESTCONF.
"""
url = "http://{h}/api/running/interfaces".format(h=HOST)
# RESTCONF media types for REST API headers
headers = {'Content-Type': 'application/vnd.yang.data+json',
'Accept': 'application/vnd.yang.data+json'}
# this statement performs a GET on the specified url
response = requests.get(url, auth=(USER, PASS),
headers=headers, verify=False)
# return the json as text
return response.text
def main():
"""
Simple main method calling our function.
"""
interfaces = get_configured_interfaces()
# print the json that is returned
print(interfaces)
if __name__ == '__main__':
sys.exit(main())
このサンプル コードを実行するには、次のようにします。
1. ステップ 1 で Git リポジトリを複製したディレクトリに移動します。ディレクトリを devnetexpress-code-samples/module06 に変更します。
2. コマンド プロンプトにこの Python コマンドを入力し、次にファイル名を入力したら、リター
ン キーを押します。
o Windows の場合:py -3 get_interfaces.py
o Mac OS または Linux の場合:python3 get_interfaces.py
次のような結果が表示されます。
{
}
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "GigabitEthernet1"
},
{
"name": "GigabitEthernet2"
},
{
"name": "GigabitEthernet3"
}
]
}
このプログラムは、デバイスで実行されている設定済みインターフェイスの、未加工の JSON を
表示します。実際の出力はデバイスによって異なる場合があります(追加のインターフェイスが
設定されている場合があります)。
RESTCONF の主要な概念
このラボでは、確認しておくべき重要な RESTCONF の項目の一部について説明しました。
RESTCONF は設定データと operational データを分けています。URI 文字列を確認して、クエ
リしたリソースをさらに詳しく見てみましょう。
•
•
•
•
•
RESTful サービスに慣れた開発者にとって、running という名前のリソースは見慣れな
いものかもしれません。
このリソースの目的は、取得されるデータが当該デバイスの running configuration であ
ることを示すことです。
一方、operational 状態は別のリソース(および URI 文字列)を使用して取得されます。
o これは、Linux におけるインターフェイスの設定と operational state 状態の比較と
よく似ています。
§ Linux のインターフェイスの設定は、vim を使用して適切なフラット ファイ
ルを見ることで把握できます。
§ operational 状態の把握には、ifconfig を使用します。
RESTCONF を使用して取得されるデータは YANG でモデル化されていることを思い
出してください。
o YANG には、設定データと operational データを区別するためのシンタックスが
用意されています。
同様に、この区別に沿った URI 文字列とリソースも使用できます。これは、ネットワーク
の運用および自動化のために非常に便利です。
o たとえば、Linux サーバで周期的に発生するパケット損失をデバッグしているとし
ましょう。
o ルータの設定ファイルで指定された最大伝送ユニット(MTU)と、Linux マシン上
の ifconfig コマンドで表示される operational 状態とが一致しない場合、これは
根本原因の重要な情報を示しています。
それでは、RESTCONF API の概念に関する課題に移りましょう。次は、CSR1000V でサブイン
ターフェイスを設定します。
ステップ 4:RESTCONF を使用して新しいサ
ブインターフェイスを設定する
前のラーニング ラボとラボの手順の内容を基にして、RESTCONF を使用してデバイスを設定
する方法を学びます。現時点では、取得しているのはデバイス設定のみです。
次の例は、前のステップで使用した devnet-express-code-samples/module06/06-dmi-04-
mission ディレクトリにあります。また、このステップで使用するスクリプトの背景情報についても
説明します。また、さらに挑戦したい場合は、ロジックを最初から作ることもできます。
create_subinterfaces.py を作成し、概要を確認する
この例では RESTCONF を使用して、CSR1000V でサブインターフェイスを設定します。このス
クリプトは、RESTCONF を使用して新しいサービスのプロビジョニングをシンプルに行う方法を
示します。
ネットワーク デバイスの管理および自動化については、RESTCONF の主な原則を学んでおく
必要があります。
それでは、ターミナルを開いて、任意のディレクトリから create_subinterfaces.py スクリプトを
作成します(このロジックを最初から作成する場合)。
次に、任意のテキスト エディタを使用して、ソース コードを編集します。このスクリプト用のロジッ
クを、これから作成します。
目標は、以下のようにしてこのスクリプトを実行し、特定の IP アドレスのサブインターフェイスを
作成することです。最初の引数は、このサブインターフェイスに対して使用される VLAN で、2
番目の引数は IP アドレスです。この例では VLAN 1409 を使用しますが、必要に応じて別の
VLAN および IP ネットワークを選択しても構いません。
$ python3 create_subinterface.py 1409 1.0.5.64/20 --insecure
Python のインタプリタをポイントし、必要なライブラリをインポートする
はじめに、このスクリプトが正しい Python インタプリタを見つけることができることを確認してくだ
さい。Python への正しいパスを見つけるには、env を使用するのが最適です。次に、このスクリ
プトで引数を使うための argparse、Python の方式で IP アドレスおよびサブネットを処理するた
めの netaddr、正規表現のメソッドを利用するための re、RESTCONF API コールを作成する
ための requests、および、後のステップで exit() メソッドを呼び出すために sys をインポート
します。また、モジュール 00 で作成した venv も必ず使用します。必要なライブラリへアクセス
できることを確認します。
#!/usr/bin/env python
import
import
import
import
import
argparse
netaddr
re
requests
sys
適切な情報を追加する
次に、デバイスを設定するために作成する関数に渡す、適切な名前を作成する必要がありま
す。CSR1000V の仮想サービス コンテナの IP アドレス、RESTCONF ポート、ユーザ名/パス
ワード、および設定するインターフェイスの名前および関連する値を作成します。
HOST
PORT
USER
PASS
BASE
=
=
=
=
=
'198.18.133.218'
8008
'admin'
'C1sco12345'
'GigabitEthernet3'
サブインターフェイスを作成するための関数を作成する
それでは、デバイスの設定を変更する方法(手動で実施される、一般的なシナリオ)を示す、さ
まざまなロジックを見ていきましょう。
まず、create_vlan() 関数を作成して、CSR1000V のインターフェイスをプロビジョニングしま
す。この関数を呼び出す場合は、CSR1000V のホスト IP アドレス、RESTCONF ポート、ユーザ
名、パスワード、サブインターフェイス(GigabitEthernet2.1409)、インターフェイスの IP アドレス
(192.168.100.1/24)、および requests ライブラリが安全ではない HTTP(S)リクエストを実行す
ることを許可する insecure という引数を指定する必要があります。
注:これは、すべての証明書が信頼されたルート CA によって検証できるわけではないテスト環
境に必要です。自己署名証明書が使用されていることが原因で、Python リクエスト パッケージ
で証明書の検証が無効になっていない場合に例外が発生することがよくあります。SSH ホスト
の主要な検証と同様に、実稼働環境では証明書の検証は無効にしないことを強く推奨します。
この例のように HTTP を使用していれば、実質的に検証の必要はなく、問題もありません。
また、シンプルな正規表現を使用して、スクリプトに適切なインターフェイスが渡されているかど
うかを検証することも役に立ちます。有効なインターフェイスがスクリプトに渡されていない場合
は、スクリプトが終了します。以下のロジックは、このタスクを実行するためのコード例です。
def create_vlan(host, port, user, password, interface,
vlan, ip, ssl, insecure):
"""
Function to create a subinterface on CSR1000V.
"""
intfc = re.compile(r'^(\D+)(\d+)$')
m = intfc.match(interface)
if m is None:
print("invalid interface name.Valid example: ", BASE)
return -1
次に、API コールを作成します。
設定の変更を行うためには、RESTCONF に関する以前のラーニング ラボに従い、PATCH メッ
セージを送信する必要があります。また、VLAN、サブインターフェイス、および IP アドレスを指
定して、適切な JSON をフォーマットする必要もあります。以下の例は、特定の要求の JSON を
フォーマットするために文字列補間を使用します。このスクリプトを実行する場合は、固有のサ
ブインターフェイスを設定するために、VLAN ID および IP アドレスを引数として渡す必要があ
ります。
注:リソースは、PUT または PATCH の両方を使用して作成できます。これらのメソッドの違いは以
下のとおりです。1)PUT はモデル内の指定されたポイントにあるリソースを置き換えます。
2)PATCH はモデル内の指定されたポイントにあるリソースを変更します。これをインターフェイス
の特定の例に置き換えて説明すると、インターフェイスを作成する場合、.../interfaces/
GigabitEthernet コンテナへ PATCH するか、.../interfaces/GigabitEthernet/3.1409 へ
このインターフェイスを PUT します。新しいインターフェイスをコンテナ レベルへ PUT する場合
は、たとえ失敗する場合でもすべてのインターフェイスを置き換えるということを意味します。
適切な YANG データ モデルを分析するために pyang を使用できることを思い出してください。
このシナリオでは、シスコ固有の ned.yang モデルを使用してみます。このモデルの確認が必
要な場合は、ned.yang モデルが devnet-express-code-samples/module06 フォルダ内にあ
ります。前の例のように pyang を使用してデータ モデル全体を解析し、PUT メッセージのペイ
ロードのために YANG シンタックスを JSON に変換することもできます。演習をシンプルにする
ために、必要な出力を以下に示します。
pyang -f tree ned.yang
・
・
・
+--rw interface
| +--rw AppNav-Compress* [name]
| | +--rw name
・
・
・
| | +--rw encapsulation
| | | +--rw dot1Q
| | | | +--rw vlan-id?
uint16
| | | | +--rw native?
empty
| | +--rw ip
| | | +--rw (address-choice)?
| | | | +--:(unnumbered)
| | | | | +--rw unnumbered?
uint16
string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+--:(no-address)
| +--rw no-address
|
+--rw address?
boolean
+--:(address)
+--rw address
+--rw (address-choice)?
+--:(fixed-case)
| +--rw primary
| | +--rw address
| | +--rw mask
inet:ipv4-address
inet:ipv4-address
pyang からの出力に基づいて、JSON でに使用される正しいエスカレーションを示す文字列を
作成できます。このシナリオでは、前に示した YANG シンタックスに基づく RESTCONF API
コールを対象にした PATCH メッセージで発行される JSON データを作成します。必要に応じ
て、IPv6 と IPv4 の両方に対応するための if/else ステートメントを作成できます。以下のコー
ド スニペットは、文字列補完を使用して必要な JSON を作成するためのロジックを示します。
data = '''
{
"ned:%s": {
"name": "%s.%d",
"encapsulation": {
"dot1Q": {
"vlan-id": %d
}
},
%s
}
}
'''
if ip.version == 6:
ipdata = '''
"ipv6": {
"address": {
"prefix-list": [
{
"prefix": "%s"
}
]
}
}
''' % str(ip)
else:
ipdata = '''
"ip": {
"address": {
"primary": {
"address": "%s",
"mask": "%s"
}
}
}
''' % (ip.ip, ip.netmask)
proto = "https:" if ssl else "http:"
data = data % (m.group(1), m.group(2), vlan, vlan, ipdata)
以下のコードは、create_vlan() 関数の残りを示します。この例で先ほど示した YANG のスニ
ペットに基づいて、ベース URL を作成します。また、content-type ヘッダーおよび
application ヘッダーを構成し、適切な HTTP ヘッダーを使用します。また、この例では
RESTCONF API コールを try/except ステートメントでラップします。これにより、実行時に
誤った認証などの例外が万一発生した場合にも対応します。また、CSR1000V ルータの設定を
更新するために、put() メソッドも使用しています。
url = "%s//%s:%s/api/running/native/interface/%s" % (proto, host,
port, m.group(1))
headers = {'content-type': 'application/vnd.yang.data+json',
'accept': 'application/vnd.yang.data+json'}
try:
result = requests.patch(url, auth=(user, password),
data=data, headers=headers,
verify=not insecure)
except:
print(str(sys.exc_info()[0]))
return -1
# we expect a 204 for success
if result.status_code == 204:
return 0
# something went wrong
print(result.status_code, result.text)
return -1
関数を呼び出すための main() メソッドを作成する
以下のコードは、例の残りの部分を示します。このシナリオでは、argparse を使用して、使用す
るスクリプトで利用するためにコマンド ラインの引数を取り出します。また、使用する VLAN ID
および IP アドレスに対して基本的なデータ検証を行ってから、create_vlan() 関数を呼び出
します。
def main():
parser = argparse.ArgumentParser()
parser.add_argument('vlan', help="VLAN number (1-4094)", type=int)
parser.add_argument('prefix', help="IPv4 or IPv6 prefix")
parser.add_argument('--ssl', '-s', action='store_true',
help="use HTTPS")
parser.add_argument('--insecure', '-k', action='store_true',
help="relax SSL verification")
parser.add_argument('--interface', '-i', default=BASE,
help="interface name to use")
parser.add_argument('--user', '-u', default=USER,
help="user name on remote host")
parser.add_argument('--password', '-p', default=PASS,
help="password on remote host")
parser.add_argument('--port', '-P', default=PORT,
help="port on remote host")
parser.add_argument('--host', '-H', default=HOST, help="remote host")
args = parser.parse_args()
# check for valid VLAN ID
if args.vlan < 1 or args.vlan > 4094:
parser.print_usage()
print("invalid VLAN ID %s" % str(args.vlan))
return -1
# check for valid prefix
try:
ip = netaddr.IPNetwork(args.prefix)
except netaddr.core.AddrFormatError as e:
parser.print_usage()
print(e)
return -1
# insecure?
if args.ssl and args.insecure:
requests.packages.urllib3.disable_warnings()
return create_vlan(args.host, args.port, args.user,
args.password, args.interface,
args.vlan, ip, args.ssl, args.insecure)
if __name__ == '__main__':
sys.exit(main())
実際に試してみる
作成したスクリプトの実行方法を以下に示します。
$ python3 create_subinterface.py 1409 1.0.5.64/20
このサンプル コードを実行するには、次のようにします。
1. リポジトリで提供されているサンプルを実行する場合は、ディレクトリを devnetexpress-code-samples/module06 に変更します。
2. コマンド プロンプトにこの Python コマンドを入力し、次にファイル名を入力したら、リター
ン キーを押します。
o Windows の場合:py -3 create_subinterface.py 1409 1.0.5.64/20
o Mac OS または Linux の場合:python3 create_subinterface.py 1409
1.0.5.64/20
スクリプトが予期したとおりに動作した場合は、何も出力されません。ただし、このラボの
get_interfaces.py スクリプトを再度実行することで、設定の変更を一部検証することができま
す。この例では、サブインターフェイスで VLAN 100 を設定しました。
注:このサンプルは、暗号化されていない状態で実行しています(HTTPS や SSL などが使用さ
れていません)。実稼働環境で実行する場合は、HTTPS または SSL の使用を強く推奨しま
す。HTTPS または SSL の使用は、--ssl コマンド ライン スイッチを指定することで有効化でき
ます。
さらに Python の Request ライブラリが証明書の有効性を組み込みルート CA ストアに対して
チェックします。自己署名証明書を使用する場合などに検証を緩やかにするには、スクリプトの
パラメータとして --insecure を使用できます。繰り返しますが、これは実稼働環境では推奨さ
れません。
$ python3 get_interfaces.py | grep 1409
"name": "GigabitEthernet2.1409"
いいですね。上記の例では、返された JSON の特定のサブインターフェイスに対して grep を実行
すると、スクリプトが正しくサブインターフェイスを設定したことを確認できます。
RESTCONF の主要な概念
このラボでは、確認しておくべき重要な RESTCONF の項目の一部について説明しました。
1. YANG データ モデルを理解する。
o このステップの例を確認してから、YANG に関係した、RESTCONF の内部に対
する操作を始めます。
o 以下の例は、PATCH メッセージの JSON を示します。
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
{
"ned:GigabitEthernet": {
"name": "2.1409",
"encapsulation": {
"dot1Q": {
"vlan-id": 1409
}
},
"ip": {
"address": {
"primary": {
"address": "1.0.5.64",
"mask": "255.255.240.0"
}
}
}
}
}
データが YANG でモデル化されています。
よくできました。このラボの最後のステップでは、さらにロジックを追加します。これで、一緒に学
習しているメンバーにあなたがこのラボを終了したことを証明し、エンジニアを目指す他のメン
バーに自分が行った変更を伝えることができるようになります。