def transfer_file(net_connect, file): net_connect.config_mode() net_connect.send_command('ip scp server enable') scp_conn = SCPConn(net_connect) s_file = file d_file = file scp_conn.scp_transfer_file(s_file, d_file)
def __init__(self, *args, **kwargs): super(SimpleSwitch13, self).__init__(*args, **kwargs) self.mac_to_port = {} self.ip_to_port = {} #We are creating a netmiko connection to the backup ryu server. #This will be used to transfer the state configuration file #between servers so that same state is maintained across both #ryu controller applications in case one goes down and comes up #again. ryu_vm = { "device_type": "linux", "ip": "10.10.10.40", "username": "******", "password": "******", "secret": "ryu", } net_connect = ConnectHandler(**ryu_vm) net_connect.enable() self.scp_conn = SCPConn(net_connect) #Check if the state configuration file exists and takes the #information into variable so that the dictionary mapping does not #have to be learned again if os.path.exists("/home/ryu/state.conf"): print("State configuration file exists. Importing from /home/ryu/state.conf...") with open("/home/ryu/state.conf","r") as state_file: lines = state_file.readlines() if lines: self.ip_to_port = ast.literal_eval(lines[0][:-1]) self.mac_to_port = ast.literal_eval(lines[1][:-1]) print(self.ip_to_port) print(self.mac_to_port)
def download_config(self): _f = self.f5temp_file + self.f5temp_suffix with ConnectHandler(**self.conn_dict) as remote_conn: _out = remote_conn.send_command(self.cli) syslog.syslog('@{} {}'.format(self.conn_dict['ip'], _out)) if self.cli_ans_chk(_out, _f + self._keyword): scp_conn = SCPConn(remote_conn) scp_conn.scp_get_file(_f, self.filename) syslog.syslog('scp ucs file from {} to {}'.format( self.conn_dict['ip'], self.filename))
def open(self): self.device = ConnectHandler(device_type='vyos', host=self.hostname, username=self.username, password=self.password, **self.netmiko_optional_args) try: self._scp_client = SCPConn(self.device) except: raise ConnectionException("Failed to open connection ")
def main(): ''' Ansible module to transfer files to Cisco IOS devices. ''' module = AnsibleModule( argument_spec=dict( host=dict(required=True), port=dict(default=22, required=False), username=dict(required=True), password=dict(required=True), source_file=dict(required=True), dest_file=dict(required=True), dest_file_system=dict(required=False), ) ) net_device = { 'device_type': 'cisco_ios', 'ip': module.params['host'], 'username': module.params['username'], 'password': module.params['password'], 'port': int(module.params['port']), 'verbose': False, } ssh_conn = ConnectHandler(**net_device) output = ssh_conn.send_command("show flash: | inc cisco_logging") scp_conn = SCPConn(ssh_conn) source_file = module.params['source_file'] source_md5 = file_md5(source_file) dest_file = module.params['dest_file'] scp_conn.scp_transfer_file(source_file, dest_file) scp_conn.close() output2 = ssh_conn.send_command("show flash: | inc cisco_logging") remote_md5_cmd = "verify /md5 {0}".format(dest_file) dest_md5 = ssh_conn.send_command(remote_md5_cmd) dest_md5 = process_cisco_md5(dest_md5) if source_md5 != dest_md5: module.fail_json(msg="File transferred to Cisco device, but MD5 does not match" \ " source file") module.exit_json(msg="Testing...", changed=True, output=output, source_file=source_file, output2=output2, source_md5=source_md5, dest_md5=dest_md5)
def sendFileToMachine(host: machine.Machine, source_file, dest_file): net_device = { 'device_type': 'linux', 'ip': host.ip, 'username': host.username, 'password': host.password, } try: ssh_conn = ConnectHandler(**net_device) scp_conn = SCPConn(ssh_conn) putFileState = scp_conn.scp_put_file(source_file, dest_file) scp_conn.close() ssh_conn.disconnect() host.status = 2 # Passed return True # succeeded sending the file to machine except: print(f"Failed connect to {host.ip}") host.status = 0 # Failed return False # Filed sending the file to machine
def main(): ''' SCP transfer cisco_logging.txt to network device Use ssh_conn as ssh channel into network device scp_conn must be closed after file transfer ''' ssh_conn = ConnectHandler(**cisco_881) scp_conn = SCPConn(ssh_conn) s_file = 'cisco_logging.txt' d_file = 'cisco_logging.txt' print "\n\n" scp_conn.scp_transfer_file(s_file, d_file) scp_conn.close() output = ssh_conn.send_command("show flash: | inc cisco_logging") print ">> " + output + '\n' # Disable file copy confirmation output = ssh_conn.send_config_set(["file prompt quiet"]) # Execute config merge print "Performing config merge\n" output = ssh_conn.send_command("copy flash:cisco_logging.txt running-config") # Verify change print "Verifying logging buffer change" output = ssh_conn.send_command("show run | inc logging buffer") print ">> " + output + '\n' # Restore copy confirmation output = ssh_conn.send_config_set(["file prompt alert"])
def scp_put_file(self, source_file=None, dest_file=None): """Put file using SCP.""" try: scp = SCPConn(ssh_conn=self) scp.scp_put_file(source_file=source_file, dest_file=dest_file) except Exception: raise finally: scp.close()
def load_file(self, file, dst_file=None): if not dst_file: dst_file = file scp_status = self.ssh.send_command( 'show running-config | i "ip scp server enable"') if not scp_status: self.enable_scp() scp = SCPConn(self.ssh) scp.scp_transfer_file(file, dst_file) scp.close() if not scp_status: self.disable_scp()
def main(self): ssh_conn = ConnectHandler( device_type='cisco_ios', ip = self.ip, username = self.username, password = self.password ) config_commands = self.cmdlist output = ssh_conn.send_config_set(config_commands) print(output) for f in myfile: s_file = f d_file = f scp_conn = SCPConn(ssh_conn) scp_conn.scp_transfer_file(s_file, d_file) scp_conn.close()
def main(self): ssh_conn = ConnectHandler(device_type='cisco_ios', ip=self.ip, username=self.username, password=self.password) static = os.chdir( '/Users/shaun/dev/netmiko_django/netmiko_django/static/') myfile = os.listdir(static) for f in myfile: s_file = f d_file = f scp_conn = SCPConn(ssh_conn) scp_conn.scp_transfer_file(s_file, d_file) config_commands = self.cmdlist output = ssh_conn.send_config_set(config_commands) print(output) return output scp_conn.close()
def main(self): ssh_conn = ConnectHandler(device_type='cisco_asa', ip=self.ip, username=self.username, password=self.password) static = os.chdir( 'C:\\Users\corcoras\\Desktop\\FY14 INSTALLS\\PythonMotors\\netmiko_django\\netmiko_django\\static' ) myfile = os.listdir(static) for f in myfile: s_file = f d_file = f scp_conn = SCPConn(ssh_conn) scp_conn.scp_transfer_file(s_file, d_file) config_commands = self.cmdlist output = ssh_conn.send_config_set(config_commands) print(output) return output scp_conn.close()
def main(self): ssh_conn = ConnectHandler(device_type='cisco_ios', ip=self.ip, username=self.username, password=self.password) static = os.chdir('C:\\Users\\corcoras\\netmiko_django\\hold') print(static) myfile = os.listdir(static) print(myfile) for f in myfile: if f == 'desktop.ini': pass else: print(f) s_file = f d_file = f scp_conn = SCPConn(ssh_conn) scp_conn.scp_transfer_file(s_file, d_file) config_commands = self.cmdlist output = ssh_conn.send_config_set(config_commands) print(output) return output scp_conn.close()
def scp_file(self, source_file, dest_file): try: scp_transfer = SCPConn(self.device) scp_transfer.scp_put_file(source_file, dest_file) except: raise ConnectionException("SCP transfer to remote device failed")
def file_transfer(self): scp_conn = SCPConn(self.vyos) s_file = "/openvpn-1.key" d_file = "/config/auth/openvpn-1.key" scp_conn.scp_transfer_file(s_file, d_file)
'ip': '192.168.1.1', 'username': '******', 'password': '******', } # open file containing commands with open('commands.txt') as f: commands_list = f.read().splitlines() # Establish ssh session to device and send commands net_connect = ConnectHandler(**netscaler_device) net_connect.send_config_set(commands_list, delay_factor=4) # open secure copy protocol to transfer backup file to server ssh_conn = ConnectHandler(**netscaler_device) scp_conn = SCPConn(ssh_conn) s_file = '/var/ns_sys_backup/backupfile.tgz' d_file = '/usr/backups/backupfile.tgz' scp_conn.scp_get_file(s_file, d_file) # Close secure copy protocol session scp_conn.close() # Close ssh session net_connect.disconnect() timestr = time.strftime("%Y%m%d-%H%M%S") # Rename backup file to contain time and date stamp
class SimpleSwitch13(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self, *args, **kwargs): super(SimpleSwitch13, self).__init__(*args, **kwargs) self.mac_to_port = {} self.ip_to_port = {} #We are creating a netmiko connection to the backup ryu server. #This will be used to transfer the state configuration file #between servers so that same state is maintained across both #ryu controller applications in case one goes down and comes up #again. ryu_vm = { "device_type": "linux", "ip": "10.10.10.40", "username": "******", "password": "******", "secret": "ryu", } net_connect = ConnectHandler(**ryu_vm) net_connect.enable() self.scp_conn = SCPConn(net_connect) #Check if the state configuration file exists and takes the #information into variable so that the dictionary mapping does not #have to be learned again if os.path.exists("/home/ryu/state.conf"): print("State configuration file exists. Importing from /home/ryu/state.conf...") with open("/home/ryu/state.conf","r") as state_file: lines = state_file.readlines() if lines: self.ip_to_port = ast.literal_eval(lines[0][:-1]) self.mac_to_port = ast.literal_eval(lines[1][:-1]) print(self.ip_to_port) print(self.mac_to_port) @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser # install table-miss flow entry # # We specify NO BUFFER to max_len of the output action due to # OVS bug. At this moment, if we specify a lesser number, e.g., # 128, OVS will send Packet-In with invalid buffer_id and # truncated packet data. In that case, we cannot output packets # correctly. The bug has been fixed in OVS v2.1.0. match = parser.OFPMatch() actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] self.add_flow(datapath, 0, match, actions) def add_flow(self, datapath, priority, match, actions, buffer_id=None, idle_timeout=None): ofproto = datapath.ofproto parser = datapath.ofproto_parser inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] if idle_timeout: if buffer_id: mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, priority=priority, match=match, idle_timeout=idle_timeout, instructions=inst) else: mod = parser.OFPFlowMod(datapath=datapath, priority=priority, idle_timeout=idle_timeout, match=match, instructions=inst) datapath.send_msg(mod) else: if buffer_id: mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, priority=priority, match=match, instructions=inst) else: mod = parser.OFPFlowMod(datapath=datapath, priority=priority, match=match, instructions=inst) datapath.send_msg(mod) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.ip_to_port.setdefault(dpid,{}) self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD #Modification in order to add flows based on IP addresses instead #of MAC addresses. if pkt_ipv4: ip_src = pkt_ipv4.src ip_dst = pkt_ipv4.dst self.ip_to_port[dpid][ip_src] = in_port #Prints current state print(self.ip_to_port) print(self.mac_to_port) #Write the current state (dictionary) to a file state.conf #and transfer the file to the backup server to maintain synchronization with open("/home/ryu/state.conf","w+") as state_file: state_file.write(str(self.ip_to_port)+"\n") state_file.write(str(self.mac_to_port)+"\n") self.scp_conn.scp_transfer_file("/home/ryu/state.conf","state.conf") if ip_dst in self.ip_to_port[dpid]: out_port = self.ip_to_port[dpid][ip_dst] actions = [parser.OFPActionOutput(out_port)] #Allowing flows to timeout after 5 seconds to account for topology changes. idle_timeout = 5 if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_type=2048 ,ipv4_dst=ip_dst, ipv4_src=ip_src) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id, idle_timeout) return else: self.add_flow(datapath, 1, match, actions, idle_timeout) actions = [parser.OFPActionOutput(out_port)] data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _transfer_file_scp(self, source_file, destination_file): scp_conn = SCPConn(self.device) scp_conn.scp_transfer_file(source_file,destination_file)
def getSerial(node=None, username=None, password=None): # print(f'what is the value at intf{intf} and the type is {type(intf)}') try: # regx = ['[G,P,E,F}[A-Za-z]{2,3}[0-9]{1,3}.[0-9]{1,2}[\/][0-9]{1,2}', '[G,P,E,F}[A-Za-z]{2,3}[0-9]{1,3}.[0-9]{1,2}','[G,P,E,F}[A-Za-z]{2,3}[0-9]{1,3}'] # regx = '[A-Za-z]{2,3}[0-9]{1,3}.[0-9]{1,2}[\/][0-9]{1,2}' eachLine = [] # int_for_device = [] hostname = str(node) device = { 'device_type': 'cisco_ios', #'autodetect', 'ip': hostname, 'username': username, 'password': password, 'verbose': False } ssh_session = netmiko.ConnectHandler(**device) scp_conn = SCPConn(ssh_session) #add commands you wish run here. # cmdList = [ # 'show ver | in Proc', # 'show int des | in up'+' ', # ] cmdList = ['show ver | in Proc', 'show int status | in connected'] for cmd in cmdList: print(hostname + ': ' + cmd) output = ssh_session.send_command(cmd) # if output == '': # cmdList = [ # 'show ver | in Proc', # 'show int status | in connected' # ] # for cmd in cmdList: # print(hostname + ': ' + cmd) # outputToSend = ssh_session.send_command(cmd) # eachLine = whenConnected(outputToSend) # else: eachLine = whenConnected(output) for intf in eachLine: if intf == '' or intf == 'Processor': break else: intfCmd = [ 'show int ' + intf + ' | in rate|errors|Desc', ] for cmd in intfCmd: # print(hostname + ': ' + cmd) print(cmd) output = ssh_session.send_command(cmd) for linedesc in output.splitlines(): print(linedesc) print('') #close the connections scp_conn.close() ssh_session.disconnect() # print(line) except IOError as eWriteFile: print(f'here is the exception : {eWriteFile}') scp_conn.close() ssh_session.disconnect()
def scpconnect(self): self.connect() self.scp_connect = SCPConn(self.net_connect)
class VyOSDriver(NetworkDriver): _MINUTE_SECONDS = 60 _HOUR_SECONDS = 60 * _MINUTE_SECONDS _DAY_SECONDS = 24 * _HOUR_SECONDS _WEEK_SECONDS = 7 * _DAY_SECONDS _YEAR_SECONDS = 365 * _DAY_SECONDS _DEST_FILENAME = "/var/tmp/candidate_running.conf" _BACKUP_FILENAME = "/var/tmp/backup_running.conf" _BOOT_FILENAME = "/config/config.boot" def __init__(self, hostname, username, password, timeout=60, optional_args=None): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = None self._scp_client = None self._new_config = None self._old_config = None self._ssh_usekeys = False # Netmiko possible arguments netmiko_argument_map = { 'port': None, 'secret': '', 'verbose': False, 'global_delay_factor': 1, '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 = {} if optional_args is not None: for k, v in netmiko_argument_map.items(): try: self.netmiko_optional_args[k] = optional_args[k] except KeyError: pass self.global_delay_factor = optional_args.get( 'global_delay_factor', 1) self.port = optional_args.get('port', 22) def open(self): self.device = ConnectHandler(device_type='vyos', host=self.hostname, username=self.username, password=self.password, **self.netmiko_optional_args) try: self._scp_client = SCPConn(self.device) except: raise ConnectionException("Failed to open connection ") def close(self): self.device.disconnect() def is_alive(self): """Returns a flag with the state of the SSH connection.""" return {'is_alive': self.device.remote_conn.transport.is_active()} def load_replace_candidate(self, filename=None, config=None): """ Only configuration files are supported with load_replace_candidate. It must be a full config file like /config/config.boot Due to the OS nature, we do not support a replace using a configuration string. """ if filename is not None: if os.path.exists(filename) is True: self._scp_client.scp_transfer_file(filename, self._DEST_FILENAME) self.device.send_command("cp " + self._BOOT_FILENAME + " " + self._BACKUP_FILENAME) output_loadcmd = self.device.send_config_set( ['load ' + self._DEST_FILENAME]) match_loaded = re.findall("Load complete.", output_loadcmd) match_notchanged = re.findall( "No configuration changes to commit", output_loadcmd) match_failed = re.findall( "Failed to parse specified config file", output_loadcmd) if match_failed: raise ReplaceConfigException("Failed replace config: " + output_loadcmd) if not match_loaded: if not match_notchanged: raise ReplaceConfigException( "Failed replace config: " + output_loadcmd) else: raise ReplaceConfigException("config file is not found") else: raise ReplaceConfigException("no configuration found") def load_merge_candidate(self, filename=None, config=None): """ Only configuration in set-format is supported with load_merge_candidate. """ if filename is not None: if os.path.exists(filename) is True: with open(filename) as f: self.device.send_command("cp " + self._BOOT_FILENAME + " " + self._BACKUP_FILENAME) self._new_config = f.read() cfg = [ x for x in self._new_config.split("\n") if x is not "" ] output_loadcmd = self.device.send_config_set(cfg) match_setfailed = re.findall("Delete failed", output_loadcmd) match_delfailed = re.findall("Set failed", output_loadcmd) if match_setfailed or match_delfailed: raise MergeConfigException("Failed merge config: " + output_loadcmd) else: raise MergeConfigException("config file is not found") elif config is not None: self._new_config = config else: raise MergeConfigException("no configuration found") def discard_config(self): self.device.exit_config_mode() def compare_config(self): output_compare = self.device.send_config_set(['compare']) match = re.findall( "No changes between working and active configurations", output_compare) if match: return "" else: diff = ''.join(output_compare.splitlines(True)[1:-1]) return diff def commit_config(self): if self.device.commit(): self.device.send_config_set(['save']) self.device.exit_config_mode() def rollback(self): """Rollback configuration to filename or to self.rollback_cfg file.""" filename = None if filename is None: filename = self._BACKUP_FILENAME output_loadcmd = self.device.send_config_set(['load ' + filename]) match = re.findall("Load complete.", output_loadcmd) if not match: raise ReplaceConfigException("Failed rollback config: " + output_loadcmd) else: self.device.send_config_set(['commit', 'save']) def get_environment(self): """ 'vmstat' output: procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 0 61404 139624 139360 0 0 0 0 9 14 0 0 100 0 """ output_cpu_list = list() output_cpu = self.device.send_command("vmstat") output_cpu = str(output_cpu) output_cpu_list = output_cpu.split("\n") if len(output_cpu_list[-1]) > 0: output_cpu_list = output_cpu_list[-1] else: output_cpu_list = output_cpu_list[-2] output_cpu_idle = output_cpu_list.split()[-2] cpu = 100 - int(output_cpu_idle) """ 'free' output: total used free shared buffers cached Mem: 508156 446784 61372 0 139624 139360 -/+ buffers/cache: 167800 340356 Swap: 0 0 0 """ output_ram = self.device.send_command("free").split("\n")[1] available_ram, used_ram = output_ram.split()[1:3] environment = { "fans": { "invalid": { "status": False } }, "temperature": { "invalid": { "temperature": 0.0, "is_alert": False, "is_critical": False } }, "power": { "invalid": { "status": True, "capacity": 0.0, "output": 0.0 } }, "cpu": { "0": { "%usage": float(cpu) }, }, "memory": { "available_ram": int(available_ram), "used_ram": int(used_ram) } } return environment def get_interfaces(self): """ "show interfaces" output example: Interface IP Address S/L Description --------- ---------- --- ----------- br0 - u/D eth0 192.168.1.1/24 u/u Management eth1 192.168.1.2/24 u/u eth2 192.168.3.1/24 u/u foobar 192.168.2.2/24 lo 127.0.0.1/8 u/u ::1/128 """ output_iface = self.device.send_command("show interfaces") # Collect all interfaces' name and status match = re.findall("(\S+)\s+[:\-\d/\.]+\s+([uAD])/([uAD])", output_iface) # 'match' example: # [("br0", "u", "D"), ("eth0", "u", "u"), ("eth1", "u", "u")...] iface_state = { iface_name: { "State": state, "Link": link } for iface_name, state, link in match } output_conf = self.device.send_command("show configuration") # Convert the configuration to dictionary config = vyattaconfparser.parse_conf(output_conf) iface_dict = dict() for iface_type in config["interfaces"]: ifaces_detail = config["interfaces"][iface_type] for iface_name in ifaces_detail: description = self._get_value("description", ifaces_detail[iface_name]) if description is None: description = "" speed = self._get_value("speed", ifaces_detail[iface_name]) if speed is None: speed = 0 if speed == "auto": speed = 0 hw_id = self._get_value("hw-id", ifaces_detail[iface_name]) if hw_id is None: hw_id = "00:00:00:00:00:00" is_up = (iface_state[iface_name]["Link"] == "u") is_enabled = (iface_state[iface_name]["State"] == "u") iface_dict.update({ iface_name: { "is_up": bool(is_up), "is_enabled": bool(is_enabled), "description": py23_compat.text_type(description), "last_flapped": float(-1), "speed": int(speed), "mac_address": py23_compat.text_type(hw_id) } }) return iface_dict @staticmethod def _get_value(key, target_dict): if key in target_dict: return target_dict[key] else: return None def get_arp_table(self): # 'age' is not implemented yet """ 'show arp' output example: Address HWtype HWaddress Flags Mask Iface 10.129.2.254 ether 00:50:56:97:af:b1 C eth0 192.168.1.134 (incomplete) eth1 192.168.1.1 ether 00:50:56:ba:26:7f C eth1 10.129.2.97 ether 00:50:56:9f:64:09 C eth0 192.168.1.3 ether 00:50:56:86:7b:06 C eth1 """ output = self.device.send_command("show arp") output = output.split("\n") # Skip the header line output = output[1:-1] arp_table = list() for line in output: line = line.split() # 'line' example: # ["10.129.2.254", "ether", "00:50:56:97:af:b1", "C", "eth0"] # [u'10.0.12.33', u'(incomplete)', u'eth1'] if "incomplete" in line[1]: macaddr = py23_compat.text_type("00:00:00:00:00:00") else: macaddr = py23_compat.text_type(line[2]) arp_table.append({ 'interface': py23_compat.text_type(line[-1]), 'mac': macaddr, 'ip': py23_compat.text_type(line[0]), 'age': 0.0 }) return arp_table def get_ntp_stats(self): """ 'ntpq -np' output example remote refid st t when poll reach delay offset jitter ============================================================================== 116.91.118.97 133.243.238.244 2 u 51 64 377 5.436 987971. 1694.82 219.117.210.137 .GPS. 1 u 17 64 377 17.586 988068. 1652.00 133.130.120.204 133.243.238.164 2 u 46 64 377 7.717 987996. 1669.77 """ output = self.device.send_command("ntpq -np") output = output.split("\n")[2:] ntp_stats = list() for ntp_info in output: if len(ntp_info) > 0: remote, refid, st, t, when, hostpoll, reachability, delay, offset, \ jitter = ntp_info.split() # 'remote' contains '*' if the machine synchronized with NTP server synchronized = "*" in remote match = re.search("(\d+\.\d+\.\d+\.\d+)", remote) ip = match.group(1) when = when if when != '-' else 0 ntp_stats.append({ "remote": py23_compat.text_type(ip), "referenceid": py23_compat.text_type(refid), "synchronized": bool(synchronized), "stratum": int(st), "type": py23_compat.text_type(t), "when": py23_compat.text_type(when), "hostpoll": int(hostpoll), "reachability": int(reachability), "delay": float(delay), "offset": float(offset), "jitter": float(jitter) }) return ntp_stats def get_ntp_peers(self): output = self.device.send_command("ntpq -np") output_peers = output.split("\n")[2:] ntp_peers = dict() for line in output_peers: if len(line) > 0: match = re.search("(\d+\.\d+\.\d+\.\d+)\s+", line) ntp_peers.update({py23_compat.text_type(match.group(1)): {}}) return ntp_peers def get_bgp_neighbors(self): # 'description', 'sent_prefixes' and 'received_prefixes' are not implemented yet """ 'show ip bgp summary' output example: BGP router identifier 192.168.1.2, local AS number 64520 IPv4 Unicast - max multipaths: ebgp 1 ibgp 1 RIB entries 3, using 288 bytes of memory Peers 3, using 13 KiB of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 192.168.1.1 4 64519 7226 7189 0 0 0 4d23h40m 1 192.168.1.3 4 64521 7132 7103 0 0 0 4d21h05m 0 192.168.1.4 4 64522 0 0 0 0 0 never Active """ output = self.device.send_command("show ip bgp summary") output = output.split("\n") match = re.search( ".* router identifier (\d+\.\d+\.\d+\.\d+), local AS number (\d+)", output[0]) if not match: return {} router_id = py23_compat.text_type(match.group(1)) local_as = int(match.group(2)) bgp_neighbor_data = dict() bgp_neighbor_data["global"] = dict() bgp_neighbor_data["global"]["router_id"] = router_id bgp_neighbor_data["global"]["peers"] = {} # delete the header and empty element bgp_info = [i.strip() for i in output[6:-2] if i is not ""] for i in bgp_info: if len(i) > 0: peer_id, bgp_version, remote_as, msg_rcvd, msg_sent, table_version, \ in_queue, out_queue, up_time, state_prefix = i.split() is_enabled = "(Admin)" not in state_prefix received_prefixes = None try: state_prefix = int(state_prefix) received_prefixes = int(state_prefix) is_up = True except ValueError: is_up = False if bgp_version == "4": address_family = "ipv4" elif bgp_version == "6": address_family = "ipv6" else: raise ValueError("BGP neighbor parsing failed") """ 'show ip bgp neighbors 192.168.1.1' output example: BGP neighbor is 192.168.1.1, remote AS 64519, local AS 64520, external link BGP version 4, remote router ID 192.168.1.1 For address family: IPv4 Unicast ~~~ Community attribute sent to this neighbor(both) 1 accepted prefixes ~~~ """ bgp_detail = self.device.send_command( "show ip bgp neighbors %s" % peer_id) match_rid = re.search( "remote router ID (\d+\.\d+\.\d+\.\d+).*", bgp_detail) remote_rid = match_rid.group(1) match_prefix_accepted = re.search("(\d+) accepted prefixes", bgp_detail) accepted_prefixes = match_prefix_accepted.group(1) bgp_neighbor_data["global"]["peers"].setdefault(peer_id, {}) peer_dict = { "description": py23_compat.text_type(""), "is_enabled": bool(is_enabled), "local_as": int(local_as), "is_up": bool(is_up), "remote_id": py23_compat.text_type(remote_rid), "uptime": int(self._bgp_time_conversion(up_time)), "remote_as": int(remote_as) } af_dict = dict() af_dict[address_family] = { "sent_prefixes": int(-1), "accepted_prefixes": int(accepted_prefixes), "received_prefixes": int(received_prefixes) } peer_dict["address_family"] = af_dict bgp_neighbor_data["global"]["peers"][peer_id] = peer_dict return bgp_neighbor_data def _bgp_time_conversion(self, bgp_uptime): # uptime_letters = set(["y", "w", "h", "d"]) if "never" in bgp_uptime: return -1 else: if "y" in bgp_uptime: match = re.search("(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime) uptime = ((int(match.group(1)) * self._YEAR_SECONDS) + (int(match.group(3)) * self._WEEK_SECONDS) + (int(match.group(5)) * self._DAY_SECONDS)) return uptime elif "w" in bgp_uptime: match = re.search("(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime) uptime = ((int(match.group(1)) * self._WEEK_SECONDS) + (int(match.group(3)) * self._DAY_SECONDS) + (int(match.group(5)) * self._HOUR_SECONDS)) return uptime elif "d" in bgp_uptime: match = re.search("(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime) uptime = ((int(match.group(1)) * self._DAY_SECONDS) + (int(match.group(3)) * self._HOUR_SECONDS) + (int(match.group(5)) * self._MINUTE_SECONDS)) return uptime else: hours, minutes, seconds = map(int, bgp_uptime.split(":")) uptime = ((hours * self._HOUR_SECONDS) + (minutes * self._MINUTE_SECONDS) + seconds) return uptime def get_interfaces_counters(self): # 'rx_unicast_packet', 'rx_broadcast_packets', 'tx_unicast_packets', # 'tx_multicast_packets' and 'tx_broadcast_packets' are not implemented yet """ 'show interfaces detail' output example: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:50:56:86:8c:26 brd ff:ff:ff:ff:ff:ff ~~~ RX: bytes packets errors dropped overrun mcast 35960043 464584 0 221 0 407 TX: bytes packets errors dropped carrier collisions 32776498 279273 0 0 0 0 """ output = self.device.send_command("show interfaces detail") interfaces = re.findall("(\S+): <.*", output) # count = re.findall("(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+", output) count = re.findall("(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)", output) counters = dict() j = 0 for i in count: if j % 2 == 0: rx_errors = i[2] rx_discards = i[3] rx_octets = i[0] rx_unicast_packets = i[1] rx_multicast_packets = i[5] rx_broadcast_packets = -1 else: counters.update({ interfaces[j // 2]: { "tx_errors": int(i[2]), "tx_discards": int(i[3]), "tx_octets": int(i[0]), "tx_unicast_packets": int(i[1]), "tx_multicast_packets": int(-1), "tx_broadcast_packets": int(-1), "rx_errors": int(rx_errors), "rx_discards": int(rx_discards), "rx_octets": int(rx_octets), "rx_unicast_packets": int(rx_unicast_packets), "rx_multicast_packets": int(rx_multicast_packets), "rx_broadcast_packets": int(rx_broadcast_packets) } }) j += 1 return counters def get_snmp_information(self): # 'acl' is not implemented yet output = self.device.send_command("show configuration") # convert the configuration to dictionary config = vyattaconfparser.parse_conf(output) snmp = dict() snmp["community"] = dict() try: for i in config["service"]["snmp"]["community"]: snmp["community"].update({ i: { "acl": py23_compat.text_type(""), "mode": py23_compat.text_type( config["service"]["snmp"]["community"][i] ["authorization"]) } }) snmp.update({ "chassis_id": py23_compat.text_type(""), "contact": py23_compat.text_type(config["service"]["snmp"]["contact"]), "location": py23_compat.text_type(config["service"]["snmp"]["location"]) }) return snmp except KeyError: return {} def get_facts(self): output_uptime = self.device.send_command( "cat /proc/uptime | awk '{print $1}'") uptime = int(float(output_uptime)) output = self.device.send_command("show version").split("\n") ver_str = [line for line in output if "Version" in line][0] version = self.parse_version(ver_str) sn_str = [line for line in output if "S/N" in line][0] snumber = self.parse_snumber(sn_str) hwmodel_str = [line for line in output if "HW model" in line][0] hwmodel = self.parse_hwmodel(hwmodel_str) output = self.device.send_command("show configuration") config = vyattaconfparser.parse_conf(output) if "host-name" in config["system"]: hostname = config["system"]["host-name"] else: hostname = None if "domain-name" in config["system"]: fqdn = config["system"]["domain-name"] else: fqdn = "" iface_list = list() for iface_type in config["interfaces"]: for iface_name in config["interfaces"][iface_type]: iface_list.append(iface_name) facts = { "uptime": int(uptime), "vendor": py23_compat.text_type("VyOS"), "os_version": py23_compat.text_type(version), "serial_number": py23_compat.text_type(snumber), "model": py23_compat.text_type(hwmodel), "hostname": py23_compat.text_type(hostname), "fqdn": py23_compat.text_type(fqdn), "interface_list": iface_list } return facts @staticmethod def parse_version(ver_str): version = ver_str.split()[-1] return version @staticmethod def parse_snumber(sn_str): sn = sn_str.split(":") return sn[1].strip() @staticmethod def parse_hwmodel(model_str): model = model_str.split(":") return model[1].strip() def get_interfaces_ip(self): output = self.device.send_command("show interfaces") output = output.split("\n") # delete the header line and the interfaces which has no ip address if len(output[-1]) > 0: ifaces = [x for x in output[3:] if "-" not in x] else: ifaces = [x for x in output[3:-1] if "-" not in x] ifaces_ip = dict() for iface in ifaces: iface = iface.split() if len(iface) != 1: iface_name = iface[0] # Delete the "Interface" column iface = iface[1:-1] # Key initialization ifaces_ip[iface_name] = dict() ip_addr, mask = iface[0].split("/") ip_ver = self._get_ip_version(ip_addr) # Key initialization if ip_ver not in ifaces_ip[iface_name]: ifaces_ip[iface_name][ip_ver] = dict() ifaces_ip[iface_name][ip_ver][ip_addr] = { "prefix_length": int(mask) } return ifaces_ip @staticmethod def _get_ip_version(ip_address): if ":" in ip_address: return "ipv6" elif "." in ip_address: return "ipv4" def get_users(self): output = self.device.send_command("show configuration commands").split( "\n") user_conf = [x.split() for x in output if "login user" in x] # Collect all users' name user_name = list(set([x[4] for x in user_conf])) user_auth = dict() for user in user_name: sshkeys = list() # extract the configuration which relates to 'user' for line in [x for x in user_conf if user in x]: # "set system login user alice authentication encrypted-password 'abc'" if line[6] == "encrypted-password": password = line[7].strip("'") # set system login user alice level 'admin' elif line[5] == "level": if line[6].strip("'") == "admin": level = 15 else: level = 0 # "set system login user alice authentication public-keys # [email protected] key 'ABC'" elif len(line) == 10 and line[8] == "key": sshkeys.append(line[9].strip("'")) user_auth.update({ user: { "level": level, "password": password, "sshkeys": sshkeys } }) return user_auth def ping(self, destination, source=C.PING_SOURCE, ttl=C.PING_TTL, timeout=C.PING_TIMEOUT, size=C.PING_SIZE, count=C.PING_COUNT, vrf=C.PING_VRF): # does not support multiple destination yet deadline = timeout * count command = "ping %s " % destination command += "ttl %d " % ttl command += "deadline %d " % deadline command += "size %d " % size command += "count %d " % count if source != "": command += "interface %s " % source ping_result = dict() output_ping = self.device.send_command(command) if "Unknown host" in output_ping: err = "Unknown host" else: err = "" if err is not "": ping_result["error"] = err else: # 'packet_info' example: # ['5', 'packets', 'transmitted,' '5', 'received,' '0%', 'packet', # 'loss,', 'time', '3997ms'] packet_info = output_ping.split("\n") if len(packet_info[-1]) > 0: packet_info = packet_info[-2] else: packet_info = packet_info[-3] packet_info = [x.strip() for x in packet_info.split()] sent = int(packet_info[0]) received = int(packet_info[3]) lost = sent - received # 'rtt_info' example: # ["0.307/0.396/0.480/0.061"] rtt_info = output_ping.split("\n") if len(rtt_info[-1]) > 0: rtt_info = rtt_info[-1] else: rtt_info = rtt_info[-2] match = re.search("([\d\.]+)/([\d\.]+)/([\d\.]+)/([\d\.]+)", rtt_info) if match is not None: rtt_min = float(match.group(1)) rtt_avg = float(match.group(2)) rtt_max = float(match.group(3)) rtt_stddev = float(match.group(4)) else: rtt_min = None rtt_avg = None rtt_max = None rtt_stddev = None ping_result["success"] = dict() ping_result["success"] = { "probes_sent": sent, "packet_loss": lost, "rtt_min": rtt_min, "rtt_max": rtt_max, "rtt_avg": rtt_avg, "rtt_stddev": rtt_stddev, "results": [{ "ip_address": destination, "rtt": rtt_avg }] } return ping_result
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)