diff --git a/connect.py b/connect.py index 0e0f6b35a..7111436f4 100644 --- a/connect.py +++ b/connect.py @@ -28,7 +28,7 @@ from jperm.perm_api import gen_resource, get_group_asset_perm, get_group_user_pe from jumpserver.settings import LOG_DIR from jperm.ansible_api import Command, MyRunner # from jlog.log_api import escapeString -from jlog.models import ExecLog +from jlog.models import ExecLog, FileLog login_user = get_object(User, username=getpass.getuser()) remote_ip = os.popen("who -m | awk '{ print $5 }'").read().strip('()\n') @@ -601,16 +601,23 @@ class Nav(object): print "匹配主机:\n" for inv in runner.inventory.get_hosts(pattern=pattern): print inv.name - asset_name_str += inv.name - print + asset_name_str += '%s ' % inv.name + + if not asset_name_str: + color_print('没有匹配主机') + print + continue tmp_dir = get_tmp_dir() logger.debug('Upload tmp dir: %s' % tmp_dir) os.chdir(tmp_dir) bash('rz') - check_notempty = os.listdir(tmp_dir) - if not check_notempty: + filename_str = ' '.join(os.listdir(tmp_dir)) + if not filename_str: print color_print("上传文件为空") continue + logger.debug('上传文件: %s' % filename_str) + FileLog(user=self.user.name, host=asset_name_str, filename=filename_str, + remote_ip=remote_ip, type='upload').save() runner = MyRunner(res) runner.run('copy', module_args='src=%s dest=%s directory_mode' % (tmp_dir, tmp_dir), pattern=pattern) @@ -644,9 +651,14 @@ class Nav(object): 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): - print inv.name + asset_name_str += '%s ' % inv.name + print ' %s' % inv.name + if not asset_name_str: + color_print('没有匹配主机') + continue print while True: tmp_dir = get_tmp_dir() @@ -655,19 +667,24 @@ class Nav(object): file_path = raw_input("\033[1;32mPath>:\033[0m ").strip() if file_path == 'q': break + FileLog(user=self.user.name, host=asset_name_str, filename=file_path, type='download', + remote_ip=remote_ip).save() runner.run('fetch', module_args='src=%s dest=%s' % (file_path, tmp_dir), pattern=pattern) ret = runner.results logger.debug('Download file result: %s' % ret) os.chdir('/tmp') tmp_dir_name = os.path.basename(tmp_dir) + if not os.listdir(tmp_dir): + color_print('下载全部失败') + continue bash('tar czf %s.tar.gz %s && sz %s.tar.gz' % (tmp_dir, tmp_dir_name, tmp_dir)) if ret.get('failed'): - error = '文件名称: %s 下载失败: [ %s ] \n下载成功 [ %s ]' % \ + error = '文件名称: %s \n下载失败: [ %s ] \n下载成功 [ %s ]' % \ ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('failed').keys()), ', '.join(ret.get('ok').keys())) color_print(error) else: - msg = '文件名称: %s 下载成功 [ %s ]' % ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('ok').keys())) + msg = '文件名称: %s \n下载成功 [ %s ]' % ('%s.tar.gz' % tmp_dir_name, ', '.join(ret.get('ok').keys())) color_print(msg, 'green') print except IndexError: diff --git a/jlog/models.py b/jlog/models.py index f37105216..ef1f81a33 100644 --- a/jlog/models.py +++ b/jlog/models.py @@ -35,3 +35,13 @@ class ExecLog(models.Model): remote_ip = models.CharField(max_length=100) datetime = models.DateTimeField(auto_now=True) + +class FileLog(models.Model): + user = models.CharField(max_length=100) + host = models.TextField() + filename = models.TextField() + type = models.CharField(max_length=20) + remote_ip = models.CharField(max_length=100) + datetime = models.DateTimeField(auto_now=True) + + diff --git a/jlog/views.py b/jlog/views.py index 85d953f86..9b492fa9a 100644 --- a/jlog/views.py +++ b/jlog/views.py @@ -8,7 +8,7 @@ from jperm.perm_api import user_have_perm from django.http import HttpResponseNotFound from jlog.log_api import renderTemplate -from jlog.models import Log, ExecLog +from jlog.models import Log, ExecLog, FileLog from jumpserver.settings import WEB_SOCKET_HOST @@ -24,8 +24,16 @@ def log_list(request, offset): if offset == 'online': posts = Log.objects.filter(is_finished=False).order_by('-start_time') - if offset == 'exec': + elif offset == 'exec': posts = ExecLog.objects.all().order_by('-id') + keyword = request.GET.get('keyword', '') + if keyword: + posts = posts.filter(Q(user__icontains=keyword)|Q(host__icontains=keyword)|Q(cmd__icontains=keyword)) + elif offset == 'file': + posts = FileLog.objects.all().order_by('-id') + keyword = request.GET.get('keyword', '') + if keyword: + posts = posts.filter(Q(user__icontains=keyword)|Q(host__icontains=keyword)|Q(filename__icontains=keyword)) else: posts = Log.objects.filter(is_finished=True).order_by('-start_time') username_all = set([log.user for log in Log.objects.all()]) @@ -59,6 +67,11 @@ def log_list(request, offset): return render_to_response('jlog/log_%s.html' % offset, locals(), context_instance=RequestContext(request)) +@require_role('admin') +def log_detail(request): + return my_render('jlog/exec_detail.html', locals(), request) + + @require_role('admin') def log_kill(request): """ 杀掉connect进程 """ diff --git a/jumpserver/views.py b/jumpserver/views.py index 20003e9c3..cd646214f 100644 --- a/jumpserver/views.py +++ b/jumpserver/views.py @@ -15,7 +15,7 @@ from jumpserver.api import * from jumpserver.models import Setting from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required -from jlog.models import Log +from jlog.models import Log, FileLog from jperm.perm_api import get_group_user_perm, gen_resource from jasset.models import Asset, IDC from jperm.ansible_api import MyRunner @@ -287,14 +287,14 @@ def setting(request): def upload(request): user = request.user assets = get_group_user_perm(user).get('asset').keys() - asset_select = [] if request.method == 'POST': + remote_ip = request.META.get('REMOTE_ADDR') asset_ids = request.POST.getlist('asset_ids', '') upload_files = request.FILES.getlist('file[]', None) date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S") upload_dir = get_tmp_dir() - filenames = {} + # file_dict = {} for asset_id in asset_ids: asset_select.append(get_object(Asset, id=asset_id)) @@ -302,9 +302,12 @@ def upload(request): illegal_asset = set(asset_select).issubset(set(assets)) return HttpResponse('没有权限的服务器 %s' % ','.join([asset.hostname for asset in illegal_asset])) + FileLog(user=request.user.username, host=' '.join([asset.hostname for asset in asset_select]), + filename=' '.join([f.name for f in upload_files]), type='upload', remote_ip=remote_ip).save() + for upload_file in upload_files: file_path = '%s/%s' % (upload_dir, upload_file.name) - filenames[upload_file.name] = file_path + # file_dict[upload_file.name] = file_path with open(file_path, 'w') as f: for chunk in upload_file.chunks(): f.write(chunk) @@ -329,9 +332,9 @@ def upload(request): def download(request): user = request.user assets = get_group_user_perm(user).get('asset').keys() - asset_select = [] if request.method == 'POST': + remote_ip = request.META.get('REMOTE_ADDR') asset_ids = request.POST.getlist('asset_ids', '') file_path = request.POST.get('file_path') date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S") @@ -342,6 +345,9 @@ def download(request): if not set(asset_select).issubset(set(assets)): illegal_asset = set(asset_select).issubset(set(assets)) return HttpResponse('没有权限的服务器 %s' % ','.join([asset.hostname for asset in illegal_asset])) + + FileLog(user=request.user.username, host=' '.join([asset.hostname for asset in asset_select]), + filename=file_path, type='download', remote_ip=remote_ip).save() res = gen_resource({'user': user, 'asset': asset_select}) runner = MyRunner(res) runner.run('fetch', module_args='src=%s dest=%s' % (file_path, upload_dir), pattern='*') @@ -349,7 +355,7 @@ def download(request): os.chdir('/tmp') tmp_dir_name = os.path.basename(upload_dir) tar_file = '%s.tar.gz' % upload_dir - bash('tar czf %s %s && sz %s.tar.gz' % (tar_file, tmp_dir_name, upload_dir)) + bash('tar czf %s %s' % (tar_file, tmp_dir_name)) f = open(tar_file) data = f.read() f.close() diff --git a/templates/jlog/exec_detail.html b/templates/jlog/exec_detail.html new file mode 100644 index 000000000..45eb21d4d --- /dev/null +++ b/templates/jlog/exec_detail.html @@ -0,0 +1,200 @@ +{% extends 'base.html' %} +{% load mytags %} +{% block content %} + {% include 'nav_cat_bar.html' %} +
+
+
+
+
+ +
+ + + + + + + + + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID{{ user.id }}
用户名{{ user.username }}
来源IP{{ user.name }}
角色{{ user.id | get_role }}
Email{{ user.email }}
激活{{ user.is_active|bool2str }}
添加日期{{ user.date_joined|date:"Y-m-d H:i:s" }}
最后登录{{ user.last_login|date:"Y-m-d H:i:s" }}
所在用户组 + + {% for group in user.group.all %} + + + + {% endfor %} +
{{ group.name }}
+
+
+
+
+
+
+
+
+
+
授权主机/组
+ +
+
+

用户的所有授权主机

+ 这里包含了用户所有的主机组和组下的主机. +
+
+{# {% for group in user|get_user_asset_group %}#} +{#
#} +{#
#} +{#
#} +{# #} +{# {{ group.name }}#} +{#
#} +{# 共: {{ group | group_asset_list_count }}台#} +{#
#} +{#
#} +{#

{{ group.comment }}

#} +{#

#} +{# {% for asset in group|group_asset_list %}#} +{# {{ asset.ip }}
#} +{# {% endfor %}#} +{#

#} +{#

#} +{#
#} +{#
#} +{#
#} +{# {% endfor %}#} +{# {% if not user|get_user_asset_group %}#} +{# (无)#} +{# {% endif %}#} +
+
+
+ +
+
+
+
登录记录
+
+ 最近登录 +
+
+
+
+
+ {% for log in logs_last %} +
+ + image + +
+{# {{ log.start_time|time_delta }}#} + {{ log.start_time }} + {{ log.user }} 登录了 {{ log.host }}.
+ {{ log.start_time|date:"Y-m-d H:i:s" }} +
+
+ {% endfor %} + {% if not logs_last %} + (暂无) + {% endif %} +
+ {% if logs_num > 10 %} + + {% endif %} +
+ + +
+
+
+
+
+ + + + +{% endblock %} \ No newline at end of file diff --git a/templates/jlog/log_exec.html b/templates/jlog/log_exec.html index d1e096c82..9cd7a6b4f 100644 --- a/templates/jlog/log_exec.html +++ b/templates/jlog/log_exec.html @@ -9,73 +9,81 @@
-
-
-
批量命令日志
-
- - - - - - - - - +
+
+
+
批量命令日志
+
-
-
- -
-
-
diff --git a/templates/jperm/perm_role_detail.html b/templates/jperm/perm_role_detail.html index d0cc9a00d..0c5ca95ea 100644 --- a/templates/jperm/perm_role_detail.html +++ b/templates/jperm/perm_role_detail.html @@ -8,7 +8,7 @@