34
自分のコンピュータを設定する方法 このラボで作業するには、VIRL サーバへのアクセス権が必要です。アクセス権が ない場合は、DevNet dCloud ラボに用意されている VIRL インスタンスを使用 できます。dCloud ラボへのアクセスについては、Pre-Event Preparation(イベント 前の準備)および Lab Setup(ラボの設定)」の各モジュールを確認してください。 VIRL に関する課題の概要 この課題では、REST API コールの使用方法に関する知識を総動員します。VIRL Python スクリプトを使用して、プロジェクトの作成、シミュレーションの開始、イン ターフェイスでのパケット キャプチャの開始を行い、最後にシミュレーションを停止し ます。 課題の目標 所要時間:30 既存の Python コードを変更して REST API コールを実行し、プロジェクトの 作成、シミュレーションの開始、パケット キャプチャの開始を行い、最後にシ ミュレーションを停止する。 PCAP ファイルをダウンロードして内容を確認する。 前提条件 VIRL へのアクセス 自分のコンピュータに VIRL がインストールされていない場合は、dCloud で利用可 能な VIRL インスタンスを使用してください。ブラウザ ベースの RDP を使用してラ ボにアクセスする方法または AnyConnect VPN を使用して接続する方法について は、ラボの準備に関する手順を参照してください。 Python サンプル コードを実行するには、使用しているマシンに Python 3 がインストールさ れている必要があります。

VIRL に関する課題の概要 - Cisco Support Community · 10/17/2016 · 自分のコンピュータを設定する方法. このラボで作業するには、virl サーバへのアクセス権が必要です。アクセス権が

Embed Size (px)

Citation preview

自分のコンピュータを設定する方法 このラボで作業するには、VIRL サーバへのアクセス権が必要です。アクセス権が

ない場合は、DevNet の dCloud ラボに用意されている VIRL インスタンスを使用

できます。dCloud ラボへのアクセスについては、「Pre-Event Preparation(イベント

前の準備)」 および 「Lab Setup(ラボの設定)」の各モジュールを確認してください。

VIRL に関する課題の概要 この課題では、REST API コールの使用方法に関する知識を総動員します。VIRL で Python スクリプトを使用して、プロジェクトの作成、シミュレーションの開始、イン

ターフェイスでのパケット キャプチャの開始を行い、最後にシミュレーションを停止し

ます。

課題の目標

所要時間:30 分

• 既存の Python コードを変更して REST API コールを実行し、プロジェクトの

作成、シミュレーションの開始、パケット キャプチャの開始を行い、最後にシ

ミュレーションを停止する。 • PCAP ファイルをダウンロードして内容を確認する。

前提条件

VIRL へのアクセス

自分のコンピュータに VIRL がインストールされていない場合は、dCloud で利用可

能な VIRL インスタンスを使用してください。ブラウザ ベースの RDP を使用してラ

ボにアクセスする方法または AnyConnect VPN を使用して接続する方法について

は、ラボの準備に関する手順を参照してください。

Python

サンプル コードを実行するには、使用しているマシンに Python 3 がインストールさ

れている必要があります。

• dCloud ラボ環境を使用している場合は、Windows および Linux ワークス

テーションに Python 3 がすでにインストールされています。 • 「How to Set up Your Own Computer(自分のコンピュータを設定する方

法)」モジュールには、Python のインストールなど、自分のコンピュータに関

する前提条件について記載されているので、参照してください。

背景情報

このラボを開始する前に、「Coding 101 Rest Basics Learning Lab(コーディング 101:

Rest の基本に関するラーニング ラボ)」および「Coding 102 Rest Python Learning Lab

(コーディング 102:Rest および Python に関するラーニング ラボ)」を完了しておくことをお

勧めします。

Python コード サンプル

この VIRL の課題では、以下のサンプル スクリプトを使用します。まず、ファイル virl_mission.py を「Code」ディレクトリからコピーして、次に 「devnet-express-code-samples/module07/07-lab04-mission」ディレクトリか

ら、作業ディレクトリにコピーして、ご使用のエディタに読み込みます。

注:dCloud ラボ環境を使用していない場合は、ご使用のローカル コンピュータにサン

プル コードのリポジトリを複製する方法が記載された、開始前の準備に関するモジュー

ルを参照してください。このラボ環境の Windows および Linux ワークステーションに

は、このコード サンプルが「Code」ディレクトリにすでにインストールされています。

#!/usr/bin/env python

# Import necessary modules

import requests

# Define necessary global variables

VIRL_URL = ""

USERNAME = "guest"

PASSWORD = "guest"

def create_project_user(url, username, password):

'''

This function will create a new project and a new user

which will be associated with the project.

'''

print("Creating the project...")

# Project URL against which the API call will be placed

project_api = ""

project_url = url + ":19400" + project_api

# Below variables will be used to create new project

project_name = ""

description = "Project created via Python"

enabled = True

new_password = project_name

# Parameters which will be passed to the server with the API call

params = {"name": project_name,

"description": description,

"enabled": enabled,

"user-password": new_password

}

# Make an API call and assign the response information to the variable

project_response = requests.post(

project_url, auth=(username, password), params=params)

# Check if call was successful, if true print it

if project_response.status_code == 200:

print("\nProject was created successfully.\n\n")

# Update global variables

global USERNAME, PASSWORD

USERNAME = new_password

PASSWORD = new_password

def start_sim(url, username, password):

'''

This function will start a simulation using provided .virl file

'''

print("\nStarting simulation...\n")

# Simulation start URL against which the API call will be placed

simulation_start_api = ""

simulation_start_url = url + ":19399" + simulation_start_api

# Open .virl file and assign it to the variable

virl_file = open('mission.virl', 'r')

# Parameter which will be passed to the server with the API call

simulation_name = ''

params = {'file': simulation_name}

# Make an API call and assign the response information to the variable

simulation_start_response = requests.post(

simulation_start_url, auth=(username, password), params=params, data=virl_file)

# Check if call was successful, if true print it and return the value

if simulation_start_response.status_code == 200:

print(simulation_start_response.text +

" simulation has successfully started.\n\n")

return simulation_start_response.text

def packet_capture(url, username, password, sim):

'''

This function will gather necessary information to start packet capturing process.

Also, user is required to answer questions in order for function to do its job.

'''

# Node URL against which the API call will be placed

node_api = ""

node_url = url + ":19399" + node_api + "/" + sim

# Make an API call and assign the response information to the variable

node_response = requests.get(node_url, auth=(username, password)).json()

# Create an empty dictionary, which will hold node information

nodes = {}

# Print columns identifiers

print("\nNumber Node")

# Iterate over node_response and assign node information to nodes{}

# dictionary

for i, node in enumerate(node_response[sim]):

# Check to see if node is not ~mgmt-lxc and then assign it

if node != '~mgmt-lxc':

nodes[i + 1] = node

print(str(i + 1) + ":" + " " * 10 + node)

# Variable which will hold a node name chosen by the user

mission_node = ''

# While loop helps to make sure that user chooses correct node

while not mission_node:

user_input = input("\nWhich node would you like to select? ")

if user_input in nodes.values():

mission_node = user_input

else:

print("\nYour choice is not valid.Please choose a valid node name.\n")

print("\n\n\nNumber Node")

for num in nodes.keys():

print(str(num) + ":" + " " * 10 + nodes[num])

# Interface URL against which the API call will be placed

iface_api = ""

iface_url = url + ":19399" + iface_api + "/" + sim

# Parameters which will be passed to the server with the API call

iface_params = {"simulation": sim,

"nodes": [mission_node]

}

# Make an API call and assign the response information to the variable

iface_response = requests.get(

iface_url, auth=(username, password), params=iface_params).json()

# Create an empty dictionary, which will hold interface information

ifaces = {}

# Print columns identifiers

print("\n\n\nInterface ID Interface Name")

# Iterate over iface_response and assign interface information to ifaces{}

# dictionary

for i, iface in enumerate(iface_response[sim][mission_node]):

# Check to see if interface is not management and then assign it

if iface != 'management':

ifaces[str(i)] = iface_response[sim][mission_node][iface]["name"]

print(

str(i) + " " * 17 + iface_response[sim][mission_node][iface]["name"])

# Variable which will hold an interface ID chosen by the user

mission_iface = ""

while not mission_iface:

user_input = input("\nOn which interface ID would "

"you like to start capturing packets? ")

if user_input in ifaces.keys():

mission_iface = user_input

else:

print("\nYour choice is not valid.Please select "

"a valid interface ID\n\n")

print("Interface ID Interface Name")

for num in ifaces.keys():

print(str(num) + " " * 17 + ifaces[num])

# Capture URL against which the API call will be placed

capture_api = ""

capture_url = url + ":19399" + capture_api + "/" + sim

# Parameters which will be passed to the server with the API call

capture_params = {"simulation": sim,

"node": mission_node,

"interface": mission_iface

}

# Make an API call and assign the response information to the variable

capture_response = requests.post(

capture_url, auth=(username, password), params=capture_params)

# Check if call was successful, if true print it

if capture_response.status_code == 200:

print(capture_response.text)

print("\n\nPacket capture was successfully started."

"\nGo to VIRL UWM page in order to download the .pcap file")

def stop_simulation(url, username, password, sim):

'''

This function will stop specified simulation

'''

# Stop URL against which the API call will be placed

stop_api = ""

stop_url = url + ":19399" + stop_api + "/" + sim

# Make an API call and assign the response information to the variable

stop_response = requests.get(stop_url, auth=(username, password))

# Check if call was successful, if true print it and exit the application

if stop_response.status_code == 200:

input("\nSimulation has been stopped."

"Press any key to exit the application")

exit()

def main():

'''

This function will start functions created above in desired order

'''

# start create_project_user(url, username, password) function

create_project_user(VIRL_URL, USERNAME, PASSWORD)

# start start_sim(url, username, password) function and assign the result

# to the variable

simulation = start_sim(VIRL_URL, USERNAME, PASSWORD)

# Print a message asking user to verify that all nodes are in active and

# reachable state

print("Please go to VIRL UWM page and make sure all nodes \n"

"are in active and reachable state in simulation pane.\n"

"It should only take 2-3 minutes.")

print("\nIf you proceed without waiting, the next function \n"

"will create a non-functional .pcap file and you will \n"

"not be able to download it from VIRL UWM page.\n")

# While loop will run infinitely until user confirms that all nodes are

# active and reachable

while True:

user_input = input(

"\n\n\nAre all nodes in active and reachable state?(y/n)[n] ")

if user_input.lower() == 'y' or user_input.lower() == 'yes':

break

else:

print(

"\nOkay! Please wait until the nodes state changes to desired value")

# start packet_capture(url, username, password, sim) function

packet_capture(VIRL_URL, USERNAME, PASSWORD, simulation)

# While loop will run infinitely until user confirms that he/she

# downloaded the .pcap file

while True:

user_input = input(

"\n\n\nWere you able to download .pcap file from VIRL UWM page?(y/n)[n] ")

if user_input.lower() == 'y' or user_input.lower() == 'yes':

break

else:

print(

"\nOkay! Go to VIRL UWM page and download the file.\n\

When you are ready, come back to terminal screen and answer the question again")

# Notify user that simulation will be stopped next

print(

"\nScript will now stop the node.You should see appropriate message briefly.\n")

# start stop_simulation(url, username, password, sim) function

stop_simulation(VIRL_URL, USERNAME, PASSWORD, simulation)

# Check if this python script has been run as a standalone program, if

# true run main() function

if __name__ == '__main__':

main()

1/9

ステップ 2:サンプル コードの変更

ステップ 1 の手順に従って、virl_mission.py ファイルを開いて確認します。 当該の API コールを機能させるために、特定の変数に対して正しい値を設定する

必要があります。このスクリプトは、これらの値の修正や挿入を行わないと、機能し

ません。

指定する必要がある情報

以下の情報が不足しているため、API ドキュメンテーションを検索して、適切な値を

指定する必要があります。

• VIRL の URL:VIRL の完全な URL アドレス。 • API コール:スクリプト内の各関数には API 変数があり、値を設定する必要

があります。 • 変数:ユーザが任意の値を指定できるようにするために、空白のままになっ

ている変数があります。

これらの関数を課題の各ステップで 1 つずつ説明し、不足している値を入力する方

法について説明します。 2/9

ステップ 3:VIRL の URL アドレス

このステップでは、VIRL の URL 部分について、不足している値を指定するために

必要な情報を紹介します。

1. モジュール 7 のラボ 2 を確認してください。このラボには、VIRL の URL についての情報が含まれています。VIRL_URL 変数に必要な値をメモしてくだ

さい。 2. コード サンプルで、VIRL_URL 変数を見つけて、この変数に完全な URL

アドレスを入力します。変数への入力を以下に示します。

3. VIRL_URL = "http://IP-ADDRESS"

これで完了です。次のステップでは、create_project_user() 関数を確認し

て、問題をすべて修正します。 3/9

ステップ 4:プロジェクトおよびユーザ関数を作成する

このステップでは、コードを確認して、不足している値を設定します。以下のコード スニペットは create_project_user() 関数のみを示しています。

def create_project_user(url, username, password):

'''

This function will create a new project and a new user

which will be associated with the project.

'''

print("Creating the project...", end="")

# Project URL against which the API call will be placed

project_api = ""

project_url = url + ":19400" + project_api

# Below variables will be used to create new project

project_name = ""

description = "Project created via Python"

enabled = True

new_password = project_name

# Parameters which will be passed to the server with the API call

params = {"name": project_name,

"description": description,

"enabled": enabled,

"user-password": new_password

}

# Make an API call and assign the response information to the variable

project_response = requests.post(

project_url, auth=(username, password), params=params)

# Check if call was successful, if true print it

if project_response.status_code == 200:

print("\nProject was created successfully.\n\n")

# Update global variables

global USERNAME, PASSWORD

USERNAME = new_password

PASSWORD = new_password

print("done")

このコードを確認すると、project_api 変数および project_name 変数の値

が空になっていることが分かります。これらの変数への値の入力方法を以下に示し

ます。

1. Web ブラウザを開き、http://VIRL-URL:19400/docs/api/uwm/ に移動します。ここで、VIRL-URL を、前のステップで取得した情報で置き換え

る必要があります。VIRL の Web UI にアクセスするのが初めての場合は、

認証のためのプロンプトが表示されます。[ユーザ名(username)] に「guest」、[パスワード(password)] に「guest」を指定してログインします。

2. ページの中ほどに、グループ化された VIRL UWM API のリストがあります。

[projects] グループを見つけて、クリックします。このグループには、プロ

ジェクトに関係するすべての API が表示されています。右側の説明を読ん

で、新規プロジェクトを作成するものを見つけます。この API の値をコピーし

て、project_api にその値を入力します。

3. 最後に、プロジェクト名を選択して、project_name 変数を入力する必要が

あります。この値は、ユーザ名およびパスワードに自動的に割り当てられま

す。たとえば、「project_name = 'devnet'」と設定すると、ユーザ名も

「devnet」になり、そのユーザ名に関連付けられたパスワードも「devnet」に設定されます。自分の名前など、何を使用しても構いません(ただし、文字

列に限ります)。 これで完了です。この関数の準備ができました。次のステップでは、start_sim() 関数について見ていきましょう。

4/9

ステップ 5:シミュレーションを開始する

このステップでは、コードを確認して、不足している値を設定します。以下のコード スニペットは start_sim() 関数のみを示しています。

def start_sim(url, username, password):

'''

This function will start a simulation using provided .virl file

'''

print("\nStarting simulation...\n")

# Simulation start URL against which the API call will be placed

simulation_start_api = ""

simulation_start_url = url + ":19399" + simulation_start_api

# Open .virl file and assign it to the variable

virl_file = open('mission.virl', 'rb')

# Parameter which will be passed to the server with the API call

simulation_name = ''

params = {'file': simulation_name}

# Make an API call and assign the response information to the variable

simulation_start_response = requests.post(

simulation_start_url, auth=(username, password), params=params, data=virl_file)

# Check if call was successful, if true print it and return the value

if simulation_start_response.status_code == 200:

print(simulation_start_response.text +

" simulation has successfully started.\n\n")

return simulation_start_response.text

コード内で確認できるように、simulation_start_api および simulation_name 変数の値が不足しており、これらの値を入力して、関数を修

正する必要があります。それでは、始めましょう。

1. VIRL UWM ページを開いている Web ブラウザに戻り、ドキュメンテーション

の下の VIRL STD API リンクをクリックします。ページの中ほどに、グループ

化された VIRL STD API のリストがあります。[simengine] グループを見つ

けて、クリックします。このグループには、シミュレーション エンジンに関係す

るすべての API が表示されています。右側の説明を読んで、新規シミュレー

ションを開始または作成するものを見つけます。この API の値をコピーして、

simulation_start_api にその値を入力します。

2. 次に、simulation_name 変数を入力して、シミュレーションに名前を付け

ます。 これで完了です。この関数も修正されました。次の関数は、さらに多くの API コール

が不足している packet_capture() です。 5/9

ステップ 6:パケット キャプチャ

このステップでは、packet_capture() 関数のコードを確認して、不足している

値を入力します。以下は、packet_capture() 関数のみを示しているコード スニ

ペットです。

def packet_capture(url, username, password, sim):

'''

This function will gather necessary information to start packet capturing process.

Also, user is required to answer questions in order for function to do its job.

'''

# Node URL against which the API call will be placed

node_api = ""

node_url = url + ":19399" + node_api + "/" + sim

# Make an API call and assign the response information to the variable

node_response = requests.get(node_url, auth=(username, password)).json()

# Create an empty dictionary, which will hold node information

nodes = {}

# Print columns identifiers

print("\nNumber Node")

# Iterate over node_response and assign node information to nodes{}

# dictionary

for i, node in enumerate(node_response[sim]):

# Check to see if node is not ~mgmt-lxc and then assign it

if node != '~mgmt-lxc':

nodes[i + 1] = node

print(str(i + 1) + ":" + " " * 10 + node)

# Variable which will hold a node name chosen by the user

mission_node = ''

# While loop helps to make sure that user chooses correct node

while not mission_node:

user_input = input("\nWhich node would you like to select? ")

if user_input in nodes.values():

mission_node = user_input

else:

print("\nYour choice is not valid.Please choose a valid node name.\n")

print("\n\n\nNumber Node")

for num in nodes.keys():

print(str(num) + ":" + " " * 10 + nodes[num])

# Interface URL against which the API call will be placed

iface_api = ""

iface_url = url + ":19399" + iface_api + "/" + sim

# Parameters which will be passed to the server with the API call

iface_params = {"simulation": sim,

"nodes": [mission_node]

}

# Make an API call and assign the response information to the variable

iface_response = requests.get(

iface_url, auth=(username, password), params=iface_params).json()

# Create an empty dictionary, which will hold interface information

ifaces = {}

# Print columns identifiers

print("\n\n\nInterface ID Interface Name")

# Iterate over iface_response and assign interface information to ifaces{}

# dictionary

for i, iface in enumerate(iface_response[sim][mission_node]):

# Check to see if interface is not management and then assign it

if iface != 'management':

ifaces[str(i)] = iface_response[sim][mission_node][iface]["name"]

print(

str(i) + " " * 17 + iface_response[sim][mission_node][iface]["name"])

# Variable which will hold an interface ID chosen by the user

mission_iface = ""

while not mission_iface:

user_input = input("\nOn which interface ID would "

"you like to start capturing packets? ")

if user_input in ifaces.keys():

mission_iface = user_input

else:

print("\nYour choice is not valid.Please select "

"a valid interface ID\n\n")

print("Interface ID Interface Name")

for num in ifaces.keys():

print(str(num) + " " * 17 + ifaces[num])

# Capture URL against which the API call will be placed

capture_api = ""

capture_url = url + ":19399" + capture_api + "/" + sim

# Parameters which will be passed to the server with the API call

capture_params = {"simulation": sim,

"node": mission_node,

"interface": mission_iface

}

# Make an API call and assign the response information to the variable

capture_response = requests.post(

capture_url, auth=(username, password), params=capture_params)

# Check if call was successful, if true print it

if capture_response.status_code == 200:

print(capture_response.text)

print("\n\nPacket capture was successfully started."

"\nGo to VIRL UWM page in order to download the .pcap file")

コード内で確認できるように、node_api、iface_api、および capture_api の各変数の値が不足しており、この関数を修正するにはこれらの変数を入力する必

要があります。それでは、始めましょう。

1. VIRL UWM ページを開いている Web ブラウザに戻り、同じ [simengine] グループで、[シミュレーションのノードをリストします(listing simulation nodes)] という説明がある API を見つけます。この API の値をコピーして、

node_api 変数に入力します。「/{simulation}」は変数から除外してく

ださい。

2. 次に、[interfaces] グループに戻り、クリックしてこのグループを展開しま

す。インターフェイスに関連した API が表示されます。API の右側にある説

明を読み、シミュレーション インターフェイスをリストするもの(List simulation inerfaces)を見つけます。この API の値をコピーして、iface_api にその

値を入力します。/{simulation} は変数から除外してください。 3. 最後に、グループのリストに戻り、[traffic capture] を見つけます。これ

をクリックして展開し、新規キャプチャを作成する API コール(Create a new traffic capture)を見つけます。この API を capture_api 変数に割り当て

ます。/{simulation} は変数から除外してください。 完了まであともう少しです。あと 1 つ関数を修正すれば、コードが動作するようにな

ります。 6/9

ステップ 7:パケット キャプチャ

このステップでは、stop_node() 関数のコードを確認して、不足している値を入力

します。以下のコード スニペットは stop_node() 関数のみを示しています。

def stop_simulation(url, username, password, sim):

'''

This function will stop specified simulation

'''

# Stop URL against which the API call will be placed

stop_api = ""

stop_url = url + ":19399" + stop_api + "/" + sim

# Make an API call and assign the response information to the variable

stop_response = requests.get(stop_url, auth=(username, password))

# Check if call was successful, if true print it and exit the application

if stop_response.status_code == 200:

input("\nSimulation has been stopped."

"Press any key to exit the application")

exit()

これは非常に小さな関数であり、値が不足している変数は 1 つのみです。すでにお

分かりのように、stop_api は空であり、値を入力する必要があります。その方法

は以下のとおりです。

1. VIRL UWM ページがある Web ブラウザに戻り、[simengine] グループを

クリックします。右側の説明を読んで、開始したシミュレーションの完全な停止

をスケジュールするもの(Schedule complete stop of a launched simulation)を見つけます。この API の値をコピーして、stop_api にその値を入力しま

す。/{simulation} は変数から除外してください。

これで完了です。コードの準備ができました。次のステップでは、コードが機能する

様子を紹介します。ご自分の実行結果と比べてみてください。 7/9

ステップ 8:スクリプトを実行する

このステップでは、プロジェクトとユーザ名を作成するスクリプトを実行します。 次に、このスクリプトによって VIRL サーバでシミュレーションが開始されます。このシミュレーションを、新規に作成したプロジェクトの新しいクレデンシャルおよびユーザ名/パスワードを使用してモニタし、スクリプトに対してユーザが入力を行います。

続いてこのスクリプトは、指定したノードのインターフェイスでパケット キャプチャを開始します。パケット キャプチャが開始されたら、VIRL サーバの UWM ページに移動して、そのキャプチャをダウンロードします。ダウンロードしたら、シミュレーションを停止するようスクリプトに指示し、スクリプトを終了します。

それでは、前のステップで説明したように、必要な値をすべて入力したらどうなるかを見てみましょう。

サンプル実行

スクリプトが開始され、プロジェクトが作成されると、ターミナル/コマンド ウィンドウに、ノードがすべてアクティブになるまで待機するように指示するメッセージが出力されます。スクリプトのプロンプトに入力すると、スクリプトは続行され、指定したノードのインターフェイスでパケット キャプチャが開始されます。

パケット キャプチャが開始されたら、UWM に移動して、それを [マイ シミュレーション(My Simulation)] セクションからダウンロードします。ダウンロード プロセスが完了したら、スクリプトにシミュレーションを停止するよう指示を出して終了します。

1. 端末画面を開き、「devnet-express-code-samples/module07/07-lab04-mission」フォルダに移動します。さらに、その端末で Python 仮想環境が有効になっていることを確認します(仮想環境を使用している場合)。

2. フォルダの内容を、dir コマンドまたは ls コマンドを発行してチェックし、 必要な mission.virl ファイルおよび virl_mission.py ファイルが存

在していることを確認します。

3. それでは、py -3 virl_mission.py コマンドを発行してスクリプトを実行

しましょう。プロジェクトが作成され、シミュレーションが正常に開始されると、 その旨がユーザに通知されます。次に、このコードにより、すべてのノードがア

クティブかつ到達可能な状態であるかどうか、確認するように求められます。

4. ノードの状態をチェックするには、Web ブラウザを開いて、

http://198.18.134.1:19400/simulations/ に移動します。プロンプトが表示さ

れたら、ステップ 4 で指定したユーザ名およびパスワードを使用します。この

例では、プロジェクト名として devnet を指定しました(ユーザ名およびパス

ワードも同じです)。以下のスクリーンショットでは、ユーザ名として virl が使用されています。実際に指定した値を使用してください。

5. 認証が作成すると、[マイ シミュレーション(My simulations)] ページが表示さ

れます。ページの中ほど、[シミュレーション(Simulation)] 列の下に、このス

クリプトによって作成されたシミュレーションが表示されます。詳細を表示する

には、シミュレーションの名前をクリックします。

6. 次のページに、選択したシミュレーションの詳細な情報が表示されます。スク

ロール ダウンして [ノード(Nodes)] セクションを探し、表にリストされたすべ

てのノードがアクティブかつ到達可能な状態であることを確認します。すべて

のノードがアクティブかつ到達可能な状態になるまでに、数分かかる場合が

あります。

7. トポロジの状態を確認するには、ページ最上部の近くにある、[ライブの可視

化(Live Visualization)] ボタンをクリックします。新しいブラウザのタブ/ペー

ジが開き、シミュレーションのトポロジが表示されます。トポロジを操作して、 トポロジの状態を確認します。

8. すべてのノードが「アクティブ/到達可能」状態であれば、ターミナル ウィンドウ

に戻り、y キーを押して確認することができます。続いて、ノードのリストが表

示され、ノードの名前を指定してノードを選択するように指示するプロンプトが

表示されます。仮想ネットワーキング デバイス(IOSv ルータ)であるノードは 2 つのみであるため、L3 または V1 ノードのいずれかを選択することをお勧

めします。これらのノードを選択することにより、インターフェイスでのパケット キャプチャの間に、データが確実に表示されるようになります。

9. ノードの名前を指定して、目的のノードを選択します。すると、スクリプトによっ

て、そのノードで使用可能なすべてのインターフェイスのリストが表示され、パ

ケット キャプチャを開始するインターフェイスの ID を指定するように求められ

ます。ID 番号を選択し、スクリプトに対してその番号を指定して処理を続行し

ます。

10. ID 番号を指定すると、パケット キャプチャ REST API コールの結果が表示

されます。その下に、指定したノードのインターフェイスでパケット キャプチャ

が正常に開始され、ダウンロードするには VIRL UWM ページに移動する

必要がある、というメッセージが表示されます。

11. Web ブラウザに戻ると VIRL UWM パージが開いたままになっているの

で、[トラフィック キャプチャ(Traffic captures)] セクションまでスクロール ダウンします。このリストには、このスクリプトによって開始されたパケット キャ

プチャが表示されています。右側にある [オプション(Options)] 列で、紙の

アイコンをクリックすることにより、最新のキャプチャ ファイルをダウンロード

して確認できます。

12. ファイルをダウンロードしたら、スクリプトが実行された端末画面に戻り、

y キーを押して .pcap ファイルがダウンロードされたことを確認します。

13. 次に、スクリプトは VIRL サーバにシミュレーションを停止するように指示し、

任意のキーを押すことでスクリプトを終了することを通知します。

「simulation stop」API コールは非同期です。たとえば、このコールはシミュ

レーションが実際に停止するのを待機しません。単に「shutdown」が開始さ

れるだけです。

「simulation stop」API コールに対して指定できる「wait」オプションを使用すると、このコールを同期することができます。これで、このコールはシミュレーションが終了するまで待機するようになります。この機能を確認して、スクリプトを変更することをお勧めします。

14. シミュレーションが正常に停止したことを確認するには、Web ブラウザに戻

り、最上部までスクロールします。シミュレーションが見つからないことを示す赤い通知エリアが表示されている場合があります。また、ノード セクションの上に、ユーザとプロジェクトに関する簡単な情報が表示され、シミュレーションが停止されたことを示すステータスが表示されています。

これで完了です。スクリプトを適切に修正し、実行後の動作を確認しました。

8/9

ステップ 9:チャレンジ(オプション) ここでは、さらに理解を深めるための演習についてご紹介します。

コード サンプル ディレクトリには、captureme.py という別のスクリプトがありま

す。このスクリプトは、以下のように「開始、待機、キャプチャ、ダウンロード、停止」

のサイクルを完全に自動化するものです。

Administrator@WKST1 MINGW64 ~/Code/devnet-express-code-samples/module07/07-lab04-mission (master)

$ ./captureme.py

2016-10-17 08:36:46 main(): Starting...

2016-10-17 08:36:46 start_sim(): Simulation start...

2016-10-17 08:36:49 start_sim(): Simulation has been started, sim id [Mission-Dq8nw3]

2016-10-17 08:36:49 wait_for_sim_to_start(): Waiting for Simulation to become active...

2016-10-17 08:38:21 wait_for_sim_to_start(): Simulation is active.

2016-10-17 08:38:21 create_packet_capture(): Starting packet capture...

2016-10-17 08:38:21 get_interface_id(): Getting interface id from name [GigabitEthernet0/1]...

2016-10-17 08:38:21 get_interface_id(): Found id: 0

2016-10-17 08:38:22 create_packet_capture(): Created packet capture (3d55413a-7900-41b8-afdc-be70862f524a)

2016-10-17 08:38:22 wait_for_packet_capture(): Waiting for capture to finish...

2016-10-17 08:39:13 wait_for_packet_capture(): Capture has finished.

2016-10-17 08:39:13 download_packet_capture(): Downloading capture file...

V1_GigabitEthernet0_1_2016-10-17-10-38-13.pcap

2016-10-17 08:39:13 download_packet_capture(): Download finished.

2016-10-17 08:39:13 stop_sim(): Simulation stop...

2016-10-17 08:39:14 stop_sim(): Simulation [Mission-Dq8nw3] stop initiated.

(mycode)

Administrator@WKST1 MINGW64 ~/Code/devnet-express-code-samples/module07/07-lab04-mission (master)

$

このスクリプトの動作を確認して、追加のテクニック(ロギング、API エラーの処理、

「traffic capture download」API、シミュレーションが完全に開始されるまでの待機

方法、キャプチャ完了までの待機など)を学ぶことをお勧めします。

このスクリプトでは現在ハードコードされているパラメータ(ノード名、名前、パケット

の数量、または pcap パケット フィルタなど)の一部を、スクリプトに対してコマンド ライン パラメータとして指定することもお勧めします。この処理により、柔軟性が大

幅に向上します。

また、Python argparse モジュール(RESTCONF のモジュールで使用)を create_subinterface.py スクリプトで使用してみてください。

そして、最後に、スクリプトのステータス出力を Spark ルームに提供することをお勧

めします。シミュレーションの開始やファイルのキャプチャに時間がかかるシミュレー

ションを使用している場合に、ユーザにフィードバックを提供できるので便利です。

それでは、コーディングを楽しんでください。 完了

9/9