Search code examples
pythonfunctionreturn

Expand python function to return onee more value


I have this script to perform config-backups from juniper-devices based on input from Netbox. I would like to expand this script a little to fetch the firmware version from the juniper device and update our netbox using a custom field.

#!/usr/bin/python3

import sys,os,getopt
from getpass import getpass
from jnpr.junos import Device
import jnpr.junos.facts
from jnpr.junos.utils.config import Config
from jnpr.junos.exception import *
from lxml import etree
from pprint import pprint
import pynetbox
import datetime

nb = pynetbox.api(url='https://netbox-test/', token='<censored>')
save_path = '/config-backups/'

def printProgress(logtype,hostname,message):
        print("%s:%s:%s"%(logtype,hostname,message))

def GetConfig(my_hostname, my_username, my_password):
        try:
                printProgress("INFO",my_hostname,"Connecting to device")
                dev=Device(host=my_hostname,user=my_username,password=my_password)
                dev.open(auto_probe=10)
                dev.timeout=10
                printProgress("INFO",my_hostname,"Retrieving config")
                config = dev.rpc.get_config(options={'database':'committed','format':'set'})
                junos_version = dev.facts['version']
                configbackup = (etree.tostring(config, encoding='unicode', pretty_print=True))
                completefilename = os.path.join(save_path, my_hostname+".set.config")  
                outfile=open(completefilename, "w")
                outfile.write(configbackup)
                dev.close()
                outfile.close()
                return True,junos_version
        except Exception as err:
                printProgress("ERROR",my_hostname,"Encountered exception while backing up config")
                printProgress("ERROR",my_hostname,str(err))
                return False

def main(argv):
   junos_password = ''
   try:
      opts, args = getopt.getopt(argv,"?u:p:",["username=","password"])
   except getopt.GetoptError:
      print ('configbackup_junos.py -u <username> [-p <junos admin password>]')
      sys.exit(2)
   for opt, arg in opts:
      if opt == '-?':
         print ('configbackup_junos.py -u <username> [-p <junos admin password>]')
         sys.exit()
      elif opt in ("-u", "--username"):
         junos_username = arg
      elif opt in ("-p", "--password"):
         junos_password = arg
   print ('Will attempt to backup junos devices documented in Netbox using username:', junos_username)
   if len(junos_password) > 0:
     print ('Junos Password set on commandline\n')
   else:
     print ('password not entered, will ask for it')
     junos_password=getpass(prompt="\nPassword: ")

   nb_devicelist = nb.dcim.devices.all()
   for nb_device in nb_devicelist:
     platform = str(nb_device.platform)
     pri_ip = str(nb_device.primary_ip)
     asset = nb_device.asset_tag
     devstatus = str(nb_device.status)
     backup_enabled = nb_device.custom_fields['backup_enable']
     if nb_device.virtual_chassis:
       vchassismaster = str(nb_device.virtual_chassis.master)
     else:
       vchassismaster = 'no_chassis'
     if backup_enabled == 'Yes' and platform == 'Junos' and devstatus == 'Active' and pri_ip != 'None' and asset:
       if vchassismaster == (nb_device.name) or vchassismaster == 'no_chassis':
         if GetConfig(asset,junos_username,junos_password):
           print ("Config Successfully backed up from device.",nb_device)
           nb_device.custom_fields['backup_status'] = "OK"
           timenow = datetime.datetime.now()
           timestamp = timenow.strftime("%Y-%m-d %X")
           nb_device.custom_fields['backup_timestamp'] = timestamp
           nb_device.save()
           print (junos_version)
         else:
           printProgress ("ERROR",nb_device,"Config backup failed! ")
           nb_device.custom_fields['backup_status'] = "FAILED"
           nb_device.save()
         print("")

if len(sys.argv) == 1:
   sys.exit()
   
if __name__ == "__main__":
   main(sys.argv[1:])

My problem is how do I get the variable "junos_version" returned from the function GetConfig. As you can see I have tried using "return True,junos_version", but how do I grab it in the output of the function? (I have read all the articles I could find about this and tried a number of suggestions, but nothing works. I need to be able to input the "junos_version" into this command nb_device.custom_fields['firmware_version'] = junos_version Which I wouldd placee just before the nb_device.save

I suspect it is my sense of logic that fails here, I just cannot see the forest for trees.


Solution

  • First you have to have a stable return.

    def GetConfig(my_hostname, my_username, my_password):
        try:
            ...
            return True,junos_version
        except Exception as err:
            ...
            return False
    

    In here you can have a tuple (of boolean and version) or a bool (True or False) as return.

    I would change it as:

    def GetConfig(my_hostname, my_username, my_password):
        try:
            ...
            return True,junos_version
        except Exception as err:
            ...
            return False, None
    

    since there is no junos_version in exception.

    Now you change the code where you use it as:

    def main(argv):
       ...
             if GetConfig(asset,junos_username,junos_password):
       ...
    

    to

    def main(argv):
       ...
             cfg, version = GetConfig(asset,junos_username,junos_password)
             if cfg:
       ...