Book Image

Practical Network Automation

By : Abhishek Ratan
Book Image

Practical Network Automation

By: Abhishek Ratan

Overview of this book

Network automation is the use of IT controls to supervise and carry out every-day network management functions. It plays a key role in network virtualization technologies and network functions. The book starts by providing an introduction to network automation, SDN, and its applications, which include integrating DevOps tools to automate the network efficiently. It then guides you through different network automation tasks and covers various data digging and reporting methodologies such as IPv6 migration, DC relocations, and interface parsing, all the while retaining security and improving data center robustness. The book then moves on to the use of Python and the management of SSH keys for machine-to-machine (M2M) communication, all followed by practical use cases. The book also covers the importance of Ansible for network automation including best practices in automation, ways to test automated networks using different tools, and other important techniques. By the end of the book, you will be well acquainted with the various aspects of network automation.
Table of Contents (14 chapters)
Title Page
Credits
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Preface

Program concepts


Now, as we start working upon our practical approach to automation, we need to understand the basics of what a program is and how to write one.

Simply explained, a program is a set of instructions that is passed to the system to perform a specific task. This set of instructions is based upon real-life challenges and tasks that need to be accomplished in an automated method. Small sets of programs can be combined to create an application that can be installed, deployed, and configured for individual or organizational requirements. Some of the key concepts and programming techniques that we will discuss from this point onward will be PowerShell and Python. These are the two most popular scripting languages that are used to create quick, effective, and result-oriented automation.

These are some of the key concepts that I would like to introduce while creating a program:

  • Variables
  • Data types
  • Decision makers
  • Loops
  • Arrays
  • Functions
  • Best practices

Variables

These are predefined, human-readable, and understandable words or letters that are used to store some values. At the very basis of writing a program we need a variable in which we will store the data or information, and based upon the variables, we can further enhance the programming logic. As we can see in the first line, an important part of creating a variable is that it should be human-readable and understandable.

Let us take an example: Suppose I want to store a number 2 in a variable. We can choose any name for a variable and define it:

Option 1: x=2
Option 2: number=2

The correct answer will be Option 2, as we know by the variable name (number) that this variable contains a specific number. As we can see in the preceding example, if we keep on using random ways of defining variables as we would when creating a big program, the complexity would be increased substantially because of the unclear meanings of the variables.

Different programming languages have different ways to define a variable, but the underlying concept of ensuring a variable is human-readable should be the top-most priority of the programmer or program author.

Data types

As the name suggests, these are the classifications of the values that we pass on to the variable. A variable can be defined to store a specific type of value that can be declared based upon the data type.

There are multiple data types, but for our initial discussion there are primarily four data types that need to be understood:

  • String: This is a catch-all data type. Any value defined as a string is as simple as saying the value is plain English with characters, alphabets, special characters, and so on. I have referred to it as a catch-all data type because nearly all other data types can be converted to string format keeping the same values intact during conversion to string.

Consider the following example:

number=2

This defines that a variable named number has a value of 2. Similarly, if we declare:

string_value="2"

This is same as saying that a value of 2 has been now defined as string and stored in a variable named string_value.

  • Integer: This specifies that any value that is a number needs to be defined with this data type. The key thing to note here is that an integer value will contain a whole number and not a decimal value:

Consider an example as follows:

integernumber=2

This defines that a variable named as integernumber has a value of the number 2. An incorrect assignation here would be something like:

integernumber=2.4

This would give an error in some programming languages as an integer needs to be interpreted as a whole number and not a decimal value.

  • Float: This data type removes the restriction that we saw earlier with integer. It simply means we can have a decimal number and can perform mathematical calculations and storage of decimal values in a float data type.
  • Datetime: This is an extended data type found in a lot of modern scripting languages. This data type ensures that the values that are being stored or retrieved are in date format. This is typically useful if we need to create a program that uses some time or date calculations. As an example, perhaps we need to find out how many syslogs were generated from a router in the last seven days. The last seven days will be stored by this data type.

Decision makers

These are one of the very critical components of a program and they can define the flow of the program. As the name suggests, a decision maker decides a certain action based upon a certain condition.

Simply put, if you wanted to buy an ice cream you would go to an ice-cream shop, but for a coffee you would go to a coffee shop. In this case, the condition was whether you wanted ice cream or coffee. The action was based upon the result of the condition: you went to that specific shop.

These decision makers, also called conditions, are defined in a different manner in different scripting languages, but the result of each of the conditions decides the future flow of the program.

Generally, in a condition, two or more values are compared and either a true or a false is returned. Depending on the value returned, a specific set of instructions are executed.

Consider the following example:

Condition:
if (2 is greater than 3), then
Proceed to perform Option 1
else
Proceed to perform Option 2

As we see in the preceding example, a condition is evaluated and if 2 is greater than 3, then the flow of program will be performed based upon Option 1, and in case of a false (which means 2 is not greater than 3), Option 2 would be chosen.

If we want a bit more complexity, we can add multiple decision-making statements or conditions to granulize the flow of a program.

Let us take an example:

if (Car is of red color), then
  if (Car is Automatic), then
    if (Car is a sedan), then
      Option 1 (Purchase the car)
    else (Option 2, ask for a sedan car from dealer)
  else (Option 3, ask for an Automatic car from dealer)
else (Option 4, ask for a red car from dealer)

As we can see in this complex condition, we can easily decide the flow of a program based upon additional checks. In this case, I only want to buy a Car that is red, Automatic, and a sedan. If any of those conditions are not met, then I ask the dealer to meet that specific condition.

Another thing to notice in the preceding example is that the conditions are nested within each other, hence they are shown as nested with spaces deciding the sub-conditions from its parent condition. This is usually depicted within brackets or with simple indentation based upon the scripting language used.

Sometimes, it is necessary to evaluate a value against multiple conditions and perform an action if it matches any of the conditions. This is called a switch case in programming.

Consider an example as follows:

Carcolor="Red" (Here we define a variable if the value of string as Red)
switch (Carcolor)
Case (Red) (Perform Option 1)
Case (Blue) (Perform Option 2)
Case (Green) (Perform Option 3)

Here we see that depending upon the variable's value, a certain type of action can be performed. In this case, option 1 will be performed. If we change the value of the Carcolor variable to Blue, then option 2 will be performed.

An important component of conditions are the comparison operators that we use to compare two values for the result. Some example operators are equal to, greater than, less than, and not equal to. Depending on which comparison operator we use, the results can vary.

Let us take an example:

greaternumber=5
lessernumber=6

if (greaternumber 'greater than' lessernumber)
Perform Option 1
else
Perform Option 2

We declare two variables named greaternumber and lessernumber and compare them in a condition. The conditional operator we use is greater than, which would result in option 1 if the condition is true (greaternumber is greater than lessernumber), or would result in option 2 if the condition is false (greaternumber is not greater than lessernumber).

Additionally, we also have operators that are called logical operators, such as AND, OR, or NOT. We can combine more than one condition by using these logical operators. They have a similar meaning in English, which means that if, for example, we use the AND operator, we want condition 1 AND condition 2 both to be true before we perform an action.

Consider an example: I want to buy a car only when the car is redautomatic, and a sedan:

if (car is 'red') AND (car is 'automatic') AND (car is 'sedan')
Perform action 'buy car'
else
Perform action 'do not buy'

This simply means I would evaluate all the three conditions and only if all of them are true, then I would perform the action buy car. In this case, if any of the conditions do not meet the values, such as the car is blue, then the do not buy action will be performed.

Loops

A loop, as we know in common language, is circling the same path over and over again. In other words, if I am asked to fetch five ice creams from the ice cream store, and I can carry only one ice cream at a time, I will repeat the process of going to the ice cream shop to purchase ice cream five times. Correlating this with programming, if the same set of instructions need to be performed multiple times, then we put those instructions inside a loop.

A very basic loop is generally depicted as an iteration of a variable as many times as we want the instructions to be carried out.

Let's take an example:

Start the loop from one, until the loop has been repeated sixty times, adding a value of 1 to the loop:
Perform action

If you see the instructions being passed, there are three separate segments that are depicted in a loop:

  1. Start the loop from one: This means that the loop should start with a value of one.
  2. until the loop has been repeated sixty times: This means perform the same set of tasks until the loop has completed sixty turns of execution.
  3. adding a value of 1 to the loop: This means that we dictate that after completion of each round of loop, increment the loop count by 1.

The result will be the same action performed sixty times, until the loop count reaches sixty. Additionally, a loop can used to iterate through multiple values stored in a variable irrespective of whether it is an integer, string, or any other data type.

Arrays

An array (or list in some scripting languages) is used to store a similar set of multiple values inside a single variable. This helps to ensure all data types with similar meanings are stored in a single variable, and also we can easily loop through these array objects to fetch the values stored in an array.

Consider the following example:

countries=["India","China","USA","UK"]
for specific country in countries 
 Perform action

As we can see in the variable declaration, now we are declaring a similar data type with a similar context or meaning by grouping them together and assigning them into a single variable. In our example, it's the country names all assigned to an array variable named countries. In the next line, we are now iterating using the loop method, and for every specific country in the list or array of countries, we will perform the action. In this case, the loop will be executed to perform the action for each country, from the country name India to the end of the country name UK.

Each value stored in an array is referred to as an element of the array. Additionally, an array can be easily sorted, which means irrespective of the order of the elements in the array, we can get a sorted list or array by calling some additional programming tasks.

Let's consider an example:

countries=["India", "China", "USA","UK"]
Sort (countries)

The result will be as follows:

countries=["China","India","UK",USA"]

The sort functionality ensured that all the elements inside the array are sorted alphabetically and stored in the sorted order.

Functions

Functions or methods are a pre-written small set of instructions that result in a specific task being performed when they are called. The functions can also be defined as a single name for a group of programming instructions written together to achieve a common task.

Taking an example, think of driving as a function. In driving, there are multiple things that need to be taken care of, such as understanding traffic signals, running a car, and driving the car in traffic and on the road.

All these tasks are grouped in a function named driving. Now, let's say we have two people, example 1 and example 2, who want to learn to drive. From a programming perspective, once we define a function, we need to call it whenever we want to perform the same set of tasks. Hence, we would call driving(example 1) and then driving (example 2), which would ensure that both people would become a driver after going through the set of instructions in the driving function.

Let us look at another example:

countries=["India","China","USA","UK"]

function hellocountry(countryname)
 Return "hello " countryname

for each country in countries:
     hellocountry(each country)

In the first line, we declare an array with country names as elements. Next, we define a function named hellocountry that accepts an input of countryname. In the function itself, we simply return the value of the countryname that was passed to the function as input, preceding by the work hello.

Now all that remains is to iterate through all the elements of countries and pass each countryname as input to the hellocountry function. As we can see, we called the same function for each element, and based upon the instructions declared inside the function, that specific task was now performed for each element in the array.

Best practices

As we have now looked at the basics of some of the key components of a program, there is another important aspect of how to write a good program that we will consider.

From a machine's perspective, there is no understanding of how a program is written, as long as the instructions given in the program are in the right format or syntax and the machine is able to interpret each of the instructions correctly. For an end user, again the way the program is written might not be important as long as the end user gets the desired result. The person concerned with how a program is written is a programmer who is writing their own program, or a programmer or developer who needs to interpret another programmer's program.

There may be multiple reasons why a programmer might need to interpret a program that's not been written by them. It may be to support the program while the programmer who wrote the program is not available, or to enhance the program by adding their own piece of code or programming instructions. Another reason for code readability is fixing bugs. Any program or set of instructions may malfunction due to incorrect input or incorrect logic, which can result in unexpected behavior or unexpected results. This is called a bug, and bugs need to be fixed to ensure the program does what it was written for originally.

Every programmer has their own set of best practices, but some of the key aspects of a program are readability, support information, and indentation.

Readability of a program

This is one of the most important aspects of writing a good program. A program needs to be written in such a way that even a layman or a first-time reader of the program should be able to interpret the basics of what is happening.

Variables need to be declared properly so that each variable makes it clear what it stores:

x="India"
y="France"

could have been written better like this:

asiancountry="India"
europecountry="France"

Here's another example:

x=5
y=2

It could be written like this:

biggernumber=5
smallernumber=2

As we can see in the preceding example, if we write a two- or three-line program, we can easily declare the variables in a random way, but things become much more complex, even for a programmer writing their own program, when these random variables are used in a longer program. Just imagine if you have declared the variables as a, b, c, and so on, and later, after using even 10 or 15 more variables, you need to go back to each line of the program to understand what value was declared in a, b, or c.

Another aspect of writing a good program is commenting. Different scripting languages provide different ways of commenting a program. Comments are necessary to ensure we break the flow of each program into sections, with each section having a comment explaining the use of that section. A very good example is if you declare a function. A function named Cooking, for example, and another function named CookingPractice might sound confusing because of their names. Now, if we add a comment to the Cooking method saying this function is to master the art of cooking when you have learned how to cook, and add a comment to CookingPractice saying this method is to learn cooking, this can make things very easy for someone reading through the program.

A programmer now can easily interpret that whenever he wants to learn to cook, he has to call CookingPractice and not the Cooking method. Comments don't have any special meaning in any programming language, and they are ignored when the machine is trying to convert the programming language to machine instructions. Hence, comments are only for programmers and to make readers aware of what is happening in a program. A comment should also be placed with every complex condition, loop, and so on, to clarify the usage of that specific condition or loop.

Support information

This, as the name suggests, is additional information, preferably added as comments, containing details about the program and author. As a suggestion, at the minimum a program should have the author info (that is, the person who created the program), contact details such as phone number and email address, basic usage of the program or the purpose of the program, and the version of the program.

The version is specific such as starting from 1.0 and as and when we enhance the program or add new features, we can change it to version 1.1 (for minor changes) or a newer version such as version 2.0 (for major changes).

Consider an example:

Program start
Comment: Author: Myself
Comment: Contact: [email protected]
Comment: Phone: 12345
Comment: Version: 1.0
Comment: Purpose: This program is to demo the comments for support info
Comment: Execution method: Open the Command Prompt and run this program by calling this program.
Comment: Any extra additional info (if needed)

Program end

This approach ensures that everyone knows which is the latest version of the script and how to execute the program or script. Also, this has info about the contact details of the author, so if anything breaks in production, the author can be easily reached to rectify or fix the scripts in production.

Indentation

This is similar to what we do when we write in plain English. Indenting a program is mandatory in some scripting languages, but as a best practice it should be followed for any program that we write in any programming language. Indentation improves the readability of a program because it helps the programmer or someone else reading the program to quickly understand the flow of the program.

Let's see an example where we have a nested condition in which we check if a Car is Red and if it is a Sedan and if it is Automatic. A bad way of writing this would be as follows:

if (Car is 'Red')
if (Car is 'Sedan')
if (Car is 'Automatic')
do something

Now, think of adding multiple lines like this to a long program, and you will get easily confused by the flow of program as you read through it. A better and recommended way to write this is as follows:

if (Car is 'Red')
    if (Car is 'Sedan')
        if (Car is 'Automatic')
           do something

This provides a clear flow of the program. Only check the other conditions if the Car is Red; otherwise, don't check for the other conditions. This is where we say we are nesting the conditions inside each other, which is also called nested conditions.

This also clears a lot of confusion while troubleshooting a complex program. We can easily identify the problematic code or instructions by quickly parsing through the program and understanding the flow for each segment of the program.

Sample best practice example

This example summarizes the best practices using all the elements that we have learned so far, by creating a basic program.

Problem statement: Parse all the countries declared in an array and only print the names of those countries that contain the letter I or letter U in their names:

Program begin:

Comment: This is a sample program to explain best practice
Comment: Author name: Programmer
Comment: Email: [email protected]
Version: 1.0

Comment: The following section declares the list of countries in array countrylist
countrylist=['India','US','UK','France','China','Japan']

function validatecountryname(countryname)
   Comment: This function takes the input of countryname, checks if it contains I or U and returns value based upon the result.
   if ((countryname contains 'I') OR (countryname contains 'U')
         return "Countryname contains I or U"
   else
       return "Countryname does not contain I our U"

Comment: This is a loop that parses each countryname from the countrylist one by one and sends the variable 'countryname' as input to function validatecoutryname

foreach countryname in countrylist
     validatecountryname (countryname)

Comment: Program ends here

The program is self-explanatory, but it is worth noting the support comments such as author, email, and so on. The indentation ensures that any reader has a clear idea of the flow of program. Additionally, another thing to observe is the use of names that clearly depict the usage of the variable or name. Each variable and function name clearly specifies what it is being used for. The additional comment lines in between add clarity on what each segment is doing and the purpose of the statement or function.