pull/26/head
ibuler 2015-12-08 23:19:39 +08:00
parent e408414631
commit 0309213ccc
3 changed files with 36 additions and 42 deletions

View File

@ -49,8 +49,10 @@ def color_print(msg, color='red', exits=False):
"""
color_msg = {'blue': '\033[1;36m%s\033[0m',
'green': '\033[1;32m%s\033[0m',
'red': '\033[1;31m%s\033[0m'}
msg = color_msg.get(color, 'blue') % msg
'yellow': '\033[1;33m%s\033[0m',
'red': '\033[1;31m%s\033[0m',
'info': '\033[32m%s\033[0m'}
msg = color_msg.get(color, 'red') % msg
print msg
if exits:
time.sleep(2)
@ -69,7 +71,7 @@ class Tty(object):
A virtual tty class
一个虚拟终端类实现连接ssh和记录日志基类
"""
def __init__(self, user, asset, role):
def __init__(self, user, asset, role, login_type='ssh'):
self.username = user.username
self.asset_name = asset.hostname
self.ip = None
@ -78,10 +80,8 @@ class Tty(object):
self.asset = asset
self.user = user
self.role = role
self.ssh = None
self.remote_ip = ''
self.connect_info = None
self.login_type = 'ssh'
self.login_type = login_type
self.vim_flag = False
self.ps1_pattern = re.compile('\[.*@.*\][\$#]')
self.vim_data = ''
@ -241,18 +241,18 @@ class Tty(object):
mkdir(today_connect_log_dir, mode=0777)
except OSError:
logger.debug('创建目录 %s 失败,请修改%s目录权限' % (today_connect_log_dir, tty_log_dir))
raise ServerError('Create %s failed, Please modify %s permission.' % (today_connect_log_dir, tty_log_dir))
raise ServerError('创建目录 %s 失败,请修改%s目录权限' % (today_connect_log_dir, tty_log_dir))
try:
log_file_f = open(log_file_path + '.log', 'a')
log_time_f = open(log_file_path + '.time', 'a')
except IOError:
logger.debug('创建tty日志文件失败, 请修改目录%s权限' % today_connect_log_dir)
raise ServerError('Create logfile failed, Please modify %s permission.' % today_connect_log_dir)
raise ServerError('创建tty日志文件失败, 请修改目录%s权限' % today_connect_log_dir)
if self.login_type == 'ssh': # 如果是ssh连接过来记录connect.py的pidweb terminal记录为日志的id
pid = os.getpid()
self.remote_ip = remote_ip # 获取远端IP
self.remote_ip = remote_ip # 获取远端IP
else:
pid = 0
@ -260,7 +260,7 @@ class Tty(object):
log_path=log_file_path, start_time=date_today, pid=pid)
log.save()
if self.login_type == 'web':
log.pid = log.id
log.pid = log.id # 设置log id为websocket的id, 然后kill时干掉websocket
log.save()
log_file_f.write('Start at %s\r\n' % datetime.datetime.now())
@ -271,17 +271,13 @@ class Tty(object):
获取需要登陆的主机的信息和映射用户的账号密码
"""
asset_info = get_asset_info(self.asset)
role_key = get_role_key(self.user, self.role)
role_key = get_role_key(self.user, self.role) # 获取角色的key因为ansible需要权限是600所以统一生成用户_角色key
role_pass = CRYPTOR.decrypt(self.role.password)
self.connect_info = {'user': self.user, 'asset': self.asset, 'ip': asset_info.get('ip'),
'port': int(asset_info.get('port')), 'role_name': self.role.name,
'role_pass': role_pass, 'role_key': role_key}
logger.debug("Connect: Host: %s Port: %s User: %s Pass: %s Key: %s" % (asset_info.get('ip'),
asset_info.get('port'),
self.role.name,
role_pass,
role_key))
return self.connect_info
connect_info = {'user': self.user, 'asset': self.asset, 'ip': asset_info.get('ip'),
'port': int(asset_info.get('port')), 'role_name': self.role.name,
'role_pass': role_pass, 'role_key': role_key}
logger.debug(connect_info)
return connect_info
def get_connection(self):
"""
@ -300,12 +296,13 @@ class Tty(object):
ssh.connect(connect_info.get('ip'),
port=connect_info.get('port'),
username=connect_info.get('role_name'),
password=connect_info.get('role_pass'),
key_filename=role_key,
look_for_keys=False)
self.ssh = ssh
look_for_keys=False,
allow_agent=False)
return ssh
except (paramiko.ssh_exception.AuthenticationException, paramiko.ssh_exception.SSHException):
logger.warning('Use ssh key %s Failed.' % role_key)
logger.warning(u'使用ssh key %s 失败, 尝试只使用密码' % role_key)
pass
ssh.connect(connect_info.get('ip'),
@ -320,7 +317,6 @@ class Tty(object):
except socket.error:
raise ServerError('端口可能不对 Connect SSH Socket Port Error, Please Correct it.')
else:
self.ssh = ssh
return ssh
@ -455,6 +451,9 @@ class SshTty(Tty):
class Nav(object):
"""
导航提示类
"""
def __init__(self, user):
self.user = user
self.search_result = {}
@ -466,9 +465,10 @@ class Nav(object):
Print prompt
打印提示导航
"""
msg = """\n\033[1;32m### 欢迎使用Jumpserver开源跳板机 ### \033[0m
msg = """\n\033[1;32m### 欢迎使用Jumpserver开源跳板机系统 ### \033[0m
1) 输入 \033[32mID\033[0m 直接登录.
2) 输入 \033[32m/\033[0m + \033[32mIP, 主机名, 主机别名 or 备注 \033[0m搜索.
2) 输入 \033[32m/\033[0m + \033[32mIP, 主机名 or 备注 \033[0m搜索.
3) 输入 \033[32mP/p\033[0m 显示您有权限的主机.
4) 输入 \033[32mG/g\033[0m 显示您有权限的主机组.
5) 输入 \033[32mG/g\033[0m\033[0m + \033[32m组ID\033[0m 显示该组下主机.
@ -503,17 +503,14 @@ class Nav(object):
user_asset_search = user_asset_all
self.search_result = dict(zip(range(len(user_asset_search)), user_asset_search))
print '\033[32m[%-3s] %-15s %-15s %-5s %-10s %s \033[0m' % ('ID', 'AssetName', 'IP', 'Port', 'Role', 'Comment')
color_print('[%-3s] %-15s %-15s %-5s %-10s %s' % ('ID', 'AssetName', 'IP', 'Port', 'Role', 'Comment'), 'info')
for index, asset in self.search_result.items():
# 获取该资产信息
asset_info = get_asset_info(asset)
# 获取该资产包含的角色
role = [str(role.name) for role in self.user_perm.get('asset').get(asset).get('role')]
if asset.comment:
print '[%-3s] %-15s %-15s %-5s %-10s %s' % (index, asset.hostname, asset.ip, asset_info.get('port'),
role, asset.comment)
else:
print '[%-3s] %-15s %-15s %-5s %-10s' % (index, asset.hostname, asset.ip, asset_info.get('port'), role)
print '[%-3s] %-15s %-15s %-5s %-10s %s' % (index, asset.hostname, asset.ip, asset_info.get('port'),
role, asset.comment)
print
def print_asset_group(self):
@ -521,8 +518,7 @@ class Nav(object):
打印用户授权的资产组
"""
user_asset_group_all = get_group_user_perm(self.user).get('asset_group', [])
print '\033[32m[%-3s] %-15s %s \033[0m' % ('ID', 'GroupName', 'Comment')
color_print('[%-3s] %-15s %s' % ('ID', 'GroupName', 'Comment'), 'info')
for asset_group in user_asset_group_all:
if asset_group.comment:
print '[%-3s] %-15s %s' % (asset_group.id, asset_group.name, asset_group.comment)
@ -540,7 +536,7 @@ class Nav(object):
roles = self.user_perm.get('role').keys()
if len(roles) > 1: # 授权角色数大于1
print '\033[32m[%-2s] %-15s \033[0m' % ('ID', '角色')
color_print('[%-2s] %-15s' % ('ID', '角色'), 'info')
role_check = dict(zip(range(len(roles)), roles))
for i, r in role_check.items():
@ -615,7 +611,7 @@ class Nav(object):
res = gen_resource({'user': self.user, 'asset': assets}, perm=self.user_perm)
runner = MyRunner(res)
asset_name_str = ''
print "匹配主机:\n"
print "匹配主机:"
for inv in runner.inventory.get_hosts(pattern=pattern):
print inv.name
asset_name_str += '%s ' % inv.name
@ -667,7 +663,6 @@ class Nav(object):
assets = self.user_perm.get('asset').keys()
res = gen_resource({'user': self.user, 'asset': assets}, perm=self.user_perm)
runner = MyRunner(res)
logger.debug("Muti download file res: %s" % res)
asset_name_str = ''
print "匹配用户:\n"
for inv in runner.inventory.get_hosts(pattern=pattern):

View File

@ -50,7 +50,7 @@ def set_log(level):
def get_asset_info(asset):
"""
获取资产的相关账号端口信息
获取资产的相关管理账号端口信息
"""
default = get_object(Setting, name='default')
info = {'hostname': asset.hostname, 'ip': asset.ip}

View File

@ -191,7 +191,6 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
class WebTty(Tty):
def __init__(self, *args, **kwargs):
super(WebTty, self).__init__(*args, **kwargs)
self.login_type = 'web'
self.ws = None
self.data = ''
self.input_mode = False
@ -328,10 +327,10 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
return
logger.debug('Websocket: request web terminal Host: %s User: %s Role: %s' % (asset.hostname, self.user.username,
login_role.name))
self.term = WebTty(self.user, asset, login_role)
self.term = WebTty(self.user, asset, login_role, login_type='web')
self.term.remote_ip = self.request.remote_ip
self.term.get_connection()
self.term.channel = self.term.ssh.invoke_shell(term='xterm')
ssh = self.term.get_connection()
self.term.channel = ssh.invoke_shell(term='xterm')
WebTerminalHandler.tasks.append(MyThread(target=self.forward_outbound))
WebTerminalHandler.clients.append(self)