有很多开源自动化运维工具都很好用如ansible/salt stack等,完全不用重复造轮子。只不过,很多运维同学学习Python之后,苦于没小项目训练,本篇演示用Python写一个批量操作主机的工具,大家空余时候可以试着写写,完善完善。

1 思路分析

在运维工作中,古老的方式部署环境、上线代码可能都需要手动在服务器上敲命令,不胜其烦。所以,脚本,自动化工具等还是很有必要的。我觉得一个批量操作工具应该考虑以下几点:

(1)本质上,就是到远程主机上执行命令并返回结果。

(2)做到批量。也就是要并发对多台机器进行操作。

(3)将返回的结果,清晰地展示给用户。

通常开源的主机批量管理工具有两类,一类是有agent,如SaltStack、Puppet等;另一类是无agent如ansible。虽然我们没必要重复造轮子,但是可以试着写一写,一是加深对这类软件原理的理解,二是练习Python。建议如果服务器规模在1000台以内的用无agent的方式也能hold住;如果超过1000台,用有agent的会好太多。

接下来我们一起看看怎么具体实现。

2 到远程机器上执行命令

到远程机器上执行命令,并返回结果,至少有两种方式:一是用paramiko模块;而是可以建立机器互信,从中控执行ssh命令。

下面我把自己封装好的代码贴一下,是基于paramiko模块封装的,ssh的大家可以自己实现:

import paramiko

class SSHParamiko(object):

err = "argument passwd or rsafile can not be None"

def __init__(self, host, port, user, passwd=None, rsafile=None):

self.h = host

self.p = port

self.u = user

self.w = passwd

self.rsa = rsafile

def _connect(self):

if self.w:

return self.pwd_connect()

elif self.rsa:

return self.rsa_connect()

else:

raise ConnectionError(self.err)

def _transfer(self):

if self.w:

return self.pwd_transfer()

elif self.rsa:

return self.rsa_transfer()

else:

raise ConnectionError(self.err)

def pwd_connect(self):

conn = paramiko.SSHClient()

conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())

conn.connect(self.h, self.p, self.u, self.w)

return conn

def rsa_connect(self):

pkey = paramiko.RSAKey.from_private_key_file(self.rsa)

conn = paramiko.SSHClient()

conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())

conn.connect(hostname=self.h, port=self.p, username=self.u, pkey=pkey)

return conn

def pwd_transfer(self):

transport = paramiko.Transport(self.h, self.p)

transport.connect(username=self.u, password=self.w)

sftp = paramiko.SFTPClient.from_transport(transport)

return sftp, transport

def rsa_transfer(self):

pkey = paramiko.RSAKey.from_private_key_file(self.rsa)

transport = paramiko.Transport(self.h, self.p)

transport.connect(username=self.u, pkey=pkey)

sftp = paramiko.SFTPClient.from_transport(transport)

return sftp, transport

def run_cmd(self, cmd):

conn = self._connect()

stdin, stdout, stderr = conn.exec_command(cmd)

code = stdout.channel.recv_exit_status()

stdout, stderr = stdout.read(), stderr.read()

conn.close()

if not stderr:

return code, stdout.decode()

else:

return code, stderr.decode()

def get_file(self, remote, local):

sftp, conn = self._transfer()

sftp.get(remote, local)

conn.close()

def put_file(self, local, remote):

sftp, conn = self._transfer()

sftp.put(local, remote)

conn.close()

当然,代码还可以重构一下哈。接下来我们看下效果:

if __name__ == ‘__main__‘:

h = "我的测试机IP"

p = 22

u = "我的用户名"

w = "我的密码"

obj = SSHParamiko(h, p, u, w)

r = obj.run_cmd("df -h")

print(r[0])

print(r[1])

执行之后的结果是:

0

Filesystem Size Used Avail Use% Mounted on

/dev/vda1 40G 3.4G 34G 9% /

devtmpfs 3.9G 0 3.9G 0% /dev

tmpfs 3.9G 0 3.9G 0% /dev/shm

tmpfs 3.9G 410M 3.5G 11% /run

tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup

/dev/vdb 300G 12G 289G 4% /search/odin

tmpfs 783M 0 783M 0% /run/user/0

tmpfs 783M 0 783M 0% /run/user/1000

可以清晰看到第一行是命令执行的状态码,0表示成功,非0表示失败;第二行开始就是我们的命令返回结果。是不是比较清晰呢?

3 并发执行并展示输出结果

并发执行通常用Python3自带的线程模块就行,这里我用的from concurrent.futures import ThreadPoolExecutor。并且当拿到结果之后,我还做了一些格式化输出,比如绿色输出表示成功,红色输出表示命令执行失败,黄色表示提醒等。废话不多说,直接看代码吧!

from concurrent.futures import ThreadPoolExecutor

class AllRun(object):

def __init__(self, ssh_objs, cmds, max_worker=50):

self.objs = [o for o in ssh_objs]

self.cmds = [c for c in cmds]

self.max_worker = max_worker # 最大并发线程数

self.success_hosts = [] # 存放成功机器数目

self.failed_hosts = [] # 存放失败的机器IP

self.mode = None

self.func = None

def serial_exec(self, obj):

"""单台机器上串行执行命令,并返回结果至字典"""

result = list()

for c in self.cmds:

r = obj.run_cmd(c)

result.append([c, r])

return obj, result

def concurrent_run(self):

"""并发执行"""

future = ThreadPoolExecutor(self.max_worker)

for obj in self.objs:

try:

future.submit(self.serial_exec, obj).add_done_callback(self.callback)

except Exception as err:

err = self.color_str(err, "red")

print(err)

future.shutdown(wait=True)

def callback(self, future_obj):

"""回调函数,处理返回结果"""

ssh_obj, rlist = future_obj.result()

print(self.color_str("{} execute detail:".format(ssh_obj.h), "yellow"))

is_success = True

for item in rlist:

cmd, [code, res] = item

info = f"{cmd} | code => {code}\nResult:\n{res}"

if code != 0:

info = self.color_str(info, "red")

is_success = False

if ssh_obj.h not in self.failed_hosts:

self.failed_hosts.append(ssh_obj.h)

else:

info = self.color_str(info, "green")

print(info)

if is_success:

self.success_hosts.append(ssh_obj.h)

if ssh_obj.h in self.failed_hosts:

self.failed_hosts.remove(ssh_obj.h)

def overview(self):

"""展示总的执行结果"""

for i in self.success_hosts:

print(self.color_str(i, "green"))

print("-" * 30)

for j in self.failed_hosts:

print(self.color_str(j, "red"))

info = "Success hosts {}; Failed hosts {}."

s, f = len(self.success_hosts), len(self.failed_hosts)

info = self.color_str(info.format(s, f), "yellow")

print(info)

@staticmethod

def color_str(old, color=None):

"""给字符串添加颜色"""

if color == "red":

new = "\033[31;1m{}\033[0m".format(old)

elif color == "yellow":

new = "\033[33;1m{}\033[0m".format(old)

elif color == "blue":

new = "\033[34;1m{}\033[0m".format(old)

elif color == "green":

new = "\033[36;1m{}\033[0m".format(old)

else:

new = old

return new

if __name__ == ‘__main__‘:

h1 = "adime01.shouji.sjs.ted"

p1 = 22

u1 = "odin"

w1 = "*****"

h = "10.129.206.97"

p = 22

u = "root"

w = "*****"

obj1 = SSHParamiko(h1, p1, u1, w1)

obj = SSHParamiko(h, p, u, w)

cmds = ["df -h", "ls"]

all_obj = AllRun([obj1, obj], cmds)

all_obj.concurrent_run()

all_obj.overview()

上述代码运行的结果:

从执行结果来看,高亮显示,清新明了。既显示了各个主机的各个命令执行状态码,返回结果,最后还汇总结果,成功了多少台机器和失败了多少台机器。

我们还可以换一下执行的命令,让命令执行失败看看:

后期还可以包装一下,将主机、密码、批量执行的命令写在配置文件中;或再根据需要包装成命令行工具,在日常运维工作中可以适当减少人肉敲命令的繁琐。

原文地址:https://www.cnblogs.com/zingp/p/8930320.html

python开发web运维工具_【实战小项目】python开发自动化运维工具--批量操作主机...相关推荐

  1. ebs开发入门 oracle 知乎_微信小程序云开发入门第一篇---开发准备事项

    在开始本文的正式内容之前,先允许我做一个简单的自我介绍,我是一名嵌入式软件开发人员,目前在一家音视频处理芯片公司做linux系统下音视频开发的相关工作,算是嵌入式软件开发行业的老人了,如果您对嵌入式行 ...

  2. python界面如何设置成黑色_实战!在Python中制作精美的图形用户界面

    在默认情况下,我们使用PyQt5创建出来的窗口和部件都是自带的默认样式,虽然谈不上很丑,但是也毫无美感可言.其实,在PyQt5中,我们可以有较高的自由度来自定义窗口和各种小部件的样式,通过自定义这些样 ...

  3. 实战小项目 | Python制作词云跳舞,刘畊宏男孩女孩看过来~

    大家好,我是王某人 最近刘教练真的很火,带领全民健身,很多人成为了刘教练的男孩.女孩! 本文是一个非常完整的Python实战项目,从一个刘教练的健身视频出发,最终生成了一个基于B站用户弹幕的词云舞视频 ...

  4. python客户端软件开发_妙小程python客户端

    妙小程python客户端官方版是一款由妙小程开发的学习Python课程的学习软件,妙小程python客户端最新版软件拥有丰富代码库,编程更加酷炫,妙小程python客户端集有趣.高科技.有温度于一身, ...

  5. python操作微信小程序云端数据库_微信小程序·云开发云数据库的基本使用-微信小程序云开发实例-腾讯云微信小程序...

    微信小程序·云开发云数据库的基本使用-微信小程序云开发实例-腾讯云微信小程序 浏览量:1120 时间:2020-04-06

  6. 游戏运维的最佳实践:搜狐畅游自动化运维之旅

    本文讲的是游戏运维的最佳实践:搜狐畅游自动化运维之旅[编者的话]本文作者见证了畅游游戏自动化运维平台的从无到有,通过在其中踩过的坑.解过的结,他向大家来阐述游戏运维的进阶之路.本文主要围绕畅游游戏管理 ...

  7. 我用Python把抖音上的美女图片转字符画,期望的AI目标更进一步【机器学习算法实战小项目,k聚类算法图片转化字符画】

    大家好,我是辣条. 最近在学习算法,今天给大家带来一个机器学习实战小项目 项目效果展示 学习目标 1.cv2转换图片数据  2.numpy提取图片矩阵数据  3.k均值算法获取图片的分类 工具使用 开 ...

  8. 【敬初学者】Python基础学完了,该怎么知道自己学的怎么样呢?十个经典实战小项目附源码

    前言 1.街霸游戏 1.1 KO街霸 程序完整源码 程序的输出界面 1.2 春丽VS巴洛克 参考源码 2.猜谜游戏 2.1简单的猜数字游戏 项目要求 参考源码 2.2 进阶的猜姓名游戏 项目要求 参考 ...

  9. 小程序确定取消弹窗_微信小程序定制开发价格确定条件?

    点击上方"蓝字"关注我们! 小程序做为变现微信流量的重要载体,已经成为了越来越多商家变现微信流量的主要方式,而在制作相应小程序的时候,我们知道是需要支付相应费用的,而开发费用也是有 ...

  10. 限时团购,6.9折:《微信开发深度解析:公众号、小程序高效开发秘籍》推荐序

    全书由目 Senparc.Weixin SDK 作者苏震巍历时 2 年完成,涵盖了开发微信公众号及小程序需要用的的各项后端开发技能.技巧.避坑提示,以及 Senparc.Weixin SDK 微信公众 ...

最新文章

  1. 用python查询数据库_用python 做数据库查询
  2. NYOJ 56 阶乘因式分解(一)
  3. Bob的烦恼II 逃离迷宫
  4. angular cli 切换 css_漫谈 Angular 定制主题的四种方式
  5. 科研地图来了,看看你的研究领域在哪里!中国科学院科技战略咨询研究院发布《科学结构图谱2021》
  6. C语言实现臭皮匠排序stooge sort 算法(附完整源码)
  7. [前台]---js+jquery校验姓名,手机号,身份证号
  8. linux防火墙允许dns服务,Linux防火墙设置-DNS服务器篇
  9. IDEA MySql之增删改查
  10. AVAudioSession
  11. JMS学习四(ActiveMQ消息过滤)
  12. 大V诞生记 —— 谁是VMware?
  13. 这有一个机器人,粉刷本领强
  14. WhoIsOnline ;) - 解读CNForum源码中在线用户统计
  15. 20. Window moveBy() 方法
  16. 琪歌实验2:Wireshark 实验
  17. RFC791:INTERNET PROTOCOL网络协议
  18. 云计算机房架构图,云计算架构技术与实践
  19. 发力“智能马桶”的小米们,选对了目标群体吗?
  20. 趣图 | 程序员的白天 vs 夜晚?

热门文章

  1. 伤害世界怎么自建服务器,Hurtworld伤害世界服务器怎么架设?服务器架设图文教程...
  2. 盘启动盘_[装机]推荐唯二的两个开源免费的启动盘工具,轻松创建USB启动盘
  3. Vue的组件为什么要export default
  4. jstack-查看Java进程的线程堆栈信息,锁定高消耗资源代码
  5. linux中通常使用 键来终止命令运行,【单选题】Linux中通常使用( )键来终止命令运行A. Ctrl+c B. Ctrl+d C. Ctrl+k D. Ctrl+f...
  6. mysql 3列索引_mysql多列索引
  7. idea提交git差件_多人合作使用git,推送代码、和并分支
  8. php的filter input,记一个php://filter和php://input的CTF题
  9. 各种门锁的内部结构图_双核CUP,电镀真金把手,0.3秒开锁,欧瑞博智能门锁S2评测...
  10. git fetch -p 获取远程仓库的新分支以及删除远程仓库已删除的分支