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

View File

@ -1,6 +1,6 @@
import datetime import datetime
from django.db import models from django.db import models
from juser.models import UserGroup, DEPT from juser.models import User, UserGroup, DEPT
class IDC(models.Model): class IDC(models.Model):
@ -43,4 +43,13 @@ class Asset(models.Model):
comment = models.CharField(max_length=100, blank=True, null=True) comment = models.CharField(max_length=100, blank=True, null=True)
def __unicode__(self): def __unicode__(self):
return self.ip 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_edit/$', edit_idc),
url(r'^idc_detail/$', detail_idc), url(r'^idc_detail/$', detail_idc),
url(r'^idc_del/(\w+)/$', del_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'^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_detail/$', detail_group),
url(r'^group_del_host/(\w+)/$', group_del_host), url(r'^group_del_host/(\w+)/$', group_del_host),
url(r'^group_del/(\w+)/$', group_del), url(r'^group_del/(\w+)/$', group_del),
url(r'^host_del/(\w+)/$', host_del), url(r'^host_del/(\w+)/$', host_del),
url(r'^host_edit/$', host_edit), url(r'^host_edit/$', host_edit),
url(r'^host_edit/batch/$', batch_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.template import RequestContext
from django.shortcuts import render_to_response 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 juser.models import UserGroup, DEPT
from jumpserver.views import jasset_host_edit, pages from jumpserver.views import jasset_host_edit, pages
from jperm.models import Perm, SudoPerm
from jumpserver.views import pages
from jumpserver.api import * from jumpserver.api import *
cryptor = PyCrypt(KEY) cryptor = PyCrypt(KEY)
@ -51,6 +53,43 @@ def f_add_host(ip, port, idc, jtype, group, dept, active, comment, username='',
a.save() 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 @require_admin
def add_host(request): def add_host(request):
login_types = {'L': 'LDAP', 'M': 'MAP'} login_types = {'L': 'LDAP', 'M': 'MAP'}
@ -152,12 +191,6 @@ def batch_host_edit(request):
j_group = request.POST.getlist(j_group) j_group = request.POST.getlist(j_group)
j_active = request.POST.get(j_active).strip() j_active = request.POST.get(j_active).strip()
j_comment = request.POST.get(j_comment).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': if j_type == 'M':
j_user = "editable[" + str(i) + "][j_user]" j_user = "editable[" + str(i) + "][j_user]"
@ -165,13 +198,36 @@ def batch_host_edit(request):
j_user = request.POST.get(j_user).strip() j_user = request.POST.get(j_user).strip()
password = request.POST.get(j_password).strip() password = request.POST.get(j_password).strip()
j_password = cryptor.encrypt(password) 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: else:
jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_dept, j_active, j_comment) 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') 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 @require_login
def list_host(request): def list_host(request):
header_title, path1, path2 = u'查看主机', u'资产管理', u'查看主机' header_title, path1, path2 = u'查看主机', u'资产管理', u'查看主机'
@ -179,28 +235,63 @@ def list_host(request):
keyword = request.GET.get('keyword', '') keyword = request.GET.get('keyword', '')
dept_id = get_user_dept(request) dept_id = get_user_dept(request)
dept = DEPT.objects.get(id=dept_id) dept = DEPT.objects.get(id=dept_id)
if is_super_user(request): did = request.GET.get('did')
if keyword: gid = request.GET.get('gid')
posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) | sid = request.GET.get('sid')
Q(bis_group__name__contains=keyword) | Q(comment__contains=keyword)).distinct().order_by('ip') if did:
else: dept = DEPT.objects.get(id=did)
posts = Asset.objects.all().order_by('ip') posts = dept.asset_set.all()
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request) return render_to_response('jasset/host_list_nop.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')
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)
elif is_common_user(request): elif gid:
user_id = request.session.get('user_id') posts = []
username = User.objects.get(id=user_id).name user_group = UserGroup.objects.get(id=gid)
posts = user_perm_asset_api(username) perms = Perm.objects.filter(user_group=user_group)
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request) for perm in perms:
print posts, username for post in perm.asset_group.asset_set.all():
return render_to_response('jasset/host_list.html', locals(), context_instance=RequestContext(request)) 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')
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')
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)
return render_to_response('jasset/host_list_common.html', locals(),
context_instance=RequestContext(request))
@require_admin @require_admin
@ -422,16 +513,35 @@ def list_group(request):
dept_id = get_user_dept(request) dept_id = get_user_dept(request)
dept = DEPT.objects.get(id=dept_id) dept = DEPT.objects.get(id=dept_id)
keyword = request.GET.get('keyword', '') keyword = request.GET.get('keyword', '')
if is_super_user(request): gid = request.GET.get('gid')
if keyword: sid = request.GET.get('sid')
posts = BisGroup.objects.exclude(name='ALL').filter(Q(name__contains=keyword) | Q(comment__contains=keyword)) if gid:
else: posts = []
posts = BisGroup.objects.exclude(name='ALL').order_by('id') user_group = UserGroup.objects.get(id=gid)
elif is_group_admin(request): perms = Perm.objects.filter(user_group=user_group)
if keyword: for perm in perms:
posts = BisGroup.objects.filter(Q(name__contains=keyword) | Q(comment__contains=keyword)).filter(dept=dept) posts.append(perm.asset_group)
else:
posts = BisGroup.objects.filter(dept=dept).order_by('id') 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))
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)
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) contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
return render_to_response('jasset/group_list.html', locals(), context_instance=RequestContext(request)) return render_to_response('jasset/group_list.html', locals(), context_instance=RequestContext(request))
@ -443,7 +553,7 @@ def edit_group(request):
group = BisGroup.objects.get(id=group_id) group = BisGroup.objects.get(id=group_id)
all = Asset.objects.all() all = Asset.objects.all()
dept_id = get_user_dept(request) 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): if is_super_user(request):
edept = DEPT.objects.all() 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)) return render_to_response('jasset/group_detail.html', locals(), context_instance=RequestContext(request))
@require_admin
def detail_idc(request): def detail_idc(request):
header_title, path1, path2 = u'IDC详情', u'资产管理', u'IDC详情' header_title, path1, path2 = u'IDC详情', u'资产管理', u'IDC详情'
login_types = {'L': 'LDAP', 'M': 'MAP'} login_types = {'L': 'LDAP', 'M': 'MAP'}
@ -542,6 +653,7 @@ def group_del(request, offset):
return HttpResponseRedirect('/jasset/jgroup_list/') return HttpResponseRedirect('/jasset/jgroup_list/')
@require_login
def host_search(request): def host_search(request):
keyword = request.GET.get('keyword') keyword = request.GET.get('keyword')
login_types = {'L': 'LDAP', 'M': 'MAP'} 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) | posts = Asset.objects.filter(Q(ip__contains=keyword) | Q(idc__name__contains=keyword) |
Q(bis_group__name__contains=keyword) | Q( Q(bis_group__name__contains=keyword) | Q(
comment__contains=keyword)).filter(dept=dept).distinct().order_by('ip') 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) 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)) return render_to_response('jasset/host_search.html', locals(), context_instance=RequestContext(request))

View File

@ -9,7 +9,7 @@ database = jumpserver
[ldap] [ldap]
ldap_enable = 1 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 base_dn = dc=jumpserver, dc=org
root_dn = cn=admin,dc=jumpserver,dc=org root_dn = cn=admin,dc=jumpserver,dc=org
root_pw = secret234 root_pw = secret234

View File

@ -13,7 +13,7 @@ import hashlib
import datetime import datetime
from django.core.paginator import Paginator, EmptyPage, InvalidPage from django.core.paginator import Paginator, EmptyPage, InvalidPage
from django.http import HttpResponse, Http404 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 jasset.models import Asset, BisGroup
from jlog.models import Log from jlog.models import Log
@ -258,8 +258,9 @@ def view_splitter(request, su=None, adm=None):
raise Http404 raise Http404
def user_perm_group_api(user): def user_perm_group_api(username):
if user: if username:
user = User.objects.get(username=username)
perm_list = [] perm_list = []
user_group_all = user.group.all() user_group_all = user.group.all()
for user_group in user_group_all: for user_group in user_group_all:
@ -271,6 +272,14 @@ def user_perm_group_api(user):
return asset_group_list 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): def user_perm_asset_api(username):
user = User.objects.filter(username=username) user = User.objects.filter(username=username)
if user: if user:
@ -347,4 +356,9 @@ def validate(request, user_group=None, user=None, asset_group=None, asset=None,
if not set(assets).issubset(eassets): if not set(assets).issubset(eassets):
return False return False
return True 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.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.humanize',
'jumpserver', 'jumpserver',
'juser', 'juser',
'jasset', 'jasset',

View File

@ -7,6 +7,7 @@ import time
from django import template from django import template
from juser.models import User, UserGroup, DEPT from juser.models import User, UserGroup, DEPT
from jumpserver.api import * from jumpserver.api import *
from jasset.models import AssetAlias
register = template.Library() register = template.Library()
@ -168,6 +169,17 @@ def ugrp_perm_asset_count(user_group_id):
return len(set(assets)) 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') @register.filter(name='group_type_to_str')
def group_type_to_str(type_name): def group_type_to_str(type_name):
group_types = { group_types = {
@ -180,7 +192,12 @@ def group_type_to_str(type_name):
@register.filter(name='ast_to_list') @register.filter(name='ast_to_list')
def ast_to_list(lis): 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') @register.filter(name='ast_to_list_1')
@ -188,10 +205,6 @@ def ast_to_list_1(lis):
return ast.literal_eval(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') @register.filter(name='string_length')
def string_length(string, length): def string_length(string, length):
return '%s ...' % string[0:length] return '%s ...' % string[0:length]

View File

@ -1,11 +1,13 @@
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from api import view_splitter
from views import index, admin_index
urlpatterns = patterns('', urlpatterns = patterns('',
# Examples: # Examples:
# url(r'^$', 'jumpserver.views.home', name='home'), # url(r'^$', 'jumpserver.views.home', name='home'),
# url(r'^blog/', include('blog.urls')), # 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'^api/user/$', 'jumpserver.api.api_user'),
(r'^skin_config/$', 'jumpserver.views.skin_config'), (r'^skin_config/$', 'jumpserver.views.skin_config'),
(r'^install/$', 'jumpserver.views.install'), (r'^install/$', 'jumpserver.views.install'),

View File

@ -1,5 +1,7 @@
# coding: utf-8 # coding: utf-8
from __future__ import division
import datetime import datetime
from django.db.models import Count from django.db.models import Count
@ -7,6 +9,7 @@ from django.shortcuts import render_to_response
from django.template import RequestContext from django.template import RequestContext
from jasset.models import IDC from jasset.models import IDC
from juser.models import DEPT from juser.models import DEPT
from jperm.models import Apply
from jumpserver.api import * from jumpserver.api import *
@ -67,13 +70,24 @@ def index_cu(request):
@require_login @require_login
@require_super_user
def index(request): def index(request):
if request.session.get('role_id') == 0: if request.session.get('role_id') == 0:
return index_cu(request) return index_cu(request)
users = User.objects.all() users = User.objects.all()
hosts = Asset.objects.all() hosts = Asset.objects.all()
online_host = Log.objects.filter(is_finished=0) online = Log.objects.filter(is_finished=0)
online_user = online_host.distinct() 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) li_date, li_str = getDaysByNum(7)
today = datetime.datetime.now().day today = datetime.datetime.now().day
from_week = datetime.datetime.now() - datetime.timedelta(days=7) 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] 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') 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 = {'user': '活跃用户数', 'host': '活跃主机数', 'times': '登录次数'}
top_dic = {} top_dic = {}
for key, value in top.items(): for key, value in top.items():
@ -101,51 +198,6 @@ def skin_config(request):
return render_to_response('skin_config.html') 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): def pages(posts, r):
"""分页公用函数""" """分页公用函数"""
contact_list = posts contact_list = posts
@ -222,28 +274,6 @@ def filter_ajax_api(request):
return render_to_response('filter_ajax_api.html', locals()) 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): def install(request):
from juser.models import DEPT, User from juser.models import DEPT, User
dept = DEPT(id=1, name="超管部", comment="超级管理员部门") dept = DEPT(id=1, name="超管部", comment="超级管理员部门")

View File

@ -1,4 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load mytags %}
{% load humanize %}
{% block content %} {% block content %}
{% include 'nav_cat_bar.html' %} {% include 'nav_cat_bar.html' %}
@ -12,7 +14,7 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="/juser/user_list/">{{ users.count}}</a></h1> <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> <small>All user</small>
</div> </div>
</div> </div>
@ -25,7 +27,7 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="/jasset/host_list/">{{ hosts.count }}</a></h1> <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> <small>All host</small>
</div> </div>
</div> </div>
@ -39,7 +41,7 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users"></span></a></h1> <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> <small>Online user</small>
</div> </div>
</div> </div>
@ -53,28 +55,175 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts"></span></a></h1> <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> <small>Connected host</small>
</div> </div>
</div> </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>
</div> </div>
<div class="row">
<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> </div>
<script> <script>
var cate = {{ li_str|safe }}; var cate = {{ li_str|safe }};
$(function () { $(function () {
$('#top10').highcharts({ $('#top10').highcharts({
chart: { // chart: {
type: 'column' // type: 'column'
}, // },
title: { title: {
text: '一周数据总览', text: '一周数据总览',
x: -20 //center x: -20 //center
@ -94,7 +243,7 @@ $(function () {
yAxis:{ yAxis:{
min: 0, min: 0,
title: { title: {
text: '登录次数' text: ''
}, },
plotLines: [{ plotLines: [{
value: 0, value: 0,

View File

@ -45,28 +45,36 @@
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="groups" class="col-lg-2 control-label">主机<span class="red-fonts">*</span></label> <div>
<div class="col-sm-3"> <label for="groups" class="col-lg-2 control-label">主机<span class="red-fonts">*</span></label>
<select id="groups" size="12" class="form-control m-b" multiple> <div class="col-sm-3">
{% for post in posts %} <select multiple="multiple" id="id_domains_filter" name="domains_filter" style="display: none;">
<option value="{{ post.id }}">{{ post.ip }}</option> </select>
{% endfor %} <div class="input-group" style="padding-bottom: 5px">
</select> <input type="text" size="19" class="form-control input-sm" id="search" name="keyword" placeholder="过滤">
</div> </div>
<div class="col-sm-1"> <select id="groups" size="12" class="form-control m-b" multiple>
<div class="btn-group" style="margin-top: 50px;"> {% for post in posts %}
<button type="button" class="btn btn-xm btn-white" onclick="move('groups', 'groups_selected')"><i class="fa fa-chevron-right"></i></button>
<button type="button" class="btn btn-xm btn-white" onclick="move_left('groups_selected', 'groups')"><i class="fa fa-chevron-left"></i></button>
</div>
</div>
<div class="col-sm-3">
<div>
<select id="groups_selected" name="j_hosts" class="form-control m-b" size="12" multiple>
{% for post in eposts %}
<option value="{{ post.id }}">{{ post.ip }}</option> <option value="{{ post.id }}">{{ post.ip }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
<div class="col-sm-1">
<div class="btn-group" style="margin-top: 50px;">
<button type="button" class="btn btn-xm btn-white" onclick="move('groups', 'groups_selected')"><i class="fa fa-chevron-right"></i></button>
<button type="button" class="btn btn-xm btn-white" onclick="move_left('groups_selected', 'groups')"><i class="fa fa-chevron-left"></i></button>
</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 %}
<option value="{{ post.id }}">{{ post.ip }}</option>
{% endfor %}
</select>
</div>
</div>
</div> </div>
</div> </div>
@ -113,6 +121,17 @@
$(this).prop('selected', true) $(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> </script>
{% endblock %} {% 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_type"> 登录方式 </th>
<th class="text-center" name="j_idc"> 所属IDC </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> {% 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_time"> 添加时间 </th>
<th class="text-center" name="j_comment"> 备注 </th> <th class="text-center" name="j_comment"> 备注 </th>
<th class="text-center"> 操作 </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_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_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_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"> {{ 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" name="j_comment"> {{ post.comment }} </td>
<td class="text-center" data-editable='false'> <td class="text-center" data-editable='false'>
<a value="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a> <a value="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a>
<a href="/jasset/host_edit/?id={{ post.id }}" class="btn btn-xs btn-info">编辑</a> {% ifnotequal session_role_id 0 %}
<a href="/jasset/host_del/{{ post.id }}" class="btn btn-xs btn-danger">删除</a> <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> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -58,8 +58,8 @@
{% for dept in contacts.object_list %} {% for dept in contacts.object_list %}
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center"> {{ dept.name }} </td> <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"><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="/jasset/host_list/?did={{ dept.id }}">{{ dept.id | dept_asset_num }}</a> </td>
<td class="text-center"> {{ dept.comment }} </td> <td class="text-center"> {{ dept.comment }} </td>
<td class="text-center"> <td class="text-center">
{# <a title="[ {{ dept.name }} ] 成员信息" href="../dept_detail/?id={{ dept.id }}" class="iframe btn btn-xs btn-primary">主机</a>#} {# <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 multiple="multiple" id="id_domains_filter" name="domains_filter" style="display: none;">
</select> </select>
<div class="input-group" style="padding-bottom: 5px"> <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> </div>
<select id="groups" size="12" class="form-control m-b" multiple> <select id="groups" size="12" class="form-control m-b" multiple>
{% for post in posts %} {% for post in posts %}
@ -119,17 +119,16 @@
</div> </div>
</div> </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> </script>
{% endblock content %} {% endblock content %}

View File

@ -60,9 +60,9 @@
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center"> {{ group.name }} </td> <td class="text-center"> {{ group.name }} </td>
<td class="text-center"> {{ group.dept.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"> <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"> <a href="/jasset/group_list/?gid={{ group.id }}"> {{ group.id | ugrp_perm_agrp_count }} </a> </td>
<td class="text-center"> {{ group.id | ugrp_perm_asset_count }} </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"> {{ group.comment }} </td>
<td class="text-center"> <td class="text-center">
<a href="../perm_edit/?id={{ group.id }}" class="btn btn-xs btn-danger">授权编辑</a> <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>
<!--<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"> <tr class="gradeX">
<td class="text-center" id="username"> {{ post.applyer }} </td> <td class="text-center" id="username"> {{ post.applyer }} </td>
<td class="text-center" id="dept"> {{ post.dept }} </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="ip"> {{ post.bisgroup|ast_to_list }} </td>
<td class="text-center" id="remote_ip">{% for i in post.asset|ast_to_list %} {{ i }} {% endfor %}... </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="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="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" id=""> {{ post.comment }} </td>
<td class="text-center" data-editable='false'> <td class="text-center" data-editable='false'>
<a value="/jperm/apply_info/?uuid={{ post.uuid }}" class="iframe btn btn-xs btn-primary">详情</a> <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"> <tr class="gradeX">
<td class="text-center" id="username"> {{ post.applyer }} </td> <td class="text-center" id="username"> {{ post.applyer }} </td>
<td class="text-center" id="dept"> {{ post.dept }} </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="ip"> {{ post.bisgroup|ast_to_list }}</td>
<td class="text-center" id="remote_ip"> {% for i in post.asset|ast_to_list %} {{ i }} {% endfor %}... </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="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" id=""> {{ post.comment }} </td>
<td class="text-center" data-editable='false'> <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.name }} </td>
<td class="text-center"> {{ group.dept.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"><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"><a href="/jasset/group_list/?sid={{ group.id }}">{{ group.id | ugrp_perm_agrp_count }} </a> </td>
<td class="text-center"> {{ group.id | ugrp_perm_asset_count }} </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.id | ugrp_perm_asset_count }} </td>
<td class="text-center"> {{ group.comment }} </td> <td class="text-center"> {{ group.comment }} </td>
<td class="text-center"> <td class="text-center">

View File

@ -28,8 +28,8 @@
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="host_add host_add_multi"><a href="/jasset/host_add/">添加资产</a></li> <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="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="group_add"><a href="/jasset/group_add/">添加主机组</a></li>
<li class="jgroup_list group_detail"><a href="/jasset/jgroup_list/">查看主机组</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_add"><a href="/jasset/idc_add/">添加IDC</a></li>
<li class="idc_list idc_detail"><a href="/jasset/idc_list/">查看IDC</a></li> <li class="idc_list idc_detail"><a href="/jasset/idc_list/">查看IDC</a></li>
</ul> </ul>
@ -98,8 +98,8 @@
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="host_add host_add_multi"><a href="/jasset/host_add/">添加资产</a></li> <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="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="group_add"><a href="/jasset/group_add/">添加主机组</a></li>
<li class="jgroup_list group_detail"><a href="/jasset/jgroup_list/">查看主机组</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> <li class="idc_list idc_detail"><a href="/jasset/idc_list/">查看IDC</a></li>
</ul> </ul>
</li> </li>