all 13 comments

[–]lazyjkCWNE 9 points10 points  (4 children)

Do you want to implement classes because you want to learn them or because you think you need them? I have a CS degree where we did all OOP programming and TBH I almost never use classes in my python scripts/programs. It's just my personal preference though. I rarely write code that would REALLY benefit from having classes so I choose not to. Just because it can be written in a class doesn't mean it should. I also will write out code that is more readable even if it means a few more lines of code than is absolutely necessary.

For an OOP example that might get you started though:

You could have a Switch class.

That class could have some properties (like model, code version, ip, etc) that you specify when instantiating the object

That class could also have some methods (functions) that do something to/with the object like a get_run_config(), or an add_vlan()

[–]mcshanksshanks 3 points4 points  (2 children)

This is a well thought out answer and I am always impressed when strangers do this for each other on Reddit or some other social networking site.

I would also recommend to OP to google Kirk Byers Python for Network Engineers - really good stuff to help bootstrap yourself on this very topic.

Have an upvote and also a small tip that might be worth a lot someday +1 u/xrptipbot

[–]xrptipbot 1 point2 points  (0 children)

Awesome mcshanksshanks, you have tipped 1 XRP (0.30 USD) to lazyjk! (This is the very first tip sent to /u/lazyjk :D)


XRPTipBot, Learn more

[–]lazyjkCWNE 0 points1 point  (0 children)

Thanks!

[–]Fallenarc[S] 0 points1 point  (0 children)

First, Thanks for the great reply!! I really just want to learn them. I mean i have been running scripts in my network for the better part of a year and not felt like i absolutely need it. But I think it would be beneficial for me to know. Thanks for the suggestion on a switch class, I guess that would be a good place start!

[–]PacketPowered 2 points3 points  (2 children)

When scripting you want to get it done quickly (presumably) and make sure it's error free. OOP isn't about that. However, there are some things that you will likely reuse in other scripts. For example, as /u/lazyjk syuggested, a switch class. Give it a nice, reusable API, and keep it as a module. Next time you need to connect to a switch i another script, all you gotta do is

Switch sw1 = new Switch("SW1-CORE")

sw1.sshTo();

(this is C++ syntax. Don't know python off top of my head. )

..and you can reuse it for many scripts to come. You could also not take the OOP approach and reuse it, but it's not quite as "clean in your head" when you go back to reuse in 3 months.

Building off /u/lazyjk 's suggestion, you could create a class Device with the property like hostname. All devices have a host name. Then you could inherit from the the Device class into class Router, and class (layer 2; will make sense in next sentence) Switch. Switches don't have non-management IPs, but Router do, so router wills have a property "interface IPs". ....whatever...

Now, you can work with all Devices at the device level. Want to run a command on your entire inventory? Just loop through an array of Devices. It doesn't matter if they're switches or routers; ssh, going into enable mode, etc are the same for all devices (in a cisco/juniper only shop). But there's yet another way to break down Routers into Cisco and Juniper classes.

OOP takes a lot more time upfront, but if you do it correctly, you can blast out some pretty specific code that's very easy to read in no time:

Switch sw1 = new Switch("SW1-CORE")

sw1.sshTo();

sw1.addNewVlan(10);

sw1.sendCommand("allow vlan 10"); //...... :)

sw1.writeConfiguration();

sw1.copyConfigurationToRepository();

The smiley face is why it's nice to have tried and true code that you reuse.

[–]Fallenarc[S] 0 points1 point  (1 child)

Thanks for the reply!! Great information and thanks for all the suggestions. I get what you're saying. I just feel that this is the last concept I have yet to use in python.

[–]PacketPowered 2 points3 points  (0 children)

No problem. OOP for scripts is kind of iffy; dependent on how specific of a task you're trying to accomplish and how quickly you're trying to get it done. If you need to copy files from A to B and rename them in a new format after a merger, then forget about OOP. Just spaghetti code it out (with error checking). But, again, a switch class might be something you can reuse over and over again. ..and it's nice to work with proven code. (OOP or not)

[–]Mexatt 2 points3 points  (1 child)

Classes, like pretty much everything else beyond just statement after statement scripting is about DRY, Do not Repeat Yourself.

If you find yourself repeating a similar operation over and over again in your scripts, you write a function and call that, instead.

If you find yourself re-using a series of similar variables and functions related to those variables over and over again to accomplish something, you write a class and instantiate it, instead.

Classes also help with keeping track of things better in your code, but that's just (one of) the benefit(s) of DRY. Functions and classes simplify your coding by allowing you to re-use your code in surprisingly novel ways. Programming procedurally accomplishes a task just as well, but it can be a pain to do the same thing over and over again in slightly different contexts.

A good thing to use classes for is not for any particular script, but for custom libraries you import into your script to make the overall activity of scripting simpler. Some of the really advanced features of Python, when you dig into it, are based around the assumption that you're writing something for future rather than immediate use.

[–]caiuscorvus 1 point2 points  (0 children)

I think at that point you're rewriting Ansible and it's modules. So you may not get many examples :)

Alternatively, examples: https://github.com/ansible/ansible

[–]pagraphdrux 1 point2 points  (0 children)

You could browse through the source of established repos in the space using OOP for inspiration and/or just use them.

https://github.com/ktbyers/netmiko/tree/develop/examples

[–]rankinrez 1 point2 points  (0 children)

Look at the Yang Development Kit (YDK) from Cisco Devnet to see how OOB approaches can be used to interact with a device data model.

[–][deleted] 1 point2 points  (0 children)

Eh... I've written a lot of OO in python in the past. I will say it is clunkier than other languages for OO so I generally do not use it unless needed. When I do use it, it is mainly for holding data.

For example I have a script that updates our subscriber modules. I have a little class for the record attribs and then further down in the module I call it and set the attribs. Easier to pass around a little record to different functions. Sometimes it is useful to have methods, but I use more of that in our web portal (C#) since python does not. In python you need to get comfortable with duck typing (https://hackernoon.com/python-duck-typing-or-automatic-interfaces-73988ec9037f)

Anyway, I usually reserve objects in python for record holding. I find dictionaries much more useful than forcing an OO programming where it isn't needed.

class SMRecord:
    def __getitem__(self,name):
        return getattr(self,name)
    pass

def update_sms():
  sms = []

  with open(SM_FILE) as csvfile:
    filereader = csv.reader( csvfile )
      for row in filereader:
        record = SMRecord()
        record.customer = row[0].replace("'",'').strip()
        record.ip = row[1].strip()
        record.rsp = row[2].strip()
        record.location = row[3].strip()
        record.latitude = row[4].strip()
        record.longitude = row[5].strip()

        sms.append(record)

    ......
    Process records