mirror of https://github.com/jumpserver/jumpserver
bug
parent
433974d77d
commit
c84f124511
|
@ -143,9 +143,6 @@ def log_record(username, host):
|
||||||
log_file_path = os.path.join(today_connect_log_dir, log_filename)
|
log_file_path = os.path.join(today_connect_log_dir, log_filename)
|
||||||
pid = os.getpid()
|
pid = os.getpid()
|
||||||
|
|
||||||
user = get_object(User, username=username)
|
|
||||||
asset = get_object(Asset, ip=host)
|
|
||||||
|
|
||||||
if not os.path.isdir(today_connect_log_dir):
|
if not os.path.isdir(today_connect_log_dir):
|
||||||
try:
|
try:
|
||||||
os.makedirs(today_connect_log_dir)
|
os.makedirs(today_connect_log_dir)
|
||||||
|
@ -158,7 +155,7 @@ def log_record(username, host):
|
||||||
except IOError:
|
except IOError:
|
||||||
raise ServerError('Create logfile failed, Please modify %s permission.' % today_connect_log_dir)
|
raise ServerError('Create logfile failed, Please modify %s permission.' % today_connect_log_dir)
|
||||||
|
|
||||||
log = Log(user=user, asset=asset, log_path=log_file_path, start_time=datetime.now(), pid=pid)
|
log = Log(user=username, host=host, log_path=log_file_path, start_time=datetime.now(), pid=pid)
|
||||||
log.save()
|
log.save()
|
||||||
return log_file, log
|
return log_file, log
|
||||||
|
|
||||||
|
@ -203,6 +200,7 @@ def posix_shell(chan, username, host):
|
||||||
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
|
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
|
||||||
log_file.close()
|
log_file.close()
|
||||||
log.is_finished = True
|
log.is_finished = True
|
||||||
|
log.log_finished = False
|
||||||
log.end_time = datetime.now()
|
log.end_time = datetime.now()
|
||||||
log.save()
|
log.save()
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,14 @@ urlpatterns = patterns('',
|
||||||
url(r'^host_add/$', add_host),
|
url(r'^host_add/$', add_host),
|
||||||
url(r"^host_add_multi/$", add_host_multi),
|
url(r"^host_add_multi/$", add_host_multi),
|
||||||
url(r'^host_list/$', list_host),
|
url(r'^host_list/$', list_host),
|
||||||
|
url(r'^search/$', host_search),
|
||||||
url(r"^(\d+.\d+.\d+.\d+)/$", jlist_ip),
|
url(r"^(\d+.\d+.\d+.\d+)/$", jlist_ip),
|
||||||
url(r'^idc_add/$', add_idc),
|
url(r'^idc_add/$', add_idc),
|
||||||
url(r'^idc_list/$', list_idc),
|
url(r'^idc_list/$', list_idc),
|
||||||
url(r'^idc_detail/(\d+)$', detail_idc),
|
url(r'^idc_detail/(\d+)$', detail_idc),
|
||||||
url(r'^idc_del/(\d+)/$', del_idc),
|
url(r'^idc_del/(\d+)/$', del_idc),
|
||||||
url(r'^group_add/$', add_group),
|
url(r'^group_add/$', add_group),
|
||||||
url(r'^group_edit/(\d+)/$', edit_group),
|
url(r'^group_edit/$', edit_group),
|
||||||
url(r'^group_list/$', list_group),
|
url(r'^group_list/$', list_group),
|
||||||
url(r'^group_detail/(\d+)/$', detail_group),
|
url(r'^group_detail/(\d+)/$', detail_group),
|
||||||
url(r'^group_del_host/(\w+)/$', group_del_host),
|
url(r'^group_del_host/(\w+)/$', group_del_host),
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
# coding:utf-8
|
# coding:utf-8
|
||||||
|
|
||||||
|
from django.db.models import Q
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
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 django.core.paginator import Paginator, EmptyPage
|
from django.core.paginator import Paginator, EmptyPage, InvalidPage
|
||||||
|
|
||||||
from models import IDC, Asset, BisGroup
|
from models import IDC, Asset, BisGroup
|
||||||
from juser.models import UserGroup
|
from juser.models import UserGroup
|
||||||
from connect import PyCrypt, KEY
|
from connect import PyCrypt, KEY
|
||||||
from jumpserver.views import jasset_group_add, jasset_host_edit
|
from jumpserver.views import jasset_group_add, jasset_host_edit, pages
|
||||||
|
|
||||||
cryptor = PyCrypt(KEY)
|
cryptor = PyCrypt(KEY)
|
||||||
|
|
||||||
|
@ -86,13 +88,13 @@ def add_host_multi(request):
|
||||||
for host in multi_hosts:
|
for host in multi_hosts:
|
||||||
if host == '':
|
if host == '':
|
||||||
break
|
break
|
||||||
j_ip, j_port, j_type, j_idc, j_groups, j_user_group, j_active, j_comment = host.split()
|
j_ip, j_port, j_type, j_idc, j_groups, j_active, j_comment = host.split()
|
||||||
j_type = login_types[j_type]
|
j_type = login_types[j_type]
|
||||||
j_groups = j_groups.split(',')
|
j_groups = j_groups.split(',')
|
||||||
for group in j_groups:
|
for group in j_groups:
|
||||||
g = group.strip('[]').encode('utf-8').strip()
|
g = group.strip('[]').encode('utf-8').strip()
|
||||||
j_group.append(g)
|
j_group.append(g)
|
||||||
print j_group,type(j_group)
|
|
||||||
if Asset.objects.filter(ip=str(j_ip)):
|
if Asset.objects.filter(ip=str(j_ip)):
|
||||||
emg = u'该IP %s 已存在!' %j_ip
|
emg = u'该IP %s 已存在!' %j_ip
|
||||||
return render_to_response('jasset/host_add_multi.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('jasset/host_add_multi.html', locals(), context_instance=RequestContext(request))
|
||||||
|
@ -141,7 +143,6 @@ def list_host(request):
|
||||||
header_title, path1, path2 = u'查看主机 | List Host', u'资产管理', u'查看主机'
|
header_title, path1, path2 = u'查看主机 | List Host', u'资产管理', u'查看主机'
|
||||||
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
|
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
|
||||||
posts = contact_list = Asset.objects.all().order_by('ip')
|
posts = contact_list = Asset.objects.all().order_by('ip')
|
||||||
print posts
|
|
||||||
p = paginator = Paginator(contact_list, 20)
|
p = paginator = Paginator(contact_list, 20)
|
||||||
try:
|
try:
|
||||||
page = int(request.GET.get('page', '1'))
|
page = int(request.GET.get('page', '1'))
|
||||||
|
@ -285,9 +286,10 @@ def list_group(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))
|
||||||
|
|
||||||
|
|
||||||
def edit_group(request, offset):
|
def edit_group(request):
|
||||||
header_title, path1, path2 = u'编辑主机组 | Edit Group', u'资产管理', u'编辑主机组'
|
header_title, path1, path2 = u'编辑主机组 | Edit Group', u'资产管理', u'编辑主机组'
|
||||||
group = BisGroup.objects.get(id=offset)
|
group_id = request.GET.get('id')
|
||||||
|
group = BisGroup.objects.get(id=group_id)
|
||||||
all = Asset.objects.all()
|
all = Asset.objects.all()
|
||||||
eposts = contact_list = Asset.objects.filter(bis_group=group).order_by('ip')
|
eposts = contact_list = Asset.objects.filter(bis_group=group).order_by('ip')
|
||||||
posts = [g for g in all if g not in eposts]
|
posts = [g for g in all if g not in eposts]
|
||||||
|
@ -296,13 +298,13 @@ def edit_group(request, offset):
|
||||||
j_hosts = request.POST.getlist('j_hosts')
|
j_hosts = request.POST.getlist('j_hosts')
|
||||||
j_comment = request.POST.get('j_comment')
|
j_comment = request.POST.get('j_comment')
|
||||||
|
|
||||||
group = BisGroup.objects.get(name=j_group)
|
|
||||||
group.asset_set.clear()
|
group.asset_set.clear()
|
||||||
for host in j_hosts:
|
for host in j_hosts:
|
||||||
g = Asset.objects.get(id=host)
|
g = Asset.objects.get(id=host)
|
||||||
group.asset_set.add(g)
|
group.asset_set.add(g)
|
||||||
|
BisGroup.objects.filter(id=group_id).update(name=j_group, comment=j_comment)
|
||||||
smg = u'主机组%s修改成功' %j_group
|
smg = u'主机组%s修改成功' %j_group
|
||||||
return HttpResponseRedirect('/jasset/group_detail/%s' %offset)
|
return HttpResponseRedirect('/jasset/group_detail/%s' % group_id)
|
||||||
|
|
||||||
return render_to_response('jasset/group_add.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('jasset/group_add.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
@ -371,5 +373,17 @@ def group_del(request, offset):
|
||||||
return HttpResponseRedirect('/jasset/group_list/')
|
return HttpResponseRedirect('/jasset/group_list/')
|
||||||
|
|
||||||
|
|
||||||
|
def host_search(request):
|
||||||
|
keyword = request.GET.get('keyword')
|
||||||
|
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
|
||||||
|
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')
|
||||||
|
print posts
|
||||||
|
contact_list, p, contacts = pages(posts, request)
|
||||||
|
print contact_list, p, contacts
|
||||||
|
|
||||||
|
return render_to_response('jasset/host_search.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
def test(request):
|
def test(request):
|
||||||
return render_to_response('jasset/test.html', locals())
|
return render_to_response('jasset/test.html', locals())
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from juser.models import User
|
|
||||||
from jasset.models import Asset
|
|
||||||
|
|
||||||
|
|
||||||
class Log(models.Model):
|
class Log(models.Model):
|
||||||
user = models.ForeignKey(User)
|
user = models.CharField(max_length=20, null=True)
|
||||||
asset = models.ForeignKey(Asset)
|
host = models.CharField(max_length=20, null=True)
|
||||||
log_path = models.CharField(max_length=100)
|
log_path = models.CharField(max_length=100)
|
||||||
start_time = models.DateTimeField(null=True)
|
start_time = models.DateTimeField(null=True)
|
||||||
pid = models.IntegerField(max_length=10)
|
pid = models.IntegerField(max_length=10)
|
||||||
is_finished = models.BooleanField(default=False)
|
is_finished = models.BooleanField(default=False)
|
||||||
|
log_finished = models.BooleanField(default=False)
|
||||||
end_time = models.DateTimeField(null=True)
|
end_time = models.DateTimeField(null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
|
|
@ -3,7 +3,10 @@ from django.conf.urls import patterns, include, url
|
||||||
from jlog.views import *
|
from jlog.views import *
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
url(r'^$', jlog_list),
|
url(r'^$', log_list_online),
|
||||||
url(r'^log_list/(\w+)/$', jlog_list),
|
url(r'^log_list/online/$', log_list_online),
|
||||||
url(r'^log_kill/(\d+)', jlog_kill),
|
url(r'^log_list/offline/$', log_list_offline),
|
||||||
|
url(r'^log_kill/(\d+)', log_kill),
|
||||||
|
url(r'^history/$', log_history),
|
||||||
|
url(r'^search/$', log_search),
|
||||||
)
|
)
|
|
@ -2,30 +2,68 @@
|
||||||
import os
|
import os
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.db.models import Q
|
||||||
|
from django.http import HttpResponse
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.template import RequestContext
|
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.core.paginator import Paginator, EmptyPage
|
|
||||||
|
|
||||||
from connect import BASE_DIR
|
from connect import BASE_DIR
|
||||||
from jlog.models import Log
|
from jlog.models import Log
|
||||||
|
from jumpserver.views import pages
|
||||||
|
|
||||||
CONF = ConfigParser.ConfigParser()
|
CONF = ConfigParser.ConfigParser()
|
||||||
CONF.read('%s/jumpserver.conf' % BASE_DIR)
|
CONF.read('%s/jumpserver.conf' % BASE_DIR)
|
||||||
|
|
||||||
|
|
||||||
def jlog_list(request, offset='online'):
|
def log_list_online(request):
|
||||||
header_title, path1, path2 = u'查看日志 | Log List.', u'查看日志', u'日志列表'
|
header_title, path1, path2 = u'查看日志 | Log List.', u'查看日志', u'在线用户'
|
||||||
web_socket_host = CONF.get('websocket', 'web_socket_host')
|
web_socket_host = CONF.get('websocket', 'web_socket_host')
|
||||||
online = Log.objects.filter(is_finished=0)
|
posts = Log.objects.filter(is_finished=0).order_by('-start_time')
|
||||||
offline = Log.objects.filter(is_finished=1)
|
contact_list, p, contacts = pages(posts, request)
|
||||||
|
|
||||||
return render_to_response('jlog/log_list.html', locals())
|
return render_to_response('jlog/log_online.html', locals())
|
||||||
|
|
||||||
|
|
||||||
def jlog_kill(request, offset):
|
def log_list_offline(request):
|
||||||
|
header_title, path1, path2 = u'查看日志 | Log List.', u'查看日志', u'历史记录'
|
||||||
|
web_socket_host = CONF.get('websocket', 'web_socket_host')
|
||||||
|
posts = Log.objects.filter(is_finished=1).order_by('-start_time')
|
||||||
|
contact_list, p, contacts = pages(posts, request)
|
||||||
|
|
||||||
|
return render_to_response('jlog/log_offline.html', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def log_kill(request, offset):
|
||||||
pid = offset
|
pid = offset
|
||||||
if pid:
|
if pid:
|
||||||
os.kill(int(pid), 9)
|
os.kill(int(pid), 9)
|
||||||
Log.objects.filter(pid=pid).update(is_finished=1, end_time=datetime.now())
|
Log.objects.filter(pid=pid).update(is_finished=1, end_time=datetime.now())
|
||||||
return HttpResponseRedirect('jlog/log_list.html', locals())
|
return HttpResponseRedirect('jlog/log_offline.html', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def log_history(request):
|
||||||
|
if request.method == 'GET':
|
||||||
|
id = request.GET.get('id', 0)
|
||||||
|
log = Log.objects.get(id=int(id))
|
||||||
|
if log:
|
||||||
|
log_his = "%s.his" % log.log_path
|
||||||
|
if os.path.isfile(log_his):
|
||||||
|
f = open(log_his)
|
||||||
|
content = f.read()
|
||||||
|
return HttpResponse(content)
|
||||||
|
|
||||||
|
|
||||||
|
def log_search(request):
|
||||||
|
keyword = request.GET.get('keyword')
|
||||||
|
env = request.GET.get('env')
|
||||||
|
if env == 'online':
|
||||||
|
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||||
|
.filter(is_finished=0).order_by('-start_time')
|
||||||
|
contact_list, p, contacts = pages(posts, request)
|
||||||
|
elif env == 'offline':
|
||||||
|
posts = contact_list = Log.objects.filter(Q(user__contains=keyword) | Q(host__contains=keyword)) \
|
||||||
|
.filter(is_finished=1).order_by('-start_time')
|
||||||
|
contact_list, p, contacts = pages(posts, request)
|
||||||
|
|
||||||
|
return render_to_response('jlog/log_search.html', locals())
|
||||||
|
|
|
@ -101,5 +101,9 @@ def filter_private(group):
|
||||||
for g in group:
|
for g in group:
|
||||||
if not pattern.match(g.name):
|
if not pattern.match(g.name):
|
||||||
agroup.append(g)
|
agroup.append(g)
|
||||||
|
try:
|
||||||
agroup.remove(p)
|
agroup.remove(p)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
return agroup
|
return agroup
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
from django.http import HttpResponse
|
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.core.paginator import Paginator, EmptyPage, InvalidPage
|
||||||
|
|
||||||
from juser.models import User
|
from juser.models import User
|
||||||
from connect import PyCrypt, KEY
|
|
||||||
from jasset.models import Asset, BisGroup, IDC
|
from jasset.models import Asset, BisGroup, IDC
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +44,6 @@ def jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_active, j_com
|
||||||
print j_idc
|
print j_idc
|
||||||
print
|
print
|
||||||
a = Asset.objects.get(id=j_id)
|
a = Asset.objects.get(id=j_id)
|
||||||
print '123'
|
|
||||||
if j_type == 'M':
|
if j_type == 'M':
|
||||||
a.ip = j_ip
|
a.ip = j_ip
|
||||||
a.port = j_port
|
a.port = j_port
|
||||||
|
@ -67,6 +65,22 @@ def jasset_host_edit(j_id, j_ip, j_idc, j_port, j_type, j_group, j_active, j_com
|
||||||
a.save()
|
a.save()
|
||||||
|
|
||||||
|
|
||||||
|
def pages(posts, r):
|
||||||
|
contact_list = posts
|
||||||
|
p = paginator = Paginator(contact_list, 10)
|
||||||
|
try:
|
||||||
|
page = int(r.GET.get('page', '1'))
|
||||||
|
except ValueError:
|
||||||
|
page = 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
contacts = paginator.page(page)
|
||||||
|
except (EmptyPage, InvalidPage):
|
||||||
|
contacts = paginator.page(paginator.num_pages)
|
||||||
|
|
||||||
|
return contact_list, p, contacts
|
||||||
|
|
||||||
|
|
||||||
def login(request):
|
def login(request):
|
||||||
"""登录界面"""
|
"""登录界面"""
|
||||||
if request.session.get('username'):
|
if request.session.get('username'):
|
||||||
|
|
|
@ -2,11 +2,10 @@
|
||||||
#coding: utf-8
|
#coding: utf-8
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import time
|
import time
|
||||||
|
import psutil
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
cur_dir = os.path.dirname(__file__)
|
|
||||||
sys.path.append('%s/webroot/AutoSa/' % cur_dir)
|
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
|
||||||
|
|
||||||
import django
|
import django
|
||||||
|
@ -14,28 +13,24 @@ django.setup()
|
||||||
from jlog.models import Log
|
from jlog.models import Log
|
||||||
|
|
||||||
|
|
||||||
def log_hanler(pid):
|
def log_hanler(id):
|
||||||
log = Log.objects.filter(id=pid)
|
log = Log.objects.get(id=id)
|
||||||
if log:
|
if log:
|
||||||
log = log[0]
|
filename = log.log_path
|
||||||
filename = log.logfile
|
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
ret1 = os.system('cat %s | grep "DateTime" > %s.his' % (filename, filename))
|
ret1 = os.system('cat %s | grep "DateTime" > %s.his' % (filename, filename))
|
||||||
ret2 = os.system('cat %s | grep "\[.*@.*\][\$\#]" >> %s.his' % (filename, filename))
|
ret2 = os.system('cat %s | grep "\[.*@.*\][\$\#]" >> %s.his' % (filename, filename))
|
||||||
ret3 = os.system('cat %s | grep "EndTime" >> %s.his' % (filename, filename))
|
ret3 = os.system('cat %s | grep "EndTime" >> %s.his' % (filename, filename))
|
||||||
if (ret1 + ret2 + ret3) == 0:
|
if (ret1 + ret2 + ret3) == 0:
|
||||||
print 'Handler %s ok.' % filename
|
print 'Handler %s ok.' % filename
|
||||||
|
log.log_finished = True
|
||||||
|
log.save()
|
||||||
|
|
||||||
|
|
||||||
def set_finish(id):
|
def set_finish(id):
|
||||||
logs = Log.objects.filter(id=id, finish=0)
|
log = Log.objects.filter(id=id)
|
||||||
if logs:
|
if log:
|
||||||
structtime_start = time.localtime()
|
log.update(is_finished=1, end_time=datetime.now())
|
||||||
timestamp_end = int(time.mktime(structtime_start))
|
|
||||||
log = logs[0]
|
|
||||||
log.finish = 1
|
|
||||||
log.end_time = timestamp_end
|
|
||||||
log.save()
|
|
||||||
|
|
||||||
|
|
||||||
def kill_pid(pid):
|
def kill_pid(pid):
|
||||||
|
@ -45,52 +40,37 @@ def kill_pid(pid):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def pid_exist(pid):
|
|
||||||
pid_dir = "/proc/%s" % pid
|
|
||||||
if os.path.isdir(pid_dir):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def del_pid(pid_id):
|
|
||||||
pid = Pid.objects.filter(id=pid_id)
|
|
||||||
if pid:
|
|
||||||
pid[0].delete()
|
|
||||||
|
|
||||||
|
|
||||||
def get_pids():
|
def get_pids():
|
||||||
pids = []
|
pids1, pids2 = [], []
|
||||||
pids_obj = Pid.objects.all()
|
pids1_obj = Log.objects.filter(is_finished=0)
|
||||||
for pid_obj in pids_obj:
|
pids2_obj = Log.objects.filter(is_finished=1, log_finished=0)
|
||||||
pids.append((pid_obj.id, pid_obj.ppid, pid_obj.cpid, pid_obj.pid, pid_obj.start_time))
|
for pid_obj in pids1_obj:
|
||||||
return pids
|
pids1.append((pid_obj.id, pid_obj.pid, pid_obj.log_path, pid_obj.is_finished, pid_obj.log_finished, pid_obj.start_time))
|
||||||
|
for pid_obj in pids2_obj:
|
||||||
|
pids2.append(pid_obj.id)
|
||||||
|
|
||||||
|
return pids1, pids2
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
for pid_id, ppid, cpid, pid, start_time in get_pids():
|
pids1, pids2 = get_pids()
|
||||||
if pid_exist(cpid):
|
for pid_id in pids2:
|
||||||
if pid_exist(ppid):
|
log_hanler(pid_id)
|
||||||
structtime_start = time.localtime()
|
|
||||||
timestamp_end = int(time.mktime(structtime_start))
|
|
||||||
if timestamp_end - start_time > 7200:
|
|
||||||
kill_pid(ppid)
|
|
||||||
kill_pid(cpid)
|
|
||||||
del_pid(pid_id)
|
|
||||||
set_finish(pid)
|
|
||||||
log_hanler(pid)
|
|
||||||
else:
|
|
||||||
kill_pid(cpid)
|
|
||||||
del_pid(pid_id)
|
|
||||||
set_finish(pid)
|
|
||||||
log_hanler(pid)
|
|
||||||
else:
|
|
||||||
del_pid(pid_id)
|
|
||||||
set_finish(pid)
|
|
||||||
log_hanler(pid)
|
|
||||||
|
|
||||||
|
for pid_id, pid, log_path, is_finished, log_finished, start_time in pids1:
|
||||||
|
print pid_id, start_time, type(start_time)
|
||||||
|
try:
|
||||||
|
file_time = int(os.stat(log_path).st_ctime)
|
||||||
|
now_time = int(time.time())
|
||||||
|
if now_time - file_time > 18000:
|
||||||
|
if psutil.pid_exists(pid):
|
||||||
|
kill_pid(pid)
|
||||||
|
set_finish(pid_id)
|
||||||
|
log_hanler(pid_id)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
while True:
|
while True:
|
||||||
run()
|
run()
|
||||||
time.sleep(0.5)
|
time.sleep(5)
|
||||||
|
|
|
@ -90,16 +90,4 @@ function selectAll(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function move(from, to) {
|
|
||||||
$("#"+from+" option").each(function(){
|
|
||||||
if ( $(this).prop("selected") == true ) {
|
|
||||||
$("#"+to).append(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function move_all(from, to){
|
|
||||||
$("#"+from).children().each(function(){
|
|
||||||
$("#"+to).append(this);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<form id="assetForm" method="post" class="form-horizontal">
|
<form id="assetForm" method="post" class="form-horizontal">
|
||||||
<div class="form-group"><label class="col-sm-2 control-label"> 主机组名 </label>
|
<div class="form-group"><label class="col-sm-2 control-label"> 主机组名 </label>
|
||||||
<div class="col-sm-8"><input type="text" value="{{ group.name }}" placeholder="网站" name="j_group" class="form-control"></div>
|
<div class="col-sm-8" name="group_id" value="{{ post.id }}"><input type="text" value="{{ group.name }}" placeholder="网站" name="j_group" class="form-control"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
|
|
|
@ -92,21 +92,21 @@
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<select id="j_group" name="j_group" class="form-control m-b" multiple size="10">
|
<select id="j_group" name="j_group" class="form-control m-b" multiple size="10">
|
||||||
{% for g in egroup %}
|
{% for g in egroup %}
|
||||||
<option type="checkbox" value="{{ g.name }}">{{ g.name }} --- {{ g.comment }}</option>
|
<option type="checkbox" value="{{ g.name }}">{{ g.name }} {% if g.comment %} --- {{ g.comment }} {% endif %}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
<!--<div class="hr-line-dashed"></div>-->
|
||||||
<div class="form-group">
|
<!--<div class="form-group">-->
|
||||||
<label for="j_group" class="col-sm-2 control-label"> 所属用户组<span class="red-fonts">*</span> </label>
|
<!--<label for="j_group" class="col-sm-2 control-label"> 所属用户组<span class="red-fonts">*</span> </label>-->
|
||||||
<div class="col-sm-8">
|
<!--<div class="col-sm-8">-->
|
||||||
{% for g in eusergroup %}
|
<!--{% for g in eusergroup %}-->
|
||||||
<label class="checkbox-inline"><input type="checkbox" id="j_usergroup" value="{{ g }}" name="j_usergroup"> {{ g }} </label>
|
<!--<label class="checkbox-inline"><input type="checkbox" id="j_usergroup" value="{{ g }}" name="j_usergroup"> {{ g }} </label>-->
|
||||||
{% endfor %}
|
<!--{% endfor %}-->
|
||||||
</div>
|
<!--</div>-->
|
||||||
</div>
|
<!--</div>-->
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
<div class="form-group"><label class="col-sm-2 control-label"> 是否激活<span class="red-fonts">*</span> </label>
|
<div class="form-group"><label class="col-sm-2 control-label"> 是否激活<span class="red-fonts">*</span> </label>
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h4>按照文本框内主机信息格式填写, 多台主机回车换行</h4>
|
<h4>按照文本框内主机信息格式填写, 多台主机回车换行</h4>
|
||||||
<form id="assetMulti" method="post" class="form-horizontal">
|
<form id="assetMulti" method="post" class="form-horizontal">
|
||||||
<div><textarea id="j_multi" name="j_multi" type="text" placeholder="192.168.1.1 22 LDAP 北京联通 [网站,数据库] admin 1 网站服务器" class="form-control" style="width:700px;height:500px"></textarea></div>
|
<div><textarea id="j_multi" name="j_multi" type="text" placeholder="192.168.1.1 22 LDAP 北京联通 [网站,数据库] 1 网站服务器" class="form-control" style="width:700px;height:500px"></textarea></div>
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-4 col-sm-offset-4">
|
<div class="col-sm-4 col-sm-offset-4">
|
||||||
|
|
|
@ -29,8 +29,19 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<div class="">
|
<div>
|
||||||
<a target="_blank" href="/jasset/host_add" class="btn btn-sm btn-primary "> 添加 </a>
|
<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>
|
</div>
|
||||||
|
|
||||||
<form id="contents_form" name="contents_form">
|
<form id="contents_form" name="contents_form">
|
||||||
|
@ -146,6 +157,25 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -0,0 +1,64 @@
|
||||||
|
{% load mytags %}
|
||||||
|
<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" name="j_time"> 添加时间 </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" 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_group">{% for group in post.bis_group.all|filter_private %} {{ group }} {% endfor %}</td>
|
||||||
|
<td class="text-center" name="j_active"> {{ post.is_active|bool2str }} </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" data-editable='false'>
|
||||||
|
<a href="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a>
|
||||||
|
<a href="/jasset/host_edit/{{ post.id }}" class="btn btn-xs btn-info">编辑</a>
|
||||||
|
<a href="/jasset/host_del/{{ post.id }}" class="btn btn-xs btn-danger">删除</a>
|
||||||
|
</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>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
|
||||||
|
<ul class="pagination" style="margin-top: 0; float: right">
|
||||||
|
|
||||||
|
{% if contacts.has_previous %}
|
||||||
|
<li><a href="?page={{ contacts.previous_page_number }}">«</a></li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for page in p.page_range %}
|
||||||
|
{% ifequal offset1 page %}
|
||||||
|
<li class="active"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||||
|
{% endifequal %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if contacts.has_next %}
|
||||||
|
<li><a href="?page={{ contacts.next_page_number }}">»</a></li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,179 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block content %}
|
||||||
|
{% include 'nav_cat_bar.html' %}
|
||||||
|
<style>
|
||||||
|
.bootstrap-dialog-body {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
.bootstrap-dialog-message {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
.modal-dialog {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
width: 800px;
|
||||||
|
}
|
||||||
|
.modal-body {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
.modal-header {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
.bootstrap-dialog-message {
|
||||||
|
color: #00FF00;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="wrapper wrapper-content animated fadeInRight">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="ibox float-e-margins">
|
||||||
|
<div id="ibox-content" class="ibox-title">
|
||||||
|
<h5> 用户日志详细信息列表 </h5>
|
||||||
|
<div class="ibox-tools">
|
||||||
|
<a class="collapse-link">
|
||||||
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||||
|
<i class="fa fa-wrench"></i>
|
||||||
|
</a>
|
||||||
|
<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 class="panel-options">
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||||
|
<li class="active"><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
|
||||||
|
<li style="float: right">
|
||||||
|
<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="log_search()">
|
||||||
|
Search
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div class="tab-content">
|
||||||
|
<table class="table table-striped table-bordered table-hover ">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for post in contacts.object_list %}
|
||||||
|
<tr class="gradeX">
|
||||||
|
<td class="text-center" id="username"> {{ post.user }} </td>
|
||||||
|
<td class="text-center" id="ip"> {{ post.host }} </td>
|
||||||
|
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 命令统计 </td>
|
||||||
|
<td class="text-center" id="start_time"> {{ post.start_time|date:"Y-m-d H:i:s"}} </td>
|
||||||
|
<td class="text-center" id="end_time"> {{ post.end_time|date:"Y-m-d H:i:s" }} </td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 col-sm-offset-6">
|
||||||
|
<div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
|
||||||
|
<ul class="pagination" style="margin-top: 0; float: right">
|
||||||
|
|
||||||
|
{% if contacts.has_previous %}
|
||||||
|
<li><a href="?page={{ contacts.previous_page_number }}">«</a></li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for page in p.page_range %}
|
||||||
|
{% ifequal offset1 page %}
|
||||||
|
<li class="active"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||||
|
{% endifequal %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if contacts.has_next %}
|
||||||
|
<li><a href="?page={{ contacts.next_page_number }}">»</a></li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="http://{{ web_socket_host }}/socket.io/socket.io.js"></script>
|
||||||
|
<script>
|
||||||
|
$('.log_command').on('click',function(){
|
||||||
|
var url = $(this).attr('href');
|
||||||
|
var username = $('#username')[0].innerText;
|
||||||
|
var ip = $('#ip')[0].innerText;
|
||||||
|
var start_time = $('#start_time')[0].innerText;
|
||||||
|
var end_time = $('#end_time')[0].innerText;
|
||||||
|
var div_username = ' 登录用户名: '+'<span class="text-info">'+username+'' + '</span>';
|
||||||
|
var div_ip = ' 登录主机: '+'<span class="text-info">' + ip + '</span>';
|
||||||
|
var div_time = ' 开始时间: ' + '<span class="text-info">'+start_time +'</span>' + ' 结束时间: ' +'<span class="text-info">' + end_time + '</span'
|
||||||
|
var title = 'JumpServer命令统计 '+ div_username + div_ip + div_time
|
||||||
|
$.ajax({url:url,success:function(data){
|
||||||
|
BootstrapDialog.show({title: title, message:data});
|
||||||
|
}});
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
globalConfig = {
|
||||||
|
SOCKET_HOST: "{{ web_socket_host }}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function cut(num){
|
||||||
|
var g_url = "/jlog/log_kill/"+num;
|
||||||
|
console.log(g_url);
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: g_url,
|
||||||
|
success: window.open("/jlog/","_self")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function log_search(){
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/jlog/search/?env=offline",
|
||||||
|
data: $("#search_form").serialize(),
|
||||||
|
success: function (data) {
|
||||||
|
$(".tab-content").html(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#search_input").keydown(function(e){
|
||||||
|
if(e.keyCode==13){
|
||||||
|
log_search()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,218 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block content %}
|
||||||
|
{% include 'nav_cat_bar.html' %}
|
||||||
|
<style>
|
||||||
|
.bootstrap-dialog-body {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
.bootstrap-dialog-message {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
.modal-dialog {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
width: 800px;
|
||||||
|
}
|
||||||
|
.modal-body {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
.modal-header {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="wrapper wrapper-content animated fadeInRight">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="ibox float-e-margins">
|
||||||
|
<div id="ibox-content" class="ibox-title">
|
||||||
|
<h5> 用户日志详细信息列表 </h5>
|
||||||
|
<div class="ibox-tools">
|
||||||
|
<a class="collapse-link">
|
||||||
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||||
|
<i class="fa fa-wrench"></i>
|
||||||
|
</a>
|
||||||
|
<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 class="panel-options">
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li class="active"><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
|
||||||
|
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
|
||||||
|
<li style="float: right">
|
||||||
|
<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="log_search()">
|
||||||
|
Search
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div class="tab-content">
|
||||||
|
<table class="table table-striped table-bordered table-hover ">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for post in contacts.object_list %}
|
||||||
|
<tr class="gradeX">
|
||||||
|
<td id="username" class="text-center"> {{ post.user }} </td>
|
||||||
|
<td id="ip" class="text-center"> {{ post.host }} </td>
|
||||||
|
<td class="text-center"><a class="monitor" filename="{{ post.log_path }}"> 监控 </a></td>
|
||||||
|
<td class="text-center"><input type="button" id="cut" class="btn btn-danger btn-xs" name="cut" value="阻断" onclick='cut("{{ post.pid }}")' /></td>
|
||||||
|
<td class="text-center"> {{ post.start_time|date:"Y-m-d H:i:s" }} </td>
|
||||||
|
<td class="text-center"> {{ post.end_time|date:"Y-m-d H:i:s" }} </td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 col-sm-offset-6">
|
||||||
|
<div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
|
||||||
|
<ul class="pagination" style="margin-top: 0; float: right">
|
||||||
|
|
||||||
|
{% if contacts.has_previous %}
|
||||||
|
<li><a href="?page={{ contacts.previous_page_number }}">«</a></li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for page in p.page_range %}
|
||||||
|
{% ifequal offset1 page %}
|
||||||
|
<li class="active"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||||
|
{% endifequal %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if contacts.has_next %}
|
||||||
|
<li><a href="?page={{ contacts.next_page_number }}">»</a></li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="http://{{ web_socket_host }}/socket.io/socket.io.js"></script>
|
||||||
|
<script>
|
||||||
|
$.fn.webSocket = function(opt){
|
||||||
|
var st = {};
|
||||||
|
st = $.extend(st,opt);
|
||||||
|
var message = {};
|
||||||
|
var $this = $(this);
|
||||||
|
var genUid = function(){
|
||||||
|
return new Date().getTime()+""+Math.floor(Math.random()*899+100);
|
||||||
|
};
|
||||||
|
var init = function(e){
|
||||||
|
var socket = io.connect('ws://'+globalConfig.SOCKET_HOST);
|
||||||
|
var node = $(e.target);
|
||||||
|
message.id = genUid();
|
||||||
|
message.filename = node.attr('filename');
|
||||||
|
var username = $('#username')[0].innerText;
|
||||||
|
var ip = $('#ip')[0].innerText;
|
||||||
|
BootstrapDialog.show({message:function(){
|
||||||
|
var escapeString = function (html){
|
||||||
|
var elem = document.createElement('div')
|
||||||
|
var txt = document.createTextNode(html)
|
||||||
|
elem.appendChild(txt)
|
||||||
|
return elem.innerHTML;
|
||||||
|
}
|
||||||
|
var tag = $('<div id="log" style="height: 500px;overflow: auto;background-color: rgba(0, 0, 0, 0);"></div>');
|
||||||
|
//告诉服务器端有用户登录
|
||||||
|
socket.emit('login', {userid:message.id, filename:message.filename});
|
||||||
|
socket.on('message',function(obj){
|
||||||
|
//去除log中的颜色控制字符
|
||||||
|
var regx = /\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]/g;
|
||||||
|
// tag.append('<p>'+escapeString(obj.content.replace(regx,''))+'</p>');
|
||||||
|
tag.append('<p>'+escapeString(obj.content)+'</p>');
|
||||||
|
tag.animate({ scrollTop: tag[0].scrollHeight}, 1);
|
||||||
|
});
|
||||||
|
tag[0].style.color = "#00FF00";
|
||||||
|
return tag[0];
|
||||||
|
} ,
|
||||||
|
title:'Jumpserver实时监控 '+' 登录用户名: '+'<span class="text-info">'+username+'</span>'+' 登录主机: '+'<span class="text-info">'+ip,
|
||||||
|
onhide:function(){
|
||||||
|
socket.emit('disconnect');
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
$this.on("click",function(e){
|
||||||
|
init(e);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$('.log_command').on('click',function(){
|
||||||
|
var url = $(this).attr('href');
|
||||||
|
$.ajax({url:url,success:function(data){
|
||||||
|
BootstrapDialog.show({title:'命令统计',message:data});
|
||||||
|
}});
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
globalConfig = {
|
||||||
|
SOCKET_HOST: "{{ web_socket_host }}"
|
||||||
|
}
|
||||||
|
$(".monitor").webSocket()
|
||||||
|
|
||||||
|
|
||||||
|
function log_search(){
|
||||||
|
console.log('hell0')
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/jlog/search/?env=online",
|
||||||
|
data: $("#search_form").serialize(),
|
||||||
|
success: function (data) {
|
||||||
|
$(".tab-content").html(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#search_input").keydown(function(e){
|
||||||
|
if(e.keyCode==13){
|
||||||
|
log_search()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function cut(num){
|
||||||
|
var g_url = "/jlog/log_kill/"+num;
|
||||||
|
console.log(g_url);
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: g_url,
|
||||||
|
success: window.open("/jlog/","_self")
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<div class="tab-content">
|
||||||
|
<table class="table table-striped table-bordered table-hover ">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for post in contacts.object_list %}
|
||||||
|
<tr class="gradeX">
|
||||||
|
<td class="text-center" id="username"> {{ post.user }} </td>
|
||||||
|
<td class="text-center" id="ip"> {{ post.host }} </td>
|
||||||
|
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 命令统计 </td>
|
||||||
|
<td class="text-center" id="start_time"> {{ post.start_time|date:"Y-m-d H:i:s"}} </td>
|
||||||
|
<td class="text-center" id="end_time"> {{ post.end_time|date:"Y-m-d H:i:s" }} </td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 col-sm-offset-6">
|
||||||
|
<div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
|
||||||
|
<ul class="pagination" style="margin-top: 0; float: right">
|
||||||
|
|
||||||
|
{% if contacts.has_previous %}
|
||||||
|
<li><a href="?page={{ contacts.previous_page_number }}">«</a></li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for page in p.page_range %}
|
||||||
|
{% ifequal offset1 page %}
|
||||||
|
<li class="active"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
|
||||||
|
{% endifequal %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if contacts.has_next %}
|
||||||
|
<li><a href="?page={{ contacts.next_page_number }}">»</a></li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -24,7 +24,7 @@
|
||||||
<a href="mailbox.html"><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
|
<a href="mailbox.html"><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
|
||||||
<ul class="nav nav-second-level">
|
<ul class="nav nav-second-level">
|
||||||
<li id="host_add"><a href="/jasset/host_add/">添加资产</a></li>
|
<li id="host_add"><a href="/jasset/host_add/">添加资产</a></li>
|
||||||
<li id="host_list"><a href="/jasset/host_list/">查看资产  <span class="label label-warning">16/18</span></a></li>
|
<li id="host_list"><a href="/jasset/host_list/">查看资产  </span><span class="label label-info pull-right">16/18</span></a></li>
|
||||||
<li id="group_add"><a href="/jasset/group_add/">添加IDC|主机组</a></li>
|
<li id="group_add"><a href="/jasset/group_add/">添加IDC|主机组</a></li>
|
||||||
<li id="group_list"><a href="/jasset/group_list/">查看IDC|主机组</a></li>
|
<li id="group_list"><a href="/jasset/group_list/">查看IDC|主机组</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
<li id="jlog">
|
<li id="jlog">
|
||||||
<a href="#"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="fa arrow"></span></a>
|
<a href="#"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="fa arrow"></span></a>
|
||||||
<ul class="nav nav-second-level">
|
<ul class="nav nav-second-level">
|
||||||
<li id="log_list"><a href="/jlog/">查看日志</a></li>
|
<li id="log_list"><a href="/jlog/log_list/online/">查看日志</a></li>
|
||||||
<li id="log_detail"><a href="/jlog/log_detail/">日志分析</a></li>
|
<li id="log_detail"><a href="/jlog/log_detail/">日志分析</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<h2>{{ header_title }}</h2>
|
<h2>{{ header_title }}</h2>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li>
|
<li>
|
||||||
<a href="/">Home</a>
|
<a href="/">仪表盘</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a>{{ path1 }}</a>
|
<a>{{ path1 }}</a>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var program = require('commander');
|
||||||
|
nodetail = require('../src/node-tail.js');
|
||||||
|
|
||||||
|
var options = {};
|
||||||
|
|
||||||
|
program
|
||||||
|
.usage('[options] file...')
|
||||||
|
.option('-p, --port <port>', 'custom port');
|
||||||
|
|
||||||
|
program.parse(process.argv);
|
||||||
|
|
||||||
|
nodetail.run({
|
||||||
|
port: program.port,
|
||||||
|
file: program.args[0]
|
||||||
|
});
|
Loading…
Reference in New Issue