def get_sv_if(self): '''查询服务器网卡信息 Args: 无 Returns: -1: 连接服务器出错 -2: socket超时 ''' ifs = [] ip = self.data['ip'] username = self.data['username'] password = self.data['password'] ssh = ssh_tools.SshConnect(ip, username, password) lines = ssh.get_cmd_ret('ip a') if type(lines) == int: print json.dumps({'err': lines}) return lines i = 0 while i < len(lines): interface = {'dev': '0', 'state': 'DOWN', 'mac': '0', 'addrs': []} line = lines[i].split() interface['dev'] = line[1].split(':')[0] if 'UP' in line[2].split(','): interface['state'] = 'UP' interface['mac'] = lines[i + 1].split()[1] i += 2 while i < len(lines) and lines[i].split()[0] == 'inet': interface['addrs'].append(lines[i].split()[1]) i += 1 while i < len(lines) and re.match(r'\d+:', lines[i].split()[0]) is None: i += 1 ifs.append(interface) print json.dumps(ifs) #将json对象转化为json字符串,打印给node.js后台
def set_server_info(self, servers): '''配置服务器信息 Args: servers: 服务器列表 Returns: common.SUCCESS: 正常执行 其他返回值参考set_server_ip和set_server_static ''' for server in servers: #print type(server['adminInfo']) sip = server['adminInfo']['ip'] sname = server['adminInfo']['userName'] spasswd = server['adminInfo']['passwd'] his = history.History(sip, sname, spasswd) self.svundolist.append(his) #print '%s %s %s' % (sip, sname, spasswd) ssh = ssh_tools.SshConnect(sip, sname, spasswd) for iface in server['svInterface']: ip = iface['ip'] + '/' + iface['mask'] dev = iface['ifName'] ret = self.set_server_ip(ssh, ip, dev, his) if ret != '0': #shell返回值为字符串,0表示执行成功 self.undo(his) return ret for static in server['svStaticRoute']: destip = '.'.join( static['destIp'].split('.')[:3]) + '.0/' + static['mask'] via = static['nextIp'] dev = static['iface'] #print 'ip:%s via:%s dev:%s' % (destip, via, dev) ret = self.set_server_static(ssh, destip, via, dev, his) if ret != '0': self.undo(his) return ret return common.SUCCESS
def getdevs(self): '''查询远程主机网卡信息 Args: 无 Returns: -1: 连接服务器出错 -2: socket超时 ''' ifs = [] ssh = ssh_tools.SshConnect(self.ip, self.uname, self.passwd) lines = ssh.get_cmd_ret('ip a') if type(lines) == int: return lines i = 0 while i < len(lines): interface = {'dev': '0', 'state': 'DOWN', 'mac': '0', 'addrs': []} line = lines[i].split() interface['dev'] = line[1].split(':')[0] if 'UP' in line[2].split(','): interface['state'] = 'UP' interface['mac'] = lines[i + 1].split()[1] i += 2 while i < len(lines) and lines[i].split()[0] == 'inet': interface['addrs'].append(lines[i].split()[1]) i += 1 while i < len(lines) and re.match(r'\d+:', lines[i].split()[0]) is None: i += 1 ifs.append(interface) return ifs
def getnets(self): '''获取目标主机所有网卡的ip子网信息 Args: None Returns: nets: 主机直连的接口和网段信息,格式为{'eth0': ['1.1.1.1/24', ...]} -5: subprocess出错 lines: 参考ssh_tools.get_cmd_ret()方法的返回值 ''' nets = [] sp = subprocess.Popen('ip a', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = sp.communicate() if err != '': return (-5, err) else: lines = out.split(os.linesep) for net in lines: net = net.split() if 'inet' in net: #读取本机网卡信息 nets.append(net[1]) for net in nets: if NetProbe.belongto(self.ip, net): #判断目标主机是否就是本机 self.local = True break #目标主机为本地主机,则使用刚才获取的信息;目标主机为远程主机,则使用ssh重新获取信息 if not self.local: ssh = ssh_tools.SshConnect(self.ip, self.uname, self.passwd) lines = ssh.get_cmd_ret('ip a') if type(lines) == int: return lines devnets = {} #{'网卡1': ['ip/mask', ...], '网卡2': ['ip/mask', ...], ...} i = 0 while i < len(lines) and lines[i] != '': inets = [] line = lines[i].split() dev = line[1].split(':')[0] i += 2 while i < len(lines) and lines[i] != ''\ and lines[i].split()[0] == 'inet': inets.append(lines[i].split()[1]) i += 1 while i < len(lines) and lines[i] != ''\ and re.match(r'\d+:', lines[i].split()[0]) is None: i += 1 devnets[dev] = inets return devnets
def undo(self, his=None): '''还原服务器操作 Args: his: 还原操作对象 Returns: 无 ''' templist = [] if his is not None: templist.append(his) else: templist = self.svundolist for i in self.svundolist: ssh = ssh_tools.SshConnect(i.ip, i.username, i.passwd) for cmd in i.cmdlist: print('undo: %s' % (cmd)) ret = ssh.send_cmd(cmd) print('return: %s' % str(ret))
def get_sv_sr(self): '''查询服务器路由信息 Args: 无 Returns: -1: 连接服务器出错 -2: socket超时 ''' routes = [] ip = self.data['ip'] username = self.data['username'] password = self.data['password'] ssh = ssh_tools.SshConnect(ip, username, password) lines = ssh.get_cmd_ret('route -n') #if type(lines) != list and lines in [-1, -2, -3]: if type(lines) == int: print json.dumps({'err': lines}) return lines i = 2 while i < len(lines): route = { 'dest': '0', 'gw': '0', 'mask': '0', 'metric': '0', 'iface': '0' } line = lines[i].split() route['dest'] = line[0] route['gw'] = line[1] route['mask'] = line[2] route['metric'] = line[4] route['iface'] = line[7] routes.append(route) i += 1 print json.dumps(routes) #将json对象转化为json字符串,打印给node.js后台
def get_connectivity2(self): self.data = { 'src': { 'ip': '10.32.19.93', 'username': '******', 'password': '******', 'dev': 'sv' }, 'dst': { 'ip': '10.32.19.99', 'username': '******', 'password': '******', 'dev': 'sv' } } json_result = {'isConnect': 0, 'connInfo': []} src_ip = self.data['src']['ip'] src_username = self.data['src']['username'] src_password = self.data['src']['password'] #src_dev = self.data['src']['dev'] dst_ip = self.data['dst']['ip'] dst_username = self.data['dst']['username'] dst_password = self.data['dst']['password'] #dst_dev = self.data['dst']['dev'] nps = netprobe.NetProbe(src_ip, src_username, src_password) npd = netprobe.NetProbe(dst_ip, dst_username, dst_password) flag = 0 mngip = '10.32.0.0/16' src_devs = nps.getnets() dst_devs = npd.getnets() print(src_devs) print(dst_devs) for sdev in src_devs: #TODO 循环待改进 if sdev == 'lo': continue #print('sdev: ' + sdev) for ddev in dst_devs: if ddev == 'lo': continue #print('ddev: ' + ddev) for sip in src_devs[sdev]: #print('sip: ' + sip) ret = netprobe.NetProbe.samenet(sip, mngip) if ret == -1 or ret: continue for dip in dst_devs[ddev]: #print('dip: ' + dip) ret = netprobe.NetProbe.samenet(dip, mngip) if ret == -1 or ret: continue if netprobe.NetProbe.samenet(sip, dip): if nps.isnbr( sip.split('/')[0], sdev, dip.split('/')[0]) == 1: if flag == 0: flag = 1 if json_result['isConnect'] == 0: json_result['isConnect'] = 1 cinfo = { 'cFlag': 'connected', 'cType': 'full', 'srcInterface': sdev, 'dstInterface': ddev, 'srcNet': sip, 'dstNet': dip, 'extra': '' } json_result['connInfo'].append(cinfo) if flag == 1: print json.dumps(json_result) return 0 #print('########################') for sdev in src_devs: #TODO 同上 if sdev == 'lo': continue #print('sdev: ' + sdev) for ddev in dst_devs: if ddev == 'lo': continue #print('ddev: ' + ddev) for sip in src_devs[sdev]: #print('sip: ' + sip) ret = netprobe.NetProbe.samenet(sip, mngip) #print(ret) if ret == -1 or ret: continue for dip in dst_devs[ddev]: #print('dip: ' + dip) ret = netprobe.NetProbe.samenet(dip, mngip) #print(ret) if ret == -1 or ret: continue src_ssh = ssh_tools.SshConnect(src_ip, src_username, src_password) dst_ssh = ssh_tools.SshConnect(dst_ip, dst_username, dst_password) sip = netprobe.NetProbe.iplus(dip) src_ssh.send_cmd('ip l set dev %s down' % (sdev)) src_ssh.send_cmd('ip l set dev %s arp off' % (sdev)) src_ssh.send_cmd('ip l set dev %s up' % (sdev)) src_ssh.send_cmd('ip l set dev %s arp on' % (sdev)) src_ssh.send_cmd('ip a add %s dev %s' % (sip, sdev)) dst_ssh.send_cmd('ip l set dev %s down' % (ddev)) dst_ssh.send_cmd('ip l set dev %s arp off' % (ddev)) dst_ssh.send_cmd('ip l set dev %s up' % (ddev)) dst_ssh.send_cmd('ip l set dev %s arp on' % (ddev)) if nps.isnbr( sip.split('/')[0], sdev, dip.split('/')[0]) == 1: cinfo = { 'cFlag': 'unconnected', 'cType': 'break', 'srcInterface': sdev, 'dstInterface': ddev, 'srcNet': 'N/A', 'dstNet': dip, 'extra': 'need to add interface info' } json_result['connInfo'].append(cinfo) src_ssh.send_cmd('ip a del %s dev %s' % (sip, sdev)) src_ssh.send_cmd('ip l set dev %s down' % (sdev)) src_ssh.send_cmd('ip l set dev %s arp off' % (sdev)) src_ssh.send_cmd('ip l set dev %s up' % (sdev)) src_ssh.send_cmd('ip l set dev %s arp on' % (sdev)) dst_ssh.send_cmd('ip l set dev %s down' % (ddev)) dst_ssh.send_cmd('ip l set dev %s arp off' % (ddev)) dst_ssh.send_cmd('ip l set dev %s up' % (ddev)) dst_ssh.send_cmd('ip l set dev %s arp on' % (ddev)) print json.dumps(json_result) return 0
def get_connectivity(self): ''' 连通性判断 Args: 无 Returns: -1: ssh连接出错 self.data = { 'src': {'ip': '10.32.19.211', 'username': '******', 'password': '******', 'dev': 'sv'}, 'dst': {'ip': '10.32.19.64', 'username': '******', 'password': '******', 'dev': 'sv'} } ''' json_result = {'isConnect': '0', 'connInfo': []} src_ip = self.data['src']['ip'] src_username = self.data['src']['username'] src_password = self.data['src']['password'] src_dev = self.data['src']['dev'] dst_ip = self.data['dst']['ip'] dst_username = self.data['dst']['username'] dst_password = self.data['dst']['password'] dst_dev = self.data['dst']['dev'] if (src_dev == 'sv') and (dst_dev == 'sv'): # 只提取ping结果的第二行,然后判断是否连通 # 连通判断依据为返回结果中匹配到time, # 如果不通,返回结果匹配到 Destination Host Unreachable src_ssh = ssh_tools.SshConnect(src_ip, src_username, src_password) dst_ssh = ssh_tools.SshConnect(dst_ip, dst_username, dst_password) conn_lines = src_ssh.get_cmd_ret( "ping -c 1 10.32.19.64 | sed -n '2,2p'") if type(conn_lines) == int: #ssh连接异常 #print json.dumps({'err': 'ssh connect error'}) return -1 mask = '' if conn_lines[0].find('time') > 0: json_result['isConnect'] = 1 cinfo = { 'cFlag': 'connected', 'cType': 'full', 'srcInterface': '', 'dstInterface': '', 'srcNet': '', 'dstNet': '', 'extra': '' } # 获取源ip服务器所有接口名 ifaces = src_ssh.get_cmd_ret( "netstat -ni | cut -d ' ' -f 1 | sed -n '3,$p'") if type(ifaces) == int: #ssh连接异常 #print json.dumps({'err': 'ssh connect error'}) return -1 for iface in ifaces: iface = iface.replace('\n', '') #print iface if_result = src_ssh.get_cmd_ret( "ifconfig {0} | sed -n '2,2p'".format(iface)) if if_result[0].find(src_ip) > 0: mask = if_result[0].split('Mask:')[1] #print common.MASK_LEN[mask] cinfo['srcInterface'] = iface break # 获取目的ip服务器所有接口名 ifaces = dst_ssh.get_cmd_ret( "netstat -ni | cut -d ' ' -f 1 | sed -n '3,$p'") if type(ifaces) == int: #ssh连接异常 #print json.dumps({'err': 'ssh connect error'}) return -1 for iface in ifaces: # 由于获取的接口名中包含\n字符,因此这里需要替换掉 iface = iface.replace('\n', '') if_result = dst_ssh.get_cmd_ret( "ifconfig {0}".format(iface)) if if_result[1].find(dst_ip) > 0: cinfo['dstInterface'] = iface break # 获取网络号 ip = socket.ntohl( struct.unpack("I", socket.inet_aton(str(src_ip)))[0]) int_mask = socket.ntohl( struct.unpack("I", socket.inet_aton(str(mask)))[0]) network = socket.inet_ntoa( struct.pack('I', socket.htonl(ip & int_mask))) cinfo['srcNet'] = network + '/' + common.MASK_LEN[mask] cinfo['dstNet'] = network + '/' + common.MASK_LEN[mask] json_result['connInfo'].append(cinfo) elif conn_lines[0].find('Destination Host Unreachable') > 0: json_result['isConnect'] = 0 elif (src_dev == 'sv') and (dst_dev == 'sw'): ''' 待处理 ''' elif (src_dev == 'sw') and (dst_dev == 'sv'): ''' 待处理 ''' elif (src_dev == 'sw') and (dst_dev == 'sw'): ''' 待处理 ''' print json.dumps(json_result)
self.islocal() if self.local: try: ans, unans = srp(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(psrc=sip, pdst=dip), verbose=0, filter='arp and arp[7] = 2', iface=dev, timeout=2) except socket.error, e: (etype, evalue, etrace) = sys.exc_info() (errno, err_msg) = evalue if errno == 19: return 0 if len(ans) == 1: (s, r) = ans if r.payload.psrc == dip: return 1 return 0 ssh = ssh_tools.SshConnect(self.ip, self.uname, self.passwd) if ssh.sftp('./remote_arping.py', '/tmp/remote_arping.py') != 0: return -1 lines = ssh.get_cmd_ret('cd /tmp && python remote_arping.py %s %s %s 2>/dev/null' % (sip, dev, dip)) if type(lines) == int: return lines ssh.send_cmd('rm -f /tmp/remote_arping.py') print lines if lines != [] and lines[0] == '1': return 1 return 0