zoukankan      html  css  js  c++  java
  • paramiko类Fabric主机管理

    环境:Linux python3.5

    要求:
    类 Fabric 主机管理程序开发:
    1. 运行程序列出主机组或者主机列表
    2. 选择指定主机或主机组
    3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)
    4. 充分使用多线程或多进程
    5. 不同主机的用户名密码、端口可以不同

    结构:
    bin-----|
    start.py ......启动目录,需配置主机列表
    core----|
    main.py ......主目录
    conf----|
    config.py ......配置目录
    system.ini ......配置文件
    file ......上传下载默认目录

    用法:
    先在system.ini中配置主机IP组
    选择主机IP,输入用户名密码,登陆
    选择需要执行命令或者传输文件
    传输文件默认目录为file目录

    bin:
    #!/usr/bin/env python
    # -*-coding:utf-8-*-
    # Author:zh
    import os
    import sys
    import threading
    PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(PATH)
    from core import main
    from conf import config
    
    if __name__ == '__main__':
        conf = config.Configuration()
        ip_list = eval(conf.get_config()[0][1])
        thread = threading.Thread(target=main.main, args=(ip_list,))
        thread.start()
    start.py

    core:

    #!/usr/bin/env python
    # -*-coding:utf-8-*-
    # Author:zh
    
    import paramiko
    import os
    PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+os.sep+"file"+os.sep
    
    
    class Fabric(object):
        '''这个类用来初始化SFTPClient和SSHClient'''
        def __init__(self, hostname, port, username, password):
            self.hostname = hostname
            self.port = port
            self.username = username
            self.password = password
            self.transport = paramiko.Transport((self.hostname, self.port))
            self.transport.connect(username=self.username, password=self.password)
    
        def command(self, cmd_input):
            # 执行命令
            ssh = paramiko.SSHClient()
            ssh._transport = self.transport
            stdin, stdout, stderr = ssh.exec_command(cmd_input)
            res, err = stdout.read(), stderr.read()
            result = res if res else err
            print(result.decode())
    
        def sftp(self, data):
            # 上传下载入口
            self.sftp = paramiko.SFTPClient.from_transport(self.transport)
            data_split = data.split()
            sign = data_split[0]
            if len(data_split) == 2:
                file_path = data_split[1]
                if file_path.rfind("/") == -1:
                    file_name = file_path
                else:
                    file_name = file_path[file_path.rfind("/")+1:]
                local_path = PATH+file_name
            elif len(data_split) == 3:
                if sign == "get":
                    local_path = data_split[2]
                    file_path = data_split[1]
                if sign == "put":
                    file_path = data_split[2]
                    local_path = data_split[1]
            else:
                local_path = ''
                file_path = ''
            if hasattr(self, sign):
                func = getattr(self, sign)
                try:
                    func(file_path, local_path)
                except Exception as e:
                    print("错误 %s" % e)
            else:
                print("输入错误")
                self.help()
    
        def get(self, *args):
            # 下载
            file_path = args[0]
            local_path = args[1]
            self.sftp.get(file_path, local_path)
    
        def put(self, *args):
            # 上传
            file_path = args[0]
            local_path = args[1]
            self.sftp.put(local_path, file_path)
    
        @staticmethod
        def help(self):
            # 展示帮助信息
            show = '''
            get path local_path ......从path下下载到本地目录
            put local_path path ......从本地上传到path目录下
            '''
            print(show)
    
        def close(self):
            # 关闭连接
            self.transport.close()
    
    
    def logon():
        # 登陆,输入端口,用户名,密码
        while True:
            port = input("请输入端口:")
            if not port:
                continue
            if not port.isdigit():
                print("请输入正确的端口")
                continue
            port = int(port)
            name = input("请输入用户名:")
            if not name:
                continue
            pwd = input("请输入密码:")
            if not pwd:
                continue
            return [port, name, pwd]
    
    
    def show(show_list):
        '''展示列表给用户选择,并返回选择信息'''
        while True:
            for value, comment in enumerate(show_list):
                print("%s. %s" % (value+1, comment))
            choose = input("请选择:")
            if not choose:
                continue
            if choose == "exit":
                exit()
            try:
                choose = int(choose)-1
                show_list[choose]
                return choose
            except (ValueError, IndexError) as e:
                print("输入错误:%s ,请重新输入" % e)
                continue
    
    
    def main(ip_list):
        # 主方法,程序入口
        ip_list = ip_list
        choose_ip = show(ip_list)
        value_list = logon()
        port = value_list[0]
        name = value_list[1]
        pwd = value_list[2]
        while True:
            action_list = ["执行命令", "上传下载"]
            choose_action = show(action_list)
            ssh = Fabric(ip_list[choose_ip], port, name, pwd)
            if choose_action == 0:
                func = ssh.command
            else:
                func = ssh.sftp
            while True:
                cmd_input = input("-->")
                if not cmd_input:
                    continue
                if cmd_input == 'b':
                    ssh.close()
                    break
                if cmd_input == 'exit':
                    exit()
                func(cmd_input)
    main.py

    conf:

    #!/usr/bin/env python
    # -*-coding:utf-8-*-
    # _author_=zh
    import os
    import configparser
    PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    class Configuration(object):
        def __init__(self):
            self.config = configparser.ConfigParser()
            self.name = PATH+os.sep+"conf"+os.sep+"system.ini"
    
        def init_config(self):
            # 初始化配置文件,ip :客户端IP,port:客户端端口
            if not os.path.exists(self.name):
                self.config["config"] = {"ip_list":['192.168.200.128', '192.168.200.129', '192.168.200.130']}
                self.config.write(open(self.name, "w", encoding="utf-8", ))
    
        def get_config(self, head="config"):
            '''
            获取配置文件数据
            :param head: 配置文件的section,默认取初始化文件config的数据
            :return:返回head中的所有数据(列表)
            '''
            self.init_config() # 取文件数据之前生成配置文件
            self.config.read(self.name, encoding="utf-8")
            if self.config.has_section(head):
                section=self.config.sections()
                return self.config.items(section[0])
    config.py


  • 相关阅读:
    FTP 协议和 HTTP 协议的比较
    HttpURLConnection的post请求,什么时候发出,writeData存在什么地方
    装饰器
    函数参数以及名称空间作用域
    函数的调用
    函数的返回值
    定义函数的三种方式
    函数
    day05
    day04
  • 原文地址:https://www.cnblogs.com/zh-20170913/p/8178534.html
Copyright © 2011-2022 走看看