文件上传日志

pull/26/head
ibuler 2015-12-03 23:24:34 +08:00
parent 9233fef63f
commit 6975acfc8a
11 changed files with 455 additions and 85 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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进程 """

View File

@ -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()

View File

@ -0,0 +1,200 @@
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-primary"><b></b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div>
<div class="text-left">
<table class="table">
<tr>
<td class="text-navy">ID</td>
<td>{{ user.id }}</td>
</tr>
<tr>
<td class="text-navy">用户名</td>
<td>{{ user.username }}</td>
</tr>
<tr>
<td class="text-navy">来源IP</td>
<td>{{ user.name }}</td>
</tr>
<tr>
<td class="text-navy">角色</td>
<td>{{ user.id | get_role }}</td>
</tr>
<tr>
<td class="text-navy">Email</td>
<td>{{ user.email }}</td>
</tr>
<tr>
<td class="text-navy">激活</td>
<td>{{ user.is_active|bool2str }}</td>
</tr>
<tr>
<td class="text-navy">添加日期</td>
<td>{{ user.date_joined|date:"Y-m-d H:i:s" }}</td>
</tr>
<tr>
<td class="text-navy">最后登录</td>
<td>{{ user.last_login|date:"Y-m-d H:i:s" }}</td>
</tr>
<tr>
<td class="text-navy">所在用户组</td>
<td>
<table class="table">
{% for group in user.group.all %}
<tr>
<td><a href="/jperm/perm_edit/?id={{ group.id }}">{{ group.name }}</a></td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>授权主机/组</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">Config option 1</a>
</li>
<li><a href="#">Config option 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content ibox-heading">
<h3>用户的所有授权主机</h3>
<small><i class="fa fa-map-marker"></i> 这里包含了用户所有的主机组和组下的主机.</small>
</div>
<div class="ibox-content inspinia-timeline">
{# {% for group in user|get_user_asset_group %}#}
{# <div class="timeline-item">#}
{# <div class="row">#}
{# <div class="col-xs-3 date">#}
{# <i class="fa fa-repeat"></i>#}
{# <b><a href="/jperm/perm_list/?uid={{ user.id }}&agid={{ group.id }}">{{ group.name }}</a></b>#}
{# <br>#}
{# <small class="text-navy">共: {{ group | group_asset_list_count }}台</small>#}
{# </div>#}
{# <div class="col-xs-7 content no-top-border">#}
{# <p class="m-b-xs"><strong>{{ group.comment }}</strong></p>#}
{# <p>#}
{# {% for asset in group|group_asset_list %}#}
{# {{ asset.ip }}<br>#}
{# {% endfor %}#}
{# </p>#}
{# <p></p>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# {% endfor %}#}
{# {% if not user|get_user_asset_group %}#}
{# (无)#}
{# {% endif %}#}
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>登录记录</h5>
<div class="ibox-tools">
<span class="label label-warning-light">最近登录</span>
</div>
</div>
<div class="ibox-content">
<div id="last">
<div class="feed-activity-list" >
{% for log in logs_last %}
<div class="feed-element">
<a href="profile.html" class="pull-left">
<img alt="image" class="img-circle" src="/static/img/{{ session_role_id | to_avatar }}.png">
</a>
<div class="media-body ">
{# <small class="pull-right">{{ log.start_time|time_delta }}</small>#}
<small class="pull-right">{{ log.start_time }}</small>
<strong>{{ log.user }}</strong> 登录了 <span class="text-navy">{{ log.host }}. </span><br>
<small class="text-muted">{{ log.start_time|date:"Y-m-d H:i:s" }}</small>
</div>
</div>
{% endfor %}
{% if not logs_last %}
(暂无)
{% endif %}
</div>
{% if logs_num > 10 %}
<button id="show" class="btn btn-primary btn-block m-t"><i class="fa fa-arrow-down"></i> Show All</button>
{% endif %}
</div>
<div id="all" style="display: none">
<div class="feed-activity-list" >
{% for log in logs_all %}
<div class="feed-element">
<a href="profile.html" class="pull-left">
<img alt="image" class="img-circle" src="/static/img/{{ session_role_id | to_avatar }}.png">
</a>
<div class="media-body ">
<small class="pull-right">{{ log.start_time }}</small>
{# <small class="pull-right">{{ log.start_time|time_delta }}</small>#}
<strong>{{ log.user }}</strong> 登录了 <span class="text-navy">{{ log.host }}. </span><br>
<small class="text-muted">{{ log.start_time|date:"Y-m-d H:i:s" }}</small>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$('#show').click(function(){
$('#last').css('display', 'none');
$('#all').css('display', 'block');
})
})
</script>
{% endblock %}

View File

@ -9,73 +9,81 @@
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> 批量命令日志 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
<div class="col-sm-10">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> 批量命令日志 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
</div>
<div class="ibox-content">
<div class="panel-options">
<ul class="nav nav-tabs">
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li class="active"><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
</ul>
</div>
<br/>
<div class="">
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
-搜索-
</button>
<div class="ibox-content">
<div class="panel-options">
<ul class="nav nav-tabs">
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li class="active"><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="/jlog/log_list/file/" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
</ul>
</div>
<br/>
<div class="">
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="keyword" name="keyword" value="{{ keyword }}" placeholder="Search">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
-搜索-
</button>
</div>
</div>
</div>
</form>
</div>
<div class="tab-content">
<table class="table table-striped table-bordered table-hover ">
<thead>
<tr>
<th class="text-center"> ID </th>
<th class="text-center"> 用户名 </th>
<th class="text-center"> 主机 </th>
<th class="text-center"> 命令 </th>
<th class="text-center"> 来源IP </th>
<th class="text-center"> 时间 </th>
</tr>
</thead>
<tbody>
</form>
</div>
<div class="tab-content">
<table class="table table-striped table-bordered table-hover ">
<thead>
<tr>
<th class="text-center"> ID </th>
<th class="text-center"> 用户名 </th>
<th class="text-center"> 主机 </th>
<th class="text-center"> 命令 </th>
<th class="text-center"> 来源IP </th>
<th class="text-center"> 时间 </th>
<th class="text-center"> 详情 </th>
{% for post in contacts.object_list %}
<tr class="gradeX">
<td class="text-center"> {{ post.id }} </td>
<td class="text-center username"> {{ post.user }} </td>
<td class="text-center ip"> {{ post.host }} </td>
<td class="text-center ip"> {{ post.cmd }} </td>
<td class="text-center remote_ip"> {{ post.remote_ip }} </td>
<td class="text-center start_time"> {{ post.datetime|date:"Y-m-d H:i:s"}} </td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
</tr>
</thead>
<tbody>
{% for post in contacts.object_list %}
<tr class="gradeX">
<td class="text-center"> {{ post.id }} </td>
<td class="text-center username"> {{ post.user }} </td>
<td class="text-center ip"> {{ post.host | truncatechars:30 }} </td>
<td class="text-center ip"> {{ post.cmd | truncatechars:30 }} </td>
<td class="text-center remote_ip"> {{ post.remote_ip }} </td>
<td class="text-center start_time"> {{ post.datetime|date:"Y-m-d H:i:s"}} </td>
<td class="text-center">
<a href="../user_detail/?id={{ user.id }}" class="btn btn-xs btn-primary">详情</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
</div>
{% include 'paginator.html' %}
</div>
{% include 'paginator.html' %}
</div>
</div>
</div>

View File

@ -0,0 +1,109 @@
{% extends 'base.html' %}
{% block self_head_css_js %}
<link href="/static/css/plugins/datepicker/datepicker3.css" rel="stylesheet">
<link href="/static/css/plugins/chosen/chosen.css" rel="stylesheet">
<script src="/static/js/plugins/chosen/chosen.jquery.js"></script>
{% endblock %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-10">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> 上传下载日志 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="panel-options">
<ul class="nav nav-tabs">
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li class="active"><a href="/jlog/log_list/file/" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
</ul>
</div>
<br/>
<div class="">
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="keyword" name="keyword" value="{{ keyword }}" placeholder="Search">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
-搜索-
</button>
</div>
</div>
</form>
</div>
<div class="tab-content">
<table class="table table-striped table-bordered table-hover ">
<thead>
<tr>
<th class="text-center"> ID </th>
<th class="text-center"> 用户名 </th>
<th class="text-center"> 主机 </th>
<th class="text-center"> 文件 </th>
<th class="text-center"> 类型 </th>
<th class="text-center"> 来源IP </th>
<th class="text-center"> 时间 </th>
<th class="text-center"> 详情 </th>
</tr>
</thead>
<tbody>
{% for post in contacts.object_list %}
<tr class="gradeX">
<td class="text-center"> {{ post.id }} </td>
<td class="text-center"> {{ post.user }} </td>
<td class="text-center"> {{ post.host | truncatechars:30 }} </td>
<td class="text-center"> {{ post.filename | truncatechars:30 }} </td>
<td class="text-center"> {{ post.type }} </td>
<td class="text-center"> {{ post.remote_ip }} </td>
<td class="text-center"> {{ post.datetime|date:"Y-m-d H:i:s"}} </td>
<td class="text-center">
<a href="../user_detail/?id={{ user.id }}" class="btn btn-xs btn-primary">详情</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
</div>
{% include 'paginator.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function log_search(){
$.ajax({
type: "GET",
url: "/jlog/search/?env=offline",
data: $("#search_form").serialize(),
success: function (data) {
$(".tab-content").html(data);
}
});
}
</script>
{% endblock %}

View File

@ -55,6 +55,7 @@
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li class="active"><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="/jlog/log_list/file/" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
</ul>
</div>
<br/>

View File

@ -70,6 +70,7 @@
<li class="active"><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="/jlog/log_list/file/" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
</ul>
</div>
<br/>

View File

@ -8,7 +8,7 @@
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-primary"><b>授权规则</b></span>
<span class="label label-primary"><b>{{ role.name }} - 授权规则</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
@ -54,7 +54,7 @@
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-primary"><b>授权用户/用户组</b></span>
<span class="label label-primary"><b>{{ role.name }} - 授权用户/用户组</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
@ -100,7 +100,7 @@
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-primary"><b>授权主机/主机组</b></span>
<span class="label label-primary"><b>{{ role.name }} - 授权主机/主机组</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
@ -148,7 +148,7 @@
<div class="col-sm-6">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-primary"><b>推送主机</b></span>
<span class="label label-primary"><b>{{ role.name }} - 推送主机</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
@ -212,7 +212,7 @@
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-danger"><b>未推送主机</b></span>
<span class="label label-danger"><b>{{ role.name }} - 未推送主机</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>

View File

@ -27,19 +27,24 @@
<li class="rule perm_rule_add">
<a href="/jperm/rule/">授权规则</a>
</li>
<li class="role">
<a href="/jperm/role/">系统角色</a>
</li>
<li class="sudo">
<a href="/jperm/sudo/">Sudo命令</a>
</li>
</ul>
</li>
<li id="jlog">
<a href="/jlog/log_list/online/"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="label label-info pull-right"></span></a>
</li>
<li id="file">
<a href="#"><i class="fa fa-download"></i> <span class="nav-label">上传下载</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li class="upload"><a href="/file/upload/">文件上传</a></li>
<li class="download"><a href="/file/download/">文件下载</a></li>
</ul>
</li>
<li id="setting">
<a href="/setting/"><i class="fa fa-gears"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a>
</li>