5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NETCONF/YANG を使って、Ciscoルータのコンフィグを設定する(IOS-XR)

Posted at

#何がやりたい?
これまで、IOS-XE を対象としてNETCONFを使って設定できることを確認してきましたが、今回は、IOS-XR に対してNETCONFでルータを設定します。

##IOS-XR上でNETCONFを有効にする設定

必須の設定
conf t
ssh server v2
ssh server netconf port 830
ssh timeout 120
netconf-yang agent ssh
commit
end

crypto key generate rsa
必要に応じて
conf t
control-plane
 management-plane
  inband
   interface GigabitEthernet0/0/0/0
    allow all
commit
end

今回の構成では、192.168.99.1がルータのアドレス、ユーザー名/パスワードがcisco/ciscoとなります。

##running-configを取得
まずは、現状のルータ(IOS-XR)からコンフィグを取得することから確認します。
NETCONF経由で設定したいコンフィグについては、まず最初に、ルータ上でコマンドラインから従来通り設定して、ここで取得したrunning-configの結果を参照して、以降で紹介しているように、スクリプトの中に引用するという流れが便利かなと思います。

get_running_001.py
#!/usr/bin/python

from ncclient import manager

# connect to netconf agent
m = manager.connect(host='192.168.99.1', port=830, username='cisco', password='cisco', hostkey_verify=False, device_params={'name': 'iosxr'})

#response = m.get_config(source='running', filter=payload)
print '###########################################################################'
print '### XML'
print '###########################################################################'
response = m.get_config(source='running').data_xml
print response

下記は、取得した結果をJSONで表示したいだけです。特に深い理由はありません。

get_running_002.py
#!/usr/bin/python

from ncclient import manager
from xml.dom import minidom
import lxml.etree as ET
import xmltodict
import json

# connect to netconf agent
m = manager.connect(host='192.168.99.1', port=830, username='cisco', password='cisco', hostkey_verify=False, device_params={'name': 'iosxr'})

#response = m.get_config(source='running', filter=payload)
print '###########################################################################'
print '### XML'
print '###########################################################################'
response = m.get_config(source='running').data_xml
print response

print '###########################################################################'
print '### XML Formatstring'
print '###########################################################################'
data = ET.fromstring(response)
print(ET.tostring(data, pretty_print=True))

print '###########################################################################'
print '### Convert to Dictionary'
print '###########################################################################'
data_dict = xmltodict.parse(response)
print(data_dict)

print '###########################################################################'
print '### Convert to JSON'
print '###########################################################################'
data_jason = json.dumps(data_dict, indent=4)
print(data_jason)

##hostnameを変更する

###XMLを直書きした場合

<config></config>に挟まれた設定内容(hostnameのコンフィグ部分)は、先のrunning-configを取得した結果からコピー&ペーストで引用しています。

edit_hostname.py
#!/usr/bin/env python

from ncclient import manager
from lxml import etree

config = """
<config>
    <host-names xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-cfg">
        <host-name>CE01</host-name>
    </host-names>
</config>
"""

# connect to netconf agent
m = manager.connect(host='192.168.99.1', port=830, username='cisco', password='cisco', hostkey_verify=False, device_params={'name': 'default'}, look_for_keys=False, allow_agent=False)

print '======================================================================'
print '=====                          response                          ====='
print '======================================================================'
response = m.edit_config(config=config, default_operation="merge", target="candidate").xml
print response
response = m.commit()
print response

###ElementTreeモジュールを利用した場合

edit_hostname_etree.py
#!/usr/bin/env python

from ncclient import manager
from lxml import etree
from xml.dom import minidom
import xmltodict
import json
import datetime

# build xml
config_e = etree.Element("config")
hostname = etree.SubElement(config_e, "host-names", nsmap = {None: 'http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-cfg'})
etree.SubElement(hostname, "host-name").text = 'CE01'

print '###########################################################################'
print '### XML'
print '###########################################################################'
print etree.tostring(config_e)

print '###########################################################################'
print '### XML Formatstring'
print '###########################################################################'
print etree.tostring(config_e, pretty_print=True)

print '###########################################################################'
print '### Convert to Dictionary'
print '###########################################################################'
data_dict = xmltodict.parse(etree.tostring(config_e))
print data_dict

print '###########################################################################'
print '### Convert to JSON'
print '###########################################################################'
data_jason = json.dumps(data_dict, indent=4)
print data_jason

# connect to netconf agent
m = manager.connect(host='192.168.99.1', port=830, username='cisco', password='cisco', hostkey_verify=False, device_params={'name': 'default'}, look_for_keys=False, allow_agent=False)

print '======================================================================'
print '=====                          response                          ====='
print '======================================================================'
response = m.edit_config(config=config_e, default_operation="merge", target="candidate")
print response
response = m.commit()
print response

参考までに、下記が実行結果になります。XML Formatstringの出力部分がXMLを直書きした場合と同じ内容であることが確認できます。

実行結果
$ python edit_hostname_etree.py 
###########################################################################
### XML
###########################################################################
<config><host-names xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-cfg"><host-name>CE01</host-name></host-names></config>
###########################################################################
### XML Formatstring
###########################################################################
<config>
  <host-names xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-cfg">
    <host-name>CE01</host-name>
  </host-names>
</config>

###########################################################################
### Convert to Dictionary
###########################################################################
OrderedDict([(u'config', OrderedDict([(u'host-names', OrderedDict([(u'@xmlns', u'http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-cfg'), (u'host-name', u'CE01')]))]))])
###########################################################################
### Convert to JSON
###########################################################################
{
    "config": {
        "host-names": {
            "@xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XR-shellutil-cfg", 
            "host-name": "CE01"
        }
    }
}
======================================================================
=====                          response                          =====
======================================================================
<?xml version="1.0"?>
<rpc-reply message-id="urn:uuid:3b59ff85-d686-4aa0-b0d9-8d7a952c09df" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <ok/>
</rpc-reply>

<?xml version="1.0"?>
<rpc-reply message-id="urn:uuid:bc03f285-9b91-41b1-9bb2-1c86e6a31cd0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <ok/>
</rpc-reply>

##interfaceのdescriptionを変更する

###XMLを直書きした場合

edit_interface-description.py
#!/usr/bin/env python

from ncclient import manager
from lxml import etree

config = """
<config>
    <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg">
        <interface-configuration>
            <active>act</active>
            <interface-name>GigabitEthernet0/0/0/0</interface-name>
            <description>NETCONF configured - 2019-03-12 00:00:00</description>
        </interface-configuration>
    </interface-configurations>
</config>
"""

# connect to netconf agent
m = manager.connect(host='192.168.99.1', port=830, username='cisco', password='cisco', hostkey_verify=False, device_params={'name': 'default'}, look_for_keys=False, allow_agent=False)

print '======================================================================'
print '=====                          response                          ====='
print '======================================================================'
response = m.edit_config(config=config, default_operation="merge", target="candidate").xml
print response
response = m.commit()
print response

###ElementTreeモジュールを利用した場合

edit_interface-description_etree.py
#!/usr/bin/env python

from ncclient import manager
from lxml import etree

import datetime
from xml.dom import minidom
import xmltodict
import json

current_time = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')

# build xml
config_e = etree.Element("config")
interface01 = etree.SubElement(config_e, "interface-configurations", nsmap = {None: 'http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg'})
interface01_cfg = etree.SubElement(interface01, "interface-configuration")
etree.SubElement(interface01_cfg, "active").text = 'act'
etree.SubElement(interface01_cfg, "interface-name").text = 'GigabitEthernet0/0/0/10'
etree.SubElement(interface01_cfg, "description").text  = 'NETCONF configured - ' + current_time
interface02 = etree.SubElement(config_e, "interface-configurations", nsmap = {None: 'http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg'})
interface02_cfg = etree.SubElement(interface01, "interface-configuration")
etree.SubElement(interface02_cfg, "active").text = 'act'
etree.SubElement(interface02_cfg, "interface-name").text = 'GigabitEthernet0/0/0/11'
etree.SubElement(interface02_cfg, "description").text  = 'NETCONF configured - ' + current_time

print '###########################################################################'
print '### XML'
print '###########################################################################'
print etree.tostring(config_e)

print '###########################################################################'
print '### XML Formatstring'
print '###########################################################################'
print etree.tostring(config_e, pretty_print=True)

print '###########################################################################'
print '### Convert to Dictionary'
print '###########################################################################'
data_dict = xmltodict.parse(etree.tostring(config_e))
print data_dict

print '###########################################################################'
print '### Convert to JSON'
print '###########################################################################'
data_jason = json.dumps(data_dict, indent=4)
print data_jason

# connect to netconf agent
m = manager.connect(host='192.168.99.1', port=830, username='cisco', password='cisco', hostkey_verify=False, device_params={'name': 'default'}, look_for_keys=False, allow_agent=False)

print '======================================================================'
print '=====                          response                          ====='
print '======================================================================'
response = m.edit_config(config=config_e, default_operation="merge", target="candidate")
print response
response = m.commit()
print response

参考までに、下記が実行結果からXML Formatstringの出力部分を抽出しています。

実行結果
###########################################################################
### XML Formatstring
###########################################################################
<config>
  <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg">
    <interface-configuration>
      <active>act</active>
      <interface-name>GigabitEthernet0/0/0/10</interface-name>
      <description>NETCONF configured - 2019-03-18 11:18:27</description>
    </interface-configuration>
    <interface-configuration>
      <active>act</active>
      <interface-name>GigabitEthernet0/0/0/11</interface-name>
      <description>NETCONF configured - 2019-03-18 11:18:27</description>
    </interface-configuration>
  </interface-configurations>
  <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg"/>
</config>

##interfaceにshutdownを設定する

###XMLを直書きした場合

sample.py
#!/usr/bin/env python

from ncclient import manager
from lxml import etree

config = """
<config>
    <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg">
        <interface-configuration>
            <active>act</active>
            <interface-name>GigabitEthernet0/0/0/10</interface-name>
            <shutdown/>
            <description>NETCONF configured - shutdown</description>
       </interface-configuration>
    </interface-configurations>
    <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg">
        <interface-configuration>
            <active>act</active>
            <interface-name>GigabitEthernet0/0/0/11</interface-name>
            <shutdown/>
            <description>NETCONF configured - shutdown</description>
       </interface-configuration>
    </interface-configurations>
</config>
"""

# connect to netconf agent
m = manager.connect(host='192.168.99.1', port=830, username='cisco', password='cisco', hostkey_verify=False, device_params={'name': 'default'}, look_for_keys=False, allow_agent=False)

print '======================================================================'
print '=====                          response                          ====='
print '======================================================================'
response = m.edit_config(config=config, default_operation="merge", target="candidate").xml
print response
response = m.commit()
print response

##interfaceにno shutを設定する

###XMLを直書きした場合

sample.py
#!/usr/bin/env python

from ncclient import manager
from lxml import etree

config = """
<config>
    <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg">
        <interface-configuration>
            <active>act</active>
            <interface-name>GigabitEthernet0/0/0/10</interface-name>
            <shutdown nc:operation="remove"></shutdown>
            <description>NETCONF configured - no shutdown</description>
       </interface-configuration>
    </interface-configurations>
    <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg">
        <interface-configuration>
            <active>act</active>
            <interface-name>GigabitEthernet0/0/0/11</interface-name>
            <shutdown nc:operation="remove"></shutdown>
            <description>NETCONF configured - no shutdown</description>
       </interface-configuration>
    </interface-configurations>
</config>
"""

# connect to netconf agent
m = manager.connect(host='192.168.99.1', port=830, username='cisco', password='cisco', hostkey_verify=False, device_params={'name': 'default'}, look_for_keys=False, allow_agent=False)

print '======================================================================'
print '=====                          response                          ====='
print '======================================================================'
response = m.edit_config(config=config, default_operation="merge", target="candidate").xml
print response
response = m.commit()
print response
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?