Skip to content

NETCONF を使用してネットワークを自動化#

このステップでは、NETCONF を使用してデバイスのネットワーク設定を管理する方法を、Python スクリプトの例を通して確認していきます。

実習:現在の設定の詳細情報を取得#

  1. テキスト エディタでファイル get_interface_list.py を開きます。確認すべき主な内容を順に見ていきましょう。
  2. imports を確認します。 ncclient はすでに見ていますが、さらに xmltodict と xml.dom.minidom も確認します。 これらのライブラリにより、XML データでの操作が容易になります。

    from ncclient import manager
    import xmltodict
    import xml.dom.minidom
    

  3. このスクリプトの目的は、ietf-interfaces モデルを使用してインターフェイスを取得することです。 リクエスト内で filter を指定しないと、NETCONF からは、すべてのデータ モデルで利用できるあらゆるものが返ってきます。 ネットワーク デバイスの面でもコードの面でも、filter を使用する方が効率的です。

    # Create an XML filter for targeted NETCONF queries
    netconf_filter = """
    <filter>
      <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
        <interface></interface>
      </interface>
    </filter>"""
    

  4. Python で with ステートメントを使用すると、不要になったリソースを自動的に終了させるコンテキスト ハンドラが作成されます。 通常はファイルにアクセスする際に使用されますが、NETCONF 接続など、その他の接続にも使用できます。

    with manager.connect(
            host=env_lab.IOS_XE_1["host"],
            port=env_lab.IOS_XE_1["netconf_port"],
            username=env_lab.IOS_XE_1["username"],
            password=env_lab.IOS_XE_1["password"],
            hostkey_verify=False
            ) as m:
    

  5. 接続がアクティブになったところで、次のステップとして、フィルタを含む 操作を実行します。

    netconf_reply = m.get_config(source = 'running', filter = netconf_filter)
    

  6. 接続後、netconf_reply にデバイスからの RPC 応答が表示されます。 次の行では、XML の raw データを見やすく整えて出力しています。

    print(xml.dom.minidom.parseString(netconf_reply.xml).toprettyxml())
    

  7. 次の行では、戻された XML の文字列を、処理しやすい Python Ordered Dictionary に変換し、データを精査してインターフェイスのリストを取得します。

    # Parse the returned XML to an Ordered Dictionary
    netconf_data = xmltodict.parse(netconf_reply.xml)["rpc-reply"]["data"]
    # Create a list of interfaces
    interfaces = netconf_data["interfaces"]["interface"]
    

  8. 最後に、インターフェイスの部分をループさせて、インターフェイスの名前とステータスを出力します。

    for interface in interfaces:
        print("Interface {} enabled status is {}".format(
                interface["name"],
                interface["enabled"]
                )
            )
    

  9. スクリプトを閉じ、ターミナルから実行します。 python get_interface_list.py

実習:設定の追加#

  1. テキスト エディタでファイル add_loopback.py を開きます。 確認すべき新しい内容を順に見ていきましょう。
  2. NETCONF による追加を実行するには、使用可能な YANG モデルに基づいてモデル化された希望の設定内容を持つ XML ペイロードを作成する必要があります。 下記に、ietf-interfaces モデルに基づいてインターフェイスを追加するための XML ペイロード用テンプレートを作成する例を示します。

    # Create an XML configuration template for ietf-interfaces
    netconf_interface_template = """
    <config>
        <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
            <interface>
                <name>{name}</name>
                <description>{desc}</description>
                <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">
                    {type}
                </type>
                <enabled>{status}</enabled>
                <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
                    <address>
                        <ip>{ip_address}</ip>
                        <netmask>{mask}</netmask>
                    </address>
                </ipv4>
            </interface>
        </interfaces>
    </config>"""
    

  3. 次のスクリプトによって、追加すべき新しいループバック インターフェイスの詳細をユーザに尋ねます。

    # Ask for the Interface Details to Add
    new_loopback = {}
    new_loopback["name"] = "Loopback" + input("What loopback number to add? ")
    new_loopback["desc"] = input("What description to use? ")
    new_loopback["type"] = IETF_INTERFACE_TYPES["loopback"]
    new_loopback["status"] = "true"
    new_loopback["ip_address"] = input("What IP address? ")
    new_loopback["mask"] = input("What network mask? ")
    

  4. ここで、ユーザから提供されたデータがテンプレートに代入されます。

    # Create the NETCONF data payload for this interface
    netconf_data = netconf_interface_template.format(
            name = new_loopback["name"],
            desc = new_loopback["desc"],
            type = new_loopback["type"],
            status = new_loopback["status"],
            ip_address = new_loopback["ip_address"],
            mask = new_loopback["mask"]
        )
    

  5. 最後に、 操作が実行されます。

    netconf_reply = m.edit_config(netconf_data, target = 'running')
    

  6. スクリプトを閉じ、ターミナルから実行します。 新しいインターフェイスの情報を求められたら、python add_loopback.py入力します。

実習:設定の削除#

これで、ループバックの追加が完了しました。では、それを設定から削除したい場合はどうすればいいでしょうか。

  1. テキスト エディタでファイル delete_loopback.py を開きます。 確認すべき新しい内容を順に見ていきましょう。
  2. 今度も XML ペイロードのテンプレートを使用します。ただし、今回は の部分が operation="delete" になっている点に留意してください。 こうすることにより、オブジェクトに対する特定のアクティビティを指定できます。

    netconf_interface_template = """
    <config>
        <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
            <interface operation="delete">
                <name>{name}</name>
            </interface>
        </interfaces>
    </config>"""
    

  3. 以上です。追加する場合とほとんど変わりません。

  4. スクリプトを閉じ、ターミナルからpython delete_loopback.pyを実行します。 最後のステップで、追加したループバックの数を表示させます。

Warning

存在しないインターフェイスを削除しようとすると、NETCONF のエラーが表示されます。

実習:設定の保存#

変更後のネットワーク内容をスタートアップ コンフィギュレーションに保存しておいたほうがよい場合があります。 NETCONF では、各ベンダーのプラットフォームで独自のアクティビティが行えるように、ネイティブ RPC 操作をサポートしています。 IOS XE デバイスは、ネイティブ データ モデルの一部として、 操作をサポートしています。 その仕組みを見てみましょう。

  1. テキスト エディタでファイル save_config.py を開きます。 確認すべき新しい内容を順に見ていきましょう。
  2. カスタムの RPC を作成するには、ncclient パッケージから別のオブジェクトを利用します。from ncclient import manager, xml_と記述して、xml_ をインポートします。
  3. 今回は、NETCONF で <filter> または <config> を作成するのではなく、モデルから RPC を明示的に呼び出します。

    save_body = """
    <cisco-ia:save-config xmlns:cisco-ia="http://cisco.com/yang/cisco-ia"/>
    """
    

  4. カスタム RPC を送信するのと同様に、dispatch メソッドを使用して、カスタム操作を送信します。

    netconf_reply = m.dispatch(xml_.to_ele(save_body))
    

  5. では、スクリプトを閉じ、ターミナルからpython save_config.pyを実行します。戻された応答の本文を見てください。 成功したことがはっきりと示されています。

    # Partial Example Output
    <result xmlns="http://cisco.com/yang/cisco-ia">Save running-config successful</result>