【python用法】property
1 # !/usr/bin/env python 2 # coding:utf-8 3 4 5 class TestProperty: 6 7 def __init__(self): 8 self.num = 1 9 10 @property 11 def get_num(self): 12 return self.num 13 14 @property 15 def set_num(self): 16 self.num += 1 17 return self.num 18 19 def del_num(self): 20 del self.num 21 22 23 class TestProperty1(object): 24 25 def __init__(self): 26 self.num = 1 27 28 @property 29 def get_num(self): 30 return self.num 31 32 @get_num.setter 33 def set_num(self, value): 34 self.num = value 35 36 @get_num.deleter 37 def del_num(self): 38 del self.num 39 40 41 class TestProperty2(object): 42 43 def __init__(self): 44 self.num = 1 45 46 def get_num(self): 47 return self.num 48 49 def set_num(self, value): 50 self.num = value 51 52 def del_num(self): 53 del self.num 54 55 BAR = property(get_num, set_num, del_num,) 56 57 58 if __name__ == '__main__': 59 t = TestProperty2() 60 # t.set_num = 3\ 61 t.BAR = 3 62 print(t.BAR)
1 #!/usr/bin/env python 2 # encoding: utf-8 3 4 import json 5 import os 6 7 8 class TemplateSchemaCenter(object): 9 10 @staticmethod 11 def get_template_schema(list_path, func_name): 12 """ 13 获取各模块目录下的json模板和schema模板 14 :param list_path:调用者的文件路径 15 :param func_name:函数名 16 :return: 该函数的json模板,schema模板 17 """ 18 # 暂时处理,template非必需品 19 template = "" 20 schema = "" 21 schema_file_path = os.path.join(list_path, "json_schema", "%s_schema.json" % func_name) 22 template_file_path = os.path.join(list_path, "json_template", "%s.json" % func_name) 23 24 print(template_file_path) 25 print(os.path.isfile(template_file_path)) 26 if os.path.exists(template_file_path): 27 template = json.loads(open(template_file_path).read()) 28 if os.path.exists(schema_file_path): 29 schema = json.loads(open(schema_file_path).read()) 30 return template, schema
1 #!/usr/bin/env python 2 # encoding: utf-8 3 4 5 class AutoInsertJson(object): 6 """stage 7 st1: complete path 8 st2: part path""" 9 key_paths = [] 10 11 def _get_key_path(self, json_template, field_name="", path_sep="->"): 12 """ 13 14 :param json_template: json模板 15 :param field_name: 直接取默认值,不用填,递归自调 16 :param path_sep: 17 :return: 18 """ 19 20 for field in json_template: 21 if not isinstance(json_template[field], dict): 22 self.key_paths.append(field_name + field) 23 elif json_template[field] == {}: 24 self.key_paths.append(field) 25 else: 26 self._get_key_path(json_template[field], field_name + field + path_sep) 27 28 def _get_key_path_list(self, json_template, field_name="", path_sep="->"): 29 """ 30 return key_path_list 31 [["a","b"], ["a","b", "c"]] ... 32 :param json_template: 33 :param field_name: 34 :param path_sep: 35 :return: 36 """ 37 key_path_list = [] 38 self._get_key_path(json_template, field_name, path_sep) 39 # LOG_DEBUG("field path is %s" % self.key_paths) 40 41 for key_path in self.key_paths: 42 temp = key_path.split(path_sep) 43 key_path_list.append(temp) 44 45 # LOG_DEBUG("field path list is %s" % key_path_list) 46 return key_path_list 47 48 def _set_field(self, target_dict, field_path, value, path_sep="->"): 49 """ 50 51 :param target_dict: 52 :param field_path: a -> b -> c... 53 :param value: 54 :param path_sep: -> 55 :return: 56 """ 57 field_list = field_path.split(path_sep) 58 field_list = map(lambda x: x.strip(), field_list) 59 temp_dict = target_dict 60 61 for index in range(0, len(field_list) - 1): 62 temp_dict = temp_dict[field_list[index]] 63 64 temp_dict[field_list[-1]] = value 65 return target_dict 66 67 def _is_exist_key_path(self, src_dict, key_path, path_sep="->"): 68 """ 69 70 :param src_dict: 71 :param key_path: 72 :param path_sep: 73 :return: 74 """ 75 all_key_path_list = self._get_key_path_list(json_template=src_dict, path_sep=path_sep) 76 key_path_list = key_path.split(path_sep) 77 key_path_list = map(lambda x: x.strip(), key_path_list) 78 result = key_path_list in all_key_path_list 79 return result 80 81 def change_json(self, json_template, conf, path_sep="->"): 82 """ 83 stage1: complete path 84 stage2: part path 85 :param json_template: 86 :param conf: 87 :param path_sep: 88 :return: 89 """ 90 for replaced_path in conf: 91 replaced_value = conf[replaced_path] 92 if not self._is_exist_key_path(json_template, replaced_path, path_sep): 93 print("input conf is invalid") 94 return False 95 # LOG_DEBUG("set %s value %s" % (replaced_path, replaced_value)) 96 self._set_field(json_template, field_path=replaced_path, value=replaced_value, path_sep=path_sep) 97 98 return json_template 99 100 101 if __name__ == '__main__': 102 src_json = dict() 103 src_json["data"] = dict() 104 src_json["data"]["a"] = dict() 105 src_json["data"]["a"]["a1"] = 1 106 src_json["data"]["b"] = 2 107 print(src_json) 108 setting_conf = {"data->a->a1": 1, "data->b": 3} 109 AutoInsertJson().change_json(src_json, conf=setting_conf) 110 print(src_json)
#!/usr/bin/env python # encoding: utf-8 import os from .get_template_schema import TemplateSchemaCenter from .auto_insert_json import AutoInsertJson LIST_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) def modify_pc_request_json(json_dir_path, json_name, replaced_conf): result = TemplateSchemaCenter.get_template_schema(json_dir_path, json_name) post_data = result[0] # post_json = str(AutoInsertJson().change_json(post_data, replaced_conf)).replace('\'', '\\\"').replace('u\\', '\\').replace(' ', '') # print("[REPLACE] post json %s " % post_json) return post_data replaced_conf = { "auto_test": False, } post_data = modify_pc_request_json(LIST_PATH, "asset_info_box", replaced_conf) print(post_data)
1 #!/usr/bin/env python 2 # encoding: utf-8 3 import ctypes 4 import time, datetime 5 from threading import Thread 6 from mgr.common.logger import * 7 import subprocess as sp 8 import paramiko 9 import platform 10 import shutil 11 import socket 12 import sys 13 import subprocess 14 from ea.tests.common.func_call_count import * 15 from ea.tests.common.ftp_down_upload import * 16 import re 17 import codecs 18 import inspect 19 import traceback 20 21 22 def robust(func): 23 """ 24 异常追踪装饰器 25 :param func: 26 :return: 27 """ 28 def add_robust(*args, **kwargs): 29 try: 30 previous_frame = inspect.currentframe().f_back 31 caller_filename, caller_line_number, caller_function_name, caller_lines, caller_index = inspect.getframeinfo( 32 previous_frame) 33 LOG_DEBUG('caller_filename: {}, caller_line_number: {}, caller_function_name: {}'.format(caller_filename, 34 caller_line_number, 35 caller_function_name)) 36 return func(*args, **kwargs) 37 except Exception: 38 LOG_ERROR('Error execute func:{}'.format(func.__name__)) 39 traceback.print_exc() 40 return add_robust 41 42 43 def time_limit_ex(timeout, func, args=[], kwargs=None): 44 """ 45 函数运行时间限制,超时后会报错误,成功返回运行结果 46 :param timeout: 超时时间 47 :param func: 函数 48 :param args: 传给函数的参数args 49 :param kwargs: 传给函数的参数kwargs 50 :return: 成功返回,func运行结果 51 """ 52 if kwargs is None: 53 kwargs = {} 54 if not isinstance(timeout, (int, float)) or timeout <= 0: 55 raise Exception("timeout param error:%s" % timeout) 56 57 class FuncThread(Thread): 58 def __init__(self): 59 Thread.__init__(self) 60 self.result = None 61 62 def run(self): 63 try: 64 self.result = func(*args, **kwargs) 65 except Exception, e: 66 self.result = e 67 68 def stop(self): 69 if self.isAlive(): 70 Thread._Thread__stop(self) 71 72 thread = FuncThread() 73 thread.start() 74 thread.join(timeout) 75 if thread.isAlive(): 76 thread.stop() 77 return "time out" 78 else: 79 return thread.result 80 81 82 def time_limit(timeout, func, args=[], kwargs=None): 83 """ 84 函数运行时间限制,超时后会报错误,成功返回运行结果 85 :param timeout: 超时时间 86 :param func: 函数 87 :param args: 传给函数的参数args 88 :param kwargs: 传给函数的参数kwargs 89 :return: 成功返回,func运行结果 90 """ 91 if kwargs is None: 92 kwargs = {} 93 if not isinstance(timeout, (int, float)) or timeout <= 0: 94 raise Exception("timeout param error:%s" % timeout) 95 96 class FuncThread(Thread): 97 def __init__(self): 98 Thread.__init__(self) 99 self.result = None 100 101 def run(self): 102 try: 103 self.result = func(*args, **kwargs) 104 except Exception, e: 105 self.result = e 106 107 def stop(self): 108 if self.isAlive(): 109 Thread._Thread__stop(self) 110 111 thread = FuncThread() 112 thread.start() 113 thread.join(timeout) 114 if thread.isAlive(): 115 thread.stop() 116 raise Exception("run function %s time out" % func) 117 else: 118 return thread.result 119 120 121 def loop_assert(func, _result=None, retry_count=1, interval=1, timeout=0, args=[], kwargs=None, comparator='eq', 122 comparator_target=None, eval_func_name=''): 123 """ 124 轮询模块 125 :param func:需要执行的function 126 :param _result: 执行function预期返回结果 127 :param retry_count: 重试次数 正整数大于0 128 :param interval: 重试时间间隔 正整数大于0,如果为0 则没有超时时间 129 :param timeout: 函数执行的超时时间 正整数大于0,默认为0时,不做超时处理 130 :param args: 传给函数的参数args 元祖类型 131 :param kwargs: 传给函数的参数kwargs 字典类型 132 :param comparator: 比较器, ['eq', 'neq, 'gt', 'ge', 'lt', 'le', 'len_eq', 'len_gt', 'len_lt', 133 'contains', 'contains_by', 'startswith', 'endswith'] 134 :param comparator_target: 用于分解func的返回结果,用于比较验证 135 e.g. resp = {'success': True, 'data': [{'name':'test'}, {'agents':[1,2,3]} ] } 136 ===> comparator_target = ('data', 1, 'agent', 0) 137 ===> 解析出 1,用于后续和_result比较 138 :param eval_func_name: type:str 用于将返回的结果进一步解析,在和_result比对,参数为函数名字符串, e.g. 'len', ... 139 :return: list(bool,str) 成功返回True,None ;失败返回False,msg 140 """ 141 # 参数校验 142 if not isinstance(retry_count, int) or retry_count <= 0: 143 raise Exception("retry_count param error:%s" % retry_count) 144 if not isinstance(interval, (int, float)) or interval < 0: 145 raise Exception("interval param error:%s" % interval) 146 if not isinstance(timeout, (int, float)) or timeout < 0: 147 raise Exception("timeout param error:%s" % timeout) 148 if kwargs is None: 149 kwargs = {} 150 res = False 151 result = None 152 while retry_count: 153 try: 154 if timeout == 0: 155 res_fun = func(*args, **kwargs) 156 else: 157 res_fun = time_limit(timeout, func, args, kwargs) 158 except Exception as e: 159 LOG_EXCEPTION(e) 160 retry_count -= 1 161 time.sleep(interval) 162 else: 163 if comparator_target: 164 res_fun_value = res_fun 165 try: 166 for i in comparator_target: 167 res_fun_value = res_fun_value[i] 168 except Exception as e: 169 LOG_DEBUG('Decomposition result exception: {}'.format(e)) 170 res_fun_value = res_fun 171 else: 172 res_fun_value = res_fun 173 if eval_func_name: 174 try: 175 res_fun_value = eval(eval_func_name + '({})'.format(res_fun_value)) 176 except Exception as e: 177 LOG_DEBUG(e) 178 res_fun_value = res_fun_value 179 if comparator == 'eq': 180 res = bool(res_fun_value == _result) 181 elif comparator == 'neq': 182 res = not bool(res_fun_value == _result) 183 elif comparator == 'gt': 184 res = bool(res_fun_value > _result) 185 elif comparator == 'ge': 186 res = bool(res_fun_value >= _result) 187 elif comparator == 'lt': 188 res = bool(res_fun_value < _result) 189 elif comparator == 'le': 190 res = bool(res_fun_value <= _result) 191 elif comparator == 'len_eq': 192 res = bool(len(res_fun_value) == len(_result)) 193 elif comparator == 'len_gt': 194 res = bool(len(res_fun_value) >= len(_result)) 195 elif comparator == 'len_lt': 196 res = bool(len(res_fun_value) <= len(_result)) 197 elif comparator == 'contains': 198 res = bool(str(_result) in str(res_fun_value)) 199 elif comparator == 'contains_by': 200 res = bool(str(res_fun_value) in str(_result)) 201 elif comparator == 'startswith': 202 res = bool(str(res_fun_value).startswith(str(_result))) 203 elif comparator == 'endswith': 204 res = bool(str(res_fun_value).endswith(str(_result))) 205 else: 206 LOG_DEBUG('Not support comparator: {}'.format(comparator)) 207 # raise AssertionError 208 res = False 209 res_fun_value = 'Not support comparator: {}'.format(comparator) 210 if res: 211 break 212 else: 213 retry_count -= 1 214 time.sleep(interval) 215 # 出错时返回错误信息 216 result = res_fun_value 217 LOG_DEBUG('loop_res: {}, loop_result: {}'.format(res, result)) 218 return res, result 219 220 221 def exec_command(ip, username, password, cmd, port=1, option=0, timeout=5): 222 """ 223 远程Linux端,执行命令 224 :param ip:IP 225 :param username:str 用户名 226 :param password:str 密码 227 :param cmd:str 命令 可输入:linux命令/tcp/udp 228 :param port:str 端口 229 :param timeout:超时时间 230 :param option:命令项控制参数 0 cmd = "nohup python [cmd] -p [port] > /dev/null 2>&1 &" 231 [cmd]:传入tcp_server.py/udp_server.py 232 1 cmd = cmd 233 :return: 234 """ 235 previous_frame = inspect.currentframe().f_back 236 caller_filename, caller_line_number, caller_function_name, caller_lines, caller_index = inspect.getframeinfo( 237 previous_frame) 238 LOG_DEBUG('caller_filename: {}, caller_line_number: {}, caller_function_name: {}'.format(caller_filename, 239 caller_line_number, 240 caller_function_name)) 241 ret = False 242 if option == 0: 243 cmd = "nohup python %s -p %r > /dev/null 2>&1 &" % (cmd, port) 244 LOG_DEBUG("Exec commman:%s" % cmd) 245 try: 246 ssh = paramiko.SSHClient() 247 key = paramiko.AutoAddPolicy() 248 ssh.set_missing_host_key_policy(key) 249 ssh.connect(ip, 22, username, password, timeout=timeout) 250 stdin, stdout, stderr = ssh.exec_command(cmd) 251 out, err = stdout.read(), stderr.read() 252 if err: 253 LOG_ERROR("Exec command %s err message: %s" % (cmd, err)) 254 else: 255 LOG_DEBUG("Exec command %s out message: %s" % (cmd, out)) 256 257 except Exception, e: 258 LOG_DEBUG("Connect %s failed,%s" % (ip, e)) 259 else: 260 if option == 0: 261 ret = True 262 else: 263 if out.replace("\n", "") == "TCP_Server_TestTEST": 264 ret = True 265 elif option == 1: 266 ret = False 267 ##用于执行其他命令 268 else: 269 ret = True 270 ssh.close() 271 return ret 272 273 274 def ssh_connect(ip, port=22, username="root", password="root", cmd="", timeout=5, read_timeout=10): 275 """ 276 远程连接Linux终端 277 :param ip: 278 :param username: 279 :param password: 280 :param port: 281 :param cmd: 282 :param timeout: 283 :return: 284 """ 285 286 ret = False 287 LOG_DEBUG("执行命令:%s" % cmd) 288 try: 289 ssh = paramiko.SSHClient() 290 key = paramiko.AutoAddPolicy() 291 ssh.set_missing_host_key_policy(key) 292 ssh.connect(ip, port, username, password, timeout=timeout) 293 if cmd != "": 294 stdin, stdout, stderr = ssh.exec_command(cmd, timeout=read_timeout) 295 out, err = stdout.read(), stderr.read() 296 if err: 297 LOG_ERROR("exec command %s err message: %s" % (cmd, err)) 298 else: 299 LOG_DEBUG("exec command %s out message: %s" % (cmd, out)) 300 except Exception, e: 301 LOG_ERROR("Ssh connect %s exception:%s" % (ip, e)) 302 else: 303 LOG_DEBUG("Ssh connect %s success" % ip) 304 ret = True 305 return ret 306 307 308 def ssh_connect_with_output(ip, port=22, username="root", password="root", cmd="", timeout=5, read_timeout=10): 309 """ 310 和上一个方法基本一致,仅返回参数多了out,怕影响其他代码,重新定义一个方法 311 远程连接Linux终端,返回带输入结果 312 :param ip: 313 :param username: 314 :param password: 315 :param port: 316 :param cmd: 317 :param timeout: 318 :return:(ret, out) 319 """ 320 321 ret = False 322 out = '' 323 LOG_DEBUG("Exec command:%s" % cmd) 324 previous_frame = inspect.currentframe().f_back 325 caller_filename, caller_line_number, caller_function_name, caller_lines, caller_index = inspect.getframeinfo( 326 previous_frame) 327 LOG_DEBUG('caller_filename: {}, caller_line_number: {}, caller_function_name: {}'.format(caller_filename, 328 caller_line_number, 329 caller_function_name)) 330 try: 331 ssh = paramiko.SSHClient() 332 key = paramiko.AutoAddPolicy() 333 ssh.set_missing_host_key_policy(key) 334 ssh.connect(ip, port, username, password, timeout=timeout) 335 if cmd != "": 336 stdin, stdout, stderr = ssh.exec_command(cmd, timeout=read_timeout) 337 out, err = stdout.read(), stderr.read() 338 if err: 339 LOG_ERROR("exec command %s err message: %s" % (cmd, err)) 340 else: 341 LOG_DEBUG("exec command %s out message: %s" % (cmd, out)) 342 ssh.close() 343 except Exception, e: 344 LOG_ERROR("Ssh connect exception:%s" % (e)) 345 else: 346 LOG_DEBUG("Ssh connect %s success" % ip) 347 ret = True 348 return (ret, out.strip()) 349 350 351 def get_local_ip(): 352 # 部分linux系统无法获取ip 353 try: 354 local_ip_addr = socket.gethostbyname(socket.getfqdn(socket.gethostname())) 355 except Exception as e: 356 LOG_DEBUG('Get local IP address error:{}'.format(e)) 357 local_ip_addr = '127.0.0.1' 358 return local_ip_addr 359 360 361 def get_format_system_info(): 362 # 获取当前系统版本信息,转换为自动化环境命名规则,对于特殊系统,进行特殊匹配 363 # 格式规则: 系统 + 版本号 + _ + 32/64 364 # win7_32/win7_64_sp1/win10_64/win8_32/win8.1_32/win8.1_64/vista/xpsp3 365 # win2008R2_64(sp1)/server2008_32/win2012_64/win2016_64/server2003_64/server2019_64/server2003_32/server2019_64 366 # centos7_64/ubuntu13_64/ubuntu16_64/debian9_64/RHEL7_64 367 368 platform_uname = platform.uname() 369 if platform_uname[0] == 'Windows': 370 cur_system_info = 'win' + platform_uname[2][:4] + '_' + platform_uname[4][-2:] # e.g. win7_64 371 if platform_uname[0] == 'Linux': 372 linux_distribution_info = platform.linux_distribution() 373 linux_name = linux_distribution_info[0].split(' ')[0] 374 linux_version_tuple = linux_distribution_info[1].split('.') 375 linux_version = linux_version_tuple[0] 376 linux_bit = platform.architecture()[0][:2] 377 cur_system_info = linux_name + linux_version + '_' + linux_bit 378 else: 379 pass 380 return cur_system_info.lower() 381 382 383 def run_system(system_info): 384 # 用于ea层的装饰器,仅当system_info与当前系统版本一致时,才跑指定的测试用例 385 system_info_list = system_info.split(',') 386 # 兼容将86系统写成32 387 # ['win7_32', 'win7_64'] ==> ['win7_32', 'win7_64', 'win7_86'] 388 system_info_list_plus = [] 389 for item in system_info_list: 390 system_info_list_plus.append(item) 391 if item[-2:] == '32': 392 system_info_list_plus.append(item[:-2]+'86') 393 394 def decorator(func): 395 def wrapper(*args, **kwargs): 396 # 对无法获取系统信息的操作系统做特殊匹配, system_map 后续持续添加 397 system_map = {'win2016_64': ['10.186.0.35', '10.186.1.35', '10.186.2.35', '10.186.3.35', '10.186.4.35', 398 '10.186.5.35'], 399 'server2019_64': ['10.186.0.64', '10.186.1.64', '10.186.2.64', '10.186.3.64', '10.186.4.64', 400 '10.186.5.64'], 401 '中标麒麟': ['10.186.0.61', '10.186.1.61', '10.186.2.61', '10.186.3.61', '10.186.4.61', 402 '10.186.5.61'], 403 '银河麒麟': ['10.186.0.62', '10.186.1.62', '10.186.2.62', '10.186.3.62', '10.186.4.62', 404 '10.186.5.62']} 405 for system_info_ in system_info_list_plus: 406 if system_info_ in system_map: 407 # 该操作系统指定规划的ip 408 map_ip = system_map[system_info_] 409 local_ip = get_local_ip() 410 if local_ip in map_ip: 411 return func(*args) 412 else: 413 LOG_DEBUG('System IP not match: {} != {}, skip'.format(map_ip, local_ip)) 414 cur_system_info = get_format_system_info() 415 if system_info_.lower() == cur_system_info.lower(): 416 return func(*args) 417 else: 418 LOG_DEBUG('System version not match: {} != {}, skip'.format(system_info_, cur_system_info)) 419 420 return wrapper 421 422 return decorator 423 424 425 def limit_system(system_info): 426 # 用于ea层的装饰器,仅当system_info与当前系统版本一致时,不跑指定的测试用例 427 system_info_list = system_info.split(',') 428 # 兼容将86系统写成32 429 # ['win7_32', 'win7_64'] ==> ['win7_32', 'win7_64', 'win7_86'] 430 system_info_list_plus = [] 431 for item in system_info_list: 432 system_info_list_plus.append(item) 433 if item[-2:] == '32': 434 system_info_list_plus.append(item[:-2] + '86') 435 436 def decorator(func): 437 def wrapper(*args, **kwargs): 438 # 对无法获取系统信息的操作系统做特殊匹配, system_map 后续持续添加 439 system_map = {'win2016_64': '10.186.3.35', 'server2019_64': '10.186.3.64', '中标麒麟': '10.186.3.61', 440 '银河麒麟': '10.186.3.62'} 441 for system_info_ in system_info_list_plus: 442 if system_info_ in system_map: 443 # 该操作系统指定规划的ip 444 map_ip = system_map[system_info_] 445 local_ip = get_local_ip() 446 if map_ip == local_ip: 447 LOG_DEBUG('System IP not match: {} != {}, skip'.format(map_ip, local_ip)) 448 else: 449 return func(*args) 450 cur_system_info = get_format_system_info() 451 if system_info_.lower() == cur_system_info.lower(): 452 LOG_DEBUG('System version not match: {} != {}, skip'.format(system_info_, cur_system_info)) 453 else: 454 return func(*args) 455 456 return wrapper 457 458 return decorator 459 460 461 # def lock_resource_on_func(cls, resource_list): 462 # """ 463 # 资源锁加锁装饰器, 装饰在 测试方法上 464 # :param cls: type: TestSomething 某个测试模块的类实例 465 # :param resource_list: type:list 需要加锁的资源 具体字段看resource表 466 # :return: 467 # """ 468 # update_params = {item: cls.cur_node_id for item in resource_list} 469 # 470 # def decorator(func): 471 # def wrapper(*args, **kwargs): 472 # try: 473 # func(*args, **kwargs) 474 # cls.redis_queue.lock_resource(update_param=update_params) 475 # except Exception as e: 476 # LOG_DEBUG(e) 477 # finally: 478 # cls.clear_env() 479 # 480 # return wrapper 481 # 482 # return decorator 483 484 485 @total 486 def os_system_exec_command(cmd): 487 """ 488 执行命令 489 :param cmd: 490 :return: 491 """ 492 if platform.system() == 'Linux': 493 os.system(cmd) 494 else: 495 os.system(cmd + '&&exit') 496 return False 497 498 499 def exec_command_with_popen(cmd): 500 """ 501 执行windows或者linux命令行 502 :param cmd: 命令 503 :return: 返回值 504 """ 505 f = os.popen(cmd + '&&exit', "r") 506 ret = f.read() # 读文件 507 if platform.system().lower() == 'windows': 508 ret = ret.decode('gbk', errors='ignore') 509 ret = ret.encode('utf-8', errors='ignore') 510 else: 511 pass 512 LOG_DEBUG(r'Exec command: {}'.format(cmd)) 513 LOG_DEBUG(r'Result:{}'.format(ret)) 514 f.close() 515 return ret 516 517 518 def loop_exec_command(cmd, _result=True, retry_count=5, interval=1, timeout=3): 519 """ 520 循环执行同一个命令 521 :param cmd: 522 :param retry_count: 523 :param interval: 524 :param timeout: 525 :return: 526 """ 527 loop_assert(os_system_exec_command, _result, retry_count, interval, timeout,args=(cmd,)) 528 529 530 def time_exec_command(command, timeout=2): 531 """call shell-command and either return its output or kill it 532 if it doesn't normally exit within timeout seconds and return None""" 533 534 command = command + '&&exit' 535 cmd = command.split(" ") 536 start = datetime.datetime.now() 537 process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 538 while process.poll() is None: 539 time.sleep(1) 540 now = datetime.datetime.now() 541 if (now - start).seconds > timeout: 542 subprocess.Popen("cmd /c taskkill /f /im notepad.exe") 543 544 return False 545 return True 546 547 548 def exec_command_as_admin(cmd): 549 """ 550 以administrator权限运行命令 551 :param cmd: type:str 要执行的cmd命令,若多行,使用换行符\n 552 :return: 553 """ 554 # 兼容winServer系统,运行脚本会有"运行身份"窗口拦截,若为server和linux,则使用os.system()代替 555 LOG_DEBUG('admin cmd: {}'.format(cmd)) 556 system_info = get_format_system_info() 557 if 'server' in system_info or 'server' in platform.platform().lower() or 'Linux' == platform.system(): 558 cmd_list = cmd.split(r'\n') 559 for cmd in cmd_list: 560 os.system(cmd) 561 else: 562 src_path = os.path.abspath( 563 os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))), 564 'Swiss-Knife\\tools\\admin_cmd.bat')) 565 cp_path = os.path.abspath( 566 os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))), 567 'Swiss-Knife\\tools\\admin_cmd_cp.bat')) 568 try: 569 cp_cmd = shutil.copyfile(src=src_path, dst=cp_path) 570 with open(cp_path, 'a+') as f: 571 f.write(cmd.decode('utf-8', 'ignore').encode('gbk', 'ignore')) 572 os.system(cp_path) 573 time.sleep(2) 574 except Exception as e: 575 576 # 解决工程是以包的形式部署,导致路径不一致 577 try: 578 agent_name = '.' 579 for name in os.listdir("C:\\jenkins\\workspace\\"): 580 if 'agent_' in name: 581 agent_name = name 582 break 583 src_path = r'C:\jenkins\workspace\{}\Swiss-Knife\tools\adkmin_cmd.bat'.format(agent_name) 584 cp_path = r'C:\jenkins\workspace\{}\Swiss-Knife\tools\admin_cmd_cp.bat'.format(agent_name) 585 cp_cmd = shutil.copyfile(src=src_path, dst=cp_path) 586 with open(cp_path, 'a+') as f: 587 f.write(cmd.decode('utf-8', 'ignore').encode('gbk', 'ignore')) 588 os.system(cp_path) 589 time.sleep(2) 590 except Exception as e: 591 LOG_DEBUG(e) 592 593 594 def wait_result(wait_time=3): 595 """ 596 等待结果 597 :param wait_time: 598 :return: 599 """ 600 time.sleep(wait_time) 601 602 603 def release(obj=r'C:\ProgramData\Sangfor\EDR\SAV\cache'): 604 try: 605 if os.path.isfile(obj): 606 return 607 cmd = 'cacls ' + obj + '\*.* /g everyone:f' 608 print(cmd) 609 # os.system(cmd) 610 p = os.popen(cmd, "w") # auto confirm 611 p.write('y\n') 612 subobjs = os.path.os.listdir(obj) 613 if subobjs == []: 614 return 615 else: 616 for temp in subobjs: 617 tempobj = os.path.join(obj, temp) 618 release(tempobj) 619 except Exception as e: 620 LOG_ERROR(e) 621 622 623 def search_file_by_re(file_path, pattern, encode ="utf-16-le"): 624 """ 625 读取文件(一般为日志),并通过正则表达式寻找内容 626 :param file_path: 627 :return: 628 """ 629 patt = re.compile(pattern) 630 with codecs.open(file_path, "r", encoding=encode) as f: 631 re_list = patt.findall(f.read()) 632 return re_list 633 634 635 def upload_file_to_mgr_tmp_dir(file_path, mgr_ip, host="10.186.0.185", username="root", password="root", port=21,mgr_sve_path=r'/tmp/'): 636 """ 637 上传文件到mgr的tmp目录 638 :param file_path: 本地文件路径 最好输入绝对路径 639 :param mgr_ip: mgr ip 640 :param host: ftp ip 641 :param username: 用户名 642 :param password: 密码 643 :param port: 端口 644 :return: 645 """ 646 ftp = ftpconnect(host=host, username=username, password=password, port=port) 647 #跳转机:10.186.0.185 648 remotepath_185 = os.path.join(r'/var/www/html/download/upload_mgr/', os.path.basename(file_path)) 649 #mgr临时目录 650 remotepath_mgr = os.path.join(mgr_sve_path, os.path.basename(file_path)) 651 uploadfile(ftp, remotepath_185, file_path) 652 cmd = "/var/www/html/download/upload_mgr/LoadFile.sh {} {} {} {} {} {} upload".format(mgr_ip, 22, "root", "root", 653 remotepath_mgr, remotepath_185) 654 ret, out = ssh_connect_with_output(ip=host, cmd=cmd) 655 return ret 656 657 658 def get_win_type(): 659 try: 660 cmd = "systeminfo" 661 output = sp.check_output(cmd) 662 except StandardError as e: 663 LOG_EXCEPTION(e) 664 return None 665 else: 666 if output: 667 if re.search(r".*windows.*\s*server.*", output, re.I): 668 return "server" 669 else: 670 return "pc" 671 else: 672 return None 673 674 675 class disable_file_system_redirection: 676 """ 677 关闭64位系统的driver目录重定向 678 使用方法:with disable_file_system_redirection(): 679 ... 680 """ 681 try: 682 _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection 683 _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection 684 except Exception as e: 685 LOG_ERROR(str(e)) 686 687 def __enter__(self): 688 self.old_value = ctypes.c_long() 689 self.success = self._disable(ctypes.byref(self.old_value)) 690 691 def __exit__(self, type, value, traceback): 692 if self.success: 693 self._revert(self.old_value) 694 695 696 if __name__ == "__main__": 697 opr = 'enable' 698 exec_command_as_admin(r'"C:\Program Files\Sangfor\EDR\agent\bin\generalcfg.exe" {} Edr_develop@123'.format(opr)) 699 exec_command_as_admin( 700 r'"C:\Program Files\Sangfor\EDR\agent\bin\generalcfg.exe" query Edr_develop@123 > C:\opr_result.txt') 701 with open(r"C:\opr_result.txt") as f: 702 ret = f.readline()[:-1] 703 if ret != 'generalcfg status is {}'.format(opr): 704 os.system(r'"C:\Program Files\Sangfor\EDR\agent\bin\rtptool.exe" {} SangforEDRTool'.format(opr)) 705 exec_command_with_popen( 706 r'"C:\Program Files\Sangfor\EDR\agent\bin\rtptool.exe" query SangforEDRTool > C:\opr_result.txt') 707 with open(r"C:\opr_result.txt") as f: 708 ret = f.readline()[:-1] 709 assert ret == 'generalcfg status is {}'.format(opr), "自保护不工作,状态:{}".format(ret) 710 if os.path.exists(r"C:\opr_result.txt"): 711 os.remove(r"C:\opr_result.txt") 712 # _, out = ssh_connect_with_output('10.186.0.200', 22, 'root', 'root', "/root/linkuploadlogserver/server/sfla_server.sh > /tmp/test.txt &",) 713 # print out 714 # ret = exec_command_with_popen( 715 # r'cd "C:\Program Files\Sangfor\EDR\agent\var\log\sfpatch\patch\down" && dir /B /O-D|findstr "log"') 716 # ret = exec_command_with_popen(r'del "C:\ProgramData\...refuXWqypW\rVkmTMPs8f.db" /F /S /Q') 717 # print ret 718 # ssh_connect(ip='10.143.0.74', username='root', password='scloud',cmd=r'docker exec -i EDR-47727611.main /sf/edr/manager/bin/eps_services restart &', timeout=500) 719 # ssh_connect(ip='10.143.0.74', username='root', password='scloud', cmd=r'docker exec -i EDR-47727611.main ls', timeout=50) 720 721 # ssh_connect(ip='10.186.0.200', 722 # cmd=r'sh /tmp/update_upgraded_dump.bash', 723 # timeout=3) 724 # print exec_command_with_popen(r'type C:\AutoTestTool\ScanState.json') 725 # attack_count = 100 726 # attacked_user = "fooName" 727 # cpu_num = 16 728 # attacked_ip = '10.186.4.23' 729 # brute_type = 'smb' 730 # cmd = 'rm -rf /root/dxx/pwd.txt;mkdir -p /root/dxx;for((i=1;i<={};i++));do echo root$i >> /root/dxx/pwd.txt;nohup hydra -l {} -P /root/dxx/password.txt -t {} {} {} > /dev/null 2>&1 &'.format( 731 # attack_count, attacked_user, cpu_num, attacked_ip, brute_type) 732 # ssh_connect(ip='10.186.0.174', username='root', password='root', cmd=cmd, timeout=120, 733 # read_timeout=120) 734 # exec_command_as_admin( 735 # r'rename "C:\Program Files\Sangfor\EDR\agent\bin\frep\local_certificate\black.dat" black_bak.dat') 736 # exec_command_as_admin( 737 # r'rename "C:\Program Files\Sangfor\EDR\agent\bin\frep\local_certificate\white.dat" white_bak.dat') 738 739 # exec_command_as_admin( 740 # r'copy /Y {} "C:\Program Files\Sangfor\EDR\agent\bin\frep\local_certificate\black.dat"'.format( 741 # os.path.join(r'C:\Users\Administrator\EDRT\Swiss-Knife', r'virus\digital_signature\black_model\black.dat'))) 742 # exec_command_as_admin( 743 # r'copy /Y {} "C:\Program Files\Sangfor\EDR\agent\bin\frep\local_certificate\white.dat"'.format( 744 # os.path.join(r'C:\Users\Administrator\EDRT\Swiss-Knife', r'virus\digital_signature\white_model\white.dat'))) 745 746 # 3.2.16 747 # file_path = ['edr3.2.16_offline_20190920123612_Build961_sign.pkg', 'manager_deploy.sh', 'mgr_clean.sh'] 748 # 3.2.15en 749 # file_path = ['edr3.2.15_offline_20200314070038_Build12319_sign.pkg', 'manager_deploy_en.sh', 'mgr_clean.sh'] 750 751 # # 第六套 752 # mgr_ips = ['10.186.1.122', '10.186.1.123', '10.186.1.124','10.186.1.125', 753 # '10.186.1.126','10.186.1.128','10.186.1.130','10.186.1.131','10.186.1.135','10.186.1.155','10.186.1.156',] 754 # 第五套 755 # mgr_ips = ['10.186.2.122', '10.186.2.123', '10.186.2.124','10.186.2.125', 756 # '10.186.2.126','10.186.2.128','10.186.2.130','10.186.2.131','10.186.2.135','10.186.2.155','10.186.2.156', 757 # '10.186.2.138','10.186.2.140','10.186.2.141','10.186.2.144','10.186.2.145','10.186.2.161','10.186.2.162','10.186.2.163'] 758 # mgr_ips = [ 759 # '10.186.2.126', '10.186.2.128', '10.186.2.130', '10.186.2.131', '10.186.2.135', '10.186.2.155', 760 # '10.186.2.156', 761 # '10.186.2.140', '10.186.2.141', '10.186.2.144', '10.186.2.161', 762 # '10.186.2.162', '10.186.2.163'] 763 764 # # 批量上传升级包和卸载/安装脚本 765 # for file in file_path: 766 # for mgr_ip in mgr_ips: 767 # print "mgr_ip:{} file:{}".format(mgr_ip, file) 768 # upload_file_to_mgr_tmp_dir(file, mgr_ip, mgr_sve_path='/root/') 769 770 # 批量卸载mgr后全新安装mgr 771 # for mgr_ip in mgr_ips: 772 # _, ret = ssh_connect_with_output(ip=mgr_ip, cmd='cd /root;chmod 777 *; ./mgr_clean.sh;./mgr_clean.sh;', timeout=1000) 773 # print '卸载mgr{}:{}'.format(mgr_ip, ret) 774 # time.sleep(3) 775 # # 采用后台运行,需要等它执行完成 776 # _, ret = ssh_connect_with_output(ip=mgr_ip, 777 # cmd='/root/{} {} 10.186.0.1 &'.format(file_path[1], file_path[0]), 778 # timeout=1500) 779 # print '安装mgr{}:{}'.format(mgr_ip, ret) 780 781 # 批量卸载agent后全新安装agent 782 # for mgr_ip in mgr_ips: 783 # agent_ip = '.'.join(mgr_ip.split('.')[:-1]) + '.' + mgr_ip.split('.1')[-1] 784 # _, ret = ssh_connect_with_output(ip=agent_ip, 785 # cmd='/sangfor/edr/agent/bin/eps_uninstall.sh;cd /root; mkdir new;cd new;' 786 # 'wget --no-check-certificate https://{0}/html/linux_edr_installer.tar.gz; ' 787 # 'tar -zxvf linux_edr_installer.tar.gz;chmod +x agent_installer.sh;' 788 # './agent_installer.sh -h {0} -p 443 -f y'.format(mgr_ip),timeout=1000) 789 # print '安装agent:{}'.format(ret) 790 791 # ret = exec_command_with_popen( 792 # r'cd "C:\Program Files\Sangfor\EDR\agent\var\log\sfpatch\patch" && dir /B /O-D|findstr "log"') 793 # file_name_list = ret.strip().split('\n') 794 # print file_name_list 795 # _, out = ssh_connect_with_output('10.186.3.126', username="root", password="root", 796 # cmd="grep '\[save_file1\]' /sf/edr/manager/var/log/evidenced/20200331-183620.log") 797 # print out.split('\n')[0]
作者:gtea
博客地址:https://www.cnblogs.com/gtea