Network dynamic operations

Our API can now provide static information about the network; anything that we can store in the database can be returned to the user. It would be great if we can interact with our network directly, such as query the device for information or push configuration changes to the device.

We will start this process by leveraging the script we have already seen in Chapter 2, Low-Level Network Device Interactions for interacting with a device via Pexpect. We will modify the script slightly into a function we can repeatedly use in chapter9_pexpect_1.py:

# We need to install pexpect for our virtual env
$ pip install pexpect

$ cat chapter9_pexpect_1.py
import pexpect

def show_version(device, prompt, ip, username, password):
device_prompt = prompt
child = pexpect.spawn('telnet ' + ip)
child.expect('Username:')
child.sendline(username)
child.expect('Password:')
child.sendline(password)
child.expect(device_prompt)
child.sendline('show version | i V')
child.expect(device_prompt)
result = child.before
child.sendline('exit')
return device, result

We can test the new function via the interactive prompt:

>>> from chapter9_pexpect_1 import show_version
>>> print(show_version('iosv-1', 'iosv-1#', '172.16.1.225', 'cisco', 'cisco'))
('iosv-1', b'show version | i V Cisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T, RELEASE SOFTWARE (fc2) ')
>>>
Make sure your Pexpect script works before you proceed.

We can add a new API for querying the device version in chapter9_7.py:

from chapter9_pexpect_1 import show_version
...
@app.route('/devices/<int:id>/version', methods=['GET'])
def get_device_version(id):
device = Device.query.get_or_404(id)
hostname = device.hostname
ip = device.mgmt_ip
prompt = hostname+"#"
result = show_version(hostname, prompt, ip, 'cisco', 'cisco')
return jsonify({"version": str(result)})

The result will be returned to the requester:

$ http GET http://172.16.1.173:5000/devices/4/version
HTTP/1.0 200 OK
Content-Length: 210
Content-Type: application/json
Date: Fri, 24 Mar 2017 17:05:13 GMT
Server: Werkzeug/0.9.6 Python/3.5.2

{
"version": "('iosv-4', b'show version | i V\r\nCisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T, RELEASE SOFTWARE (fc2)\r\nProcessor board ID 9U96V39A4Z12PCG4O6Y0Q\r\n')"
}

We can also add another endpoint that would allow us to perform bulk action on multiple devices, based on their common fields. In the following example, the endpoint will take the device_role attribute in the URL and match it up with the appropriate device(s):

@app.route('/devices/<device_role>/version', methods=['GET'])
def get_role_version(device_role):
device_id_list = [device.id for device in Device.query.all() if device.role == device_role]
result = {}
for id in device_id_list:
device = Device.query.get_or_404(id)
hostname = device.hostname
ip = device.mgmt_ip
prompt = hostname + "#"
device_result = show_version(hostname, prompt, ip, 'cisco', 'cisco')
result[hostname] = str(device_result)
return jsonify(result)
Of course, looping through all the devices in Device.query.all() is not efficient, as in the preceding code. In production, we will use a SQL query that specifically targets the role of the device.

When we use the REST API, we can see that all the spine as well as leaf devices can be queried at the same time:

$ http GET http://172.16.1.173:5000/devices/spine/version
HTTP/1.0 200 OK
...
{
"iosv-1": "('iosv-1', b'show version | i V\r\nCisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T, RELEASE SOFTWARE (fc2)\r\n')",
"iosv-2": "('iosv-2', b'show version | i V\r\nCisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T, RELEASE SOFTWARE (fc2)\r\nProcessor board ID 9T7CB2J2V6F0DLWK7V48E\r\n')"
}


$ http GET http://172.16.1.173:5000/devices/leaf/version
HTTP/1.0 200 OK
...
{
"iosv-3": "('iosv-3', b'show version | i V\r\nCisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T, RELEASE SOFTWARE (fc2)\r\nProcessor board ID 9MGG8EA1E0V2PE2D8KDD7\r\n')",
"iosv-4": "('iosv-4', b'show version | i V\r\nCisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T, RELEASE SOFTWARE (fc2)\r\nProcessor board ID 9U96V39A4Z12PCG4O6Y0Q\r\n')"
}

As illustrated, the new API endpoints query the device(s) in real time and return the result to the requester. This works relatively well when you can guarantee a response from the operation within the timeout value of the transaction (30 seconds by default) or if you are OK with the HTTP session timing out before the operation is completed. One way to deal with the timeout issue is to perform the tasks asynchronously. We will look at an example in the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.198.81