def install_process(plugin_name, host_info, packages): """ 子进程执行安装 :return: """ ssh = MySSH(host=host_info["local_ip"], port=host_info["port"], username=host_info["username"], password=host_info["password"]) if ssh: result = [] venv = ". {}/bin/activate && ".format( get_config("py_venv", "VENV_PATH")) for package in packages: cmd = "{}pip install -U {}".format(venv, package) stdin, stdout, stderr = ssh.exec_cmd(cmd) for line in stdout.read().decode().split("\n"): if re.search(r"\s*Successfully\s+installed.*", line): result.append(line) ssh.close() packages = " ".join(packages) mdbs["sys"].init_app(reinit=True) plugin = mdbs["sys"].db.plugin.find_one({"plugin_name": plugin_name}, { "require_package_install_result": 1}) if "require_package_install_result" in plugin and plugin["require_package_install_result"]: updated = False for old_result in plugin["require_package_install_result"]: if old_result["host_ip"] == host_info["local_ip"]: old_result["packages"] = packages if result: old_result["result"] = result old_result["time"] = time.time() old_result["error"] = None updated = True break if not updated: result = { "host_ip": host_info["local_ip"], "packages": packages, "error": None, "time": time.time() } if result: result["result"] = result plugin["require_package_install_result"].append(result) else: plugin["require_package_install_result"] = [{ "host_ip": host_info["local_ip"], "packages":packages, "result":result, "error": None, "time":time.time() } ] mdbs["sys"].db.plugin.update_one({"plugin_name": plugin_name}, {"$set": { "require_package_install_result": plugin["require_package_install_result"]}})
def sys_host_exec_cmd(): ip = request.argget.all('host_ip') host = mdb_sys.db.sys_host.find_one({"host_info.local_ip": ip}) exec_cmd = request.argget.all('cmd', "") if host: host_info = host["host_info"] s, v = audit_host_info(host_info) if not s: return v else: try: ssh = MySSH(host=ip, port=host_info["port"], username=host_info["username"], password=host_info["password"]) except BaseException as e: data = { "msg": gettext("[{}] {}").format(ip, str(e)), "msg_type": "e", "http_status": 400 } return data if not ssh: data = { "msg": gettext( "Connection host[{}] failed,Check the host Settings"). format(ip), "msg_type": "e", "http_status": 400 } return data result = [] if not exec_cmd and "cmd" in host: exec_cmd = host["cmd"] for cmd in exec_cmd.split("\n"): cmd = cmd.strip() if re.search(r"^#.*", cmd): continue if re.search(r"^sudo\s*.*", cmd) or re.search( r".*\s+sudo\s+.*", cmd): result.append( [gettext('[Warning]: "sudo" command go to the server')]) elif re.search(r"^rm\s+.*", cmd) or re.search( r".*\s+rm\s+.*", cmd): result.append( [gettext('[Warning]: "rm" command go to the server')]) else: stdin, stdout, stderr = ssh.exec_cmd("nohup {} &".format(cmd)) result.append(stdout.read().decode().split("\n")) ssh.close() data = { "msg": gettext("Command executed {}").format(ip), "msg_type": "s", "http_status": 201, "result": result, "cmd": exec_cmd } else: data = { "msg": gettext("There is no host {}").format(ip), "msg_type": "e", "http_status": 400 } return data
def sys_log(): name = request.argget.all('name') ip = request.argget.all('ip') page = int(request.argget.all('page', 1)) host = mdbs["sys"].db.sys_host.find_one({"host_info.local_ip": ip}) if host: host_info = host["host_info"] s, v = audit_host_info(host_info) if not s: return v else: ssh = MySSH(ip, port=host_info["port"], username=host_info["username"], password=host_info["password"]) if not ssh: data = { "msg": gettext( "Connection host[{}] failed,Check the host Settings"). format(ip), "msg_type": "e", "custom_status": 400 } return data sftp = ssh.client.open_sftp() remote_file = "{}/logs/{}".format(PROJECT_PATH, name) local_temp_log_dir = '{}/logs/remote_file'.format(PROJECT_PATH) if not os.path.exists(local_temp_log_dir): os.makedirs(local_temp_log_dir) local_file = '{}/{}_{}'.format(local_temp_log_dir, ip, name) sftp.get(remote_file, local_file) ssh.close() pre = 50 rf = open(local_file) count = 0 while True: buffer = rf.read(8192 * 1024) if not buffer: break count += buffer.count('\n') rf.close() logs = [] n = 1 with open(local_file) as f: for line in f: if n > (page - 1) * pre: logs.append(line) if n >= page * pre: break n += 1 f.close() logs = datas_paging(pre=pre, page_num=page, data_cnt=count, datas=logs) logs["datas"] = "".join(logs["datas"]) logs["datas"] = logs["datas"].replace("\n", "<br>") data = {"logs": logs} os.remove(local_file) else: data = { "msg": gettext("There is no host {}").format(ip), "msg_type": "e", "custom_status": 400 } return data
def install_require_package(): ''' 安装插件需要的其他python 包 :return: ''' plugin_name = request.argget.all('plugin_name') s, r = arg_verify(reqargs=[("plugin name", plugin_name)], required=True) if not s: return r plugin_req_file_path = "{}/requirements.txt".format( os.path.join(PLUG_IN_FOLDER, plugin_name)) if not os.path.exists(plugin_req_file_path): data = { "msg": gettext("There is no requirement file"), "msg_type": "e", "http_status": 400 } return data with open(plugin_req_file_path) as rf: new_reqs = rf.read().split() hosts = mdb_sys.db.sys_host.find({"host_info.local_ip": {"$exists": True}}) connection_failed = [] for host in hosts: host_info = host["host_info"] s, v = audit_host_info(host_info) if not s: connection_failed.append({ "host_ip": host_info["local_ip"], "error": r }) continue else: try: ssh = MySSH(host=host_info["local_ip"], port=host_info["port"], username=host_info["username"], password=host_info["password"]) except BaseException as e: connection_failed.append({ "host_ip": host_info["local_ip"], "error": str(e) }) continue if not ssh: connection_failed.append({ "host_ip": host_info["local_ip"], "error": "Failed to connect to server host" }) continue ssh.close() install_process(plugin_name, host_info, new_reqs) if connection_failed: # 更新插件需求包安装状态 plugin = mdb_sys.db.plugin.find_one( {"plugin_name": plugin_name}, {"require_package_install_result": 1}) for connect in connection_failed: if "require_package_install_result" in plugin and plugin[ "require_package_install_result"]: updated = False for old_result in plugin["require_package_install_result"]: if old_result["host_ip"] == connect["host_ip"]: old_result["error"] = connect["error"] old_result["time"] = time.time() updated = True break if not updated: result = { "host_ip": connect["host_ip"], "error": connect["error"], "time": time.time() } plugin["require_package_install_result"].append(result) else: plugin["require_package_install_result"] = [{ "host_ip": connect["host_ip"], "error": connect["error"], "time": time.time() }] mdb_sys.db.plugin.update_one({"plugin_name": plugin_name}, { "$set": { "require_package_install_result": plugin["require_package_install_result"] } }) data = { "msg": gettext( "Some host connections failed. Successfully connected host has installed requirements package in the background" ), "data": connection_failed, "msg_type": "w", "http_status": 201 } else: data = { "msg": gettext( "Executed related installation commands in the background"), "msg_type": "s", "http_status": 201 } return data