Merge branches 'master' and 'wangyong' of gitcafe.com:ibuler/jumpserver

Conflicts:
	jasset/views.py
	jumpserver/views.py
pull/6/head
guanghongwei 2015-04-08 17:38:30 +08:00
commit b840db12a6
22 changed files with 959 additions and 203 deletions

View File

@ -3,6 +3,7 @@
import socket
import sys
import os
import re
import ast
import select
import time
@ -23,7 +24,7 @@ from django.core.exceptions import ObjectDoesNotExist
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
django.setup()
from juser.models import User
from jasset.models import Asset
from jasset.models import AssetAlias
from jlog.models import Log
from jumpserver.api import *
try:
@ -98,7 +99,7 @@ def log_record(username, host):
today_connect_log_dir = os.path.join(connect_log_dir, today)
log_filename = '%s_%s_%s.log' % (username, host, time_now)
log_file_path = os.path.join(today_connect_log_dir, log_filename)
dept_name = User.objects.get(username=username).dept
dept_name = User.objects.get(username=username).dept.name
pid = os.getpid()
ip_list = []
remote_ip = os.popen("who |grep `ps aux |gawk '{if ($2==%s) print $1}'` |gawk '{print $5}'|tr -d '()'" % pid).readlines()
@ -160,7 +161,6 @@ def posix_shell(chan, username, host):
chan.send(x)
finally:
timestamp_end = time.time()
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
log_file.write('Endtime is %s' % datetime.now())
log_file.close()
@ -168,14 +168,20 @@ def posix_shell(chan, username, host):
log.log_finished = False
log.end_time = datetime.now()
log.save()
print_prompt()
def get_user_host(username):
"""Get the hosts of under the user control."""
hosts_attr = {}
asset_all = user_perm_asset_api(username)
user = User.objects.get(username=username)
for asset in asset_all:
hosts_attr[asset.ip] = [asset.id, asset.comment]
alias = AssetAlias.objects.filter(user=user, host=asset)
if alias and alias[0].alias != '':
hosts_attr[asset.ip] = [asset.id, asset.ip, alias[0].alias]
else:
hosts_attr[asset.ip] = [asset.id, asset.ip, asset.comment]
return hosts_attr
@ -188,6 +194,20 @@ def get_user_hostgroup(username):
return groups_attr
def get_user_hostgroup_host(username, gid):
"""Get the hostgroup hosts of under the user control."""
hosts_attr = {}
user = User.objects.get(username=username)
hosts = user_perm_group_hosts_api(gid)
for host in hosts:
alias = AssetAlias.objects.filter(user=user, host=host)
if alias and alias[0].alias != '':
hosts_attr[host.ip] = [host.id, host.ip, alias[0].alias]
else:
hosts_attr[host.ip] = [host.id, host.ip, host.comment]
return hosts_attr
def get_connect_item(username, ip):
asset = get_object(Asset, ip=ip)
@ -219,13 +239,16 @@ def get_connect_item(username, ip):
def verify_connect(username, part_ip):
ip_matched = []
hosts_attr = get_user_host(username)
hosts = hosts_attr.keys()
ip_matched = [ip for ip in hosts if part_ip in ip]
hosts = hosts_attr.values()
for ip_info in hosts:
for info in ip_info[1:]:
if part_ip in info:
ip_matched.append(ip_info[1])
if len(ip_matched) > 1:
for ip in ip_matched:
print '%s -- %s' % (ip, hosts_attr[ip][1])
print '%s -- %s' % (ip, hosts_attr[ip][2])
elif len(ip_matched) < 1:
color_print('No Permission or No host.', 'red')
else:
@ -238,8 +261,9 @@ def print_prompt():
1) Type \033[32mIP ADDRESS\033[0m To Login.
2) Type \033[32mP/p\033[0m To Print The Servers You Available.
3) Type \033[32mG/g\033[0m To Print The Server Groups You Available.
4) Type \033[32mE/e\033[0m To Execute Command On Several Servers.
5) Type \033[32mQ/q\033[0m To Quit.
4) Type \033[32mG/g+gid\033[0m To Print The Server Group Hosts You Available.
5) Type \033[32mE/e\033[0m To Execute Command On Several Servers.
6) Type \033[32mQ/q\033[0m To Quit.
"""
print textwrap.dedent(msg)
@ -249,14 +273,27 @@ def print_user_host(username):
hosts = hosts_attr.keys()
hosts.sort()
for ip in hosts:
print '%s -- %s' % (ip, hosts_attr[ip][1])
print '%-15s -- %s' % (ip, hosts_attr[ip][2])
def print_user_hostgroup(username):
group_attr = get_user_hostgroup(username)
groups = group_attr.keys()
for g in groups:
print '%s -- %s' % (g, group_attr[g][1])
print "[%3s]%s -- %s" % (group_attr[g][0], g, group_attr[g][1])
def print_user_hostgroup_host(username, gid):
pattern = re.compile(r'\d+')
match = pattern.match(gid)
if match:
hosts_attr = get_user_hostgroup_host(username, gid)
hosts = hosts_attr.keys()
hosts.sort()
for ip in hosts:
print '%-15s -- %s' % (ip, hosts_attr[ip][2])
else:
color_print('No such group id, Please check it.', 'red')
def connect(username, password, host, port, login_name):
@ -377,9 +414,13 @@ if __name__ == '__main__':
elif option in ['G', 'g']:
print_user_hostgroup(LOGIN_NAME)
continue
elif option.startswith('g') or option.startswith('G'):
gid = option[1:].strip()
print_user_hostgroup_host(LOGIN_NAME, gid)
continue
elif option in ['E', 'e']:
exec_cmd_servers(LOGIN_NAME)
elif option in ['Q', 'q']:
elif option in ['Q', 'q', 'exit']:
sys.exit()
else:
try:

View File

@ -1,6 +1,6 @@
import datetime
from django.db import models
from juser.models import UserGroup, DEPT
from juser.models import User, UserGroup, DEPT
class IDC(models.Model):
@ -44,3 +44,12 @@ class Asset(models.Model):
def __unicode__(self):
return self.ip
class AssetAlias(models.Model):
user = models.ForeignKey(User)
host = models.ForeignKey(Asset)
alias = models.CharField(max_length=100, blank=True, null=True)
def __unicode__(self):
return self.comment

View File

@ -13,13 +13,14 @@ urlpatterns = patterns('',
url(r'^idc_edit/$', edit_idc),
url(r'^idc_detail/$', detail_idc),
url(r'^idc_del/(\w+)/$', del_idc),
url(r'^jgroup_add/$', add_group),
url(r'^group_add/$', add_group),
url(r'^group_edit/$', edit_group),
url(r'^jgroup_list/$', list_group),
url(r'^group_list/$', list_group),
url(r'^group_detail/$', detail_group),
url(r'^group_del_host/(\w+)/$', group_del_host),
url(r'^group_del/(\w+)/$', group_del),
url(r'^host_del/(\w+)/$', host_del),
url(r'^host_edit/$', host_edit),
url(r'^host_edit/batch/$', batch_host_edit),
url(r'^host_edit_common/batch/$', batch_host_edit_common),
)

View File

@ -6,9 +6,11 @@ from django.db.models import Q
from django.template import RequestContext
from django.shortcuts import render_to_response
from models import IDC, Asset, BisGroup
from jasset.models import IDC, Asset, BisGroup, AssetAlias
from juser.models import UserGroup, DEPT
from jumpserver.views import jasset_host_edit, pages
from jperm.models import Perm, SudoPerm
from jumpserver.views import pages
from jumpserver.api import *
cryptor = PyCrypt(KEY)
@ -51,6 +53,43 @@ def f_add_host(ip, port, idc, jtype, group, dept, active, comment, username='',
a.save()
def jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_dept, j_active, j_comment, j_user='', j_password=''):
groups, depts = [], []
is_active = {u'': '1', u'': '2'}
login_types = {'LDAP': 'L', 'MAP': 'M'}
for group in j_group[0].split():
c = BisGroup.objects.get(name=group.strip())
groups.append(c)
print j_dept
for d in j_dept[0].split():
p = DEPT.objects.get(name=d.strip())
depts.append(p)
j_type = login_types[j_type]
j_idc = IDC.objects.get(name=j_idc)
a = Asset.objects.get(id=j_id)
if j_type == 'M':
a.ip = j_ip
a.port = j_port
a.login_type = j_type
a.idc = j_idc
a.is_active = j_active
a.comment = j_comment
a.username = j_user
a.password = j_password
else:
a.ip = j_ip
a.port = j_port
a.idc = j_idc
a.login_type = j_type
a.is_active = is_active[j_active]
a.comment = j_comment
a.save()
a.bis_group = groups
a.dept = depts
a.save()
@require_admin
def add_host(request):
login_types = {'L': 'LDAP', 'M': 'MAP'}
@ -152,12 +191,6 @@ def batch_host_edit(request):
j_group = request.POST.getlist(j_group)
j_active = request.POST.get(j_active).strip()
j_comment = request.POST.get(j_comment).strip()
print j_dept, j_group
#
# if is_group_admin(request) and not validate(request, asset=[j_id]):
# emg = u'删除失败,您无权操作!'
# print 'hehe'
# return HttpResponseRedirect('/jasset/host_list/')
if j_type == 'M':
j_user = "editable[" + str(i) + "][j_user]"
@ -165,13 +198,36 @@ def batch_host_edit(request):
j_user = request.POST.get(j_user).strip()
password = request.POST.get(j_password).strip()
j_password = cryptor.encrypt(password)
jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_dept, j_active, j_comment, j_user, j_password)
jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_dept, j_active, j_comment, j_user,
j_password)
else:
jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_dept, j_active, j_comment)
return render_to_response('jasset/host_list.html')
@require_login
def batch_host_edit_common(request):
user_id = request.session.get('user_id', '')
u = User.objects.get(id=user_id)
if request.method == 'POST':
len_table = request.POST.get('len_table')
for i in range(int(len_table)):
j_id = "editable[" + str(i) + "][j_id]"
j_alias = "editable[" + str(i) + "][j_alias]"
j_id = request.POST.get(j_id).strip()
j_alias = request.POST.get(j_alias).strip()
a = Asset.objects.get(id=j_id)
asset_alias = AssetAlias.objects.filter(user=u, host=a)
if asset_alias:
asset_alias = asset_alias[0]
asset_alias.alias = j_alias
asset_alias.save()
else:
AssetAlias.objects.create(user=u, host=a, alias=j_alias)
return render_to_response('jasset/host_list_common.html')
@require_login
def list_host(request):
header_title, path1, path2 = u'查看主机', u'资产管理', u'查看主机'
@ -179,28 +235,63 @@ def list_host(request):
keyword = request.GET.get('keyword', '')
dept_id = get_user_dept(request)
dept = DEPT.objects.get(id=dept_id)
did = request.GET.get('did')
gid = request.GET.get('gid')
sid = request.GET.get('sid')
if did:
dept = DEPT.objects.get(id=did)
posts = dept.asset_set.all()
return render_to_response('jasset/host_list_nop.html', locals(), context_instance=RequestContext(request))
elif gid:
posts = []
user_group = UserGroup.objects.get(id=gid)
perms = Perm.objects.filter(user_group=user_group)
for perm in perms:
for post in perm.asset_group.asset_set.all():
posts.append(post)
posts = list(set(posts))
return render_to_response('jasset/host_list_nop.html', locals(), context_instance=RequestContext(request))
elif sid:
posts = []
user_group = UserGroup.objects.get(id=sid)
perms = Perm.objects.filter(user_group=user_group)
for perm in perms:
for post in perm.asset_group.asset_set.all():
posts.append(post)
posts = list(set(posts))
return render_to_response('jasset/host_list_nop.html', locals(), context_instance=RequestContext(request))
else:
if is_super_user(request):
if keyword:
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
Q(bis_group__name__contains=keyword) | Q(comment__contains=keyword)).distinct().order_by('ip')
Q(bis_group__name__contains=keyword) | Q(
comment__contains=keyword)).distinct().order_by('ip')
else:
posts = Asset.objects.all().order_by('ip')
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
return render_to_response('jasset/host_list.html', locals(), context_instance=RequestContext(request))
elif is_group_admin(request):
if keyword:
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
Q(bis_group__name__contains=keyword) | Q(comment__contains=keyword)).filter(dept=dept).distinct().order_by('ip')
Q(bis_group__name__contains=keyword) | Q(
comment__contains=keyword)).filter(dept=dept).distinct().order_by('ip')
else:
posts = Asset.objects.all().filter(dept=dept).order_by('ip')
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
return render_to_response('jasset/host_list.html', locals(), context_instance=RequestContext(request))
elif is_common_user(request):
user_id = request.session.get('user_id')
username = User.objects.get(id=user_id).name
posts = user_perm_asset_api(username)
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
print posts, username
return render_to_response('jasset/host_list.html', locals(), context_instance=RequestContext(request))
return render_to_response('jasset/host_list_common.html', locals(),
context_instance=RequestContext(request))
@require_admin
@ -422,14 +513,33 @@ def list_group(request):
dept_id = get_user_dept(request)
dept = DEPT.objects.get(id=dept_id)
keyword = request.GET.get('keyword', '')
gid = request.GET.get('gid')
sid = request.GET.get('sid')
if gid:
posts = []
user_group = UserGroup.objects.get(id=gid)
perms = Perm.objects.filter(user_group=user_group)
for perm in perms:
posts.append(perm.asset_group)
elif sid:
posts = []
user_group = UserGroup.objects.get(id=sid)
perms = Perm.objects.filter(user_group=user_group)
for perm in perms:
posts.append(perm.asset_group)
else:
if is_super_user(request):
if keyword:
posts = BisGroup.objects.exclude(name='ALL').filter(Q(name__contains=keyword) | Q(comment__contains=keyword))
posts = BisGroup.objects.exclude(name='ALL').filter(
Q(name__contains=keyword) | Q(comment__contains=keyword))
else:
posts = BisGroup.objects.exclude(name='ALL').order_by('id')
elif is_group_admin(request):
if keyword:
posts = BisGroup.objects.filter(Q(name__contains=keyword) | Q(comment__contains=keyword)).filter(dept=dept)
posts = BisGroup.objects.filter(Q(name__contains=keyword) | Q(comment__contains=keyword)).filter(
dept=dept)
else:
posts = BisGroup.objects.filter(dept=dept).order_by('id')
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
@ -443,7 +553,7 @@ def edit_group(request):
group = BisGroup.objects.get(id=group_id)
all = Asset.objects.all()
dept_id = get_user_dept(request)
eposts = contact_list = Asset.objects.filter(bis_group=group).order_by('ip')
eposts = Asset.objects.filter(bis_group=group).order_by('ip')
if is_super_user(request):
edept = DEPT.objects.all()
@ -489,6 +599,7 @@ def detail_group(request):
return render_to_response('jasset/group_detail.html', locals(), context_instance=RequestContext(request))
@require_admin
def detail_idc(request):
header_title, path1, path2 = u'IDC详情', u'资产管理', u'IDC详情'
login_types = {'L': 'LDAP', 'M': 'MAP'}
@ -542,6 +653,7 @@ def group_del(request, offset):
return HttpResponseRedirect('/jasset/jgroup_list/')
@require_login
def host_search(request):
keyword = request.GET.get('keyword')
login_types = {'L': 'LDAP', 'M': 'MAP'}
@ -555,6 +667,15 @@ def host_search(request):
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
Q(bis_group__name__contains=keyword) | Q(
comment__contains=keyword)).filter(dept=dept).distinct().order_by('ip')
elif is_common_user(request):
user_id = request.session.get('user_id')
username = User.objects.get(id=user_id).name
post_perm = user_perm_asset_api(username)
post_all = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
Q(bis_group__name__contains=keyword) | Q(comment__contains=keyword)) \
.distinct().order_by('ip')
posts = list(set(post_all) & set(post_perm))
print posts
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
return render_to_response('jasset/host_search.html', locals(), context_instance=RequestContext(request))

View File

@ -9,7 +9,7 @@ database = jumpserver
[ldap]
ldap_enable = 1
host_url = ldap://127.0.0.1:389
host_url = ldap://192.168.8.230:389
base_dn = dc=jumpserver, dc=org
root_dn = cn=admin,dc=jumpserver,dc=org
root_pw = secret234

View File

@ -13,7 +13,7 @@ import hashlib
import datetime
from django.core.paginator import Paginator, EmptyPage, InvalidPage
from django.http import HttpResponse, Http404
from juser.models import User, UserGroup
from juser.models import User, UserGroup, DEPT
from jasset.models import Asset, BisGroup
from jlog.models import Log
@ -258,8 +258,9 @@ def view_splitter(request, su=None, adm=None):
raise Http404
def user_perm_group_api(user):
if user:
def user_perm_group_api(username):
if username:
user = User.objects.get(username=username)
perm_list = []
user_group_all = user.group.all()
for user_group in user_group_all:
@ -271,6 +272,14 @@ def user_perm_group_api(user):
return asset_group_list
def user_perm_group_hosts_api(gid):
hostgroup = BisGroup.objects.filter(id=gid)
if hostgroup:
return hostgroup[0].asset_set.all()
else:
return []
def user_perm_asset_api(username):
user = User.objects.filter(username=username)
if user:
@ -348,3 +357,8 @@ def validate(request, user_group=None, user=None, asset_group=None, asset=None,
return False
return True
def get_dept_asset(request):
dept_id = get_user_dept(request)
dept_asset = DEPT.objects.get(id=dept_id).asset_set.all()

View File

@ -53,6 +53,7 @@ INSTALLED_APPS = (
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'jumpserver',
'juser',
'jasset',

View File

@ -7,6 +7,7 @@ import time
from django import template
from juser.models import User, UserGroup, DEPT
from jumpserver.api import *
from jasset.models import AssetAlias
register = template.Library()
@ -168,6 +169,17 @@ def ugrp_perm_asset_count(user_group_id):
return len(set(assets))
@register.filter(name='get_user_alias')
def get_user_alias(post, user_id):
user = User.objects.get(id=user_id)
host = Asset.objects.get(id=post.id)
alias = AssetAlias.objects.filter(user=user, host=host)
if alias:
return alias[0].alias
else:
return ''
@register.filter(name='group_type_to_str')
def group_type_to_str(type_name):
group_types = {
@ -180,7 +192,12 @@ def group_type_to_str(type_name):
@register.filter(name='ast_to_list')
def ast_to_list(lis):
return ast.literal_eval(lis)[0:2]
ast_lis = ast.literal_eval(lis)
if len(ast_lis) <= 2:
return ','.join([i for i in ast_lis])
else:
restr = ','.join([i for i in ast_lis[0:2]]) + '...'
return restr
@register.filter(name='ast_to_list_1')
@ -188,10 +205,6 @@ def ast_to_list_1(lis):
return ast.literal_eval(lis)
# @register.filter(name='perm_asset_count')
# def perm_asset_count(user_id):
# return len(perm_user_asset(user_id))
@register.filter(name='string_length')
def string_length(string, length):
return '%s ...' % string[0:length]

View File

@ -1,11 +1,13 @@
from django.conf.urls import patterns, include, url
from api import view_splitter
from views import index, admin_index
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'jumpserver.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
(r'^$', 'jumpserver.views.index'),
(r'^$', view_splitter, {'su': index, 'adm': admin_index}),
(r'^api/user/$', 'jumpserver.api.api_user'),
(r'^skin_config/$', 'jumpserver.views.skin_config'),
(r'^install/$', 'jumpserver.views.install'),

View File

@ -1,5 +1,7 @@
# coding: utf-8
from __future__ import division
import datetime
from django.db.models import Count
@ -7,6 +9,7 @@ from django.shortcuts import render_to_response
from django.template import RequestContext
from jasset.models import IDC
from juser.models import DEPT
from jperm.models import Apply
from jumpserver.api import *
@ -67,13 +70,24 @@ def index_cu(request):
@require_login
@require_super_user
def index(request):
if request.session.get('role_id') == 0:
return index_cu(request)
users = User.objects.all()
hosts = Asset.objects.all()
online_host = Log.objects.filter(is_finished=0)
online_user = online_host.distinct()
online = Log.objects.filter(is_finished=0)
online_host = online.values('host').distinct()
online_user = online.values('user').distinct()
active_users = User.objects.filter(is_active=1)
active_hosts = Asset.objects.filter(is_active=1)
# percent of dashboard
percent_user = format(active_users.count() / users.count(), '.0%')
percent_host = format(active_hosts.count() / hosts.count(), '.0%')
percent_online_user = format(online_user.count() / users.count(), '.0%')
percent_online_host = format(online_host.count() / hosts.count(), '.0%')
li_date, li_str = getDaysByNum(7)
today = datetime.datetime.now().day
from_week = datetime.datetime.now() - datetime.timedelta(days=7)
@ -82,6 +96,89 @@ def index(request):
host_top_ten = week_data.values('host').annotate(times=Count('host')).order_by('-times')[:10]
user_dic, host_dic = get_data(week_data, user_top_ten, 'user'), get_data(week_data, host_top_ten, 'host')
# a week data
week_users = week_data.values('user').distinct().count()
week_hosts = week_data.count()
user_top_five = week_data.values('user').annotate(times=Count('user')).order_by('-times')[:5]
color = ['label-success', 'label-info', 'label-primary', 'label-default', 'label-warnning']
# perm apply latest 10
perm_apply_10 = Apply.objects.order_by('-date_add')[:10]
# latest 10 login
login_10 = Log.objects.order_by('-start_time')[:10]
# a week top 10
for user_info in user_top_ten:
username = user_info.get('user')
last = Log.objects.filter(user=username).latest('start_time')
user_info['last'] = last
print user_top_ten
top = {'user': '活跃用户数', 'host': '活跃主机数', 'times': '登录次数'}
top_dic = {}
for key, value in top.items():
li = []
for t in li_date:
year, month, day = t.year, t.month, t.day
if key != 'times':
times = week_data.filter(start_time__year=year, start_time__month=month, start_time__day=day).values(key).distinct().count()
else:
times = week_data.filter(start_time__year=year, start_time__month=month, start_time__day=day).count()
li.append(times)
top_dic[value] = li
return render_to_response('index.html', locals(), context_instance=RequestContext(request))
@require_admin
def admin_index(request):
user_id = request.session.get('user_id', '')
user = User.objects.get(id=user_id)
dept = user.dept
dept_name = user.dept.name
users = User.objects.filter(dept=dept)
hosts = Asset.objects.filter(dept=dept)
online = Log.objects.filter(dept_name=dept_name, is_finished=0)
online_host = online.values('host').distinct()
online_user = online.values('user').distinct()
active_users = users.filter(is_active=1)
active_hosts = hosts.filter(is_active=1)
# percent of dashboard
percent_user = format(active_users.count() / users.count(), '.0%')
percent_host = format(active_hosts.count() / hosts.count(), '.0%')
percent_online_user = format(online_user.count() / users.count(), '.0%')
percent_online_host = format(online_host.count() / hosts.count(), '.0%')
li_date, li_str = getDaysByNum(7)
today = datetime.datetime.now().day
from_week = datetime.datetime.now() - datetime.timedelta(days=7)
week_data = Log.objects.filter(dept_name=dept_name, start_time__range=[from_week, datetime.datetime.now()])
user_top_ten = week_data.values('user').annotate(times=Count('user')).order_by('-times')[:10]
host_top_ten = week_data.values('host').annotate(times=Count('host')).order_by('-times')[:10]
user_dic, host_dic = get_data(week_data, user_top_ten, 'user'), get_data(week_data, host_top_ten, 'host')
# a week data
week_users = week_data.values('user').distinct().count()
week_hosts = week_data.count()
user_top_five = week_data.values('user').annotate(times=Count('user')).order_by('-times')[:5]
color = ['label-success', 'label-info', 'label-primary', 'label-default', 'label-warnning']
# perm apply latest 10
perm_apply_10 = Apply.objects.order_by('-date_add')[:10]
# latest 10 login
login_10 = Log.objects.order_by('-start_time')[:10]
# a week top 10
for user_info in user_top_ten:
username = user_info.get('user')
last = Log.objects.filter(user=username).latest('start_time')
user_info['last'] = last
print user_top_ten
top = {'user': '活跃用户数', 'host': '活跃主机数', 'times': '登录次数'}
top_dic = {}
for key, value in top.items():
@ -101,51 +198,6 @@ def skin_config(request):
return render_to_response('skin_config.html')
def jasset_group_add(name, comment, jtype):
if BisGroup.objects.filter(name=name):
emg = u'该业务组已存在!'
else:
BisGroup.objects.create(name=name, comment=comment, type=jtype)
smg = u'业务组%s添加成功' % name
def jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_dept, j_active, j_comment, j_user='', j_password=''):
groups, depts = [], []
is_active = {u'': '1', u'': '2'}
login_types = {'LDAP': 'L', 'MAP': 'M'}
for group in j_group[0].split():
c = BisGroup.objects.get(name=group.strip())
groups.append(c)
print j_dept
for d in j_dept[0].split():
p = DEPT.objects.get(name=d.strip())
depts.append(p)
j_type = login_types[j_type]
j_idc = IDC.objects.get(name=j_idc)
a = Asset.objects.get(id=j_id)
if j_type == 'M':
a.ip = j_ip
a.port = j_port
a.login_type = j_type
a.idc = j_idc
a.is_active = j_active
a.comment = j_comment
a.username = j_user
a.password = j_password
else:
a.ip = j_ip
a.port = j_port
a.idc = j_idc
a.login_type = j_type
a.is_active = is_active[j_active]
a.comment = j_comment
a.save()
a.bis_group = groups
a.dept = depts
a.save()
def pages(posts, r):
"""分页公用函数"""
contact_list = posts
@ -222,28 +274,6 @@ def filter_ajax_api(request):
return render_to_response('filter_ajax_api.html', locals())
# def perm_user_asset(user_id=None, username=None):
# if user_id:
# user = User.objects.get(id=user_id)
# else:
# user = User.objects.get(username=username)
# user_groups = user.user_group.all()
# perms = []
# assets = []
# asset_groups = []
# for user_group in user_groups:
# perm = user_group.perm_set.all()
# perms.extend(perm)
#
# for perm in perms:
# asset_groups.extend(perm.asset_group.all())
#
# for asset_group in asset_groups:
# assets.extend(list(asset_group.asset_set.all()))
#
# return assets
def install(request):
from juser.models import DEPT, User
dept = DEPT(id=1, name="超管部", comment="超级管理员部门")

View File

@ -1,4 +1,6 @@
{% extends 'base.html' %}
{% load mytags %}
{% load humanize %}
{% block content %}
{% include 'nav_cat_bar.html' %}
@ -12,7 +14,7 @@
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/juser/user_list/">{{ users.count}}</a></h1>
<div class="stat-percent font-bold text-success">98% <i class="fa fa-bolt"></i></div>
<div class="stat-percent font-bold text-success">{{ percent_user }} <i class="fa fa-bolt"></i></div>
<small>All user</small>
</div>
</div>
@ -25,7 +27,7 @@
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jasset/host_list/">{{ hosts.count }}</a></h1>
<div class="stat-percent font-bold text-info">20% <i class="fa fa-level-up"></i></div>
<div class="stat-percent font-bold text-info">{{ percent_host }} <i class="fa fa-level-up"></i></div>
<small>All host</small>
</div>
</div>
@ -39,7 +41,7 @@
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users"></span></a></h1>
<div class="stat-percent font-bold text-navy">44% <i class="fa fa-level-up"></i></div>
<div class="stat-percent font-bold text-navy">{{ percent_online_user }} <i class="fa fa-level-up"></i></div>
<small>Online user</small>
</div>
</div>
@ -53,28 +55,175 @@
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts"></span></a></h1>
<div class="stat-percent font-bold text-danger">38% <i class="fa fa-level-down"></i></div>
<div class="stat-percent font-bold text-danger">{{ percent_online_host }} <i class="fa fa-level-down"></i></div>
<small>Connected host</small>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6" id="top10" style="width:50%;height:400px;"></div>
<div class="col-lg-6" id="usertop10" style="width:50%;height:400px;"></div>
</div>
<div class="row">
<div class="col-lg-6" id="hosttop10" style="width:50%;height:400px; margin-top: 20px"></div>
<div class="col-lg-3 border-bottom white-bg dashboard-header" style="margin-left:15px;">
<h2>活跃用户TOP5</h2>
<small>过去一周共有<span class="text-info">{{ week_users }}</span>位用户登录<span class="text-success">{{ week_hosts }}</span>次服务器.</small>
<ul class="list-group clear-list m-t">
{% for data in user_top_five %}
<li class="list-group-item fist-item">
<span class="pull-right">
{{ data.times }}次/周
</span>
<span class="label {{ color|random }}">{{ forloop.counter }}</span> {{ data.user }}
</li>
{% endfor %}
</ul>
</div>
<div class="col-lg-9" id="top10" style="margin-left: -15px;height: 345px"></div>
</div>
<br/>
<div class="row">
<div class="col-lg-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="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content ibox-heading">
<h3><i class="fa fa-envelope-o"></i> 权限申请记录 </h3>
<small><i class="fa fa-map-marker"></i> 最近十条权限申请记录信息.</small>
</div>
<div class="ibox-content">
<div class="feed-activity-list">
{% for perm in perm_apply_10 %}
<div class="feed-element">
<div>
{% ifequal perm.status 0 %}
<small class="pull-right text-navy">{{ perm.date_add|naturaltime }}</small>
{% else %}
<small class="pull-right">{{ perm.date_add|naturaltime }}</small>
{% endifequal %}
<strong>{{ perm.applyer }}</strong>
<div>申请 {{ perm.bisgroup|ast_to_list }} 主机组权限</div>
<div>申请 {{ perm.asset|ast_to_list }} 主机权限</div>
<small class="text-muted">{{ perm.date_add }}</small>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>最近十次登录</h5>
<div class="ibox-tools">
<span class="label label-info-light">10 Messages</span>
</div>
</div>
<div class="ibox-content ibox-heading">
<h3><i class="fa fa-paper-plane-o"></i> 登录记录 </h3>
<small<i class="fa fa-map-marker"></i> 最近十次登录记录. </small>
</div>
<div class="ibox-content">
<div>
<div class="feed-activity-list">
{% for login in login_10 %}
<div class="feed-element">
<a href="profile.html" class="pull-left">
<img alt="image" class="img-circle" src="/static/img/root.png">
</a>
<div class="media-body ">
{% ifequal login.is_finished 0 %}
<small class="pull-right text-navy">{{ login.start_time|naturaltime }}</small>
{% else %}
<small class="pull-right">{{ login.start_time|naturaltime }}</small>
{% endifequal %}
<strong>{{ login.user }}</strong> 登录了{{ login.host }} <br>
<small class="text-muted">{{ login.start_time }}</small>
</div>
</div>
{% endfor %}
</div>
<button class="btn btn-primary btn-block m-t"><i class="fa fa-arrow-down"></i> 更多 </button>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>一周Top10用户</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><i class="fa fa-user"></i> 一周Top10用户 </h3>
<small><i class="fa fa-map-marker"></i> 一周Top10用户登录次数及最近一次登录记录. </small>
</div>
<div class="ibox-content inspinia-timeline">
{% for data in user_top_ten %}
<div class="timeline-item">
<div class="row">
<div class="col-xs-5 date">
<i class="fa fa-info-circle"></i>
<strong>{{ data.user }}</strong>
<br/>
<small class="text-navy">{{ data.times }}次</small>
</div>
<div class="col-xs-7 content no-top-border">
<p class="m-b-xs">最近一次登录</p>
<p>{{ data.last.host }}</p>
<p>于{{ data.last.start_time |date:"Y-m-d H:i:s" }}</p>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<!--</div>-->
<!--<div class="col-xm-6" id="top10" style="width:50%;height:400px;"></div>-->
<!--<div class="col-xm-6" id="usertop10" style="width:50%;height:400px;"></div>-->
<!--<div class="row">-->
<!--<div class="col-lg-6" id="hosttop10" style="width:50%;height:400px; margin-top: 20px"></div>-->
<!--</div>-->
</div>
<script>
var cate = {{ li_str|safe }};
$(function () {
$('#top10').highcharts({
chart: {
type: 'column'
},
// chart: {
// type: 'column'
// },
title: {
text: '一周数据总览',
x: -20 //center
@ -94,7 +243,7 @@ $(function () {
yAxis:{
min: 0,
title: {
text: '登录次数'
text: ''
},
plotLines: [{
value: 0,

View File

@ -45,8 +45,14 @@
<div class="hr-line-dashed"></div>
<div class="form-group">
<div>
<label for="groups" class="col-lg-2 control-label">主机<span class="red-fonts">*</span></label>
<div class="col-sm-3">
<select multiple="multiple" id="id_domains_filter" name="domains_filter" style="display: none;">
</select>
<div class="input-group" style="padding-bottom: 5px">
<input type="text" size="19" class="form-control input-sm" id="search" name="keyword" placeholder="过滤">
</div>
<select id="groups" size="12" class="form-control m-b" multiple>
{% for post in posts %}
<option value="{{ post.id }}">{{ post.ip }}</option>
@ -60,6 +66,7 @@
</div>
</div>
<div class="col-sm-3">
<h4 style="padding-bottom: 5px">已选中主机</h4>
<div>
<select id="groups_selected" name="j_hosts" class="form-control m-b" size="12" multiple>
{% for post in eposts %}
@ -69,6 +76,7 @@
</div>
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
@ -113,6 +121,17 @@
$(this).prop('selected', true)
})
}
$('#search').keyup(function() {
var $rows = $('#groups option');
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
$rows.show().filter(function() {
var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
return !~text.indexOf(val);
}).hide();
});
</script>
{% endblock %}

View File

@ -0,0 +1,172 @@
{% 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-lg-12">
<div class="ibox float-e-margins" id="all">
<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="#">未启用 1</a>
</li>
<li><a href="#">未启用 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div>
<span>点击别名栏修改主机别名, 可在跳板机上使用别名直接登录.</span>
<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">
<input type="text" style="display: none">
<div class="input-group-btn">
<button id='search_btn' type="button" class="btn btn-sm btn-primary" onclick="host_search()">
Search
</button>
</div>
</div>
</form>
</div>
<form id="contents_form" name="contents_form">
<table class="table table-striped table-bordered table-hover " id="editable" name="editable">
<thead>
<tr>
<th class="text-center"><input id="checkall" type="checkbox" class="i-checks" name="checkall" value="checkall" data-editable='false' onclick="check_all('contents_form')"></th>
<th class="text-center" name="j_ip"> IP地址 </th>
<th class="text-center"> 端口号 </th>
<th class="text-center" name="j_type"> 登录方式 </th>
<th class="text-center" name="j_idc"> 所属IDC </th>
<th class="text-center"> 所属部门 </th>
<th class="text-center"> 所属主机组 </th>
<th class="text-center"> 别名 </th>
<th class="text-center" name="j_comment"> 备注 </th>
<th class="text-center"> 操作 </th>
</tr>
</thead>
<tbody>
{% for post in contacts.object_list %}
<tr class="gradeX">
<td class="text-center" name="j_id" value="{{ post.id }}" data-editable='false'><input name="id" value="{{ post.id }}" type="checkbox" class="i-checks"></td>
<td class="text-center" data-editable='false' name="j_ip"> {{ post.ip }} </td>
<td class="text-center" data-editable='false' name="j_port"> {{ post.port }} </td>
<td class="text-center" data-editable='false' name="j_type"> {{ login_types|get_item:post.login_type }} </td>
<td class="text-center" data-editable='false' name="j_idc"> {{ post.idc.name }} </td>
<td class="text-center" data-editable='false' name="j_dept">{{ post.dept.all | group_str2 }}</td>
<td class="text-center" data-editable='false' name="j_group">{{ post.bis_group.all | group_str2_all }}</td>
<td class="text-center" name="j_alias"> {{ post|get_user_alias:user_id }} </td>
<td class="text-center" data-editable='false' name="j_comment"> {{ post.comment }} </td>
<td class="text-center" data-editable='false'>
<a value="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<input type="button" id="alter_button" class="btn btn-warning btn-sm" name="alter_button" value="修改" onclick="alter('contents_form')" />
</div>
{% include 'paginator.html' %}
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$('#editable').editableTableWidget();
});
$(".iframe").on('click', function(){
var url= $(this).attr("value");
$.layer({
type: 2,
title: 'JumpServer主机详情',
maxmin: true,
shift: 'top',
border: [2, 0.3, '#1AB394'],
shade: [0.5, '#000000'],
shadeClose: true,
area : ['800px' , '600px'],
iframe: {src: url}
});
});
function alter(form) {
selectData = GetTableDataBox();
if (selectData[1] != 0) {
$.ajax({
type: "post",
url: "/jasset/host_edit_common/batch/",
data: {"editable": selectData[0], "len_table": selectData[1]},
success: function (data) {
alert("修改成功");
window.open("/jasset/host_list/", "_self");
}
});
}
}
function del(form) {
var checkboxes = document.getElementById(form);
var id_list = {};
var j = 0;
for (var i = 0; i < checkboxes.elements.length; i++) {
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked == true && checkboxes.elements[i].value != "checkall") {
id_list[j] = checkboxes.elements[i].value;
j++;
}
}
if (confirm("确定删除")) {
$.ajax({
type: "POST",
url: "/jasset/host_del/multi/",
data: {"id_list": id_list, "len_list": j},
success: function (data) {
window.open("/jasset/host_list/", "_self");
}
});
}
}
function host_search(){
$.ajax({
type: "GET",
url: "/jasset/search/",
data: $("#search_form").serialize(),
success: function (data) {
$("#contents_form").html(data);
}
});
}
$("#search_input").keydown(function(e){
if(e.keyCode==13){
host_search()
}
})
</script>
{% endblock %}

View File

@ -0,0 +1,177 @@
{% 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-lg-12">
<div class="ibox float-e-margins" id="all">
<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="#">未启用 1</a>
</li>
<li><a href="#">未启用 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div>
<a target="_blank" href="/jasset/host_add" class="btn btn-sm btn-primary "> 添加 </a>
<!--<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">-->
<!--<input type="text" style="display: none">-->
<!--<div class="input-group-btn">-->
<!--<button id='search_btn' type="button" class="btn btn-sm btn-primary" onclick="host_search()">-->
<!--Search-->
<!--</button>-->
<!--</div>-->
<!--</div>-->
<!--</form>-->
</div>
<form id="contents_form" name="contents_form">
<table class="table table-striped table-bordered table-hover " id="editable" name="editable">
<thead>
<tr>
<th class="text-center"><input id="checkall" type="checkbox" class="i-checks" name="checkall" value="checkall" data-editable='false' onclick="check_all('contents_form')"></th>
<th class="text-center" name="j_ip"> IP地址 </th>
<th class="text-center"> 端口号 </th>
<th class="text-center" name="j_type"> 登录方式 </th>
<th class="text-center" name="j_idc"> 所属IDC </th>
<th class="text-center"> 所属部门 </th>
<th class="text-center"> 所属主机组 </th>
<th class="text-center"> 是否激活 </th>
<th class="text-center" name="j_comment"> 备注 </th>
<th class="text-center"> 操作 </th>
</tr>
</thead>
<tbody>
{% for post in posts %}
<tr class="gradeX">
<td class="text-center" name="j_id" value="{{ post.id }}" data-editable='false'><input name="id" value="{{ post.id }}" type="checkbox" class="i-checks"></td>
<td class="text-center" name="j_ip"> {{ post.ip }} </td>
<td class="text-center" name="j_port"> {{ post.port }} </td>
<td class="text-center" name="j_type"> {{ login_types|get_item:post.login_type }} </td>
<td class="text-center" name="j_idc"> {{ post.idc.name }} </td>
<td class="text-center" name="j_dept">{{ post.dept.all | group_str2 }}</td>
<td class="text-center" name="j_group">{{ post.bis_group.all | group_str2_all }}</td>
<td class="text-center" name="j_active"> {{ post.is_active|bool2str }} </td>
<td class="text-center" name="j_comment"> {{ post.comment }} </td>
<td class="text-center" data-editable='false'>
<a value="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a>
{% ifnotequal session_role_id 0 %}
<a href="/jasset/host_edit/?id={{ post.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="/jasset/host_del/{{ post.id }}" class="btn btn-xs btn-danger">删除</a>
{% endifnotequal %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<input type="button" id="del_button" class="btn btn-danger btn-sm" name="del_button" value="删除" onclick="del('contents_form')" />
<input type="button" id="alter_button" class="btn btn-warning btn-sm" name="alter_button" value="修改" onclick="alter('contents_form')" />
</div>
<!--{% include 'paginator.html' %}-->
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$('#editable').editableTableWidget();
});
$(".iframe").on('click', function(){
var url= $(this).attr("value");
$.layer({
type: 2,
title: 'JumpServer主机详情',
maxmin: true,
shift: 'top',
border: [2, 0.3, '#1AB394'],
shade: [0.5, '#000000'],
shadeClose: true,
area : ['800px' , '600px'],
iframe: {src: url}
});
});
function alter(form) {
selectData = GetTableDataBox();
if (selectData[1] != 0) {
$.ajax({
type: "post",
url: "/jasset/host_edit/batch/",
data: {"editable": selectData[0], "len_table": selectData[1]},
success: function (data) {
alert("修改成功");
window.open("/jasset/host_list/", "_self");
}
});
}
}
function del(form) {
var checkboxes = document.getElementById(form);
var id_list = {};
var j = 0;
for (var i = 0; i < checkboxes.elements.length; i++) {
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked == true && checkboxes.elements[i].value != "checkall") {
id_list[j] = checkboxes.elements[i].value;
j++;
}
}
if (confirm("确定删除")) {
$.ajax({
type: "POST",
url: "/jasset/host_del/multi/",
data: {"id_list": id_list, "len_list": j},
success: function (data) {
window.open("/jasset/host_list/", "_self");
}
});
}
}
function host_search(){
$.ajax({
type: "GET",
url: "/jasset/search/",
data: $("#search_form").serialize(),
success: function (data) {
$("#contents_form").html(data);
}
});
}
$("#search_input").keydown(function(e){
if(e.keyCode==13){
host_search()
}
})
</script>
{% endblock %}

View File

@ -8,7 +8,11 @@
<th class="text-center" name="j_type"> 登录方式 </th>
<th class="text-center" name="j_idc"> 所属IDC </th>
<th class="text-center"> 所属业务组 </th>
{% ifnotequal session_role_id 0 %}
<th class="text-center"> 是否激活 </th>
{% else %}
<th class="text-center"> 别名 </th>
{% endifnotequal %}
<th class="text-center" name="j_time"> 添加时间 </th>
<th class="text-center" name="j_comment"> 备注 </th>
<th class="text-center"> 操作 </th>
@ -23,13 +27,19 @@
<td class="text-center" name="j_type"> {{ login_types|get_item:post.login_type }} </td>
<td class="text-center" name="j_idc"> {{ post.idc.name }} </td>
<td class="text-center" name="j_group">{{ post.bis_group.all | group_str2 }}</td>
<td class="text-center" name="j_active"> {{ post.is_active|bool2str }} </td>
{% ifnotequal session_role_id 0 %}
<td class="text-center" name="j_alias"> {{ post.is_active|bool2str }} </td>
{% else %}
<td class="text-center" name="j_active"> {{ post|get_user_alias:user_id }} </td>
{% endifnotequal %}
<td class="text-center"> {{ post.date_added|date:"Y-m-d H:i:s" }} </td>
<td class="text-center" name="j_comment"> {{ post.comment }} </td>
<td class="text-center" data-editable='false'>
<a value="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a>
{% ifnotequal session_role_id 0 %}
<a href="/jasset/host_edit/?id={{ post.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="/jasset/host_del/{{ post.id }}" class="btn btn-xs btn-danger">删除</a>
{% endifnotequal %}
</td>
</tr>
{% endfor %}

View File

@ -58,8 +58,8 @@
{% for dept in contacts.object_list %}
<tr class="gradeX">
<td class="text-center"> {{ dept.name }} </td>
<td class="text-center"><a href="/juser/user_list/?did={{ dept.id }}">{{ dept.id | dept_user_num }} </a> </td>
<td class="text-center"> {{ dept.id | dept_asset_num }} </td>
<td class="text-center"><a href="/juser/user_list/?did={{ dept.id }}">{{ dept.id | dept_user_num }}</a> </td>
<td class="text-center"><a href="/jasset/host_list/?did={{ dept.id }}">{{ dept.id | dept_asset_num }}</a> </td>
<td class="text-center"> {{ dept.comment }} </td>
<td class="text-center">
{# <a title="[ {{ dept.name }} ] 成员信息" href="../dept_detail/?id={{ dept.id }}" class="iframe btn btn-xs btn-primary">主机</a>#}

View File

@ -74,7 +74,7 @@
<select multiple="multiple" id="id_domains_filter" name="domains_filter" style="display: none;">
</select>
<div class="input-group" style="padding-bottom: 5px">
<input type="text" size="19" class="form-control input-sm" id="search_input" name="keyword" placeholder="过滤" oninput="search_domain(this.value)">
<input type="text" size="19" class="form-control input-sm" id="search" name="keyword" placeholder="过滤">
</div>
<select id="groups" size="12" class="form-control m-b" multiple>
{% for post in posts %}
@ -119,17 +119,16 @@
</div>
</div>
</div>
<script>
function search_domain(text){
console.log(text)
$("#groups").children().each(function(){$(this).remove();});
$("#id_domains_filter").children().each(function(){
if ($(this).text().search(text) != -1) {
console.log(text);
$("#groups").append($(this).clone())
}
});
}
<script>
var $rows = $('#groups option');
$('#search').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
$rows.show().filter(function() {
var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
return !~text.indexOf(val);
}).hide();
});
</script>
{% endblock content %}

View File

@ -60,9 +60,9 @@
<tr class="gradeX">
<td class="text-center"> {{ group.name }} </td>
<td class="text-center"> {{ group.dept.name }} </td>
<td class="text-center"><a href="/juser/user_list/?gid={{ group.id }}">{{ group.id | member_count }} </a> </td>
<td class="text-center"> {{ group.id | ugrp_perm_agrp_count }} </td>
<td class="text-center"> {{ group.id | ugrp_perm_asset_count }} </td>
<td class="text-center"> <a href="/juser/user_list/?gid={{ group.id }}">{{ group.id | member_count }} </a> </td>
<td class="text-center"> <a href="/jasset/group_list/?gid={{ group.id }}"> {{ group.id | ugrp_perm_agrp_count }} </a> </td>
<td class="text-center"> <a href="/jasset/host_list/?gid={{ group.id }}">{{ group.id | ugrp_perm_asset_count }} </a> </td>
<td class="text-center"> {{ group.comment }} </td>
<td class="text-center">
<a href="../perm_edit/?id={{ group.id }}" class="btn btn-xs btn-danger">授权编辑</a>

View File

@ -58,7 +58,6 @@
<th class="text-center"> 申请主机 </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"> 详情 </th>
@ -69,11 +68,10 @@
<tr class="gradeX">
<td class="text-center" id="username"> {{ post.applyer }} </td>
<td class="text-center" id="dept"> {{ post.dept }} </td>
<td class="text-center" id="ip"> {% for i in post.bisgroup|ast_to_list %} {{ i }} {% endfor %}... </td>
<td class="text-center" id="remote_ip">{% for i in post.asset|ast_to_list %} {{ i }} {% endfor %}... </td>
<td class="text-center" id="ip"> {{ post.bisgroup|ast_to_list }} </td>
<td class="text-center" id="remote_ip">{{ post.asset|ast_to_list }} </td>
<td class="text-center" id="approver"> {{ post.approver }} </td>
<td class="text-center" id="start_time"> {{ post.date_add|date:"Y-m-d H:i:s"}} </td>
<!--<td class="text-center" id="end_time"> {{ post.date_end|date:"Y-m-d H:i:s" }} </td>-->
<td class="text-center" id=""> {{ post.comment }} </td>
<td class="text-center" data-editable='false'>
<a value="/jperm/apply_info/?uuid={{ post.uuid }}" class="iframe btn btn-xs btn-primary">详情</a>

View File

@ -67,8 +67,8 @@
<tr class="gradeX">
<td class="text-center" id="username"> {{ post.applyer }} </td>
<td class="text-center" id="dept"> {{ post.dept }} </td>
<td class="text-center" id="ip"> {% for i in post.bisgroup|ast_to_list %} {{ i }} {% endfor %}... </td>
<td class="text-center" id="remote_ip"> {% for i in post.asset|ast_to_list %} {{ i }} {% endfor %}... </td>
<td class="text-center" id="ip"> {{ post.bisgroup|ast_to_list }}</td>
<td class="text-center" id="remote_ip"> {{ post.asset|ast_to_list }} </td>
<td class="text-center" id="start_time"> {{ post.date_add|date:"Y-m-d H:i:s"}} </td>
<td class="text-center" id=""> {{ post.comment }} </td>
<td class="text-center" data-editable='false'>

View File

@ -67,8 +67,8 @@
<td class="text-center"> {{ group.name }} </td>
<td class="text-center"> {{ group.dept.name }} </td>
<td class="text-center"><a href="/juser/user_list/?gid={{ group.id }}">{{ group.id | member_count }} </a> </td>
<td class="text-center"> {{ group.id | ugrp_perm_agrp_count }} </td>
<td class="text-center"> {{ group.id | ugrp_perm_asset_count }} </td>
<td class="text-center"><a href="/jasset/group_list/?sid={{ group.id }}">{{ group.id | ugrp_perm_agrp_count }} </a> </td>
<td class="text-center"><a href="/jasset/host_list/?sid={{ group.id }}"> {{ group.id | ugrp_perm_asset_count }} </a> </td>
<td class="text-center"> {{ group.id | ugrp_perm_asset_count }} </td>
<td class="text-center"> {{ group.comment }} </td>
<td class="text-center">

View File

@ -28,8 +28,8 @@
<ul class="nav nav-second-level">
<li class="host_add host_add_multi"><a href="/jasset/host_add/">添加资产</a></li>
<li class="host_list"><a href="/jasset/host_list/">查看资产&nbsp&nbsp</span><span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
<li class="jgroup_add"><a href="/jasset/jgroup_add/">添加主机组</a></li>
<li class="jgroup_list group_detail"><a href="/jasset/jgroup_list/">查看主机组</a></li>
<li class="group_add"><a href="/jasset/group_add/">添加主机组</a></li>
<li class="group_list group_detail"><a href="/jasset/group_list/">查看主机组</a></li>
<li class="idc_add"><a href="/jasset/idc_add/">添加IDC</a></li>
<li class="idc_list idc_detail"><a href="/jasset/idc_list/">查看IDC</a></li>
</ul>
@ -98,8 +98,8 @@
<ul class="nav nav-second-level">
<li class="host_add host_add_multi"><a href="/jasset/host_add/">添加资产</a></li>
<li class="host_list"><a href="/jasset/host_list/">查看资产&nbsp&nbsp</span><span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
<li class="jgroup_add"><a href="/jasset/jgroup_add/">添加主机组</a></li>
<li class="jgroup_list group_detail"><a href="/jasset/jgroup_list/">查看主机组</a></li>
<li class="group_add"><a href="/jasset/group_add/">添加主机组</a></li>
<li class="group_list group_detail"><a href="/jasset/group_list/">查看主机组</a></li>
<li class="idc_list idc_detail"><a href="/jasset/idc_list/">查看IDC</a></li>
</ul>
</li>