ajax发送命令
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" id="submit_task_confirm" onclick="submit_task(this,'/api/multitask/cmd/')" class="btn btn-primary">确定执行</button>
</div>
function submit_task(ele,post_url){
//console.log(ele);
$(ele).attr('disabled','true');
$.post(post_url, postDic,function(callback){
console.log(callback);
if (callback != 'TaskCreatingError'){
$("#modal_content").html("任务创建成功! 任务编号:" + callback);
$("#modal_content").attr("style","color:green;font:bold");
$(".task_result").html("");
$("#file-download-to-local").attr("task_id",callback); // only works when task_type = file_get
GetTaskResult(callback,'refresh');
}else{
$("#modal_content").html("任务创建失败,请查看相关日志进行调试!");
$("#modal_content").attr("style","color:red;font:bold")
}
});
}
api接口
url(r'multitask/cmd/$', views.multitask_cmd,name='multitask_cmd'),
@login_required
def multitask_cmd(request):
#print '==post:',request.POST
multi_task = host_mgr.MultiTask('run_cmd',request)
task_id = multi_task.run() # 执行run方法
if task_id:
return HttpResponse(task_id)
else:
return HttpResponse("TaskCreatingError")
class MultiTask(object):
def __init__(self,task_type,request_ins):
self.request = request_ins
self.task_type = task_type
def run(self):
return self.parse_args()
def parse_args(self):
#print '==>parse_args:', self.request.POST
task_func = getattr(self,self.task_type)
return task_func()
def terminate_task(self):
task_id = self.request.POST.get('task_id')
assert task_id.isdigit()
task_obj = models.TaskLog.objects.get(id=int(task_id))
res_msg = ''
try:
os.killpg(task_obj.task_pid,signal.SIGTERM)
res_msg = 'Task %s has terminated!' % task_id
except OSError as e:
res_msg = "Error happened when tries to terminate task %s , err_msg[%s]" % (task_id,str(e))
return res_msg
def run_cmd(self):
cmd = self.request.POST.get("cmd")
host_ids =[int(i.split('host_')[-1]) for i in json.loads(self.request.POST.get("selected_hosts"))]
task_expire_time = self.request.POST.get("expire_time")
exec_hosts = models.BindHosts.objects.filter(id__in=host_ids)
random_str = self.request.POST.get('local_file_path')
task_obj= self.create_task_log('cmd',exec_hosts,task_expire_time,cmd,random_str)
#'-task_type', 'cmd', '-task_id', '15', '-expire', '30', '-task', 'ifconfig', '-uid', '1']
print("-->run cmd:",cmd,host_ids)
p = subprocess.Popen(['python3',
settings.MultiTaskScript,
'-task_type','cmd',
'-expire',task_expire_time,
'-uid',str(self.request.user.id) ,
'-task',cmd ,
'-task_id', str(task_obj.id)
],
preexec_fn=os.setsid)
task_obj.task_pid = p.pid
task_obj.save()
return task_obj.id
调用python脚本,并格式化参数
if __name__ == '__main__':
require_args= ['-task_type','-task_id','-expire','-uid']
lack_args = [arg for arg in require_args if arg not in sys.argv[1:]]
if len(lack_args) >0:
sys.exit("lack args of: %s"% lack_args)
task_type = sys.argv[sys.argv.index('-task_type')+1]
if task_type =='cmd':
require_args= ['-task',]
# elif task_type == 'file_send':
# require_args = ['-local','-remote']
elif task_type == 'file_get':
require_args = ['-remote',]
lack_args = [arg for arg in require_args if arg not in sys.argv[1:]]
if len(lack_args) >0:
sys.exit("lack args of: %s"% lack_args)
task_id = sys.argv[sys.argv.index('-task_id')+1]
expire_time = sys.argv[sys.argv.index('-expire')+1]
if task_type =='cmd':
content = sys.argv[sys.argv.index('-task')+1]
else:
content = sys.argv
uid = sys.argv[sys.argv.index('-uid')+1]
task_obj = models.TaskLog.objects.get(id=int(task_id))
connection.close()
Pool = multiprocessing.Pool(processes=settings.MaxTaskProcesses)
res_list = []
if task_type == 'cmd':
task_func = cmd_exec
elif task_type == 'file_send' or task_type == 'file_get':
task_func = file_tranfer_exec
else:
sys.exit("wrong task_type")
for h in task_obj.hosts.select_related():
p = Pool.apply_async(task_func,args=(task_id,h.id,uid,content))
res_list.append(p)
#get result
Pool.close()
Pool.join()
#for res in res_list:
# res.get()
执行前端传递的cmd命令,并将结果存入数据库
__author__ = 'jieli'
import global_settings
import json
import traceback
import paramiko
from CrazyEye import settings
import django
django.setup()
from web import models
from django.db import connection
import sys,time,os
import multiprocessing
def cmd_exec(task_id,bind_host_id,user_id,cmd ):
bind_host = models.BindHosts.objects.get(id=bind_host_id)
s = paramiko.SSHClient()
s.load_system_host_keys()
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
if bind_host.host_user.auth_method == 'ssh-password':
s.connect(bind_host.host.ip_addr,
int(bind_host.host.port),
bind_host.host_user.username,
bind_host.host_user.password,
timeout=5)
else:#rsa_key
key = paramiko.RSAKey.from_private_key_file(settings.RSA_PRIVATE_KEY_FILE)
s.connect(bind_host.host.ip_addr,
int(bind_host.host.port),
bind_host.host_user.username,
pkey=key,
timeout=5)
stdin,stdout,stderr = s.exec_command(cmd)
result = stdout.read(),stderr.read()
if any(result):
#cmd_result = filter(lambda x:len(x.strip())>0,result)[0]
cmd_result = result[0] if result[0] else result[1]
else:
cmd_result = b'execution has no output!'
res_status = 'success'
print('----------- HOST:%s IP:%s -------------' %(bind_host.host.hostname,bind_host.host.ip_addr) )
# for line in cmd_result.decode():
# print(line)
print(cmd_result.decode())
s.close()
except Exception as e:
#except ValueError as e:
print('----------- HOST:%s IP:%s -------------' %(bind_host.host.hostname,bind_host.host.ip_addr))
print('\033[31;1mError:%s\033[0m' % e)
print(traceback.print_exc())
cmd_result = e
res_status = 'failed'
log_obj = models.TaskLogDetail.objects.get(child_of_task_id= int(task_id), bind_host_id=bind_host.id)
log_obj.event_log = cmd_result
log_obj.result= res_status
log_obj.save()
执行cmd命令后,返回任务id给前端,前端根据任务id获得cmd任务执行结果
获取结果API
def get_task_result(self,detail=True):
'''get multi run task result'''
task_id = self.request.GET.get('task_id')
log_dic ={
#'summary':{},
'detail':{}
}
task_obj = models.TaskLog.objects.get(id=int(task_id))
task_detail_obj_list = models.TaskLogDetail.objects.filter(child_of_task_id=task_obj.id)
log_dic['summary']={
'id':task_obj.id ,
'start_time': task_obj.start_time,
'end_time': task_obj.end_time,
'task_type': task_obj.task_type,
'host_num': task_obj.hosts.select_related().count(),
'finished_num': task_detail_obj_list.filter(result='success').count(),
'failed_num': task_detail_obj_list.filter(result='failed').count(),
'unknown_num': task_detail_obj_list.filter(result='unknown').count(),
'content': task_obj.cmd,
'expire_time':task_obj.expire_time
}
if detail:
for log in task_detail_obj_list:
log_dic['detail'][log.id] = {
'date': log.date ,
'bind_host_id':log.bind_host_id,
'host_id': log.bind_host.host.id,
'hostname': log.bind_host.host.hostname,
'ip_addr': log.bind_host.host.ip_addr,
'username': log.bind_host.host_user.username,
'system' : log.bind_host.host.system_type,
'event_log': log.event_log,
'result': log.result,
'note': log.note
}
return json.dumps(log_dic,default=json_date_handler)