def stop_cron(request): """ 停用计划任务 :param request: :return: """ try: cron_id = request.POST.get('id') # 从前端点击停止/启动按钮时,获取id值 re_cron_id = cron_id.replace('-', '') # 去掉‘-’ cron_obj = CronJob.objects.filter(id=re_cron_id) cron_name = cron_obj[0].name servers = cron_obj[0].server li_srv = servers.split(',') li_rem_host = [ srv.ansible_host for srv in ServerInfo.objects.filter(id__in=li_srv) ] cron_cmd = 'name="' + cron_name + '"' + ' ' + 'state=absent' log.info('Set disable cron!') run_task(li_rem_host, module_name='cron', module_args=cron_cmd) # 停用计划任务 log.info('Set disable cron completed!') cron_line = CronJob.objects.get(id=re_cron_id) cron_line.status = 0 cron_line.save() return JsonResponse({'result': True, 'message': '计划任务停止成功'}) except Exception as e: log.error("Cron stop Failed! Caused by: \n" + traceback.format_exc()) return JsonResponse({ 'result': False, 'message': '计划任务停用失败:' + e.message })
def remove_cron_line(request): """ 删除计划任务 :param request: :return: """ cron_id = request.POST.getlist("id[]", []) print("cron_id_del_test", cron_id) log.info("start Remove cron: " + str(id)) if not cron_id: log.error("Remove cron not appoint!") return JsonResponse({'result': False, 'message': '请输入要删除的Cron ID'}) try: # 停止计划任务 re_cron_id = cron_id[0].replace('-', '') # 去掉‘-’ cron_obj = CronJob.objects.filter(id=re_cron_id) cron_name = cron_obj[0].name servers = cron_obj[0].server li_srv = servers.split(',') li_rem_host = [ srv.ansible_host for srv in ServerInfo.objects.filter(id__in=li_srv) ] cron_cmd = 'name="' + cron_name + '"' + ' ' + 'state=absent' log.info('Set disable cron!') run_task(li_rem_host, module_name='cron', module_args=cron_cmd) log.info('Set disable cron completed!') # 删除计划任务 cron = CronJob.objects.filter(id__in=cron_id) cron.delete() log.info('Cron delete Sucess!' + str(id)) return JsonResponse({'result': True, 'message': '删除计划任务成功!'}) except Exception as e: log.error("Cron Remove Failed! Caused by: \n" + traceback.format_exc()) return JsonResponse({'result': False, 'message': '删除失败:' + e.message})
def runscript_task(task, li_rs_srv, account, run_type): li_rem_host = [ srv.ansible_host for srv in Server.objects.filter(id__in=li_rs_srv) if srv.ansible_host ] # 注意这里id__in=后面要跟一个列表 commands_obj = RunScript.objects.filter(id=task) commands_from_mysql = commands_obj[0].script_content file_path = save_tmp_script(commands_from_mysql) start_time = datetime.datetime.utcnow() r_result = run_task(li_rem_host, module_name='script', module_args=file_path) # 运行脚本 end_time = datetime.datetime.utcnow() total_time = (end_time - start_time).total_seconds() # 把run_task的执行返回结果,转化为列表,为后面传参做准备 li_r_result = [] li_r_result.append(r_result) # print "li_r_result", li_r_result try: tr = TaskRecord(account=account, task_id=task, start_time=start_time, end_time=end_time, total_time=total_time, run_type=run_type, task_type='job_bash') tr.save() tr.result, flag = run_results(li_r_result) tr.result = json.dumps(tr.result) tr.save() rs = RunScript.objects.get(id=task) rs.status = 1 if flag else 2 rs.save() except Exception as e3: traceback.print_exc()
def ansible_sync_server(srv=None): """ 使用ansibleAPI的SETUP模块获取服务器详情 :param srv: ServerInfo列表 :return: """ print("START ansible sync server!") server_data = {} ansible_hosts = [] if not srv: srvs = ServerInfo.objects.filter(InstanceType__in=['ECS', 'KEC']) else: srvs = ServerInfo.objects.filter(InstanceType__in=['ECS', 'KEC'], id__in=srv) for si in srvs: if si.ansible_host: ip = ansible_ip(si.ansible_host) ansible_hosts.append(si.ansible_host) server_data.setdefault( ip, { "ansible_host": si.ansible_host, "server_id": si.id, "server_location": si.server_location, }) if not ansible_hosts: return None print(ansible_hosts) result = run_task(ansible_hosts, module_name='setup') for ip, _result in list(result.items()): # si = server_data[ip]['server'] si = ServerInfo.objects.safe_get(id=server_data[ip]['server_id']) _r = _result['result'] if _result['status'] != 'ok': print(("ERROR", _r)) continue facts = _r['ansible_facts'] if server_data[ip]['server_location'] == 'aliyun': si.os = facts['ansible_distribution'] si.os_release = facts['ansible_distribution_release'] si.os_version = facts['ansible_distribution_version'] si.Cpu_info = facts['ansible_processor'][1] si.sys_bits = facts['ansible_machine'] # memory = facts['ansible_devices']['sda']['size'] # cpu = facts['ansible_processor_cores'] si.save() else: si.os = facts['ansible_distribution'] si.os_release = facts['ansible_distribution_release'] si.os_version = facts['ansible_distribution_version'] si.Cpu_info = facts['ansible_processor'][1] si.sys_bits = facts['ansible_machine'] si.Cpu = facts['ansible_processor_cores'] si.Memory = facts['ansible_memtotal_mb'] si.InstanceName = facts['ansible_nodename'] si.DiskSize = sum( [i['size_total'] for i in facts['ansible_mounts']]) / 1024.0 / 1024 / 1024 si.save()
def run_multi_tasks(tasks): print(type(tasks)) print(tasks) result = [] for i in tasks: print(i, type(i)) result.append( run_task(i.inventory, i.module_name, i.module_args, i.pattern)) return result
def start_cron(request): """ 启用计划任务 :param request: :return: """ try: cron_id = request.POST.get('id') # 从前端点击停止/启动按钮时,获取id值 re_cron_id = cron_id.replace('-', '') # 去掉‘-’ cron_obj = CronJob.objects.filter(id=re_cron_id) cron_name = cron_obj[0].name servers = cron_obj[0].server li_srv = servers.split(',') li_rem_host = [ srv.ansible_host for srv in ServerInfo.objects.filter(id__in=li_srv) ] dest_cron_name = '/data/upload/crontab/' + cron_name + '.sh' print("dest_cron_name", dest_cron_name) cron_contents = cron_obj[0].cron_content # 从前端取出计划任务内容 contents = cron_contents.split(' ') # 将取出的计划任务内容转化为列表 cron_cmd = 'minute=' + contents[0] + ' ' + 'hour=' + contents[ 1] + ' ' + 'day=' + contents[2] + ' ' + 'month=' + contents[ 3] + ' ' + 'weekday=' + contents[ 4] + ' ' + 'job="' + '/bin/sh ' + dest_cron_name + '"' + ' ' + 'name="' + cron_name + '"' + ' ' + 'state=present' log.info('Set enable cron!') log.info("CRON shell: " + cron_cmd) run_task(li_rem_host, module_name='cron', module_args=cron_cmd) # 执行 log.info('Set enable cron completed!') cron_line = CronJob.objects.get(id=re_cron_id) cron_line.status = 1 cron_line.save() return JsonResponse({'result': True, 'message': '计划任务启动成功'}) except Exception as e: log.error("Cron start Failed! Caused by: \n" + traceback.format_exc()) return JsonResponse({ 'result': False, 'message': '计划任务启动失败:' + e.message })
def flush_to_database(has_errors=False, stats=None, playbook=None): """Save log_message to database""" global log_message log_type = 'info' if has_errors: log_type = 'error' # 这里仅适用于安装部署服务 if playbook and hasattr(playbook, 'service_ids'): srvs = Service.objects.filter(id__in=playbook.service_ids) print("srvs :::", srvs) srvs.update(install_log='\n'.join(log_message)) # 检测nginx_php_memcache镜像包是否安装成功 srv_nginx = srvs[0].service_name srv_id = srvs[0].server_id srv_odj = srvs[0] # 取出server的对象 print("srv_ojb", srv_odj) if srv_nginx == "nginx_php_memcache": print("srv_nginx", srv_nginx) c_path = srv_odj.config_path if srv_odj.config_path else srv_odj.image.config_path print("c_pach:::", c_path) cf = configparser.ConfigParser() cf.read(c_path) # 读取配置文件 # 取出检测nginx镜像安装状态脚本 c_check_status_cmd = cf.get("operation", "check_rpm_install_status") rem_host = Server.objects.filter( id=srv_id)[0].ansible_host # 取出remote_host rem_ip = ansible_ip(rem_host) # 取出远程主机IP # 检测服务 status_result = run_task([rem_host], module_args=c_check_status_cmd) s_result = status_result[rem_ip]['result']['stdout'] if 'install nginx php memcache ok' in s_result: # 判断服务是否启动 if has_errors: srvs.update(state=-1) else: srvs.update(state=1) else: print("install nginx php memcache faild !") else: if has_errors: srvs.update(state=-1) else: srvs.update(state=1) else: print("Playbook is None")
def execute(self): log.info("Start fetch Ansible Host...") """ 执行更新ansible Host任务 :return: """ # guess_connect_args = [None, {'port': 8022, 'pwd': ''}, {'port': 8022, 'pwd': '__password__'}, # {'port': 22, 'pwd': ''}, {'port': 22, 'pwd': '__password__'}] # 尝试连接逻辑,仅测试8022端口公钥认证 guess_connect_args = [{'port': 8022, 'pwd': ''}] for switch in guess_connect_args: _max = max([len(i) for i in self.instance_list]) log.info("开始初始化ansible-host: " + str(switch)) for i in range(1, _max): inv = [ self.format_ansible_host(line[i], switch) for line in self.instance_list if len(line) > i and line[i] ] ping_result = run_task(inv, module_name='ping') remove_ips = [] for ip, result in list(ping_result.items()): if result['status'] == 'ok' and result['result'][ 'ping'] == 'pong': si = ServerInfo.objects.safe_get( id=self.ip_list[ip]['id']) si.ansible_host = self.format_ansible_host(ip, switch) switch_data = self.merge_ansible_data(ip, switch) si.connect = 1 si.port = switch_data['port'] si.user = switch_data['user'] si.pwd = switch_data['pwd'] si.save() remove_ips.append(ip) log.info("ping <%s> pong!" % ip) self.clear_instances(remove_ips) log.warning("连接失败的服务器: " + str(self.instance_list)) for err_list in self.instance_list: srvs = ServerInfo.objects.filter( Q(PublicIpAddress__in=err_list) | Q(InnerIpAddress__in=err_list)) if srvs: srvs.update(connect=0) log.info("Ansible Host fetch complete!")
def ansible_setup(server): """ ansible执行setup模块获取目标主机的基本信息 :param server: :return: """ if server.connect == 2: setup_data = run_task([server.ansible_host], module_name='setup') ip = ansible_ip(server.ansible_host) if setup_data[ip]['status'] == 'ok': data = setup_data[ip]['result'] facts = data['ansible_facts'] server.hostname = facts['ansible_hostname'] server.os = facts['ansible_distribution'] server.memory = facts['ansible_memory_mb']['real']['total'] server.memory_free = facts['ansible_memory_mb']['real']['free'] server.save()
def test_ecs(): r = run_task(['172.66.110.12 ansible_user=root ansible_port=22 ansible_ssh_pass=__password__'], 'setup') print(r) return r
def init_ecs(ecs_list): ''' 等待机器创建完毕运行时,使用ansible执行ksyinit脚本 :param ecs_list: [{'InstanceName': 'bj-ksy-vn-java-01', 'InstanceId': '218edaab-3f0f-4c5f-8775-54c961779e99'},] :param form_data: 提交的表单数据,以方便在需要区域、VPC等信息时获取 :return: ''' try: # 搜索指定实例ID列表的方式: # client.describe_instances(**{"InstanceId.1": "xxxxx"}) # s = get_session() # client = get_session().create_client("kec", form_data['region'], use_ssl=False, # ks_access_key_id=settings.ACCESS_KEY_ID, # ks_secret_access_key=settings.SECRET_ACCESS_KEY) # client = s.create_client("kec", 'cn-beijing-6', use_ssl=False, ks_access_key_id=settings.ACCESS_KEY_ID, # ks_secret_access_key=settings.SECRET_ACCESS_KEY) print("start execute ksyinit") ansible_hosts = [] for instance in ecs_list: if 'PrivateIp' in instance: # if instance['PrivateIpAddress'] == '172.66.110.12': # ansible_hosts.append('%s ansible_user=root ansible_port=22 ansible_ssh_pass=__password__' % '172.66.110.122') # else: ansible_hosts.append('%s ansible_user=root ansible_port=22 ansible_ssh_pass=__password__' % instance['PrivateIp']) else: log.error("Instance's Private Ip Address Not Found!", instance) print("ansible_hosts: ", ansible_hosts) for _ in range(0, 24): print("开始测试ansible连通性 第 %d 次" % (_+1)) ping_result = run_task(ansible_hosts, 'ping') print("------------------------------------------------------------------") # {'172.66.110.12': {'status': 'ok', 'result': {'_ansible_parsed': True, '_ansible_no_log': False, 'ping': 'pong', 'invocation': {'module_name': 'ping', 'module_args': {'data': None}}, 'changed': False}}} print(ping_result) ping_flag = True for ip, result in ping_result.items(): # {'172.66.110.24': # {'result': {'msg': 'Failed to connect to the host via ssh: ssh: connect to host 172.66.110.24 port 22: Operation timed out\r\n', 'changed': False, 'unreachable': True}, # 'status': 'unreachable'}, '172.66.110.6': {'result': {'msg': 'Failed to connect to the host via ssh: ssh: connect to host 172.66.110.6 port 22: Operation timed out\r\n', 'changed': False, 'unreachable': True}, 'status': 'unreachable'}, '172.66.110.25': {'result': {'msg': 'Failed to connect to the host via ssh: ssh: connect to host 172.66.110.25 port 22: Operation timed out\r\n', 'changed': False, 'unreachable': True}, 'status': 'unreachable'}} if result['status'] == 'ok' and result['result']['ping'] == 'pong': continue else: print("ERROR: ", ping_result) ping_flag = False break else: print("ansible连接成功!") break if not ping_flag: print("ansible连接失败,等待重试。。。") time.sleep(10) continue else: # 未能break,表示ansible连接失败,直接返回ping的结果 for ip, results in ping_result.items(): for _instance_data in ecs_list: if 'PrivateIp' in _instance_data and _instance_data['PrivateIp'] == ip: _instance_data['init_result'] = results return ecs_list print("======================开始执行init任务==============================") init_result = run_task(ansible_hosts, 'script', os.path.join(settings.BASE_DIR, 'scripts/ksy_init.sh')) # init_result = run_task(ansible_hosts, 'script', os.path.join(settings.BASE_DIR, 'scripts/hostname')) # init_result = run_task(ansible_hosts, 'setup') # log.info(init_result) print("------------------------------------------------------------------") print(init_result) print("==================================================================") ''' {'172.66.110.122': {'status': 'unreachable', 'result': {'changed': False, 'unreachable': True, 'msg': 'Failed to connect to the host via ssh: ssh: connect to host 172.66.110.122 port 22: Operation timed out\r\n'}}, '172.66.110.15': {'status': 'ok', 'result': {'changed': True, 'stderr': 'Shared connection to 172.66.110.15 closed.\r\n', 'stdout_lines': ['\x1b[32m+--------------------------------------------------------------+\x1b[0m', '\x1b[32m| Welcome to Centos System init |\x1b[0m', '\x1b[32m+--------------------------------------------------------------+\x1b[0m', 'vm172-66-110-15.ksc.com'], 'rc': 0, '_ansible_no_log': False, 'stdout': '\x1b[32m+--------------------------------------------------------------+\x1b[0m\r\n\x1b[32m| Welcome to Centos System init |\x1b[0m\r\n\x1b[32m+--------------------------------------------------------------+\x1b[0m\r\nvm172-66-110-15.ksc.com\r\n'}}} ------------------ {"instanceId": {"PrivateIp": "172.66.110.12", "PublicIp":"202.202.202.202", init_result:{"status":"ok", "result":{}}}} ''' for ip, results in init_result.items(): for _instance_data in ecs_list: if 'PrivateIp' in _instance_data and _instance_data['PrivateIp'] == ip: _instance_data['init_result'] = results print(ecs_list) return ecs_list except Exception as e: traceback.print_exc() return ecs_list
def index(request): """ 快速脚本执行 :param request: :return: """ name = create_name('执行脚本') if request.method == 'GET': srv_param = request.GET.get("server", None) print(request.GET) if srv_param: server_ids = srv_param.split(',') srvs = ServerInfo.objects.filter(id__in=server_ids) servers = [srv.to_dict() for srv in srvs] return render(request, 'operating/index.html', locals()) if request.method == "POST": user = request.POST.get('user') runscript_form = RunScriptForm(request.POST) try: if runscript_form.is_valid(): data = runscript_form.cleaned_data print("data", data) script_data = RunScript( name=name, user=data['user'], script_content=data['script_content'], server=data['server'], script_args=data['script_args'], ) script_data.save() tsk_id = str(script_data.id) li_srv = data['server'].split(",") li = [ srv.ansible_host for srv in ServerInfo.objects.filter(id__in=li_srv) ] # 构造ansible_host列表 if not li: raise Exception("No Server Selected!") file_path = save_tmp_script(script_data.script_content) start_time = datetime.datetime.utcnow() r_result = run_task(li, module_name='script', module_args=file_path + " " + script_data.script_args) # 运行脚本 end_time = datetime.datetime.utcnow() total_time = (end_time - start_time).total_seconds() tr = TaskRecord(account=request.user.username, start_time=start_time, task_id=tsk_id, end_time=end_time, total_time=total_time, run_type=0, task_type='bash') tr.result, flag = run_results(r_result) tr.result = json.dumps(tr.result) tr.save() script_data.status = 1 if flag else 2 script_data.save() return JsonResponse({ 'result': True, 'message': str(tr.result) }) else: log.error("Form data ERROR: " + str(runscript_form.errors)) message = '表单验证失败!请检查您的填写内容。' + str(runscript_form.errors) return JsonResponse({'result': False, 'message': message}) except Exception as e: log.error(traceback.format_exc()) message = e.message return JsonResponse({'result': False, 'message': message})
def cron_update(request, crn_id): """ 更新计划任务 :param request: :param crn_id: 计划任务id :return: """ if request.method == "GET": crn_ids = CronJob.objects.filter(id=crn_id) if crn_ids: crn_obj = crn_ids[0] return render(request, 'operating/add_cronjob.html', locals()) else: crn_ids = CronJob.objects.filter(id=crn_id) server_items = ServerInfo.objects.all() cron_form = CronjobForm(request.POST) if cron_form.is_valid(): print("cron_form", cron_form) servers = request.POST.getlist('server') str_srv = "" str_server = ','.join(servers) print("str_server2222", str_server) data = cron_form.cleaned_data print("data", data) crn = CronJob.objects.filter(id=crn_id) crn.update( name=data['name'], cron_creater=request.user.username, script_content=data['script_content'], cron_content=data['cron_content'], server=str_server, cron_modified=request.user.username, ) # 更新脚本内容 servs_obj = CronJob.objects.get(id=crn_id) print("servs_obj", servs_obj.server) servs = servs_obj.server cron_name = servs_obj.name li_servs = servs.split(',') li_rem_host = [ srv.ansible_host for srv in ServerInfo.objects.filter(id__in=li_servs) ] commands_from_mysql = servs_obj.script_content new_path = save_tmp_script(commands_from_mysql, cron_name + '.sh') # 传输本地保存的cron文件到远程主机 src = new_path dest = '/data/upload/crontab/' tsk = [ Tasks(li_rem_host, module_name='copy', module_args='src=%s' % src + ' dest=%s' % dest) ] result = run_multi_tasks(tsk) # 开始传输文件 # 授权文件具备执行权限 cmds = 'chmod +x ' + dest + cron_name + '.sh' log.info('Beginning update cron !') run_task(li_rem_host, module_name='command', module_args=cmds) log.info('Update cron completed !') msg = "计划任务更新成功!" return render(request, 'operating/add_cronjob_result.html', locals()) else: msg = "对不起,表单验证失败,请确认填写信息!" return render(request, 'operating/add_cronjob_result.html', locals())
def add_cronjobs(request): """ 添加计划任务 :param request: :return: """ cron_name = create_name('cron') if request.method == 'GET': return render(request, 'operating/add_cronjob.html', locals()) if request.method == "POST": servers = request.POST.getlist('server') cronjobform = CronjobForm(request.POST) if cronjobform.is_valid(): try: data = cronjobform.cleaned_data # 校验crontab表达式是否正确 li_contents = data['cron_content'].split(' ') if len(li_contents) != 5: msg = "对不起,表单验证失败,CRON表达式错误!" return render(request, 'operating/add_cronjob_result.html', locals()) str_server = ','.join(servers) # 保存到数据库 cronjob_data = CronJob( name=data['name'], cron_creater=request.user.username, script_content=data['script_content'], cron_content=data['cron_content'], server=str_server, cron_modified=request.user.username, ) cronjob_data.save() # 定时作业信息存数据库 # 推送脚本到目标主机 ## 获取server的ansible列表 li_rem_host = [ srv.ansible_host for srv in ServerInfo.objects.filter(id__in=servers) ] ## 生成shell脚本 src = save_tmp_script(cronjob_data.script_content, new_name=data['name'] + '.sh') dest = settings.CRON_SHELL_PATH ## 执行ansible任务 run_task(li_rem_host, module_name='copy', module_args='src=%s dest=%s mode=0755' % (src, dest)) msg = "定时任务作业保存成功!" return render(request, 'operating/add_cronjob_result.html', locals()) except Exception as e3: log.error(traceback.format_exc()) msg = "定时任务作业保存失败!" return render(request, 'operating/add_cronjob_result.html', locals()) else: msg = "对不起,表单验证失败,请重新输入!" return render(request, 'operating/add_cronjob_result.html', locals())