You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
flyapps/fir_ser/api/utils/app/shellcmds.py

188 lines
6.5 KiB

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# project: 3月
# author: liuyu
# date: 2020/3/6
import time,re,os,signal
from subprocess import Popen, PIPE
import logging
import paramiko,json
import socket
import pexpect
from api.utils.storage.caches import developer_auth_code
def default_result():
return {'exit_code': '99', 'return_info': 'Failed to run, function_name is not existed'}
def portisonline(host,port):
result={}
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.settimeout(3)
result["host"] = host
result["port"]=port
result["functionname"]="CHECK_HOST_ONLINE:"
try:
sk.connect((host,port))
result["message"]="Connection success"
result["code"]=0
except Exception:
result["message"]="SSH Port Connection refused"
result["code"]=1
sk.close()
return result
class SSHConnection(object):
def __init__(self, host, port, username, password):
self._host = host
self._port = port
self._username = username
self._password = password
self._transport = None
self._sftp = None
self._client = None
self._connect()
def _connect(self):
transport = paramiko.Transport((self._host, self._port))
transport.connect(username=self._username, password=self._password)
self._transport = transport
#下载
def download(self, remotepath, localpath):
if self._sftp is None:
self._sftp = paramiko.SFTPClient.from_transport(self._transport)
self._sftp.get(remotepath, localpath)
self.close()
#上传
def put(self, localpath, remotepath):
if self._sftp is None:
self._sftp = paramiko.SFTPClient.from_transport(self._transport)
self.exec_command('mkdir -p %s'%(os.path.dirname(remotepath)))
self._sftp.put(localpath, remotepath)
self.close()
#执行命令
def exec_command(self, command):
if self._client is None:
self._client = paramiko.SSHClient()
self._client._transport = self._transport
stdin, stdout, stderr = self._client.exec_command(command)
data = stdout.read()
if len(data) > 0:
return {'status':0,'infos':data}
err = stderr.read()
if len(err) > 0:
return {'status':1,'infos':err}
return {'status': 0, 'infos': data}
def close(self):
if self._transport:
self._transport.close()
if self._client:
self._client.close()
def pshell_command(cmdstrs,user_obj,developer_email,timeout=60*10):
result = default_result()
run = pexpect.spawn(cmdstrs, encoding='utf-8')
try:
index = run.expect(["Two-factor Authentication","Invalid username and password combination", pexpect.EOF, pexpect.TIMEOUT],timeout=timeout)
if index == 0:
count = 1
if timeout == -1:
timeout = 60*60*24
while True and count<timeout/3:
code = developer_auth_code("get",user_obj,developer_email)
if code:
run.sendline(code)
try:
err = run.expect(["Unauthorized Access", pexpect.EOF, pexpect.TIMEOUT])
if err == 0:
result['exit_code'] = 2
result['return_info'] = 'Unauthorized Access'
elif err == 1:
result['exit_code'] = 0
result['return_info'] = 'Verify Code Success'
else:
result['exit_code'] = 3
result['return_info'] = 'Verify Code TimeOut or UnKnown Error'
developer_auth_code("del", user_obj, developer_email)
return result
except Exception as e:
print(e)
developer_auth_code("del", user_obj, developer_email)
result['exit_code'] = 0
result['return_info'] = 'Success'
return result
count+=1
time.sleep(3)
elif index == 1:
result['exit_code'] = 1
result['return_info'] = 'Invalid username and password combination'
elif index == 2:
result['exit_code'] = 0
result['return_info'] = 'Alreay Success'
else:
result['exit_code'] = 4
result['return_info'] = 'Code TimeOut or UnKnown Error'
except Exception as e:
print(e)
return result
def shell_command(cmdstrs,timeout):
result = default_result()
result['return_info'] = ''
shell_start_time = time.time()
child = Popen(cmdstrs, shell=True, stdout=PIPE, stderr=PIPE)
if timeout:
while child.poll() is None:
time.sleep(1)
now = time.time()
if int(now - shell_start_time) > timeout:
os.kill(child.pid, signal.SIGKILL)
os.waitpid(-1, os.WNOHANG)
result['exit_code']=126
return result
out, err = child.communicate()
if err:
result['err_info'] = err
shell_end_time = time.time()
result['shell_run_time'] = shell_end_time - shell_start_time
out = out.strip(b'\n')
result['return_info'] = out
result['exit_code'] = child.returncode
logging.info(u'shell: %s - %s%s - %s%d' % (cmdstrs, 'return_info: ', out, 'exit_code: ', child.returncode))
return result
def use_user_pass(hostip,port,user,passwd,cmdstrs):
result = default_result()
checkinfo = portisonline(hostip, port)
if checkinfo["code"] != 0:
result['shell_run_time'] = 0
result['return_info'] = json.dumps(checkinfo)
result['exit_code'] = checkinfo["code"]
else:
conn = SSHConnection(hostip, port, user, passwd)
result['return_info'] = ''
shell_start_time = time.time()
out=conn.exec_command(cmdstrs)
shell_end_time = time.time()
result['shell_run_time'] = shell_end_time - shell_start_time
outs =str(out['infos'],'utf-8')
outs = outs.strip('\n')
result['return_info'] = outs
result['exit_code'] = out['status']
# logging.info(u'shell: %s - %s%s - %s%d' % (cmdstrs, 'return_info: ', out, 'exit_code: ', out['status']))
print('host: %s user:%s - shell: %s - %s%s - %s%d' % (hostip,user,cmdstrs, 'return_info: ', out, 'exit_code: ', out['status']))
conn.close()
return result