def execute(opts, net_cmd, net_config, device_commit, use_textfsm): """ This function setups up a netmiko connection and performs the different commands. The results are returned in a json document :param opts: :param net_cmd: :param net_config: :param device_commit: used with net_config cmds :param use_textfsm: used with net_cmd to specify the results should be formatted through TextFSM :return: json results such as: { 'status': 'success'|'failure', 'reason': xx, 'send_command': xx, 'send_result': xx, 'config_command': xx, 'config_result': xx } """ result = {} connection = None try: # if secret is specified, use enable_mode bEnable_mode = len(opts.get('secret', '')) > 0 connection = ConnectHandler(**opts) if bEnable_mode: connection.enable() # standard commands to execute if net_cmd: result['send_command'] = net_cmd send_result = connection.send_command(net_cmd, use_textfsm=use_textfsm) result['send_result'] = send_result # configuration commands to execute if net_config: result['config_command'] = net_config config_result = connection.send_config_set(net_config.split("\n")) result['config_result'] = config_result if device_commit: connection.commit() result['status'] = 'success' except Exception as err: result['status'] = 'failure' result['reason'] = str(err) finally: if connection: if bEnable_mode: connection.exit_enable_mode() connection.disconnect() return result
def enable_netconf(net_device): print("{} Connecting to {}".format(time.asctime(), net_device['ip'])) junos_device = ConnectHandler(**net_device) configure = junos_device.config_mode() #eq edit or configuration mode print("{} Applying configuration to {}".format(time.asctime(), net_device['ip'])) set_netc_ssh = junos_device.send_command( "delete system services netconf ssh") print("{} Commiting config to {}".format(time.asctime(), net_device['ip'])) junos_device.commit(comment='Enable Netconf Service', and_quit=True) print("{} Closing connection to {}".format(time.asctime(), net_device['ip'])) junos_device.disconnect()
def enable_netconf(net_device): print("{} Connecting to {}".format(time.asctime(), net_device['ip'])) junos_device = ConnectHandler(**net_device) configure = junos_device.config_mode() print("{} Applying configuration to {}".format(time.asctime(), net_device['ip'])) setssns = junos_device.send_command("set system services netconf ssh") print("{} Committing configuration to {}".format(time.asctime(), net_device['ip'])) junos_device.commit(comment='Enabled NETCONF service', and_quit=True) print("{} Closing connection to {}".format(time.asctime(), net_device['ip'])) junos_device.disconnect()
def ConfigP(HOSTNAME, login_details): print('\nDevice to be configured= ' + login_details['ip'] + '\n') # push config on device and create log # net_connect = ConnectHandler(device_type=deviceType, ip=dip, username=username, password=pw, port=port) net_connect = ConnectHandler(**login_details) #output1 = net_connect.send_config_set(config) # get config file from Config folder file_path = os.path.dirname(os.path.realpath(__file__)) print(file_path) config_file = file_path + '\\Config\\' + HOSTNAME + '.cfg' output1 = net_connect.send_config_from_file(config_file) time.sleep(5) output2 = net_connect.commit() time.sleep(4) output3 = net_connect.exit_config_mode() output4 = net_connect.disconnect() c = ('\n----' + login_details['ip'] + '----\n' + '\n' + output1 + output2 + output3 + '\n' + '\n---- END ----\n') print(c) deviceLog(c) time.sleep(1)
def send_commands(devices: list, cmds: str) -> list: """ Send commands to specified device. :param list devices: List of dictionaries representing each device :param str cmds: String containing the commands to send :return list: List containing the status of each device configured """ log.info("Preparing to send onboarding commands to devices...") statuses = list() for device in devices: status = {"device": device['ip'], "status": "pending", "error": None} log.info(f"Sending commands to {device['ip']}...") try: net_connect = ConnectHandler(**device) net_connect.find_prompt() o = net_connect.send_config_set(config_commands=cmds, exit_config_mode=False) log_cmds.debug(f"Output for {device['ip']} config: {o}") o = net_connect.commit(and_quit=True) log_cmds.debug(f"Output for {device['ip']} commit: {o}") log.info(f"Successfully sent commands to {device['ip']}!") status['status'] = "success" except Exception as e: log.error(f"Failed sending commands to {device['ip']}!") log.error(f"Error sending commands: {e}") status['status'] = "failed" status['error'] = str(e) continue statuses.append(status) return statuses
def enable_netconf(net_device): print("{} Connecting to {}".format(time.asctime(), net_device['ip'])) junos_device = ConnectHandler(**net_device) configure = junos_device.config_mode() print("{} Applying configuration to {}".format(time.asctime(), net_device['ip'])) junos_device.send_command("delete interfaces ge-0/0/2 disable") print("{} Committing configuration to {}".format(time.asctime(), net_device['ip'])) junos_device.commit(comment='delete ge0/0/2 disable', and_quit=True) print("{} Closing connecting to {}".format(time.asctime(), net_device['ip'])) junos_device.disconnect()
def gethostname(device): dev = { 'device_type': platform, 'ip': device, 'username': username, 'secret': password, 'password': password, 'global_delay_factor': 4, 'verbose': True, } device = ConnectHandler(**dev) device.enable() hostname = device.send_config_set(command) hostname += device.commit(confirm=True, confirm_delay=5) time.sleep(30) hostname += device.commit(check=True) return hostname
def net_connect(request): """ Create the SSH connection to the remote device Return the netmiko connection object """ device_under_test = request.config.getoption("test_device") test_devices = parse_yaml(PWD + "/etc/test_devices.yml") device = test_devices[device_under_test] device["verbose"] = False conn = ConnectHandler(**device) # Temporarily set the hostname if device_under_test == "cisco3_long_name": conn.send_config_set("hostname cisco3-with-a-very-long-hostname") elif device_under_test == "cisco_xr_long_name": conn.send_config_set("hostname iosxr3-with-very-long-hostname-plus") conn.commit() conn.exit_config_mode() return conn
def setup_module(module): module.EXPECTED_RESPONSES = { 'enable_prompt' : 'RP/0/0/CPU0:XRv-1#', 'base_prompt' : 'RP/0/0/CPU0:XRv-1', 'interface_ip' : '169.254.254.181', 'config_mode' : '(config)' } show_ver_command = 'show version' commit_history_cmd = 'show configuration commit list' module.basic_command = 'show ipv4 int brief' net_connect = ConnectHandler(**cisco_xr) module.show_version = net_connect.send_command(show_ver_command) module.show_ip = net_connect.send_command(module.basic_command) net_connect.enable() module.enable_prompt = net_connect.find_prompt() current_commit_history = net_connect.send_command(commit_history_cmd) # get the current 10 digit commit Label ID module.current_commit = current_commit_history.split('\n')[4].split()[1] module.config_mode = net_connect.config_mode() config_commands = ['logging monitor warning', 'logging buffered 30720100', 'logging console errors'] net_connect.send_config_set(config_commands) net_connect.commit() # get the new 10 digit commit Label ID new_commit_history = net_connect.send_command(commit_history_cmd) module.new_commit = new_commit_history.split('\n')[4].split()[1] module.config_commands_output = net_connect.send_command("show run | inc logging") net_connect.disconnect()
def main(): nc = ConnectHandler(**cros) output = nc.send_command("show interface configuration brief") print(output) output = nc.send_config_set([ "interface physical 7/1/3", "admin-status up", "ipv4 address 1.1.1.1 prefix 24", ]) print(output) output = nc.commit() print(output) output = nc.send_command("show interface configuration brief") print(output)
connect = ConnectHandler(device_type='juniper', ip=devices, username=username, password=password, port=22, global_delay_factor=2) connect.find_prompt() time.sleep(1) print('Connect Successfully') connect.config_mode() print(connect.send_config_set('rollback 0')) connect.send_config_from_file(config) print(connect.send_config_set('show | compare')) print(connect.send_config_set('commit check')) x = raw_input(str('Proceed to commit(Y or N) : ')) if x == 'Y': print('Commiting') connect.commit() #connect.send_config_set('commit') print('Below configuration hasbeen modified to device') print('==================') print(connect.send_config_set('show | compare rollback 1')) connect.exit_config_mode() connect.disconnect() else: connect.send_config_set('rollback 0') connect.commit() connect.disconnect() end_time = datetime.now() print("Total time: {}".format(end_time - start_time)) print('Completed Successfully!!')
def create_ospf(n: str) -> list: return [ f"set interfaces ge-0/0/1 unit 0 family inet address 192.168.0.{n}/30", f"set interfaces lo0 unit 0 family inet address 10.0.0.{n}/32", f"set routing-options router-id 10.0.0.{n}", "set protocols ospf area 0.0.0.0 interface lo0.0 passive", "set protocols ospf area 0.0.0.0 interface ge-0/0/1.0" ] if __name__ == "__main__": vsrx1 = create_conn("2201") vsrx2 = create_conn("2202") vsrx1_conn = ConnectHandler(**vsrx1) vsrx2_conn = ConnectHandler(**vsrx2) vsrx1_conn.send_config_set(create_ospf("1")) vsrx2_conn.send_config_set(create_ospf("2")) vsrx1_conn.commit() vsrx2_conn.commit() vsrx1_conn.disconnect() vsrx2_conn.disconnect() vsrx1 = create_conn("2201") vsrx2 = create_conn("2202") vsrx1_conn = ConnectHandler(**vsrx1) vsrx2_conn = ConnectHandler(**vsrx2) print(vsrx1_conn.send_command(SHOW_OSPF)) print(vsrx2_conn.send_command(SHOW_OSPF)) vsrx1_conn.disconnect() vsrx2_conn.disconnect()
class BaseNode(object): def __init__(self, ip, hostname, username, password, platform, type): self.ip = ip self.hostname = hostname self.username = username self.password = password self.platform = platform self.type = type self.password_decrypt = base64.b64decode(self.password) def connect(self): if (self.type == 'switch'): self.net_connect = ConnectHandler(self.ip, self.hostname, self.username, self.password_decrypt, self.get_secret(), device_type=self.get_device()) elif (self.type == 'vfirewall'): self.net_connect = ConnectHandler(self.ip, self.hostname, self.username, self.password_decrypt, self.get_secret(), port=22, device_type=self.get_device()) else: self.net_connect = ConnectHandler(self.ip, self.hostname, self.username, self.password_decrypt, self.get_secret(), device_type=self.get_device()) def get_secret(self): enable_get_secret = '' if (self.location() == 'wdstk'): enable_get_secret = base64.b64decode(self.password) elif (self.location() == 'ktch'): enable_get_secret = base64.b64decode(self.password) return enable_get_secret def location(self): datacenter_location = '' if (self.type == 'firewall'): location_list = self.hostname.split('-') datacenter_location = location_list[3] elif (self.type == 'switch' or self.type == 'router'): location_list = self.hostname.split('.') datacenter_location = location_list[3] return datacenter_location def get_device(self): device_attribute = '' if (self.type == 'router' or self.type == 'switch'): device_attribute = 'cisco_ios' elif (self.type == 'firewall'): device_attribute = 'cisco_asa' elif (self.type == 'vfirewall'): device_attribute = 'juniper' return device_attribute def push_cfgs(self, commands): self.connect() output = self.net_connect.enable() if (self.platform == 'cisco'): output = self.net_connect.send_config_set(commands) print output if (self.platform == 'juniper'): output = self.net_connect.send_config_set(commands, exit_config_mode=False) self.net_connect.commit(and_quit=True) print output self.net_connect.disconnect() def exec_command(self, command): self.connect() output = self.net_connect.send_command(command) output = output.replace('\n', '\n{}: '.format(self.hostname)) output = re.sub(r'^', '{}: '.format(self.hostname), output) print("{}".format(output)) print("") self.net_connect.disconnect() def get_config(self, command): command = 'show running-config' f = open("/backup-configs/{}".format(self.hostname) + ".conf", "w") self.connect() output = self.net_connect.send_command_expect("show running-config") f.write(output) f.close() self.net_connect.disconnect() def get_diff(self, commands): f = open("/diff-configs/{}".format(self.hostname) + ".conf", "w") self.connect() output = self.net_connect.send_config_set(commands) # print output f.write(output) f.close() self.net_connect.disconnect()
class BaseNode(object): def __init__(self,created_at,created_by,domain_name,hardware_vendor,lifecycle_status,location_name,mgmt_ip4,mgmt_con_ip4,mgmt_oob_ip4,mgmt_snmp_community4,name,platform_name,oncall_team,opersys,software_image,software_version,type,role_name,serial_num,status,updated_at,updated_by): self.created_at = created_at self.created_by = created_by self.domain_name = domain_name self.hardware_vendor = hardware_vendor self.lifecycle_status = lifecycle_status self.location_name = location_name self.mgmt_con_ip4 = mgmt_con_ip4 self.mgmt_ip4 = mgmt_ip4 self.mgmt_oob_ip4 = mgmt_oob_ip4 self.mgmt_snmp_community4 = mgmt_snmp_community4 self.name = name self.password = os.environ.get('PASSWORD') self.platform_name = platform_name self.oncall_team = oncall_team self.opersys = opersys self.role_name = role_name self.serial_num = serial_num self.software_image = software_image self.software_version = software_version self.status = status self.type = type self.updated_at = updated_at self.updated_by = updated_by self.username = os.environ.get('USERNAME') def connect(self): self.net_connect = ConnectHandler(self.mgmt_ip4,self.name,self.username,self.password,self.password,device_type=self.get_device_type()) def scpconnect(self): self.connect() self.scp_connect = SCPConn(self.net_connect) def location(self): datacenter_location = '' if (self.type == 'firewall'): location_list = self.name.split('-') datacenter_location = location_list[3] elif (self.type == 'switch' or self.type == 'router'): location_list = self.name.split('.') datacenter_location = location_list[3] return datacenter_location def get_device_type(self): device_type = { 'ASA5510' : 'cisco_asa', 'WS-C3750G-24TS-1U' : 'cisco_ios', 'f5linux' : 'f5_linux', 'ltm' : 'f5_ltm', 'tmsh' : 'f5_tmsh', 'firefly-perimeter' : 'juniper', 'juniper_junos' : 'juniper_junos', 'vyattavyos' : 'vyatta_vyos', 'vyos' : 'vyos' } return device_type['{}'.format(self.platform_name)] def push_cfgs(self,commands): self.connect() output = self.net_connect.enable() if self.hardware_vendor == 'cisco' and self.opersys == 'ios': output = self.net_connect.send_config_set(commands, exit_config_mode=True) save = self.net_connect.send_command('write memory') # print(output) # print(save) elif self.hardware_vendor == 'cisco' and self.opersys == 'asa': output = self.net_connect.send_config_set(commands, exit_config_mode=True) save = self.net_connect.send_command('write memory') # print(output) # print(save) elif self.hardware_vendor == 'cisco' and self.opersys == 'nxos': output = self.net_connect.send_config_set(commands, exit_config_mode=True) save = self.net_connect.send_command('copy running-config startup-config') # print(output) # print(save) elif self.hardware_vendor == 'juniper': output = self.net_connect.send_config_set(commands, exit_config_mode=False) self.net_connect.commit(and_quit=True) # print(output) elif self.hardware_vendor == 'vyatta': output = self.net_connect.send_config_set(commands, exit_config_mode=False) self.net_connect.commit() # print(output) elif self.hardware_vendor == 'f5': output = self.net_connect.send_config_set(commands,enter_config_mode=False,exit_config_mode=False) save = self.net_connect.send_command('save sys config') # print(output) # print(save) self.net_connect.disconnect() def pull_cfgs(self,command): scp_flag = False method = 'pull_cfgs' if self.hardware_vendor == 'cisco' and self.opersys == 'ios': command = 'show running-config | exclude ntp clock-period' elif self.hardware_vendor == 'cisco' and self.opersys == 'nxos': command = 'show running-config | exclude Time' elif self.hardware_vendor == 'cisco' and self.opersys == 'asa': command = 'show running-config' elif self.hardware_vendor == 'juniper': command = 'show configuration' elif(self.hardware_vendor == 'vyatta'): command = 'show configuration commands' elif self.hardware_vendor == 'f5': command = 'list ltm one-line' self.scpconnect() self.write_to_file(command) scp_flag = True self.scp_connect.scp_get_file('/var/local/ucs/config.ucs', '{}/backup-configs/{}'.format(self.get_home_directory(),self.name)) self.scp_connect.close() self.net_connect.disconnect() if self.hardware_vendor != 'juniper' or self.hardware_vendor != 'f5': self.connect() self.write_to_file(command,scp_flag,method) self.net_connect.disconnect() def exec_cmd(self,command): self.connect() output = self.net_connect.send_command(command) output = output.replace('\n','\n{}: '.format(self.name)) output = re.sub(r'^','{}: '.format(self.name),output) print ('{}'.format(output)) print('') self.net_connect.disconnect() def get_home_directory(self): home_directory = os.getenv('HOME') return home_directory def get_config(self,command): scp_flag = False method = 'get_config' if self.hardware_vendor == 'cisco': command = 'show running-config' elif self.hardware_vendor == 'f5': command = 'list one-line' self.connect() self.write_to_file(command,scp_flag,method) self.net_connect.disconnect() def get_diff(self,commands): scp_flag = False method = 'get_diff' self.connect() self.write_to_file(commands,scp_flag,method) self.net_connect.disconnect() def get_subdir(self,scp_flag): if self.hardware_vendor == 'f5' and scp_flag: sub_dir = 'ucs' else: sub_dir = 'configs' return sub_dir def write_to_file(self,command,scp_flag,method): if method == 'pull_cfgs': extention = '' if self.hardware_vendor == 'juniper' and 'display set' in command: extention = '.set' else: extention = '.conf' self.check_and_mkdir(scp_flag,method) with open('{}/backup-configs/{}/{}{}'.format(self.get_home_directory(),self.get_subdir(scp_flag),self.name,extention), "w") as file: output = self.net_connect.send_command(command) file.write(output) file.close() elif method == 'get_config': self.check_and_mkdir(scp_flag,method) with open('{}/backup-configs/{}'.format(self.get_home_directory(),self.name) + ".conf", "w") as file: output = self.net_connect.send_command(command) file.write(output) file.close() elif method == 'get_diff': self.check_and_mkdir(scp_flag,method) with open('{}/diff-configs/{}'.format(self.get_home_directory(),self.name) + ".conf", "w") as file: output = self.net_connect.send_config_set(command) file.write(output) file.close() def check_and_mkdir(self,scp_flag,method): if method == 'pull_cfgs': os.makedirs('{}/backup-configs/{}/'.format(self.get_home_directory(),self.get_subdir(scp_flag)),exist_ok=True) elif method == 'get_config': os.makedirs('{}/backup-configs/{}'.format(self.get_home_directory(),self.name),exist_ok=True) elif method == 'get_diff': os.makedirs('{}/diff-configs/{}'.format(self.get_home_directory(),self.name),exist_ok=True)
Pynet2ExitConfig = Pynet2Connect.exit_config_mode() JuniperExitConfig = JuniperConnect.exit_config_mode() print "\n", Pynet1ExitConfig, "\n", Pynet2ExitConfig, "\n", JuniperExitConfig, "\n" print "Checking interfaces' IPs..." time.sleep(2) Pynet1IpInt = Pynet1Connect.send_command('show ip int brief') Pynet2IpInt = Pynet2Connect.send_command('show ip int brief') JuniperIpInt = JuniperConnect.send_command('show interfaces terse | match "up up"') print "\n", Pynet1IpInt, "\n\n", Pynet2IpInt, "\n\n", JuniperIpInt, "\n" print "Sending a few config commands to the Juniper..." time.sleep(2) JuniperConfig = JuniperConnect.config_mode() JuniperConfigCommands = ['set interfaces vlan unit 0 description "Management Vlan 0"', 'set system host-name pynet-juniper-srx1'] JuniperConfigChange = JuniperConnect.send_config_set(JuniperConfigCommands) JuniperConfigCheckCommand = ['show | compare'] JuniperConfigChangeCheck = JuniperConnect.send_config_set(JuniperConfigCheckCommand) print "Displaying the change below...\n" print JuniperConfigChangeCheck time.sleep(1) print "\nCommiting the change..." JuniperConnect.commit() time.sleep(60)
'device_type': 'juniper', 'ip': '127.0.0.1', 'username': '******', 'password': '******', 'port': 2222, 'verbose': False } routers = [rtr1, rtr2] for dev in routers: net_connect = ConnectHandler(**dev) print("************Show commands*************") output1 = net_connect.send_command("show config| display set") output2 = net_connect.send_command( "show system information | match Hostname:") print(output1) print(output2) print("*******" * 10) print("***********Config mode********") net_connect.config_mode() config_output1 = net_connect.send_command( "set interfaces et-0/0/0 description netmiko_juniper_test_script") print(config_output1) #Commit commands commit = net_connect.commit(and_quit=True) print(commit) print("************Show command*************") output3 = net_connect.send_command("show interfaces description") print(output3)
class PANOSDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60, optional_args=None): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.loaded = False self.changed = False self.device = None self.ssh_device = None self.ssh_connection = False self.merge_config = False if optional_args is None: optional_args = {} netmiko_argument_map = { 'port': None, 'verbose': False, 'use_keys': False, 'key_file': None, 'ssh_strict': False, 'system_host_keys': False, 'alt_host_keys': False, 'alt_key_file': '', 'ssh_config_file': None, } fields = netmiko_version.split('.') fields = [int(x) for x in fields] maj_ver, min_ver, bug_fix = fields if maj_ver >= 2: netmiko_argument_map['allow_agent'] = False elif maj_ver == 1 and min_ver >= 1: netmiko_argument_map['allow_agent'] = False # Build dict of any optional Netmiko args self.netmiko_optional_args = {} for k, v in netmiko_argument_map.items(): try: self.netmiko_optional_args[k] = optional_args[k] except KeyError: pass self.api_key = optional_args.get('api_key', '') def open(self): try: if self.api_key: self.device = pan.xapi.PanXapi(hostname=self.hostname, api_key=self.api_key) else: self.device = pan.xapi.PanXapi(hostname=self.hostname, api_username=self.username, api_password=self.password) except ConnectionException as e: raise ConnectionException(str(e)) def _open_ssh(self): try: self.ssh_device = ConnectHandler(device_type='paloalto_panos', ip=self.hostname, username=self.username, password=self.password, **self.netmiko_optional_args) except ConnectionException as e: raise ConnectionException(str(e)) self.ssh_connection = True def close(self): self.device = None if self.ssh_connection: self.ssh_device.disconnect() self.ssh_connection = False self.ssh_device = None def _import_file(self, filename): if not self.api_key: key = self.device.keygen() else: key = self.api_key params = { 'type': 'import', 'category': 'configuration', 'key': key } path = os.path.basename(filename) mef = requests_toolbelt.MultipartEncoder( fields={ 'file': (path, open(filename, 'rb'), 'application/octet-stream') } ) requests.packages.urllib3.disable_warnings(InsecureRequestWarning) url = 'https://{0}/api/'.format(self.hostname) request = requests.post( url, verify=False, params=params, headers={'Content-Type': mef.content_type}, data=mef ) # if something goes wrong just raise an exception request.raise_for_status() response = xml.etree.ElementTree.fromstring(request.content) if response.attrib['status'] == 'error': return False else: return path def is_alive(self): if self.device: if self.ssh_connection: is_alive = self.ssh_device.remote_conn.transport.is_active() else: is_alive = True else: is_alive = False return {'is_alive': is_alive} def load_replace_candidate(self, filename=None, config=None): if config: raise ReplaceConfigException("This method requires a config file.") elif filename: if self.loaded is False: if self._save_backup() is False: raise ReplaceConfigException('Error while storing backup config') path = self._import_file(filename) if path is False: msg = "Error while trying to move the config file to the device." raise ReplaceConfigException(msg) # Let's load the config. cmd = '<load><config><from>{0}</from></config></load>'.format(path) self.device.op(cmd=cmd) if self.device.status == 'success': self.loaded = True else: raise ReplaceConfigException('Error while loading config from {0}').format(path) else: raise ReplaceConfigException("This method requires a config file.") def _get_file_content(self, filename): try: with open(filename, 'r') as f: content = f.read() except IOError: raise MergeConfigException('Error while opening {0}. Make sure ' 'filename is correct.'.format(filename)) return content def _send_merge_commands(self, config, file_config): """ Netmiko is being used to push set commands. """ if self.loaded is False: if self._save_backup() is False: raise MergeConfigException('Error while storing backup ' 'config.') if self.ssh_connection is False: self._open_ssh() if file_config: if isinstance(config, str): config = config.splitlines() else: if isinstance(config, str): config = str(config).split() self.ssh_device.send_config_set(config) self.loaded = True self.merge_config = True def _get_candidate(self): candidate_command = '<show><config><candidate></candidate></config></show>' self.device.op(cmd=candidate_command) candidate = str(self.device.xml_root()) return candidate def _get_running(self): self.device.show() running = str(self.device.xml_root()) return running def get_config(self, retrieve='all'): configs = {} running = py23_compat.text_type('') candidate = py23_compat.text_type('') startup = py23_compat.text_type('') if retrieve == 'all': running = py23_compat.text_type(self._get_running()) candidate = py23_compat.text_type(self._get_candidate()) elif retrieve == 'running': running = py23_compat.text_type(self._get_running()) elif retrieve == 'candidate': candidate = py23_compat.text_type(self._get_candidate()) configs['running'] = running configs['candidate'] = candidate configs['startup'] = startup return configs def load_merge_candidate(self, filename=None, config=None): if filename: file_config = True content = self._get_file_content(filename) config = content.splitlines() self._send_merge_commands(config, file_config) elif config: file_config = False self._send_merge_commands(config, file_config) else: raise MergeConfigException('You must provide either a file ' 'or a set-format string') def compare_config(self): """ Netmiko is being used to obtain config diffs because pan-python doesn't support the needed command. """ if self.ssh_connection is False: self._open_ssh() self.ssh_device.exit_config_mode() diff = self.ssh_device.send_command("show config diff") return diff.strip() def _save_backup(self): self.backup_file = 'config_{0}.xml'.format(str(datetime.now().date()).replace(' ', '_')) backup_command = '<save><config><to>{0}</to></config></save>'.format(self.backup_file) self.device.op(cmd=backup_command) if self.device.status == 'success': return True else: return False def commit_config(self): """ Netmiko is being used to commit the configuration because it takes a better care of results compared to pan-python. """ if self.loaded: if self.ssh_connection is False: self._open_ssh() try: self.ssh_device.commit() time.sleep(3) self.loaded = False self.changed = True except: # noqa if self.merge_config: raise MergeConfigException('Error while commiting config') else: raise ReplaceConfigException('Error while commiting config') else: raise ReplaceConfigException('No config loaded.') def discard_config(self): if self.loaded: discard_cmd = '<load><config><from>{0}</from></config></load>'.format(self.backup_file) self.device.op(cmd=discard_cmd) if self.device.status == 'success': self.loaded = False self.merge_config = False else: raise ReplaceConfigException("Error while loading backup config.") def rollback(self): """ Netmiko is being used to commit the rollback configuration because it takes a better care of results compared to pan-python. """ if self.changed: rollback_cmd = '<load><config><from>{0}</from></config></load>'.format(self.backup_file) self.device.op(cmd=rollback_cmd) time.sleep(5) if self.ssh_connection is False: self._open_ssh() try: self.ssh_device.commit() self.loaded = False self.changed = False self.merge_config = False except: # noqa ReplaceConfigException("Error while loading backup config") def _extract_interface_list(self): self.device.op(cmd='<show><interface>all</interface></show>') interfaces_xml = xmltodict.parse(self.device.xml_root()) interfaces_json = json.dumps(interfaces_xml['response']['result']) interfaces = json.loads(interfaces_json) interface_set = set() for entry in interfaces.values(): for entry_contents in entry.values(): if isinstance(entry_contents, dict): # If only 1 interface is listed, xmltodict returns a dictionary, otherwise # it returns a list of dictionaries. entry_contents = [entry_contents] for intf in entry_contents: interface_set.add(intf['name']) return list(interface_set) def get_facts(self): facts = {} try: self.device.op(cmd='<show><system><info></info></system></show>') system_info_xml = xmltodict.parse(self.device.xml_root()) system_info_json = json.dumps(system_info_xml['response']['result']['system']) system_info = json.loads(system_info_json) except AttributeError: system_info = {} if system_info: facts['hostname'] = system_info['hostname'] facts['vendor'] = py23_compat.text_type('Palo Alto Networks') facts['uptime'] = int(convert_uptime_string_seconds(system_info['uptime'])) facts['os_version'] = system_info['sw-version'] facts['serial_number'] = system_info['serial'] facts['model'] = system_info['model'] facts['fqdn'] = py23_compat.text_type('N/A') facts['interface_list'] = self._extract_interface_list() facts['interface_list'].sort() return facts def get_lldp_neighbors(self): """Return LLDP neighbors details.""" neighbors = {} cmd = '<show><lldp><neighbors>all</neighbors></lldp></show>' try: self.device.op(cmd=cmd) lldp_table_xml = xmltodict.parse(self.device.xml_root()) lldp_table_json = json.dumps(lldp_table_xml['response']['result']['entry']) lldp_table = json.loads(lldp_table_json) except AttributeError: lldp_table = [] for lldp_item in lldp_table: local_int = lldp_item['@name'] if local_int not in neighbors.keys(): neighbors[local_int] = [] try: lldp_neighs = lldp_item.get('neighbors').get('entry') except AttributeError: lldp_neighs = '' if isinstance(lldp_neighs, dict): lldp_neighs = [lldp_neighs] for neighbor in lldp_neighs: n = {} n['hostname'] = neighbor['system-name'] n['port'] = neighbor['port-id'] neighbors[local_int].append(n) return neighbors def get_route_to(self, destination='', protocol=''): """Return route details to a specific destination, learned from a certain protocol.""" # Note, it should be possible to query the FIB: # "<show><routing><fib></fib></routing></show>" # To add informations to this getter routes = {} if destination: destination = "<destination>{0}</destination>".format(destination) if protocol: protocol = "<type>{0}</type>".format(protocol) cmd = "<show><routing><route>{0}{1}</route></routing></show>".format(protocol, destination) try: self.device.op(cmd=cmd) routes_table_xml = xmltodict.parse(self.device.xml_root()) routes_table_json = json.dumps(routes_table_xml['response']['result']['entry']) routes_table = json.loads(routes_table_json) except (AttributeError, KeyError): routes_table = [] if isinstance(routes_table, dict): routes_table = [routes_table] for route in routes_table: d = { 'current_active': False, 'last_active': False, 'age': -1, 'next_hop': u'', 'protocol': u'', 'outgoing_interface': u'', 'preference': -1, 'inactive_reason': u'', 'routing_table': u'default', 'selected_next_hop': False, 'protocol_attributes': {} } destination = route['destination'] flags = route['flags'] if 'A' in flags: d['current_active'] = True else: d['current_active'] = False if 'C' in flags: d['protocol'] = "connect" if 'S' in flags: d['protocol'] = "static" if 'R' in flags: d['protocol'] = "rip" if 'R' in flags: d['protocol'] = "rip" if 'O' in flags: d['protocol'] = "ospf" if 'B' in flags: d['protocol'] = "bgp" if 'H' in flags: d['protocol'] = "host" if route['age'] is not None: d['age'] = int(route['age']) if route['nexthop'] is not None: d['next_hop'] = route['nexthop'] if route['interface'] is not None: d['outgoing_interface'] = route['interface'] if route['metric'] is not None: d['preference'] = int(route['metric']) if route['virtual-router'] is not None: d['routing_table'] = route['virtual-router'] if destination not in routes.keys(): routes[destination] = [] routes[destination].append(d) return routes def get_interfaces(self): LOOPBACK_SUBIF_DEFAULTS = { 'is_up': True, 'is_enabled': True, 'speed': 0, 'last_flapped': -1.0, 'mac_address': '', 'description': 'N/A' } interface_dict = {} interface_list = self._extract_interface_list() for intf in interface_list: interface = {} cmd = "<show><interface>{0}</interface></show>".format(intf) try: self.device.op(cmd=cmd) interface_info_xml = xmltodict.parse(self.device.xml_root()) interface_info_json = json.dumps(interface_info_xml['response']['result']['hw']) interface_info = json.loads(interface_info_json) except KeyError as err: if 'loopback.' in intf and 'hw' in str(err): # loopback sub-ifs don't return a 'hw' key interface_dict[intf] = LOOPBACK_SUBIF_DEFAULTS continue raise interface['is_up'] = interface_info.get('state') == 'up' conf_state = interface_info.get('state_c') if conf_state == 'down': interface['is_enabled'] = False elif conf_state in ('up', 'auto'): interface['is_enabled'] = True else: msg = 'Unknown configured state {} for interface {}'.format(conf_state, intf) raise RuntimeError(msg) interface['last_flapped'] = -1.0 interface['speed'] = interface_info.get('speed') # Loopback and down interfaces if interface['speed'] in ('[n/a]', 'unknown'): interface['speed'] = 0 else: interface['speed'] = int(interface['speed']) interface['mac_address'] = standardize_mac(interface_info.get('mac')) interface['description'] = py23_compat.text_type('N/A') interface_dict[intf] = interface return interface_dict def get_interfaces_ip(self): '''Return IP interface data.''' def extract_ip_info(parsed_intf_dict): ''' IPv4: - Primary IP is in the '<ip>' tag. If no v4 is configured the return value is 'N/A'. - Secondary IP's are in '<addr>'. If no secondaries, this field is not returned by the xmltodict.parse() method. IPv6: - All addresses are returned in '<addr6>'. If no v6 configured, this is not returned either by xmltodict.parse(). Example of XML response for an intf with multiple IPv4 and IPv6 addresses: <response status="success"> <result> <ifnet> <entry> <name>ethernet1/5</name> <zone/> <fwd>N/A</fwd> <vsys>1</vsys> <dyn-addr/> <addr6> <member>fe80::d61d:71ff:fed8:fe14/64</member> <member>2001::1234/120</member> </addr6> <tag>0</tag> <ip>169.254.0.1/30</ip> <id>20</id> <addr> <member>1.1.1.1/28</member> </addr> </entry> {...} </ifnet> <hw> {...} </hw> </result> </response> ''' intf = parsed_intf_dict['name'] _ip_info = {intf: {}} v4_ip = parsed_intf_dict.get('ip') secondary_v4_ip = parsed_intf_dict.get('addr') v6_ip = parsed_intf_dict.get('addr6') if v4_ip != 'N/A': address, pref = v4_ip.split('/') _ip_info[intf].setdefault('ipv4', {})[address] = {'prefix_length': int(pref)} if secondary_v4_ip is not None: members = secondary_v4_ip['member'] if not isinstance(members, list): # If only 1 secondary IP is present, xmltodict converts field to a string, else # it converts it to a list of strings. members = [members] for address in members: address, pref = address.split('/') _ip_info[intf].setdefault('ipv4', {})[address] = {'prefix_length': int(pref)} if v6_ip is not None: members = v6_ip['member'] if not isinstance(members, list): # Same "1 vs many -> string vs list of strings" comment. members = [members] for address in members: address, pref = address.split('/') _ip_info[intf].setdefault('ipv6', {})[address] = {'prefix_length': int(pref)} # Reset dictionary if no addresses were found. if _ip_info == {intf: {}}: _ip_info = {} return _ip_info ip_interfaces = {} cmd = "<show><interface>all</interface></show>" self.device.op(cmd=cmd) interface_info_xml = xmltodict.parse(self.device.xml_root()) interface_info_json = json.dumps( interface_info_xml['response']['result']['ifnet']['entry'] ) interface_info = json.loads(interface_info_json) if isinstance(interface_info, dict): # Same "1 vs many -> dict vs list of dicts" comment. interface_info = [interface_info] for interface_dict in interface_info: ip_info = extract_ip_info(interface_dict) if ip_info: ip_interfaces.update(ip_info) return ip_interfaces
f = open('vars.yml', 'r') vars = load(f.read(), Loader=FullLoader) f.close() print("generating and loading configuration") for item in vars: host_vars = vars[item] device = host_vars['netmiko'] dev = ConnectHandler(**device) f = open(host_vars['netmiko']['host'] + '.txt', 'w') f.write(junos_template.render(host_vars)) f.close() load = dev.send_config_from_file(config_file=host_vars['netmiko']['host'] + '.txt') commit = dev.commit(confirm=False, check=False, comment='commited from netmiko') dev.disconnect() print("waiting 15 seconds before validating BGP sessions state") time.sleep(15) for item in vars: host_vars = vars[item] device = host_vars['netmiko'] dev = ConnectHandler(**device) command = "show bgp neighbor" command_output = dev.send_command(command + "| display json") data_json = json.loads(command_output) print("Device " + host_vars['netmiko']['host']) for neighbor in data_json["bgp-information"][0]["bgp-peer"]: print("session with " + neighbor["peer-address"][0]['data'] + " is " +
class Connection(object): '''Netmiko Based Connection Sample implementation of NetmikoConnection connection to devices allowing devices to ssh or telnet to end routers ''' def __init__(self, protocol, ip, port, username, enable_password, tacacs_password, line_passwd, os, *args, **kwargs): # instantiate device information self.protocol = protocol self.ip = ip self.port = port self.username = username self.enable_password = enable_password self.tacacs_password = tacacs_password self.line_passwd = line_passwd self.os = os self._is_connected = False def connect(self): #self.net_connect = ConnectHandler(device_type='a10', ip='192.168.100.96', username='******', password='******',secret='admin') connect_params = self._connect_params_dict() try: self.net_connect = ConnectHandler(**connect_params) except ValueError: extends = 'netconnect.extends.' + str( self.os) + '.' + 'ConnectHandler' self.net_connect = utils.import_object(extends, **connect_params) self._is_connected = True except Exception as ex: log.info(ex) self._is_connected = False else: self._is_connected = True @property def connected(self): return self._is_connected def execute(self, command, timeout=500): if not self._is_connected: log.error("Error: device not connected") return False if isinstance(command, str): ## if string is given, transfer to list command = command.splitlines() if self.os not in [ 'linux', 'nso' ]: ## some devices like linux don't need enable operation self.net_connect.enable() expect_string = None if self.os in ['linux']: ## add Linux prompt pattern expect_string = r'(.*?([>\$~%]|[^#\s]#))\s?$' output = "" for cmd in command: log.debug('To be executed command: %s', cmd) result = self.net_connect.send_command_expect( cmd, expect_string=expect_string, max_loops=int(timeout)) output = output + result return output def send(self, command): result = self.net_connect.send_command_timing(command) return result def configure(self, cmd): if not self._is_connected: log.error("Error: device not connected") return False log.debug('To be configured command: %s', cmd) result = self.net_connect.send_config_set(cmd) if self.os in ['cisco_xr', 'nso' ]: ## some devices like cisco_xr need commit operation self.net_connect.commit() self.net_connect.exit_config_mode() return result def disconnect(self): self.net_connect.disconnect() self._is_connected = False def cli_style(self, style): if self.os != 'nso': log.error("Error: Only nso supported cli") return False if style == 'cisco' and self.current_cli_style != 'cisco': self.net_connect.send_command_timing("switch cli") elif style == 'juniper' and self.current_cli_style != 'juniper': self.net_connect.send_command_timing("switch cli") else: log.error("Please input right cli style!") return self.current_cli_style @property def current_cli_style(self): if self.os != 'nso': log.error("Error: Only nso supported cli") return False prompt = self.net_connect.find_prompt() if prompt.endswith('#'): self._current_cli_style = 'cisco' elif prompt.endswith('>'): self._current_cli_style = 'juniper' else: self._current_cli_style = 'unknow' log.debug('Current cli style: %s', self._current_cli_style) return self._current_cli_style def _connect_params_dict(self): """Generate dictionary of Paramiko connection parameters.""" conn_dict = { 'device_type': self.os, 'ip': self.ip, 'port': self.port, 'username': self.username, 'password': self.tacacs_password, 'secret': self.enable_password } log.debug('The connection info dict: %s', conn_dict) return conn_dict
class PANOSDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60, optional_args=None): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.loaded = False self.changed = False self.device = None self.ssh_device = None self.ssh_connection = False self.merge_config = False if optional_args is None: optional_args = {} netmiko_argument_map = { 'port': None, 'verbose': False, 'use_keys': False, 'key_file': None, 'ssh_strict': False, 'system_host_keys': False, 'alt_host_keys': False, 'alt_key_file': '', 'ssh_config_file': None, } fields = netmiko_version.split('.') fields = [int(x) for x in fields] maj_ver, min_ver, bug_fix = fields if maj_ver >= 2: netmiko_argument_map['allow_agent'] = False elif maj_ver == 1 and min_ver >= 1: netmiko_argument_map['allow_agent'] = False # Build dict of any optional Netmiko args self.netmiko_optional_args = {} for k, v in netmiko_argument_map.items(): try: self.netmiko_optional_args[k] = optional_args[k] except KeyError: pass self.api_key = optional_args.get('api_key', '') def open(self): try: if self.api_key: self.device = pan.xapi.PanXapi(hostname=self.hostname, api_key=self.api_key) else: self.device = pan.xapi.PanXapi(hostname=self.hostname, api_username=self.username, api_password=self.password) except ConnectionException as e: raise ConnectionException(str(e)) def _open_ssh(self): try: self.ssh_device = ConnectHandler(device_type='paloalto_panos', ip=self.hostname, username=self.username, password=self.password, **self.netmiko_optional_args) except ConnectionException as e: raise ConnectionException(str(e)) self.ssh_connection = True def close(self): self.device = None if self.ssh_connection: self.ssh_device.disconnect() self.ssh_connection = False self.ssh_device = None def _import_file(self, filename): if not self.api_key: key = self.device.keygen() else: key = self.api_key params = { 'type': 'import', 'category': 'configuration', 'key': key } path = os.path.basename(filename) mef = requests_toolbelt.MultipartEncoder( fields={ 'file': (path, open(filename, 'rb'), 'application/octet-stream') } ) requests.packages.urllib3.disable_warnings(InsecureRequestWarning) url = 'https://{0}/api/'.format(self.hostname) request = requests.post( url, verify=False, params=params, headers={'Content-Type': mef.content_type}, data=mef ) # if something goes wrong just raise an exception request.raise_for_status() response = xml.etree.ElementTree.fromstring(request.content) if response.attrib['status'] == 'error': return False else: return path def is_alive(self): if self.device: if self.ssh_connection: is_alive = self.ssh_device.remote_conn.transport.is_active() else: is_alive = True else: is_alive = False return {'is_alive': is_alive} def load_replace_candidate(self, filename=None, config=None): if config: raise ReplaceConfigException("This method requires a config file.") elif filename: if self.loaded is False: if self._save_backup() is False: raise ReplaceConfigException('Error while storing backup config') path = self._import_file(filename) if path is False: msg = "Error while trying to move the config file to the device." raise ReplaceConfigException(msg) # Let's load the config. cmd = '<load><config><from>{0}</from></config></load>'.format(path) self.device.op(cmd=cmd) if self.device.status == 'success': self.loaded = True else: raise ReplaceConfigException('Error while loading config from {0}').format(path) else: raise ReplaceConfigException("This method requires a config file.") def _get_file_content(self, filename): try: with open(filename, 'r') as f: content = f.read() except IOError: raise MergeConfigException('Error while opening {0}. Make sure ' 'filename is correct.'.format(filename)) return content def _send_merge_commands(self, config, file_config): """ Netmiko is being used to push set commands. """ if self.loaded is False: if self._save_backup() is False: raise MergeConfigException('Error while storing backup ' 'config.') if self.ssh_connection is False: self._open_ssh() if file_config: if isinstance(config, str): config = config.splitlines() else: if isinstance(config, str): config = str(config).split() self.ssh_device.send_config_set(config) self.loaded = True self.merge_config = True def _get_candidate(self): candidate_command = '<show><config><candidate></candidate></config></show>' self.device.op(cmd=candidate_command) candidate = str(self.device.xml_root()) return candidate def _get_running(self): self.device.show() running = str(self.device.xml_root()) return running def get_config(self, retrieve='all'): configs = {} running = py23_compat.text_type('') candidate = py23_compat.text_type('') startup = py23_compat.text_type('') if retrieve == 'all': running = py23_compat.text_type(self._get_running()) candidate = py23_compat.text_type(self._get_candidate()) elif retrieve == 'running': running = py23_compat.text_type(self._get_running()) elif retrieve == 'candidate': candidate = py23_compat.text_type(self._get_candidate()) configs['running'] = running configs['candidate'] = candidate configs['startup'] = startup return configs def load_merge_candidate(self, filename=None, config=None): if filename: file_config = True content = self._get_file_content(filename) config = content.splitlines() self._send_merge_commands(config, file_config) elif config: file_config = False self._send_merge_commands(config, file_config) else: raise MergeConfigException('You must provide either a file ' 'or a set-format string') def compare_config(self): """ Netmiko is being used to obtain config diffs because pan-python doesn't support the needed command. """ if self.ssh_connection is False: self._open_ssh() self.ssh_device.exit_config_mode() diff = self.ssh_device.send_command("show config diff") return diff.strip() def _save_backup(self): self.backup_file = 'config_{0}.xml'.format(str(datetime.now().date()).replace(' ', '_')) backup_command = '<save><config><to>{0}</to></config></save>'.format(self.backup_file) self.device.op(cmd=backup_command) if self.device.status == 'success': return True else: return False def commit_config(self): """ Netmiko is being used to commit the configuration because it takes a better care of results compared to pan-python. """ if self.loaded: if self.ssh_connection is False: self._open_ssh() try: self.ssh_device.commit() time.sleep(3) self.loaded = False self.changed = True except: if self.merge_config: raise MergeConfigException('Error while commiting config') else: raise ReplaceConfigException('Error while commiting config') else: raise ReplaceConfigException('No config loaded.') def discard_config(self): if self.loaded: discard_cmd = '<load><config><from>{0}</from></config></load>'.format(self.backup_file) self.device.op(cmd=discard_cmd) if self.device.status == 'success': self.loaded = False self.merge_config = False else: raise ReplaceConfigException("Error while loading backup config.") def rollback(self): """ Netmiko is being used to commit the rollback configuration because it takes a better care of results compared to pan-python. """ if self.changed: rollback_cmd = '<load><config><from>{0}</from></config></load>'.format(self.backup_file) self.device.op(cmd=rollback_cmd) time.sleep(5) if self.ssh_connection is False: self._open_ssh() try: self.ssh_device.commit() self.loaded = False self.changed = False self.merge_config = False except: ReplaceConfigException("Error while loading backup config") def get_facts(self): facts = {} try: self.device.op(cmd='<show><system><info></info></system></show>') system_info_xml = xmltodict.parse(self.device.xml_root()) system_info_json = json.dumps(system_info_xml['response']['result']['system']) system_info = json.loads(system_info_json) except AttributeError: system_info = {} try: self.device.op(cmd='<show><interface>all</interface></show>') interfaces_xml = xmltodict.parse(self.device.xml_root()) interfaces_json = json.dumps(interfaces_xml['response']['result']) interfaces = json.loads(interfaces_json) except AttributeError: interfaces = {} if system_info: facts['hostname'] = system_info['hostname'] facts['vendor'] = py23_compat.text_type('Palo Alto Networks') facts['uptime'] = int(convert_uptime_string_seconds(system_info['uptime'])) facts['os_version'] = system_info['sw-version'] facts['serial_number'] = system_info['serial'] facts['model'] = system_info['model'] facts['fqdn'] = py23_compat.text_type('N/A') facts['interface_list'] = [] for element in interfaces: for entry in interfaces[element]: for intf in interfaces[element][entry]: if intf['name'] not in facts['interface_list']: facts['interface_list'].append(intf['name']) facts['interface_list'].sort() return facts def get_lldp_neighbors(self): """Return LLDP neighbors details.""" neighbors = {} cmd = '<show><lldp><neighbors>all</neighbors></lldp></show>' try: self.device.op(cmd=cmd) lldp_table_xml = xmltodict.parse(self.device.xml_root()) lldp_table_json = json.dumps(lldp_table_xml['response']['result']['entry']) lldp_table = json.loads(lldp_table_json) except AttributeError: lldp_table = [] for lldp_item in lldp_table: local_int = lldp_item['@name'] if local_int not in neighbors.keys(): neighbors[local_int] = [] lldp_neighs = lldp_item['neighbors']['entry'] if isinstance(lldp_neighs, dict): lldp_neighs = [lldp_neighs] for neighbor in lldp_neighs: n = {} n['hostname'] = neighbor['system-name'] n['port'] = neighbor['port-id'] neighbors[local_int].append(n) return neighbors def get_route_to(self, destination='', protocol=''): """Return route details to a specific destination, learned from a certain protocol.""" # Note, it should be possible to query the FIB: # "<show><routing><fib></fib></routing></show>" # To add informations to this getter routes = {} if destination: destination = "<destination>{0}</destination>".format(destination) if protocol: protocol = "<type>{0}</type>".format(protocol) cmd = "<show><routing><route>{0}{1}</route></routing></show>".format(protocol, destination) try: self.device.op(cmd=cmd) routes_table_xml = xmltodict.parse(self.device.xml_root()) routes_table_json = json.dumps(routes_table_xml['response']['result']['entry']) routes_table = json.loads(routes_table_json) except AttributeError: routes_table = [] if isinstance(routes_table, dict): routes_table = [routes_table] for route in routes_table: d = { 'current_active': False, 'last_active': False, 'age': -1, 'next_hop': u'', 'protocol': u'', 'outgoing_interface': u'', 'preference': -1, 'inactive_reason': u'', 'routing_table': u'default', 'selected_next_hop': False, 'protocol_attributes': {} } destination = route['destination'] flags = route['flags'] if 'A' in flags: d['current_active'] = True else: d['current_active'] = False if 'C' in flags: d['protocol'] = "connect" if 'S' in flags: d['protocol'] = "static" if 'R' in flags: d['protocol'] = "rip" if 'R' in flags: d['protocol'] = "rip" if 'O' in flags: d['protocol'] = "ospf" if 'B' in flags: d['protocol'] = "bgp" if 'H' in flags: d['protocol'] = "host" if route['age'] is not None: d['age'] = int(route['age']) if route['nexthop'] is not None: d['next_hop'] = route['nexthop'] if route['interface'] is not None: d['outgoing_interface'] = route['interface'] if route['metric'] is not None: d['preference'] = int(route['metric']) if route['virtual-router'] is not None: d['routing_table'] = route['virtual-router'] if destination not in routes.keys(): routes[destination] = [] routes[destination].append(d) return routes def get_interfaces(self): interface_dict = {} interface_list = self.get_facts()['interface_list'] for intf in interface_list: interface = {} cmd = "<show><interface>{0}</interface></show>".format(intf) try: self.device.op(cmd=cmd) interface_info_xml = xmltodict.parse(self.device.xml_root()) interface_info_json = json.dumps(interface_info_xml['response']['result']['hw']) interface_info = json.loads(interface_info_json) except AttributeError: interface_info = {} name = interface_info.get('name') state = interface_info.get('state') if state == 'up': interface['is_up'] = True interface['is_enabled'] = True else: interface['is_up'] = False interface['is_enabled'] = False interface['last_flapped'] = -1.0 interface['speed'] = interface_info.get('speed') # Quick fix for loopback interfaces if interface['speed'] == '[n/a]': interface['speed'] = 0 else: interface['speed'] = int(interface['speed']) interface['mac_address'] = interface_info.get('mac') interface['description'] = py23_compat.text_type('N/A') interface_dict[name] = interface return interface_dict