Site icon Karneliuk

CEX (Code EXpress) 08. Conditionals and wishes.

Hello my friend,

In the previous blogpost we’ve started the discussion about the instructions, which yo need to know in order to create a Python’s code. Namely, we you have learned how to create and use for loops for the Python’s lists and dictionaries. Today you will learn how to create conditionals.

Network automation training – boost your career

Don’t wait to be kicked out of IT business. Join our network automation training to secure your job in future. Come to NetDevOps side.

How does the training differ from this blog post series? Here you get the basics and learn some programming concepts in general, whereas in the training you get comprehensive set of knowledge with the detailed examples how to use Python for the network and IT automation. You need both.

What are we going to do today?

Together with the the loops, the conditionals create a basis of almost each and every script. You would use them, when you need to make a decision about an action you code should execute, when there are multiple actions available and they are dependent in some facts. Therefore, you will learn:

In addition to that you will learn how to use if .. conditional with the multiple statements for a more sophisticated checks, which are very common in the network automation environment.

If you want to know how to install Python 3.8, check the corresponding blogpost.

Why does it matter?

Every day you need to make decision, what to dress or where to go. So your network functions make decisions:

That’s why you can find the conditionals absolutely everywhere. That’s why the Python’s code will have it anyway. From the perspective of the network automation coding, here are some insights for you:

The provided list is very tiny, but even it provides you ideas, where and how the if .. else .. conditionals could be used in your Python’s code to make it really production grade.

How are we doing that?

Following the approach, we have started earlier, we create a new directory in our GitHub Python’s lessons:


1
2
3
4
$ cd CEX
$ mkdir 08
$ cd 08
$

Inside the directory we create a new file called conditionals.py, which we will use during this class:


1
2
3
$ touch conditionals.py && chmod a+x conditionals.py
$ cat conditionals.py
#!/usr/local/bin/python3.8

If you have a question to chmod command or to the path to the Python interpreter, take a look on the corresponding class .

Before we kick off with the Python’s script development, let’s take a look on the syntax. Generally, it looks as


1
2
3
4
5
6
if condition1:
    action1
elif condition[2..N]:
    action[2..N]
else:
    actionX

Now you know the process how it works and you are equipped with the knowledge to transform them in your Python skills.

#1. Preparing the test input

Following the previous discussion about Python’s list and Python’s dictionary, we will create a joint variable, which will use as an input to the for loop:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ cat conditional.py
#!/usr/local/bin/python3.8

interfaces = [
               {'name': 'Ethernet1', 'enabled': True, 'ipv4': '192.168.100.1/24'},
               {'name': 'Ethernet2', 'enabled': False, 'vlan': 'tagged'}
             ]

config_lines = []

for iface_entry in interfaces:
    config_lines.append('interface {}'.format(iface_entry['name']))

    config_lines.append('!')

for line in config_lines:
    print(line)

In a nutshell, we create a list interfaces, which contain two dictionaries, each having various variables’ types. We also create list config_lines, which will be populated with the configuration commands during the for loop execution. And it is starting getting populated with the append() function.

If you have questions to what is explained above, refer to the corresponding CEX blogposts.

#2. Conditional for the Boolean logic

The simplest form is an if .. else .. instruction, where the actions associated with one of the two conditional statements will be executed anyway. This works perfectly, when you have variable of the Boolean type, which only has values True or False:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ cat conditional.py
#!/usr/local/bin/python3.8

interfaces = [
               {'name': 'Ethernet1', 'enabled': True, 'ipv4': '192.168.100.1/24'},
               {'name': 'Ethernet2', 'enabled': False, 'vlan': 'tagged'}
             ]

config_lines = []

for iface_entry in interfaces:
    config_lines.append('interface {}'.format(iface_entry['name']))

    if iface_entry['enabled']:
        config_lines.append('  no shutdown')

    else:
        config_lines.append('  shutdown')

    config_lines.append('!')

for line in config_lines:
    print(line)

The key enabled from the elements of the list interfaces has a Boolean type. Therefore, we create an if .. else .. conditional, which adds the element to the resulting list config_lines using the append() function. In case the enabled key is True, you add ‘ no shutdown’ string; otherwise, ‘ shutdown’ is added.

Once you execute the script, you can see the following output:


1
2
3
4
5
6
7
$ ./conditional.py
interface Ethernet1
  no shutdown
!
interface Ethernet2
  shutdown
!

#3. Checking if the key exists and multiple conditional in one statement

Another very popular case in the network automation world with the Python is to check, if a specific key exist in the Python’s dictionary or in the Python’s list (the check is the same) and to act upon that.

If you carefully take a loon on the original interfaces list, you will see that one element has a key ipv4, whereas another doesn’t. The Python’s code deal with that will be the following:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ cat conditional.py
#!/usr/local/bin/python3.8

interfaces = [
               {'name': 'Ethernet1', 'enabled': True, 'ipv4': '192.168.100.1/24'},
               {'name': 'Ethernet2', 'enabled': False, 'vlan': 'tagged'}
             ]

config_lines = []

for iface_entry in interfaces:
    config_lines.append('interface {}'.format(iface_entry['name']))

    if iface_entry['enabled']:
        config_lines.append('  no shutdown')

    else:
        config_lines.append('  shutdown')

    if 'ipv4' in iface_entry or 'ipv6' in iface_entry:
        config_lines.append('  no switchport')

    else:
        config_lines.append('  switchport')  

    config_lines.append('!')

for line in config_lines:
    print(line)

In this snippet we are checking the presence the key ipv4 or ipv6 in the dictionary iface_entry. If it was the list, then such a check would look for an element with the value ipv4 or ipv6. You also see a conjunction “or“, which means that at the associated actions are taken in case ANY of these checks is True.

If you want to execute the action if BOTH checks are true, use “and” conjunction.

Here is the Boolean logic summary for you:

Condition 1Condition 2ConjunctionResult
TrueTrueandTrue
TrueFalseandFalse
FalseTrueandFalse
FalseFalseandFalse
TrueTrueorTrue
TrueFalseorTrue
FalseTrueorTrue
FalseFalseorFalse

The execution of this Python’s script provide the following result for you:


1
2
3
4
5
6
7
8
9
$ ./conditional.py
interface Ethernet1
  no shutdown
  no switchport
!
interface Ethernet2
  shutdown
  switchport
!

#4. Nested conditionals and if .. without else ..

If your logic requires multiple levels of conditionals, you can nest them as deep as you like. That would allow you to create quite a flexible decision-making.

Before you will see how this is achieved, there is one more point you might consider during designing your Python script. It might be, that you need to make some option on a condition, which does not include any action to happen in case the conditional check is False. That is easy, as the only mandatory part of the if .. conditional is the if .. itself; both elif .. and else .. are optional. The following example shows how you can achieve in the Python script:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$ cat conditional.py
#!/usr/local/bin/python3.8

interfaces = [
               {'name': 'Ethernet1', 'enabled': True, 'ipv4': '192.168.100.1/24'},
               {'name': 'Ethernet2', 'enabled': False, 'vlan': 'tagged'}
             ]

config_lines = []

for iface_entry in interfaces:
    config_lines.append('interface {}'.format(iface_entry['name']))

    if iface_entry['enabled']:
        config_lines.append('  no shutdown')

    else:
        config_lines.append('  shutdown')

    if 'ipv4' in iface_entry or 'ipv6' in iface_entry:
        config_lines.append('  no switchport')

        if 'ipv4' in iface_entry:
           config_lines.append('  ipv4 address {}'.format(iface_entry['ipv4']))

        if 'ipv6' in iface_entry:
           config_lines.append('  ipv6 address {}'.format(iface_entry['ipv6']))

    else:
        config_lines.append('  switchport')

        if iface_entry['vlan'] == 'tagged':
           config_lines.append('  switchport mode trunk')

        elif iface_entry['vlan'] == 'untagged':
           config_lines.append('  switchport mode access')    

    config_lines.append('!')

for line in config_lines:
    print(line)

You can see that if ‘ipv4’ in iface_entry doesn’t have any else statement, which is perfectly fine.

Besides that, in the snippet above you can also find the conditional check, where you compare the value of a certain key to a string value. If there is a full match then condition is true: iface_entry[‘vlan’] == ‘untagged’.

The result of this Python script execution gives you the following result:


1
2
3
4
5
6
7
8
9
10
11
$ ./conditional.py
interface Ethernet1
  no shutdown
  no switchport
  ipv4 address 192.168.100.1/24
!
interface Ethernet2
  shutdown
  switchport
  switchport mode trunk
!

#5. Grouping multiple checks.

The last point we’ll cover in this blogpost today is the grouping of the checks. You have already seen the usage of the or and and conjunction. If you have a sophisticated condition, where multiple different checks are to be done, you can also use round brackets “(” and “)” to group the certain blocs together. That allows you to group the checks together and take their joint result for the further comparison per the Boolean logic shared above.

Let’s modify the previous code by adding stricter conditional for checking the IP address and VLAN presence to avoid the situation that the interface’s Python dictionary has both. We also add a new element into interfaces list to test that :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$ cat conditional.py
#!/usr/local/bin/python3.8

interfaces = [
               {'name': 'Ethernet1', 'enabled': True, 'ipv4': '192.168.100.1/24'},
               {'name': 'Ethernet2', 'enabled': False, 'vlan': 'tagged'},
               {'name': 'Ethernet3', 'enabled': True, 'ipv4': '192.168.101.1/24', 'vlan': 'tagged'}
             ]

config_lines = []

for iface_entry in interfaces:
    config_lines.append('interface {}'.format(iface_entry['name']))

    if iface_entry['enabled']:
        config_lines.append('  no shutdown')

    else:
        config_lines.append('  shutdown')

    if ('ipv4' in iface_entry or 'ipv6' in iface_entry) and 'vlan' not in iface_entry:
        config_lines.append('  no switchport')

        if 'ipv4' in iface_entry:
           config_lines.append('  ipv4 address {}'.format(iface_entry['ipv4']))

        if 'ipv6' in iface_entry:
           config_lines.append('  ipv6 address {}'.format(iface_entry['ipv6']))

    elif 'vlan' in iface_entry and not ('ipv4' in iface_entry or 'ipv6' in iface_entry):
        config_lines.append('  switchport')

        if iface_entry['vlan'] == 'tagged':
           config_lines.append('  switchport mode trunk')

        elif iface_entry['vlan'] == 'untagged':
           config_lines.append('  switchport mode access')    

    else:
        config_lines.pop(-1)
        config_lines.append('  descriontion THERE IS SOME MESS WITH VARS')
        config_lines.append('  shutdown')

    config_lines.append('!')

for line in config_lines:
    print(line)

The newly added element in the list interfaces contains both the ‘ipv4‘ and ‘vlan‘ keys, what should not be the case per our logic. Therefore, we create the following conditions:

And here is how it works:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ./conditional.py
interface Ethernet1
  no shutdown
  no switchport
  ipv4 address 192.168.100.1/24
!
interface Ethernet2
  shutdown
  switchport
  switchport mode trunk
!
interface Ethernet3
  descriontion THERE IS SOME MESS WITH VARS
  shutdown
!

#6. List of the most widely used conditional checks in the network automation

There are multiple other possible checks, which you might need to have in your code. We tried to summarise the vast majority of them for you:

Conditional statementDescription
sting_var == ‘text’The value of the sting_var is compared with the string ‘text’. True if it matches exactly.
sting_var != ‘text’The value of the sting_var is compared with the string ‘text’. True if it does NOT match exactly.
‘text’ in sting_varThe substring ‘text’ must present inside the sting_var value. True if it presents.
int_var == 10The value of the int_var is compared with the number. True if that they are equal.
int_var [<, >, <=, >=, !=] 10The value of the int_var is compared with the number. True if that it is [less, greater, less or equal, greater or equal, don’t equal] than value.
‘text’ in dictionaryThe key with the name ‘text’ is looked for into the dictionary. True if it exists.
‘text’ in listThe element with the value ‘text’ is looked for into the list. True if it exists.
var_nameChecks the element value and depends on the variable type:
– digit: True if not 0
– string: True if not ” (empty string)
– Boolean: True if True

If any of these checks are prepended by “not” keyword, than their result are inverted.

If you prefer video

If you prefer watching the video instead of reading blogpost, that is also wonderful. We value your time and want to create for you the best experience possible. Therefore, for all the blogposts associated with CEX series, we will record the video and post it on our YouTube channel.

And here is the video for this blogpost:

What else shall you try?

Programming is all around testing, trying, breaking and fixing the things. Try to do the following things to collect some more experience:

Lessons in GitHub

You can find the final working versions of the files from this blog at our GitHub page.

Conclusion

The for loop and the if conditional is a foundation of almost all the Python’s script. Having master them, you can start developing some logic, which could help you to solve some basic tasks. But this basics tasks might be taking quite a huge amount of your time. Take care and goodbye!

Support us






P.S.

If you have further questions or you need help with your networks, I’m happy to assist you, just send me message. Also don’t forget to share the article on your social media, if you like it.

BR,

Anton Karneliuk 

Exit mobile version