#python #function #return
Вопрос:
У меня есть этот скрипт для выполнения резервного копирования конфигурации с устройств juniper на основе ввода из Netbox. Я хотел бы немного расширить этот скрипт, чтобы получить версию прошивки с устройства juniper и обновить наш netbox, используя пользовательское поле.
#!/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='lt;censoredgt;') 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 lt;usernamegt; [-p lt;junos admin passwordgt;]') sys.exit(2) for opt, arg in opts: if opt == '-?': print ('configbackup_junos.py -u lt;usernamegt; [-p lt;junos admin passwordgt;]') 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) gt; 0: print ('Junos Password set on commandlinen') 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:])
Моя проблема в том, как мне получить переменную «junos_version», возвращаемую функцией getConfig. Как вы можете видеть,я пытался использовать «return True, junos_version», но как мне захватить его в выводе функции? (Я прочитал все статьи, которые смог найти об этом, и попробовал ряд предложений, но ничего не работает. Мне нужно иметь возможность ввести «junos_version» в эту команду nb_device.custom_fields['firmware_version'] = junos_version
Который я бы разместил как раз перед nb_device.save
Я подозреваю, что здесь подводит мое чувство логики, я просто не вижу леса за деревьями.
Ответ №1:
if GetConfig(asset,junos_username,junos_password):
вы можете изменить это с помощью :
with flag, junos_version=GetConfig(asset,junos_username,junos_password):
Комментарии:
1. Это приведет к ошибке
not enough values to unpack
, еслиGetConfig
перейдет кexception
.2. затем верните другое значение в части исключения, не желательно, чтобы функция иногда возвращала 1 значение, а иногда возвращала 2
Ответ №2:
Если вы возвращаете несколько значений из функции, считайте их кортежем. В вашем случае вы можете получить второе значение следующим образом:
cfg = GetConfig(...) // add your args junos_version = cfg[1] // get the 2-nd returned value from a tuple.
Ответ №3:
Сначала у вас должна быть стабильная доходность.
def GetConfig(my_hostname, my_username, my_password): try: ... return True,junos_version except Exception as err: ... return False
Здесь вы можете получить кортеж (логического значения и версии) или bool (True или False) в качестве возврата.
Я бы изменил его как:
def GetConfig(my_hostname, my_username, my_password): try: ... return True,junos_version except Exception as err: ... return False, None
так как нет никаких junos_version
исключений.
Теперь вы меняете код, в котором используете его в качестве:
def main(argv): ... if GetConfig(asset,junos_username,junos_password): ...
Для
def main(argv): ... cfg, version = GetConfig(asset,junos_username,junos_password) if cfg: ...
Комментарии:
1. Я выбрал это решение, потому что это очень хорошо объясненное решение, которое также сработало. 🙂