Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
8f985ade
Commit
8f985ade
authored
Dec 05, 2015
by
wangyong
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' of
https://git.coding.net/jumpserver/jumpserver
into dev
parents
9b7ef113
b5325fd0
Hide whitespace changes
Inline
Side-by-side
Showing
65 changed files
with
734 additions
and
345 deletions
+734
-345
connect.py
connect.py
+98
-167
models.py
jlog/models.py
+23
-2
urls.py
jlog/urls.py
+8
-7
views.py
jlog/views.py
+35
-2
ansible_api.py
jperm/ansible_api.py
+47
-32
models.py
jperm/models.py
+1
-1
perm_api.py
jperm/perm_api.py
+3
-0
views.py
jperm/views.py
+19
-15
api.py
jumpserver/api.py
+1
-1
views.py
jumpserver/views.py
+17
-10
run_websocket.py
run_websocket.py
+40
-20
style.css
static/css/style.css
+3
-1
download.html
templates/download.html
+1
-1
exec_cmd.html
templates/exec_cmd.html
+1
-1
index.html
templates/index.html
+10
-10
index_cu.html
templates/index_cu.html
+3
-3
asset_add.html
templates/jasset/asset_add.html
+1
-1
asset_add_batch.html
templates/jasset/asset_add_batch.html
+1
-1
asset_detail.html
templates/jasset/asset_detail.html
+3
-3
asset_edit.html
templates/jasset/asset_edit.html
+1
-1
asset_edit_batch.html
templates/jasset/asset_edit_batch.html
+1
-1
asset_list.html
templates/jasset/asset_list.html
+2
-2
group_add.html
templates/jasset/group_add.html
+1
-1
group_edit.html
templates/jasset/group_edit.html
+1
-1
group_list.html
templates/jasset/group_list.html
+1
-1
idc_add.html
templates/jasset/idc_add.html
+1
-1
idc_edit.html
templates/jasset/idc_edit.html
+1
-1
idc_list.html
templates/jasset/idc_list.html
+1
-1
exec_detail.html
templates/jlog/exec_detail.html
+127
-0
log_exec.html
templates/jlog/log_exec.html
+107
-0
log_file.html
templates/jlog/log_file.html
+109
-0
log_filter.html
templates/jlog/log_filter.html
+1
-1
log_offline.html
templates/jlog/log_offline.html
+3
-1
log_online.html
templates/jlog/log_online.html
+3
-1
user_history.html
templates/jlog/user_history.html
+1
-1
perm_group_edit.html
templates/jperm/perm_group_edit.html
+1
-1
perm_group_list.html
templates/jperm/perm_group_list.html
+1
-1
perm_log.html
templates/jperm/perm_log.html
+1
-1
perm_role_add.html
templates/jperm/perm_role_add.html
+1
-1
perm_role_detail.html
templates/jperm/perm_role_detail.html
+5
-5
perm_role_edit.html
templates/jperm/perm_role_edit.html
+1
-1
perm_role_list.html
templates/jperm/perm_role_list.html
+1
-1
perm_role_push.html
templates/jperm/perm_role_push.html
+1
-1
perm_rule_add.html
templates/jperm/perm_rule_add.html
+1
-1
perm_rule_detail.html
templates/jperm/perm_rule_detail.html
+3
-3
perm_rule_edit.html
templates/jperm/perm_rule_edit.html
+1
-1
perm_rule_list.html
templates/jperm/perm_rule_list.html
+1
-1
perm_sudo_add.html
templates/jperm/perm_sudo_add.html
+1
-1
perm_sudo_edit.html
templates/jperm/perm_sudo_edit.html
+1
-1
perm_sudo_list.html
templates/jperm/perm_sudo_list.html
+1
-1
sys_user_add.html
templates/jperm/sys_user_add.html
+1
-1
sys_user_list.html
templates/jperm/sys_user_list.html
+1
-1
change_info.html
templates/juser/change_info.html
+1
-1
group_add.html
templates/juser/group_add.html
+1
-1
group_list.html
templates/juser/group_list.html
+1
-1
run_command.html
templates/juser/run_command.html
+1
-1
user_add.html
templates/juser/user_add.html
+1
-1
user_detail.html
templates/juser/user_detail.html
+3
-3
user_edit.html
templates/juser/user_edit.html
+3
-3
user_list.html
templates/juser/user_list.html
+12
-12
log_watch.html
templates/log_watch.html
+1
-1
nav.html
templates/nav.html
+7
-2
nav_cat_bar.html
templates/nav_cat_bar.html
+2
-2
setting.html
templates/setting.html
+1
-1
upload.html
templates/upload.html
+1
-1
No files found.
connect.py
View file @
8f985ade
...
...
@@ -27,9 +27,11 @@ from jumpserver.api import logger, Log, TtyLog, get_role_key, CRYPTOR, bash, get
from
jperm.perm_api
import
gen_resource
,
get_group_asset_perm
,
get_group_user_perm
,
user_have_perm
,
PermRole
from
jumpserver.settings
import
LOG_DIR
from
jperm.ansible_api
import
Command
,
MyRunner
from
jlog.log_api
import
escapeString
# from jlog.log_api import escapeString
from
jlog.models
import
ExecLog
,
FileLog
login_user
=
get_object
(
User
,
username
=
getpass
.
getuser
())
remote_ip
=
os
.
popen
(
"who -m | awk '{ print $5 }'"
)
.
read
()
.
strip
(
'()
\n
'
)
try
:
import
termios
...
...
@@ -227,8 +229,6 @@ class Tty(object):
raise
ServerError
(
'Create
%
s failed, Please modify
%
s permission.'
%
(
today_connect_log_dir
,
tty_log_dir
))
try
:
# log_file_f = copen(log_file_path + '.log', mode='at', encoding='utf-8', errors='replace')
# log_time_f = copen(log_file_path + '.time', mode='at', encoding='utf-8', errors='replace')
log_file_f
=
open
(
log_file_path
+
'.log'
,
'a'
)
log_time_f
=
open
(
log_file_path
+
'.time'
,
'a'
)
except
IOError
:
...
...
@@ -237,13 +237,12 @@ class Tty(object):
if
self
.
login_type
==
'ssh'
:
# 如果是ssh连接过来,记录connect.py的pid,web terminal记录为日志的id
pid
=
os
.
getpid
()
self
.
remote_ip
=
os
.
popen
(
"who -m | awk '{ print $5 }'"
)
.
read
()
.
strip
(
'()
\n
'
)
# 获取远端IP
self
.
remote_ip
=
remote_ip
# 获取远端IP
else
:
pid
=
0
log
=
Log
(
user
=
self
.
username
,
host
=
self
.
asset_name
,
remote_ip
=
self
.
remote_ip
,
login_type
=
self
.
login_type
,
log_path
=
log_file_path
,
start_time
=
date_today
,
pid
=
pid
)
log
.
save
()
if
self
.
login_type
==
'web'
:
log
.
pid
=
log
.
id
...
...
@@ -421,9 +420,6 @@ class SshTty(Tty):
Connect server.
连接服务器
"""
ps1
=
"PS1='[
\
u@
%
s
\
W]
\
$ '
\n
"
%
self
.
ip
login_msg
=
"clear;echo -e '
\\
033[32mLogin
%
s done. Enjoy it.
\\
033[0m'
\n
"
%
self
.
ip
# 发起ssh连接请求 Make a ssh connection
ssh
=
self
.
get_connection
()
...
...
@@ -435,20 +431,6 @@ class SshTty(Tty):
signal
.
signal
(
signal
.
SIGWINCH
,
self
.
set_win_size
)
except
:
pass
# 设置PS1并提示 Set PS1 and msg it
#channel.send(ps1)
#channel.send(login_msg)
# channel.send('echo ${SSH_TTY}\n')
# global SSH_TTY
# while not channel.recv_ready():
# time.sleep(1)
# tmp = channel.recv(1024)
#print 'ok'+tmp+'ok'
# SSH_TTY = re.search(r'(?<=/dev/).*', tmp).group().strip()
# SSH_TTY = ''
# channel.send('clear\n')
# Make ssh interactive tunnel
self
.
posix_shell
()
# Shutdown channel socket
...
...
@@ -468,16 +450,6 @@ class Nav(object):
Print prompt
打印提示导航
"""
msg
=
"""
\n\033
[1;32m### Welcome To Use JumpServer, A Open Source System . ###
\033
[0m
1) Type
\033
[32mID
\033
[0m To Login.
2) Type
\033
[32m/
\033
[0m +
\033
[32mIP, Host Name, Host Alias or Comments
\033
[0mTo Search.
3) Type
\033
[32mP/p
\033
[0m To Print The Servers You Available.
4) Type
\033
[32mG/g
\033
[0m To Print The Server Groups You Available.
5) Type
\033
[32mG/g
\033
[0m
\033
[0m +
\033
[32mGroup ID
\033
[0m To Print The Server Group You Available.
6) Type
\033
[32mE/e
\033
[0m To Execute Command On Several Servers.
7) Type
\033
[32mQ/q
\033
[0m To Quit.
"""
msg
=
"""
\n\033
[1;32m### 欢迎使用Jumpserver开源跳板机 ###
\033
[0m
1) 输入
\033
[32mID
\033
[0m 直接登录.
2) 输入
\033
[32m/
\033
[0m +
\033
[32mIP, 主机名, 主机别名 or 备注
\033
[0m搜索.
...
...
@@ -542,35 +514,6 @@ class Nav(object):
print
'[
%-3
s]
%-15
s'
%
(
asset_group
.
id
,
asset_group
.
name
)
print
def
get_exec_log
(
self
,
assets_name_str
):
exec_log_dir
=
os
.
path
.
join
(
LOG_DIR
,
'exec'
)
date_today
=
datetime
.
datetime
.
now
()
date_start
=
date_today
.
strftime
(
'
%
Y
%
m
%
d'
)
time_start
=
date_today
.
strftime
(
'
%
H
%
M
%
S'
)
today_connect_log_dir
=
os
.
path
.
join
(
exec_log_dir
,
date_start
)
log_file_path
=
os
.
path
.
join
(
today_connect_log_dir
,
'
%
s_
%
s'
%
(
self
.
user
.
username
,
time_start
))
try
:
mkdir
(
os
.
path
.
dirname
(
today_connect_log_dir
),
mode
=
0777
)
mkdir
(
today_connect_log_dir
,
mode
=
0777
)
except
OSError
:
logger
.
debug
(
'创建目录
%
s 失败,请修改
%
s目录权限'
%
(
today_connect_log_dir
,
exec_log_dir
))
raise
ServerError
(
'Create
%
s failed, Please modify
%
s permission.'
%
(
today_connect_log_dir
,
exec_log_dir
))
try
:
log_file_f
=
open
(
log_file_path
+
'.log'
,
'a'
)
log_file_f
.
write
(
'Start at
%
s
\r\n
'
%
datetime
.
datetime
.
now
())
log_time_f
=
open
(
log_file_path
+
'.time'
,
'a'
)
except
IOError
:
logger
.
debug
(
'创建tty日志文件失败, 请修改目录
%
s权限'
%
today_connect_log_dir
)
raise
ServerError
(
'Create logfile failed, Please modify
%
s permission.'
%
today_connect_log_dir
)
remote_ip
=
os
.
popen
(
"who -m | awk '{ print $5 }'"
)
.
read
()
.
strip
(
'()
\n
'
)
log
=
Log
(
user
=
self
.
user
.
username
,
host
=
assets_name_str
,
remote_ip
=
remote_ip
,
login_type
=
'exec'
,
log_path
=
log_file_path
,
start_time
=
datetime
.
datetime
.
now
(),
pid
=
os
.
getpid
())
log
.
save
()
return
log_file_f
,
log_time_f
,
log
def
exec_cmd
(
self
):
"""
批量执行命令
...
...
@@ -578,104 +521,75 @@ class Nav(object):
while
True
:
if
not
self
.
user_perm
:
self
.
user_perm
=
get_group_user_perm
(
self
.
user
)
print
'
\033
[32m[
%-2
s]
%-15
s
\033
[0m'
%
(
'ID'
,
'角色'
)
roles
=
self
.
user_perm
.
get
(
'role'
)
.
keys
()
role_check
=
dict
(
zip
(
range
(
len
(
roles
)),
roles
))
if
len
(
roles
)
>
1
:
# 授权角色数大于1
print
'
\033
[32m[
%-2
s]
%-15
s
\033
[0m'
%
(
'ID'
,
'角色'
)
role_check
=
dict
(
zip
(
range
(
len
(
roles
)),
roles
))
for
i
,
r
in
role_check
.
items
():
print
'[
%-2
s]
%-15
s'
%
(
i
,
r
.
name
)
print
print
"请输入运行命令角色的ID, q退出"
for
i
,
r
in
role_check
.
items
():
print
'[
%-2
s]
%-15
s'
%
(
i
,
r
.
name
)
print
print
"请输入运行命令角色的ID, q退出"
try
:
role_id
=
raw_input
(
"
\033
[1;32mRole>:
\033
[0m "
)
.
strip
()
if
role_id
==
'q'
:
break
try
:
role_id
=
raw_input
(
"
\033
[1;32mRole>:
\033
[0m "
)
.
strip
()
if
role_id
==
'q'
:
break
except
(
IndexError
,
ValueError
):
color_print
(
'错误输入'
)
else
:
role
=
role_check
[
int
(
role_id
)]
assets
=
list
(
self
.
user_perm
.
get
(
'role'
,
{})
.
get
(
role
)
.
get
(
'asset'
))
print
"该角色有权限的所有主机"
for
asset
in
assets
:
print
asset
.
hostname
print
print
"请输入主机名、IP或ansile支持的pattern, q退出"
pattern
=
raw_input
(
"
\033
[1;32mPattern>:
\033
[0m "
)
.
strip
()
if
pattern
==
'q'
:
break
else
:
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
,
'role'
:
role
},
perm
=
self
.
user_perm
)
cmd
=
Command
(
res
)
logger
.
debug
(
"批量执行res:
%
s"
%
res
)
asset_name_str
=
''
for
inv
in
cmd
.
inventory
.
get_hosts
(
pattern
=
pattern
):
print
inv
.
name
asset_name_str
+=
inv
.
name
print
elif
len
(
roles
)
==
1
:
# 授权角色数为1
role
=
roles
[
0
]
assets
=
list
(
self
.
user_perm
.
get
(
'role'
,
{})
.
get
(
role
)
.
get
(
'asset'
))
# 获取该用户,角色授权主机
print
"该角色有权限的所有主机"
for
asset
in
assets
:
print
'
%
s'
%
asset
.
hostname
print
print
"请输入主机名、IP或ansile支持的pattern, q退出"
pattern
=
raw_input
(
"
\033
[1;32mPattern>:
\033
[0m "
)
.
strip
()
if
pattern
==
'q'
:
break
else
:
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
,
'role'
:
role
},
perm
=
self
.
user_perm
)
runner
=
MyRunner
(
res
)
logger
.
debug
(
"批量执行res:
%
s"
%
res
)
asset_name_str
=
''
print
"匹配主机:"
for
inv
in
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
print
'
%
s'
%
inv
.
name
asset_name_str
+=
'
%
s '
%
inv
.
name
print
log_file_f
,
log_time_f
,
log
=
self
.
get_exec_log
(
asset_name_str
)
pre_timestamp
=
time
.
time
()
while
True
:
print
"请输入执行的命令, 按q退出"
data
=
'ansible> '
write_log
(
log_file_f
,
data
)
now_timestamp
=
time
.
time
()
write_log
(
log_time_f
,
'
%
s
%
s
\n
'
%
(
round
(
now_timestamp
-
pre_timestamp
,
4
),
len
(
data
)))
pre_timestamp
=
now_timestamp
command
=
raw_input
(
"
\033
[1;32mCmds>:
\033
[0m "
)
.
strip
()
data
=
'
%
s
\r\n
'
%
command
write_log
(
log_file_f
,
data
)
now_timestamp
=
time
.
time
()
write_log
(
log_time_f
,
'
%
s
%
s
\n
'
%
(
round
(
now_timestamp
-
pre_timestamp
,
4
),
len
(
data
)))
pre_timestamp
=
now_timestamp
TtyLog
(
log
=
log
,
cmd
=
command
,
datetime
=
datetime
.
datetime
.
now
())
.
save
()
if
command
==
'q'
:
log
.
is_finished
=
True
log
.
end_time
=
datetime
.
datetime
.
now
()
log
.
save
()
break
result
=
cmd
.
run
(
module_name
=
'shell'
,
command
=
command
,
pattern
=
pattern
)
for
k
,
v
in
result
.
items
():
if
k
==
'ok'
:
for
host
,
output
in
v
.
items
():
header
=
color_print
(
"
%
s =>
%
s"
%
(
host
,
'Ok'
),
'green'
)
print
output
output
=
re
.
sub
(
r'[\r\n]'
,
'
\r\n
'
,
output
)
data
=
'
%
s
\r\n
%
s
\r\n
'
%
(
header
,
output
)
now_timestamp
=
time
.
time
()
write_log
(
log_file_f
,
data
)
write_log
(
log_time_f
,
'
%
s
%
s
\n
'
%
(
round
(
now_timestamp
-
pre_timestamp
,
4
),
len
(
data
)))
pre_timestamp
=
now_timestamp
print
else
:
for
host
,
output
in
v
.
items
():
header
=
color_print
(
"
%
s =>
%
s"
%
(
host
,
k
),
'red'
)
output
=
color_print
(
output
,
'red'
)
output
=
re
.
sub
(
r'[\r\n]'
,
'
\r\n
'
,
output
)
data
=
'
%
s
\r\n
%
s
\r\n
'
%
(
header
,
output
)
now_timestamp
=
time
.
time
()
write_log
(
log_file_f
,
data
)
write_log
(
log_time_f
,
'
%
s
%
s
\n
'
%
(
round
(
now_timestamp
-
pre_timestamp
,
4
),
len
(
data
)))
pre_timestamp
=
now_timestamp
print
print
"="
*
20
while
True
:
print
"请输入执行的命令, 按q退出"
command
=
raw_input
(
"
\033
[1;32mCmds>:
\033
[0m "
)
.
strip
()
if
command
==
'q'
:
break
runner
.
run
(
'shell'
,
command
,
pattern
=
pattern
)
ExecLog
(
host
=
asset_name_str
,
user
=
self
.
user
.
username
,
cmd
=
command
,
remote_ip
=
remote_ip
,
result
=
runner
.
results
)
.
save
()
for
k
,
v
in
runner
.
results
.
items
():
if
k
==
'ok'
:
for
host
,
output
in
v
.
items
():
color_print
(
"
%
s =>
%
s"
%
(
host
,
'Ok'
),
'green'
)
print
output
print
except
(
IndexError
,
KeyError
):
color_print
(
'ID输入错误'
)
continue
except
EOFError
:
print
break
finally
:
log
.
is_finished
=
True
log
.
end_time
=
datetime
.
datetime
.
now
()
else
:
for
host
,
output
in
v
.
items
():
color_print
(
"
%
s =>
%
s"
%
(
host
,
k
),
'red'
)
color_print
(
output
,
'red'
)
print
print
"~o~ Task finished ~o~"
print
def
upload
(
self
):
while
True
:
if
not
self
.
user_perm
:
self
.
user_perm
=
get_group_user_perm
(
self
.
user
)
try
:
print
"进入批量上传模式"
print
"请输入主机名、IP或ansile支持的pattern, q退出"
pattern
=
raw_input
(
"
\033
[1;32mPattern>:
\033
[0m "
)
.
strip
()
if
pattern
==
'q'
:
...
...
@@ -684,33 +598,39 @@ class Nav(object):
assets
=
self
.
user_perm
.
get
(
'asset'
)
.
keys
()
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
},
perm
=
self
.
user_perm
)
runner
=
MyRunner
(
res
)
logger
.
debug
(
"Muti upload file res:
%
s"
%
res
)
asset_name_str
=
''
print
"匹配主机:
\n
"
for
inv
in
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
print
inv
.
name
asset_name_str
+=
inv
.
name
print
asset_name_str
+=
'
%
s '
%
inv
.
name
if
not
asset_name_str
:
color_print
(
'没有匹配主机'
)
continue
tmp_dir
=
get_tmp_dir
()
logger
.
debug
(
'Upload tmp dir:
%
s'
%
tmp_dir
)
os
.
chdir
(
tmp_dir
)
bash
(
'rz'
)
check_notempty
=
os
.
listdir
(
tmp_dir
)
if
not
check_notempty
:
print
color_print
(
"上传文件为空"
)
filename_str
=
' '
.
join
(
os
.
listdir
(
tmp_dir
)
)
if
not
filename_str
:
color_print
(
"上传文件为空"
)
continue
logger
.
debug
(
'上传文件:
%
s'
%
filename_str
)
runner
=
MyRunner
(
res
)
runner
.
run
(
'copy'
,
module_args
=
'src=
%
s dest=
%
s directory_mode'
%
(
tmp_dir
,
tmp_dir
),
pattern
=
pattern
)
ret
=
runner
.
get_result
()
logger
.
debug
(
ret
)
ret
=
runner
.
results
FileLog
(
user
=
self
.
user
.
name
,
host
=
asset_name_str
,
filename
=
filename_str
,
remote_ip
=
remote_ip
,
type
=
'upload'
,
result
=
ret
)
.
save
()
logger
.
debug
(
'Upload file:
%
s'
%
ret
)
if
ret
.
get
(
'failed'
):
print
ret
error
=
'上传目录:
%
s
\n
上传失败: [
%
s ]
\n
上传成功 [
%
s ]'
%
(
tmp_dir
,
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'ok'
)))
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()
))
color_print
(
error
)
else
:
msg
=
'上传目录:
%
s
\n
传送成功 [
%
s ]'
%
(
tmp_dir
,
', '
.
join
(
ret
.
get
(
'ok'
)))
msg
=
'上传目录:
%
s
\n
传送成功 [
%
s ]'
%
(
tmp_dir
,
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()
))
color_print
(
msg
,
'green'
)
print
...
...
@@ -731,30 +651,41 @@ class Nav(object):
assets
=
self
.
user_perm
.
get
(
'asset'
)
.
keys
()
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
},
perm
=
self
.
user_perm
)
runner
=
MyRunner
(
res
)
logger
.
debug
(
"Muti Muti file res:
%
s"
%
res
)
logger
.
debug
(
"Muti download file res:
%
s"
%
res
)
asset_name_str
=
''
print
"匹配用户:
\n
"
for
inv
in
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
print
inv
.
name
asset_name_str
+=
'
%
s '
%
inv
.
name
print
'
%
s'
%
inv
.
name
if
not
asset_name_str
:
color_print
(
'没有匹配主机'
)
continue
print
tmp_dir
=
get_tmp_dir
()
logger
.
debug
(
'Download tmp dir:
%
s'
%
tmp_dir
)
while
True
:
tmp_dir
=
get_tmp_dir
()
logger
.
debug
(
'Download tmp dir:
%
s'
%
tmp_dir
)
print
"请输入文件路径(不支持目录)"
file_path
=
raw_input
(
"
\033
[1;32mPath>:
\033
[0m "
)
.
strip
()
if
file_path
==
'q'
:
break
runner
.
run
(
'fetch'
,
module_args
=
'src=
%
s dest=
%
s'
%
(
file_path
,
tmp_dir
),
pattern
=
pattern
)
ret
=
runner
.
get_result
()
ret
=
runner
.
results
FileLog
(
user
=
self
.
user
.
name
,
host
=
asset_name_str
,
filename
=
file_path
,
type
=
'download'
,
remote_ip
=
remote_ip
,
result
=
ret
)
.
save
()
logger
.
debug
(
'Download file result:
%
s'
%
ret
)
os
.
chdir
(
'/tmp'
)
tmp_dir_name
=
os
.
path
.
basename
(
tmp_dir
)
bash
(
'tar czf
%
s.tar.gz
%
s '
%
(
tmp_dir
,
tmp_dir_name
))
if
not
os
.
listdir
(
tmp_dir
):
color_print
(
'下载全部失败'
)
continue
bash
(
'tar czf
%
s.tar.gz
%
s && sz
%
s.tar.gz'
%
(
tmp_dir
,
tmp_dir_name
,
tmp_dir
))
if
ret
.
get
(
'failed'
):
print
ret
error
=
'文件名称:
%
s 下载失败: [
%
s ]
\n
下载成功 [
%
s ]'
%
\
(
'
%
s.tar.gz'
%
tmp_dir_name
,
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'ok'
)))
error
=
'文件名称:
%
s
\n
下载失败: [
%
s ]
\n
下载成功 [
%
s ]'
%
\
(
'
%
s.tar.gz'
%
tmp_dir_name
,
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()))
color_print
(
error
)
else
:
msg
=
'文件名称:
%
s
下载成功 [
%
s ]'
%
(
'
%
s.tar.gz'
%
tmp_dir_name
,
', '
.
join
(
ret
.
get
(
'ok'
)))
msg
=
'文件名称:
%
s
\n
下载成功 [
%
s ]'
%
(
'
%
s.tar.gz'
%
tmp_dir_name
,
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
(
)))
color_print
(
msg
,
'green'
)
print
except
IndexError
:
...
...
jlog/models.py
View file @
8f985ade
...
...
@@ -3,7 +3,7 @@ from django.db import models
class
Log
(
models
.
Model
):
user
=
models
.
CharField
(
max_length
=
20
,
null
=
True
)
host
=
models
.
CharField
(
max_length
=
20
,
null
=
True
)
host
=
models
.
CharField
(
max_length
=
20
0
,
null
=
True
)
remote_ip
=
models
.
CharField
(
max_length
=
100
)
login_type
=
models
.
CharField
(
max_length
=
100
)
log_path
=
models
.
CharField
(
max_length
=
100
)
...
...
@@ -24,5 +24,26 @@ class Alert(models.Model):
class
TtyLog
(
models
.
Model
):
log
=
models
.
ForeignKey
(
Log
)
datetime
=
models
.
DateTimeField
()
datetime
=
models
.
DateTimeField
(
auto_now
=
True
)
cmd
=
models
.
CharField
(
max_length
=
200
)
class
ExecLog
(
models
.
Model
):
user
=
models
.
CharField
(
max_length
=
100
)
host
=
models
.
TextField
()
cmd
=
models
.
TextField
()
remote_ip
=
models
.
CharField
(
max_length
=
100
)
result
=
models
.
TextField
(
default
=
''
)
datetime
=
models
.
DateTimeField
(
auto_now
=
True
)
class
FileLog
(
models
.
Model
):
user
=
models
.
CharField
(
max_length
=
100
)
host
=
models
.
TextField
()
filename
=
models
.
TextField
()
type
=
models
.
CharField
(
max_length
=
20
)
remote_ip
=
models
.
CharField
(
max_length
=
100
)
result
=
models
.
TextField
(
default
=
''
)
datetime
=
models
.
DateTimeField
(
auto_now
=
True
)
jlog/urls.py
View file @
8f985ade
...
...
@@ -3,11 +3,11 @@ from django.conf.urls import patterns, include, url
from
jlog.views
import
*
urlpatterns
=
patterns
(
''
,
url
(
r'^$'
,
log_list
),
url
(
r'^log_list/(\w+)/$'
,
log_list
),
url
(
r'^history/$'
,
log_history
),
url
(
r'^log_kill/'
,
log_kill
),
url
(
r'^record/$'
,
log_record
),
url
(
r'^web_terminal/$'
,
web_terminal
),
(
r'^$'
,
log_list
),
(
r'^log_list/(\w+)/$'
,
log_list
),
(
r'^log_detail/(\w+)/$'
,
log_detail
),
(
r'^history/$'
,
log_history
),
(
r'^log_kill/'
,
log_kill
),
(
r'^record/$'
,
log_record
),
(
r'^web_terminal/$'
,
web_terminal
),
)
\ No newline at end of file
jlog/views.py
View file @
8f985ade
...
...
@@ -8,7 +8,7 @@ from jperm.perm_api import user_have_perm
from
django.http
import
HttpResponseNotFound
from
jlog.log_api
import
renderTemplate
from
models
import
Log
from
jlog.models
import
Log
,
ExecLog
,
File
Log
from
jumpserver.settings
import
WEB_SOCKET_HOST
...
...
@@ -21,9 +21,19 @@ def log_list(request, offset):
username_list
=
request
.
GET
.
getlist
(
'username'
,
[])
host_list
=
request
.
GET
.
getlist
(
'host'
,
[])
cmd
=
request
.
GET
.
get
(
'cmd'
,
''
)
print
date_seven_day
,
date_now_str
if
offset
==
'online'
:
posts
=
Log
.
objects
.
filter
(
is_finished
=
False
)
.
order_by
(
'-start_time'
)
elif
offset
==
'exec'
:
posts
=
ExecLog
.
objects
.
all
()
.
order_by
(
'-id'
)
keyword
=
request
.
GET
.
get
(
'keyword'
,
''
)
if
keyword
:
posts
=
posts
.
filter
(
Q
(
user__icontains
=
keyword
)
|
Q
(
host__icontains
=
keyword
)
|
Q
(
cmd__icontains
=
keyword
))
elif
offset
==
'file'
:
posts
=
FileLog
.
objects
.
all
()
.
order_by
(
'-id'
)
keyword
=
request
.
GET
.
get
(
'keyword'
,
''
)
if
keyword
:
posts
=
posts
.
filter
(
Q
(
user__icontains
=
keyword
)
|
Q
(
host__icontains
=
keyword
)
|
Q
(
filename__icontains
=
keyword
))
else
:
posts
=
Log
.
objects
.
filter
(
is_finished
=
True
)
.
order_by
(
'-start_time'
)
username_all
=
set
([
log
.
user
for
log
in
Log
.
objects
.
all
()])
...
...
@@ -57,6 +67,11 @@ def log_list(request, offset):
return
render_to_response
(
'jlog/log_
%
s.html'
%
offset
,
locals
(),
context_instance
=
RequestContext
(
request
))
@require_role
(
'admin'
)
def
log_detail
(
request
):
return
my_render
(
'jlog/exec_detail.html'
,
locals
(),
request
)
@require_role
(
'admin'
)
def
log_kill
(
request
):
""" 杀掉connect进程 """
...
...
@@ -114,3 +129,21 @@ def web_terminal(request):
web_terminal_uri
=
'ws://
%
s/terminal?id=
%
s&role=
%
s'
%
(
WEB_SOCKET_HOST
,
asset_id
,
role_name
)
return
render_to_response
(
'jlog/web_terminal.html'
,
locals
())
@require_role
(
'admin'
)
def
log_detail
(
request
,
offset
):
log_id
=
request
.
GET
.
get
(
'id'
)
if
offset
==
'exec'
:
log
=
get_object
(
ExecLog
,
id
=
log_id
)
assets_hostname
=
log
.
host
.
split
(
' '
)
result
=
eval
(
str
(
log
.
result
))
return
my_render
(
'jlog/exec_detail.html'
,
locals
(),
request
)
elif
offset
==
'file'
:
log
=
get_object
(
FileLog
,
id
=
log_id
)
assets_hostname
=
log
.
host
.
split
(
' '
)
file_list
=
log
.
filename
.
split
(
' '
)
try
:
result
=
eval
(
str
(
log
.
result
))
except
(
SyntaxError
,
NameError
):
result
=
{}
return
my_render
(
'jlog/file_detail.html'
,
locals
(),
request
)
jperm/ansible_api.py
View file @
8f985ade
...
...
@@ -117,9 +117,9 @@ class MyRunner(MyInventory):
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
MyRunner
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
results
=
{}
self
.
results
_raw
=
{}
def
run
(
self
,
module_name
,
module_args
=
''
,
timeout
=
10
,
forks
=
10
,
pattern
=
''
,
def
run
(
self
,
module_name
=
'shell'
,
module_args
=
''
,
timeout
=
10
,
forks
=
10
,
pattern
=
''
,
sudo
=
False
,
sudo_user
=
'root'
,
sudo_pass
=
''
):
"""
run module from andible ad-hoc.
...
...
@@ -137,23 +137,29 @@ class MyRunner(MyInventory):
become_user
=
sudo_user
,
become_pass
=
sudo_pass
)
self
.
results
=
hoc
.
run
()
return
self
.
results
self
.
results
_raw
=
hoc
.
run
()
return
self
.
results
_raw
def
get_result
(
self
):
result
=
{
'failed'
:
{},
'ok'
:
[]}
dark
=
self
.
results
.
get
(
'dark'
)
contacted
=
self
.
results
.
get
(
'contacted'
)
@property
def
results
(
self
):
"""
{'failed': {'localhost': ''}, 'ok': {'jumpserver': ''}}
"""
result
=
{
'failed'
:
{},
'ok'
:
{}}
dark
=
self
.
results_raw
.
get
(
'dark'
)
contacted
=
self
.
results_raw
.
get
(
'contacted'
)
if
dark
:
for
host
,
info
in
dark
.
items
():
result
[
'failed'
][
host
]
=
info
.
get
(
'msg'
)
if
contacted
:
for
host
,
info
in
contacted
.
items
():
if
info
.
get
(
'msg'
):
result
[
'failed'
][
host
]
=
info
.
get
(
'msg'
)
if
info
.
get
(
'failed'
):
result
[
'failed'
][
host
]
=
info
.
get
(
'msg'
)
+
info
.
get
(
'stderr'
,
''
)
elif
info
.
get
(
'stderr'
):
result
[
'failed'
][
host
]
=
info
.
get
(
'stderr'
)
+
str
(
info
.
get
(
'warnings'
))
else
:
result
[
'ok'
]
.
append
(
host
)
result
[
'ok'
]
[
host
]
=
info
.
get
(
'stdout'
)
return
result
...
...
@@ -163,9 +169,9 @@ class Command(MyInventory):
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Command
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
results
=
{}
self
.
results
_raw
=
{}
def
run
(
self
,
command
,
module_name
=
"command"
,
timeout
=
10
,
forks
=
10
,
pattern
=
'
*
'
):
def
run
(
self
,
command
,
module_name
=
"command"
,
timeout
=
10
,
forks
=
10
,
pattern
=
''
):
"""
run command from andible ad-hoc.
command : 必须是一个需要执行的命令字符串, 比如
...
...
@@ -183,25 +189,34 @@ class Command(MyInventory):
pattern
=
pattern
,
forks
=
forks
,
)
self
.
results
=
hoc
.
run
()
self
.
results
_raw
=
hoc
.
run
()
ret
=
{}
@property
def
result
(
self
):
result
=
{}
for
k
,
v
in
self
.
results_raw
.
items
():
if
k
==
'dark'
:
for
host
,
info
in
v
.
items
():
result
[
host
]
=
{
'dark'
:
info
.
get
(
'msg'
)}
elif
k
==
'contacted'
:
for
host
,
info
in
v
.
items
():
result
[
host
]
=
{}
if
info
.
get
(
'stdout'
):
result
[
host
][
'stdout'
]
=
info
.
get
(
'stdout'
)
elif
info
.
get
(
'stderr'
):
result
[
host
][
'stderr'
]
=
info
.
get
(
'stderr'
)
return
result
@property
def
state
(
self
):
result
=
{}
if
self
.
stdout
:
data
[
'ok'
]
=
self
.
stdout
result
[
'ok'
]
=
self
.
stdout
if
self
.
stderr
:
data
[
'err'
]
=
self
.
stderr
result
[
'err'
]
=
self
.
stderr
if
self
.
dark
:
data
[
'dark'
]
=
self
.
dark
return
data
@property
def
raw_results
(
self
):
"""
get the ansible raw results.
"""
return
self
.
results
result
[
'dark'
]
=
self
.
dark
return
result
@property
def
exec_time
(
self
):
...
...
@@ -209,7 +224,7 @@ class Command(MyInventory):
get the command execute time.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
all
=
self
.
results
_raw
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
{
"start"
:
value
.
get
(
"start"
),
...
...
@@ -223,7 +238,7 @@ class Command(MyInventory):
get the comamnd standard output.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
all
=
self
.
results
_raw
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
value
.
get
(
"stdout"
)
return
result
...
...
@@ -234,7 +249,7 @@ class Command(MyInventory):
get the command standard error.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
all
=
self
.
results
_raw
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
if
value
.
get
(
"stderr"
)
or
value
.
get
(
"warnings"
):
result
[
key
]
=
{
...
...
@@ -247,7 +262,7 @@ class Command(MyInventory):
"""
get the dark results.
"""
return
self
.
results
.
get
(
"dark"
)
return
self
.
results
_raw
.
get
(
"dark"
)
class
Tasks
(
Command
):
...
...
jperm/models.py
View file @
8f985ade
...
...
@@ -55,6 +55,6 @@ class PermPush(models.Model):
is_public_key
=
models
.
BooleanField
(
default
=
False
)
is_password
=
models
.
BooleanField
(
default
=
False
)
success
=
models
.
BooleanField
(
default
=
False
)
result
=
models
.
TextField
()
result
=
models
.
TextField
(
default
=
''
)
date_added
=
models
.
DateTimeField
(
auto_now
=
True
)
jperm/perm_api.py
View file @
8f985ade
...
...
@@ -217,6 +217,7 @@ def gen_resource(ob, perm=None):
for
asset
in
ob
:
info
=
get_asset_info
(
asset
)
res
.
append
(
info
)
logger
.
debug
(
'生成res:
%
s'
%
res
)
return
res
...
...
@@ -295,9 +296,11 @@ def get_role_push_host(role):
asset_all
=
Asset
.
objects
.
all
()
asset_pushed
=
{}
for
push
in
pushs
:
print
push
.
result
asset_pushed
[
push
.
asset
]
=
{
'success'
:
push
.
success
,
'key'
:
push
.
is_public_key
,
'password'
:
push
.
is_password
,
'result'
:
push
.
result
}
asset_no_push
=
set
(
asset_all
)
-
set
(
asset_pushed
.
keys
())
print
asset_no_push
,
asset_pushed
return
asset_pushed
,
asset_no_push
...
...
jperm/views.py
View file @
8f985ade
...
...
@@ -78,11 +78,11 @@ def perm_rule_add(request):
if
request
.
method
==
'POST'
:
# 获取用户选择的 用户,用户组,资产,资产组,用户角色
users_select
=
request
.
POST
.
getlist
(
'user'
,
[])
user_groups_select
=
request
.
POST
.
getlist
(
'usergroup'
,
[])
assets_select
=
request
.
POST
.
getlist
(
'asset'
,
[])
asset_groups_select
=
request
.
POST
.
getlist
(
'assetgroup'
,
[])
roles_select
=
request
.
POST
.
getlist
(
'role'
,
[])
users_select
=
request
.
POST
.
getlist
(
'user'
,
[])
# 需要授权用户
user_groups_select
=
request
.
POST
.
getlist
(
'usergroup'
,
[])
# 需要授权用户组
assets_select
=
request
.
POST
.
getlist
(
'asset'
,
[])
# 需要授权资产
asset_groups_select
=
request
.
POST
.
getlist
(
'assetgroup'
,
[])
# 需要授权资产组
roles_select
=
request
.
POST
.
getlist
(
'role'
,
[])
# 需要授权角色
rule_name
=
request
.
POST
.
get
(
'rulename'
)
rule_comment
=
request
.
POST
.
get
(
'rule_comment'
)
...
...
@@ -94,8 +94,10 @@ def perm_rule_add(request):
# 获取需要授权的主机列表
assets_obj
=
[
Asset
.
objects
.
get
(
id
=
asset_id
)
for
asset_id
in
assets_select
]
asset_groups_obj
=
[
AssetGroup
.
objects
.
get
(
id
=
group_id
)
for
group_id
in
asset_groups_select
]
group_assets_obj
=
[
asset
for
asset
in
[
group
.
asset_set
.
all
()
for
group
in
asset_groups_obj
]]
calc_assets
=
set
(
group_assets_obj
)
|
set
(
assets_obj
)
group_assets_obj
=
[]
for
asset_group
in
asset_groups_obj
:
group_assets_obj
.
extend
(
list
(
asset_group
.
asset_set
.
all
()))
calc_assets
=
set
(
group_assets_obj
)
|
set
(
assets_obj
)
# 授权资产和资产组包含的资产
# 获取需要授权的用户列表
users_obj
=
[
User
.
objects
.
get
(
id
=
user_id
)
for
user_id
in
users_select
]
...
...
@@ -106,8 +108,9 @@ def perm_rule_add(request):
# 获取授予的角色列表
roles_obj
=
[
PermRole
.
objects
.
get
(
id
=
role_id
)
for
role_id
in
roles_select
]
need_push_asset
=
set
()
for
role
in
roles_obj
:
asset_no_push
=
get_role_push_host
(
role
=
role
)[
1
]
asset_no_push
=
get_role_push_host
(
role
=
role
)[
0
]
# 获取某角色已经推送的资产
need_push_asset
.
update
(
set
(
calc_assets
)
-
set
(
asset_no_push
))
if
need_push_asset
:
raise
ServerError
(
u'没有推送角色
%
s 的主机
%
s'
...
...
@@ -444,13 +447,14 @@ def perm_role_push(request):
if
password_push
or
key_push
:
role_chosen_aliase
=
{}
# {'dev': 'NETWORKING, SHUTDOWN'}
sudo_alias
=
set
([
sudo
for
sudo
in
role
.
sudo
.
all
()])
# set(sudo1, sudo2, sudo3)
role_chosen_aliase
[
role
.
name
]
=
','
.
join
(
sudo
.
name
for
sudo
in
sudo_alias
)
add_sudo_script
=
get_add_sudo_script
(
role_chosen_aliase
,
sudo_alias
)
ret
[
'sudo'
]
=
task
.
push_sudo_file
(
add_sudo_script
)
if
ret
[
'sudo'
]
.
get
(
'msg'
):
ret_failed
=
ret
[
'sudo'
]
.
get
(
'msg'
)
# os.remove(add_sudo_script)
if
sudo_alias
:
role_chosen_aliase
[
role
.
name
]
=
','
.
join
(
sudo
.
name
for
sudo
in
sudo_alias
if
sudo
.
name
)
add_sudo_script
=
get_add_sudo_script
(
role_chosen_aliase
,
sudo_alias
)
ret
[
'sudo'
]
=
task
.
push_sudo_file
(
add_sudo_script
)
if
ret
[
'sudo'
]
.
get
(
'msg'
):
ret_failed
=
ret
[
'sudo'
]
.
get
(
'msg'
)
os
.
remove
(
add_sudo_script
)
logger
.
debug
(
'推送role结果:
%
s'
%
ret
)
logger
.
debug
(
'推送role错误:
%
s'
%
ret_failed
)
...
...
jumpserver/api.py
View file @
8f985ade
...
...
@@ -96,7 +96,7 @@ def get_role_key(user, role):
with
open
(
os
.
path
.
join
(
role
.
key_path
,
'id_rsa'
))
as
fk
:
with
open
(
user_role_key_path
,
'w'
)
as
fu
:
fu
.
write
(
fk
.
read
())
logger
.
debug
(
"创建新的用户角色key
%
s"
%
user_role_key_path
)
logger
.
debug
(
u
"创建新的用户角色key
%
s"
%
user_role_key_path
)
chown
(
user_role_key_path
,
user
.
username
)
os
.
chmod
(
user_role_key_path
,
0600
)
return
user_role_key_path
...
...
jumpserver/views.py
View file @
8f985ade
...
...
@@ -15,7 +15,7 @@ from jumpserver.api import *
from
jumpserver.models
import
Setting
from
django.contrib.auth
import
authenticate
,
login
,
logout
from
django.contrib.auth.decorators
import
login_required
from
jlog.models
import
Log
from
jlog.models
import
Log
,
FileLog
from
jperm.perm_api
import
get_group_user_perm
,
gen_resource
from
jasset.models
import
Asset
,
IDC
from
jperm.ansible_api
import
MyRunner
...
...
@@ -287,14 +287,14 @@ def setting(request):
def
upload
(
request
):
user
=
request
.
user
assets
=
get_group_user_perm
(
user
)
.
get
(
'asset'
)
.
keys
()
asset_select
=
[]
if
request
.
method
==
'POST'
:
remote_ip
=
request
.
META
.
get
(
'REMOTE_ADDR'
)
asset_ids
=
request
.
POST
.
getlist
(
'asset_ids'
,
''
)
upload_files
=
request
.
FILES
.
getlist
(
'file[]'
,
None
)
date_now
=
datetime
.
datetime
.
now
()
.
strftime
(
"
%
Y
%
m
%
d
%
H
%
M
%
S"
)
upload_dir
=
get_tmp_dir
()
filenames
=
{}
# file_dict
= {}
for
asset_id
in
asset_ids
:
asset_select
.
append
(
get_object
(
Asset
,
id
=
asset_id
))
...
...
@@ -302,9 +302,10 @@ def upload(request):
illegal_asset
=
set
(
asset_select
)
.
issubset
(
set
(
assets
))
return
HttpResponse
(
'没有权限的服务器
%
s'
%
','
.
join
([
asset
.
hostname
for
asset
in
illegal_asset
]))
for
upload_file
in
upload_files
:
file_path
=
'
%
s/
%
s'
%
(
upload_dir
,
upload_file
.
name
)
filenames
[
upload_file
.
name
]
=
file_path
with
open
(
file_path
,
'w'
)
as
f
:
for
chunk
in
upload_file
.
chunks
():
f
.
write
(
chunk
)
...
...
@@ -313,14 +314,17 @@ def upload(request):
runner
=
MyRunner
(
res
)
runner
.
run
(
'copy'
,
module_args
=
'src=
%
s dest=
%
s directory_mode'
%
(
upload_dir
,
upload_dir
),
pattern
=
'*'
)
ret
=
runner
.
get_result
()
ret
=
runner
.
results
logger
.
debug
(
ret
)
FileLog
(
user
=
request
.
user
.
username
,
host
=
' '
.
join
([
asset
.
hostname
for
asset
in
asset_select
]),
filename
=
' '
.
join
([
f
.
name
for
f
in
upload_files
]),
type
=
'upload'
,
remote_ip
=
remote_ip
,
result
=
ret
)
.
save
()
if
ret
.
get
(
'failed'
):
error
=
'上传目录:
%
s <br> 上传失败: [
%
s ] <br>上传成功 [
%
s ]'
%
(
upload_dir
,
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'ok'
)))
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()
))
return
HttpResponse
(
error
,
status
=
500
)
msg
=
'上传目录:
%
s <br> 传送成功 [
%
s ]'
%
(
upload_dir
,
', '
.
join
(
ret
.
get
(
'ok'
)))
msg
=
'上传目录:
%
s <br> 传送成功 [
%
s ]'
%
(
upload_dir
,
', '
.
join
(
ret
.
get
(
'ok'
))
.
keys
()
)
return
HttpResponse
(
msg
)
return
my_render
(
'upload.html'
,
locals
(),
request
)
...
...
@@ -329,9 +333,9 @@ def upload(request):
def
download
(
request
):
user
=
request
.
user
assets
=
get_group_user_perm
(
user
)
.
get
(
'asset'
)
.
keys
()
asset_select
=
[]
if
request
.
method
==
'POST'
:
remote_ip
=
request
.
META
.
get
(
'REMOTE_ADDR'
)
asset_ids
=
request
.
POST
.
getlist
(
'asset_ids'
,
''
)
file_path
=
request
.
POST
.
get
(
'file_path'
)
date_now
=
datetime
.
datetime
.
now
()
.
strftime
(
"
%
Y
%
m
%
d
%
H
%
M
%
S"
)
...
...
@@ -342,14 +346,17 @@ def download(request):
if
not
set
(
asset_select
)
.
issubset
(
set
(
assets
)):
illegal_asset
=
set
(
asset_select
)
.
issubset
(
set
(
assets
))
return
HttpResponse
(
'没有权限的服务器
%
s'
%
','
.
join
([
asset
.
hostname
for
asset
in
illegal_asset
]))
res
=
gen_resource
({
'user'
:
user
,
'asset'
:
asset_select
})
runner
=
MyRunner
(
res
)
runner
.
run
(
'fetch'
,
module_args
=
'src=
%
s dest=
%
s'
%
(
file_path
,
upload_dir
),
pattern
=
'*'
)
logger
.
debug
(
runner
.
get_result
())
FileLog
(
user
=
request
.
user
.
username
,
host
=
' '
.
join
([
asset
.
hostname
for
asset
in
asset_select
]),
filename
=
file_path
,
type
=
'download'
,
remote_ip
=
remote_ip
,
result
=
runner
.
results
)
.
save
()
logger
.
debug
(
runner
.
results
)
os
.
chdir
(
'/tmp'
)
tmp_dir_name
=
os
.
path
.
basename
(
upload_dir
)
tar_file
=
'
%
s.tar.gz'
%
upload_dir
bash
(
'tar czf
%
s
%
s
&& sz
%
s.tar.gz'
%
(
tar_file
,
tmp_dir_name
,
upload_dir
))
bash
(
'tar czf
%
s
%
s
'
%
(
tar_file
,
tmp_dir_name
))
f
=
open
(
tar_file
)
data
=
f
.
read
()
f
.
close
()
...
...
run_websocket.py
View file @
8f985ade
...
...
@@ -8,7 +8,7 @@ import sys
import
os.path
import
threading
import
datetime
import
urllib
import
re
import
tornado.ioloop
import
tornado.options
...
...
@@ -24,7 +24,7 @@ from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE
import
select
from
connect
import
Tty
,
User
,
Asset
,
PermRole
,
logger
,
get_object
,
PermRole
,
gen_resource
from
connect
import
TtyLog
,
Log
,
Session
,
user_have_perm
,
get_group_user_perm
,
Command
from
connect
import
TtyLog
,
Log
,
Session
,
user_have_perm
,
get_group_user_perm
,
MyRunner
,
ExecLog
try
:
import
simplejson
as
json
...
...
@@ -218,9 +218,10 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
self
.
id
=
0
self
.
user
=
None
self
.
role
=
None
self
.
cmd
=
None
self
.
runner
=
None
self
.
assets
=
[]
self
.
perm
=
{}
self
.
remote_ip
=
''
super
(
ExecHandler
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
check_origin
(
self
,
origin
):
...
...
@@ -230,6 +231,7 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
def
open
(
self
):
logger
.
debug
(
'Websocket: Open exec request'
)
role_name
=
self
.
get_argument
(
'role'
,
'sb'
)
self
.
remote_ip
=
self
.
request
.
remote_ip
logger
.
debug
(
'Web执行命令: 请求角色
%
s'
%
role_name
)
self
.
role
=
get_object
(
PermRole
,
name
=
role_name
)
self
.
perm
=
get_group_user_perm
(
self
.
user
)
...
...
@@ -238,32 +240,50 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
self
.
write_message
(
'No perm that role
%
s'
%
role_name
)
self
.
close
()
self
.
assets
=
self
.
perm
.
get
(
'role'
)
.
get
(
self
.
role
)
.
get
(
'asset'
)
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
self
.
assets
,
'role'
:
self
.
role
})
logger
.
debug
(
'Web执行命令res:
%
s'
%
res
)
self
.
cmd
=
Command
(
res
)
message
=
'有权限的主机:'
+
', '
.
join
([
asset
.
hostname
for
asset
in
self
.
assets
]
)
self
.
runner
=
MyRunner
(
res
)
message
=
'有权限的主机: '
+
', '
.
join
([
asset
.
hostname
for
asset
in
self
.
assets
]
)
self
.
__class__
.
clients
.
append
(
self
)
self
.
write_message
(
message
)
def
on_message
(
self
,
message
):
data
=
json
.
loads
(
message
)
pattern
=
data
.
get
(
'pattern'
,
''
)
command
=
data
.
get
(
'command'
,
''
)
asset_name_str
=
'
匹配主机:
'
asset_name_str
=
''
if
pattern
and
command
:
for
inv
in
self
.
cmd
.
inventory
.
get_hosts
(
pattern
=
pattern
):
asset_name_str
+=
'
\n
%
s
'
%
inv
.
name
self
.
write_message
(
asset_name_str
)
for
inv
in
self
.
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
asset_name_str
+=
'
%
s
'
%
inv
.
name
self
.
write_message
(
'匹配主机: '
+
asset_name_str
)
self
.
write_message
(
'<span style="color: yellow">Ansible>
%
s</span>
\n\n
'
%
command
)
result
=
self
.
cmd
.
run
(
module_name
=
'shell'
,
command
=
command
,
pattern
=
pattern
)
for
k
,
v
in
result
.
items
():
for
host
,
output
in
v
.
items
():
if
k
==
'ok'
:
header
=
"<span style='color: green'>[
%
s =>
%
s]</span>
\n
"
%
(
host
,
'Ok'
)
else
:
header
=
"<span style='color: red'>[
%
s =>
%
s]</span>
\n
"
%
(
host
,
'failed'
)
self
.
write_message
(
header
)
self
.
write_message
(
output
)
self
.
write_message
(
'
\n
~o~ Task finished ~o~
\n
'
)
self
.
__class__
.
tasks
.
append
(
MyThread
(
target
=
self
.
run_cmd
,
args
=
(
command
,
pattern
)))
ExecLog
(
host
=
asset_name_str
,
cmd
=
command
,
user
=
self
.
user
.
username
,
remote_ip
=
self
.
remote_ip
)
.
save
()
for
t
in
self
.
__class__
.
tasks
:
if
t
.
is_alive
():
continue
try
:
t
.
setDaemon
(
True
)
t
.
start
()
except
RuntimeError
:
pass
def
run_cmd
(
self
,
command
,
pattern
):
self
.
runner
.
run
(
'shell'
,
command
,
pattern
=
pattern
)
for
k
,
v
in
self
.
runner
.
results
.
items
():
for
host
,
output
in
v
.
items
():
if
k
==
'ok'
:
header
=
"<span style='color: green'>[
%
s =>
%
s]</span>
\n
"
%
(
host
,
'Ok'
)
else
:
header
=
"<span style='color: red'>[
%
s =>
%
s]</span>
\n
"
%
(
host
,
'failed'
)
self
.
write_message
(
header
)
self
.
write_message
(
output
)
self
.
write_message
(
'
\n
~o~ Task finished ~o~
\n
'
)
def
on_close
(
self
):
logger
.
debug
(
'关闭web_exec请求'
)
class
WebTerminalHandler
(
tornado
.
websocket
.
WebSocketHandler
):
...
...
static/css/style.css
View file @
8f985ade
...
...
@@ -2822,7 +2822,9 @@ body.body-small .footer.fixed {
.table
>
thead
>
tr
>
td
,
.table
>
tbody
>
tr
>
td
,
.table
>
tfoot
>
tr
>
td
{
border-top
:
1px
solid
#e7eaec
;
/*border-top: 1px solid #e7eaec;*/
border-bottom
:
1px
solid
#e7eaec
;
border-top
:
none
;
line-height
:
1.42857
;
padding
:
8px
;
vertical-align
:
top
;
...
...
templates/download.html
View file @
8f985ade
...
...
@@ -10,7 +10,7 @@
<div
class=
"wrapper wrapper-content animated fadeIn"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
下载文件
</h5>
...
...
templates/exec_cmd.html
View file @
8f985ade
...
...
@@ -2,7 +2,7 @@
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<meta
name=
"viewport"
content=
"width=320, initial-scale=1"
>
<title>
Chat
</title>
<title>
Jumpserver Exec Terminal
</title>
<style
type=
"text/css"
></style>
</head>
...
...
templates/index.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
<div
class=
"wrapper wrapper-content"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-3"
>
<div
class=
"col-
sm
-3"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-success pull-right"
>
Users
</span>
...
...
@@ -18,7 +18,7 @@
</div>
</div>
</div>
<div
class=
"col-
lg
-3"
>
<div
class=
"col-
sm
-3"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-info pull-right"
>
Hosts
</span>
...
...
@@ -31,7 +31,7 @@
</div>
</div>
<div
class=
"col-
lg
-3"
>
<div
class=
"col-
sm
-3"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary pull-right"
>
Online
</span>
...
...
@@ -45,7 +45,7 @@
</div>
</div>
<div
class=
"col-
lg
-3"
>
<div
class=
"col-
sm
-3"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-danger pull-right"
>
Connected
</span>
...
...
@@ -74,7 +74,7 @@
</ul>
</div>
<div
class=
"col-sm-7"
id=
"top10"
style=
"margin-left: -15px;height: 346px;padding: 15px 0 15px 0;"
></div>
<div
class=
"col-
lg
-3 white-bg"
id=
"top1"
style=
"margin-left: -15px;height: 346px"
>
<div
class=
"col-
sm
-3 white-bg"
id=
"top1"
style=
"margin-left: -15px;height: 346px"
>
<div
class=
"statistic-box"
>
<h4>
活跃用户资产占比
...
...
@@ -83,13 +83,13 @@
以下图形分别描述一个月活跃用户和资产占所有用户主机的百分比
</p>
<div
class=
"row text-center"
>
<div
class=
"col-
lg
-6"
>
<div
class=
"col-
sm
-6"
>
<div
id=
"activeUser"
style=
"width: 140px; height: 140px;"
>
</div>
<h5>
用户
</h5>
</div>
<div
class=
"col-
lg
-6"
>
<div
class=
"col-
sm
-6"
>
<div
id=
"activeAsset"
style=
"width: 140px; height: 140px;"
></div>
<h5>
主机
</h5>
</div>
...
...
@@ -103,7 +103,7 @@
<br/>
<div
class=
"row"
>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
{#
<div
class=
"ibox float-e-margins"
>
#}
{#
<div
class=
"ibox-title"
>
#}
{#
<h5>
权限申请
</h5>
#}
...
...
@@ -192,7 +192,7 @@
</div>
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
最近十次登录
</h5>
...
...
@@ -258,7 +258,7 @@
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
一周Top10用户
</h5>
...
...
templates/index_cu.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
<div
class=
"wrapper wrapper-content"
xmlns=
"http://www.w3.org/1999/html"
>
<div
class=
"row"
>
<div
class=
"col-sm-8"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
使用说明
</h5>
...
...
@@ -30,7 +30,7 @@
</div>
</div>
</div>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
登录记录
</h5>
...
...
@@ -85,7 +85,7 @@
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
{{ user.username }}
</b></span>
...
...
templates/jasset/asset_add.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
填写资产基本信息
</h5>
...
...
templates/jasset/asset_add_batch.html
View file @
8f985ade
...
...
@@ -8,7 +8,7 @@
</style>
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
填写主机基本信息
</h5>
...
...
templates/jasset/asset_detail.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"text text-primary"
><b>
{{ asset.ip }}
</b></span>
...
...
@@ -167,7 +167,7 @@
</div>
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
拥有权限的用户
</h5>
...
...
@@ -291,7 +291,7 @@
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
最近一周登录记录
</h5>
...
...
templates/jasset/asset_edit.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
修改资产基本信息
</h5>
...
...
templates/jasset/asset_edit_batch.html
View file @
8f985ade
...
...
@@ -18,7 +18,7 @@
<body>
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
{#
<div
class=
"ibox-title"
>
#}
{#
<h5
class=
"text-center"
>
填写修改主机信息.
</h5>
#}
...
...
templates/jasset/asset_list.html
View file @
8f985ade
...
...
@@ -194,7 +194,7 @@
title
:
title
,
maxmin
:
true
,
shade
:
false
,
area
:
[
'800px'
,
'
7
00px'
],
area
:
[
'800px'
,
'
6
00px'
],
content
:
new_url
+
data
+
'&check_assets='
+
check_assets
});
//window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no');
...
...
@@ -282,7 +282,7 @@
type
:
2
,
title
:
title
,
maxmin
:
true
,
area
:
[
'800px'
,
'
7
00px'
],
area
:
[
'800px'
,
'
6
00px'
],
shade
:
false
,
content
:
new_url
});
...
...
templates/jasset/group_add.html
View file @
8f985ade
...
...
@@ -19,7 +19,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
填写主机组基本信息
</h5>
...
...
templates/jasset/group_edit.html
View file @
8f985ade
...
...
@@ -19,7 +19,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
填写主机组基本信息
</h5>
...
...
templates/jasset/group_list.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
主机组详细信息列表
</h5>
...
...
templates/jasset/idc_add.html
View file @
8f985ade
...
...
@@ -4,7 +4,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
填写IDC基本信息
</h5>
...
...
templates/jasset/idc_edit.html
View file @
8f985ade
...
...
@@ -4,7 +4,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
填写IDC基本信息
</h5>
...
...
templates/jasset/idc_list.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
IDC详细信息列表
</h5>
...
...
templates/jlog/exec_detail.html
0 → 100644
View file @
8f985ade
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
{{ log.id }}
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
</ul>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<div>
<div
class=
"text-left"
>
<table
class=
"table"
>
<tr>
<td
class=
"text-navy"
>
ID
</td>
<td>
{{ log.id }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
用户名
</td>
<td>
{{ log.user }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
来源IP
</td>
<td>
{{ log.remote_ip }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
日期
</td>
<td>
{{ log.datetime|date:"Y-m-d H:i:s" }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
主机
</td>
<td>
<table
class=
"table"
>
{% for asset_name in assets_hostname %}
{% if asset_name %}
<tr>
<td>
{{ asset_name }}
</td>
</tr>
{% endif %}
{% endfor %}
</table>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<div
class=
"col-sm-8"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
结果
</h5>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
</ul>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content inspinia-timeline"
>
<div>
<div
class=
"text-left"
>
<table
class=
"table"
>
<tr>
<td
class=
"text-navy"
>
命令
</td>
<td>
{{ log.cmd }}
</td>
</tr>
{% for result, info in result.items %}
{% for host, msg in info.items %}
{% ifequal result 'failed' %}
<tr>
<td
class=
"text-navy"
style=
"color: #ed5565"
>
{{ host }}
</td>
<td>
{{ msg }}
</td>
</tr>
{% else %}
<tr>
<td
class=
"text-navy"
>
{{ host }}
</td>
<td>
{{ msg }}
</td>
</tr>
{% endifequal %}
{% endfor %}
{% endfor %}
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$
(
document
).
ready
(
function
(){
$
(
'#show'
).
click
(
function
(){
$
(
'#last'
).
css
(
'display'
,
'none'
);
$
(
'#all'
).
css
(
'display'
,
'block'
);
})
})
</script>
{% endblock %}
\ No newline at end of file
templates/jlog/log_exec.html
0 → 100644
View file @
8f985ade
{% extends 'base.html' %}
{% block self_head_css_js %}
<link
href=
"/static/css/plugins/datepicker/datepicker3.css"
rel=
"stylesheet"
>
<link
href=
"/static/css/plugins/chosen/chosen.css"
rel=
"stylesheet"
>
<script
src=
"/static/js/plugins/chosen/chosen.jquery.js"
></script>
{% endblock %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-10"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
批量命令日志
</h5>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li><a
href=
"/jlog/log_list/online/"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
在线
</a></li>
<li><a
href=
"/jlog/log_list/offline/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
历史记录
</a></li>
<li
class=
"active"
><a
href=
"/jlog/log_list/exec/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
命令记录
</a></li>
<li><a
href=
"/jlog/log_list/file/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
上传下载
</a></li>
</ul>
</div>
<br/>
<div
class=
""
>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right mail-search"
>
<div
class=
"input-group"
>
<input
type=
"text"
class=
"form-control input-sm"
id=
"keyword"
name=
"keyword"
value=
"{{ keyword }}"
placeholder=
"Search"
>
<div
class=
"input-group-btn"
>
<button
id=
'search_btn'
type=
"submit"
class=
"btn btn-sm btn-primary"
>
-搜索-
</button>
</div>
</div>
</form>
</div>
<div
class=
"tab-content"
>
<table
class=
"table table-striped table-bordered table-hover "
>
<thead>
<tr>
<th
class=
"text-center"
>
ID
</th>
<th
class=
"text-center"
>
用户名
</th>
<th
class=
"text-center"
>
主机
</th>
<th
class=
"text-center"
>
命令
</th>
<th
class=
"text-center"
>
来源IP
</th>
<th
class=
"text-center"
>
时间
</th>
<th
class=
"text-center"
>
详情
</th>
</tr>
</thead>
<tbody>
{% for post in contacts.object_list %}
<tr
class=
"gradeX"
>
<td
class=
"text-center"
>
{{ post.id }}
</td>
<td
class=
"text-center username"
>
{{ post.user }}
</td>
<td
class=
"text-center ip"
>
{{ post.host | truncatechars:30 }}
</td>
<td
class=
"text-center ip"
>
{{ post.cmd | truncatechars:30 }}
</td>
<td
class=
"text-center remote_ip"
>
{{ post.remote_ip }}
</td>
<td
class=
"text-center start_time"
>
{{ post.datetime|date:"Y-m-d H:i:s"}}
</td>
<td
class=
"text-center"
>
<a
href=
"/jlog/log_detail/exec/?id={{ post.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div
class=
"row"
>
<div
class=
"col-sm-6"
>
</div>
{% include 'paginator.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function
log_search
(){
$
.
ajax
({
type
:
"GET"
,
url
:
"/jlog/search/?env=offline"
,
data
:
$
(
"#search_form"
).
serialize
(),
success
:
function
(
data
)
{
$
(
".tab-content"
).
html
(
data
);
}
});
}
</script>
{% endblock %}
templates/jlog/log_file.html
0 → 100644
View file @
8f985ade
{% extends 'base.html' %}
{% block self_head_css_js %}
<link
href=
"/static/css/plugins/datepicker/datepicker3.css"
rel=
"stylesheet"
>
<link
href=
"/static/css/plugins/chosen/chosen.css"
rel=
"stylesheet"
>
<script
src=
"/static/js/plugins/chosen/chosen.jquery.js"
></script>
{% endblock %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-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>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li><a
href=
"/jlog/log_list/online/"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
在线
</a></li>
<li><a
href=
"/jlog/log_list/offline/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
历史记录
</a></li>
<li><a
href=
"/jlog/log_list/exec/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
命令记录
</a></li>
<li
class=
"active"
><a
href=
"/jlog/log_list/file/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
上传下载
</a></li>
</ul>
</div>
<br/>
<div
class=
""
>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right mail-search"
>
<div
class=
"input-group"
>
<input
type=
"text"
class=
"form-control input-sm"
id=
"keyword"
name=
"keyword"
value=
"{{ keyword }}"
placeholder=
"Search"
>
<div
class=
"input-group-btn"
>
<button
id=
'search_btn'
type=
"submit"
class=
"btn btn-sm btn-primary"
>
-搜索-
</button>
</div>
</div>
</form>
</div>
<div
class=
"tab-content"
>
<table
class=
"table table-striped table-bordered table-hover "
>
<thead>
<tr>
<th
class=
"text-center"
>
ID
</th>
<th
class=
"text-center"
>
用户名
</th>
<th
class=
"text-center"
>
主机
</th>
<th
class=
"text-center"
>
文件
</th>
<th
class=
"text-center"
>
类型
</th>
<th
class=
"text-center"
>
来源IP
</th>
<th
class=
"text-center"
>
时间
</th>
<th
class=
"text-center"
>
详情
</th>
</tr>
</thead>
<tbody>
{% for post in contacts.object_list %}
<tr
class=
"gradeX"
>
<td
class=
"text-center"
>
{{ post.id }}
</td>
<td
class=
"text-center"
>
{{ post.user }}
</td>
<td
class=
"text-center"
>
{{ post.host | truncatechars:30 }}
</td>
<td
class=
"text-center"
>
{{ post.filename | truncatechars:30 }}
</td>
<td
class=
"text-center"
>
{{ post.type }}
</td>
<td
class=
"text-center"
>
{{ post.remote_ip }}
</td>
<td
class=
"text-center"
>
{{ post.datetime|date:"Y-m-d H:i:s"}}
</td>
<td
class=
"text-center"
>
<a
href=
"/jlog/log_detail/file/?id={{ post.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div
class=
"row"
>
<div
class=
"col-sm-6"
>
</div>
{% include 'paginator.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function
log_search
(){
$
.
ajax
({
type
:
"GET"
,
url
:
"/jlog/search/?env=offline"
,
data
:
$
(
"#search_form"
).
serialize
(),
success
:
function
(
data
)
{
$
(
".tab-content"
).
html
(
data
);
}
});
}
</script>
{% endblock %}
templates/jlog/log_filter.html
View file @
8f985ade
...
...
@@ -9,7 +9,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
用户日志详细信息列表
</h5>
...
...
templates/jlog/log_offline.html
View file @
8f985ade
...
...
@@ -32,7 +32,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
用户日志详细信息列表
</h5>
...
...
@@ -54,6 +54,8 @@
<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><a
href=
"/jlog/log_list/exec/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
命令记录
</a></li>
<li><a
href=
"/jlog/log_list/file/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
上传下载
</a></li>
</ul>
</div>
<br/>
...
...
templates/jlog/log_online.html
View file @
8f985ade
...
...
@@ -47,7 +47,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
用户日志详细信息列表
</h5>
...
...
@@ -69,6 +69,8 @@
<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><a
href=
"/jlog/log_list/exec/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
命令记录
</a></li>
<li><a
href=
"/jlog/log_list/file/"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
上传下载
</a></li>
</ul>
</div>
<br/>
...
...
templates/jlog/user_history.html
View file @
8f985ade
...
...
@@ -28,7 +28,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
用户{{ username }}日志详细信息列表
</h5>
...
...
templates/jperm/perm_group_edit.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
{{ user_group.name }}授权修改
</h5>
...
...
templates/jperm/perm_group_list.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
查看小组
</h5>
...
...
templates/jperm/perm_log.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
查看小组
</h5>
...
...
templates/jperm/perm_role_add.html
View file @
8f985ade
...
...
@@ -9,7 +9,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/jperm/perm_role_detail.html
View file @
8f985ade
...
...
@@ -8,7 +8,7 @@
<div
class=
"col-sm-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
授权规则
</b></span>
<span
class=
"label label-primary"
><b>
{{ role.name }} -
授权规则
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
@@ -54,7 +54,7 @@
<div
class=
"col-sm-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
授权用户/用户组
</b></span>
<span
class=
"label label-primary"
><b>
{{ role.name }} -
授权用户/用户组
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
@@ -100,7 +100,7 @@
<div
class=
"col-sm-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
授权主机/主机组
</b></span>
<span
class=
"label label-primary"
><b>
{{ role.name }} -
授权主机/主机组
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
@@ -148,7 +148,7 @@
<div
class=
"col-sm-6"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
推送主机
</b></span>
<span
class=
"label label-primary"
><b>
{{ role.name }} -
推送主机
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
@@ -212,7 +212,7 @@
<div
class=
"col-sm-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-danger"
><b>
未推送主机
</b></span>
<span
class=
"label label-danger"
><b>
{{ role.name }} -
未推送主机
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
templates/jperm/perm_role_edit.html
View file @
8f985ade
...
...
@@ -9,7 +9,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/jperm/perm_role_list.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div>
{% if error %}
...
...
templates/jperm/perm_role_push.html
View file @
8f985ade
...
...
@@ -9,7 +9,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/jperm/perm_rule_add.html
View file @
8f985ade
...
...
@@ -9,7 +9,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/jperm/perm_rule_detail.html
View file @
8f985ade
...
...
@@ -7,7 +7,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
{{ rule.name }}
</b></span>
...
...
@@ -60,7 +60,7 @@
</div>
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
授权用户/用户组
</b></span>
...
...
@@ -106,7 +106,7 @@
</div>
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
授权主机/主机组
</b></span>
...
...
templates/jperm/perm_rule_edit.html
View file @
8f985ade
...
...
@@ -9,7 +9,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/jperm/perm_rule_list.html
View file @
8f985ade
...
...
@@ -7,7 +7,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div>
{% if error %}
...
...
templates/jperm/perm_sudo_add.html
View file @
8f985ade
...
...
@@ -4,7 +4,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/jperm/perm_sudo_edit.html
View file @
8f985ade
...
...
@@ -9,7 +9,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/jperm/perm_sudo_list.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div>
{% if error %}
...
...
templates/jperm/sys_user_add.html
View file @
8f985ade
...
...
@@ -4,7 +4,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel blank-panel"
>
<div
class=
"panel-heading"
>
...
...
templates/jperm/sys_user_list.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel blank-panel"
>
<div
class=
"panel-heading"
>
...
...
templates/juser/change_info.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
编辑用户信息
</h5>
...
...
templates/juser/group_add.html
View file @
8f985ade
...
...
@@ -4,7 +4,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/juser/group_list.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
...
...
templates/juser/run_command.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
命令批量执行
</h5>
...
...
templates/juser/user_add.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
填写基本信息
</h5>
...
...
templates/juser/user_detail.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
{{ user.name }}
</b></span>
...
...
@@ -82,7 +82,7 @@
</div>
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
授权主机/组
</h5>
...
...
@@ -137,7 +137,7 @@
</div>
</div>
<div
class=
"col-
lg
-4"
>
<div
class=
"col-
sm
-4"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
登录记录
</h5>
...
...
templates/juser/user_edit.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
编辑用户信息
</h5>
...
...
@@ -55,7 +55,7 @@
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<label
for=
"groups"
class=
"col-
lg
-2 control-label"
>
小组
</label>
<label
for=
"groups"
class=
"col-
sm
-2 control-label"
>
小组
</label>
<div
class=
"col-sm-8"
>
<select
id=
"groups"
name=
"groups"
class=
"form-control m-b"
multiple
size=
"12"
>
{% for group in group_all %}
...
...
@@ -70,7 +70,7 @@
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<label
for=
"role"
class=
"col-
lg
-2 control-label"
>
角色
<span
class=
"red-fonts"
>
*
</span></label>
<label
for=
"role"
class=
"col-
sm
-2 control-label"
>
角色
<span
class=
"red-fonts"
>
*
</span></label>
<div
class=
"col-sm-8"
>
{% for r, role_name in user_role.items %}
<div
class=
"col-sm-3"
>
...
...
templates/juser/user_list.html
View file @
8f985ade
...
...
@@ -5,7 +5,7 @@
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
查看用户
</h5>
...
...
@@ -24,18 +24,18 @@
<div
class=
"ibox-content"
>
<div
class=
""
>
<a
target=
"_blank"
href=
"/juser/user_add/"
class=
"btn btn-sm btn-primary "
>
添加用户
</a>
<a
id=
"del_btn"
class=
"btn btn-sm btn-danger "
>
删除所选
</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"
>
<div
class=
"input-group-btn"
>
<button
id=
'search_btn'
type=
"submit"
class=
"btn btn-sm btn-primary"
>
-搜索-
</button>
<a
target=
"_blank"
href=
"/juser/user_add/"
class=
"btn btn-sm btn-primary "
>
添加用户
</a>
<a
id=
"del_btn"
class=
"btn btn-sm btn-danger "
>
删除所选
</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"
>
<div
class=
"input-group-btn"
>
<button
id=
'search_btn'
type=
"submit"
class=
"btn btn-sm btn-primary"
>
-搜索-
</button>
</div>
</div>
</div>
</form>
</form>
</div>
<table
class=
"table table-striped table-bordered table-hover "
id=
"editable"
>
...
...
templates/log_watch.html
View file @
8f985ade
...
...
@@ -99,7 +99,7 @@
{#
<div
id=
"message"
></div>
#}
{#
</div>
#}
{#
</div>
#}
<div
class=
"col-
lg
-12"
>
<div
class=
"col-
sm
-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
style=
"border: solid"
>
<h5>
实时监控
</h5>
...
...
templates/nav.html
View file @
8f985ade
...
...
@@ -27,19 +27,24 @@
<li
class=
"rule perm_rule_add"
>
<a
href=
"/jperm/rule/"
>
授权规则
</a>
</li>
<li
class=
"role"
>
<a
href=
"/jperm/role/"
>
系统角色
</a>
</li>
<li
class=
"sudo"
>
<a
href=
"/jperm/sudo/"
>
Sudo命令
</a>
</li>
</ul>
</li>
<li
id=
"jlog"
>
<a
href=
"/jlog/log_list/online/"
><i
class=
"fa fa-files-o"
></i>
<span
class=
"nav-label"
>
日志审计
</span><span
class=
"label label-info pull-right"
></span></a>
</li>
<li
id=
"file"
>
<a
href=
"#"
><i
class=
"fa fa-download"
></i>
<span
class=
"nav-label"
>
上传下载
</span><span
class=
"fa arrow"
></span></a>
<ul
class=
"nav nav-second-level"
>
<li
class=
"upload"
><a
href=
"/file/upload/"
>
文件上传
</a></li>
<li
class=
"download"
><a
href=
"/file/download/"
>
文件下载
</a></li>
</ul>
</li>
<li
id=
"setting"
>
<a
href=
"/setting/"
><i
class=
"fa fa-gears"
></i>
<span
class=
"nav-label"
>
设置
</span><span
class=
"label label-info pull-right"
></span></a>
</li>
...
...
templates/nav_cat_bar.html
View file @
8f985ade
<div
class=
"row wrapper border-bottom white-bg page-heading"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<h2>
{{ header_title }}
</h2>
<ol
class=
"breadcrumb"
>
<li>
...
...
@@ -17,6 +17,6 @@
{% endif %}
</ol>
</div>
<div
class=
"col-
lg
-2"
>
<div
class=
"col-
sm
-2"
>
</div>
</div>
templates/setting.html
View file @
8f985ade
...
...
@@ -6,7 +6,7 @@
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
项目设置
</h5>
...
...
templates/upload.html
View file @
8f985ade
...
...
@@ -50,7 +50,7 @@
</style>
<div
class=
"wrapper wrapper-content animated fadeIn"
>
<div
class=
"row"
>
<div
class=
"col-
lg
-10"
>
<div
class=
"col-
sm
-10"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
上传文件
</h5>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment