多主機控制與遠程命令執行

Mabaxterm

mobaxterm

python SSH

import paramiko
import getpass  # getpass是隱藏密碼
import time
# import _thread
import threading
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--H', type=str, help='host ID [1,2,3,4,5]')
parser.add_argument('--cmd', type=str,
                    default='echo \"Hello\"', help='executing your command')
args = parser.parse_args()
print(args.cmd)
print(args.H)



host = {
    'host_name_1': {"host_name": "host_name_1", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_2': {"host_name": "host_name_2", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_3': {"host_name": "host_name_3", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_4': {"host_name": "host_name_4", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_5': {"host_name": "host_name_5", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_6': {"host_name": "host_name_6", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_7': {"host_name": "host_name_7", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_8': {"host_name": "host_name_8", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_9': {"host_name": "host_name_9", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_10': {"host_name": "host_name_10", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_11': {"host_name": "host_name_11", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_12': {"host_name": "host_name_12", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_13': {"host_name": "host_name_13", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_14': {"host_name": "host_name_14", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_15': {"host_name": "host_name_15", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
    'host_name_16': {"host_name": "host_name_16", "ip": "XXX.XXX.XXX.XXX", "port": "22", "user_name": "user_name", "password": " "},
}


class Channel(object):
    def __init__(self, ctx):
        self._ctx = ctx
        self._ssh_channel = None
        self._thread_group = None

        self._ret_data = None
        self._ret_error = None

        print("Connecting to: ", ctx['ip'], end='')
        self._ssh_channel = self.create_channel(self._ctx)
        print(" [Successful]")

    def create_channel(self, ctx):
        ip = ctx['ip']
        port = ctx['port']
        user_name = ctx['user_name']
        password = ctx['password']
        # password = getpass.getpass("Your password: ")
        # SSH遠程連接
        ssh = paramiko.SSHClient()  # 創建sshclient
        # 指定當對方主機沒有本機公鑰的情況時應該怎麼辦,AutoAddPolicy表示自動在對方主機保存下本機的祕鑰
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(ip, port, user_name, password)
        return ssh

    def execute_command(self, cmd):

        # 執行命令並獲取執行結果
        stdin, stdout, stderr = self._ssh_channel.exec_command(cmd)
        out = stdout.readlines()
        err = stderr.readlines()
        # for each_out in out:
        #     print(each_out, end='')
        # print(''.join(out), end='')  # , ''.join(err))
        self._ret_data = ''.join(out)
        self._ret_error = ''.join(err)
        return cmd
        pass

    def submit_command_async(self, cmd):
        print("Submitting to [{}]: {}".format(self._ctx['host_name'], cmd))
        try:
            self._thread_group = threading.Thread(
                target=self.execute_command, args=(cmd,))
            self._thread_group.start()
        except:
            print("Error: cannot launching threads")
            exit(0)
        pass

    def query_command_async(self):
        self._thread_group.join()

        self._thread_group = None
        return self._ret_data, self._ret_error
        pass

    def close_channel(self):
        self._ssh_channel.close()
        print("Channel to {}:{} has been Closed".format(
            self._ctx['host_name'], self._ctx['ip']))


class ConnectorManager(object):
    def __init__(self):
        self.ssh_mgr = []
        self.results = {}
        self.host_groups = []

        self.connecting()
        pass

    def connecting(self, host_index=None):
        if host_index is None:
            host_index = [x for x in range(1, 16 + 1)]
        print(host_index)
        print("---------------connections setup-----------------------")
        for index in range(1, 16+1):
            host_name = "g" + str(index)
            self.ssh_mgr.append(Channel(host[host_name]))
            self.host_groups.append(host_name)
        print("------------connections established-------------------")

    def closing(self):
        print("------------closing connections-------------------")
        for each_ssh in self.ssh_mgr:
            each_ssh.close_channel()
        print("-------------connections closed-------------------")

    def executing(self, cmds):
        for each_cmd in cmds:
            print("Executing: ", each_cmd)
            for each_ssh in self.ssh_mgr:
                each_ssh.submit_command_async(each_cmd)
            self.syncing()
            # time.sleep(1)

    def testing(self, cmds=None):
        # self.connecting()
        print("------------testing-------------------")
        if cmds is None:
            cmds = ['cat /etc/hostname', 'cd /home',
                    'python -c \"print(\'hello\')\"', 'aaa']

        self.executing(cmds)
        print("----------testing done----------------")

    def syncing(self):
        self.data = []
        self.errors = []
        for each_ssh, host_name in zip(self.ssh_mgr, self.host_groups):
            ret_data, ret_error = each_ssh.query_command_async()
            self.data.append('[from: '+host_name+']: ' +
                             (ret_data if len(ret_data) > 0 else '\n'))
            self.errors.append(ret_error)
            if len(''.join(ret_error)) != 0:
                print("[Error from {}]: {}".format(
                    host_name, ret_error), end='')
        print("----------syncing done----------------")
        for each_ret in self.data:
            print(each_ret, end='')


if __name__ == '__main__':
    test = ConnectorManager()
    test.testing(['echo "I am OK"'])
    test.closing()

發佈了108 篇原創文章 · 獲贊 95 · 訪問量 125萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章