Python 101 for Network Engineers

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone my name is calvin rimsburg and i'm a sales engineer for juniper networks based out of houston texas and it is this distinct honor to be able to share with you my fellow network engineers an introduction into python programming now python is one of those really rare programming languages that manages to be both relatively easy to learn but also have this capability to scale to the ultimate level of complexity so it doesn't matter if you're just writing a script that will change a router's host name or if you're building an entire artificial intelligence like juniper's mist python is a single programming languages that can in theory do it all but probably more appropriate for those of us that live within the it infrastructure world python has a rich package ecosystem that allows us to import snippets of code that handles some of the more complex tasks things like managing an ssh connection to a router how to send a command to a remote device and then store the data that's returned my hope is that by the end of this course you'll have an awareness of the foundations within python programming and will have some real world experience into building a practical network automation script so what exactly are we going to be doing today well today we're going to be building a software compliance tool within python something that will prompt the user for their username and password and then we'll use that information to log into each of our firewalls and tell us whether or not that firewall is running the certified golden image from juniper and in order to do that we've got to cover a few topics within python well we there's the obvious we need to install python uh but then we're going to transition to more of the concepts within python things like what are data types where we'll we'll discuss things like strings and integers and lists and dictionaries then we'll talk a little bit about how to install and import some of that ecosystem packages that are out there remember we talked about managing ssh connections and all that type of thing then we'll cover the basic foundations of loops and then we'll wrap it up with conditionals where we talk about how to compare different values which will be really important when we want to compare our certified golden image with that of what's running on the device so without any further delay let's go ahead and start with the installation process on our windows mac and linux machines so let's start our installation process with arguably the most complicated one which is installing on windows now traditionally it's been pretty difficult to get a developer environment set up within windows but things are improving in the windows world there is a technology out there called wsl2 which allows you to basically run linux inside of windows it's a phenomenal piece of software that's provided by microsoft we're not going to go down that route because it's a little bit more than i wanted to to really cover today instead let's show you how to install python on just a vanilla windows 10 installation so i'm going to move over into my windows install i've got one thing that i've installed in here and that's just a different more secure web browser let's go ahead and open up our command prompt by typing in cmd either at our search bar or from the run menu and if i type in the word python and hit enter i'm not going to get the python shell if i do not have python installed windows 10 will automatically open up the microsoft store here and ask you to install through this now this might work i don't know i've never done it this way i'm sure microsoft has got you know all their eyes dotted and their t's crossed and that this works exceptionally well but i'm going to show you the more conventional way of doing things and that is by going to opening up your web browser and then typing in python.org from here we're going to download the latest version of python which i believe is 3.9 and it is so let's hover over this downloads menu click this button that says python 3.9 and we'll hit the save button now from there we're going to follow the traditional microsoft installation process which is a bunch of next next next done but there's one thing i want you to include on here and that is this bottom check mark here this should be by default i don't know why they didn't do this but let's say add python 3.9 to the path now if you're unfamiliar with what you know systems and how they work the path is basically a a a list of directories for the system to look in whenever you type in a command it's a very poor way of saying it but whenever i type in python if we did not add it to the path the windows operating system wouldn't know to look in the specific directory that our python has installed so clicking this is very good let's go ahead and click this install now or we'll get prompted and we'll just say yes keep in mind this is the more difficult of the installations across the operating system it's even easier on on mac and linux and once this is done there will be one more option here for us to disable this max length parameter now this is a windows only thing i don't know if what i really want to call it an issue but microsoft it has a has a limit of characters that you can have within the path and here it is right here i'm just going to go ahead and select this disable the path limit length limit you don't need to i don't think you're going to run into this problem but let's just go ahead and do it and say yes and just like that python's installed if i close out of my my shell or my command prompt and i open it back up that by the way will help refresh the path right if i had not re opened up my terminal and then hit the python tab again the path would not have been updated and would probably open up that microsoft store again but now that we've got a fresh session let's go ahead and type in the word python and now you can see we are in the python interpreter also known as the python reple and from here i can just go ahead and exit by typing the word quit and doing open and close parentheses that'll take me out of the python repel so that's how to install python on a windows machine you probably didn't need a video tutorial on that let's also install vs code the visual studio code is the the ide or the text editor that i'm going to be leveraging in order to build all my python scripts not only does it give you the really nice text editor look and feel but you can also run python within the actual text editor itself so you don't have to work from the command prompt anymore so very nice in addition to that is there's all kinds of features and extensions within visual studio code to help you work within python they'll have linters that can help identify where your code is broken before you try to execute it there's even extensions to help juniper syntax so that you can actually see juno's config with nice highlighting of keywords really really nice so i'm going to go ahead and say i accept the agreement you guys saw me read all those terms of services right let's go ahead and do next next next and i'm going to add a i'm just going to go ahead and click all these these are good look at that add to path it's already there by default and let's click the install this again this is going to install our text editor that we're going to be working from i will not be working from windows machine since my company laptop is a macintosh but i hope this part has at least been beneficial for you let's see there we go there's our visual studio code this is our text editor from here i can say let's create a new file and let's see if you can see let's let's move my face there we go uh from here i can change the language of the file from plain text i can just type in python and now my text editor will understand python language and and provide some syntactical highlighting for me and if i want to enter the python terminal directly from my text editor i would just go to this terminal window right here and say new terminal and then here i'm given my python terminal right here so this is a shortcut allows you to execute your python code directly from your terminal we're going to be doing that extensively back on the macintosh uh version or the mac os uh install for me but for my fellow for my windows 10 enthusiast out there this is how you go through the installation process for windows i hope this part has been beneficial for you now for my macintosh users my mac os users let's go ahead and go through the install and there's a little bit of good news and a little bit of bad news so let's just show you if i open up my terminal here and i type in the word python i'm not going to get the windows store that pops up in fact i will actually get the python repl the interpreter but for the bad news is that the version that ships with mac os is extremely outdated it's eol it's been eol for uh for quite some time i believe uh so python version two as you saw on the windows install the latest version was 3.9.1 so a whole major release and several minor release updates on there and they unfortunately aren't backwards compatible just kind of like ipv4 and ipv6 not really backwards compatible without some kind of translation happening but unlike ipv6 the world has kind of wiped their hands clear of python 2 and everyone's kind of moved on to python 3. so although my operating system still uses python 2 shame on you by the way mac we need to go ahead and install python 3. so the installation process is you can go either way on on this one you can follow the same path that we did which was to go to python.org hover over the downloads download the package and run through the installer or if you are using a the homebrew package manager for your mac you can also use that to install python 3 from the terminal now if you're familiar with homebrew and you you would know whether or not you have it installed because it doesn't come by default only thing that you need to do to get python 3 installed with homebrew is to let's return to our terminal here see here would be to type in the word brew install python3 now in my case i already had python 3 installed through homebrew so it's just going to let us know hey it's already installed don't worry about it but back into my installer here let's see here's the path it looks like python 3 has now been successfully installed right here we'll just close out the window say move to trash and open up our interpreter again let's just go ahead and clear the screen and i'll type in python 3.9 let's see there we go and i get python 3.9 uh the repel is now right here so really really easy to install sorry it's supposed to be quit and then open close parenthesis uh that will be a very common mistake that you run into by the way when you're starting out with python and you're trying to leave the python interpreter the python repel make sure you type in the word quit and then close open and close parentheses in order to do so and i'm happy to report that the linux installation process is even easier than all those that we had before for those of you that use linux on a regular basis you're probably not too surprised to hear that so let's go ahead and transition this is a vanilla ubuntu 20.0.4 install for us to install python 3 and all the packages that we would like just go ahead and type in sudo apt install python3 dash dev so that we get a the developer package of this python 3 dash vim so that will help us do virtual environments and python 3 dash was the last one tip there we go and pip if you didn't know is the python in a package installation tool that we'll be using extensively for installing external packages in python let's go ahead and enter my super secret password uh hit the y letter for yes and we should be good to go so if i clear my screen type in python 3 now i get my python interpreter now you notice that i'm using python.3.8.5 this is not really my doing this is goes back to the fact that the linux operating system has a source of repositories that it pulls from and in that master list of repositories the version of python 3 that's in there is 3.8.5 that's how we landed on this if you'd rather pull down 3.9.1 go ahead google it there's plenty of really great resources to help you install that version we're now equipped to transition into the python world and the very first thing i want to cover is data types when we create an object in python it's going to be associated with some kind of data type whether it's an integer or it's a string or it's a list or a dictionary or something completely different and i think that's probably the best place for us to start let's go ahead and ditch powerpoint and just jump right into back into visual studio code i will open up a terminal session and i will get into the python repel by typing in the word python3 all right so what is an object in python anyways you can or at least i like to think of an object as kind of like an empty box like an empty cardboard box you might use boxes like this to move you know to a different house location or maybe you're just storing some things inside of the attic but the idea behind the box i can't believe i'm explaining this is you just store stuff in there it's usually common things like maybe you have a box that's just baseball cards that you used to trade as a child or maybe it's full of basketballs or maybe it's full of old science fiction novels or david bowie lps or whatever it is but it doesn't have to be a common thing right boxes you can store all kinds of things nail polish with lps doesn't really matter the same is true whenever you create an object in python this can hold either a switch configuration maybe an object will create a firewall policy maybe it's just a hostname of a firewall it doesn't really matter what you store within it however when you create that object python will try its best to infer what data type that object is so let's go ahead and start giving you some examples so you can start kind of putting this together within your head i'm going to go ahead and create my first variable in python by calling ospf and setting it equal to the value of 10. now in the python world as you can see for us to create a variable you declare the variable you separate it with an equal sign and you give it the value in this case i've given it a value of 10. now python will look at that and say huh 10 10 is a number so python will automatically infer that this type of object is an integer and we can validate that by typing the word type and passing it in a parameter into parentheses of the object name in this case it's ospf when i hit the enter button back python lets us know that hey python thinks that ospf is an integer which is great now if i created another object here called bgp and set it equal to 20. let's just go ahead and pretend that these are the amount of routes in each table now i've got two objects an ospf object equal to 10 a bgp object equal to 20. and because they are integer types we can perform basic arithmetic addition subtraction multiplication division etc so let's go ahead and say bgp plus ospf if i hit the enter key what do you think will be the return value if you said 30 well i want to first off congratulate you for having a first grader's level of basic math skills you should be proud 30 is the correct answer we've added the bgp object with the ospf object which is effectively 20 plus 10 and we get a response back of 30. which is great integers are fantastic it allows us to do a bunch of really great things and it will definitely be a really important part when we start looking at operations in the networking world now what about the string values right what is a string to begin with well you can think of a string as just basically a collection of text right so for instance we'll create an object called hostname and we will use the quotes we'll actually wrap our value into double quotes here i'll call this hostname router1 now router1 is not an integer because it is text it's a combination of actually text and an integer at the end but in the python world that is all considered one thing which in this case is a string let's go ahead and use the type function to validate that python inferred this correctly and then we get the class that returned back or the object type for this instance for hostname is a string now you cannot do basic arithmetic with letters i don't care what level of algebra that we were talking about in this context right now i could not for instance add hostname plus ospf and expect to get something that comes back in this case python reple returns back and says hey there's a type error it's a data type error we're trying to do an operation of adding a string plus an integer and there's a conflict there right so i hope that provides a little bit of clarity the two primary data types that we're going to talk about right now integers are numbers and because they're numbers we can perform kinds of operations on them basic arithmetic whereas strings are a collection of text either it's a hostname an interface config whatever it is that is the type of string now let's give you a little bit better of an example here this time let's go ahead and create a new object and set it equal to the combination of our ospf and our bgp table i'm going to create a new object i'm going to call it a routing table i'm going to set it equal to bgp plus ospf now we've got this routing table object you'll note that it didn't return back the value immediately within the python repel the way that we can get insight into that is we can either type in the name of the variable see type it incorrectly just type it in to the reply and we'll get the immediate value back which is 30 which we kind of guessed because we did that operation up here but that really only works instead of the reply when you're in an actual python script what you'll need to do is use the print function that's provided by python to print out the value to the screen so let's go ahead and type in print routing table right here and you see that we get that value coming back as well so again the the idea here is that we've got these objects or variables inside of that object there's data and then python wants to know what kind of data what's the type of data is it an integer is it a string or is it something else and based on what type of data it is allows it to perform a necessary type of function now moving over into the world of lists now lists are going to be your friend whenever you need to create an object that stores multiple objects within there so again going back to that context that an object is just an empty box you might store more than one thing inside of that object but you still needed to represent that single box as a full entity despite the fact that there's multiple things within there and probably most appropriate for us in the networking world let's think about this in terms of devices right we have a network there's usually more than one network device but we want to reference all of those devices at once so how do we do that in python we use the data type of a list so let's go ahead and let's do an example let's create an object called devices and i'm going to set it equal to a list of devices and the way that we create a list in the python world is we use an open and close square brackets and then we'll store all of our objects inside of these square brackets separated by comma values so for my first device second device and third device we'll go ahead and start filling these in so i'm going to have warf.ds9.com i'm going to have a cisco.ds9.com and we'll have dax.ds9.com now these are three separate unique devices that are stored and represented as a as a list name devices so again extremely powerful lists allow us to store a bunch of stuff in there and then represent all those objects by just calling out the name of the object in this case it's devices now a really interesting thing to note and this will make sense if you're coming from a juniper background already is that since a list contains multiple objects there will be times where we want to grab a specific object within that list for instance if i wanted to reference the cisco.ds9.com device how do i do that when it's within a list well the good news is that there's something that we call an index basically saying each object within this list is represented by an integer now here's where things get a little bit confusing if you're not coming from a juniper background and the python world and actually i think all programming world everything every number and or every number system in programming will start with the number zero not one all right really important to kind of get your head around that so if i wanted to and let's just go ahead and talk through this wharf.ds09.com is my first object in this list it is not the index of one because remember in programming we start with the index of zero so zero is what wharf that ds9 is called and if i wanted to let's say devices and i'll pass the index of zero here again by using the brackets i get back right in my interpreter wharf.ds9.com if i wanted that cisco object i would hit the up arrow and i would give it the second index which is the number one so this is a little bit it takes a little bit getting used to again in the juniper world our first everything that we do is very programmatic it's very developer friendly so our interfaces start with the number zero in case of python we operate that same way inside of a list so i hope that makes sense a little bit in that list again collection of different objects each object is represented by an integer and we start at the number zero and scale up to the number of infinity i hope that makes a little bit sense let's now transition and talk about dictionaries dictionaries are great for storing complex structures of data in a really good example that i think we're going to walk through here would be probably something like a bgp configuration we're going to encapsulate our new object we'll call it bgp config but instead of like with the list we used the square brackets open and close in a dictionary world we're going to use the curly braces instead and this time we're going to be creating a series of key value pairs now if you're not familiar with the term key value basically we're we're going to set a we're going to create an object we're going to give it a name that object's name is going to be represented as what we call the key and then we're going to set the value of that object and that's basically how we develop these complex structures within a dictionary doesn't really sound like it makes sense so let's just go ahead and walk through it if we're talking in the context of a bgp configuration we may have a key value pair uh let's say a key would be maybe my neighbor ip address and i'll set that equal to we'll just say 1.1.1.1 let's make sure that we've got that encapsulated correctly with the quotes all right then we'll create a new object similar to list separated by a comma but remember everything inside of this dictionary is in the format of a key value pair rather than just a value so maybe my neighbor asn is going to be set equal to the value of 6500 or 65 000 as you can see that was an integer uh because there's no text within there uh and then maybe i want to set my local asn local asn and we'll set that to a value of 65 thousand and one so again this concept of a dictionary it allows you to store complex data structures underneath a single object name and it really kind of helps with this concept of a of a bgp configuration or interface config or whatever you can look at an entire device configuration as a series of key value pairs hostname is equal to router one loopback zero ip address is equal to 1.1.1.1 whatever everything within that we do on a router configuration or switch config is basically just a series of of dictionaries a bunch of key value pairs everywhere uh what makes though the the power of a key value type of mechanism so flexible and so easy to work with let's say for instance i wanted to know what my local autonomous system number was anywhere within my python script all i would do is i would type in my object my dictionary called bgp config and then i would pass in a key asking for the value of that key in this case we'll type in the key of local asn now if i hit the enter key what do you think will be the value that comes back i don't have the jeopardy music in the background but let's just pretend it's playing here think about this i'm passing in a dictionary and i'm saying give me the value of the key local autonomous system number when you look at all the key value pairs here the one that you should have said is 65001 that's exactly correct so think about this for a little bit think about the power of dictionaries again you could build an entire router configuration and have everything stored as key value pairs that will that power should be quite uh evident like right off the gate but this will definitely play into a different way of managing our networks it's a more advanced topic but when we talk about infrastructure as code what we're really talking about is extrapolating a router or switch configuration and setting it to a series of key value pairs stored inside of some kind of dictionary when when you extrapolate a router config and just separate all the syntax stuff a cisco device an aristo device well those are kind of the same uh like a cisco device and a juniper device for instance the syntax is is wildly different but at the end of the day there are parameters that we set there's values that we set here's the value of my host name here's the value of my bgp neighbor ip address if you boil all that down it's really just a dictionary key value pair system and now you can manage that into some kind of external source code repository like github or what have you and then all you need to really do is just run the those key value pairs against some kind of template maybe a cisco config template or a juniper config template and get the full configuration for your device so again to infrastructure as a code is is a more advanced topic uh but just kind of think about you know where dictionaries lay in the context of a configuration or operation and the power should be pretty evident uh so with that we're going to wrap up our conversation around data types we talked about strings they're basically a collection of texts a single object we talked about integers they are numbers that allow us to do basic arithmetic we talked about list which is a collection of different variables and values stored within there and then we talked about dictionaries which are similar to lists it's a single object that will sometimes contain multiple objects within there but they're separated with a key value pair that allows us to reference that value by calling it key like what we did here so next we're going to talk about the python package ecosystem how to install packages how to import packages and we'll do our very first network automation interaction where we interact with a firewall programmatically through python so let's move on to that next section because it's going to be a lot of fun one of the very first things that i had talked about as far as benefits of using python is the rich ecosystem of libraries or packages that exist out there these packages allow us to import very mature code into our script to kind of shortcut the development process as you can imagine developing an ssh driver in python is not necessarily a introduction to python type of material so let's go ahead and leverage what juniper has provided by installing the pi easy package and the best place for us to look for this is actually back in our web browser uh there is a webpage called pi pi pypi dot org this is the official python package repository uh it is accessible through the command line by using the pip keyword pip install and whatever the name of the package is or you can just browse and find whatever kind of packages that you're looking for in our case we want to install juniper's pi easy which is a python library that helps us interact with the netconf api on all of our juniper devices so i'm going to go ahead and search for junos eznc ez netconf i hope that kind of makes sense and we can see at the very top here we have junos easy automation for non-programmers which is us right we're network engineers uh this isn't our primary role in life uh and so from here we get the immediate installation uh steps required all that's required for us to do this is to run this from the command line now when you installed python you automatically installed pip which is a is a program that's not a program it's a command line tool to help you install these python packages and manage them within your operating system the only exception was on the linux one where we had to specify python 3-pip because it doesn't come with the native python package in linux so now that we've copied this command let's return to our terminal let's well actually let's open up a new terminal and let's just go ahead and paste it in here pip install junos eznc that is the uh admittedly the unfortunate name i really wish we would have just called it pi easy like it's commonly known as uh but okay so this is kind of interesting i get an alert from my terminal to tell us that the command pip was not found now that's because we installed python 3 so the actual pip command should be pip3 now we can see that that's going and executing it's reaching out to the worldwide internet or specifically to the pi pi resource and here's a really interesting thing to note there are packages that are found on pi pi that will have dependencies on other packages so in the case of us installing pi easy it's not just simple enough to just install pi easy pi easy depends on packages like lxml for helping us work with xml data ncc client for helping us manage netcomp connections through python uh cryptography to help with the ssh markdown blah blah blah there's all these different types of packages now we installed all of those just with that single command and we get that uh we get the response right here as you can see we installed all of these just by typing that that single command that's great uh and and that's the way that we probably want it to be but just know just because you're installing one package doesn't mean you're going to get that one package sometimes that package has dependencies in this case there were several dependencies that pi easy had automatically installed now we can validate the uh packages that are currently installed by typing in pip3 and the word freeze now i don't know why they called it freeze if anyone out there has got a bigger brain than mine and knows why freeze of all words well there you have it but pip 3 freeze will give us a list of the python packages that are installed the one that i really care about right now is junos eznc which is the package name for pi easy my friends it is time that we graduate away from using the python repel and in this our first network automation script we will actually be using python files so congratulations if you made it this far you have now certified python repel expert but in order to help maintain my development and and all the typing errors that i make it's easier for me to start working inside the context of a text file so within visual studio code i'm going to start by saying create a new file and let me just go ahead and save this file we'll save it to my desktop we'll call this uh python or no let's not call it anything called python let's just call this um compliance dot pi because our script will ultimately be performing the role of a compliance tool so i've got compliance dot pi that's created one thing that you'll note right off the gate is that your text editor visual studio code automatically gives you a nice little icon here for the python logo it detects that this is a dot pi extension so that it expects this to be a python script that might not sound like a whole lot to you right now but what's great about it is that we'll start to get a lot of the keywords in python we'll start to have different colors and that will help us identify exactly what is what within our script uh so definitely help with the uh the development cycle i'm gonna close out my terminal window and let's now focus on the next important thing which is getting visual studio code to point to the appropriate python version on our machine in my case that's going to be at user local bin python 3 and this will again help us identify the appropriate python packages that are installed now if i open up a terminal i should automatically be within there that user local bin python3 if i do pip3 freeze i should still see my junos eznc packages and i do so python pi easy is now installed and it's available so we're good to go now the first thing i want to do is i want to import the junos or the the yeah the junos pi easy package into my script the way i'm going to do that is i'm going to type in the word from now this is a way of saying from this package import this function so in our case to point to the pi easy it's jnpr and look my text editor is trying to help me it's trying to let me know what packages are available for me and you can just hit the enter key for auto completion so juniper.junos import device right so what we're doing is we're actually importing a data type a custom data type from the juniper.junos package which again is the pie easy i apologize that the terms are a little all over the board but when i call jmpr.junos i'm calling the pie easy package and this time i'm bringing in a class or a an object type of device now again what's great about visual studio code is that if you hover over things it will help kind of bring some kind of context into what it is that you're looking for a little bit more of advanced topic to get into the description but again it's a really nice ad value add for you within your script so just like that we've imported this this function or this device type or this data type called device from the pi easy package now what does that really do on a surface it does nothing by itself what pi easy is going to expect us now to do is to create a new object and then pass it certain parameters into this device data type so let's go ahead and let's create an object i'll call it uh connection and i'll set it equal to device and this is again where it this is what we had imported from the package and then here i'm going to pass some key value parameters the host is going to be called alderaan.dmz.home which is the name of one of my firewalls the user is going to be set to the name of automation and then the password is going to be equal to juniper123 so again the device was something that we imported from pi easy it's basically a shortcut for giving pi easy all the parameters of your network device now i've i've passed in my parameters the name of my device is host the user will be automation the password will be juniper123 and i've stored those into a new object that we call connection now what we'll do is we'll go ahead and we'll call connection.open now this is a a function of this device type that we imported that's going to open up the netconf session to our device over ssh so connection.open is going to open up an active ssh session now we're going to go ahead and let's run a command i'll create an object called show version where we're going to go ahead and issue an rpc so connection dot rpc get software information and then even in there i'm going to pass another set of parameters and it's just because i want the format of this to be in json so just like you can on a juniper device where you say display xml or display json we can actually replicate that functionality here within our remote procedure call which is basically in this case git software information is directly mapped into a show version and i'll show you really quickly after this how we actually found that appropriate rpc call but the next thing i want to do is i want to go ahead and i want to close that netcomp session i don't want my python script to just leave a bunch of ssh sessions active in the background because as you know as a network engineer tcp has no timeout value associated with it so there if you don't close the connection it'll it'll stay there and it'll persist until some kind of event uh has effectively closed it out now finally what i want to do is i want to print the value of show version to the screen so that's it uh effectively line nine lines of code um and some of them are just empty spaces so let's talk again through this really quick we're importing the pi easy package which happens to be called jnpr.junos and inside of there i'm importing a device or a data type called device now that is that ships with pi easy it's it's a bit of what we call a boilerplate code that allows you to manage a device's connection and now we create a new object called connection we set it equal to that device type of device or that set it equal to the data type of device but we also pass in support some parameters about my device the name of the device the username and the password we then open the netcomp session to the device by passing in the function of open and here visual studio code is kind enough to give us some information about you know what the open function does once the connection is open we're going to run a remote procedure call or an rpc on the device in this case we're saying get software information which is a programmatic way of saying show version and i'm passing in some extra parameters in there to say give me back the data in the format of json now this can absolutely be a format of text where it'd be just like it is on the screen or format of xml if you like working with xml actually the format of xml just trivia notes is the default because as you know in juniper everything that we do is already in xml so the data type we would have gotten back is in xml but working with xml is a whole other conversation that we'll get to in a different type of session then we close our netcomp session to the device and then we print the output to the screen that should be everything that's needed so let's go ahead and open up a terminal window again and this time i'm going to change into my desktop and i'm going to say python python3 and then the name of my script which is compliance dot pi let's see if we're successful let's hit the enter key and the fact that it didn't immediately error out is a little bit good news believe it or not uh so what we're doing right now is we're going through the connection we're running the command closing the connection and then we print it to the screen now as you can see the data type that we got back uh looks like it's in the data type of json uh it's actually pi easy actually goes a step further and converts that format of json back into a python dictionary and again we haven't talked about json yet but just know that json is a is a data format and it's interchangeable with python dictionaries it's a lot of fun to work between the two in this case pi easy took the json and returned the data back into the format of a python dictionary so very very helpful very useful uh in in if we had excluded the format of json and i just issued it like this this will still work but the data type that will come back will be a xml format and unfortunately working with xml you need to know that it's it's not something that you can just print out to the screen as simple as we did uh here in this case we got an element that came back this is an element within the xml data object that really doesn't give us the information it's there it just xml requires us to do a little bit of digging it's not as easy to work with as json but again uh really really easy for us to issue remote procedural calls and get some feedback back from our devices all right so we're in a pretty good position we have a piece of software that can log into a firewall run a command and print it out to the screen great that works for one device how do we scale well there's a couple ways there's a really really bad way and then there's the appropriate way which is involving loops but for us to kind of go down the discussion of loops let's first show you the really bad way of doing it so let's return back to our text editor here and you can see that we've got all the parameters set up to issue the commands against a single device this works well but if we wanted to execute it against three devices well the the wrong way to do this would be to copy and paste and just change the name of the device each time so hoth and then we'll call this one deep space nine and this will absolutely work and if you have only three devices and this is your script hey you know i might turn my head and look the other way and say yeah that's fine but rare it's rare when there's a network engineer in a company and there's only three networking devices more often than times than not there's dozens or hundreds or even thousands of different networking devices out there in the environment how could you get this thing to scale you're obviously not going to copy and paste for every single device that's where the construct of loops really come into value so in order for us to work with loops let's first revisit the data type of a list now as you recall a list is a object that allows us to store multiple things within there whether it's records or drinks or whatever it is in our case we're going to create a list that hosts our inventory i'm going to call this list a devices or we'll call it devices and as you recall in order for us to create a list we use the open and close square brackets and then we store each one of our devices within these brackets and we separate them with a comma so in this case i have three devices i've got alderon i've got hoth and i've got space nine let's go ahead and add those in here let's paste deep space nine all right now i have a list of all three of my devices in my environment how do i run this snippet of code against each one of the devices that's where the concept of the loops really starts to shine so what we're going to do is we're going to create something called a for loop and inside of that for loop we're going to execute this code that we've got typed between lines 6 and 12 we're going to run it against every single instance of an object within that list so in order for us to create a for loop what we're going to do is we're going to type the word for and then we're going to give it a temporary ephemeral variable name i'll just call this for firewall in and now this is where i point to my list of devices and you can see my python my text editor is trying to help me it's trying to give me a little bit of hint as to what it is i want to do so i'm going to say for firewall in devices right this right here is my list and i'm saying for every single object within that list let's run this certain code against it now python is it's not unique in this but it's an important thing to understand python is one of the programming languages that's white space sensitive meaning that the indentation level that you have set tells python what is nested under another object in this case i've got a for loop and i want some code nested inside of that loop so the way that we do that in python is that there's it's four spaces not tabs don't be the person that uses tabs four spaces indicate that something is nested underneath something else in this case we've got a for loop and i'm nesting in some code underneath there so let's just take our our code that we had developed previously and make sure that it's appropriately nested inside of there and we'll move it just like this and that should be good to go now i need a way of telling my my code right here which device we're currently working for and since we're looping through our list we're just going to reference the ephemeral variable name right here that i use the word firewall and that will become what we insert as our host now this right here is all that's required for us to take our previously functioning script and then loop it over multiple devices so the output that we see on the screen should be the same exact that we got earlier just with a lot less amount of code so again what we're doing right now is we're looping over the devices list we're picking on the first one first which is alderaan.dmz.home we're opening the ssh connection and running the netconf rpc we're printing it to the screen closing the connection going on to the next one doing the same operations closing the connection then moving on to the final one again just basically two lines of code where we one was where we created the list of the devices and two where we created the loop allows us to scale this up infinitely so if i was to add another device into here let's say tattooine.network.home this script will continue to operate i don't need to refactor it i don't need to make any additional changes to my for loop it doesn't matter if there's one device in this list it doesn't matter if there's 100 000 list devices in the list this code will continue to work obviously you can see just how powerful this looping mechanism is so i hope that helps you again there is another concept of a loop called a while loop but in order to understand while loops you kind of have to understand the the section we'll cover later on on conditionals and again while loops they have their purpose out there in the wild but not nearly as common as for loops again the idea behind the for loop is that we're going to run a snippet of code against all the devices within a list and that's going to make our lives just that much easier so there's something terribly wrong with our scripts right now and it's it's not that it doesn't work it definitely works the problem is that the username and password are hard-coded into the script which is in clear text which will probably be pushed to github or gitlab so that the whole world can see it so we obviously don't want that to be the situation we would rather that the script prompt the user for them to enter their username and password and then use that information to handle the logging in into our devices so python ships with some built-in functions one of them is called the input function and what it allows you to do is whenever the script is ran it will prompt the user for whatever value to be associated to an object so in our case let's go ahead and let's create a couple new objects one of them is going to be called username and we're going to set it equal to the result of this input function now the input function takes a argument and in this case it's asking us what kind of question would you like to prompt the user and we would say hey please enter your username okay admittedly that's not a question but uh this will be what's actually printed out to the screen and let's copy and paste that and say password will be equal to please enter your password now whenever we issue the the script again it's going to prompt us first for the username and anything that we type in on the keyboard will be saved inside of that username object as a string really important that you understand if your username just happened to be a number it will still be stored as a string that is the default for input just important to remember and then after we've received that input data and stored it as the username it will repeat the process for our password and then what we need to do to acknowledge or to leverage this information is to change what we pass into the device type uh from the juniper pi easy object in this case we'll just say user will be equal to whatever we stored into the username object and password will be equal to whatever we stored into the password object now just know it doesn't have to be we don't have to call this username and password i could call this vanilla ice cream cone and the password could be called pineapple upside down kick it doesn't matter it's just this helps us understand a little bit more if it's directly in line with the function that it performs so let's save our script and let's run our code again so we'll say python3 compliance.pi and now we get prompted please enter your username in this case we'll type in the word automation and then please enter your password and this will be juniper123 now the python script will use that information to log into the devices over that netcomp api issue the rpc calls and we're good to go now every time this this script is issued this prompt will be given so that no sensitive information is stored within our script now if anyone's watching over your shoulder they'll say ah automation user i see that your passwords juniper one two three and there are packages in python that will help you manage the the you know protecting your password from showing up on the screen that's a whole other conversation but just know that there are other packages that allow you to do what we did with the input just won't put whatever you type out into the screen but as you can see the input function allowed us to pass in our username and password which removed our sensitive information being stored within the python script so that now everyone in our team can use the script successfully without having to worry about uh that uh username and password information being leaked uh so let us wrap up this introduction to python and talking about conditionals and where they plan to fit now in the real world humans commonly evaluate a situation and then take an action based on the results of that evaluation for instance if it's below freezing outside i might take the action of putting on a coat before i walk outside or if i'm headed to the beach for one reason the other based on my complexion then i know to bring a high spf sunscreen and my bathing suit so these types of logical operations are extremely common in our day-to-day life probably happens millions of times without us even knowing it but that type of logic isn't inherently available within the python code we have to develop it ourselves and that's where the role of conditionals come into play in our specific use case we're trying to evaluate whether or not the firewalls operating system is the golden image of our company whatever we've established that as so what we need to do is we need to have some kind of evaluation criteria embedded into our script to say hey we we see the version of code is that equal to what is our golden image and if it is take this action and if it's not take this action as well so the thing about conditionals to to know is that for one they are what helps us incorporate some type of logic within our script but that they're the result of an evaluation or the result of a conditional is always going to be a true or a false is this exactly as it should be or is it something different now that's not to say that you can't have additional evaluation criteria within a single boolean or a single conditional you can absolutely do that but in our case we're just going to be evaluating is the operating system running the golden image of our of our enterprise or is there something is the device non-compliant so in order to incorporate this type of logic what we're going to do is we're going to create an if statement within our our loop that we had created and if in that evaluation basically it's going to say if operating system is equal to this then take this action if it is anything other than this then take this type of action so to better kind of flesh out this concept let's go ahead and jump back into our code to reevaluate what exactly is going to be inserted into this program so here we are we're within the loop at this point within the code we know exactly which version of operating system we have available right now now we are also getting a lot of extra data within this rpc call we're getting things like the key value pair the key is software information the value is a list of things and embedded in that list there's other key value pairs so we're going to have to do a little bit of digging to get exactly the object that represents the version of our of our device and once we have that then we'll be able to intelligently say yes or no this is exactly the version that we want to do within our conditional so first let's build our conditional actually you know what probably more appropriate let's first dig into the rpc uh response that comes from our device in the format of json and that is uh this show version object so we know if we we type in print show version we get the full monty we get everything available for us but again we really only want a specific object within here which is this version of code right here so how do we get that there's a couple of ways uh let's just kind of shortcut the process by jumping back into our web browser and let's go back to the python pretty fire and i'm going to go ahead and paste the payload right in here i'm going to hit this format and this is again this is just really for us to help us understand exactly kind of what we're working with here we know that we're working with a dictionary because we see the curly braces that tells us the object itself is a dictionary and we have a key in that dictionary called software information so right off the bat i know the very first thing i need to do within my show version is to look inside for the software information key so let's go back to our script here and we'll say print show version and then we'll ask for the key of software information now i when i run this script again and we'll run it and i'll actually end up canceling it after the first device let's go ahead and say automation juniper123 what we're going to get back is all the data that was within this software information key now in our use case all the information was still embedded within there and that's just fine let's go ahead and cancel out and let's look at the first object i just didn't want this to run three times against all the devices now when i look at the object i see that i'm working with a list right so the next object in here within software information this is actually a list now it's a list of just one object but it is still a list so we have a couple of different things that we can do for this here we could write a for loop to iterate over this list and that will absolutely work but that doesn't really make sense in our case because we're just working with one object inside of that list and if you actually let me just ask can you recall how to reference the first object in a list in python that's right it's the zero index right so let's go ahead and return back to our script and let's say give us the show version software information but give us the zero index now in our script we can absolutely get away with this because there really is only one uh one object inside of here automation juniper one two three but if you had multiple routing engines or multiple uh maybe if this was like an mc lag or a virtual chassis you could get multiple different objects that came back from this just so you know in our case our firewall's just got a single routing engine it's not clustered nothing like that so we're only getting back a single entity uh from each one of our devices all right so now we're digging through a little bit we're stepping through this dictionary to find out what's the object that represents our operating system all right uh very well let's go ahead and just copy this new dictionary uh i will paste it into here we'll format again and now i can see that we're working inside of a another list it looks to be a list with a single dictionary again the data model that's available the json daily uh the json data model that was sent back to us was meant for you know to cover both use cases of a single device multiple devices devices clustered together multiple devices with multiple routing engines so we kind of got to step through this so if it's a little a little un confusing don't don't be afraid all right so the first thing that we want to look at is we're working inside of this object right here it's a dictionary and what we want to see is oh i want to see the software version so let's go ahead and key in on junos dash version within here so we'll call for the key of junos version don't worry just because there's a hyphen in here it's not going to confuse python with doing that subtraction because we've wrapped that hyphen inside of quotes so it knows not to perform that type of operation let's go ahead and hit the save button and we will run our script again automation juniper123 and what we should get back is a much more condensed version of the payload from our devices all right so now we're very very close now we can see the the version that's coming back but the payload is now a list with a dictionary embedded in that list now that list again just a single object but it's still a list so we have to dig into it and the way that we can do that is either looping over all the values within the list which would make sense if there was more than one or in our case we can just reference again the zero index in here and hit save and let's go ahead and hit the up arrow and automation juniper one two three now what i'm expecting back is simply a dictionary with the key of data and the value being equal to the operating system version that's running on our device which is exactly what we see here now we already know looking at the payload above here one of these things is not like the other we've got one firewall that's running 18.4 while the other two are running 19.4 so let's go ahead and make this declaration right now that our golden image is supposed to be this 19.4 r3 r3 s1.3 so what we'll do is we'll go ahead way above our loop at the very very beginning let's type in let's create a new golden image object and we'll set it to the value of oops of 19.4 there we go okay so now we have an object it's set to the string value of 19.4 r3-s1.3 run out of breath i keep saying that over all right now we have everything required for us to create an evaluation criteria so let's go ahead and say uh let's go ahead and create our first if loop or our first if conditional if and we're going to set it equal to this string or this this line of code right here and then let's also dig in and make sure we get the the key in on the data so let's key in right here on data oops data all right so if show version and then we're working way through that dictionary software information zero index junos version zero index data and then that will reveal the actual value of the operating system if that is equal to and you'll notice that we're using double equal signs here and i'll type in the word or the object golden image and it'll hit the colon to actually create this nested operation again we we want to take some action if the result is true and another action if the result is false so we'll say is we'll say print this device is running the golden image and anything else we'll go ahead and use the else key for this conditional and say this device is not running the golden image now again we're using the double equal signs as far in as part of our conditional this is a mechanism for us to say evaluate what's on the left hand side of these equal signs with what's on the right hand side of the equal signs if we had just set the the conditional to a single equal sign python's going to can get confused and think that you're trying to set one thing to the other you're trying to create an object and set it to the value of the other that's not what we're doing we're doing a conditional which is an evaluation so that is double equal signs you may also see more commonly you might see maybe greater than or equal to you might see less than or equal to there's all kinds of different conditionals uh that are available for us in this case we want a perfect match and so that should be enough let's go ahead and remove that last print statement i think this is going to be enough for us to be successful let's go ahead and run our script again i'm going to say the username is automation the password is juniper123 and we should get back now whether or not the device the firewall is running the golden image or if it is out of compliance now one thing that we are not accounting for is we're not providing a very intuitive way of sharing what that device name is and i'll cover that in just in a second how to get the device name and put it within this string right here because this this is helpful for you and i as we work through the development but somebody that is operating this you know at some other time down its life cycle will not know hey that third one that's not running the golden image what was that device what was its host name so uh first of all let's get rid of the grammatical error this device is not running the golden image okay so right off the bat our conditional works we've been able to evaluate the current version of the operating system by digging through that python dictionary that we got back from our rpc call we found the key that represents the value of the operating system and now we've done this evaluation by using the double equal signs and then calling back to our golden image string that we had created up there now for the last step let's go ahead and get the string i'm sorry let's get the hostname of the device to be printed out with the rest of this string within our if conditional now the way that we can do this in a and the more recent version and the only one that i'll cover today is something called an f string and what that allows you to do is basically insert a variable into a string and have that variable spelled out entirely rather than you know trying to hard code it or some other kind of operation that wouldn't be appropriate so the way that we create an f string is by pressing the letter f in front of a string and then using a single curly braces open and close and then typing the name of our variable in our case that's just going to be the temporary name or the temporal variable and thermal variable of firewall and then we can remove that and then we can do the same right here so the expectation is that the firewall's name will be inserted into the string now let's see whether or not that is accurate automation juniper one two three all right let's see how this comes back so alderaan.dmz.home is running the golden image it's running the 19.4 we've evaluated it and then hoth is gonna return back to say it is running the golden image and then the last one is going to be deep space nine and that's going to be the one that's not compliant within our script great last thing for us to do just make the output just a little bit prettier because right now the only thing that that we're getting back is everything is on the same or it's just it's separated by a single line and i'd rather it to have just a little bit extra flare on it so let's go ahead and add an additional line right up here and we'll say we want the string let's go ahead and delete this there we go we want an equal sign and i want it multiplied by 64. now you might be thinking to yourself that's an invalid operation but you're incorrect you can absolutely have a single character and multiply it by 64 you would just get a combination of 64 of that specific character repeated uh i'm sorry you get that single character repeated 64 times you cannot do addition or i'm sorry you can't do a mathematical equation where we um you know we we mix and match different you know integers and strings and etc but we can absolutely use operations like this to just kind of help us get some additional um flare within our our output here so let's go ahead and run this again automation and juniper one two three and what we should get now is a nice little banner of equal signs uh and then it'll actually say the name of the device and whether or not it is compliant and there we go so this will help us humans as we interpret the output that comes back sometimes it's nice to be friendly to your fellow humans and this is one way that we're giving back uh so there we are nice little separation in between the host names so that we can quickly identify what is compliant and what is not so just like that you know it didn't take too long for us to to walk through the creation of a software compliance tool on the juniper firewalls um you know we we covered quite a bit today we talked about why python was important for networking engineers mostly because of the the ease of use but also because of the packages that are available within the ecosystem we talked about the different data types what's a string what's an integer what's a list what's the dictionary we showed how those can be combined within a single script to give us our compliance code we talked through the importance of installing and importing our packages again just not necessarily just to be lazy but to make our lives just a lot better by reusing code that's already out there and then we talked about creating loops we talked about the relationship with loops and lists together and then finally we talked about the conditionals how to incorporate logic within to your script now don't run off and go update your linkedin profile as some kind of python automation guru uh there's there's still a lot to be learned it's difficult to take an entire career and boil it down into like an hour's worth of content there's so much to learn in fact the one thing i'll point out right here one thing that you may have noticed is the speed the speed of python now just kind of wrapping up just talking about where to go from here on out one of the things that i would start looking at is automation frameworks tools like ansible nor near net palm how do those devices help not only the development of our code but also help with the speed in which that we're running in because python inherently is is a little slow it's not a bad thing it's still faster than humans uh but there's a lot of room for improvement and that's where automation frameworks really kind of shine uh they also shine in other ways such as working in a group context but that's a whole other conversation for another time for now again my name is calvin rimsburg and thank you for hanging out with us while we learned some python for networking and engineers have a good day
Info
Channel: Calvin Remsburg
Views: 7,802
Rating: undefined out of 5
Keywords:
Id: m3KP--H2jNI
Channel Id: undefined
Length: 82min 9sec (4929 seconds)
Published: Sun Jan 31 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.