import json import time import paramiko import pymysql from update.models import UpdateCommand, Cinema from update.serializers import UpdateCommandSerializer from django.db.models import Q from time import sleep class UpdateCommandUtil: def __init__(self): self.client = paramiko.SSHClient() self.channel = None self.model = UpdateCommand def connect(self, cinema_ip): cinema_config = {'hostname': cinema_ip, 'port': 22, 'username': 'root', 'password': 'cine123456'} self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.client.connect(**cinema_config) def disconnect(self): self.client.close() def get_all_cmd(self): return self.model.objects.filter(is_delete=False).order_by('id').all() def get_sys_cmd(self): return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=True)).order_by('id').all() def get_no_sys_cmd(self): return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=False)).order_by('run_num').all() def get_no_sys_setup_cmd(self): return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=False) & Q(process='setup')).order_by('id').all() def get_no_sys_teardown_cmd(self): return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=False) & Q(process='teardown')).order_by( 'id').all() def get_no_sys_sql_cmd(self): return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=False) & Q(process='sql')).order_by('id').all() def get_no_sys_client_cmd(self): return self.model.objects.filter(Q(is_delete=False) & Q(is_sys=False) & Q(process='client')).order_by( 'id').all() def get_checked_cmd(self, cmd_list, is_delete='0'): sys_result = self.get_sys_cmd() checked_setup_result = self.model.objects.filter( Q(is_delete=is_delete) & Q(id__in=cmd_list) & Q(process='setup')).order_by('run_num').all() checked_teardown_result = self.model.objects.filter( Q(is_delete=is_delete) & Q(id__in=cmd_list) & Q(process='teardown')).order_by('run_num').all() sys_cmd = [{'desc': sys.desc, 'cmd': sys.command} for sys in sys_result] checked_setup_cmd = [{'desc': setup.desc, 'cmd': setup.command} for setup in checked_setup_result] checked_teardown_cmd = [{'desc': teardown.desc, 'cmd': teardown.command} for teardown in checked_teardown_result] return {'sys': sys_cmd, 'setup': checked_setup_cmd, 'teardown': checked_teardown_cmd} def exec_cmd(self, cinema_ip, _exec_cmd_list): self.connect(cinema_ip) exec_output = [] exec_list = [] for exec_cmd in _exec_cmd_list: print('执行命令对象:', exec_cmd) cmd = str(exec_cmd['cmd']).replace(r'\\', '\\').replace(r"\'", "'") stdin, stdout, stderr = self.client.exec_command(cmd) out = stdout.read().decode('utf-8') err = stderr.read().decode('utf-8') print('正确输出:', out) print('错误输出:', err) out_format = out.replace('\n', '
').strip() err_format = err.replace('\n', '
').strip() if err == '': if out == '': if exec_cmd['desc'] not in exec_list: exec_output.append(exec_cmd['desc'] + ':执行成功') exec_list.append(exec_cmd['desc']) else: exec_output.append(exec_cmd['desc'] + ':执行成功
' + out_format) else: if exec_cmd['desc'] in ['检出版本', '拉取代码']: exec_output.append( exec_cmd['desc'] + ':执行成功
' + out_format + '
' + err_format) continue if exec_cmd['desc'] in ['执行升级脚本']: exec_output.append(exec_cmd['desc'] + ':执行成功') continue else: exec_output.append(exec_cmd['desc'] + ':执行失败 ' + err.replace('\n', '
').strip()) return False, exec_output self.disconnect() print('输出结果:', exec_output) return True, '
'.join(exec_output) def exec_cmd_by_type(self, cinema_ip, _type, cmd_list, short_release, is_delete='0'): print('需要执行的命令列表:', cmd_list) exec_cmd_list = [] exec_cmd_data = self.get_checked_cmd(cmd_list, is_delete) if _type == 'setup': cmds = exec_cmd_data['sys'] + exec_cmd_data['setup'] elif _type == 'combo': cmds = exec_cmd_data['setup'] elif _type == 'teardown': cmds = exec_cmd_data['teardown'] else: cmds = exec_cmd_data['sys'] for cmd in cmds: if '' in cmd['cmd']: cmd['cmd'] = cmd['cmd'].replace('', short_release) exec_cmd_list.append(cmd) elif cmd['cmd'].startswith(''): cmd['cmd'] = cmd['cmd'].replace('', '') for c in cmd['cmd'].split('|||'): exec_cmd_list.append({'desc': cmd['desc'], 'cmd': c}) else: exec_cmd_list.append(cmd) return self.exec_cmd(cinema_ip, exec_cmd_list) # 执行设置相关 class UpdateConfigUtil: def __init__(self, cinema_ip, checked_list, run_before_teardown): self.ip = cinema_ip self.checked_list = checked_list self.run_before_teardown = run_before_teardown def exec_config(self, short_release): cmd_list = self.get_all_exec_cmd() db_config = Cinema.objects.filter(ip=self.ip).values()[0] db_conn = pymysql.Connect(host=self.ip, port=3306, user=db_config['db_user'], passwd=db_config['db_pwd'], database='cine') db_cursor = db_conn.cursor() result_list = [] for cmds in cmd_list: print('执行命令: ', cmds) for cmd in cmds['cmd']: r = db_cursor.execute(cmd) print("执行子命令: ", cmds['desc'], cmd, '结果:', '执行失败(设置无需修改)' if r == 0 else '执行成功') result_list.append(cmds['desc'] + (':执行失败(设置无需修改)' if r == 0 else ':执行成功')) db_conn.commit() if cmds['combo_cmd'] != 0: update_cmd = UpdateCommandUtil() result, setup_output = update_cmd.exec_cmd_by_type(self.ip, 'combo', [cmds['combo_cmd']], short_release, is_delete='1') print('执行关联命令:', setup_output) db_cursor.close() db_conn.close() return '
'.join(result_list) def get_all_exec_cmd(self): all_config_obj = UpdateCommand.objects.filter( Q(process='config') & Q(run=self.run_before_teardown) & Q(is_delete=False)).values() cmd_list = [] print(all_config_obj) for config_item in all_config_obj: if config_item['id'] in self.checked_list: cmd_list.append({"desc": config_item['desc'], "cmd": json.loads(config_item['command'])['checked'], "combo_cmd": config_item['combo_cmd']}) else: cmd_list.append({"desc": config_item['desc'], "cmd": json.loads(config_item['command'])['unchecked'], "combo_cmd": config_item['combo_cmd']}) return cmd_list