COSC Learning Lab: Inventory

Keyword Definition
Inventory List of network devices that the Controller has access to.
Network Device Routers, switches, etc.
Controller Service that intermediates between client applications and network devices. E.g. ODL, COSC
ODL Open Day Light
COSC Cisco Open Source Controller, enhanced ODL
Mount Introduce a Network Device to a Controller.
Capability A feature of a network device that is dynamically discovered.

Introduction

This page explores the connection from a Controller to multiple network devices. The topics are:

  • Mount network devices on the Controller.
  • Obtain the inventory from the Controller.
  • Dis-mount network devices from the Controller.
  • Verify that mounted network devices are present in the inventory.
  • Obtain the connection status of inventory items.
  • Count the capabilities of inventory items.
  • Obtain data for individual network devices
  • Process Controller response of type JSON and XML.
  • HTTP Reference table for every HTTP request and response.

Table of Contents

Prologue

If the Learning Lab team have provided you with either:

  • a Python Interactive Shell, or
  • an IPython Notebook

then please proceed. Otherwise, please follow the instructions on web page: How to set up your computer

Import the Python module named learning_lab.


In [1]:
import learning_lab
from inspect import getsource
from importlib import import_module

Sample Scripts

01_inventory_mount.py

Import


In [2]:
script = import_module('01_inventory_mount', 'learning_lab')

Documentation


In [3]:
help(script)


Help on module 01_inventory_mount:

NAME
    01_inventory_mount - Sample usage of function 'inventory_mount'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_mount.py

DESCRIPTION
    Print the function's documentation then apply the function to every device that is configured and not mounted.

FUNCTIONS
    main()


Code


In [4]:
print(getsource(script.main))


def main():
    print(plain(doc(inventory_mount)))
    unmounted_list = inventory_unmounted()
    if not unmounted_list:
        print('There are no (configured) devices unmounted.')
    else:
        configured = settings.config['network_device']
        for device_name in unmounted_list:
            device_config = configured[device_name]
            print('inventory_mount(' + device_name, *device_config.values(), sep=', ', end=')\n')
            inventory_mount(
                device_name,
                device_config['address'],
                device_config['port'],
                device_config['username'],
                device_config['password'])

Run


In [5]:
script.main()


Python Library Documentation: function inventory_mount in module basics.inventory

inventory_mount(device_name, device_address, device_port, device_username, device_password)
    Add the specified network device to the inventory of the Controller.

There are no (configured) devices unmounted.

HTTP

The HTTP requests for this script can be examined here

The HTTP requests for this script are the same as for:

01_inventory.py

Import


In [6]:
script = import_module('01_inventory', 'learning_lab')

Documentation


In [7]:
help(script)


Help on module 01_inventory:

NAME
    01_inventory - Sample usage of function 'inventory'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory.py

DESCRIPTION
    Print the function's documentation then invoke the function and print the output.

FUNCTIONS
    main()


Code


In [8]:
print(getsource(script.main))


def main():
    print(plain(doc(inventory)))
    print(inventory())

Run


In [9]:
script.main()


Python Library Documentation: function inventory in module basics.inventory

inventory()
    Names of network devices known to the Controller.
    
    The inventory includes all mounted devices.
    The inventory excludes all unmounted devices.
    The inventory can contain devices that are neither mounted nor unmounted.
    The inventory includes all connected devices.
    The inventory can contain unconnected devices.
    Returns a list.

['openflow:1', 'xrvr-1', 'xrvr-2', 'openflow:2', 'openflow:3']

HTTP

The HTTP requests for this script can be examined here

01_device_dismount.py

Import


In [10]:
script = import_module('01_device_dismount', 'learning_lab')

Documentation


In [11]:
help(script)


Help on module 01_device_dismount:

NAME
    01_device_dismount - Sample usage of function 'device_dismount'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_device_dismount.py

DESCRIPTION
    Print the function's documentation then apply the function to any one device that is mounted.

FUNCTIONS
    main()


Code


In [12]:
print(getsource(script.main))


def main():
    print(plain(doc(device_dismount)))
    mounted_list = inventory_mounted()
    if not mounted_list:
        print('There are no mounted devices to dismount.')
    else:
        device_name = mounted_list[0]
        print('device_dismount(' + device_name, end=')\n')
        device_dismount(device_name)

Run


In [13]:
script.main()


Python Library Documentation: function device_dismount in module basics.inventory

device_dismount(device_name)
    Remove one network device from the inventory of the Controller.
    
    It is the responsibility of the caller to ensure that the specified device is mounted.

device_dismount(xrvr-1)

HTTP

The HTTP requests for this script can be examined here.

01_inventory_unmounted.py

Import


In [14]:
script = import_module('01_inventory_unmounted', 'learning_lab')

Documentation


In [15]:
help(script)


Help on module 01_inventory_unmounted:

NAME
    01_inventory_unmounted - Sample usage of function 'inventory_unmounted'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_unmounted.py

DESCRIPTION
    Print the function's documentation then invoke the function and print the output.

FUNCTIONS
    main()


Code


In [16]:
print(getsource(script.main))


def main():
    print(plain(doc(inventory_unmounted)))
    print(inventory_unmounted())

Run


In [17]:
script.main()


Python Library Documentation: function inventory_unmounted in module basics.inventory

inventory_unmounted()
    Names of network devices not mounted on the Controller.
    
    Returns a list.

[]

HTTP

The HTTP request for this script is the same as 01_inventory_mounted.py.

01_inventory_mounted.py

Import


In [18]:
script = import_module('01_inventory_mounted', 'learning_lab')

Documentation


In [19]:
help(script)


Help on module 01_inventory_mounted:

NAME
    01_inventory_mounted - Sample usage of function 'inventory_mounted'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_mounted.py

DESCRIPTION
    Print the function's documentation then invoke the function and print the output.

FUNCTIONS
    main()


Code


In [20]:
print(getsource(script.main))


def main():
    print(plain(doc(inventory_mounted)))
    print(inventory_mounted())

Run


In [21]:
script.main()


Python Library Documentation: function inventory_mounted in module basics.inventory

inventory_mounted()
    Names of network devices mounted on the Controller.
    
    Output a list of names.
    Mounted devices are a subset of the inventory.
    Mounted devices can be connected or not.

['xrvr-1', 'xrvr-2']

HTTP

The HTTP requests for this script can be examined here.

01_inventory_mount.py

Import


In [22]:
script = import_module('01_inventory_mount', 'learning_lab')

Documentation


In [23]:
help(script)


Help on module 01_inventory_mount:

NAME
    01_inventory_mount - Sample usage of function 'inventory_mount'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_mount.py

DESCRIPTION
    Print the function's documentation then apply the function to any one device that is configured and not mounted.

FUNCTIONS
    main()


Code


In [24]:
print(getsource(script.main))


def main():
    print(plain(doc(inventory_mount)))
    configs = settings.config['network_device']
    if not configs:
        print('There are no devices configured in the settings.')
    else:
        configured = configs.keys()
        mounted_list = inventory_mounted()
        unmounted_list = list(set(configured) - set(mounted_list)) if mounted_list else configured
        if not unmounted_list:
            print('All configured devices are mounted.')
        else:
            device_name = unmounted_list[0]
            device_config = configs[device_name]
            print('inventory_mount(' + device_name, *device_config.values(), sep=', ', end=')\n')
            inventory_mount(
                device_name,
                device_config['address'],
                device_config['port'],
                device_config['username'],
                device_config['password'])

Run


In [25]:
script.main()


Python Library Documentation: function inventory_mount in module basics.inventory

inventory_mount(device_name, device_address, device_port, device_username, device_password)
    Add the specified network device to the inventory of the Controller.

All configured devices are mounted.

HTTP

The HTTP requests for this script can be examined here.

01_inventory_summary.py

Import


In [26]:
script = import_module('01_inventory_summary', 'learning_lab')

Documentation


In [27]:
help(script)


Help on module 01_inventory_summary:

NAME
    01_inventory_summary - Sample usage of function 'inventory_summary'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_summary.py

DESCRIPTION
    Print the function's documentation then invoke the function and print the output.
    
    The related function `inventory()` returns just the name of each network device. 
    To see more than just the name of the device use function `inventory_summary()`.

FUNCTIONS
    main()


Code


In [28]:
print(getsource(script.main))


def main():
    print(plain(doc(inventory_summary)))
    print('InventorySummary fields:', *InventorySummary._fields, sep='\n\t', end='\n\n')
    print(*inventory_summary(), sep='\n')

Run


In [29]:
script.main()


Python Library Documentation: function inventory_summary in module basics.inventory

inventory_summary()
    'Return a list containing one instance of InventorySummary per inventory item.

InventorySummary fields:
	name
	connected
	capabilities

InventorySummary(name='openflow:1', connected=False, capabilities=5)
InventorySummary(name='xrvr-1', connected=True, capabilities=131)
InventorySummary(name='xrvr-2', connected=True, capabilities=131)
InventorySummary(name='controller-config', connected=True, capabilities=182)
InventorySummary(name='openflow:2', connected=False, capabilities=5)
InventorySummary(name='openflow:3', connected=False, capabilities=5)

HTTP

The HTTP request for this script is the same as 01_inventory.py.

01_inventory_summary_html.py

Import


In [30]:
script = import_module('01_inventory_summary_html', 'learning_lab')

Documentation


In [31]:
help(script)


Help on module 01_inventory_summary_html:

NAME
    01_inventory_summary_html - Sample usage of function 'inventory_summary'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_summary_html.py

DESCRIPTION
    Invoke the function and convert the output to HTML.
    See also: 01_inventory_summary.py

FUNCTIONS
    main()


Code


In [32]:
print(getsource(script.main))


def main():
    rows = ''
    for summary in inventory_summary():
        rows += _row_template % summary
    print(_table_template % ''.join(rows))

Run


In [33]:
%%capture console
script.main()

In [34]:
from IPython.core.display import HTML
HTML(console.stdout)


Out[34]:
Name Is Connected Number of Capabilities
openflow:1 False 5
xrvr-1 True 131
xrvr-2 True 131
controller-config True 182
openflow:2 False 5
openflow:3 False 5

HTTP

The HTTP request for this script is the same as 01_inventory.py.

01_inventory_json.py

Import


In [35]:
script = import_module('01_inventory_json', 'learning_lab')

Documentation


In [36]:
help(script)


Help on module 01_inventory_json:

NAME
    01_inventory_json - Sample usage of function 'inventory_json'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_json.py

DESCRIPTION
    Demonstrate how to process JSON.
    The function output is 'reduced' to a summary per network device.
    The summary is comparable to function inventory_summary().
    See also: function 'inventory()', which processes XML.

FUNCTIONS
    main()

DATA
    capability_field = u'netconf-node-inventory:initial-capability'
    connected_field = u'netconf-node-inventory:connected'
    name_field = u'id'


Code


In [37]:
print getsource(script.main)


def main():
    print(plain(doc(inventory_json)))
    print('Summary of lengthy JSON response:')
    print(*[
        InventorySummary(
            item[name_field],
            connected_field in item and item[connected_field],
            len(item[capability_field]) if capability_field in item else 0
        )
        for item in inventory_json()
    ], sep='\n')

Run


In [38]:
script.main()


Python Library Documentation: function inventory_json in module basics.inventory

inventory_json()
    Return a list of inventory items in JSON representation.

Summary of lengthy JSON response:
InventorySummary(name=u'openflow:1', connected=False, capabilities=0)
InventorySummary(name=u'xrvr-1', connected=True, capabilities=131)
InventorySummary(name=u'xrvr-2', connected=True, capabilities=131)
InventorySummary(name=u'controller-config', connected=True, capabilities=182)
InventorySummary(name=u'openflow:2', connected=False, capabilities=0)
InventorySummary(name=u'openflow:3', connected=False, capabilities=0)

HTTP

The HTTP requests for this script can be examined here.

Compare processing of JSON versus XML

Function inventory_summary() requests a HTTP response of type XML instead of JSON. The processing of XML versus JSON is similar yet different.


In [39]:
from basics.inventory import inventory_xml, inventory_summary_from_xml
print(getsource(inventory_summary_from_xml))
inventory_summary_from_xml(inventory_xml())


def inventory_summary_from_xml(xml):
    return [ 
        InventorySummary(
            name=item.findtext('i:id', namespaces=_inventory_namespaces),
            connected=item.findtext('nni:connected', namespaces=_inventory_namespaces) == 'true',
            capabilities=int(
                item.xpath('count(nni:initial-capability)', namespaces=_inventory_namespaces) + 
                item.xpath('count(fi:switch-features/fi:capabilities)', namespaces=_inventory_namespaces)
            )
        ) for item in xml.iterfind('i:node', namespaces=_inventory_namespaces)
    ]

Out[39]:
[InventorySummary(name='openflow:1', connected=False, capabilities=5),
 InventorySummary(name='xrvr-1', connected=True, capabilities=131),
 InventorySummary(name='xrvr-2', connected=True, capabilities=131),
 InventorySummary(name='controller-config', connected=True, capabilities=182),
 InventorySummary(name='openflow:2', connected=False, capabilities=5),
 InventorySummary(name='openflow:3', connected=False, capabilities=5)]

01_inventory_connected.py

Import


In [40]:
script = import_module('01_inventory_connected', 'learning_lab')

Documentation


In [41]:
help(script)


Help on module 01_inventory_connected:

NAME
    01_inventory_connected - Sample usage of function 'inventory_connected'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_connected.py

DESCRIPTION
    Print the function's documentation then invoke the function and print the output.

FUNCTIONS
    main()


Code


In [42]:
print(getsource(script.main))


def main():
    print(_doc)
    print(inventory_connected())

Run


In [43]:
script.main()


Python Library Documentation: function inventory_connected in module basics.inventory

inventory_connected()
    Names of network devices connected to the Controller.
    
    Output a list of names.
    Connected devices are a subset of the inventory.

['xrvr-1', 'xrvr-2']

HTTP

The HTTP request for this script is the same as 01_inventory.py.

01_inventory_unreachable.py

Import


In [44]:
script = import_module('01_inventory_unreachable', 'learning_lab')

Documentation


In [45]:
help(script)


Help on module 01_inventory_unreachable:

NAME
    01_inventory_unreachable - Mount a network device that is intentionally unreachable.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_unreachable.py

DESCRIPTION
    Verify that the device is present in the inventory and is mounted but not connected.

FUNCTIONS
    main()

DATA
    device_address = '192.168.0.999'
    device_name = 'unreachable'
    device_password = 'cisco'
    device_port = 830
    device_username = 'cisco'


Code


In [46]:
print(getsource(script.main))


def main():
    if mounted(device_name):
        print('Preparation.')     
        print('device_dismount(', device_name, sep='', end=')\n')
        device_dismount(device_name)
        time.sleep(1)
        print()
        
    print('Verify absence of unreachable device.')     
    in_inventory = device_name in inventory()
    in_mounted = device_name in inventory_mounted()
    print(device_name + ' in inventory', in_inventory, sep=': ')
    print(device_name + ' is mounted', in_mounted, sep=': ')
    assert not in_inventory
    assert not in_mounted
    del in_inventory, in_mounted

    print()
    
    print('Discover effect of mounting unreachable device.')     
    print('inventory_mount(' + device_name, device_address, device_port, sep=', ', end=')\n')
    inventory_mount(device_name, device_address, device_port, device_username, device_password)
    time.sleep(1)
    in_connected = device_name in inventory_connected()
    in_mounted = device_name in inventory_mounted()
    print(device_name + ' is connected', in_connected, sep=': ')
    print(device_name + ' is mounted', in_mounted, sep=': ')
    assert not in_connected
    assert in_mounted

Run


In [47]:
script.main()


Verify absence of unreachable device.
unreachable in inventory: False
unreachable is mounted: False

Discover effect of mounting unreachable device.
inventory_mount(unreachable, 192.168.0.999, 830)
unreachable is connected: False
unreachable is mounted: True

HTTP

The HTTP requests for this script are the same as for:

01_inventory_not_connected.py

Import


In [48]:
script = import_module('01_inventory_not_connected', 'learning_lab')

Documentation


In [49]:
help(script)


Help on module 01_inventory_not_connected:

NAME
    01_inventory_not_connected - Sample usage of function 'inventory_not_connected'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_not_connected.py

DESCRIPTION
    Print the function's documentation then invoke the function and print the output.

FUNCTIONS
    main()


Code


In [50]:
print(getsource(script.main))


def main():
    print(plain(doc(inventory_not_connected)))
    print(inventory_not_connected())

Run


In [51]:
script.main()


Python Library Documentation: function inventory_not_connected in module basics.inventory

inventory_not_connected()
    Names of network devices mounted on the Controller but not connected to the Controller.

['openflow:1', 'unreachable', 'openflow:2', 'openflow:3']

HTTP

The HTTP request for this script is the same as 01_inventory.py.

01_inventory_integrity.py

Import


In [52]:
script = import_module('01_inventory_integrity', 'learning_lab')

Documentation


In [53]:
help(script)


Help on module 01_inventory_integrity:

NAME
    01_inventory_integrity - Integrity check of all inventory related function output.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_inventory_integrity.py

DESCRIPTION
    Obtain the entire inventory and the various subsets and validate them.

FUNCTIONS
    main()


Code


In [54]:
print(getsource(script.main))


def main():
    inventory_set = set(inventory())
    inventory_connected_set = set(inventory_connected())
    inventory_not_connected_set = set(inventory_not_connected())
    inventory_mounted_set = set(inventory_mounted())
    inventory_unmounted_set = set(inventory_unmounted())
    empty_set = set()
    
    print("The set of 'connected' devices is a subset of the inventory:",
           inventory_connected_set <= inventory_set)
    assert inventory_connected_set <= inventory_set
    
    print("The set of 'not connected' devices is also a subset of the inventory:",
           inventory_not_connected_set <= inventory_set)
    assert inventory_not_connected_set <= inventory_set
    
    print("There are no network devices in both the 'connected' set and the 'not connected' set:",
           inventory_not_connected_set & inventory_connected_set == empty_set)
    assert inventory_not_connected_set & inventory_connected_set == empty_set
    
    print("Every network device in the inventory is in either the 'connected' set or the 'not connected' set:",
           inventory_connected_set | inventory_not_connected_set == inventory_set)
    assert inventory_connected_set | inventory_not_connected_set == inventory_set
    
    print()
    
    print("The set of 'mounted' devices is a subset of the inventory:",
           inventory_mounted_set <= inventory_set)
    assert inventory_mounted_set <= inventory_set
    
    print("The set of 'unmounted' devices has no intersection with the inventory:",
           inventory_unmounted_set & inventory_set == empty_set)
    assert inventory_unmounted_set & inventory_set == empty_set
    
    print("There are no network devices in both the 'mounted' set and the 'unmounted' set:",
           inventory_unmounted_set & inventory_mounted_set == empty_set)
    assert inventory_unmounted_set & inventory_mounted_set == empty_set

Run


In [55]:
script.main()


The set of 'connected' devices is a subset of the inventory: True
The set of 'not connected' devices is also a subset of the inventory: True
There are no network devices in both the 'connected' set and the 'not connected' set: True
Every network device in the inventory is in either the 'connected' set or the 'not connected' set: True

The set of 'mounted' devices is a subset of the inventory: True
The set of 'unmounted' devices has no intersection with the inventory: True
There are no network devices in both the 'mounted' set and the 'unmounted' set: True

HTTP

The HTTP requests for this script are the same as for:

01_device_mounted.py

Import


In [56]:
script = import_module('01_device_mounted', 'learning_lab')

Documentation


In [57]:
help(script)


Help on module 01_device_mounted:

NAME
    01_device_mounted - Sample usage of function 'mounted'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_device_mounted.py

DESCRIPTION
    Print the function's documentation then invoke the function and print the output.

FUNCTIONS
    main()


Code


In [58]:
print(getsource(script.main))


def main():
    print(plain(doc(mounted)))
    device_names = settings.config['network_device'].keys()
    if not device_names:
        print('There are no devices configured in the settings.')
    else:
        device_name = device_names[0]
        print('is mounted(%s):' % device_name, mounted(device_name))

Run


In [59]:
script.main()


Python Library Documentation: function mounted in module basics.inventory

mounted(device_name)
    Determine whether a single device is mounted on the Controller.
    
    Return True if mounted.

is mounted(xrvr-2): True

HTTP

The HTTP request for this script is here

01_device_connected.py

Import


In [60]:
script = import_module('01_device_connected', 'learning_lab')

Documentation


In [61]:
help(script)


Help on module 01_device_connected:

NAME
    01_device_connected - Sample usage of function 'connected'.

FILE
    /home/virl/git/cosc-learning-labs/src/learning_lab/01_device_connected.py

DESCRIPTION
    Print the function's documentation then invoke the function and print the output.

FUNCTIONS
    main()


Code


In [62]:
print(getsource(script.main))


def main():
    print(plain(doc(connected)))
    device_names = inventory_mounted()
    if not device_names:
        print('There are no devices mounted on the Controller.')
    else:
        device_name = device_names[0]
        print('is connected(%s):' % device_name, connected(device_name))

Run


In [63]:
script.main()


Python Library Documentation: function connected in module basics.inventory

connected(device_name)
    Determine whether a single device is connected to the Controller.
    
    Return True if connected.

is connected(xrvr-2): True

HTTP

The HTTP request for this script is here

Conclusion

The inventory was obtained from the Controller and examined. Network devices were mounted on the Controller then dis-mounted. The inventory data was shown to be lengthy and a demonstration of reduction was applied to both JSON and XML data. The connection status and the number of capabilities were extracted. Data available for groups of network devices was shown to be also available for individual network devices. The details of each HTTP request and response were published in reference tables.