Extending the python script to configure OSPF with ncclient

Previously I have successfully download the configuration from the netconf enabled router, now i have extended support to configure ospf.
This is a simple lab to further extend and get myself familiarize and comfortable with netconf.

During the lab I was careless, I inadvertently left a space on my netconf snippet that breaks my script and it generate an error, I turned on the debug on the router and found that a “<" was missing.

*Sep  2 04:38:08.709: NETCONF: netconf_xml_interpret.86.failure<?xml version="1.0" encoding="UTF-8"?><nc:rpc xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"message-id="urn:uuid:36abc85e-d850-45b5-95d0-fdf5d0a3226f"><nc:edit-config><nc:target><nc:running/></nc:target><config>
             cli-config-data>
                <cmd<cmd>interface Ethernet0/0</cmd>
                <cmd>ip address 10.0.0.2 255.255.255.252</cmd>
                <cmd>no shutdown</cmd>
            </config></nc:edit-config></nc:rpc>
*Sep  2 04:38:08.709: NETCONF: _nssd.87.snd.now<?xml version="1.0" encoding="UTF-8"?><rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><rpc-error><error-type>rpc</error-type><error-tag>unknown-element</error-tag><error-severity>error</error-severity><error-info><bad-element>cmd</bad-element></error-info></rpc-error></rpc-reply>

So on this lab I have put together a simple menu, the feature to download configuration file and added ospf.
Here's the entire code

import sys, time, os.path
from ncclient import manager
from getpass import getpass
from datetime import datetime
import logging


CREATE_INTERFACE_IP = """
        <config>
            <cli-config-data>
                <cmd>interface %s</cmd>
                <cmd>description Configured by ncclient</cmd>
                <cmd>ip address %s %s</cmd>
                <cmd>no shutdown</cmd>
            </cli-config-data>
        </config>
        """

CREATE_OSPF = """
        <config>
            <cli-config-data>
                <cmd>router ospf %i</cmd>
                <cmd>router-id %s</cmd>
                <cmd>passive-interface default</cmd>
                <cmd>no passive-interface %s</cmd>
                <cmd>network %s 0.0.0.0 area 0</cmd>
                <cmd>network %s 0.0.0.0 area 0</cmd>
            </cli-config-data>
        </config>
     """


def create_interface_ip(conn, interface, ip, mask):
    try:
        config_str = CREATE_INTERFACE_IP % (interface, ip, mask)
        conn.edit_config(target='running', config=config_str)
    except Exception:
        print('Exception occurs while creating interface %s' % interface)


def create_ospf(conn, ospf_id, rid, interface, network1, network2):
    try:
        config_str = CREATE_OSPF % (ospf_id, rid, interface, network1, network2)
        conn.edit_config(target='running', config=config_str)
    except  Exception:
        print('Exception occurs while creating ospf %i' % ospf_id)


def r_connect(host,port,usr,passwd):
    try:
            return manager.connect(host=host,
                    port=port,
                    username=usr,
                    password=passwd,
                    hostkey_verify=False)
    except EnvironmentError:
        print('Exception occurred while connecting %s' % host)


def main_menu():
    print(30 * "*", "Simple Conf Wizard", 30 * "*")
    print("1. Configure OSPF for router.")
    print("2. Download router configuration.")
    print("3. Quit")
    print(60 * "*")


def conn():
    user = input('Username: ')
    password = getpass()
    #loop = True
    with r_connect('192.168.1.46','22',user,password) as m:
        print("Connection is established" )
        time.sleep(3)
        #while loop:
        main_menu()
        try:
                choice = int(input("What you want to do? [1-3] "))
        except ValueError:
                print("Oops you have entered an invalid choice")
                #continue
        if choice == 1:
            ip = input("Enter IP address for Ethernet0/0: ")
            mask = input("Enter subnet mask: ")
            print("Interface has been configured")
            ospf_id = int(input("Enter OSPF id: "))
            router_id = input("Enter router id: ")
            network1 = input("Enter 1st network to be advertised: ")
            network2 = input("Enter 2nd network to be advertised: ")
            create_interface_ip(m, "Ethernet0/0", ip, mask)
            create_ospf(m,ospf_id,router_id,'Ethernet0/0',network1,network2)
            print("OSPF has been configured")
            #time.sleep(3)
        elif choice == 2:
            path = 'd:/temp/'
            today = datetime.now().strftime("%d%m%y-%H%M")
            filename = "config" + today + ".cfg"
            fullpath = os.path.join(path, filename)
            output = m.get_config(source='running').data_xml
            with open(fullpath, "w") as f:
                f.write(output)
                print("Backup saved in {}".format(fullpath))
        elif choice == 3:
            print("bye")
        else:
            print("You may have entered an invalid choice")


if __name__ == '__main__':
    #logging.basicConfig(level=logging.DEBUG)
    conn()

Before configuration

R3#sh ip int brief | include Ethernet0/0
Ethernet0/0 unassigned YES TFTP administratively down down


R3#sh run | s r o
R3#

No OSPF and interface e0/0 is down and no ip address assigned.

Test option 1
pycharm2.png

Here’s the outcome after option 1 was chosen:

R3#
*Sep 2 05:13:58.873: %LINK-3-UPDOWN: Interface Ethernet0/0, changed state to up
R3#
*Sep 2 05:13:59.878: %LINEPROTO-5-UPDOWN: Line protocol on Interface Ethernet0/0, changed state to up
R3#

The interface is up after the option 1 was selected.

Here is the router’s configuration:

R3#sh run int e0/0
Building configuration...

Current configuration : 102 bytes
!
interface Ethernet0/0
description Configured by ncclient
ip address 10.0.0.2 255.255.255.252
end

R3#sh run | s r o
router ospf 1
router-id 3.3.3.3
passive-interface default
no passive-interface Ethernet0/0
network 10.0.0.2 0.0.0.0 area 0
network 192.168.1.46 0.0.0.0 area 0
R3#

Test option 2
pycharm3

Here’s the file in my folder:
pycharm4.png

This is the configuration which was downloaded:
pycharm5

Visible password
The password was visible in debug, however it is not visible when it was executed outside the Python IDE environment:
pycharm6

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s