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

    目录结果:

  • 相关阅读:
    leetcode 48. Rotate Image
    leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点) 、26/80. Remove Duplicates from Sorted ArrayI、II
    leetcode 263. Ugly Number 、264. Ugly Number II 、313. Super Ugly Number 、204. Count Primes
    leetcode 58. Length of Last Word
    安卓操作的一些问题解决
    leetcode 378. Kth Smallest Element in a Sorted Matrix
    android studio Gradle Build速度加快方法
    禁用gridview,listview回弹或下拉悬停
    Android Studio找不到FragmentActivity类
    安卓获取ListView、GridView等滚动的距离(高度)
  • 原文地址:https://www.cnblogs.com/pythonstudy/p/6636790.html
Copyright © 2011-2022 走看看