diff --git a/connect.py b/connect.py index b998bf21c..83db6b855 100644 --- a/connect.py +++ b/connect.py @@ -24,7 +24,7 @@ if django.get_version() != '1.6': from django.contrib.sessions.models import Session from jumpserver.api import ServerError, User, Asset, PermRole, AssetGroup, get_object, mkdir, get_asset_info, get_role from jumpserver.api import logger, Log, TtyLog, get_role_key, CRYPTOR, bash, get_tmp_dir -from jperm.perm_api import gen_resource, get_group_asset_perm, get_group_user_perm, user_have_perm +from jperm.perm_api import gen_resource, get_group_asset_perm, get_group_user_perm, user_have_perm, PermRole from jumpserver.settings import LOG_DIR from jperm.ansible_api import Command, MyRunner from jlog.log_api import escapeString diff --git a/jumpserver/urls.py b/jumpserver/urls.py index 3e3efede8..3be4e631a 100644 --- a/jumpserver/urls.py +++ b/jumpserver/urls.py @@ -8,6 +8,7 @@ urlpatterns = patterns('', (r'^skin_config/$', 'jumpserver.views.skin_config'), (r'^login/$', 'jumpserver.views.Login'), (r'^logout/$', 'jumpserver.views.Logout'), + (r'^exec_cmd/$', 'jumpserver.views.exec_cmd'), (r'^file/upload/$', 'jumpserver.views.upload'), (r'^file/download/$', 'jumpserver.views.download'), (r'^setting', 'jumpserver.views.setting'), diff --git a/jumpserver/views.py b/jumpserver/views.py index 04e906b2d..5eb0cac80 100644 --- a/jumpserver/views.py +++ b/jumpserver/views.py @@ -360,3 +360,8 @@ def download(request): return render_to_response('download.html', locals(), context_instance=RequestContext(request)) +@login_required(login_url='/login') +def exec_cmd(request): + role_name = request.GET.get('role_name') + web_terminal_uri = 'ws://%s/exec?role=%s' % (WEB_SOCKET_HOST, role_name) + return my_render('exec_cmd.html', locals(), request) diff --git a/run_websocket.py b/run_websocket.py index 742220c6d..0bdd609cf 100644 --- a/run_websocket.py +++ b/run_websocket.py @@ -23,8 +23,8 @@ from tornado.options import define, options from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE, IN_MODIFY, AsyncNotifier import select -from connect import Tty, User, Asset, PermRole, logger, get_object -from connect import TtyLog, Log, Session, user_have_perm +from connect import Tty, User, Asset, PermRole, logger, get_object, PermRole, gen_resource +from connect import TtyLog, Log, Session, user_have_perm, get_group_user_perm, Command try: import simplejson as json @@ -67,22 +67,6 @@ def require_auth(role='user'): except AttributeError: pass logger.warning('Websocket: Request auth failed.') - # asset_id = int(request.get_argument('id', 9999)) - # print asset_id - # asset = Asset.objects.filter(id=asset_id) - # if asset: - # asset = asset[0] - # request.asset = asset - # else: - # request.close() - # - # if user: - # user = user[0] - # request.user = user - # - # else: - # print("No session user.") - # request.close() return _deco2 return _deco @@ -138,6 +122,7 @@ class Application(tornado.web.Application): (r'/monitor', MonitorHandler), (r'/terminal', WebTerminalHandler), (r'/kill', WebTerminalKillHandler), + (r'/exec', ExecHandler), ] setting = { @@ -225,6 +210,61 @@ class WebTerminalKillHandler(tornado.web.RequestHandler): logger.debug('Websocket: web terminal client num: %s' % len(WebTerminalHandler.clients)) +class ExecHandler(tornado.websocket.WebSocketHandler): + clients = [] + tasks = [] + + def __init__(self, *args, **kwargs): + self.id = 0 + self.user = None + self.role = None + self.cmd = None + self.assets = [] + self.perm = {} + super(ExecHandler, self).__init__(*args, **kwargs) + + def check_origin(self, origin): + return True + + @require_auth('user') + def open(self): + logger.debug('Websocket: Open exec request') + role_name = self.get_argument('role', 'dev') + self.role = get_object(PermRole, name=role_name) + self.perm = get_group_user_perm(self.user) + roles = self.perm.get('role').keys() + if self.role not in roles: + self.write_message('No perm that role %s' % role_name) + self.close() + self.assets = self.perm.get('role').get(self.role).get('asset') + res = gen_resource({'user': self.user, 'asset': self.assets, 'role': self.role}) + logger.debug('Web执行命令res: %s' % res) + self.cmd = Command(res) + message = '有权限的主机:' + ', '.join([asset.hostname for asset in self.assets]) + self.write_message(message) + + def on_message(self, message): + data = json.loads(message) + pattern = data.get('pattern', '') + command = data.get('command', '') + asset_name_str = '匹配主机: ' + if pattern and command: + for inv in self.cmd.inventory.get_hosts(pattern=pattern): + asset_name_str += '\n%s' % inv.name + self.write_message(asset_name_str) + self.write_message('Ansible> %s\n\n' % command) + result = self.cmd.run(module_name='shell', command=command, pattern=pattern) + for k, v in result.items(): + for host, output in v.items(): + if k == 'ok': + header = "[ %s => %s]\n" % (host, 'Ok') + else: + header = "[ %s => %s]\n" % (host, 'failed') + self.write_message(header) + self.write_message(output) + self.write_message('\n\n') + + class WebTerminalHandler(tornado.websocket.WebSocketHandler): clients = [] tasks = [] diff --git a/templates/jasset/asset_list.html b/templates/jasset/asset_list.html index 8373f8a0f..3f9c6c6cf 100644 --- a/templates/jasset/asset_list.html +++ b/templates/jasset/asset_list.html @@ -148,6 +148,7 @@ 修改 + {% include 'paginator.html' %} @@ -175,6 +176,46 @@ } }); + $('#exec_cmd').click(function(){ + var url='/jlog/get_role_name/?id={{ user.id }}'; + var href = $(this).attr('href'); + $.ajax({ + type: 'GET', + url: url, + data: {}, + success: function(data){ + var dataArray = data.split(','); + if (dataArray.length == 1 && data != 'error'){ + var title = 'Jumpserver Exec Terminal'; + layer.open({ + type: 2, + title: title, + maxmin: true, + shade: false, + area: ['628px', '452px'], + content: new_url+data + }); + //window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no'); + } else if (dataArray.length == '1' && data == 'error'){ + layer.alert('没有授权角色') + } else { + aUrl = ''; + $.each(dataArray, function(index, value){ + aUrl += '' + value + ' ' + }); + layer.alert(aUrl, { + skin: 'layui-layer-molv', + title: '多个角色,请选择一个连接', + shade: false, + closeBtn: 0 + }) + } + } + }); + return false + + }); + $('.conn').click(function(){ var url='/jlog/get_role_name/?id=' + $(this).attr('value'); var href = $(this).attr('href'); diff --git a/templates/jlog/log_monitor.html b/templates/jlog/log_monitor.html deleted file mode 100644 index 8f3c1ef3d..000000000 --- a/templates/jlog/log_monitor.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - Jumpserver | 开源跳板机系统 - - - {% include 'link_css.html' %} - {% include 'head_script.html' %} - - - - -
-
-
-
-
实时监控
-
- -
- 你好
-
-
-
-
- - - {% block self_footer_js %} - - {% endblock %} -