Getting Started with Netconf/Yang/Python on a Cicso Catalyst 9300
I put together this quick reference guide for Netconf/Yang with Python for the Catalyst 9300. I assume this with work on the 3850 as well (have not tested it)
Enable Netconf Yang on the device.
!Create a user account with level 15 access
username admin privilege 15 secret cisco123
!enable netconf-yang
netconf-yang
https://developer.cisco.com/docs/ios-xe/#!enabling-netconf-on-ios-xe/netconf
Run examples.
Requirement
Python 3.6
Installing python dependencies:
> pip3 install lxml ncclient
Running script: (save as example.py)
> python example.py
-u <username> -p <password> --host <ip/hostname>
--port 830
*I am testing these scripts from Linux*
you can get all code in listed on github
git clone https://github.com/caiena78/Netconf_Part1.git
Enable Netconf Yang on the device.
!Create a user account with level 15 access
username admin privilege 15 secret cisco123
!enable netconf-yang
netconf-yang
https://developer.cisco.com/docs/ios-xe/#!enabling-netconf-on-ios-xe/netconf
Run examples.
Requirement
Python 3.6
Installing python dependencies:
> pip3 install lxml ncclient
Running script: (save as example.py)
> python example.py
-u <username> -p <password> --host <ip/hostname>
--port 830
*I am testing these scripts from Linux*
you can get all code in listed on github
git clone https://github.com/caiena78/Netconf_Part1.git
Requirement
Python 3.6
Installing python dependencies:
> pip3 install lxml ncclient
Running script: (save as example.py)
> python example.py
-u <username> -p <password> --host <ip/hostname>
--port 830
*I am testing these scripts from Linux*
you can get all code in listed on github
git clone https://github.com/caiena78/Netconf_Part1.git
Get the config.
import sys
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
filter = '''
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native"/>
'''
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
filter = '''
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native"/>
'''
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
if len(filter) > 0:
data = '''<filter>%s</filter>''' % filter
else:
data = None
m.timeout = 120
reply = m.get(data)
# Pretty print the XML reply
xmlDom = xml.dom.minidom.parseString(str(reply))
print(xmlDom.toprettyxml(indent=' '))
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
if len(filter) > 0:
data = '''<filter>%s</filter>''' % filter
else:
data = None
m.timeout = 120
reply = m.get(data)
# Pretty print the XML reply
xmlDom = xml.dom.minidom.parseString(str(reply))
print(xmlDom.toprettyxml(indent=' '))
List the capabilities of the switch
import sys
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
for c in m.server_capabilities:
print(c)
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
for c in m.server_capabilities:
print(c)
Get a list of all interfaces
import sys
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
data='''
<filter>
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface/>
</native>
</filter>
'''
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
m.timeout = 120
reply = m.get(data)
# Pretty print the XML reply
xmlDom = xml.dom.minidom.parseString(str(reply))
print(xmlDom.toprettyxml(indent=' '))
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
data='''
<filter>
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface/>
</native>
</filter>
'''
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
m.timeout = 120
reply = m.get(data)
# Pretty print the XML reply
xmlDom = xml.dom.minidom.parseString(str(reply))
print(xmlDom.toprettyxml(indent=' '))
List details on GigabitEthernet1/0/10 interface
import sys
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
data='''
<filter>
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface>
<GigabitEthernet>
<name>1/0/10</name>
</GigabitEthernet>
</interface>
</native>
</filter>
'''
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
m.timeout = 120
reply = m.get(data)
# Pretty print the XML reply
xmlDom = xml.dom.minidom.parseString(str(reply))
print(xmlDom.toprettyxml(indent=' '))
Disable a interface with a description.
import sys
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
payload = '''
<config>
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface>
<GigabitEthernet>
<name>1/0/10</name>
<description>disabled by Netconf</description>
<shutdown/>
</GigabitEthernet>
</interface>
</native>
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
payload = '''
<config>
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface>
<GigabitEthernet>
<name>1/0/10</name>
<description>disabled by Netconf</description>
<shutdown/>
</GigabitEthernet>
</interface>
</native>
</config>
'''
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
reply = m.edit_config(payload,target='running')
xmlDom = xml.dom.minidom.parseString(str(reply))
print(xmlDom.toprettyxml(indent=' '))
'''
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
reply = m.edit_config(payload,target='running')
xmlDom = xml.dom.minidom.parseString(str(reply))
print(xmlDom.toprettyxml(indent=' '))
Enable a Interface with a description.
***If the interface is not shutdown you will receive a error if you try to no shut a interface that
is already enabled***
import sys
from argparse import ArgumentParser
from ncclient import manager
import xml.dom.minidom
payload = '''
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface>
<GigabitEthernet>
<name>1/0/10</name>
<description>Enabled by Netconf</description>
<!--If you try to enable a interface that is enabled already it will cause an RPC error -->
<shutdown xc:operation="delete"/>
</GigabitEthernet>
</interface>
</native>
</config>
'''
if __name__ == '__main__':
parser = ArgumentParser(description='Select options.')
# Input parameters
parser.add_argument('--host', type=str, required=True,
help='The device IP or DN. Required')
parser.add_argument('-u', '--username', type=str, required=True,
help='Username on the device. Required')
parser.add_argument('-p', '--password', type=str, required=True,
help='Password for the username. Required')
parser.add_argument('--port', type=int, default=830,
help='Specify this if you want a non-default port. Default: 830')
args = parser.parse_args()
m = manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
device_params={'name':'csr'})
reply = m.edit_config(payload,target='running')
xmlDom = xml.dom.minidom.parseString(str(reply))
print(xmlDom.toprettyxml(indent=' '))
configure a trunk interface with allowed vlan's configured (100,200).
***If the interface is not shutdown you will receive a error if you try to no shut a interface that
is already enabled***
import lxml.etree as ET
from argparse import ArgumentParser
from ncclient import manager
from ncclient.operations import RPCError
payload = """
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface>
<GigabitEthernet>
<name>1/0/9</name>
<description>Netconf Trunk Port</description>
<!--If you try to enable a interface that is enabled already it will cause an RPC error -->
<shutdown xc:operation="delete"/>
<switchport>
<mode xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-switch">
<trunk/>
</mode>
<trunk xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-switch">
<allowed>
<vlan>
<vlans>100,200</vlans>
</vlan>
</allowed>
</trunk>
</switchport>
</GigabitEthernet>
</interface>
</native>
</config>
"""
if __name__ == '__main__':
parser = ArgumentParser(description='Usage:')
# script arguments
parser.add_argument('-a', '--host', type=str, required=True,
help="Device IP address or Hostname")
parser.add_argument('-u', '--username', type=str, required=True,
help="Device Username (netconf agent username)")
parser.add_argument('-p', '--password', type=str, required=True,
help="Device Password (netconf agent password)")
parser.add_argument('--port', type=int, default=830,
help="Netconf agent port")
args = parser.parse_args()
# connect to netconf agent
with manager.connect(host=args.host,
port=args.port,
username=args.username,
password=args.password,
timeout=90,
hostkey_verify=False,
device_params={'name': 'csr'}) as m:
# execute netconf operation
try:
data = m.edit_config(target='running', config=payload).xml
except RPCError as e:
data = e._raw
print(data)
Comments
Post a Comment