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
175f2702
Commit
175f2702
authored
Nov 25, 2015
by
liuzheng712
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' of
https://git.coding.net/jumpserver/jumpserver
into NormalUserPageLZ
parents
c89d43d2
742e56fc
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
521 additions
and
799 deletions
+521
-799
connect.py
connect.py
+66
-74
ansible_api.py
jasset/ansible_api.py
+0
-459
asset_api.py
jasset/asset_api.py
+66
-3
models.py
jasset/models.py
+2
-2
urls.py
jasset/urls.py
+1
-0
views.py
jasset/views.py
+39
-60
urls.py
jlog/urls.py
+2
-0
views.py
jlog/views.py
+16
-5
perm_api.py
jperm/perm_api.py
+9
-0
utils.py
jperm/utils.py
+1
-1
jumpserver.conf
jumpserver.conf
+1
-1
api.py
jumpserver/api.py
+5
-2
context_processors.py
jumpserver/context_processors.py
+2
-6
settings.py
jumpserver/settings.py
+5
-0
mytags.py
jumpserver/templatetags/mytags.py
+14
-1
run_websocket.py
run_websocket.py
+108
-46
cmdb_excel_2015_11_14_11_38.xlsx
static/files/excels/cmdb_excel_2015_11_14_11_38.xlsx
+0
-0
cmdb_excel_2015_11_14_11_39.xlsx
static/files/excels/cmdb_excel_2015_11_14_11_39.xlsx
+0
-0
cmdb_excel_2015_11_20_00_04.xlsx
static/files/excels/cmdb_excel_2015_11_20_00_04.xlsx
+0
-0
asset_add.html
templates/jasset/asset_add.html
+33
-13
asset_detail.html
templates/jasset/asset_detail.html
+10
-4
asset_edit.html
templates/jasset/asset_edit.html
+35
-14
asset_edit_batch.html
templates/jasset/asset_edit_batch.html
+0
-27
asset_list.html
templates/jasset/asset_list.html
+79
-32
error.html
templates/jasset/error.html
+1
-1
idc_list.html
templates/jasset/idc_list.html
+4
-4
log_online.html
templates/jlog/log_online.html
+9
-29
perm_role_add.html
templates/jperm/perm_role_add.html
+1
-1
nav.html
templates/nav.html
+0
-2
nav_li_profile.html
templates/nav_li_profile.html
+2
-2
setting.html
templates/setting.html
+10
-10
No files found.
connect.py
View file @
175f2702
...
@@ -19,14 +19,14 @@ import struct, fcntl, signal, socket, select
...
@@ -19,14 +19,14 @@ import struct, fcntl, signal, socket, select
os
.
environ
[
'DJANGO_SETTINGS_MODULE'
]
=
'jumpserver.settings'
os
.
environ
[
'DJANGO_SETTINGS_MODULE'
]
=
'jumpserver.settings'
if
django
.
get_version
()
!=
'1.6'
:
if
django
.
get_version
()
!=
'1.6'
:
django
.
setup
()
django
.
setup
()
from
jumpserver.api
import
ServerError
,
User
,
Asset
,
AssetGroup
,
get_object
,
mkdir
,
get_asset_info
,
get_role
from
django.contrib.sessions.models
import
Session
from
jumpserver.api
import
logger
,
Log
,
TtyLog
,
get_role_key
from
jumpserver.api
import
ServerError
,
User
,
Asset
,
PermRole
,
AssetGroup
,
get_object
,
mkdir
,
get_asset_info
,
get_role
from
jperm.perm_api
import
gen_resource
,
get_group_asset_perm
,
get_group_user_perm
from
jumpserver.api
import
logger
,
Log
,
TtyLog
,
get_role_key
,
CRYPTOR
from
jperm.perm_api
import
gen_resource
,
get_group_asset_perm
,
get_group_user_perm
,
user_have_perm
from
jumpserver.settings
import
LOG_DIR
from
jumpserver.settings
import
LOG_DIR
from
jperm.ansible_api
import
Command
from
jperm.ansible_api
import
Command
login_user
=
get_object
(
User
,
username
=
getpass
.
getuser
())
login_user
=
get_object
(
User
,
username
=
getpass
.
getuser
())
VIM_FLAG
=
False
try
:
try
:
import
termios
import
termios
...
@@ -69,6 +69,9 @@ class Tty(object):
...
@@ -69,6 +69,9 @@ class Tty(object):
self
.
ssh
=
None
self
.
ssh
=
None
self
.
connect_info
=
None
self
.
connect_info
=
None
self
.
login_type
=
'ssh'
self
.
login_type
=
'ssh'
self
.
vim_flag
=
False
self
.
ps1_pattern
=
re
.
compile
(
'
\
[.*@.*
\
][
\
$#]'
)
self
.
vim_data
=
''
@staticmethod
@staticmethod
def
is_output
(
strings
):
def
is_output
(
strings
):
...
@@ -78,25 +81,24 @@ class Tty(object):
...
@@ -78,25 +81,24 @@ class Tty(object):
return
True
return
True
return
False
return
False
@staticmethod
def
deal_command
(
self
,
str_r
):
def
deal_command
(
str_r
):
"""
"""
处理命令中特殊字符
处理命令中特殊字符
"""
"""
str_r
=
re
.
sub
(
'
\x07
'
,
''
,
str_r
)
#
删除响铃
str_r
=
re
.
sub
(
'
\x07
'
,
''
,
str_r
)
#
删除响铃
patch_char
=
re
.
compile
(
'
\x08\x1b
\
[C'
)
#
删除方向左右一起的按键
patch_char
=
re
.
compile
(
'
\x08\x1b
\
[C'
)
#
删除方向左右一起的按键
while
patch_char
.
search
(
str_r
):
while
patch_char
.
search
(
str_r
):
str_r
=
patch_char
.
sub
(
''
,
str_r
.
rstrip
())
str_r
=
patch_char
.
sub
(
''
,
str_r
.
rstrip
())
result_command
=
''
#
最后的结果
result_command
=
''
#
最后的结果
backspace_num
=
0
#
光标移动的个数
backspace_num
=
0
#
光标移动的个数
reach_backspace_flag
=
False
#没有检测到光标键则为true
reach_backspace_flag
=
False
#
没有检测到光标键则为true
pattern_str
=
''
pattern_str
=
''
while
str_r
:
while
str_r
:
tmp
=
re
.
match
(
r'\s*\w+\s*'
,
str_r
)
tmp
=
re
.
match
(
r'\s*\w+\s*'
,
str_r
)
if
tmp
:
if
tmp
:
if
reach_backspace_flag
:
if
reach_backspace_flag
:
pattern_str
+=
str
(
tmp
.
group
(
0
))
pattern_str
+=
str
(
tmp
.
group
(
0
))
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
continue
continue
else
:
else
:
...
@@ -107,7 +109,7 @@ class Tty(object):
...
@@ -107,7 +109,7 @@ class Tty(object):
tmp
=
re
.
match
(
r'\x1b\[K[\x08]*'
,
str_r
)
tmp
=
re
.
match
(
r'\x1b\[K[\x08]*'
,
str_r
)
if
tmp
:
if
tmp
:
if
backspace_num
>
0
:
if
backspace_num
>
0
:
if
backspace_num
>
len
(
result_command
)
:
if
backspace_num
>
len
(
result_command
):
result_command
+=
pattern_str
result_command
+=
pattern_str
result_command
=
result_command
[
0
:
-
backspace_num
]
result_command
=
result_command
[
0
:
-
backspace_num
]
else
:
else
:
...
@@ -117,8 +119,8 @@ class Tty(object):
...
@@ -117,8 +119,8 @@ class Tty(object):
if
del_len
>
0
:
if
del_len
>
0
:
result_command
=
result_command
[
0
:
-
del_len
]
result_command
=
result_command
[
0
:
-
del_len
]
reach_backspace_flag
=
False
reach_backspace_flag
=
False
backspace_num
=
0
backspace_num
=
0
pattern_str
=
''
pattern_str
=
''
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
continue
continue
...
@@ -136,13 +138,13 @@ class Tty(object):
...
@@ -136,13 +138,13 @@ class Tty(object):
else
:
else
:
break
break
if
reach_backspace_flag
:
if
reach_backspace_flag
:
pattern_str
+=
str_r
[
0
]
pattern_str
+=
str_r
[
0
]
else
:
else
:
result_command
+=
str_r
[
0
]
result_command
+=
str_r
[
0
]
str_r
=
str_r
[
1
:]
str_r
=
str_r
[
1
:]
if
backspace_num
>
0
:
if
backspace_num
>
0
:
result_command
=
result_command
[
0
:
-
backspace_num
]
+
pattern_str
result_command
=
result_command
[
0
:
-
backspace_num
]
+
pattern_str
control_char
=
re
.
compile
(
r"""
control_char
=
re
.
compile
(
r"""
...
@@ -155,35 +157,13 @@ class Tty(object):
...
@@ -155,35 +157,13 @@ class Tty(object):
[\x80-\x9f] | (?:\x1b\]0.*) | \[.*@.*\][\$#] | (.*mysql>.*) #匹配 所有控制字符
[\x80-\x9f] | (?:\x1b\]0.*) | \[.*@.*\][\$#] | (.*mysql>.*) #匹配 所有控制字符
"""
,
re
.
X
)
"""
,
re
.
X
)
result_command
=
control_char
.
sub
(
''
,
result_command
.
strip
())
result_command
=
control_char
.
sub
(
''
,
result_command
.
strip
())
global
VIM_FLAG
if
not
self
.
vim_flag
:
if
not
VIM_FLAG
:
if
result_command
.
startswith
(
'vi'
)
or
result_command
.
startswith
(
'fg'
):
if
result_command
.
startswith
(
'vi'
):
self
.
vim_flag
=
True
VIM_FLAG
=
True
return
result_command
.
decode
(
'utf8'
,
"ignore"
)
return
result_command
.
decode
(
'utf8'
,
"ignore"
)
else
:
else
:
return
''
return
''
@staticmethod
def
remove_control_char
(
str_r
):
"""
处理日志特殊字符
"""
control_char
=
re
.
compile
(
r"""
\x1b[ #
%
()*+\-.\/]. |
\r | #匹配 回车符(CR)
(?:\x1b\[|\x9b) [ -?]* [@-~] | #匹配 控制顺序描述符(CSI)... Cmd
(?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 | #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL)
(?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST)
\x1b. #匹配 转义过后的字符
[\x80-\x9f] #匹配 所有控制字符
"""
,
re
.
X
)
backspace
=
re
.
compile
(
r"[^\b][\b]"
)
line_filtered
=
control_char
.
sub
(
''
,
str_r
.
rstrip
())
while
backspace
.
search
(
line_filtered
):
line_filtered
=
backspace
.
sub
(
''
,
line_filtered
)
return
line_filtered
def
get_log
(
self
):
def
get_log
(
self
):
"""
"""
Logging user command and output.
Logging user command and output.
...
@@ -230,15 +210,17 @@ class Tty(object):
...
@@ -230,15 +210,17 @@ class Tty(object):
"""
"""
获取需要登陆的主机的信息和映射用户的账号密码
获取需要登陆的主机的信息和映射用户的账号密码
"""
"""
# 1. get ip, port
# 2. get 映射用户
# 3. get 映射用户的账号,密码或者key
# self.connect_info = {'user': '', 'asset': '', 'ip': '', 'port': 0, 'role_name': '', 'role_pass': '', 'role_key': ''}
asset_info
=
get_asset_info
(
self
.
asset
)
asset_info
=
get_asset_info
(
self
.
asset
)
role_key
=
get_role_key
(
self
.
user
,
self
.
role
)
role_pass
=
CRYPTOR
.
decrypt
(
self
.
role
.
password
)
self
.
connect_info
=
{
'user'
:
self
.
user
,
'asset'
:
self
.
asset
,
'ip'
:
asset_info
.
get
(
'ip'
),
self
.
connect_info
=
{
'user'
:
self
.
user
,
'asset'
:
self
.
asset
,
'ip'
:
asset_info
.
get
(
'ip'
),
'port'
:
int
(
asset_info
.
get
(
'port'
)),
'role_name'
:
self
.
role
.
name
,
'port'
:
int
(
asset_info
.
get
(
'port'
)),
'role_name'
:
self
.
role
.
name
,
'role_pass'
:
self
.
role
.
password
,
'role_key'
:
self
.
role
.
key_path
}
'role_pass'
:
role_pass
,
'role_key'
:
role_key
}
logger
.
debug
(
"Connect: Host:
%
s Port:
%
s User:
%
s Pass:
%
s Key:
%
s"
%
(
asset_info
.
get
(
'ip'
),
asset_info
.
get
(
'port'
),
self
.
role
.
name
,
role_pass
,
role_key
))
return
self
.
connect_info
return
self
.
connect_info
def
get_connection
(
self
):
def
get_connection
(
self
):
...
@@ -252,7 +234,7 @@ class Tty(object):
...
@@ -252,7 +234,7 @@ class Tty(object):
ssh
.
load_system_host_keys
()
ssh
.
load_system_host_keys
()
ssh
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
ssh
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
try
:
try
:
role_key
=
get_role_key
(
self
.
user
,
self
.
role
)
role_key
=
connect_info
.
get
(
'role_key'
)
if
role_key
and
os
.
path
.
isfile
(
role_key
):
if
role_key
and
os
.
path
.
isfile
(
role_key
):
try
:
try
:
ssh
.
connect
(
connect_info
.
get
(
'ip'
),
ssh
.
connect
(
connect_info
.
get
(
'ip'
),
...
@@ -262,7 +244,8 @@ class Tty(object):
...
@@ -262,7 +244,8 @@ class Tty(object):
look_for_keys
=
False
)
look_for_keys
=
False
)
self
.
ssh
=
ssh
self
.
ssh
=
ssh
return
ssh
return
ssh
except
paramiko
.
ssh_exception
.
AuthenticationException
,
paramiko
.
ssh_exception
.
SSHException
:
except
(
paramiko
.
ssh_exception
.
AuthenticationException
,
paramiko
.
ssh_exception
.
SSHException
):
logger
.
warning
(
'Use ssh key
%
s Failed.'
%
role_key
)
pass
pass
ssh
.
connect
(
connect_info
.
get
(
'ip'
),
ssh
.
connect
(
connect_info
.
get
(
'ip'
),
...
@@ -319,12 +302,8 @@ class SshTty(Tty):
...
@@ -319,12 +302,8 @@ class SshTty(Tty):
log_file_f
,
log_time_f
,
log
=
self
.
get_log
()
log_file_f
,
log_time_f
,
log
=
self
.
get_log
()
old_tty
=
termios
.
tcgetattr
(
sys
.
stdin
)
old_tty
=
termios
.
tcgetattr
(
sys
.
stdin
)
pre_timestamp
=
time
.
time
()
pre_timestamp
=
time
.
time
()
pattern
=
re
.
compile
(
'
\
[.*@.*
\
][
\
$#]'
)
data
=
''
data
=
''
chan_str
=
''
input_mode
=
False
input_mode
=
False
global
VIM_FLAG
try
:
try
:
tty
.
setraw
(
sys
.
stdin
.
fileno
())
tty
.
setraw
(
sys
.
stdin
.
fileno
())
tty
.
setcbreak
(
sys
.
stdin
.
fileno
())
tty
.
setcbreak
(
sys
.
stdin
.
fileno
())
...
@@ -341,8 +320,8 @@ class SshTty(Tty):
...
@@ -341,8 +320,8 @@ class SshTty(Tty):
x
=
self
.
channel
.
recv
(
1024
)
x
=
self
.
channel
.
recv
(
1024
)
if
len
(
x
)
==
0
:
if
len
(
x
)
==
0
:
break
break
if
VIM_FLAG
:
if
self
.
vim_flag
:
chan_str
+=
x
self
.
vim_data
+=
x
sys
.
stdout
.
write
(
x
)
sys
.
stdout
.
write
(
x
)
sys
.
stdout
.
flush
()
sys
.
stdout
.
flush
()
now_timestamp
=
time
.
time
()
now_timestamp
=
time
.
time
()
...
@@ -361,21 +340,20 @@ class SshTty(Tty):
...
@@ -361,21 +340,20 @@ class SshTty(Tty):
if
sys
.
stdin
in
r
:
if
sys
.
stdin
in
r
:
x
=
os
.
read
(
sys
.
stdin
.
fileno
(),
1
)
x
=
os
.
read
(
sys
.
stdin
.
fileno
(),
1
)
input_mode
=
True
input_mode
=
True
if
str
(
x
)
in
[
'
\r
'
,
'
\n
'
,
'
\r\n
'
]:
if
str
(
x
)
in
[
'
\r
'
,
'
\n
'
,
'
\r\n
'
]:
if
VIM_FLAG
:
if
self
.
vim_flag
:
match
=
pattern
.
search
(
chan_str
)
match
=
self
.
ps1_pattern
.
search
(
self
.
vim_data
)
if
match
:
if
match
:
VIM_FLAG
=
False
self
.
vim_flag
=
False
data
=
self
.
deal_command
(
data
)
data
=
self
.
deal_command
(
data
)
[
0
:
200
]
if
len
(
data
)
>
0
:
if
len
(
data
)
>
0
:
TtyLog
(
log
=
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
data
)
.
save
()
TtyLog
(
log
=
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
data
)
.
save
()
else
:
else
:
data
=
self
.
deal_command
(
data
)
data
=
self
.
deal_command
(
data
)
[
0
:
200
]
if
len
(
data
)
>
0
:
if
len
(
data
)
>
0
:
TtyLog
(
log
=
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
data
)
.
save
()
TtyLog
(
log
=
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
data
)
.
save
()
data
=
''
data
=
''
chan_str
=
''
self
.
vim_data
=
''
input_mode
=
False
input_mode
=
False
if
len
(
x
)
==
0
:
if
len
(
x
)
==
0
:
...
@@ -465,24 +443,33 @@ class Nav(object):
...
@@ -465,24 +443,33 @@ class Nav(object):
def
search
(
self
,
str_r
=
''
):
def
search
(
self
,
str_r
=
''
):
gid_pattern
=
re
.
compile
(
r'^g\d+$'
)
gid_pattern
=
re
.
compile
(
r'^g\d+$'
)
# 获取用户授权的所有主机信息
if
not
self
.
user_perm
:
if
not
self
.
user_perm
:
self
.
user_perm
=
get_group_user_perm
(
self
.
user
)
self
.
user_perm
=
get_group_user_perm
(
self
.
user
)
user_asset_all
=
self
.
user_perm
.
get
(
'asset'
)
.
keys
()
user_asset_all
=
self
.
user_perm
.
get
(
'asset'
)
.
keys
()
# 搜索结果保存
user_asset_search
=
[]
user_asset_search
=
[]
if
str_r
:
if
str_r
:
# 资产组组id匹配
if
gid_pattern
.
match
(
str_r
):
if
gid_pattern
.
match
(
str_r
):
user_asset_search
=
list
(
Asset
.
objects
.
all
())
gid
=
int
(
str_r
.
lstrip
(
'g'
))
# 获取资产组包含的资产
user_asset_search
=
get_object
(
AssetGroup
,
id
=
gid
)
.
asset_set
.
all
()
else
:
else
:
# 匹配 ip, hostname, 备注
for
asset
in
user_asset_all
:
for
asset
in
user_asset_all
:
if
str_r
in
asset
.
ip
or
str_r
in
str
(
asset
.
comment
):
if
str_r
in
asset
.
ip
or
str_r
in
str
(
asset
.
hostname
)
or
str_r
in
str
(
asset
.
comment
):
user_asset_search
.
append
(
asset
)
user_asset_search
.
append
(
asset
)
else
:
else
:
# 如果没有输入就展现所有
user_asset_search
=
user_asset_all
user_asset_search
=
user_asset_all
self
.
search_result
=
dict
(
zip
(
range
(
len
(
user_asset_search
)),
user_asset_search
))
self
.
search_result
=
dict
(
zip
(
range
(
len
(
user_asset_search
)),
user_asset_search
))
print
'
\033
[32m[
%-3
s]
%-15
s
%-15
s
%-5
s
%-10
s
%
s
\033
[0m'
%
(
'ID'
,
'AssetName'
,
'IP'
,
'Port'
,
'Role'
,
'Comment'
)
print
'
\033
[32m[
%-3
s]
%-15
s
%-15
s
%-5
s
%-10
s
%
s
\033
[0m'
%
(
'ID'
,
'AssetName'
,
'IP'
,
'Port'
,
'Role'
,
'Comment'
)
for
index
,
asset
in
self
.
search_result
.
items
():
for
index
,
asset
in
self
.
search_result
.
items
():
# 获取该资产信息
asset_info
=
get_asset_info
(
asset
)
asset_info
=
get_asset_info
(
asset
)
# 获取该资产包含的角色
role
=
[
str
(
role
.
name
)
for
role
in
self
.
user_perm
.
get
(
'asset'
)
.
get
(
asset
)
.
get
(
'role'
)]
role
=
[
str
(
role
.
name
)
for
role
in
self
.
user_perm
.
get
(
'asset'
)
.
get
(
asset
)
.
get
(
'role'
)]
if
asset
.
comment
:
if
asset
.
comment
:
print
'[
%-3
s]
%-15
s
%-15
s
%-5
s
%-10
s
%
s'
%
(
index
,
asset
.
hostname
,
asset
.
ip
,
asset_info
.
get
(
'port'
),
print
'[
%-3
s]
%-15
s
%-15
s
%-5
s
%-10
s
%
s'
%
(
index
,
asset
.
hostname
,
asset
.
ip
,
asset_info
.
get
(
'port'
),
...
@@ -491,9 +478,11 @@ class Nav(object):
...
@@ -491,9 +478,11 @@ class Nav(object):
print
'[
%-3
s]
%-15
s
%-15
s
%-5
s
%-10
s'
%
(
index
,
asset
.
hostname
,
asset
.
ip
,
asset_info
.
get
(
'port'
),
role
)
print
'[
%-3
s]
%-15
s
%-15
s
%-5
s
%-10
s'
%
(
index
,
asset
.
hostname
,
asset
.
ip
,
asset_info
.
get
(
'port'
),
role
)
print
print
@staticmethod
def
print_asset_group
(
self
):
def
print_asset_group
():
"""
user_asset_group_all
=
AssetGroup
.
objects
.
all
()
打印用户授权的资产组
"""
user_asset_group_all
=
get_group_user_perm
(
self
.
user
)
.
get
(
'asset_group'
,
[])
print
'
\033
[32m[
%-3
s]
%-15
s
%
s
\033
[0m'
%
(
'ID'
,
'GroupName'
,
'Comment'
)
print
'
\033
[32m[
%-3
s]
%-15
s
%
s
\033
[0m'
%
(
'ID'
,
'GroupName'
,
'Comment'
)
for
asset_group
in
user_asset_group_all
:
for
asset_group
in
user_asset_group_all
:
...
@@ -504,6 +493,9 @@ class Nav(object):
...
@@ -504,6 +493,9 @@ class Nav(object):
print
print
def
exec_cmd
(
self
):
def
exec_cmd
(
self
):
"""
批量执行命令
"""
self
.
search
()
self
.
search
()
while
True
:
while
True
:
print
"请输入主机名、IP或ansile支持的pattern, q退出"
print
"请输入主机名、IP或ansile支持的pattern, q退出"
...
...
jasset/ansible_api.py
deleted
100644 → 0
View file @
c89d43d2
# -*- coding: utf-8 -*-
from
ansible.inventory.group
import
Group
from
ansible.inventory.host
import
Host
from
ansible.inventory
import
Inventory
from
ansible.runner
import
Runner
from
ansible.playbook
import
PlayBook
from
ansible
import
callbacks
from
ansible
import
utils
from
passlib.hash
import
sha512_crypt
# from utils import get_rand_pass
import
random
import
os.path
API_DIR
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
ANSIBLE_DIR
=
os
.
path
.
join
(
API_DIR
,
'playbooks'
)
def
get_rand_pass
():
"""
get a reandom password.
"""
lower
=
[
chr
(
i
)
for
i
in
range
(
97
,
123
)]
upper
=
[
chr
(
i
)
.
upper
()
for
i
in
range
(
97
,
123
)]
digit
=
[
str
(
i
)
for
i
in
range
(
10
)]
password_pool
=
[]
password_pool
.
extend
(
lower
)
password_pool
.
extend
(
upper
)
password_pool
.
extend
(
digit
)
pass_list
=
[
random
.
choice
(
password_pool
)
for
i
in
range
(
1
,
14
)]
pass_list
.
insert
(
random
.
choice
(
range
(
1
,
14
)),
'@'
)
pass_list
.
insert
(
random
.
choice
(
range
(
1
,
14
)),
random
.
choice
(
digit
))
password
=
''
.
join
(
pass_list
)
return
password
class
AnsibleError
(
StandardError
):
"""
the base AnsibleError which contains error(required),
data(optional) and message(optional).
存储所有Ansible 异常对象
"""
def
__init__
(
self
,
error
,
data
=
''
,
message
=
''
):
super
(
AnsibleError
,
self
)
.
__init__
(
message
)
self
.
error
=
error
self
.
data
=
data
self
.
message
=
message
class
CommandValueError
(
AnsibleError
):
"""
indicate the input value has error or invalid.
the data specifies the error field of input form.
输入不合法 异常对象
"""
def
__init__
(
self
,
field
,
message
=
''
):
super
(
CommandValueError
,
self
)
.
__init__
(
'value:invalid'
,
field
,
message
)
class
MyInventory
(
object
):
"""
this is my ansible inventory object.
"""
def
__init__
(
self
,
resource
):
"""
resource的数据格式是一个列表字典,比如
{
"group1": {
"hosts": [{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...],
"vars": {"var1": value1, "var2": value2, ...}
}
}
如果你只传入1个列表,这默认该列表内的所有主机属于my_group组,比如
[{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...]
"""
self
.
resource
=
resource
self
.
inventory
=
Inventory
()
self
.
gen_inventory
()
def
add_group
(
self
,
hosts
,
groupname
,
groupvars
=
None
):
"""
add hosts to a group
"""
my_group
=
Group
(
name
=
groupname
)
# if group variables exists, add them to group
if
groupvars
:
for
key
,
value
in
groupvars
.
iteritems
():
my_group
.
set_variable
(
key
,
value
)
# add hosts to group
for
host
in
hosts
:
# set connection variables
hostname
=
host
.
get
(
"hostname"
)
hostport
=
host
.
get
(
"port"
)
username
=
host
.
get
(
"username"
)
password
=
host
.
get
(
"password"
)
my_host
=
Host
(
name
=
hostname
,
port
=
hostport
)
my_host
.
set_variable
(
'ansible_ssh_host'
,
hostname
)
my_host
.
set_variable
(
'ansible_ssh_port'
,
hostport
)
my_host
.
set_variable
(
'ansible_ssh_user'
,
username
)
my_host
.
set_variable
(
'ansible_ssh_pass'
,
password
)
# set other variables
for
key
,
value
in
host
.
iteritems
():
if
key
not
in
[
"hostname"
,
"port"
,
"username"
,
"password"
]:
my_host
.
set_variable
(
key
,
value
)
# add to group
my_group
.
add_host
(
my_host
)
self
.
inventory
.
add_group
(
my_group
)
def
gen_inventory
(
self
):
"""
add hosts to inventory.
"""
if
isinstance
(
self
.
resource
,
list
):
self
.
add_group
(
self
.
resource
,
'my_group'
)
elif
isinstance
(
self
.
resource
,
dict
):
for
groupname
,
hosts_and_vars
in
self
.
resource
.
iteritems
():
self
.
add_group
(
hosts_and_vars
.
get
(
"hosts"
),
groupname
,
hosts_and_vars
.
get
(
"vars"
))
class
Command
(
MyInventory
):
"""
this is a command object for parallel execute command.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Command
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
results
=
''
def
run
(
self
,
command
,
module_name
=
"command"
,
timeout
=
5
,
forks
=
10
,
group
=
'my_group'
):
"""
run command from andible ad-hoc.
command : 必须是一个需要执行的命令字符串, 比如
'uname -a'
"""
if
module_name
not
in
[
"raw"
,
"command"
,
"shell"
]:
raise
CommandValueError
(
"module_name"
,
"module_name must be of the 'raw, command, shell'"
)
hoc
=
Runner
(
module_name
=
module_name
,
module_args
=
command
,
timeout
=
timeout
,
inventory
=
self
.
inventory
,
subset
=
group
,
forks
=
forks
)
self
.
results
=
hoc
.
run
()
if
self
.
stdout
:
return
{
"ok"
:
self
.
stdout
}
else
:
msg
=
[]
if
self
.
stderr
:
msg
.
append
(
self
.
stderr
)
if
self
.
dark
:
msg
.
append
(
self
.
dark
)
return
{
"failed"
:
msg
}
@property
def
raw_results
(
self
):
"""
get the ansible raw results.
"""
return
self
.
results
@property
def
exec_time
(
self
):
"""
get the command execute time.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
{
"start"
:
value
.
get
(
"start"
),
"end"
:
value
.
get
(
"end"
),
"delta"
:
value
.
get
(
"delta"
),}
return
result
@property
def
stdout
(
self
):
"""
get the comamnd standard output.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
value
.
get
(
"stdout"
)
return
result
@property
def
stderr
(
self
):
"""
get the command standard error.
"""
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
{
"stderr"
:
value
.
get
(
"stderr"
),
"warnings"
:
value
.
get
(
"warnings"
),}
return
result
@property
def
dark
(
self
):
"""
get the dark results.
"""
return
self
.
results
.
get
(
"dark"
)
class
Tasks
(
Command
):
"""
this is a tasks object for include the common command.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Tasks
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
__run
(
self
,
module_args
,
module_name
=
"command"
,
timeout
=
5
,
forks
=
10
,
group
=
'my_group'
):
"""
run command from andible ad-hoc.
command : 必须是一个需要执行的命令字符串, 比如
'uname -a'
"""
hoc
=
Runner
(
module_name
=
module_name
,
module_args
=
module_args
,
timeout
=
timeout
,
inventory
=
self
.
inventory
,
subset
=
group
,
forks
=
forks
)
self
.
results
=
hoc
.
run
()
@property
def
msg
(
self
):
"""
get the contacted and dark msg
"""
msg
=
{}
for
result
in
[
"contacted"
,
"dark"
]:
all
=
self
.
results
.
get
(
result
)
for
key
,
value
in
all
.
iteritems
():
if
value
.
get
(
"msg"
):
msg
[
key
]
=
value
.
get
(
"msg"
)
return
msg
def
push_key
(
self
,
user
,
key_path
):
"""
push the ssh authorized key to target.
"""
module_args
=
'user="
%
s" key="{{ lookup("file", "
%
s") }}"'
%
(
user
,
key_path
)
self
.
__run
(
module_args
,
"authorized_key"
)
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
}
def
del_key
(
self
,
user
,
key_path
):
"""
push the ssh authorized key to target.
"""
module_args
=
'user="
%
s" key="{{ lookup("file", "
%
s") }}" state="absent"'
%
(
user
,
key_path
)
self
.
__run
(
module_args
,
"authorized_key"
)
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
}
def
add_user
(
self
,
username
,
password
):
"""
add a host user.
"""
encrypt_pass
=
sha512_crypt
.
encrypt
(
password
)
module_args
=
'name=
%
s shell=/bin/bash password=
%
s'
%
(
username
,
encrypt_pass
)
self
.
__run
(
module_args
,
"user"
)
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
}
def
add_multi_user
(
self
,
*
args
):
"""
add multi user
:param args:
user
:return:
"""
results
=
{}
users
=
{}
action
=
results
[
"action_info"
]
=
{}
for
user
in
args
:
users
[
user
]
=
get_rand_pass
()
for
user
,
password
in
users
.
iteritems
():
ret
=
self
.
add_user
(
user
,
password
)
action
[
user
]
=
ret
results
[
"user_info"
]
=
users
return
results
def
del_user
(
self
,
username
):
"""
delete a host user.
"""
module_args
=
'name=
%
s state=absent remove=yes move_home=yes force=yes'
%
(
username
)
self
.
__run
(
module_args
,
"user"
)
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
}
def
add_init_users
(
self
):
"""
add initail users: SA, DBA, DEV
"""
results
=
{}
action
=
results
[
"action_info"
]
=
{}
users
=
{
"SA"
:
get_rand_pass
(),
"DBA"
:
get_rand_pass
(),
"DEV"
:
get_rand_pass
()}
for
user
,
password
in
users
.
iteritems
():
ret
=
self
.
add_user
(
user
,
password
)
action
[
user
]
=
ret
results
[
"user_info"
]
=
users
return
results
def
del_init_users
(
self
):
"""
delete initail users: SA, DBA, DEV
"""
results
=
{}
action
=
results
[
"action_info"
]
=
{}
for
user
in
[
"SA"
,
"DBA"
,
"DEV"
]:
ret
=
self
.
del_user
(
user
)
action
[
user
]
=
ret
return
results
def
get_host_info
(
self
):
"""
use the setup module get host informations
:return:
all_ip is list
processor_count is int
system_dist_version is string
system_type is string
disk is dict (device_name: device_size}
system_dist is string
processor_type is string
default_ip is string
hostname is string
product_sn is string
memory_total is int (MB)
default_mac is string
product_name is string
"""
self
.
__run
(
''
,
'setup'
)
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
setup
=
value
.
get
(
"ansible_facts"
)
# get disk informations
disk_all
=
setup
.
get
(
"ansible_devices"
)
disk_need
=
{}
for
disk_name
,
disk_info
in
disk_all
.
iteritems
():
if
disk_name
.
startswith
(
'sd'
)
or
disk_name
.
startswith
(
'hd'
)
or
disk_name
.
startswith
(
'vd'
):
disk_need
[
disk_name
]
=
disk_info
.
get
(
"size"
)
result
[
key
]
=
{
"other_ip"
:
setup
.
get
(
"ansible_all_ipv4_addresses"
),
"hostname"
:
setup
.
get
(
"ansible_hostname"
),
"ip"
:
setup
.
get
(
"ansible_default_ipv4"
)
.
get
(
"address"
),
"mac"
:
setup
.
get
(
"ansible_default_ipv4"
)
.
get
(
"macaddress"
),
"brand"
:
setup
.
get
(
"ansible_product_name"
),
"cpu_type"
:
setup
.
get
(
"ansible_processor"
),
"cpu_cores"
:
setup
.
get
(
"ansible_processor_count"
),
"memory"
:
setup
.
get
(
"ansible_memtotal_mb"
),
"disk"
:
disk_need
,
"system_type"
:
setup
.
get
(
"ansible_distribution"
),
"system_version"
:
setup
.
get
(
"ansible_distribution_version"
),
"asset_type"
:
setup
.
get
(
"ansible_system"
),
"sn"
:
setup
.
get
(
"ansible_product_serial"
)
}
return
{
"status"
:
"failed"
,
"msg"
:
self
.
msg
}
if
self
.
msg
else
{
"status"
:
"ok"
,
"result"
:
result
}
class
CustomAggregateStats
(
callbacks
.
AggregateStats
):
"""
Holds stats about per-host activity during playbook runs.
"""
def
__init__
(
self
):
super
(
CustomAggregateStats
,
self
)
.
__init__
()
self
.
results
=
[]
def
compute
(
self
,
runner_results
,
setup
=
False
,
poll
=
False
,
ignore_errors
=
False
):
"""
Walk through all results and increment stats.
"""
super
(
CustomAggregateStats
,
self
)
.
compute
(
runner_results
,
setup
,
poll
,
ignore_errors
)
self
.
results
.
append
(
runner_results
)
def
summarize
(
self
,
host
):
"""
Return information about a particular host
"""
summarized_info
=
super
(
CustomAggregateStats
,
self
)
.
summarize
(
host
)
# Adding the info I need
summarized_info
[
'result'
]
=
self
.
results
return
summarized_info
class
MyPlaybook
(
MyInventory
):
"""
this is my playbook object for execute playbook.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
MyPlaybook
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
run
(
self
,
playbook_relational_path
,
extra_vars
=
None
):
"""
run ansible playbook,
only surport relational path.
"""
stats
=
callbacks
.
AggregateStats
()
playbook_cb
=
callbacks
.
PlaybookCallbacks
(
verbose
=
utils
.
VERBOSITY
)
runner_cb
=
callbacks
.
PlaybookRunnerCallbacks
(
stats
,
verbose
=
utils
.
VERBOSITY
)
playbook_path
=
os
.
path
.
join
(
ANSIBLE_DIR
,
playbook_relational_path
)
pb
=
PlayBook
(
playbook
=
playbook_path
,
stats
=
stats
,
callbacks
=
playbook_cb
,
runner_callbacks
=
runner_cb
,
inventory
=
self
.
inventory
,
extra_vars
=
extra_vars
,
check
=
False
)
self
.
results
=
pb
.
run
()
@property
def
raw_results
(
self
):
"""
get the raw results after playbook run.
"""
return
self
.
results
class
App
(
MyPlaybook
):
"""
this is a app object for inclue the common playbook.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
App
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
if
__name__
==
"__main__"
:
pass
jasset/asset_api.py
View file @
175f2702
...
@@ -4,6 +4,8 @@ import xlsxwriter
...
@@ -4,6 +4,8 @@ import xlsxwriter
from
django.db.models
import
AutoField
from
django.db.models
import
AutoField
from
jumpserver.api
import
*
from
jumpserver.api
import
*
from
jasset.models
import
ASSET_STATUS
,
ASSET_TYPE
,
ASSET_ENV
,
IDC
,
AssetRecord
from
jasset.models
import
ASSET_STATUS
,
ASSET_TYPE
,
ASSET_ENV
,
IDC
,
AssetRecord
from
jperm.ansible_api
import
MyRunner
from
jperm.perm_api
import
gen_resource
def
group_add_asset
(
group
,
asset_id
=
None
,
asset_ip
=
None
):
def
group_add_asset
(
group
,
asset_id
=
None
,
asset_ip
=
None
):
...
@@ -359,7 +361,6 @@ def ansible_record(asset, ansible_dic, username):
...
@@ -359,7 +361,6 @@ def ansible_record(asset, ansible_dic, username):
old
=
asset_dic
.
get
(
field
)
old
=
asset_dic
.
get
(
field
)
new
=
ansible_dic
.
get
(
field
)
new
=
ansible_dic
.
get
(
field
)
if
unicode
(
old
)
!=
unicode
(
new
):
if
unicode
(
old
)
!=
unicode
(
new
):
print
old
,
new
,
type
(
old
),
type
(
new
)
setattr
(
asset
,
field
,
value
)
setattr
(
asset
,
field
,
value
)
asset
.
save
()
asset
.
save
()
alert_dic
[
field
]
=
[
old
,
new
]
alert_dic
[
field
]
=
[
old
,
new
]
...
@@ -384,16 +385,17 @@ def excel_to_db(excel_file):
...
@@ -384,16 +385,17 @@ def excel_to_db(excel_file):
row
=
table
.
row_values
(
row_num
)
row
=
table
.
row_values
(
row_num
)
if
row
:
if
row
:
ip
,
port
,
hostname
,
use_default_auth
,
username
,
password
,
group
=
row
ip
,
port
,
hostname
,
use_default_auth
,
username
,
password
,
group
=
row
use_default_auth
=
1
if
use_default_auth
==
u'默认'
else
0
if
get_object
(
Asset
,
hostname
=
hostname
):
if
get_object
(
Asset
,
hostname
=
hostname
):
continue
continue
use_default_auth
=
1
if
use_default_auth
==
u'默认'
else
0
password_encode
=
CRYPTOR
.
encrypt
(
password
)
if
password
else
''
if
hostname
:
if
hostname
:
asset
=
Asset
(
ip
=
ip
,
asset
=
Asset
(
ip
=
ip
,
port
=
port
,
port
=
port
,
hostname
=
hostname
,
hostname
=
hostname
,
use_default_auth
=
use_default_auth
,
use_default_auth
=
use_default_auth
,
username
=
username
,
username
=
username
,
password
=
password
password
=
password
_encode
)
)
asset
.
save
()
asset
.
save
()
group_list
=
group
.
split
(
'/'
)
group_list
=
group
.
split
(
'/'
)
...
@@ -406,3 +408,64 @@ def excel_to_db(excel_file):
...
@@ -406,3 +408,64 @@ def excel_to_db(excel_file):
asset
.
group
=
group_instance
asset
.
group
=
group_instance
asset
.
save
()
asset
.
save
()
return
True
return
True
def
get_ansible_asset_info
(
asset_ip
,
setup_info
):
disk_all
=
setup_info
.
get
(
"ansible_devices"
)
disk_need
=
{}
for
disk_name
,
disk_info
in
disk_all
.
iteritems
():
if
disk_name
.
startswith
(
'sd'
)
or
disk_name
.
startswith
(
'hd'
)
or
disk_name
.
startswith
(
'vd'
):
disk_need
[
disk_name
]
=
disk_info
.
get
(
"size"
)
all_ip
=
setup_info
.
get
(
"ansible_all_ipv4_addresses"
)
other_ip_list
=
all_ip
.
remove
(
asset_ip
)
if
asset_ip
in
all_ip
else
[]
other_ip
=
','
.
join
(
other_ip_list
)
if
other_ip_list
else
''
# hostname = setup_info.get("ansible_hostname")
# ip = setup_info.get("ansible_default_ipv4").get("address")
mac
=
setup_info
.
get
(
"ansible_default_ipv4"
)
.
get
(
"macaddress"
)
brand
=
setup_info
.
get
(
"ansible_product_name"
)
cpu_type
=
setup_info
.
get
(
"ansible_processor"
)[
1
]
cpu_cores
=
setup_info
.
get
(
"ansible_processor_count"
)
cpu
=
cpu_type
+
' * '
+
unicode
(
cpu_cores
)
memory
=
setup_info
.
get
(
"ansible_memtotal_mb"
)
disk
=
disk_need
system_type
=
setup_info
.
get
(
"ansible_distribution"
)
system_version
=
setup_info
.
get
(
"ansible_distribution_version"
)
# asset_type = setup_info.get("ansible_system")
sn
=
setup_info
.
get
(
"ansible_product_serial"
)
asset_info
=
[
other_ip
,
mac
,
cpu
,
memory
,
disk
,
sn
,
system_type
,
system_version
,
brand
]
return
asset_info
def
asset_ansible_update
(
obj_list
,
name
=
''
):
resource
=
gen_resource
(
obj_list
)
ansible_instance
=
MyRunner
(
resource
)
ansible_asset_info
=
ansible_instance
.
run
(
module_name
=
'setup'
,
pattern
=
'*'
)
for
asset
in
obj_list
:
try
:
setup_info
=
ansible_asset_info
[
'contacted'
][
asset
.
hostname
][
'ansible_facts'
]
except
KeyError
:
continue
else
:
asset_info
=
get_ansible_asset_info
(
asset
.
ip
,
setup_info
)
other_ip
,
mac
,
cpu
,
memory
,
disk
,
sn
,
system_type
,
system_version
,
brand
=
asset_info
asset_dic
=
{
"other_ip"
:
other_ip
,
"mac"
:
mac
,
"cpu"
:
cpu
,
"memory"
:
memory
,
"disk"
:
disk
,
"sn"
:
sn
,
"system_type"
:
system_type
,
"system_version"
:
system_version
,
"brand"
:
brand
}
ansible_record
(
asset
,
asset_dic
,
name
)
def
asset_ansible_update_all
():
name
=
u'定时更新'
asset_all
=
Asset
.
objects
.
all
()
asset_ansible_update
(
asset_all
,
name
)
jasset/models.py
View file @
175f2702
...
@@ -57,7 +57,7 @@ class Asset(models.Model):
...
@@ -57,7 +57,7 @@ class Asset(models.Model):
"""
"""
asset modle
asset modle
"""
"""
ip
=
models
.
GenericIPAddressField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u"主机IP"
)
ip
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"主机IP"
)
other_ip
=
models
.
CharField
(
max_length
=
255
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"其他IP"
)
other_ip
=
models
.
CharField
(
max_length
=
255
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"其他IP"
)
hostname
=
models
.
CharField
(
unique
=
True
,
max_length
=
128
,
verbose_name
=
u"主机名"
)
hostname
=
models
.
CharField
(
unique
=
True
,
max_length
=
128
,
verbose_name
=
u"主机名"
)
port
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u"端口号"
)
port
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u"端口号"
)
...
@@ -73,7 +73,7 @@ class Asset(models.Model):
...
@@ -73,7 +73,7 @@ class Asset(models.Model):
memory
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'内存'
)
memory
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'内存'
)
disk
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'硬盘'
)
disk
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'硬盘'
)
system_type
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"系统类型"
)
system_type
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"系统类型"
)
system_version
=
models
.
CharField
(
max_length
=
8
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"版本号"
)
system_version
=
models
.
CharField
(
max_length
=
8
,
blank
=
True
,
null
=
True
,
verbose_name
=
u"
系统
版本号"
)
cabinet
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'机柜号'
)
cabinet
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'机柜号'
)
position
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u'机器位置'
)
position
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
verbose_name
=
u'机器位置'
)
number
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'资产编号'
)
number
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
null
=
True
,
verbose_name
=
u'资产编号'
)
...
...
jasset/urls.py
View file @
175f2702
...
@@ -11,6 +11,7 @@ urlpatterns = patterns('',
...
@@ -11,6 +11,7 @@ urlpatterns = patterns('',
url
(
r"^asset_detail/$"
,
asset_detail
),
url
(
r"^asset_detail/$"
,
asset_detail
),
url
(
r'^asset_edit/$'
,
asset_edit
),
url
(
r'^asset_edit/$'
,
asset_edit
),
url
(
r'^asset_update/$'
,
asset_update
),
url
(
r'^asset_update/$'
,
asset_update
),
url
(
r'^asset_update_batch/$'
,
asset_update_batch
),
# url(r'^search/$', host_search),
# url(r'^search/$', host_search),
# url(r"^show_all_ajax/$", show_all_ajax),
# url(r"^show_all_ajax/$", show_all_ajax),
url
(
r'^group_add/$'
,
group_add
),
url
(
r'^group_add/$'
,
group_add
),
...
...
jasset/views.py
View file @
175f2702
# coding:utf-8
# coding:utf-8
import
ast
from
django.db.models
import
Q
from
django.db.models
import
Q
from
jasset.asset_api
import
*
from
jasset.asset_api
import
*
from
jumpserver.api
import
*
from
jumpserver.api
import
*
from
jumpserver.models
import
Setting
from
jumpserver.models
import
Setting
from
jasset.forms
import
AssetForm
,
IdcForm
from
jasset.forms
import
AssetForm
,
IdcForm
from
jasset.models
import
Asset
,
IDC
,
AssetGroup
,
ASSET_TYPE
,
ASSET_STATUS
from
jasset.models
import
Asset
,
IDC
,
AssetGroup
,
ASSET_TYPE
,
ASSET_STATUS
from
ansible_api
import
Tasks
from
jperm.ansible_api
import
Tasks
,
MyRunner
from
jperm.perm_api
import
gen_resource
@require_role
(
'admin'
)
@require_role
(
'admin'
)
...
@@ -95,8 +95,6 @@ def group_list(request):
...
@@ -95,8 +95,6 @@ def group_list(request):
"""
"""
header_title
,
path1
,
path2
=
u'查看资产组'
,
u'资产管理'
,
u'查看资产组'
header_title
,
path1
,
path2
=
u'查看资产组'
,
u'资产管理'
,
u'查看资产组'
keyword
=
request
.
GET
.
get
(
'keyword'
,
''
)
keyword
=
request
.
GET
.
get
(
'keyword'
,
''
)
gid
=
request
.
GET
.
get
(
'gid'
)
sid
=
request
.
GET
.
get
(
'sid'
)
asset_group_list
=
AssetGroup
.
objects
.
all
()
asset_group_list
=
AssetGroup
.
objects
.
all
()
if
keyword
:
if
keyword
:
...
@@ -132,6 +130,7 @@ def asset_add(request):
...
@@ -132,6 +130,7 @@ def asset_add(request):
af
=
AssetForm
()
af
=
AssetForm
()
if
request
.
method
==
'POST'
:
if
request
.
method
==
'POST'
:
af_post
=
AssetForm
(
request
.
POST
)
af_post
=
AssetForm
(
request
.
POST
)
print
af_post
ip
=
request
.
POST
.
get
(
'ip'
,
''
)
ip
=
request
.
POST
.
get
(
'ip'
,
''
)
hostname
=
request
.
POST
.
get
(
'hostname'
,
''
)
hostname
=
request
.
POST
.
get
(
'hostname'
,
''
)
is_active
=
True
if
request
.
POST
.
get
(
'is_active'
)
==
'1'
else
False
is_active
=
True
if
request
.
POST
.
get
(
'is_active'
)
==
'1'
else
False
...
@@ -200,7 +199,7 @@ def asset_edit(request):
...
@@ -200,7 +199,7 @@ def asset_edit(request):
header_title
,
path1
,
path2
=
u'修改资产'
,
u'资产管理'
,
u'修改资产'
header_title
,
path1
,
path2
=
u'修改资产'
,
u'资产管理'
,
u'修改资产'
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
username
=
request
.
session
.
get
(
'username'
,
'admin'
)
username
=
request
.
user
.
username
asset
=
get_object
(
Asset
,
id
=
asset_id
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
if
asset
:
if
asset
:
password_old
=
asset
.
password
password_old
=
asset
.
password
...
@@ -211,13 +210,13 @@ def asset_edit(request):
...
@@ -211,13 +210,13 @@ def asset_edit(request):
ip
=
request
.
POST
.
get
(
'ip'
,
''
)
ip
=
request
.
POST
.
get
(
'ip'
,
''
)
hostname
=
request
.
POST
.
get
(
'hostname'
,
''
)
hostname
=
request
.
POST
.
get
(
'hostname'
,
''
)
password
=
request
.
POST
.
get
(
'password'
,
''
)
password
=
request
.
POST
.
get
(
'password'
,
''
)
is_active
=
True
if
request
.
POST
.
get
(
'is_active'
)
==
'1'
else
False
use_default_auth
=
request
.
POST
.
get
(
'use_default_auth'
,
''
)
use_default_auth
=
request
.
POST
.
get
(
'use_default_auth'
,
''
)
try
:
try
:
asset_test
=
get_object
(
Asset
,
hostname
=
hostname
)
asset_test
=
get_object
(
Asset
,
hostname
=
hostname
)
if
asset_test
and
asset_id
!=
unicode
(
asset_test
.
id
):
if
asset_test
and
asset_id
!=
unicode
(
asset_test
.
id
):
e
rror
=
u'该主机名
%
s 已存在!'
%
hostname
e
mg
=
u'该主机名
%
s 已存在!'
%
hostname
raise
ServerError
(
e
rror
)
raise
ServerError
(
e
mg
)
except
ServerError
:
except
ServerError
:
pass
pass
else
:
else
:
...
@@ -226,10 +225,12 @@ def asset_edit(request):
...
@@ -226,10 +225,12 @@ def asset_edit(request):
if
use_default_auth
:
if
use_default_auth
:
af_save
.
username
=
''
af_save
.
username
=
''
af_save
.
password
=
''
af_save
.
password
=
''
af_save
.
port
=
None
else
:
else
:
if
password_old
!=
password
:
if
password_old
!=
password
:
password_encode
=
CRYPTOR
.
encrypt
(
password
)
password_encode
=
CRYPTOR
.
encrypt
(
password
)
af_save
.
password
=
password_encode
af_save
.
password
=
password_encode
af_save
.
is_active
=
True
if
is_active
else
False
af_save
.
save
()
af_save
.
save
()
af_post
.
save_m2m
()
af_post
.
save_m2m
()
# asset_new = get_object(Asset, id=asset_id)
# asset_new = get_object(Asset, id=asset_id)
...
@@ -237,9 +238,10 @@ def asset_edit(request):
...
@@ -237,9 +238,10 @@ def asset_edit(request):
info
=
asset_diff
(
af_post
.
__dict__
.
get
(
'initial'
),
request
.
POST
)
info
=
asset_diff
(
af_post
.
__dict__
.
get
(
'initial'
),
request
.
POST
)
db_asset_alert
(
asset
,
username
,
info
)
db_asset_alert
(
asset
,
username
,
info
)
ms
g
=
u'主机
%
s 修改成功'
%
ip
sm
g
=
u'主机
%
s 修改成功'
%
ip
else
:
else
:
emg
=
u'主机
%
s 修改失败'
%
ip
emg
=
u'主机
%
s 修改失败'
%
ip
return
my_render
(
'jasset/error.html'
,
locals
(),
request
)
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
return
my_render
(
'jasset/asset_edit.html'
,
locals
(),
request
)
return
my_render
(
'jasset/asset_edit.html'
,
locals
(),
request
)
...
@@ -250,6 +252,7 @@ def asset_list(request):
...
@@ -250,6 +252,7 @@ def asset_list(request):
"""
"""
asset list view
asset list view
"""
"""
header_title
,
path1
,
path2
=
u'查看资产'
,
u'资产管理'
,
u'查看资产'
idc_all
=
IDC
.
objects
.
filter
()
idc_all
=
IDC
.
objects
.
filter
()
asset_group_all
=
AssetGroup
.
objects
.
all
()
asset_group_all
=
AssetGroup
.
objects
.
all
()
asset_types
=
ASSET_TYPE
asset_types
=
ASSET_TYPE
...
@@ -311,7 +314,7 @@ def asset_list(request):
...
@@ -311,7 +314,7 @@ def asset_list(request):
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
asset_edit_batch
(
request
):
def
asset_edit_batch
(
request
):
af
=
AssetForm
()
af
=
AssetForm
()
name
=
request
.
session
.
get
(
'username'
,
'admin'
)
name
=
request
.
user
.
username
asset_group_all
=
AssetGroup
.
objects
.
all
()
asset_group_all
=
AssetGroup
.
objects
.
all
()
if
request
.
method
==
'POST'
:
if
request
.
method
==
'POST'
:
...
@@ -382,9 +385,8 @@ def asset_edit_batch(request):
...
@@ -382,9 +385,8 @@ def asset_edit_batch(request):
asset
.
save
()
asset
.
save
()
if
alert_list
:
if
alert_list
:
username
=
unicode
(
name
)
+
' - '
+
u'批量'
recode_name
=
unicode
(
name
)
+
' - '
+
u'批量'
print
alert_list
AssetRecord
.
objects
.
create
(
asset
=
asset
,
username
=
recode_name
,
content
=
alert_list
)
AssetRecord
.
objects
.
create
(
asset
=
asset
,
username
=
username
,
content
=
alert_list
)
return
HttpResponse
(
'ok'
)
return
HttpResponse
(
'ok'
)
return
my_render
(
'jasset/asset_edit_batch.html'
,
locals
(),
request
)
return
my_render
(
'jasset/asset_edit_batch.html'
,
locals
(),
request
)
...
@@ -410,53 +412,34 @@ def asset_update(request):
...
@@ -410,53 +412,34 @@ def asset_update(request):
"""
"""
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
asset_id
=
request
.
GET
.
get
(
'id'
,
''
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
name
=
request
.
user
.
username
if
not
asset
:
if
not
asset
:
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
name
=
request
.
session
.
get
(
'username'
,
'admin'
)
if
asset
.
use_default_auth
:
default
=
Setting
.
objects
.
all
()
if
default
:
default
=
default
[
0
]
username
=
default
.
default_user
password
=
default
.
default_password
port
=
default
.
default_port
else
:
return
HttpResponse
(
u'没有设置默认用户名和密码!'
)
else
:
else
:
username
=
asset
.
username
asset_ansible_update
([
asset
],
name
)
password
=
asset
.
password
port
=
asset
.
port
resource
=
[{
"hostname"
:
asset
.
ip
,
"port"
:
port
,
"username"
:
username
,
"password"
:
password
}]
ansible_instance
=
Tasks
(
resource
)
ansible_asset_info
=
ansible_instance
.
get_host_info
()
if
ansible_asset_info
[
'status'
]
==
'ok'
:
asset_info
=
ansible_asset_info
[
'result'
][
asset
.
ip
]
if
asset_info
:
hostname
=
asset_info
.
get
(
'hostname'
)
other_ip
=
','
.
join
(
asset_info
.
get
(
'other_ip'
))
cpu_type
=
asset_info
.
get
(
'cpu_type'
)[
1
]
cpu_cores
=
asset_info
.
get
(
'cpu_cores'
)
cpu
=
cpu_type
+
' * '
+
unicode
(
cpu_cores
)
memory
=
asset_info
.
get
(
'memory'
)
disk
=
asset_info
.
get
(
'disk'
)
sn
=
asset_info
.
get
(
'sn'
)
brand
=
asset_info
.
get
(
'brand'
)
system_type
=
asset_info
.
get
(
'system_type'
)
system_version
=
asset_info
.
get
(
'system_version'
)
asset_dic
=
{
"hostname"
:
hostname
,
"other_ip"
:
other_ip
,
"cpu"
:
cpu
,
"memory"
:
memory
,
"disk"
:
disk
,
"system_type"
:
system_type
,
"system_version"
:
system_version
,
"brand"
:
brand
,
"sn"
:
sn
}
ansible_record
(
asset
,
asset_dic
,
name
)
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
return
HttpResponseRedirect
(
'/jasset/asset_detail/?id=
%
s'
%
asset_id
)
@require_role
(
'admin'
)
def
asset_update_batch
(
request
):
if
request
.
method
==
'POST'
:
arg
=
request
.
GET
.
get
(
'arg'
,
''
)
name
=
unicode
(
request
.
user
.
username
)
+
' - '
+
u'自动更新'
if
arg
==
'all'
:
asset_list
=
Asset
.
objects
.
all
()
else
:
asset_list
=
[]
asset_id_all
=
unicode
(
request
.
POST
.
get
(
'asset_id_all'
,
''
))
asset_id_all
=
asset_id_all
.
split
(
','
)
for
asset_id
in
asset_id_all
:
asset
=
get_object
(
Asset
,
id
=
asset_id
)
if
asset
:
asset_list
.
append
(
asset
)
asset_ansible_update
(
asset_list
,
name
)
return
HttpResponse
(
u'批量更新成功!'
)
return
HttpResponse
(
u'批量更新成功!'
)
@require_role
(
'admin'
)
@require_role
(
'admin'
)
def
idc_add
(
request
):
def
idc_add
(
request
):
"""
"""
...
@@ -477,9 +460,7 @@ def idc_add(request):
...
@@ -477,9 +460,7 @@ def idc_add(request):
return
HttpResponseRedirect
(
"/jasset/idc_list/"
)
return
HttpResponseRedirect
(
"/jasset/idc_list/"
)
else
:
else
:
idc_form
=
IdcForm
()
idc_form
=
IdcForm
()
return
render_to_response
(
'jasset/idc_add.html'
,
return
my_render
(
'jasset/idc_add.html'
,
locals
(),
request
)
locals
(),
context_instance
=
RequestContext
(
request
))
@require_role
(
'admin'
)
@require_role
(
'admin'
)
...
@@ -495,9 +476,7 @@ def idc_list(request):
...
@@ -495,9 +476,7 @@ def idc_list(request):
else
:
else
:
posts
=
IDC
.
objects
.
exclude
(
name
=
'ALL'
)
.
order_by
(
'id'
)
posts
=
IDC
.
objects
.
exclude
(
name
=
'ALL'
)
.
order_by
(
'id'
)
contact_list
,
p
,
contacts
,
page_range
,
current_page
,
show_first
,
show_end
=
pages
(
posts
,
request
)
contact_list
,
p
,
contacts
,
page_range
,
current_page
,
show_first
,
show_end
=
pages
(
posts
,
request
)
return
render_to_response
(
'jasset/idc_list.html'
,
return
my_render
(
'jasset/idc_list.html'
,
locals
(),
request
)
locals
(),
context_instance
=
RequestContext
(
request
))
@require_role
(
'admin'
)
@require_role
(
'admin'
)
...
...
jlog/urls.py
View file @
175f2702
...
@@ -9,4 +9,5 @@ urlpatterns = patterns('',
...
@@ -9,4 +9,5 @@ urlpatterns = patterns('',
url
(
r'^log_kill/'
,
log_kill
),
url
(
r'^log_kill/'
,
log_kill
),
url
(
r'^record/$'
,
log_record
),
url
(
r'^record/$'
,
log_record
),
url
(
r'^web_terminal/$'
,
web_terminal
),
url
(
r'^web_terminal/$'
,
web_terminal
),
url
(
r'^get_role_name/$'
,
get_role_name
),
)
)
\ No newline at end of file
jlog/views.py
View file @
175f2702
...
@@ -4,6 +4,7 @@ from django.template import RequestContext
...
@@ -4,6 +4,7 @@ from django.template import RequestContext
from
django.shortcuts
import
render_to_response
from
django.shortcuts
import
render_to_response
from
jumpserver.api
import
*
from
jumpserver.api
import
*
from
jperm.perm_api
import
user_have_perm
from
django.http
import
HttpResponseNotFound
from
django.http
import
HttpResponseNotFound
from
jlog.log_api
import
renderTemplate
from
jlog.log_api
import
renderTemplate
...
@@ -50,6 +51,7 @@ def log_list(request, offset):
...
@@ -50,6 +51,7 @@ def log_list(request, offset):
web_monitor_uri
=
'ws://
%
s/monitor'
%
WEB_SOCKET_HOST
web_monitor_uri
=
'ws://
%
s/monitor'
%
WEB_SOCKET_HOST
web_kill_uri
=
'http://
%
s/kill'
%
WEB_SOCKET_HOST
web_kill_uri
=
'http://
%
s/kill'
%
WEB_SOCKET_HOST
session_id
=
request
.
session
.
session_key
return
render_to_response
(
'jlog/log_
%
s.html'
%
offset
,
locals
(),
context_instance
=
RequestContext
(
request
))
return
render_to_response
(
'jlog/log_
%
s.html'
%
offset
,
locals
(),
context_instance
=
RequestContext
(
request
))
...
@@ -103,11 +105,20 @@ def log_record(request):
...
@@ -103,11 +105,20 @@ def log_record(request):
return
HttpResponse
(
'无日志记录!'
)
return
HttpResponse
(
'无日志记录!'
)
@require_role
(
'user'
)
def
get_role_name
(
request
):
asset_id
=
request
.
GET
.
get
(
'id'
,
9999
)
asset
=
get_object
(
Asset
,
id
=
asset_id
)
if
asset
:
role
=
user_have_perm
(
request
.
user
,
asset
=
asset
)
return
HttpResponse
(
','
.
join
([
i
.
name
for
i
in
role
]))
return
HttpResponse
(
'error'
)
@require_role
(
'user'
)
def
web_terminal
(
request
):
def
web_terminal
(
request
):
#username = get_session.get('username', '')
asset_id
=
request
.
GET
.
get
(
'id'
)
token
=
request
.
COOKIES
.
get
(
'sessionid'
)
role_name
=
request
.
GET
.
get
(
'role'
)
username
=
request
.
user
.
username
web_terminal_uri
=
'ws://
%
s/terminal?id=
%
s&role=
%
s'
%
(
WEB_SOCKET_HOST
,
asset_id
,
role_name
)
asset_name
=
'127.0.0.1'
web_terminal_uri
=
'ws://
%
s/terminal?username=
%
s&asset_name=
%
s&token=
%
s'
%
(
WEB_SOCKET_HOST
,
username
,
asset_name
,
token
)
return
render_to_response
(
'jlog/web_terminal.html'
,
locals
())
return
render_to_response
(
'jlog/web_terminal.html'
,
locals
())
jperm/perm_api.py
View file @
175f2702
...
@@ -132,6 +132,15 @@ def get_group_asset_perm(ob):
...
@@ -132,6 +132,15 @@ def get_group_asset_perm(ob):
return
perm
return
perm
def
user_have_perm
(
user
,
asset
):
user_perm_all
=
get_group_user_perm
(
user
)
user_assets
=
user_perm_all
.
get
(
'asset'
)
.
keys
()
if
asset
in
user_assets
:
return
user_perm_all
.
get
(
'asset'
)
.
get
(
asset
)
.
get
(
'role'
)
else
:
return
[]
def
gen_resource
(
ob
,
ex
=
''
,
perm
=
None
):
def
gen_resource
(
ob
,
ex
=
''
,
perm
=
None
):
"""
"""
ob为用户或资产列表或资产queryset, 如果同时输入用户和资产,则获取用户在这些资产上的信息
ob为用户或资产列表或资产queryset, 如果同时输入用户和资产,则获取用户在这些资产上的信息
...
...
jperm/utils.py
View file @
175f2702
...
@@ -46,7 +46,7 @@ def gen_keys():
...
@@ -46,7 +46,7 @@ def gen_keys():
"""
"""
key_basename
=
"key-"
+
uuid4
()
.
hex
key_basename
=
"key-"
+
uuid4
()
.
hex
key_path_dir
=
os
.
path
.
join
(
KEY_DIR
,
'role_key'
,
key_basename
)
key_path_dir
=
os
.
path
.
join
(
KEY_DIR
,
'role_key'
,
key_basename
)
mkdir
(
key_path_dir
,
0755
)
mkdir
(
key_path_dir
,
mode
=
0755
)
key
=
RSAKey
.
generate
(
2048
)
key
=
RSAKey
.
generate
(
2048
)
private_key
=
os
.
path
.
join
(
key_path_dir
,
'id_rsa'
)
private_key
=
os
.
path
.
join
(
key_path_dir
,
'id_rsa'
)
public_key
=
os
.
path
.
join
(
key_path_dir
,
'id_rsa.pub'
)
public_key
=
os
.
path
.
join
(
key_path_dir
,
'id_rsa.pub'
)
...
...
jumpserver.conf
View file @
175f2702
...
@@ -13,7 +13,7 @@ password = mysql234
...
@@ -13,7 +13,7 @@ password = mysql234
database
=
jumpserver
database
=
jumpserver
[
websocket
]
[
websocket
]
web_socket_host
=
j
:
3000
web_socket_host
=
j
s
:
3000
[
mail
]
[
mail
]
mail_enable
=
1
mail_enable
=
1
...
...
jumpserver/api.py
View file @
175f2702
...
@@ -54,12 +54,15 @@ def get_asset_info(asset):
...
@@ -54,12 +54,15 @@ def get_asset_info(asset):
if
default
:
if
default
:
info
[
'port'
]
=
default
.
default_port
info
[
'port'
]
=
default
.
default_port
info
[
'username'
]
=
default
.
default_user
info
[
'username'
]
=
default
.
default_user
info
[
'password'
]
=
CRYPTOR
.
decrypt
(
default
.
default_password
)
try
:
info
[
'password'
]
=
CRYPTOR
.
decrypt
(
default
.
default_password
)
except
ServerError
:
pass
info
[
'ssh_key'
]
=
default
.
default_pri_key_path
info
[
'ssh_key'
]
=
default
.
default_pri_key_path
else
:
else
:
info
[
'port'
]
=
asset
.
port
info
[
'port'
]
=
asset
.
port
info
[
'username'
]
=
asset
.
username
info
[
'username'
]
=
asset
.
username
info
[
'password'
]
=
asset
.
password
info
[
'password'
]
=
CRYPTOR
.
decrypt
(
asset
.
password
)
return
info
return
info
...
...
jumpserver/context_processors.py
View file @
175f2702
...
@@ -5,16 +5,12 @@ from jumpserver.api import *
...
@@ -5,16 +5,12 @@ from jumpserver.api import *
def
name_proc
(
request
):
def
name_proc
(
request
):
user_id
=
request
.
user
.
id
user_id
=
request
.
user
.
id
# role_id = request.session.get('role_id')
role_id
=
{
'SU'
:
2
,
'GA'
:
1
,
'CU'
:
0
}
.
get
(
request
.
user
.
role
,
0
)
role_id
=
{
'SU'
:
2
,
'GA'
:
1
,
'CU'
:
0
}
.
get
(
request
.
user
.
role
,
0
)
# role_id = 'SU'
# if role_id == 2:
user_total_num
=
User
.
objects
.
all
()
.
count
()
user_total_num
=
User
.
objects
.
all
()
.
count
()
user_active_num
=
User
.
objects
.
filter
()
.
count
()
user_active_num
=
User
.
objects
.
filter
()
.
count
()
host_total_num
=
Asset
.
objects
.
all
()
.
count
()
host_total_num
=
Asset
.
objects
.
all
()
.
count
()
host_active_num
=
Asset
.
objects
.
filter
(
is_active
=
True
)
.
count
()
host_active_num
=
Asset
.
objects
.
filter
(
is_active
=
True
)
.
count
()
# else:
# pass
request
.
session
.
set_expiry
(
3600
)
request
.
session
.
set_expiry
(
3600
)
info_dic
=
{
'session_user_id'
:
user_id
,
info_dic
=
{
'session_user_id'
:
user_id
,
...
...
jumpserver/settings.py
View file @
175f2702
...
@@ -66,6 +66,7 @@ INSTALLED_APPS = (
...
@@ -66,6 +66,7 @@ INSTALLED_APPS = (
'django.contrib.messages'
,
'django.contrib.messages'
,
'django.contrib.staticfiles'
,
'django.contrib.staticfiles'
,
'django.contrib.humanize'
,
'django.contrib.humanize'
,
'django_crontab'
,
'bootstrapform'
,
'bootstrapform'
,
'jumpserver'
,
'jumpserver'
,
'juser'
,
'juser'
,
...
@@ -149,3 +150,7 @@ USE_TZ = False
...
@@ -149,3 +150,7 @@ USE_TZ = False
STATIC_URL
=
'/static/'
STATIC_URL
=
'/static/'
BOOTSTRAP_COLUMN_COUNT
=
10
BOOTSTRAP_COLUMN_COUNT
=
10
CRONJOBS
=
[
(
'0 1 * * *'
,
'jasset.asset_api.asset_ansible_update_all'
)
]
jumpserver/templatetags/mytags.py
View file @
175f2702
...
@@ -209,7 +209,11 @@ def str_to_dic(info):
...
@@ -209,7 +209,11 @@ def str_to_dic(info):
"""
"""
str to list
str to list
"""
"""
return
ast
.
literal_eval
(
info
)
.
iteritems
()
if
'{'
in
info
:
info_dic
=
ast
.
literal_eval
(
info
)
.
iteritems
()
else
:
info_dic
=
{}
return
info_dic
@register.filter
(
name
=
'str_to_code'
)
@register.filter
(
name
=
'str_to_code'
)
...
@@ -237,3 +241,12 @@ def key_exist(username):
...
@@ -237,3 +241,12 @@ def key_exist(username):
return
True
return
True
else
:
else
:
return
False
return
False
@register.filter
(
name
=
'check_role'
)
def
check_role
(
asset_id
,
user
):
"""
ssh key is exist or not
"""
return
user
run_websocket.py
View file @
175f2702
...
@@ -7,6 +7,7 @@ import os
...
@@ -7,6 +7,7 @@ import os
import
sys
import
sys
import
os.path
import
os.path
import
threading
import
threading
import
datetime
import
urllib
import
urllib
import
tornado.ioloop
import
tornado.ioloop
...
@@ -20,16 +21,10 @@ from tornado.websocket import WebSocketClosedError
...
@@ -20,16 +21,10 @@ from tornado.websocket import WebSocketClosedError
from
tornado.options
import
define
,
options
from
tornado.options
import
define
,
options
from
pyinotify
import
WatchManager
,
Notifier
,
ProcessEvent
,
IN_DELETE
,
IN_CREATE
,
IN_MODIFY
,
AsyncNotifier
from
pyinotify
import
WatchManager
,
Notifier
,
ProcessEvent
,
IN_DELETE
,
IN_CREATE
,
IN_MODIFY
,
AsyncNotifier
import
select
# from gevent import monkey
from
connect
import
Tty
,
User
,
Asset
,
PermRole
,
logger
,
get_object
# monkey.patch_all()
from
connect
import
TtyLog
,
Log
,
Session
,
user_have_perm
# import gevent
# from gevent.socket import wait_read, wait_write
import
struct
,
fcntl
,
signal
,
socket
,
select
,
fnmatch
import
paramiko
from
connect
import
Tty
from
connect
import
TtyLog
,
Log
try
:
try
:
import
simplejson
as
json
import
simplejson
as
json
...
@@ -41,17 +36,54 @@ define("port", default=3000, help="run on the given port", type=int)
...
@@ -41,17 +36,54 @@ define("port", default=3000, help="run on the given port", type=int)
define
(
"host"
,
default
=
'0.0.0.0'
,
help
=
"run port on"
,
type
=
str
)
define
(
"host"
,
default
=
'0.0.0.0'
,
help
=
"run port on"
,
type
=
str
)
def
require_auth
(
func
):
def
require_auth
(
role
=
'user'
):
def
_deco
(
request
,
*
args
,
**
kwargs
):
def
_deco
(
func
):
username
=
request
.
get_argument
(
'username'
,
''
)
def
_deco2
(
request
,
*
args
,
**
kwargs
):
asset_name
=
request
.
get_argument
(
'asset_name'
,
''
)
if
request
.
get_cookie
(
'sessionid'
):
token
=
request
.
get_argument
(
'token'
,
''
)
session_key
=
request
.
get_cookie
(
'sessionid'
)
print
username
,
asset_name
,
token
else
:
client
=
tornado
.
httpclient
.
HTTPClient
()
session_key
=
request
.
get_argument
(
'sessionid'
,
''
)
# response = client.fetch('http://some/url') + urllib.urlencode({'username': username,
# 'asset_name': asset_name, 'token': token})
logger
.
debug
(
'Websocket: session_key:
%
s'
%
session_key
)
# return request.close()
if
session_key
:
return
func
(
request
,
*
args
,
**
kwargs
)
session
=
get_object
(
Session
,
session_key
=
session_key
)
logger
.
debug
(
'Websocket: session:
%
s'
%
session
)
if
session
and
datetime
.
datetime
.
now
()
<
session
.
expire_date
:
user_id
=
session
.
get_decoded
()
.
get
(
'_auth_user_id'
)
user
=
get_object
(
User
,
id
=
user_id
)
if
user
:
logger
.
debug
(
'Websocket: user [
%
s ] request websocket'
%
user
.
username
)
request
.
user
=
user
if
role
==
'admin'
:
if
user
.
role
in
[
'SU'
,
'GA'
]:
return
func
(
request
,
*
args
,
**
kwargs
)
logger
.
debug
(
'Websocket: user [
%
s ] is not admin.'
%
user
.
username
)
else
:
return
func
(
request
,
*
args
,
**
kwargs
)
else
:
logger
.
debug
(
'Websocket: session expired:
%
s'
%
session_key
)
try
:
request
.
close
()
except
AttributeError
:
pass
logger
.
warning
(
'Websocket: Request auth failed.'
)
# asset_id = int(request.get_argument('id', 9999))
# print asset_id
# asset = Asset.objects.filter(id=asset_id)
# if asset:
# asset = asset[0]
# request.asset = asset
# else:
# request.close()
#
# if user:
# user = user[0]
# request.user = user
#
# else:
# print("No session user.")
# request.close()
return
_deco2
return
_deco
return
_deco
...
@@ -70,14 +102,7 @@ class EventHandler(ProcessEvent):
...
@@ -70,14 +102,7 @@ class EventHandler(ProcessEvent):
def
__init__
(
self
,
client
=
None
):
def
__init__
(
self
,
client
=
None
):
self
.
client
=
client
self
.
client
=
client
def
process_IN_CREATE
(
self
,
event
):
print
"Create file:
%
s."
%
os
.
path
.
join
(
event
.
path
,
event
.
name
)
def
process_IN_DELETE
(
self
,
event
):
print
"Delete file:
%
s."
%
os
.
path
.
join
(
event
.
path
,
event
.
name
)
def
process_IN_MODIFY
(
self
,
event
):
def
process_IN_MODIFY
(
self
,
event
):
print
"Modify file:
%
s."
%
os
.
path
.
join
(
event
.
path
,
event
.
name
)
self
.
client
.
write_message
(
f
.
read
())
self
.
client
.
write_message
(
f
.
read
())
...
@@ -87,10 +112,10 @@ def file_monitor(path='.', client=None):
...
@@ -87,10 +112,10 @@ def file_monitor(path='.', client=None):
notifier
=
AsyncNotifier
(
wm
,
EventHandler
(
client
))
notifier
=
AsyncNotifier
(
wm
,
EventHandler
(
client
))
wm
.
add_watch
(
path
,
mask
,
auto_add
=
True
,
rec
=
True
)
wm
.
add_watch
(
path
,
mask
,
auto_add
=
True
,
rec
=
True
)
if
not
os
.
path
.
isfile
(
path
):
if
not
os
.
path
.
isfile
(
path
):
print
"You should monitor a file"
logger
.
debug
(
"File
%
s does not exist."
%
path
)
sys
.
exit
(
3
)
sys
.
exit
(
3
)
else
:
else
:
print
"now starting monitor
%
s."
%
path
logger
.
debug
(
"Now starting monitor file
%
s."
%
path
)
global
f
global
f
f
=
open
(
path
,
'r'
)
f
=
open
(
path
,
'r'
)
st_size
=
os
.
stat
(
path
)[
6
]
st_size
=
os
.
stat
(
path
)[
6
]
...
@@ -136,7 +161,7 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
...
@@ -136,7 +161,7 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
def
check_origin
(
self
,
origin
):
def
check_origin
(
self
,
origin
):
return
True
return
True
@require_auth
@require_auth
(
'admin'
)
def
open
(
self
):
def
open
(
self
):
# 获取监控的path
# 获取监控的path
self
.
file_path
=
self
.
get_argument
(
'file_path'
,
''
)
self
.
file_path
=
self
.
get_argument
(
'file_path'
,
''
)
...
@@ -158,7 +183,8 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
...
@@ -158,7 +183,8 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
MonitorHandler
.
clients
.
remove
(
self
)
MonitorHandler
.
clients
.
remove
(
self
)
MonitorHandler
.
threads
.
remove
(
MonitorHandler
.
threads
[
client_index
])
MonitorHandler
.
threads
.
remove
(
MonitorHandler
.
threads
[
client_index
])
print
len
(
MonitorHandler
.
threads
),
len
(
MonitorHandler
.
clients
)
logger
.
debug
(
"Websocket: Monitor client num:
%
s, thread num:
%
s"
%
(
len
(
MonitorHandler
.
clients
),
len
(
MonitorHandler
.
threads
)))
def
on_message
(
self
,
message
):
def
on_message
(
self
,
message
):
# 监控日志,发生变动发向客户端
# 监控日志,发生变动发向客户端
...
@@ -168,10 +194,13 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
...
@@ -168,10 +194,13 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
# 客户端主动关闭
# 客户端主动关闭
# self.close()
# self.close()
print
"Close websocket."
logger
.
debug
(
"Websocket: Monitor client close request"
)
client_index
=
MonitorHandler
.
clients
.
index
(
self
)
try
:
MonitorHandler
.
clients
.
remove
(
self
)
client_index
=
MonitorHandler
.
clients
.
index
(
self
)
MonitorHandler
.
threads
.
remove
(
MonitorHandler
.
threads
[
client_index
])
MonitorHandler
.
clients
.
remove
(
self
)
MonitorHandler
.
threads
.
remove
(
MonitorHandler
.
threads
[
client_index
])
except
ValueError
:
pass
class
WebTty
(
Tty
):
class
WebTty
(
Tty
):
...
@@ -184,16 +213,16 @@ class WebTty(Tty):
...
@@ -184,16 +213,16 @@ class WebTty(Tty):
class
WebTerminalKillHandler
(
tornado
.
web
.
RequestHandler
):
class
WebTerminalKillHandler
(
tornado
.
web
.
RequestHandler
):
@require_auth
(
'admin'
)
def
get
(
self
):
def
get
(
self
):
ws_id
=
self
.
get_argument
(
'id'
)
ws_id
=
self
.
get_argument
(
'id'
)
Log
.
objects
.
filter
(
id
=
ws_id
)
.
update
(
is_finished
=
True
)
Log
.
objects
.
filter
(
id
=
ws_id
)
.
update
(
is_finished
=
True
)
for
ws
in
WebTerminalHandler
.
clients
:
for
ws
in
WebTerminalHandler
.
clients
:
print
ws
.
id
if
ws
.
id
==
int
(
ws_id
):
if
ws
.
id
==
int
(
ws_id
):
print
"killed"
logger
.
debug
(
"Kill log id
%
s"
%
ws_id
)
ws
.
log
.
save
()
ws
.
log
.
save
()
ws
.
close
()
ws
.
close
()
print
len
(
WebTerminalHandler
.
clients
)
logger
.
debug
(
'Websocket: web terminal client num:
%
s'
%
len
(
WebTerminalHandler
.
clients
)
)
class
WebTerminalHandler
(
tornado
.
websocket
.
WebSocketHandler
):
class
WebTerminalHandler
(
tornado
.
websocket
.
WebSocketHandler
):
...
@@ -206,18 +235,38 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
...
@@ -206,18 +235,38 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
self
.
log_time_f
=
None
self
.
log_time_f
=
None
self
.
log
=
None
self
.
log
=
None
self
.
id
=
0
self
.
id
=
0
self
.
user
=
None
super
(
WebTerminalHandler
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
super
(
WebTerminalHandler
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
check_origin
(
self
,
origin
):
def
check_origin
(
self
,
origin
):
return
True
return
True
@require_auth
@require_auth
(
'user'
)
def
open
(
self
):
def
open
(
self
):
asset_name
=
self
.
get_argument
(
'asset_name'
,
''
)
logger
.
debug
(
'Websocket: Open request'
)
username
=
self
.
get_argument
(
'username'
,
''
)
role_name
=
self
.
get_argument
(
'role'
,
'sb'
)
token
=
self
.
get_argument
(
'token'
,
''
)
asset_id
=
self
.
get_argument
(
'id'
,
9999
)
print
asset_name
,
username
,
token
asset
=
get_object
(
Asset
,
id
=
asset_id
)
self
.
term
=
WebTty
(
'a'
,
'b'
)
if
asset
:
roles
=
user_have_perm
(
self
.
user
,
asset
)
logger
.
debug
(
roles
)
login_role
=
''
for
role
in
roles
:
if
role
.
name
==
role_name
:
login_role
=
role
break
if
not
login_role
:
logger
.
warning
(
'Websocket: Not that Role
%
s for Host:
%
s User:
%
s '
%
(
role_name
,
asset
.
hostname
,
self
.
user
.
username
))
self
.
close
()
return
else
:
logger
.
warning
(
'Websocket: No that Host:
%
s User:
%
s '
%
(
asset_id
,
self
.
user
.
username
))
self
.
close
()
return
logger
.
debug
(
'Websocket: request web terminal Host:
%
s User:
%
s Role:
%
s'
%
(
asset
.
hostname
,
self
.
user
.
username
,
login_role
.
name
))
self
.
term
=
WebTty
(
self
.
user
,
asset
,
login_role
)
self
.
term
.
get_connection
()
self
.
term
.
get_connection
()
self
.
term
.
channel
=
self
.
term
.
ssh
.
invoke_shell
(
term
=
'xterm'
)
self
.
term
.
channel
=
self
.
term
.
ssh
.
invoke_shell
(
term
=
'xterm'
)
WebTerminalHandler
.
tasks
.
append
(
MyThread
(
target
=
self
.
forward_outbound
))
WebTerminalHandler
.
tasks
.
append
(
MyThread
(
target
=
self
.
forward_outbound
))
...
@@ -236,13 +285,23 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
...
@@ -236,13 +285,23 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
if
data
.
get
(
'data'
):
if
data
.
get
(
'data'
):
self
.
term
.
input_mode
=
True
self
.
term
.
input_mode
=
True
if
str
(
data
[
'data'
])
in
[
'
\r
'
,
'
\n
'
,
'
\r\n
'
]:
if
str
(
data
[
'data'
])
in
[
'
\r
'
,
'
\n
'
,
'
\r\n
'
]:
TtyLog
(
log
=
self
.
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
self
.
term
.
deal_command
(
self
.
term
.
data
,
self
.
term
.
ssh
))
.
save
()
if
self
.
term
.
vim_flag
:
match
=
self
.
term
.
ps1_pattern
.
search
(
self
.
term
.
vim_data
)
if
match
:
self
.
term
.
vim_flag
=
False
vim_data
=
self
.
term
.
deal_command
(
self
.
term
.
vim_data
)[
0
:
200
]
if
len
(
data
)
>
0
:
TtyLog
(
log
=
self
.
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
vim_data
)
.
save
()
TtyLog
(
log
=
self
.
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
self
.
term
.
deal_command
(
self
.
term
.
data
)[
0
:
200
])
.
save
()
self
.
term
.
vim_data
=
''
self
.
term
.
data
=
''
self
.
term
.
data
=
''
self
.
term
.
input_mode
=
False
self
.
term
.
input_mode
=
False
self
.
term
.
channel
.
send
(
data
[
'data'
])
self
.
term
.
channel
.
send
(
data
[
'data'
])
def
on_close
(
self
):
def
on_close
(
self
):
print
'On_close'
logger
.
debug
(
'Websocket: Close request'
)
if
self
in
WebTerminalHandler
.
clients
:
if
self
in
WebTerminalHandler
.
clients
:
WebTerminalHandler
.
clients
.
remove
(
self
)
WebTerminalHandler
.
clients
.
remove
(
self
)
try
:
try
:
...
@@ -267,6 +326,8 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
...
@@ -267,6 +326,8 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
if
not
len
(
recv
):
if
not
len
(
recv
):
return
return
data
+=
recv
data
+=
recv
if
self
.
term
.
vim_flag
:
self
.
term
.
vim_data
+=
recv
try
:
try
:
self
.
write_message
(
json
.
dumps
({
'data'
:
data
}))
self
.
write_message
(
json
.
dumps
({
'data'
:
data
}))
now_timestamp
=
time
.
time
()
now_timestamp
=
time
.
time
()
...
@@ -290,4 +351,5 @@ if __name__ == '__main__':
...
@@ -290,4 +351,5 @@ if __name__ == '__main__':
server
.
bind
(
options
.
port
,
options
.
host
)
server
.
bind
(
options
.
port
,
options
.
host
)
# server.listen(options.port)
# server.listen(options.port)
server
.
start
(
num_processes
=
1
)
server
.
start
(
num_processes
=
1
)
print
"Run server on
%
s:
%
s"
%
(
options
.
host
,
options
.
port
)
tornado
.
ioloop
.
IOLoop
.
instance
()
.
start
()
tornado
.
ioloop
.
IOLoop
.
instance
()
.
start
()
static/files/excels/cmdb_excel_2015_11_14_11_38.xlsx
deleted
100644 → 0
View file @
c89d43d2
File deleted
static/files/excels/cmdb_excel_2015_11_14_11_39.xlsx
deleted
100644 → 0
View file @
c89d43d2
File deleted
static/files/excels/cmdb_excel_2015_11_
19_22_05
.xlsx
→
static/files/excels/cmdb_excel_2015_11_
20_00_04
.xlsx
View file @
175f2702
No preview for this file type
templates/jasset/asset_add.html
View file @
175f2702
...
@@ -55,7 +55,7 @@
...
@@ -55,7 +55,7 @@
<div
class=
"col-sm-2"
>
<div
class=
"col-sm-2"
>
<div
class=
"radio i-checks"
>
<div
class=
"radio i-checks"
>
<label>
<label>
<input
type=
"checkbox"
checked=
""
id=
"id_use_default_auth"
name=
"use_default_auth"
><span>
使用默认
</span>
<input
type=
"checkbox"
checked=
"
checked
"
id=
"id_use_default_auth"
name=
"use_default_auth"
><span>
使用默认
</span>
</label>
</label>
</div>
</div>
</div>
</div>
...
@@ -142,26 +142,46 @@
...
@@ -142,26 +142,46 @@
rules
:
{
rules
:
{
check_ip
:
[
/^
(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])(\.(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])){3}
$/
,
'ip地址不正确'
],
check_ip
:
[
/^
(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])(\.(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])){3}
$/
,
'ip地址不正确'
],
check_port
:
[
/^
\d{1,5}
$/
,
'端口号不正确'
],
check_port
:
[
/^
\d{1,5}
$/
,
'端口号不正确'
],
use_default_auth
:
function
()
{
var
str1
=
$
(
"#id_use_default_auth"
).
is
(
":checked"
);
if
(
str1
==
true
){
var
decide
=
false
;
}
else
{
var
decide
=
true
;
}
return
decide
}
},
},
fields
:
{
fields
:
{
{
#
"ip"
:
{
#
}
"ip"
:
{
{
#
rule
:
"required;check_ip"
,
#
}
rule
:
"check_ip;"
,
{
#
tip
:
"输入IP"
,
#
}
tip
:
"输入IP"
,
{
#
ok
:
""
,
#
}
ok
:
""
,
{
#
msg
:
{
required
:
"必须填写!"
}
#
}
msg
:
{
required
:
"必须填写!"
}
{
#
},
#
}
},
"hostname"
:
{
"hostname"
:
{
rule
:
"required"
,
rule
:
"required"
,
tip
:
"填写主机名"
,
tip
:
"填写主机名"
,
ok
:
""
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
msg
:
{
required
:
"必须填写!"
}
},
},
{
#
"port"
:
{
#
}
"port"
:
{
{
#
rule
:
"required;check_port"
,
#
}
rule
:
"required(use_default_auth)"
,
{
#
tip
:
"输入端口号"
,
#
}
tip
:
"输入端口号"
,
{
#
ok
:
""
,
#
}
ok
:
""
,
{
#
msg
:
{
required
:
"必须填写!"
}
#
}
msg
:
{
required
:
"必须填写!"
}
{
#
}
#
}
},
"username"
:
{
rule
:
"required(use_default_auth)"
,
tip
:
"输入用户名"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
},
"password"
:
{
rule
:
"required(use_default_auth)"
,
tip
:
"输入密码"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
}
},
},
valid
:
function
(
form
)
{
valid
:
function
(
form
)
{
form
.
submit
();
form
.
submit
();
...
...
templates/jasset/asset_detail.html
View file @
175f2702
...
@@ -11,9 +11,15 @@
...
@@ -11,9 +11,15 @@
<div
class=
"ibox-title"
>
<div
class=
"ibox-title"
>
<span
class=
"text text-primary"
><b>
{{ asset.ip }}
</b></span>
<span
class=
"text text-primary"
><b>
{{ asset.ip }}
</b></span>
<div
class=
"ibox-tools"
>
<div
class=
"ibox-tools"
>
<a
class=
""
href=
"/jasset/asset_update/?id={{ asset.id }}"
>
<i
class=
"fa fa-refresh"
></i>
</a>
<a
class=
"collapse-link"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
<i
class=
"fa fa-chevron-up"
></i>
</a>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
<ul
class=
"dropdown-menu dropdown-user"
>
</ul>
</ul>
<a
class=
"close-link"
>
<a
class=
"close-link"
>
...
@@ -29,14 +35,14 @@
...
@@ -29,14 +35,14 @@
<div>
<div>
<div
class=
"text-left"
>
<div
class=
"text-left"
>
<table
class=
"table"
>
<table
class=
"table"
>
<tr>
<td
class=
"text-navy"
>
IP
</td>
<td>
{{ asset.ip|default_if_none:"" }}
</td>
</tr>
<tr>
<tr>
<td
class=
"text-navy"
>
主机名
</td>
<td
class=
"text-navy"
>
主机名
</td>
<td>
{{ asset.hostname|default_if_none:"" }}
</td>
<td>
{{ asset.hostname|default_if_none:"" }}
</td>
</tr>
</tr>
<tr>
<td
class=
"text-navy"
>
IP
</td>
<td>
{{ asset.ip|default_if_none:"" }}
</td>
</tr>
<tr>
<tr>
<td
class=
"text-navy"
>
其他IP
</td>
<td
class=
"text-navy"
>
其他IP
</td>
<td>
<td>
...
...
templates/jasset/asset_edit.html
View file @
175f2702
...
@@ -55,7 +55,7 @@
...
@@ -55,7 +55,7 @@
<div
class=
"col-sm-2"
>
<div
class=
"col-sm-2"
>
<div
class=
"radio i-checks"
>
<div
class=
"radio i-checks"
>
<label>
<label>
<input
type=
"checkbox"
{%
if
asset
.
use_default_auth
%}
checked=
""
{%
endif
%}
id=
"id_use_default_auth"
name=
"use_default_auth"
><span>
使用默认
</span>
<input
type=
"checkbox"
{%
if
asset
.
use_default_auth
%}
checked=
"
checked
"
{%
endif
%}
id=
"id_use_default_auth"
name=
"use_default_auth"
><span>
使用默认
</span>
</label>
</label>
</div>
</div>
</div>
</div>
...
@@ -77,7 +77,7 @@
...
@@ -77,7 +77,7 @@
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<label
class=
"col-sm-2 control-label"
>
端口
<span
class=
"red-fonts"
>
*
</span>
</label>
<label
class=
"col-sm-2 control-label"
>
端口
<span
class=
"red-fonts"
>
*
</span>
</label>
<div
class=
"col-sm-8"
>
<div
class=
"col-sm-8"
>
<input
type=
"text"
placeholder=
"Port"
value=
"{{ asset.port }}"
name=
"port"
class=
"form-control"
>
<input
type=
"text"
placeholder=
"Port"
value=
"{{ asset.port
|default_if_none:"
"
}}"
name=
"port"
class=
"form-control"
>
</div>
</div>
</div>
</div>
...
@@ -99,6 +99,12 @@
...
@@ -99,6 +99,12 @@
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
{{ af.disk|bootstrap_horizontal }}
{{ af.disk|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
{{ af.system_type|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
{{ af.system_version|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
{{ af.number|bootstrap_horizontal }}
{{ af.number|bootstrap_horizontal }}
...
@@ -180,12 +186,20 @@
...
@@ -180,12 +186,20 @@
$
(
'label[for="'
+
field
+
'"]'
).
parent
().
addClass
(
"required"
);
$
(
'label[for="'
+
field
+
'"]'
).
parent
().
addClass
(
"required"
);
});
});
$
(
'#assetForm'
).
validator
({
$
(
'#assetForm'
).
validator
({
timely
:
2
,
timely
:
2
,
theme
:
"yellow_right_effect"
,
theme
:
"yellow_right_effect"
,
rules
:
{
rules
:
{
check_ip
:
[
/^
(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])(\.(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])){3}
$/
,
'ip地址不正确'
],
check_ip
:
[
/^
(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])(\.(\d{1,2}
|1
\d\d
|2
[
0-4
]\d
|25
[
0-5
])){3}
$/
,
'ip地址不正确'
],
check_port
:
[
/^
\d{1,5}
$/
,
'端口号不正确'
],
check_port
:
[
/^
\d{1,5}
$/
,
'端口号不正确'
],
use_default_auth
:
function
()
{
var
str1
=
$
(
"#id_use_default_auth"
).
is
(
":checked"
);
if
(
str1
==
true
){
var
decide
=
false
;
}
else
{
var
decide
=
true
;
}
return
decide
}
},
},
fields
:
{
fields
:
{
"hostname"
:
{
"hostname"
:
{
...
@@ -194,17 +208,24 @@
...
@@ -194,17 +208,24 @@
ok
:
""
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
msg
:
{
required
:
"必须填写!"
}
},
},
{
#
"ip"
:
{
#
}
"port"
:
{
{
#
rule
:
"required;check_ip"
,
#
}
rule
:
"required(use_default_auth)"
,
{
#
tip
:
"输入IP"
,
#
}
tip
:
"输入端口号"
,
{
#
ok
:
""
,
#
}
ok
:
""
,
{
#
msg
:
{
required
:
"必须填写!"
}
#
}
msg
:
{
required
:
"必须填写!"
}
{
#
},
#
}
},
{
#
"port"
:
{
#
}
"username"
:
{
{
#
rule
:
"required;check_port"
,
#
}
rule
:
"required(use_default_auth)"
,
{
#
tip
:
"输入端口号"
,
#
}
tip
:
"输入用户名"
,
{
#
ok
:
""
,
#
}
ok
:
""
,
{
#
msg
:
{
required
:
"必须填写!"
}
#
}
msg
:
{
required
:
"必须填写!"
}
},
"password"
:
{
rule
:
"required(use_default_auth)"
,
tip
:
"输入密码"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
}
},
},
valid
:
function
(
form
)
{
valid
:
function
(
form
)
{
form
.
submit
();
form
.
submit
();
...
...
templates/jasset/asset_edit_batch.html
View file @
175f2702
...
@@ -54,29 +54,17 @@
...
@@ -54,29 +54,17 @@
<div
class=
"col-sm-2"
>
<div
class=
"col-sm-2"
>
<div
class=
"radio i-checks"
>
<div
class=
"radio i-checks"
>
<label>
<label>
<
<<<<<<
HEAD
<
input
type=
"radio"
checked=
""
value=
"no_action"
id=
"no"
name=
"use_default_auth"
class=
"auth"
><span>
不修改
</span>
=======
<input
type=
"radio"
checked=
""
value=
""
id=
"no"
name=
"use_default_auth"
class=
"auth"
><span>
不修改
</span>
<input
type=
"radio"
checked=
""
value=
""
id=
"no"
name=
"use_default_auth"
class=
"auth"
><span>
不修改
</span>
>>>>>>> cmdb
</label>
</label>
</div>
</div>
<div
class=
"radio i-checks"
>
<div
class=
"radio i-checks"
>
<label>
<label>
<
<<<<<<
HEAD
<
input
type=
"radio"
id=
"default"
name=
"use_default_auth"
class=
"auth"
><span>
使用默认
</span>
=======
<input
type=
"radio"
id=
"default"
name=
"use_default_auth"
class=
"auth"
value=
"default"
><span>
使用默认
</span>
<input
type=
"radio"
id=
"default"
name=
"use_default_auth"
class=
"auth"
value=
"default"
><span>
使用默认
</span>
>>>>>>> cmdb
</label>
</label>
</div>
</div>
<div
class=
"radio i-checks"
>
<div
class=
"radio i-checks"
>
<label>
<label>
<
<<<<<<
HEAD
<
input
type=
"radio"
id=
"pass"
name=
"use_default_auth"
class=
"auth"
><span>
用户名密码
</span>
=======
<input
type=
"radio"
id=
"pass"
name=
"use_default_auth"
class=
"auth"
value=
"user_passwd"
><span>
用户名密码
</span>
<input
type=
"radio"
id=
"pass"
name=
"use_default_auth"
class=
"auth"
value=
"user_passwd"
><span>
用户名密码
</span>
>>>>>>> cmdb
</label>
</label>
</div>
</div>
</div>
</div>
...
@@ -138,21 +126,6 @@
...
@@ -138,21 +126,6 @@
</div>
</div>
<script>
<script>
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
<<<<<<<
HEAD
$
(
'#host_edit'
).
click
(
function
()
{
var
args
=
{};
var
match
=
null
;
var
uuid
=
decodeURIComponent
(
location
.
search
.
substring
(
1
));
var
reg
=
/
(?:([^
&
]
+
)
=
([^
&
]
+
))
/g
;
while
((
match
=
reg
.
exec
(
uuid
))
!==
null
){
args
[
match
[
1
]]
=
match
[
2
];
}
var
ids
=
args
[
'uuid'
];
$
(
'#uuid'
).
val
(
ids
)
});
=======
>>>>>>>
cmdb
$
(
'.auth'
).
click
(
function
(){
$
(
'.auth'
).
click
(
function
(){
if
(
$
(
this
).
attr
(
'id'
)
==
'pass'
){
if
(
$
(
this
).
attr
(
'id'
)
==
'pass'
){
$
(
'#admin_account'
).
css
(
'display'
,
'block'
)
$
(
'#admin_account'
).
css
(
'display'
,
'block'
)
...
...
templates/jasset/asset_list.html
View file @
175f2702
...
@@ -130,7 +130,7 @@
...
@@ -130,7 +130,7 @@
<a
href=
"/jasset/asset_detail/?id={{ asset.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
<a
href=
"/jasset/asset_detail/?id={{ asset.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
{% ifnotequal session_role_id 0 %}
{% ifnotequal session_role_id 0 %}
<a
href=
"/jasset/asset_edit/?id={{ asset.id }}"
class=
"btn btn-xs btn-info"
>
编辑
</a>
<a
href=
"/jasset/asset_edit/?id={{ asset.id }}"
class=
"btn btn-xs btn-info"
>
编辑
</a>
<a
href=
"/jasset/asset_update/?id={{ asset.id }}"
class=
"btn btn-xs btn-info"
>
更新
</a>
<a
value=
"{{ asset.id }}"
class=
"conn btn btn-xs btn-warning"
>
连接
</a>
<a
value=
"/jasset/asset_del/?id={{ asset.id }}"
class=
"btn btn-xs btn-danger asset_del"
>
删除
</a>
<a
value=
"/jasset/asset_del/?id={{ asset.id }}"
class=
"btn btn-xs btn-danger asset_del"
>
删除
</a>
{% endifnotequal %}
{% endifnotequal %}
</td>
</td>
...
@@ -142,6 +142,8 @@
...
@@ -142,6 +142,8 @@
<div
class=
"col-sm-6"
>
<div
class=
"col-sm-6"
>
<input
type=
"button"
id=
"asset_del"
class=
"btn btn-danger btn-sm"
name=
"del_button"
value=
"删除"
/>
<input
type=
"button"
id=
"asset_del"
class=
"btn btn-danger btn-sm"
name=
"del_button"
value=
"删除"
/>
<a
value=
"/jasset/asset_edit_batch/"
type=
"button"
class=
"btn btn-sm btn-warning iframe"
>
修改
</a>
<a
value=
"/jasset/asset_edit_batch/"
type=
"button"
class=
"btn btn-sm btn-warning iframe"
>
修改
</a>
<input
type=
"button"
id=
"asset_update"
class=
"btn btn-info btn-sm"
name=
"update_button"
value=
"更新"
/>
<input
type=
"button"
id=
"asset_update_all"
class=
"btn btn-primary btn-sm"
name=
"update_button"
value=
"更新全部"
/>
</div>
</div>
{% include 'paginator.html' %}
{% include 'paginator.html' %}
</div>
</div>
...
@@ -155,23 +157,10 @@
...
@@ -155,23 +157,10 @@
{% block self_footer_js %}
{% block self_footer_js %}
<script>
<script>
$
(
'table td'
).
on
(
'change'
,
function
(
env
,
id
){
var
url
=
"/jasset/show_all_ajax/?env="
+
env
+
"&id="
+
id
;
console
.
log
(
url
);
$
.
ajax
({
type
:
"GET"
,
url
:
url
,
// data: $("#search_form").serialize(),
success
:
function
(
data
)
{
$
(
"#j_dept_"
+
id
).
html
(
data
);
}
});
});
$
(
document
).
ready
(
function
(){
$
(
document
).
ready
(
function
(){
$
(
'.asset_del'
).
click
(
function
(){
$
(
'.asset_del'
).
click
(
function
(){
var
row
=
$
(
this
).
closest
(
'tr'
);
var
row
=
$
(
this
).
closest
(
'tr'
);
if
(
confirm
(
"确定删除"
))
{
if
(
confirm
(
"确定删除
?
"
))
{
$
.
get
(
$
.
get
(
$
(
this
).
attr
(
'value'
),
$
(
this
).
attr
(
'value'
),
{},
{},
...
@@ -180,9 +169,46 @@
...
@@ -180,9 +169,46 @@
}
}
)
)
}
}
})
});
$
(
'.conn'
).
click
(
function
(){
var
url
=
'/jlog/get_role_name/?id='
+
$
(
this
).
attr
(
'value'
);
var
href
=
$
(
this
).
attr
(
'href'
);
var
new_url
=
'/jlog/web_terminal/?id='
+
$
(
this
).
attr
(
'value'
)
+
'&role='
;
$
.
ajax
({
type
:
'GET'
,
url
:
url
,
data
:
{},
success
:
function
(
data
){
var
dataArray
=
data
.
split
(
','
);
if
(
dataArray
.
length
==
1
&&
data
!=
'error'
){
console
.
log
(
'one'
);
window
.
open
(
new_url
+
data
,
''
,
'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'
);
}
else
if
(
dataArray
.
length
==
'1'
&&
data
==
'error'
){
layer
.
alert
(
'没有授权角色'
)
}
else
{
aUrl
=
''
;
$
.
each
(
dataArray
,
function
(
index
,
value
){
aUrl
+=
'<a onclick="windowOpen(this); return false" class="btn btn-xs btn-primary newa" href='
+
new_url
+
value
+
'>'
+
value
+
'</a> '
});
layer
.
alert
(
aUrl
,
{
skin
:
'layui-layer-molv'
,
title
:
'多个角色,请选择一个连接'
,
closeBtn
:
0
})
}
}
});
return
false
});
});
});
function
windowOpen
(
aTab
){
var
new_url
=
aTab
.
href
;
window
.
open
(
new_url
,
''
,
'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'
);
return
false
}
$
(
".iframe"
).
on
(
'click'
,
function
(){
$
(
".iframe"
).
on
(
'click'
,
function
(){
var
asset_id_all
=
getIDall
();
var
asset_id_all
=
getIDall
();
if
(
asset_id_all
==
''
){
if
(
asset_id_all
==
''
){
...
@@ -219,14 +245,15 @@
...
@@ -219,14 +245,15 @@
});
});
});
});
$
(
'#asset_del'
).
click
(
function
()
{
$
(
'#asset_del'
).
click
(
function
()
{
var
asset_id_all
=
getIDall
();
var
asset_id_all
=
getIDall
();
console
.
log
(
asset_id_all
);
if
(
asset_id_all
==
''
){
if
(
asset_id_all
==
''
){
alert
(
"请至少选择一行!"
);
alert
(
"请至少选择一行!"
);
return
false
;
return
false
;
}
}
if
(
confirm
(
"确定删除"
))
{
if
(
confirm
(
"确定删除
?
"
))
{
$
.
ajax
({
$
.
ajax
({
type
:
"post"
,
type
:
"post"
,
data
:
{
asset_id_all
:
asset_id_all
},
data
:
{
asset_id_all
:
asset_id_all
},
...
@@ -238,6 +265,40 @@
...
@@ -238,6 +265,40 @@
}
}
});
});
$
(
'#asset_update'
).
click
(
function
()
{
var
asset_id_all
=
getIDall
();
if
(
asset_id_all
==
''
){
alert
(
"请至少选择一行!"
);
return
false
;
}
layer
.
msg
(
'玩命更新中...'
,
{
time
:
200000
});
$
.
ajax
({
type
:
"post"
,
data
:
{
asset_id_all
:
asset_id_all
},
url
:
"/jasset/asset_update_batch/"
,
success
:
function
()
{
parent
.
location
.
reload
();
}
});
});
{
#
function
update_tips
(){
#
}
{
#
layer
.
tips
(
'我是另外一个tips,只不过我长得跟之前那位稍有些不一样。'
,
'吸附元素选择器'
,
{
#
}
{
#
tips
:
[
1
,
'#3595CC'
],
#
}
{
#
time
:
4000
#
}
{
#
});
#
}
{
#
}
#
}
$
(
'#asset_update_all'
).
click
(
function
()
{
layer
.
msg
(
'玩命更新中...'
,
{
time
:
200000
});
$
.
ajax
({
type
:
"post"
,
url
:
"/jasset/asset_update_batch/?arg=all"
,
success
:
function
()
{
parent
.
location
.
reload
();
}
});
});
function
change_info
(){
function
change_info
(){
var
args
=
$
(
"#asset_form"
).
serialize
();
var
args
=
$
(
"#asset_form"
).
serialize
();
...
@@ -249,19 +310,6 @@
...
@@ -249,19 +310,6 @@
change_info
()
change_info
()
}
}
});
});
function
show_all
(
env
,
id
)
{
var
url
=
"/jasset/show_all_ajax/?env="
+
env
+
"&id="
+
id
;
console
.
log
(
url
);
$
.
ajax
({
type
:
"GET"
,
url
:
url
,
success
:
function
(
data
)
{
$
(
"#j_group_"
+
id
).
html
(
data
);
}
});
}
</script>
</script>
{% endblock %}
{% endblock %}
\ No newline at end of file
templates/jasset/error.html
View file @
175f2702
{% for field in af %}
{% for field in af
_form
%}
<div
class=
"alert alert-warning text-center"
>
{{ field.errors }}
</div>
<div
class=
"alert alert-warning text-center"
>
{{ field.errors }}
</div>
{{ field.label_tag }}: {{ field }}
{{ field.label_tag }}: {{ field }}
{% endfor %}
{% endfor %}
...
...
templates/jasset/idc_list.html
View file @
175f2702
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
<div
class=
"ibox-content"
>
<div
class=
"ibox-content"
>
<div
class=
""
>
<div
class=
""
>
<a
target=
"_blank"
href=
"/jasset/idc_add"
class=
"btn btn-sm btn-primary "
>
添加IDC
</a>
<a
target=
"_blank"
href=
"/jasset/idc_add"
class=
"btn btn-sm btn-primary "
>
添加IDC
</a>
<input
type=
"button"
id=
"del_check"
class=
"btn btn-danger btn-sm"
name=
"del_button"
value=
"删除所选"
/>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right mail-search"
>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right mail-search"
>
<div
class=
"input-group"
>
<div
class=
"input-group"
>
<input
type=
"text"
class=
"form-control input-sm"
id=
"search_input"
name=
"keyword"
placeholder=
"Search"
>
<input
type=
"text"
class=
"form-control input-sm"
id=
"search_input"
name=
"keyword"
placeholder=
"Search"
>
...
@@ -78,10 +79,9 @@
...
@@ -78,10 +79,9 @@
</table>
</table>
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-sm-6"
>
<div
class=
"col-sm-6"
>
{% ifequal session_role_id 2 %}
<div
class=
"dataTables_info"
id=
"editable_info"
role=
"status"
aria-live=
"polite"
>
<input
type=
"button"
id=
"del_check"
class=
"btn btn-danger btn-sm"
name=
"del_button"
value=
"删除"
/>
Showing {{ contacts.start_index }} to {{ contacts.end_index }} of {{ p.count }} entries
<!--<input type="button" id="alter_button" class="btn btn-warning btn-sm" name="alter_button" value="修改" onclick="alter('contents_form')" />-->
</div>
{% endifequal %}
</div>
</div>
{% include 'paginator.html' %}
{% include 'paginator.html' %}
</div>
</div>
...
...
templates/jlog/log_online.html
View file @
175f2702
...
@@ -50,7 +50,7 @@
...
@@ -50,7 +50,7 @@
<div
class=
"col-lg-12"
>
<div
class=
"col-lg-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox float-e-margins"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<div
id=
"ibox-content"
class=
"ibox-title"
>
<h5>
用户日志详细信息列表
<
input
type=
"button"
id=
"test_connect"
class=
"btn btn-primary"
value=
"测试连接 web terminal"
/>
<
/h5>
<h5>
用户日志详细信息列表
</h5>
<div
class=
"ibox-tools"
>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
<i
class=
"fa fa-chevron-up"
></i>
...
@@ -79,11 +79,9 @@
...
@@ -79,11 +79,9 @@
<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"
>
来源IP
</th>
{% ifnotequal session_role_id 0 %}
<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>
{% endifnotequal %}
<th
class=
"text-center"
>
登录时间
</th>
<th
class=
"text-center"
>
登录时间
</th>
</tr>
</tr>
...
@@ -94,11 +92,9 @@
...
@@ -94,11 +92,9 @@
<td
id=
"username"
class=
"text-center"
>
{{ post.user }}
</td>
<td
id=
"username"
class=
"text-center"
>
{{ post.user }}
</td>
<td
id=
"ip"
class=
"text-center"
>
{{ post.host }}
</td>
<td
id=
"ip"
class=
"text-center"
>
{{ post.host }}
</td>
<td
id=
"remote_ip"
class=
"text-center"
>
{{ post.remote_ip }}
</td>
<td
id=
"remote_ip"
class=
"text-center"
>
{{ post.remote_ip }}
</td>
{% ifnotequal session_role_id 0 %}
<td
class=
"text-center"
><a
href=
"/jlog/history/?id={{ post.id }}"
class=
"log_command"
>
命令统计
</a></td>
<td
class=
"text-center"
><a
href=
"/jlog/history/?id={{ post.id }}"
class=
"log_command"
>
命令统计
</a></td>
<td
class=
"text-center"
><a
class=
"monitor"
file_path=
"{{ post.log_path }}"
>
监控
</a></td>
<td
class=
"text-center"
><a
class=
"monitor"
file_path=
"{{ 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 }}", "{{ post.remote_ip }}")'
/></td>
<td
class=
"text-center"
><input
type=
"button"
id=
"cut"
class=
"btn btn-danger btn-xs"
name=
"cut"
value=
"阻断"
onclick=
'cut("{{ post.pid }}", "{{ post.remote_ip }}")'
/></td>
{% endifnotequal %}
<td
class=
"text-center"
id=
"start_time"
>
{{ post.start_time|date:"Y-m-d H:i:s" }}
</td>
<td
class=
"text-center"
id=
"start_time"
>
{{ post.start_time|date:"Y-m-d H:i:s" }}
</td>
</tr>
</tr>
{% endfor %}
{% endfor %}
...
@@ -188,35 +184,19 @@
...
@@ -188,35 +184,19 @@
}});
}});
return
false
;
return
false
;
});
});
$
(
'#test_connect'
).
click
(
function
(){
window
.
open
(
'/jlog/web_terminal/?asset_name="hello'
,
'播放'
,
'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'
);
});
});
});
{
#
function
log_search
(){
#
}
{
#
$
.
ajax
({
#
}
{
#
type
:
"GET"
,
#
}
{
#
url
:
"/jlog/search/?env=online"
,
#
}
{
#
data
:
$
(
"#search_form"
).
serialize
(),
#
}
{
#
success
:
function
(
data
)
{
#
}
{
#
$
(
".tab-content"
).
html
(
data
);
#
}
{
#
}
#
}
{
#
});
#
}
{
#
}
#
}
function
cut
(
num
,
host
){
function
cut
(
num
,
host
){
console
.
log
(
host
);
console
.
log
(
host
);
if
(
host
==
'Web'
){
if
(
host
==
'Web'
){
var
g_url
=
'{{ web_kill_uri }}'
+
'?id='
+
num
;
var
g_url
=
'{{ web_kill_uri }}'
+
'?id='
+
num
;
}
else
{
}
else
{
g_url
=
"/jlog/log_kill/?id="
+
num
;
var
g_url
=
"/jlog/log_kill/?id="
+
num
;
}
}
$
.
ajax
({
$
.
ajax
({
type
:
"GET"
,
type
:
"GET"
,
url
:
g_url
,
url
:
g_url
+
"&sessionid={{ session_id }}"
,
success
:
window
.
open
(
"/jlog/log_list/online/"
,
"_self"
)
success
:
window
.
open
(
"/jlog/log_list/online/"
,
"_self"
)
});
});
...
...
templates/jperm/perm_role_add.html
View file @
175f2702
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
<div
class=
"alert alert-success text-center"
>
{{ msg }}
</div>
<div
class=
"alert alert-success text-center"
>
{{ msg }}
</div>
{% endif %}
{% endif %}
<div
class=
"form-group"
>
<div
class=
"form-group"
>
<label
for=
"role_name"
class=
"col-sm-2 control-label"
>
规则
名称
<span
class=
"red-fonts"
>
*
</span></label>
<label
for=
"role_name"
class=
"col-sm-2 control-label"
>
角色
名称
<span
class=
"red-fonts"
>
*
</span></label>
<div
class=
"col-sm-8"
>
<div
class=
"col-sm-8"
>
<input
id=
"role_name"
name=
"role_name"
placeholder=
"Role Name"
type=
"text"
class=
"form-control"
>
<input
id=
"role_name"
name=
"role_name"
placeholder=
"Role Name"
type=
"text"
class=
"form-control"
>
</div>
</div>
...
...
templates/nav.html
View file @
175f2702
...
@@ -36,8 +36,6 @@
...
@@ -36,8 +36,6 @@
<li
class=
"role"
>
<li
class=
"role"
>
<a
href=
"/jperm/role/"
>
系统角色
</a>
<a
href=
"/jperm/role/"
>
系统角色
</a>
</li>
</li>
<li
class=
"apply_show online"
><a
href=
"/jperm/apply_show/online/"
>
权限审批
</a></li>
<li
class=
"apply_show online"
><a
href=
"/jperm/log/"
>
授权记录
</a></li>
</ul>
</ul>
</li>
</li>
<li
id=
"jlog"
>
<li
id=
"jlog"
>
...
...
templates/nav_li_profile.html
View file @
175f2702
...
@@ -36,7 +36,7 @@
...
@@ -36,7 +36,7 @@
<script>
<script>
$
(
".iframe_user"
).
on
(
'click'
,
function
(){
$
(
".iframe_user"
).
on
(
'click'
,
function
(){
var
url
=
$
(
this
).
attr
(
"value"
);
var
url
=
$
(
this
).
attr
(
"value"
);
$
.
layer
({
layer
.
open
({
type
:
2
,
type
:
2
,
title
:
'个人信息'
,
title
:
'个人信息'
,
maxmin
:
true
,
maxmin
:
true
,
...
@@ -45,7 +45,7 @@
...
@@ -45,7 +45,7 @@
shade
:
[
0.5
,
'#000000'
],
shade
:
[
0.5
,
'#000000'
],
shadeClose
:
true
,
shadeClose
:
true
,
area
:
[
'800px'
,
'600px'
],
area
:
[
'800px'
,
'600px'
],
iframe
:
{
src
:
url
}
content
:
url
});
});
});
});
</script>
</script>
...
...
templates/setting.html
View file @
175f2702
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
<div
class=
"panel-options"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<ul
class=
"nav nav-tabs"
>
<li
id=
"tab1"
class=
"active"
><a
data-toggle=
"tab"
href=
"#tab-default"
aria-expanded=
"true"
>
默认设置
</a></li>
<li
id=
"tab1"
class=
"active"
><a
data-toggle=
"tab"
href=
"#tab-default"
aria-expanded=
"true"
>
默认设置
</a></li>
<li
id=
"tab2"
class=
""
><a
data-toggle=
"tab"
href=
"#tab-email"
aria-expanded=
"true"
>
邮箱设置
</a></li>
{#
<li
id=
"tab2"
class=
""
><a
data-toggle=
"tab"
href=
"#tab-email"
aria-expanded=
"true"
>
邮箱设置
</a></li>
#}
</ul>
</ul>
</div>
</div>
</div>
</div>
...
@@ -82,15 +82,15 @@
...
@@ -82,15 +82,15 @@
</form>
</form>
</div>
</div>
<div
id=
"tab-email"
class=
"tab-pane"
>
{#
<div
id=
"tab-email"
class=
"tab-pane"
>
#}
<table
class=
"table table-striped table-bordered table-hover "
id=
"editable"
>
{#
<table
class=
"table table-striped table-bordered table-hover "
id=
"editable"
>
#}
<thead>
{#
<thead>
#}
<tr>
{#
<tr>
#}
<th
class=
"text-center"
>
组名
</th>
{#
<th
class=
"text-center"
>
组名
</th>
#}
</tr>
{#
</tr>
#}
</thead>
{#
</thead>
#}
</table>
{#
</table>
#}
</div>
{#
</div>
#}
</div>
</div>
</div>
</div>
</div>
</div>
...
...
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