运维常用的第三方库
一、psutil
系统性能信息模块
psutil是一个跨平台库,能够轻松的实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。它主要应用于系统监控,分析和限制系统资源及进程的管理。它实现了同等命令行工具提供的功能,如ps、top、lsof、netstat、ifconfig、who、df、kill、free、nice、ionice、iostat、iotop、uptime、pidof、tty、taskset、pmap等。目前支持32位和64位的Linux、Windows、OS X、FreeBSD和Sun Solaris等操作系统,支持从2.6 到 3.5的Python版本,目前最新版本为5.1.3。
项目地址:https://github.com/giampaolo/psutil
1、安装
pip install psutil
2、CPU
#显示所有逻辑CPU信息。 psutil.cpu_times(percpu=True) #获取CPU的逻辑个数 psutil.cpu_count() #获取物理cpu个数 psutil.cpu_count(logical=False)
3、Memory
#内存信息 psutil.virtual_memory() #获取内存总数 psutil.virtual_memory().total #获取空闲内存数 psutil.virtual_memory().free #获取swap信息 psutil.swap_memory()
4、Disks
#磁盘信息 psutil.disk_partitions(all=True) #获取分区参数 psutil.disk_usage('/') #获取磁盘IO个数 psutil.disk_io_counters()
5、Network
#获取网络总的IO信息 psutil.net_io_counters() #获取每个网络接口的io信息 psutil.net_io_counters(pernic=True)
6、Other system info
#返回当前用户登录信息 psutil.users() #获取开机时间(以时间戳的方式) psutil.boot_time() #让人能看懂 import datetime datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
7、Process management
# 进程信息 psutil.pids() #获取所有进程的PID p = psutil.Process(2128) #实例化一个Process对象,参数为一个进程PID p.name() #进程名 p.exe() #经常bin路径 p.cwd() #进程工作目录路径 p.status() #进程状态 p.create_time() #进程创建时间,时间戳格式 p.uids() #进程uid信息 p.gids() #进程gid信息 p.cpu_times() #进程cpu时间信息,包括use,system两个时间 p.cpu_affinity() #get进程CPU亲合度,如果设置了进程cpu的亲和度,降CPU号作为参数即可 p.memory_percent() #进程内存利用率 p.memory_info() #进程内存rss.vms信息 p.io_counters() #进程IO信息,包括读写IO数及字节数 p.connections() #返回打开进程socket的namedutples列表,包括fs、family、laddr等信息 p.num_threads() #进程开启的线程数 #popen类的使用 from subprocess import PIPE #通过psutil的popen方法启动的应用程序,可以跟踪程序运行的所有相关信息 p = psutil.Popen(['/usr/bin/python','-c','print ("hello")'],stdout=PIPE) p.name() p.username() p.communicate() p.cpu_times()
二、Ipy
IP地址处理模块
IP地址规划是网络设计中非常重要的一个环节,规划的好坏会直接影响路由协议算法的效率,包括网络性能、可扩展性等方面,在这个过程当中,免不了要计算大量的IP地址,包括网段、网络掩码、广播地址、子网数、IP类型等。
官方地址: https://github.com/autocracy/python-ipy
1、安装
版本号 0.83
pip install IPy
IPy模块包含IP类,使用它可以方便处理绝大部分格式为IPv6及IPv4的网络和地址。比如通过version方法就可以区分出IPv4与IPv6,如:
from IPy import IP IP('192.168.1.0/24').version() IP('::1').version() ip = IP('192.168.0.0/16') ip.len() #输出192.168.0.0网段的ip个数 for x in ip: print(x) test_ip = IP('192.168.17.8') test_ip.reverseName() #反向解析地址格式 test_ip.iptype() #192.168.17.8为私网类型'PRIVATE' IP('8.8.8.8').iptype() #8.8.8.8 为公网类型 IP('8.8.8.8').int() #转换为整形格式 IP('8.8.8.8').strHex() #转换为16进制 IP('8.8.8.8').strBin() #转换为2进制 IP(0x8080808) #16进制转换成IP格式
IP方法也支持网络地址的转换,例如根据IP与掩码生产网段格式,如下:
>>> from IPy import IP >>> IP('192.168.1.0').make_net('255.255.255.0') IP('192.168.1.0/24') >>> IP('192.168.1.0/255.255.255.0', make_net=True) IP('192.168.1.0/24') >>> IP('192.168.1.0-192.168.1.255', make_net=True) IP('192.168.1.0/24')
也可以通过strNormal方法指定不同wantprefixlen参数值以定制不同输出类型的网段。输出类型为字符串,如下:
>>>IP('192.168.1.0/24').strNormal(0) '192.168.1.0' >>>IP('192.168.1.0/24').strNormal(1) '192.168.1.0/24' >>>IP('192.168.1.0/24').strNormal(2) '192.168.1.0/255.255.255.0' >>>IP('192.168.1.0/24').strNormal(3) '192.168.1.0-192.168.1.255'
示例 根据输入的IP或子网返回网络、掩码、广播、反向解析、子网数、IP类型等信息。
#!/usr/bin/env python #-*- coding:utf-8 -*- from IPy import IP ip_s = input('请输入一个ip或 网段地址:') ips = IP(ip_s) if len(ips) > 1: print('net: %s' % ips.net()) #输出网络地址 print('netmask: %s' % ips.netmask()) #输出网络地址掩码 print('broadcast: %s' % ips.broadcast()) #输出网络广播地址 print('reverse adress: %s' % ips.reverseName()[0]) #输出地址反向解析 print('subnet: %s' %len(ips)) #输出网络子网数 else: #为单个ip地址 print('reverse adress: %s' % ips.reverseName()[0]) print('十六进制地址:%s' % ips.strHex()) print('二进制地址:%s' % ips.strBin()) print('IP地址类型:%s' % ips.iptype())
三、dnspython
DNS处理模块
dnspython(http://www.dnspython.org/) 是Python实现的一个DNS工具包,它支持几乎所有的记录类型,可以用于查询、传输并动态更新ZONE信息,同时支持TSIG(事务签名)验证消息和EDNS0(扩展DNS)。在系统管理方面,我们可以利用其查询功能来实现DNS服务监控以及解析结果的校验,可以代替nslookup及dig等工具,轻松做到与现有平台的整合。
项目地址:https://github.com/rthalley/dnspython
1、安装
pip install dnspython
最新版本 dnspython-1.15.0
dnspython模块提供了大量的DNS处理方法,最常用的方法是域名查询。dnspython提供了一个DNS解析器类—resolver,使用它的query方法来实现域名的查询功能。query方法的定义如下:
query(self, qname, rdtype=1, rdclass=1, tcp=False, source=None, raise_on_no_answer=True, source_port=0)
- qname参数为查询的域名。
- rdtype参数用来指定RR资源的类型,常用的有以下几种:
- A记录,将主机名转换成IP地址;
- MX记录,邮件交换记录,定义邮件服务器的域名;
- CNAME记录,指别名记录,实现域名间的映射;
- NS记录,标记区域的域名服务器及授权子域;
- PTR记录,反向解析,与A记录相反,将IP转换成主机名;
- SOA记录,SOA标记,一个起始授权区的定义。
- rdclass参数用于指定网络类型,可选的值有IN、CH与HS,其中IN为默认,使用最广泛。tcp参数用于指定查询是否启用TCP协议,默认为False(不启用)。
- source与source_port参数作为指定查询源地址与端口,默认值为查询设备IP地址和0。
- raise_on_no_answer参数用于指定当查询无应答时是否触发异常,默认为True。
2、A记录查询
#!/usr/bin/env python #-*- coding:utf-8 -*- import dns.resolver domain = raw_input('Please input an domain: ') #输入域名地址 A = dns.resolver.query(domain, 'A') #指定查询类型为A记录 for i in A.response.answer: #通过response.answer方法获取查询回应信息 print(i)
3、mx记录查询
#!/usr/bin/env python #-*- coding:utf-8 -*- import dns.resolver domain = raw_input("Please input an domain:") MX = dns.resolver.query(domain,'MX')#指定查询记录类型为mx for i in MX: print('MX preference=', i.preference, ' mail exchanger=', i.exchange)
4、NS记录查询
只限输入一级域名,baidu.com。
#!/usr/bin/env python #-*- coding:utf-8 -*- import dns.resolver domain = raw_input("Please input an domain:") ns = dns.resolver.query(domain,'NS') #指定查询类型为NS记录 for i in ns.response.answer: for j in i.items: print j.to_text()
CNAME记录查询
#!/usr/bin/env python #-*- coding:utf-8 -*- import dns.resolver domain = raw_input("Please input an domain:") cname = dns.resolver.query(domain,'CNAME') #指定查询类型为CNAME记录 for i in cname.response.answer: for j in i.items: print j.to_text()
结果返回cname后的目标域名。
5、DNS域名轮询业务监控
#!/usr/bin/env python # coding=utf-8 import dns.resolver # import httplib import http.client iplist = [] # 定义域名IP列表变量 appdomain = "jingfengjiaoyu.com" # 定义业务域名 def get_iplist(domain=""): # 域名解析函数,解析成功IP将被追加到iplist try: A = dns.resolver.query(domain, 'A') # 解析A记录类型 except Exception as e: print("dns resolver error:" + str(e)) return for i in A.response.answer: for j in i.items: iplist.append(j.address) # 追加到iplist return True def checkip(ip): checkurl = ip + ":80" getcontent = "" http.client.socket.setdefaulttimeout(5) # 定义http连接超时时间(5秒) conn = http.client.HTTPConnection(checkurl) # 创建http连接对象 try: conn.request("GET", "/", headers={"Host": appdomain}) # 发起URL请求,添 # 加host主机头 r = conn.getresponse() getcontent = r.read(7) # 获取URL页面前15个字符,以便做可用性校验 print(getcontent) finally: if getcontent == "<html>": # 监控URL页的内容一般是事先定义好的,比如 “HTTP200”等 print(ip + " [OK]") else: print(ip + " [Error]") # 此处可放告警程序,可以是邮件、短信通知 if __name__ == "__main__": if get_iplist(appdomain) and len(iplist) > 0: # 条件:域名解析正确且至少返回一个IP for ip in iplist: checkip(ip) else: print("dns resolver error.")
四、paramiko
模仿ssh登录执行命
官方网站:http://www.paramiko.org/
项目网站:https://github.com/paramiko/paramiko
1、安装
pip install paramiko
paramiko-2.1.2
2、连接服务器
2.1 用户名和密码连接
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #作用是允许连接不在know_hosts文件中的主机 ssh.connect('139.199.228.59', 22, 'root', '!@#)(*WGK') stdin,stdout,stderr = ssh.exec_command('df -h\nls') stdout.read() ssh.close()
2.2 上传和下载文件
import paramiko import os,sys t = paramiko.Transport(('192.168.17.248',22)) t.connect(username='root',password='123456') sftp = paramiko.SFTPClient.from_transport(t) #上传 sftp.put('D:\log.conf','/tmp/log.conf') #下载 sftp.get('/tmp/ks-script-mZm5Oi','D:\ks-script-mZm5Oi') t.close()
3、通过公私钥免密码SSH连接服务器
3.1 公私钥生成
ssh-keygen -t rsa # 生成密钥 ssh-copy-id -i ~/ssh/id_rsa.pub root@192.168.17.258 # 将本机的公钥复制到远程机器的authorized_keys文件中,ssh-copy-id也能让你有到远程机器的home, ~./ssh , 和 ~/.ssh/authorized_keys的权利 import paramiko private_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(private_key_path) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('192.168.17.258 ', 22, 'root', key) stdin, stdout, stderr = ssh.exec_command('df') print stdout.read() ssh.close();
3.2 paramiko sftp —— SSH上传和下载文件
import paramiko #建立一个加密的管道 scp=paramiko.Transport(('192.168.0.102', 22)) #建立连接 scp.connect(username='root',password='361way') #建立一个sftp客户端对象,通过ssh transport操作远程文件 sftp=paramiko.SFTPClient.from_transport(scp) #Copy a remote file (remotepath) from the SFTP server to the local host sftp.get('/root/testfile','/tmp/361way') #Copy a local file (localpath) to the SFTP server as remotepath sftp.put('/root/crash-6.1.6.tar.gz','/tmp/crash-6.1.6.tar.gz') scp.close()
一个目录下多个文件上传下载的示例:bx
#!/usr/bin/env python #-*- coding: utf-8 -*- import paramiko,datetime,os hostname='139.199.228.59' username='root' password='!@#)(*WGK1' port=22 local_dir='/tmp/getfile' remote_dir='/tmp/abc' try: t=paramiko.Transport((hostname,port)) t.connect(username=username,password=password) sftp=paramiko.SFTPClient.from_transport(t) files=sftp.listdir(remote_dir) for f in files: print '' print '#########################################' print 'Beginning to download file from %s %s ' % (hostname,datetime.datetime.now()) print 'Downloading file:',os.path.join(remote_dir,f) sftp.get(os.path.join(remote_dir, f),os.path.join(local_dir, f))#下载 #sftp.put(os.path.join(local_dir, f),os.path.join(remote_dir, f))#上传 print 'Download file success %s ' % datetime.datetime.now() print '' print '##########################################' t.close() except Exception: print "connect error!"
注:本处的目录下所有文件进行下载或上传的示例中,在遇到目录下还有嵌套的目录存在时,会将目录也当做文件进行处理,所以如果想要更加的完美的话,可以通过引入stat模块下的S_ISDIR方法进行处理
五、pexpect
pexpect 是linux下expect的python封装,通过pexpect我们可以实现对ssh、ftp、password、telnet等命令进行自动交互,无需人工达到自动化需求。
项目地址:https://github.com/pexpect/pexpect
1、安装
pip install pexpect
2、登陆脚本
#!/usr/bin/env python # coding=utf-8 import pexpect username = 'root' ip = '139.199.228.59' child.interact()mypassword = '!@#)(*WGK1' child = pexpect.spawn('ssh {0}@{1}'.format(username, ip)) child.expect ('password:') child.sendline (mypassword) child.expect('$') child.sendline('sudo -s') child.expect (':') child.sendline (mypassword) child.expect('#') child.sendline('ls -la') child.expect('#') print child.before # Print the result of the ls command. child.interact() # Give control of the child to the user. child.close()
六、fabric
Fabric是基于python2.5及以上版本实现的SSH命令行工具,简化了SSH应用程序部署及系统管理任务,他提供了系统基础的操作组件,可以实现本地或远程shell命令,包括命令执行、文件上传、下载及完整执行日志输出等功能。Fabric在paramiko的基础上做更高一层的封装,操作起来更加简单。
官网地址:http://www.fabfile.org/
项目地址:https://github.com/fabric/fabric/
2.0 支持 python3
fab的常用参数
Usage: fab [options] <command>[:arg1,arg2=val2,host=foo,hosts='h1;h2',...] ...
- -l,显示定义好的任务函数名;
- -f,指定fab入口文件,默认入口文件名为fabfile.py
- -g,指定网关(中转)设备,比如堡垒机环境,填写堡垒机ip即可
- -H,指定目标主机,多台主机用“,”号分隔;
- -P,以异步并行方式运行多主机任务,默认为串行运行;
- -R,指定role,以角色名区分不同业务组设备;
- -t,设置设备连接超时时间(秒);
- -T,设置远程主机命令执行超时时间(秒);
- -w,当命令执行失败,发出告警,而非默认终止任务。
有时候我们可已不需要写一行python代码也可以完成远程操作,直接使用命令的形式,例如
fab -p 123456(密码) -H 192.168.1.21,192.168.1.22 -- 'uname -s'
1、fabric的环境变量
fabric的环境变量有很多,存放在一个字典中, fabric.state.env,而它包含在fabric.api中。 为了方便,我们一般使用env来指代环境变量。 env环境变量可以控制很多fabric的行为,一般通过env.xxx可以进行设置。
fabric默认使用本地用户通过ssh进行连接远程机器,不过你可以通过env.user变量进行覆盖。 当你进行ssh连接时,fabric会让你交互的让你输入远程机器密码,如果你设置了env.password变量,则就不需要交互的输入密码。 下面介绍一些常用的环境变量:
- abort_on_prompts 设置是否运行在交互模式下,例如会提示输入密码之类,默认是false
- connection_attempts fabric尝试连接到新服务器的次数,默认1次
- cwd 目前的工作目录,一般用来确定cd命令的上下文环境
- disable_known_hosts 默认是false,如果是true,则会跳过用户知道的hosts文件
- exclude_hosts 指定一个主机列表,在fab执行时,忽略列表中的机器
- fabfile 默认值是fabfile.py在fab命令执行时,会自动搜索这个文件执行。
- host_string 当fabric连接远程机器执行run、put时,设置的user/host/port等
- hosts 一个全局的host列表
- keepalive 默认0 设置ssh的keepalive
- loacl_user 一个只读的变量,包含了本地的系统用户,同user变量一样,但是user可以修改
- parallel 默认false,如果是true则会并行的执行所有的task
- pool_size 默认0 在使用parallel执行任务时设置的进程数
- password ssh远程连接时使用的密码,也可以是在使用sudo时使用的密码
- passwords 一个字典,可以为每一台机器设置一个密码,key是ip,value是密码
- path 在使用run/sudo/local执行命令时设置的$PATH环境变量
- port 设置主机的端口
- roledefs 一个字典,设置主机名到规则组的映射
- roles 一个全局的role列表
- shell 默认是/bin/bash -1 -c 在执行run命令时,默认的shell环境
- skip_bad_hosts 默认false,为ture时,会导致fab跳过无法连接的主机
- sudo_prefix 默认值”sudo -S -p ‘%(sudo_prompt)s’ “ % env 执行sudo命令时调用的sudo环境
- sudo_prompt 默认值”sudo password:”
- timeout 默认10 网络连接的超时时间
- user ssh使用哪个用户登录远程主机
- local 执行本地命令,如: local(‘uname -s’)
- lcd 切换本地目录,如: lcd(‘/home’)
- cd 切换远程目录,如: cd(‘/data/logs’)
- run 执行远程命令 如: run(‘free -m’)
- sudo sudo方式执行命令,如sudo(‘/etc/init.d/httpd start’)
- put 上传本地文件到远程主机,如put(‘/home/user.info’,/data/user.info’’)
- get 从远程主机下载文件到本地,如get(‘/home/user.info’,/data/user.info’’)
- prompt 获得用户输入信息,如: prompt(‘please input user:’)
- confirm 获得提示信息确认, 如: confirm(‘Tests failed. Continue[Y/N]?’)
- reboot 重启远程主机,如: reboot();
- @task 函数修饰符,标识的函数为fab可调用的,非标记对fab不可见,纯业务逻辑。
- @runs_once, 函数修饰符,标识的函数只会执行一次,不会受多台主机的影响。