<jupyter_start><jupyter_text>Basics* YANG RFC: * YANG Stanards repo: https://github.com/YangModels/yang * Cisco Suuport for NetConf: https://developer.cisco.com/site/standard-network-devices/ Install initial libraries* use `pip install ncclient pyang napalm` to install base libraries     * `ncclient` connects remote hosts over netconf    * `pyang` converts YANG XML payload into readable tree format    * `napalm` conencts remote hosts for CLI configuration<jupyter_code>import ncclient
import pyang<jupyter_output><empty_output><jupyter_text>Access details Developers and network engineers access the IOS XE on CSR Recommended Code Always On Sandbox directly using the following information from Cisco IOS XE Sandbox https://devnetsandbox.cisco.com/RM/Diagram/Index/27d9747a-db48-4565-8d44-df318fce37ad?diagramType=Topology * CSR1000V Host: ios-xe-mgmt.cisco.com* SSH Port: 8181* NETCONF Port: 10000* RESTCONF Ports: 9443 (HTTPS)* Username: developer* Password: <PASSWORD>  import<jupyter_code>from ncclient import manager
import pyang<jupyter_output><empty_output><jupyter_text>`get_capabilities()`This functions prints all the supported capabilities from a given device<jupyter_code>def get_capabilities(m):
    print('***Here are the Remote Devices Capabilities***')
    for capability in m.server_capabilities:
        print(capability.split('?')[0])<jupyter_output><empty_output><jupyter_text>`get_schema()`This function prints some common schema supported by a given device. It's a menu driven function to choose from the follwoing schema.* IOS-XE native* IOS-Interface* IETF-Interface<jupyter_code>def get_schema(m):
    
    bad_choice=False
    
    print('Select a schema...')
    print('\t [1] IOS-XE')
    print('\t [2] IOS-interface')
    print('\t [3] IETF-interface')
    choice=int(input('Enter your choice...'))
    
    if choice == 1:
        s = 'Cisco-IOS-XE-native'
    elif choice == 2:
        s = 'Cisco-IOS-XE-interface-common'
    elif choice == 3:
        s = 'ietf-interfaces'
    else:
        bad_choice=True
    if bad_choice:
        schema = 'Invalid Choice...'
    else:
        schema = m.get_schema(s)
    print(schema)<jupyter_output><empty_output><jupyter_text>`get_running(m, to_json)`This function prints the running config of a given device with session variable `m`. The `to_json` vatiable is a boolian, if set as True the outcome is in JSON, otherwise in XML<jupyter_code>def get_running(m, to_json):
    import xmltodict 
    import json 
    response = m.get_config('running')
    if to_json:
        print(json.dumps(
                xmltodict.parse(
                    str(response) # parse() expects sring
                ),sort_keys=True, indent=4)   # to beautify json  
        )
    else:
        print(response)<jupyter_output><empty_output><jupyter_text>`get_config(m, to_json)`<jupyter_code>def get_config(m, to_json):
    import xmltodict    # to convert XML into dictionary
    import json         # to convert dictionary to JSON
    
    print('******** \nOptions\n********')
    print('\t [1] hostname')
    print('\t [2] Username')
    print('\t [3] Interface Config')
    print('\t [4] Static Route')
    print('\t [5] Routing protocol')
    choice = int(input('Enter your choice... '))
    
    if choice == 1: #hostname
        _filter="""
            <filter>
                <native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
                    <hostname></hostname>
                </native>
            </filter>
             """
    if choice == 2: #username
         _filter="""
            <filter>
                <native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
                    <username></username>
                </native>
            </filter>
             """
    if choice == 3: #interface 
         _filter="""
            <filter>
                <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
                    <interface>
                        <name></name>
                        <description></description>
                        <enabled></enabled>
                        <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
                        <address>
                                <ip></ip>
                                <netmask></netmask>
                            </address>
                        </ipv4>
                    </interface>
                </interfaces>
            </filter>
             """
    if choice == 4:  #static route
         _filter="""
            <filter>
                <interfaces xmlns="http://openconfig.net/yang/interfaces">
                    <ip><route></route></ip>
                </native>
            </filter>
             """
    if choice == 5:  # dynamic routes
        _filter="""
                <filter>
                    <routing xmlns="urn:ietf:params:xml:ns:yang:ietf-routing">
                        <routing-instance>
                            <name></name>
                            <description></description>
                            <routing-protocols>
                                <routing-protocol></routing-protocol>
                            </routing-protocols>
                        </routing-instance>
                    </routing>
                </filter>
                """
    
    response = m.get_config('running',_filter)
    if to_json:
        print(json.dumps(
                xmltodict.parse(
                    str(response) # parse() expects sring
                ),sort_keys=True, indent=4)   # to beautify json  
        )
    else:
        print(response)
def main():
    
    #assign global variables
    host='ios-xe-mgmt.cisco.com'
    ssh_port=8181
    nc_port=10000
    rc_port=9443
    uname='developer'
    pward='<PASSWORD>'
    
    print(f'Connecting... {host} ')
    with manager.connect( host=host,
                          port=10000,
                          username=uname,
                          password=<PASSWORD>,
                          hostkey_verify=False,
                          device_params={'name': 'default'},
                          look_for_keys=False, allow_agent=False
                        ) as m:
        while True:
            #os.system('clear')
            print('[OK]')
            print('OPTIONS')
            print('\t [1] Get Capabilities')
            print('\t [2] Get Schema')
            print('\t [3] Get Running Cofig')
            print('\t [4] Get Basic infor')
            print('\t [0] Exit')
            choice = int(input('Enter your choice...'))

            if choice == 0:
                break
            elif choice == 1:
                get_capabilities(m)
            elif choice == 2:
                get_schema(m)
            elif choice == 3:
                get_running(m, to_json=False)
            elif choice == 4:
                get_basic(m, to_json=True)
            else:
                print('Sorry invalid selection... ')
main()<jupyter_output>Connecting... ios-xe-mgmt.cisco.com 
[OK]
OPTIONS
	 [1] Get Capabilities
	 [2] Get Schema
	 [3] Get Running Cofig
	 [4] Get Basic infor
	 [0] Exit
Enter your choice...4
******** 
Options
********
	 [1] hostname
	 [2] Username
	 [3] Interface Config
	 [4] Static Route
	 [5] Routing protocol
Enter your choice... 3
{
    "rpc-reply": {
        "@message-id": "urn:uuid:83b38023-b6de-4ac6-afd2-53adbb5829eb",
        "@xmlns": "urn:ietf:params:xml:ns:netconf:base:1.0",
        "@xmlns:nc": "urn:ietf:params:xml:ns:netconf:base:1.0",
        "data": {
            "interfaces": {
                "@xmlns": "urn:ietf:params:xml:ns:yang:ietf-interfaces",
                "interface": [
                    {
                        "description": "MANAGEMENT INTERFACE - DON'T TOUCH ME",
                        "enabled": "true",
                        "ipv4": {
                            "@xmlns": "urn:ietf:params:xml:ns:yang:ietf-ip",
                            "address": {
                     [...]<jupyter_text>Accessing the device using Napalm over SSH<jupyter_code>import napalm as npm

#assign global variables
host='ios-xe-mgmt.cisco.com'
ssh_port=8181
nc_port=10000
rc_port=9443
uname='developer'
pward='C1sco12345'

driver = npm.get_network_driver('iosxr')

router = driver(hostname = 'ios-xe-mgmt.cisco.com',
                username = 'developer',
                password = 'C1sco12345',
                optional_args={"port": 8181}
               )
print('Connecting...')
router.open()
print('[OK]')

router.close()
print('Connection Closed..')<jupyter_output>Connecting...
[OK]
Connection Closed..<jupyter_text>Connecting Using Raw SSH<jupyter_code>import paramiko
#assign global variables
host='ios-xe-mgmt.cisco.com'
ssh_port=8181
nc_port=10000
rc_port=9443
uname='developer'
pword='<PASSWORD>'

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print('Connecting using SSH...')
ssh.connect(host, ssh_port, uname, pword)

cmd = input('Enter a Command: ')
stdin, stdout, stderr = ssh.exec_command(cmd)

for line in stdout.readlines():
    print(line)<jupyter_output>Enter a Command: sh ip route 


Welcome to the DevNet Sandbox for CSR1000v and IOS XE



The following programmability features are already enabled:

  - NETCONF

  - RESTCONF



Thanks for stopping by.





Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP

       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 

       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2

       E1 - OSPF external type 1, E2 - OSPF external type 2

       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2

       ia - IS-IS inter area, * - candidate default, U - per-user static route

       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP

       a - application route

       + - replicated route, % - next hop override, p - overrides from PfR



Gateway of last resort is 10.10.20.254 to network 0.0.0.0



S*    0.0.0.0/0 [1/0] via 10.10.20.254, GigabitEthernet1

      10.0.0.0/8 is variably subnetted, 4 subnets, 2 m[...]
{'fraction_non_alphanumeric': 0.12183794466403162, 'fraction_numerical': 0.021343873517786563, 'mean_word_length': 1.9481503058549374, 'pattern_counts': {'":': 14, '<': 88, '<?xml version=': 0, '>': 88, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 21}, 'pii_count': 5, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '346484', 'license': 'MIT', 'n_tokens_mistral': 3311, 'n_tokens_neox': 3067, 'n_words': 740, 'path': 'ENCOR/Network Programmability .ipynb', 'repo_name': 'rishiCSE17/CCIE_ENT', 'size': '10115'}