zoukankan      html  css  js  c++  java
  • 简说python之批量操作主机

    目前,很多的工作都是批量的操作Linux主机。通过python脚本,封装Linux的shell命令。保证批量操作,简易优化工作。

    Python批量操作主机

    安装paramiko模块

    ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography)。有了Paramiko以后,我们就可以在Python代码中直接使用SSH协议对远程服务器执行操作,而不是通过ssh命令对远程服务器进行操作。

    由于paramiko属于第三方库,安装方式如下:

    G:Py>pip install paramiko
    

    远程ssh控制主机

    import paramiko
    from concurrent.futures import ThreadPoolExecutor
     
    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 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 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()
     
    
    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:
                    print(err)
            future.shutdown(wait=True)
     
        def callback(self, future_obj):
            """回调函数,处理返回结果"""
            ssh_obj, rlist = future_obj.result()
            print("{} execute detail:".format(ssh_obj.h))
            is_success = True
            for item in rlist:
                cmd, [code, res] = item
                info = f"{cmd} | code => {code}
    Result:
    {res}"
                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(i)
            print("-" * 30)
            for j in self.failed_hosts:
                print(j)
            info = "Success hosts {}; Failed hosts {}."
            s, f = len(self.success_hosts), len(self.failed_hosts)
            info = info.format(s, f)
            print(info)
            
    if __name__ == '__main__':
    #   测试环境
        ip_204 = SSHParamiko("172.17.xx.204", 22, "root", "xx")
        ip_200 = SSHParamiko("172.17.xx.200", 22, "root", "xx")
        ip_202 = SSHParamiko("172.17.xx.202", 22, "root", "xx")
    #   种子环境
        ip_200_30 = SSHParamiko("172.30.xx.30", 9900, "root", "xx")
        cmds =["df -h"]
    #    all_ip = AllRun([ip_204, ip_200,ip_202], cmds)
        seed_ip = AllRun([ip_200_30], cmds)
        seed_ip.concurrent_run()
        seed_ip.overview()
        print("--------------------------------------------------------------")
        res = ip_200_30.run_cmd("df -h")
        print(res[0])
        print(res[1])  
    

    另存为batch01.py,执行结果如下:

    G:Py>python batch01.py
    172.30.200.30 execute detail:
    df -h | code => 0
    Result:
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/sda3        30G  3.4G   25G  13% /
    tmpfs           7.8G     0  7.8G   0% /dev/shm
    /dev/sda1       190M   52M  129M  29% /boot
    /dev/sdb1       197G   20G  168G  11% /opt
    
    172.30.200.30
    ------------------------------
    Success hosts 1; Failed hosts 0.
    --------------------------------------------------------------
    0
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/sda3        30G  3.4G   25G  13% /
    tmpfs           7.8G     0  7.8G   0% /dev/shm
    /dev/sda1       190M   52M  129M  29% /boot
    /dev/sdb1       197G   20G  168G  11% /opt
    
    
  • 相关阅读:
    面向对象实验 ——(二)类与对象
    [LeetCode] 957. Prison Cells After N Days
    [LeetCode] 32. Longest Valid Parentheses
    [LeetCode] 120. Triangle
    [LeetCode] 441. Arranging Coins
    [LeetCode] 79. Word Search
    [LeetCode] 1143. Longest Common Subsequence
    [LeetCode] 718. Maximum Length of Repeated Subarray
    [LeetCode] 332. Reconstruct Itinerary
    [LeetCode] 279. Perfect Squares
  • 原文地址:https://www.cnblogs.com/zhangshengdong/p/12497823.html
Copyright © 2011-2022 走看看