zoukankan      html  css  js  c++  java
  • python3 实现堡垒机功能(并发执行命令及上传下载文件)

    转载请注明出处,欢迎提出宝贵意见,谢谢!

    功能介绍:

    1、主机分组
      登录后显示分组主机及主机数量
      选择主机组后显示该主机组下所有主机信息,主机名及IP
    显示输入选择:
    1、执行命令
    利用线程并发组内所有主机同时执行命令,并将结果,返回
    格式为:
    ----------------------host1------------------

    ----------------------host2------------------

    ----------------------host3------------------

    ----------------------host4------------------

    2、传输文件

    主函数:

    #Author by Guangboli
    #_*_ coding:utf-8 _*_
    
    import configparser,threading,paramiko,time,os,sys
    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(base_dir)
    from core import Color_set
    color = Color_set.Colorset()
    cf = configparser.ConfigParser()
    cf.read('config',encoding='utf-8')
    secs = cf.sections()
    def get_group_info():
        '''获取主机组信息'''
        print("主机组列表:")
        for i in secs:
            opts = cf.options(i)
            quantity = int(len(opts) / 4)
            print(i,'[%s]'%quantity)
    def get_host_ip_list(group_name,quantity):
        '''获取主机ip列表信息'''
        i = 1
        while i <= quantity:
            print(cf.get(group_name,'ip%s'%i))
            i+=1
    def cmd_run(ip,username,password,cmd):
    
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect(hostname=ip, port=22, username=username, password=password)
            stdin, stdout, stderr = ssh.exec_command(cmd)  # 执行命令,不可执行类似vim,top watch命令
            result = stdout.read().decode()  # 获取结果
            tips = color.red('- - - - - %s - - - - - - '.center(20) % ip)
            print(tips)
            print(result,stderr.read().decode())
        except Exception as e:
            print('%s 主机发生异常:'%ip,e)
        ssh.close()
    def transport_put_file(ip,username,password,cmd):
        try:
            transport = paramiko.Transport((ip, 22))
            transport.connect(username=username, password=password)
            sftp = paramiko.SFTPClient.from_transport(transport)
            sftp.put(local_file,remote_dir+'/'+put_filename)
        except Exception as e:
            print(print('%s 主机发生异常:'%ip,e))
        transport.close()
    def transport_get_file(ip,username,password,cmd):
        transport = paramiko.Transport((ip, 22))
        try:
            transport.connect(username=username, password=password)
            sftp = paramiko.SFTPClient.from_transport(transport)
            sftp.get(remote_file,local_dir+'\'+ip+'-'+get_filename)    #Linux 需要将\改为/
        except Exception as e:
            print(print('%s 主机发生异常:'%ip,e))
        transport.close()
    def make_treading(func,quantity,group_name,cmd):
        i = 1
        while i <= quantity:
            ip = cf.get(group_name, 'ip%s' % i)
            username = cf.get(group_name, 'username%s' % i)
            password = cf.get(group_name, 'password%s' % i)
            thread = threading.Thread(target=func,args=(ip,username,password,cmd))
            thread.setDaemon(True)
            thread.start()
            i+=1
    def welcome():
        '''show group and host ip information '''
        get_group_info()
        global opts,quantity,group_name
        while True:
            group_name = input('请输入组名(退出请按q or Q):').strip().upper()
            if group_name == 'Q':
                print('欢迎再次使用,谢谢....')
                exit()
            elif group_name not in secs:
                print("Wrong input,please confirm!")
            else:
                break
        print(group_name,'组下的主机:')
        opts = cf.options(group_name)
        quantity = int(len(opts) / 4)       #hosts quantity
        get_host_ip_list(group_name,quantity)
    def menu_line2():
        global local_dir,local_file,remote_file,remote_dir,get_filename,put_filename
        print('''usage:
              上传文件:put 本地文件 远程目录
              下载文件:get 远程文件 本地目录
              退出输入q or Q
              examples:
              put test.txt /tmp
              get /tmp/test.txt /data
              ''')
        while True:
            cmd = input("请输入操作:").strip()
            args = cmd.split()
            if cmd == 'q' or cmd == 'Q':
                menu_line1()
    
            elif len(args) != 3:
                print("输入有误,请重新输入!")
                menu_line2()
            else:
                if args[0] == 'put':
                    local_file = args[1]
                    put_filename=args[1].split('/')[-1]
                    remote_dir = args[2]
                    func = transport_put_file
                    make_treading(func, quantity, group_name, cmd)
                    while threading.active_count() != 1:
                        time.sleep(0.1)
                    else:
                        continue
                elif args[0] == 'get':
                    remote_file = args[1]
                    get_filename = args[1].split('/')[-1]
                    local_dir = args[2]
                    func = transport_get_file
                    make_treading(func, quantity, group_name, cmd)
                    while threading.active_count() != 1:
                        time.sleep(0.1)
                    else:
                        continue
                else:
                    print("输入格式有误,请重新输入!")
                    menu_line2()
    def menu_line1():
        '''commadns menu'''
        func = cmd_run
        while True:
            print('1、执行命令
    2、传输文件
    ')
            choice = input("请选择操作:").strip()
            if choice == '1':
                cmd = input("请输入命令:").strip()
                print('%s 命令执行结果如下:' % cmd)
                make_treading(func,quantity,group_name,cmd)
                while threading.active_count() != 1:
                    # print(threading.active_count())
                    time.sleep(0.1)
                else:
                    continue
            elif choice == '2':
                menu_line2()
            elif choice == 'q' or choice == 'Q':
                welcome()
            else:
                continue
    def run():
        '''
        main function 
        '''
        print('welcome.....')
        welcome()
        menu_line1()
    
    if __name__ == '__main__':
        run()
    View Code

    config文件:

    [GROUP1]
    host1 = host1
    ip1 = 10.1.2.3
    username1 = root
    password1 = 123456
    host2 = host2
    ip2 = 10.1.2.2
    username2 = user1
    password2 = 123456
    host3 = host3
    ip3 = 10.1.2.7
    username3 = user2
    password3 = 123456
    
    
    
    [GROUP2]
    host1 = host1
    ip1 = 10.1.2.1
    username1 = root
    password1 = 123456
    host2 = host2
    ip2 = 10.1.2.2
    username2 = root
    password2 = 123456
    host3 = host3
    ip3 = 10.1.2.3
    username3 = root
    password3 = 123456
    
    
    [GROUP3]
    host1 = host1
    ip1 = 10.1.2.1
    username1 = root
    password1 = 123456
    host2 = host2
    ip2 = 10.1.2.2
    username2 = root
    password2 = 123456
    host3 = host3
    ip3 = 10.1.2.3
    username3 = root
    password3 = 123456
    host4 = host4
    ip4 = 10.1.2.4
    username4 = root
    password4 = 123456
    host5 = host5
    ip5 = 10.1.2.5
    username5 = root
    password5 = 123456
    
    
    [GROUP4]
    host1 = host1
    ip1 = 10.1.2.1
    username1 = root
    password1 = 123456
    host2 = host2
    ip2 = 10.1.2.2
    username2 = root
    password2 = 123456
    host3 = host3
    ip3 = 10.1.2.3
    username3 = root
    password3 = 123456
    host4 = host4
    ip4 = 10.1.2.4
    username4 = root
    password4 = 123456
    host5 = host5
    ip5 = 10.1.2.5
    username5 = root
    password5 = 123456
    host6 = host6
    ip6 = 10.1.2.6
    username6 = root
    password6 = 123456
    host7 = host7
    ip7 = 10.1.2.7
    username7 = root
    password7 = 123456
    View Code

    目录结果:

  • 相关阅读:
    Django学习(二) Django框架简单搭建
    Django学习(一) Django安装配置
    Python学习(一) Python安装配置
    注册第一天,纪念一下
    小程序笔记
    详解HTML5中的进度条progress元素简介及兼容性处理
    服务管理
    yum
    管道,输出,管道,重定向,grep
    VIM
  • 原文地址:https://www.cnblogs.com/pythonstudy/p/6636790.html
Copyright © 2011-2022 走看看