What You’ll Need

What You’ll Need: Linux and Mac Users

What You’ll Need: Windows Users

Additional Important Points

Basic Python scripts are typically executed linearly. For example, basic scripts would start executing at the first line and would then execute one line at a time by moving through each line sequentially until the last line was reached.

In order to make our scripts more sophisticated, we can implement conditional statements. Conditional statements enable our script to make decisions. Using conditional statements, a script can decide to execute or not execute lines of code based on whether a condition is True or False. When using conditional statements in our script, our script will no longer be executed in a linear fashion because certain parts of the script might be skipped if a certain condition is not met.

One type of conditional statement in Python is an if statement.

To see how if statements work, let’s go over some code. Create a new script called numbers.py. Add the following code into your numbers.py script:

script

Let’s break down the code in the following image. In line 1, the user running the script will be prompted to input a number. The number will get stored into the num variable. Line 3 is where our if statement begins.

script

Referencing the following image, to create an if statement in line 3, we use the if keyword.

script

After the if keyword, we specify the condition (red box below) that we want our script to evaluate.

script

Our condition is num > 0:. The condition will evaluate to True if the num variable is greater than 0.

Notice we are using a greater-than sign (red arrow below) in our condition. The greater-than sign is referred to as a comparison operator.

script

If the condition in line 3 evaluates to True, Python will then execute the block of code in line 4. Notice how the block of code in line 4 is indented to the right of the if statement in line 3. Python relies on indentation to signify which code should execute if a conditional statement evaluates to True.

script

Let’s test out your script. Save and run your script. When prompted, enter a positive number into your script.

linux$ python numbers.py
Please enter a number: 2
2 is a positive number

When we entered a positive number, the condition in line 3 evaluated to True. Because the condition evaluated to True, the code in line 4 was executed and the following string printed out: 2 is a positive number.

What do think will happen if we enter a negative number into our script? Will the condition in line 3 evaluate to True or False? Will the code in line 4 get executed?

Run your script, but this time, enter a negative number.

linux$ python numbers.py
Please enter a number: -2

When you enter a negative number, nothing prints out because the condition in line 3 is evaluating to False. Consequently, the indented code in line 4 is not executed.

What if we want our numbers.py script to be able to detect negative numbers? To accomplish this, we can use another type of conditional statement, the elif statement. Elif statements follow if statements and are like adding another if statement to our script. An elif statement is unique because it is only evaluated if the preceding if statement is False. To detect negative numbers in our script, let’s create an elif statement.

Before we create our elif statement, we need to choose the correct comparison operator to use in our condition. When we previously created our if statement in line 3, we used the greater-than sign as our comparison operator. The following image depicts other valid comparison operators. Which comparison operator do you think we will use in our elif statement to detect negative numbers?

script

We will use the less-than sign (<) comparison operator to detect negative numbers in our script.

Add the code in lines 5 and 6 into your numbers.py script to implement an elif statement.

script

What will happen now if we run our script and input a negative number into the script? The condition within the if statement in line 3 would evaluate to False. Next, the condition within the elif statement in line 5 would be evaluated. The condition within the elif statement in line 5 would evaluate to True, and the indented code in line 6 would be executed.

To see this in action, save and run your script. When prompted, enter a negative number.

linux$ python numbers.py
Please enter a number: -2
-2 is a negative number

Next, what do you think might happen if we run our script and enter the number 0? Will the condition within the if statement in line 3 evaluate to True or False? Will the code in line 4 be executed? Will the condition within the elif statement in line 5 be evaluated? If the condition in line 5 is evaluated, will the condition evaluate to True or False? Will the code in line 6 be executed?

Let’s find out. Run your script and enter the number 0.

linux$ python numbers.py
Please enter a number: 0

When we ran the script and entered 0 into the script, nothing printed out. We are seeing this behavior because the conditional statements in both lines 3 and 5 are evaluating to False. Consequently, the indented code in lines 4 and 6 is not being executed.

What if we want our script to be able to detect the number 0? Another type of conditional statement we can use is the else statement. Else statements will only run a block of code when all the previous conditional statements have evaluated to False. Else statements essentially catch anything that was not caught by the preceding conditional statements.

Let’s create an else statement. Add the code in lines 7 and 8 into your numbers.py script.

script

In line 7, we added an else statement. This means that if the previous conditional statements in lines 3 and 5 both evaluated to False, then the indented code in line 8 will be executed.

Save and run your script. When prompted, enter the number 0.

linux$ python numbers.py
Please enter a number: 0
Your number must be zero!

Your script should print out the following string: Your number must be zero!. When the string prints out, it confirms that the code within the else statement was executed.

To prevent a potential conflict later in this tutorial, close and then delete your numbers.py file.

linux$ rm numbers.py

Imagine that you have been tasked with creating a script to check the software version running on a router. If the router is on the correct version of software, your script would then notify the administrator that the router is up to date. If the router is on the incorrect version of software, your script can then notify the administrator that the router needs to be upgraded.

To accomplish the above task, we will send an application programming interface (API) call to the router to obtain the router’s software version. After the software version has been obtained, we will program conditional statements into our script to notify the administrator if the router needs to be upgraded or not.

First, let’s obtain the software version of the router. Create a script called netmiko_test.py. Copy and paste the following lines of code into your script. Notice that in line 13 of your script, you are using the genie parser to convert the show version command output from a string to a Python dictionary.

from netmiko import ConnectHandler

HOST = 'sandbox-iosxe-latest-1.cisco.com'
USER = 'admin'
PASSWORD = 'C1sco12345'
TYPE = 'cisco_xe'


r1 = ConnectHandler(host=HOST, username=USER, password=PASSWORD, device_type=TYPE)



response = r1.send_command('show version', use_genie=True)

print(response)

Save and then run your script.

linux$ python netmiko_test.py
{'version': {'xe_version': '17.09.02a', 'version_short': '17.9', 'platform': 'Virtual XE', 'version': '17.9.2a', 'image_id': 'X86_64_LINUX_IOSD-UNIVERSALK9-M', 'label': 'RELEASE SOFTWARE (fc4)', 'os': 'IOS-XE', 'location': 'Cupertino', 'image_type': 'production image', 'copyright_years': '1986-2022', 'compiled_date': 'Wed 30-Nov-22 02:47', 'compiled_by': 'mcpre', 'rom': 'IOS-XE ROMMON', 'hostname': 'Cat8000V', 'uptime': '5 hours, 2 minutes', 'uptime_this_cp': '5 hours, 4 minutes', 'returned_to_rom_by': 'reload', 'system_image': 'bootflash:packages.conf', 'last_reload_reason': 'reload', 'license_type': 'Perpetual', 'chassis': 'C8000V', 'main_mem': '1980715', 'processor_type': 'VXE', 'rtr_type': 'C8000V', 'chassis_sn': '9UWS2FADP45', 'router_operating_mode': 'Autonomous', 'number_of_intfs': {'Gigabit Ethernet': '3'}, 'mem_size': {'non-volatile configuration': '32768', 'physical': '3965344'}, 'disks': {'bootflash:.': {'disk_size': '5234688', 'type_of_disk': 'virtual hard disk'}}, 'curr_config_register': '0x2102'}}

When you run the script, the response from the router’s API is printed out. Take note of how the data is nested. The data appears to be dictionaries nested within a dictionary. Read through the printed response and see if you can find which key-value pair stores the software version of the router.

The answer is below.

script

You can obtain the software version that your router is running by viewing the value of the xe_version key. In my lab, the router is running software version 17.09.02a; however, your software version will likely be a different version number because the router being used in this tutorial is upgraded on a recurring basis. Make sure to use the software version that you obtained from the xe_version key in the rest of the upcoming steps in this tutorial.

Before we can create our conditional statements to check that the routers are on the correct software version, we must first store the value of the xe_version key into a variable. To store the value of the xe_version key into a variable, we must first determine how the xe_version key is nested within other keys.

Analyze the following image. Notice that the xe_version key (green outline) is nested with the version key (red outline). We will to need specify the previously named keys in the correct order to access the value of the xe_version key.

script

Next, access and print out the value of the xe_version key. To do so, add the version and the xe_version key to the end of the response variable in line 15.

script

Save and then run your script.

linux$ python netmiko_test.py
17.09.02a

Now that you have obtained the value of the xe_version key, change line 15 to store the value of the xe_version key into the software_version variable.

script

Now that we have stored the router’s software version into a variable, it is time to create our conditional statements.

First, create an if statement that will detect if your router is on the correct version of software. Add lines 17 and 18 into your netmiko_test.py script by referencing the following image. Make sure to use the software version that you obtained from the xe_version key earlier because your software version may differ from mine.

script

Save and run the script.

linux$ python netmiko_test.py
This router is running software version 17.09.02a and does not need to be upgraded.

Let’s now create an elif statement. Remember, elif statements follow if statements and are like adding another if statement to our script. Try changing line 17 from an if statement to an elif statement.

script

Save and then run the script.

linux$ python netmiko_test.py
  File "/home/bob/netmiko_test.py", line 17
    elif software_version == '17.09.02a':
    ^^^^
SyntaxError: invalid syntax

You should get a SyntaxError exception when running your script. Why? You are receiving this exception because it is required that you have an if statement before an elif statement when creating conditional statements in Python.

Let’s resolve the exception and also enable our script to detect another software version (version 1.2.3x) using another conditional statement. In line 17, add a new if statement before our elif statement. In your new if statement, create a condition that will detect software version 1.2.3x. Add indented code in line 18 that will be executed if the preceding if statement evaluates to True.

script

Save and run your script.

linux$ python netmiko_test.py
This router is running software version 17.09.02a and does not need to be upgraded.

Next, let’s change the elif statement in line 19 to a software version that is different from the version your router is running.

script

What do you think will happen if we run the script?

Let’s find out. Save and then run the script.

linux$ python netmiko_test.py

Nothing should print out when our script runs. Why is this happening? The router in my example is on software version 17.09.02a. The if and elif statements on lines 17 and 19, respectively, reference different software versions than 17.09.02a. Because lines 17 and 19 reference different software versions, both the if and elif statements evaluate to False, and the blocks of code indented within the if and elif statements do not get executed.

Let’s add an enhancement to our script. If a router is not on version 1.2.3x or 4.5.6x, we want the script to notify the administrator that the router needs to be upgraded. To accomplish this, we can use an else statement.

Remember, else statements will only run their indented block of code when all the previous conditional statements evaluated to False.

Implement an else statement in line 21. In line 22, print out a notification that the router needs to be upgraded.

script

Save and run your script.

linux$ python netmiko_test.py
This router is on software version 17.09.02a and needs to be upgraded.

Because the if statement in line 17 and the elif statement in line 19 both evaluated to False, the code within the else statement in line 22 should get executed. When running the script, you should get notified that your router needs to be upgraded.

You can also specify more than one condition next to an if statement. To join the multiple conditions, you use logical operators. There are three logical operators:

In the upcoming script, we will join multiple conditions within a single if statement. The script will use the if statement to detect if the router is on version 17.09.02a and if there is at least 2000000000 bytes of storage space remaining in the router’s bootflash directory. If the router meets both of these conditions, the if statement will evaluate to True, and a message will be printed to the administrator that the router can be upgraded.

Delete all the lines of code in your netmiko_test.py script. Next, copy and paste the following code into your empty netmiko_test.py script:

from netmiko import ConnectHandler
from rich.pretty import pprint

HOST = 'sandbox-iosxe-latest-1.cisco.com'
USER = 'admin'
PASSWORD = 'C1sco12345'
TYPE = 'cisco_xe'


r1 = ConnectHandler(host=HOST, username=USER, password=PASSWORD, device_type=TYPE)

response = r1.send_command('', use_genie=True)

pprint(response)

Before we create our conditional statements, we first need our script to obtain the router’s software version and the amount of storage space remaining in the router’s bootflash directory.

First, let’s obtain the software version of the router by using the show version command in our script. Update line 12 to include the show version command. Save the response into the show_version_response variable. Change the variable name in line 14 to print out the value of the show_version_response variable.

script

Save and run your script.

linux$ python netmiko_test.py
{
'version': {
│   │   'xe_version': '17.09.02a',
│   │   'version_short': '17.9',
│   │   'platform': 'Virtual XE',
│   │   'version': '17.9.2a',
│   │   'image_id': 'X86_64_LINUX_IOSD-UNIVERSALK9-M',
│   │   'label': 'RELEASE SOFTWARE (fc4)',
│   │   'os': 'IOS-XE',
│   │   'location': 'Cupertino',
│   │   'image_type': 'production image',
│   │   'copyright_years': '1986-2022',
│   │   'compiled_date': 'Wed 30-Nov-22 02:47',
│   │   'compiled_by': 'mcpre',
│   │   'rom': 'IOS-XE ROMMON',
│   │   'hostname': 'Cat8000V',
│   │   'uptime': '2 days, 9 hours, 40 minutes',
│   │   'uptime_this_cp': '2 days, 9 hours, 42 minutes',
│   │   'returned_to_rom_by': 'reload',
│   │   'system_image': 'bootflash:packages.conf',
│   │   'last_reload_reason': 'Reload Command',
│   │   'license_type': 'Perpetual',
│   │   'chassis': 'C8000V',
│   │   'main_mem': '1980715',
│   │   'processor_type': 'VXE',
│   │   'rtr_type': 'C8000V',
│   │   'chassis_sn': '9UWS2FADP45',
│   │   'router_operating_mode': 'Autonomous',
│   │   'number_of_intfs': {'Gigabit Ethernet': '3'},
│   │   'mem_size': {'non-volatile configuration': '32768', 'physical': '3965344'},
│   │   'disks': {'bootflash:.': {'disk_size': '5234688', 'type_of_disk': 'virtual hard disk'}},
│   │   'curr_config_register': '0x2102'
}
}

The router’s software version is stored in the xe_version key. Next, we will need to access the value of the xe_version key. To access the value, we need to determine how the xe_version key is nested within other keys. Can you figure out which key or keys that the xe_version key is nested within?

The answer is below.

script

The xe_version key is nested within the version key. Now that you have obtained the required keys, change line 14 in your script to store the value of the xe_version key into the software_version variable. In line 16, print out the software_version variable to confirm that the variable has the correct value.

script

Save and then run your script.

linux$ python netmiko_test.py
17.09.02a

We have successfully stored the software version of the router into a variable.

Next, we need to obtain the amount of storage space remaining in the router’s bootflash directory. We can do so by using the dir command. Replace line 16 in the script with the code in the following image to send the dir command to the router. Store the response from the router into the dir_response variable. In line 18, pretty-print out the response stored in the dir_response variable.

script

Save and run the script.

linux$ python netmiko_test.py
{
'dir': {
│   │   'bootflash:/': {
│   │   │   'files': {
│   │   │   │   'tracelogs': {
│   │   │   │   │   'index': '131078',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '36864',
│   │   │   │   │   'last_modified_date': 'Sep 4 2023 15:19:05 +00:00'
│   │   │   │   },
│   │   │   │   'nbar2': {
│   │   │   │   │   'index': '131215',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 16:43:44 +00:00'
│   │   │   │   },
│   │   │   │   'nbar2_http_default.tar': {
│   │   │   │   │   'index': '34',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '2672640',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 16:43:41 +00:00'
│   │   │   │   },
│   │   │   │   'guest-share': {
│   │   │   │   │   'index': '131295',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 16:38:11 +00:00'
│   │   │   │   },
│   │   │   │   'cvac.log': {
│   │   │   │   │   'index': '28',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '2952',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 04:11:01 +00:00'
│   │   │   │   },
│   │   │   │   'license_evlog': {
│   │   │   │   │   'index': '131110',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 04:11:01 +00:00'
│   │   │   │   },
│   │   │   │   '.iox_dir_list': {
│   │   │   │   │   'index': '32',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '301',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 04:10:47 +00:00'
│   │   │   │   },
│   │   │   │   'csrlxc-cfg.log': {
│   │   │   │   │   'index': '31',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '157',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 04:10:43 +00:00'
│   │   │   │   },
│   │   │   │   'SHARED-IOX': {
│   │   │   │   │   'index': '131073',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 04:10:39 +00:00'
│   │   │   │   },
│   │   │   │   'throughput_monitor_params': {
│   │   │   │   │   'index': '27',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '30',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 04:10:23 +00:00'
│   │   │   │   },
│   │   │   │   'mode_event_log': {
│   │   │   │   │   'index': '12',
│   │   │   │   │   'permissions': '-rwx',
│   │   │   │   │   'size': '2132',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 04:09:34 +00:00'
│   │   │   │   },
│   │   │   │   '.installer': {
│   │   │   │   │   'index': '131074',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Sep 2 2023 04:09:02 +00:00'
│   │   │   │   },
│   │   │   │   'Line': {
│   │   │   │   │   'index': '33',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '126408',
│   │   │   │   │   'last_modified_date': 'Sep 1 2023 19:52:10 +00:00'
│   │   │   │   },
│   │   │   │   'iox_host_data_share': {
│   │   │   │   │   'index': '131342',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Mar 15 2023 09:36:12 +00:00'
│   │   │   │   },
│   │   │   │   '.dbpersist': {
│   │   │   │   │   'index': '131094',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:59 +00:00'
│   │   │   │   },
│   │   │   │   'onep': {
│   │   │   │   │   'index': '131112',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:56 +00:00'
│   │   │   │   },
│   │   │   │   '.cvac_version': {
│   │   │   │   │   'index': '29',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '1',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:53 +00:00'
│   │   │   │   },
│   │   │   │   'ovf_env.md5': {
│   │   │   │   │   'index': '30',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '16',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:53 +00:00'
│   │   │   │   },
│   │   │   │   'pnp-info': {
│   │   │   │   │   'index': '131109',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:52 +00:00'
│   │   │   │   },
│   │   │   │   'virtual-instance': {
│   │   │   │   │   'index': '131107',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:28 +00:00'
│   │   │   │   },
│   │   │   │   'ios_core.p7b': {
│   │   │   │   │   'index': '25',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '20109',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:08 +00:00'
│   │   │   │   },
│   │   │   │   'trustidrootx3_ca_092024.ca': {
│   │   │   │   │   'index': '26',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '1923',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:08 +00:00'
│   │   │   │   },
│   │   │   │   'core': {
│   │   │   │   │   'index': '131077',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:16:02 +00:00'
│   │   │   │   },
│   │   │   │   'bootlog_history': {
│   │   │   │   │   'index': '131084',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:15:58 +00:00'
│   │   │   │   },
│   │   │   │   '.prst_sync': {
│   │   │   │   │   'index': '131083',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:15:57 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-rpboot.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '23',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '51959459',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:45 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-mono-universalk9.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '22',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '797045848',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:45 +00:00'
│   │   │   │   },
│   │   │   │   'packages.conf': {
│   │   │   │   │   'index': '24',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '5794',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:45 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-firmware_nim_async.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '17',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '13038668',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:43 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-firmware_ngwic_t1e1.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '16',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '11760716',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:43 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-firmware_nim_cwan.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '18',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '17724492',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:43 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-firmware_dreamliner.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '15',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '66636',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:43 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-firmware_nim_ge.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '19',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '4346952',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:43 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-firmware_nim_shdsl.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '20',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '11568204',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:43 +00:00'
│   │   │   │   },
│   │   │   │   'c8000v-firmware_nim_xdsl.17.09.02a.SPA.pkg': {
│   │   │   │   │   'index': '21',
│   │   │   │   │   'permissions': '-rw-',
│   │   │   │   │   'size': '5575756',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:43 +00:00'
│   │   │   │   },
│   │   │   │   'appqoe-service': {
│   │   │   │   │   'index': '14',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:39 +00:00'
│   │   │   │   },
│   │   │   │   '.rollback_timer': {
│   │   │   │   │   'index': '13',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '4096',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:38 +00:00'
│   │   │   │   },
│   │   │   │   'lost+found': {
│   │   │   │   │   'index': '11',
│   │   │   │   │   'permissions': 'drwx',
│   │   │   │   │   'size': '16384',
│   │   │   │   │   'last_modified_date': 'Feb 27 2023 05:14:13 +00:00'
│   │   │   │   }
│   │   │   },
│   │   │   'bytes_total': '5183766528',
│   │   │   'bytes_free': '2909155328'
│   │   },
│   │   'dir': 'bootflash:/'

Based on the previous output, can you determine which key stores the value for the amount of storage space remaining in the router’s bootflash directory?

The answer is below.

script

The bytes_free key stores the value for the amount of storage space remaining in the router’s bootflash directory. Next, we will need to extract the value of the bytes_free key. To do this, we need to determine how the bytes_free key is nested within other keys. Can you figure out which key or keys that the bytes_free key is nested within?

The answer is below.

script

The bytes_free key is nested within the dir and the bootflash:/ keys, respectively. Now that you have obtained the required keys, change line 18 in your script to store the value of the bytes_free key into the bootflash_space variable. Also in line 18 we will need to convert the type of data that is stored in the bootflash_space variable. Enclose line 18 within the int class so that we can convert the bootflash_space variable from a string to an integer. Print the bootflash_space variable to confirm that we have accessed the correct value.

script

Save and then run your script.

linux$ python netmiko_test.py
2909143040

Let’s recap what we have done so far:

Next, we will add an if statement to our script to achieve the following: If the router is on software version 17.09.02a and there are 2000000000 bytes of storage space remaining in the bootflash directory, the script will print out a message that the router can be upgraded.

Delete the code in line 20, and then replace the code with the if statement seen in line 20 below. In line 21, add code that will print a message to the administrator.

script

Save and run your script.

linux$ python netmiko_test.py
Router is running 17.09.02a. 2909118464 bytes left of space in bootflash. Router can be upgraded.

Next, in lines 22 and 23, implement an else statement so that we can detect routers that should not be upgraded.

script

In line 21, change the software version that has to be upgraded from 17.09.02a to 16.09.02a.

script

What do you think will happen when we run our script now?

Save and run your script.

linux$ python netmiko_test.py
Router is running 17.09.02a. 2909159424 bytes left of space in bootflash. Router cannot be upgraded.

You should be notified that the router cannot be upgraded. Why is this occurring? We are using the and logical operator in our if statement (line 20), so the if statement will only evaluate to True if both conditions are True. Because one of the conditions evaluates to False (the software version not equaling 16.09.02a), the entire if statement evaluates to False, and the code on line 21 does not get executed. The if statement evaluates to False, so the code within the else statement (line 23) automatically executes, and a string is printed out that the router cannot be upgraded.

Change line 20 from the and logical operator to the or logical operator.

script

What do you think will happen if we run our script?

Save and then run your script.

linux$ python netmiko_test.py
Router is running 17.09.02a. 2909167616 bytes left of space in bootflash. Router can be upgraded.

Because we are using the or logical operator, the if statement will evaluate to True if just a single condition in our if statement evaluates to True. The amount of space left in our bootflash directory is greater than 2000000000 bytes, so the if statement will automatically evaluate to True even if the router is not running on version 16.09.02a.

Nice work! You now understand how to use conditional statements in network automation scripts. Also, if you are interested, I teach at Cisco DevNet Automation Bootcamp.

Learn More