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
267bb024
Commit
267bb024
authored
Dec 03, 2015
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改exec 和 MyRUnner
parent
255e3a04
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
178 additions
and
202 deletions
+178
-202
connect.py
connect.py
+71
-139
models.py
jlog/models.py
+10
-2
ansible_api.py
jperm/ansible_api.py
+47
-32
models.py
jperm/models.py
+1
-1
perm_api.py
jperm/perm_api.py
+3
-0
api.py
jumpserver/api.py
+1
-1
views.py
jumpserver/views.py
+4
-4
run_websocket.py
run_websocket.py
+38
-20
exec_cmd.html
templates/exec_cmd.html
+1
-1
asset_list.html
templates/jasset/asset_list.html
+2
-2
No files found.
connect.py
View file @
267bb024
...
@@ -27,7 +27,8 @@ from jumpserver.api import logger, Log, TtyLog, get_role_key, CRYPTOR, bash, get
...
@@ -27,7 +27,8 @@ from jumpserver.api import logger, Log, TtyLog, get_role_key, CRYPTOR, bash, get
from
jperm.perm_api
import
gen_resource
,
get_group_asset_perm
,
get_group_user_perm
,
user_have_perm
,
PermRole
from
jperm.perm_api
import
gen_resource
,
get_group_asset_perm
,
get_group_user_perm
,
user_have_perm
,
PermRole
from
jumpserver.settings
import
LOG_DIR
from
jumpserver.settings
import
LOG_DIR
from
jperm.ansible_api
import
Command
,
MyRunner
from
jperm.ansible_api
import
Command
,
MyRunner
from
jlog.log_api
import
escapeString
# from jlog.log_api import escapeString
from
jlog.models
import
ExecLog
login_user
=
get_object
(
User
,
username
=
getpass
.
getuser
())
login_user
=
get_object
(
User
,
username
=
getpass
.
getuser
())
...
@@ -468,16 +469,6 @@ class Nav(object):
...
@@ -468,16 +469,6 @@ class Nav(object):
Print prompt
Print prompt
打印提示导航
打印提示导航
"""
"""
msg
=
"""
\n\033
[1;32m### Welcome To Use JumpServer, A Open Source System . ###
\033
[0m
1) Type
\033
[32mID
\033
[0m To Login.
2) Type
\033
[32m/
\033
[0m +
\033
[32mIP, Host Name, Host Alias or Comments
\033
[0mTo Search.
3) Type
\033
[32mP/p
\033
[0m To Print The Servers You Available.
4) Type
\033
[32mG/g
\033
[0m To Print The Server Groups You Available.
5) Type
\033
[32mG/g
\033
[0m
\033
[0m +
\033
[32mGroup ID
\033
[0m To Print The Server Group You Available.
6) Type
\033
[32mE/e
\033
[0m To Execute Command On Several Servers.
7) Type
\033
[32mQ/q
\033
[0m To Quit.
"""
msg
=
"""
\n\033
[1;32m### 欢迎使用Jumpserver开源跳板机 ###
\033
[0m
msg
=
"""
\n\033
[1;32m### 欢迎使用Jumpserver开源跳板机 ###
\033
[0m
1) 输入
\033
[32mID
\033
[0m 直接登录.
1) 输入
\033
[32mID
\033
[0m 直接登录.
2) 输入
\033
[32m/
\033
[0m +
\033
[32mIP, 主机名, 主机别名 or 备注
\033
[0m搜索.
2) 输入
\033
[32m/
\033
[0m +
\033
[32mIP, 主机名, 主机别名 or 备注
\033
[0m搜索.
...
@@ -542,35 +533,6 @@ class Nav(object):
...
@@ -542,35 +533,6 @@ class Nav(object):
print
'[
%-3
s]
%-15
s'
%
(
asset_group
.
id
,
asset_group
.
name
)
print
'[
%-3
s]
%-15
s'
%
(
asset_group
.
id
,
asset_group
.
name
)
print
print
def
get_exec_log
(
self
,
assets_name_str
):
exec_log_dir
=
os
.
path
.
join
(
LOG_DIR
,
'exec'
)
date_today
=
datetime
.
datetime
.
now
()
date_start
=
date_today
.
strftime
(
'
%
Y
%
m
%
d'
)
time_start
=
date_today
.
strftime
(
'
%
H
%
M
%
S'
)
today_connect_log_dir
=
os
.
path
.
join
(
exec_log_dir
,
date_start
)
log_file_path
=
os
.
path
.
join
(
today_connect_log_dir
,
'
%
s_
%
s'
%
(
self
.
user
.
username
,
time_start
))
try
:
mkdir
(
os
.
path
.
dirname
(
today_connect_log_dir
),
mode
=
0777
)
mkdir
(
today_connect_log_dir
,
mode
=
0777
)
except
OSError
:
logger
.
debug
(
'创建目录
%
s 失败,请修改
%
s目录权限'
%
(
today_connect_log_dir
,
exec_log_dir
))
raise
ServerError
(
'Create
%
s failed, Please modify
%
s permission.'
%
(
today_connect_log_dir
,
exec_log_dir
))
try
:
log_file_f
=
open
(
log_file_path
+
'.log'
,
'a'
)
log_file_f
.
write
(
'Start at
%
s
\r\n
'
%
datetime
.
datetime
.
now
())
log_time_f
=
open
(
log_file_path
+
'.time'
,
'a'
)
except
IOError
:
logger
.
debug
(
'创建tty日志文件失败, 请修改目录
%
s权限'
%
today_connect_log_dir
)
raise
ServerError
(
'Create logfile failed, Please modify
%
s permission.'
%
today_connect_log_dir
)
remote_ip
=
os
.
popen
(
"who -m | awk '{ print $5 }'"
)
.
read
()
.
strip
(
'()
\n
'
)
log
=
Log
(
user
=
self
.
user
.
username
,
host
=
assets_name_str
,
remote_ip
=
remote_ip
,
login_type
=
'exec'
,
log_path
=
log_file_path
,
start_time
=
datetime
.
datetime
.
now
(),
pid
=
os
.
getpid
())
log
.
save
()
return
log_file_f
,
log_time_f
,
log
def
exec_cmd
(
self
):
def
exec_cmd
(
self
):
"""
"""
批量执行命令
批量执行命令
...
@@ -578,104 +540,74 @@ class Nav(object):
...
@@ -578,104 +540,74 @@ class Nav(object):
while
True
:
while
True
:
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
)
print
'
\033
[32m[
%-2
s]
%-15
s
\033
[0m'
%
(
'ID'
,
'角色'
)
roles
=
self
.
user_perm
.
get
(
'role'
)
.
keys
()
roles
=
self
.
user_perm
.
get
(
'role'
)
.
keys
()
role_check
=
dict
(
zip
(
range
(
len
(
roles
)),
roles
))
if
len
(
roles
)
>
1
:
# 授权角色数大于1
print
'
\033
[32m[
%-2
s]
%-15
s
\033
[0m'
%
(
'ID'
,
'角色'
)
role_check
=
dict
(
zip
(
range
(
len
(
roles
)),
roles
))
for
i
,
r
in
role_check
.
items
():
for
i
,
r
in
role_check
.
items
():
print
'[
%-2
s]
%-15
s'
%
(
i
,
r
.
name
)
print
'[
%-2
s]
%-15
s'
%
(
i
,
r
.
name
)
print
print
print
"请输入运行命令角色的ID, q退出"
print
"请输入运行命令角色的ID, q退出"
try
:
try
:
role_id
=
raw_input
(
"
\033
[1;32mRole>:
\033
[0m "
)
.
strip
()
role_id
=
raw_input
(
"
\033
[1;32mRole>:
\033
[0m "
)
.
strip
()
if
role_id
==
'q'
:
if
role_id
==
'q'
:
break
break
except
(
IndexError
,
ValueError
):
color_print
(
'错误输入'
)
else
:
else
:
role
=
role_check
[
int
(
role_id
)]
role
=
role_check
[
int
(
role_id
)]
assets
=
list
(
self
.
user_perm
.
get
(
'role'
,
{})
.
get
(
role
)
.
get
(
'asset'
))
elif
len
(
roles
)
==
1
:
# 授权角色数为1
print
"该角色有权限的所有主机"
role
=
roles
[
0
]
for
asset
in
assets
:
assets
=
list
(
self
.
user_perm
.
get
(
'role'
,
{})
.
get
(
role
)
.
get
(
'asset'
))
# 获取该用户,角色授权主机
print
asset
.
hostname
print
"该角色有权限的所有主机"
print
for
asset
in
assets
:
print
"请输入主机名、IP或ansile支持的pattern, q退出"
print
'
%
s'
%
asset
.
hostname
pattern
=
raw_input
(
"
\033
[1;32mPattern>:
\033
[0m "
)
.
strip
()
print
if
pattern
==
'q'
:
print
"请输入主机名、IP或ansile支持的pattern, q退出"
break
pattern
=
raw_input
(
"
\033
[1;32mPattern>:
\033
[0m "
)
.
strip
()
else
:
if
pattern
==
'q'
:
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
,
'role'
:
role
},
perm
=
self
.
user_perm
)
break
cmd
=
Command
(
res
)
else
:
logger
.
debug
(
"批量执行res:
%
s"
%
res
)
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
,
'role'
:
role
},
perm
=
self
.
user_perm
)
asset_name_str
=
''
runner
=
MyRunner
(
res
)
for
inv
in
cmd
.
inventory
.
get_hosts
(
pattern
=
pattern
):
logger
.
debug
(
"批量执行res:
%
s"
%
res
)
print
inv
.
name
asset_name_str
=
''
asset_name_str
+=
inv
.
name
print
"匹配主机:"
print
for
inv
in
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
print
'
%
s'
%
inv
.
name
asset_name_str
+=
'
%
s '
%
inv
.
name
print
log_file_f
,
log_time_f
,
log
=
self
.
get_exec_log
(
asset_name_str
)
while
True
:
pre_timestamp
=
time
.
time
()
print
"请输入执行的命令, 按q退出"
while
True
:
command
=
raw_input
(
"
\033
[1;32mCmds>:
\033
[0m "
)
.
strip
()
print
"请输入执行的命令, 按q退出"
ExecLog
(
host
=
asset_name_str
,
cmd
=
command
)
.
save
()
data
=
'ansible> '
if
command
==
'q'
:
write_log
(
log_file_f
,
data
)
break
now_timestamp
=
time
.
time
()
runner
.
run
(
'shell'
,
command
,
pattern
=
pattern
)
write_log
(
log_time_f
,
'
%
s
%
s
\n
'
%
(
round
(
now_timestamp
-
pre_timestamp
,
4
),
len
(
data
)))
for
k
,
v
in
runner
.
results
.
items
():
pre_timestamp
=
now_timestamp
if
k
==
'ok'
:
command
=
raw_input
(
"
\033
[1;32mCmds>:
\033
[0m "
)
.
strip
()
for
host
,
output
in
v
.
items
():
data
=
'
%
s
\r\n
'
%
command
color_print
(
"
%
s =>
%
s"
%
(
host
,
'Ok'
),
'green'
)
write_log
(
log_file_f
,
data
)
print
output
now_timestamp
=
time
.
time
()
write_log
(
log_time_f
,
'
%
s
%
s
\n
'
%
(
round
(
now_timestamp
-
pre_timestamp
,
4
),
len
(
data
)))
pre_timestamp
=
now_timestamp
TtyLog
(
log
=
log
,
cmd
=
command
,
datetime
=
datetime
.
datetime
.
now
())
.
save
()
if
command
==
'q'
:
log
.
is_finished
=
True
log
.
end_time
=
datetime
.
datetime
.
now
()
log
.
save
()
break
result
=
cmd
.
run
(
module_name
=
'shell'
,
command
=
command
,
pattern
=
pattern
)
for
k
,
v
in
result
.
items
():
if
k
==
'ok'
:
for
host
,
output
in
v
.
items
():
header
=
color_print
(
"
%
s =>
%
s"
%
(
host
,
'Ok'
),
'green'
)
print
output
output
=
re
.
sub
(
r'[\r\n]'
,
'
\r\n
'
,
output
)
data
=
'
%
s
\r\n
%
s
\r\n
'
%
(
header
,
output
)
now_timestamp
=
time
.
time
()
write_log
(
log_file_f
,
data
)
write_log
(
log_time_f
,
'
%
s
%
s
\n
'
%
(
round
(
now_timestamp
-
pre_timestamp
,
4
),
len
(
data
)))
pre_timestamp
=
now_timestamp
print
else
:
for
host
,
output
in
v
.
items
():
header
=
color_print
(
"
%
s =>
%
s"
%
(
host
,
k
),
'red'
)
output
=
color_print
(
output
,
'red'
)
output
=
re
.
sub
(
r'[\r\n]'
,
'
\r\n
'
,
output
)
data
=
'
%
s
\r\n
%
s
\r\n
'
%
(
header
,
output
)
now_timestamp
=
time
.
time
()
write_log
(
log_file_f
,
data
)
write_log
(
log_time_f
,
'
%
s
%
s
\n
'
%
(
round
(
now_timestamp
-
pre_timestamp
,
4
),
len
(
data
)))
pre_timestamp
=
now_timestamp
print
print
"="
*
20
print
print
else
:
except
(
IndexError
,
KeyError
):
for
host
,
output
in
v
.
items
():
color_print
(
'ID输入错误'
)
color_print
(
"
%
s =>
%
s"
%
(
host
,
k
),
'red'
)
continue
color_print
(
output
,
'red'
)
print
except
EOFError
:
print
"~o~ Task finished ~o~"
print
print
break
finally
:
log
.
is_finished
=
True
log
.
end_time
=
datetime
.
datetime
.
now
()
def
upload
(
self
):
def
upload
(
self
):
while
True
:
while
True
:
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
)
try
:
try
:
print
"进入批量上传模式"
print
"请输入主机名、IP或ansile支持的pattern, q退出"
print
"请输入主机名、IP或ansile支持的pattern, q退出"
pattern
=
raw_input
(
"
\033
[1;32mPattern>:
\033
[0m "
)
.
strip
()
pattern
=
raw_input
(
"
\033
[1;32mPattern>:
\033
[0m "
)
.
strip
()
if
pattern
==
'q'
:
if
pattern
==
'q'
:
...
@@ -684,8 +616,8 @@ class Nav(object):
...
@@ -684,8 +616,8 @@ class Nav(object):
assets
=
self
.
user_perm
.
get
(
'asset'
)
.
keys
()
assets
=
self
.
user_perm
.
get
(
'asset'
)
.
keys
()
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
},
perm
=
self
.
user_perm
)
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
},
perm
=
self
.
user_perm
)
runner
=
MyRunner
(
res
)
runner
=
MyRunner
(
res
)
logger
.
debug
(
"Muti upload file res:
%
s"
%
res
)
asset_name_str
=
''
asset_name_str
=
''
print
"匹配主机:
\n
"
for
inv
in
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
for
inv
in
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
print
inv
.
name
print
inv
.
name
asset_name_str
+=
inv
.
name
asset_name_str
+=
inv
.
name
...
@@ -701,16 +633,15 @@ class Nav(object):
...
@@ -701,16 +633,15 @@ class Nav(object):
runner
=
MyRunner
(
res
)
runner
=
MyRunner
(
res
)
runner
.
run
(
'copy'
,
module_args
=
'src=
%
s dest=
%
s directory_mode'
runner
.
run
(
'copy'
,
module_args
=
'src=
%
s dest=
%
s directory_mode'
%
(
tmp_dir
,
tmp_dir
),
pattern
=
pattern
)
%
(
tmp_dir
,
tmp_dir
),
pattern
=
pattern
)
ret
=
runner
.
get_result
()
ret
=
runner
.
results
logger
.
debug
(
ret
)
logger
.
debug
(
'Upload file:
%
s'
%
ret
)
if
ret
.
get
(
'failed'
):
if
ret
.
get
(
'failed'
):
print
ret
error
=
'上传目录:
%
s
\n
上传失败: [
%
s ]
\n
上传成功 [
%
s ]'
%
(
tmp_dir
,
error
=
'上传目录:
%
s
\n
上传失败: [
%
s ]
\n
上传成功 [
%
s ]'
%
(
tmp_dir
,
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'ok'
)))
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()
))
color_print
(
error
)
color_print
(
error
)
else
:
else
:
msg
=
'上传目录:
%
s
\n
传送成功 [
%
s ]'
%
(
tmp_dir
,
', '
.
join
(
ret
.
get
(
'ok'
)))
msg
=
'上传目录:
%
s
\n
传送成功 [
%
s ]'
%
(
tmp_dir
,
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()
))
color_print
(
msg
,
'green'
)
color_print
(
msg
,
'green'
)
print
print
...
@@ -731,30 +662,31 @@ class Nav(object):
...
@@ -731,30 +662,31 @@ class Nav(object):
assets
=
self
.
user_perm
.
get
(
'asset'
)
.
keys
()
assets
=
self
.
user_perm
.
get
(
'asset'
)
.
keys
()
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
},
perm
=
self
.
user_perm
)
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
assets
},
perm
=
self
.
user_perm
)
runner
=
MyRunner
(
res
)
runner
=
MyRunner
(
res
)
logger
.
debug
(
"Muti Muti file res:
%
s"
%
res
)
logger
.
debug
(
"Muti download file res:
%
s"
%
res
)
print
"匹配用户:
\n
"
for
inv
in
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
for
inv
in
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
print
inv
.
name
print
inv
.
name
print
print
tmp_dir
=
get_tmp_dir
()
logger
.
debug
(
'Download tmp dir:
%
s'
%
tmp_dir
)
while
True
:
while
True
:
tmp_dir
=
get_tmp_dir
()
logger
.
debug
(
'Download tmp dir:
%
s'
%
tmp_dir
)
print
"请输入文件路径(不支持目录)"
print
"请输入文件路径(不支持目录)"
file_path
=
raw_input
(
"
\033
[1;32mPath>:
\033
[0m "
)
.
strip
()
file_path
=
raw_input
(
"
\033
[1;32mPath>:
\033
[0m "
)
.
strip
()
if
file_path
==
'q'
:
if
file_path
==
'q'
:
break
break
runner
.
run
(
'fetch'
,
module_args
=
'src=
%
s dest=
%
s'
%
(
file_path
,
tmp_dir
),
pattern
=
pattern
)
runner
.
run
(
'fetch'
,
module_args
=
'src=
%
s dest=
%
s'
%
(
file_path
,
tmp_dir
),
pattern
=
pattern
)
ret
=
runner
.
get_result
()
ret
=
runner
.
results
logger
.
debug
(
'Download file result:
%
s'
%
ret
)
os
.
chdir
(
'/tmp'
)
os
.
chdir
(
'/tmp'
)
tmp_dir_name
=
os
.
path
.
basename
(
tmp_dir
)
tmp_dir_name
=
os
.
path
.
basename
(
tmp_dir
)
bash
(
'tar czf
%
s.tar.gz
%
s
'
%
(
tmp_dir
,
tmp_dir_name
))
bash
(
'tar czf
%
s.tar.gz
%
s
&& sz
%
s.tar.gz'
%
(
tmp_dir
,
tmp_dir_name
,
tmp_dir
))
if
ret
.
get
(
'failed'
):
if
ret
.
get
(
'failed'
):
print
ret
error
=
'文件名称:
%
s 下载失败: [
%
s ]
\n
下载成功 [
%
s ]'
%
\
error
=
'文件名称:
%
s 下载失败: [
%
s ]
\n
下载成功 [
%
s ]'
%
\
(
'
%
s.tar.gz'
%
tmp_dir_name
,
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'ok'
)))
(
'
%
s.tar.gz'
%
tmp_dir_name
,
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()
))
color_print
(
error
)
color_print
(
error
)
else
:
else
:
msg
=
'文件名称:
%
s 下载成功 [
%
s ]'
%
(
'
%
s.tar.gz'
%
tmp_dir_name
,
', '
.
join
(
ret
.
get
(
'ok'
)))
msg
=
'文件名称:
%
s 下载成功 [
%
s ]'
%
(
'
%
s.tar.gz'
%
tmp_dir_name
,
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()
))
color_print
(
msg
,
'green'
)
color_print
(
msg
,
'green'
)
print
print
except
IndexError
:
except
IndexError
:
...
...
jlog/models.py
View file @
267bb024
...
@@ -3,7 +3,7 @@ from django.db import models
...
@@ -3,7 +3,7 @@ from django.db import models
class
Log
(
models
.
Model
):
class
Log
(
models
.
Model
):
user
=
models
.
CharField
(
max_length
=
20
,
null
=
True
)
user
=
models
.
CharField
(
max_length
=
20
,
null
=
True
)
host
=
models
.
CharField
(
max_length
=
20
,
null
=
True
)
host
=
models
.
CharField
(
max_length
=
20
0
,
null
=
True
)
remote_ip
=
models
.
CharField
(
max_length
=
100
)
remote_ip
=
models
.
CharField
(
max_length
=
100
)
login_type
=
models
.
CharField
(
max_length
=
100
)
login_type
=
models
.
CharField
(
max_length
=
100
)
log_path
=
models
.
CharField
(
max_length
=
100
)
log_path
=
models
.
CharField
(
max_length
=
100
)
...
@@ -24,5 +24,13 @@ class Alert(models.Model):
...
@@ -24,5 +24,13 @@ class Alert(models.Model):
class
TtyLog
(
models
.
Model
):
class
TtyLog
(
models
.
Model
):
log
=
models
.
ForeignKey
(
Log
)
log
=
models
.
ForeignKey
(
Log
)
datetime
=
models
.
DateTimeField
()
datetime
=
models
.
DateTimeField
(
auto_now
=
True
)
cmd
=
models
.
CharField
(
max_length
=
200
)
cmd
=
models
.
CharField
(
max_length
=
200
)
class
ExecLog
(
models
.
Model
):
user
=
models
.
CharField
(
max_length
=
100
)
host
=
models
.
TextField
()
cmd
=
models
.
TextField
()
datetime
=
models
.
DateTimeField
(
auto_now
=
True
)
jperm/ansible_api.py
View file @
267bb024
...
@@ -117,9 +117,9 @@ class MyRunner(MyInventory):
...
@@ -117,9 +117,9 @@ class MyRunner(MyInventory):
"""
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
MyRunner
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
super
(
MyRunner
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
results
=
{}
self
.
results
_raw
=
{}
def
run
(
self
,
module_name
,
module_args
=
''
,
timeout
=
10
,
forks
=
10
,
pattern
=
''
,
def
run
(
self
,
module_name
=
'shell'
,
module_args
=
''
,
timeout
=
10
,
forks
=
10
,
pattern
=
''
,
sudo
=
False
,
sudo_user
=
'root'
,
sudo_pass
=
''
):
sudo
=
False
,
sudo_user
=
'root'
,
sudo_pass
=
''
):
"""
"""
run module from andible ad-hoc.
run module from andible ad-hoc.
...
@@ -137,23 +137,29 @@ class MyRunner(MyInventory):
...
@@ -137,23 +137,29 @@ class MyRunner(MyInventory):
become_user
=
sudo_user
,
become_user
=
sudo_user
,
become_pass
=
sudo_pass
become_pass
=
sudo_pass
)
)
self
.
results
=
hoc
.
run
()
self
.
results
_raw
=
hoc
.
run
()
return
self
.
results
return
self
.
results
_raw
def
get_result
(
self
):
@property
result
=
{
'failed'
:
{},
'ok'
:
[]}
def
results
(
self
):
dark
=
self
.
results
.
get
(
'dark'
)
"""
contacted
=
self
.
results
.
get
(
'contacted'
)
{'failed': {'localhost': ''}, 'ok': {'jumpserver': ''}}
"""
result
=
{
'failed'
:
{},
'ok'
:
{}}
dark
=
self
.
results_raw
.
get
(
'dark'
)
contacted
=
self
.
results_raw
.
get
(
'contacted'
)
if
dark
:
if
dark
:
for
host
,
info
in
dark
.
items
():
for
host
,
info
in
dark
.
items
():
result
[
'failed'
][
host
]
=
info
.
get
(
'msg'
)
result
[
'failed'
][
host
]
=
info
.
get
(
'msg'
)
if
contacted
:
if
contacted
:
for
host
,
info
in
contacted
.
items
():
for
host
,
info
in
contacted
.
items
():
if
info
.
get
(
'msg'
):
if
info
.
get
(
'failed'
):
result
[
'failed'
][
host
]
=
info
.
get
(
'msg'
)
result
[
'failed'
][
host
]
=
info
.
get
(
'msg'
)
+
info
.
get
(
'stderr'
,
''
)
elif
info
.
get
(
'stderr'
):
result
[
'failed'
][
host
]
=
info
.
get
(
'stderr'
)
+
str
(
info
.
get
(
'warnings'
))
else
:
else
:
result
[
'ok'
]
.
append
(
host
)
result
[
'ok'
]
[
host
]
=
info
.
get
(
'stdout'
)
return
result
return
result
...
@@ -163,9 +169,9 @@ class Command(MyInventory):
...
@@ -163,9 +169,9 @@ class Command(MyInventory):
"""
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
Command
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
super
(
Command
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
results
=
{}
self
.
results
_raw
=
{}
def
run
(
self
,
command
,
module_name
=
"command"
,
timeout
=
10
,
forks
=
10
,
pattern
=
'
*
'
):
def
run
(
self
,
command
,
module_name
=
"command"
,
timeout
=
10
,
forks
=
10
,
pattern
=
''
):
"""
"""
run command from andible ad-hoc.
run command from andible ad-hoc.
command : 必须是一个需要执行的命令字符串, 比如
command : 必须是一个需要执行的命令字符串, 比如
...
@@ -183,25 +189,34 @@ class Command(MyInventory):
...
@@ -183,25 +189,34 @@ class Command(MyInventory):
pattern
=
pattern
,
pattern
=
pattern
,
forks
=
forks
,
forks
=
forks
,
)
)
self
.
results
=
hoc
.
run
()
self
.
results
_raw
=
hoc
.
run
()
ret
=
{}
@property
def
result
(
self
):
result
=
{}
for
k
,
v
in
self
.
results_raw
.
items
():
if
k
==
'dark'
:
for
host
,
info
in
v
.
items
():
result
[
host
]
=
{
'dark'
:
info
.
get
(
'msg'
)}
elif
k
==
'contacted'
:
for
host
,
info
in
v
.
items
():
result
[
host
]
=
{}
if
info
.
get
(
'stdout'
):
result
[
host
][
'stdout'
]
=
info
.
get
(
'stdout'
)
elif
info
.
get
(
'stderr'
):
result
[
host
][
'stderr'
]
=
info
.
get
(
'stderr'
)
return
result
@property
def
state
(
self
):
result
=
{}
if
self
.
stdout
:
if
self
.
stdout
:
data
[
'ok'
]
=
self
.
stdout
result
[
'ok'
]
=
self
.
stdout
if
self
.
stderr
:
if
self
.
stderr
:
data
[
'err'
]
=
self
.
stderr
result
[
'err'
]
=
self
.
stderr
if
self
.
dark
:
if
self
.
dark
:
data
[
'dark'
]
=
self
.
dark
result
[
'dark'
]
=
self
.
dark
return
result
return
data
@property
def
raw_results
(
self
):
"""
get the ansible raw results.
"""
return
self
.
results
@property
@property
def
exec_time
(
self
):
def
exec_time
(
self
):
...
@@ -209,7 +224,7 @@ class Command(MyInventory):
...
@@ -209,7 +224,7 @@ class Command(MyInventory):
get the command execute time.
get the command execute time.
"""
"""
result
=
{}
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
all
=
self
.
results
_raw
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
{
result
[
key
]
=
{
"start"
:
value
.
get
(
"start"
),
"start"
:
value
.
get
(
"start"
),
...
@@ -223,7 +238,7 @@ class Command(MyInventory):
...
@@ -223,7 +238,7 @@ class Command(MyInventory):
get the comamnd standard output.
get the comamnd standard output.
"""
"""
result
=
{}
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
all
=
self
.
results
_raw
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
for
key
,
value
in
all
.
iteritems
():
result
[
key
]
=
value
.
get
(
"stdout"
)
result
[
key
]
=
value
.
get
(
"stdout"
)
return
result
return
result
...
@@ -234,7 +249,7 @@ class Command(MyInventory):
...
@@ -234,7 +249,7 @@ class Command(MyInventory):
get the command standard error.
get the command standard error.
"""
"""
result
=
{}
result
=
{}
all
=
self
.
results
.
get
(
"contacted"
)
all
=
self
.
results
_raw
.
get
(
"contacted"
)
for
key
,
value
in
all
.
iteritems
():
for
key
,
value
in
all
.
iteritems
():
if
value
.
get
(
"stderr"
)
or
value
.
get
(
"warnings"
):
if
value
.
get
(
"stderr"
)
or
value
.
get
(
"warnings"
):
result
[
key
]
=
{
result
[
key
]
=
{
...
@@ -247,7 +262,7 @@ class Command(MyInventory):
...
@@ -247,7 +262,7 @@ class Command(MyInventory):
"""
"""
get the dark results.
get the dark results.
"""
"""
return
self
.
results
.
get
(
"dark"
)
return
self
.
results
_raw
.
get
(
"dark"
)
class
Tasks
(
Command
):
class
Tasks
(
Command
):
...
...
jperm/models.py
View file @
267bb024
...
@@ -55,6 +55,6 @@ class PermPush(models.Model):
...
@@ -55,6 +55,6 @@ class PermPush(models.Model):
is_public_key
=
models
.
BooleanField
(
default
=
False
)
is_public_key
=
models
.
BooleanField
(
default
=
False
)
is_password
=
models
.
BooleanField
(
default
=
False
)
is_password
=
models
.
BooleanField
(
default
=
False
)
success
=
models
.
BooleanField
(
default
=
False
)
success
=
models
.
BooleanField
(
default
=
False
)
result
=
models
.
TextField
()
result
=
models
.
TextField
(
default
=
''
)
date_added
=
models
.
DateTimeField
(
auto_now
=
True
)
date_added
=
models
.
DateTimeField
(
auto_now
=
True
)
jperm/perm_api.py
View file @
267bb024
...
@@ -217,6 +217,7 @@ def gen_resource(ob, perm=None):
...
@@ -217,6 +217,7 @@ def gen_resource(ob, perm=None):
for
asset
in
ob
:
for
asset
in
ob
:
info
=
get_asset_info
(
asset
)
info
=
get_asset_info
(
asset
)
res
.
append
(
info
)
res
.
append
(
info
)
logger
.
debug
(
'生成res:
%
s'
%
res
)
return
res
return
res
...
@@ -295,9 +296,11 @@ def get_role_push_host(role):
...
@@ -295,9 +296,11 @@ def get_role_push_host(role):
asset_all
=
Asset
.
objects
.
all
()
asset_all
=
Asset
.
objects
.
all
()
asset_pushed
=
{}
asset_pushed
=
{}
for
push
in
pushs
:
for
push
in
pushs
:
print
push
.
result
asset_pushed
[
push
.
asset
]
=
{
'success'
:
push
.
success
,
'key'
:
push
.
is_public_key
,
'password'
:
push
.
is_password
,
asset_pushed
[
push
.
asset
]
=
{
'success'
:
push
.
success
,
'key'
:
push
.
is_public_key
,
'password'
:
push
.
is_password
,
'result'
:
push
.
result
}
'result'
:
push
.
result
}
asset_no_push
=
set
(
asset_all
)
-
set
(
asset_pushed
.
keys
())
asset_no_push
=
set
(
asset_all
)
-
set
(
asset_pushed
.
keys
())
print
asset_no_push
,
asset_pushed
return
asset_pushed
,
asset_no_push
return
asset_pushed
,
asset_no_push
...
...
jumpserver/api.py
View file @
267bb024
...
@@ -96,7 +96,7 @@ def get_role_key(user, role):
...
@@ -96,7 +96,7 @@ def get_role_key(user, role):
with
open
(
os
.
path
.
join
(
role
.
key_path
,
'id_rsa'
))
as
fk
:
with
open
(
os
.
path
.
join
(
role
.
key_path
,
'id_rsa'
))
as
fk
:
with
open
(
user_role_key_path
,
'w'
)
as
fu
:
with
open
(
user_role_key_path
,
'w'
)
as
fu
:
fu
.
write
(
fk
.
read
())
fu
.
write
(
fk
.
read
())
logger
.
debug
(
"创建新的用户角色key
%
s"
%
user_role_key_path
)
logger
.
debug
(
u
"创建新的用户角色key
%
s"
%
user_role_key_path
)
chown
(
user_role_key_path
,
user
.
username
)
chown
(
user_role_key_path
,
user
.
username
)
os
.
chmod
(
user_role_key_path
,
0600
)
os
.
chmod
(
user_role_key_path
,
0600
)
return
user_role_key_path
return
user_role_key_path
...
...
jumpserver/views.py
View file @
267bb024
...
@@ -313,14 +313,14 @@ def upload(request):
...
@@ -313,14 +313,14 @@ def upload(request):
runner
=
MyRunner
(
res
)
runner
=
MyRunner
(
res
)
runner
.
run
(
'copy'
,
module_args
=
'src=
%
s dest=
%
s directory_mode'
runner
.
run
(
'copy'
,
module_args
=
'src=
%
s dest=
%
s directory_mode'
%
(
upload_dir
,
upload_dir
),
pattern
=
'*'
)
%
(
upload_dir
,
upload_dir
),
pattern
=
'*'
)
ret
=
runner
.
get_result
()
ret
=
runner
.
results
logger
.
debug
(
ret
)
logger
.
debug
(
ret
)
if
ret
.
get
(
'failed'
):
if
ret
.
get
(
'failed'
):
error
=
'上传目录:
%
s <br> 上传失败: [
%
s ] <br>上传成功 [
%
s ]'
%
(
upload_dir
,
error
=
'上传目录:
%
s <br> 上传失败: [
%
s ] <br>上传成功 [
%
s ]'
%
(
upload_dir
,
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'failed'
)
.
keys
()),
', '
.
join
(
ret
.
get
(
'ok'
)))
', '
.
join
(
ret
.
get
(
'ok'
)
.
keys
()
))
return
HttpResponse
(
error
,
status
=
500
)
return
HttpResponse
(
error
,
status
=
500
)
msg
=
'上传目录:
%
s <br> 传送成功 [
%
s ]'
%
(
upload_dir
,
', '
.
join
(
ret
.
get
(
'ok'
)))
msg
=
'上传目录:
%
s <br> 传送成功 [
%
s ]'
%
(
upload_dir
,
', '
.
join
(
ret
.
get
(
'ok'
))
.
keys
()
)
return
HttpResponse
(
msg
)
return
HttpResponse
(
msg
)
return
my_render
(
'upload.html'
,
locals
(),
request
)
return
my_render
(
'upload.html'
,
locals
(),
request
)
...
@@ -345,7 +345,7 @@ def download(request):
...
@@ -345,7 +345,7 @@ def download(request):
res
=
gen_resource
({
'user'
:
user
,
'asset'
:
asset_select
})
res
=
gen_resource
({
'user'
:
user
,
'asset'
:
asset_select
})
runner
=
MyRunner
(
res
)
runner
=
MyRunner
(
res
)
runner
.
run
(
'fetch'
,
module_args
=
'src=
%
s dest=
%
s'
%
(
file_path
,
upload_dir
),
pattern
=
'*'
)
runner
.
run
(
'fetch'
,
module_args
=
'src=
%
s dest=
%
s'
%
(
file_path
,
upload_dir
),
pattern
=
'*'
)
logger
.
debug
(
runner
.
get_result
()
)
logger
.
debug
(
runner
.
results
)
os
.
chdir
(
'/tmp'
)
os
.
chdir
(
'/tmp'
)
tmp_dir_name
=
os
.
path
.
basename
(
upload_dir
)
tmp_dir_name
=
os
.
path
.
basename
(
upload_dir
)
tar_file
=
'
%
s.tar.gz'
%
upload_dir
tar_file
=
'
%
s.tar.gz'
%
upload_dir
...
...
run_websocket.py
View file @
267bb024
...
@@ -8,7 +8,7 @@ import sys
...
@@ -8,7 +8,7 @@ import sys
import
os.path
import
os.path
import
threading
import
threading
import
datetime
import
datetime
import
urllib
import
re
import
tornado.ioloop
import
tornado.ioloop
import
tornado.options
import
tornado.options
...
@@ -24,7 +24,7 @@ from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE
...
@@ -24,7 +24,7 @@ from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE
import
select
import
select
from
connect
import
Tty
,
User
,
Asset
,
PermRole
,
logger
,
get_object
,
PermRole
,
gen_resource
from
connect
import
Tty
,
User
,
Asset
,
PermRole
,
logger
,
get_object
,
PermRole
,
gen_resource
from
connect
import
TtyLog
,
Log
,
Session
,
user_have_perm
,
get_group_user_perm
,
Command
from
connect
import
TtyLog
,
Log
,
Session
,
user_have_perm
,
get_group_user_perm
,
MyRunner
,
ExecLog
try
:
try
:
import
simplejson
as
json
import
simplejson
as
json
...
@@ -218,7 +218,7 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
...
@@ -218,7 +218,7 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
self
.
id
=
0
self
.
id
=
0
self
.
user
=
None
self
.
user
=
None
self
.
role
=
None
self
.
role
=
None
self
.
cmd
=
None
self
.
runner
=
None
self
.
assets
=
[]
self
.
assets
=
[]
self
.
perm
=
{}
self
.
perm
=
{}
super
(
ExecHandler
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
super
(
ExecHandler
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
@@ -238,32 +238,50 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
...
@@ -238,32 +238,50 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
self
.
write_message
(
'No perm that role
%
s'
%
role_name
)
self
.
write_message
(
'No perm that role
%
s'
%
role_name
)
self
.
close
()
self
.
close
()
self
.
assets
=
self
.
perm
.
get
(
'role'
)
.
get
(
self
.
role
)
.
get
(
'asset'
)
self
.
assets
=
self
.
perm
.
get
(
'role'
)
.
get
(
self
.
role
)
.
get
(
'asset'
)
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
self
.
assets
,
'role'
:
self
.
role
})
res
=
gen_resource
({
'user'
:
self
.
user
,
'asset'
:
self
.
assets
,
'role'
:
self
.
role
})
logger
.
debug
(
'Web执行命令res:
%
s'
%
res
)
self
.
runner
=
MyRunner
(
res
)
self
.
cmd
=
Command
(
res
)
message
=
'有权限的主机: '
+
', '
.
join
([
asset
.
hostname
for
asset
in
self
.
assets
]
)
message
=
'有权限的主机:'
+
', '
.
join
([
asset
.
hostname
for
asset
in
self
.
assets
]
)
self
.
__class__
.
clients
.
append
(
self
)
self
.
write_message
(
message
)
self
.
write_message
(
message
)
def
on_message
(
self
,
message
):
def
on_message
(
self
,
message
):
data
=
json
.
loads
(
message
)
data
=
json
.
loads
(
message
)
pattern
=
data
.
get
(
'pattern'
,
''
)
pattern
=
data
.
get
(
'pattern'
,
''
)
command
=
data
.
get
(
'command'
,
''
)
command
=
data
.
get
(
'command'
,
''
)
asset_name_str
=
'
匹配主机:
'
asset_name_str
=
''
if
pattern
and
command
:
if
pattern
and
command
:
for
inv
in
self
.
cmd
.
inventory
.
get_hosts
(
pattern
=
pattern
):
for
inv
in
self
.
runner
.
inventory
.
get_hosts
(
pattern
=
pattern
):
asset_name_str
+=
'
\n
%
s
'
%
inv
.
name
asset_name_str
+=
'
%
s
'
%
inv
.
name
self
.
write_message
(
asset_name_str
)
self
.
write_message
(
'匹配主机: '
+
asset_name_str
)
self
.
write_message
(
'<span style="color: yellow">Ansible>
%
s</span>
\n\n
'
%
command
)
self
.
write_message
(
'<span style="color: yellow">Ansible>
%
s</span>
\n\n
'
%
command
)
result
=
self
.
cmd
.
run
(
module_name
=
'shell'
,
command
=
command
,
pattern
=
pattern
)
self
.
__class__
.
tasks
.
append
(
MyThread
(
target
=
self
.
run_cmd
,
args
=
(
command
,
pattern
)))
for
k
,
v
in
result
.
items
():
ExecLog
(
host
=
asset_name_str
,
cmd
=
command
)
.
save
()
for
host
,
output
in
v
.
items
():
if
k
==
'ok'
:
for
t
in
self
.
__class__
.
tasks
:
header
=
"<span style='color: green'>[
%
s =>
%
s]</span>
\n
"
%
(
host
,
'Ok'
)
if
t
.
is_alive
():
else
:
continue
header
=
"<span style='color: red'>[
%
s =>
%
s]</span>
\n
"
%
(
host
,
'failed'
)
try
:
self
.
write_message
(
header
)
t
.
setDaemon
(
True
)
self
.
write_message
(
output
)
t
.
start
()
self
.
write_message
(
'
\n
~o~ Task finished ~o~
\n
'
)
except
RuntimeError
:
pass
def
run_cmd
(
self
,
command
,
pattern
):
self
.
runner
.
run
(
'shell'
,
command
,
pattern
=
pattern
)
for
k
,
v
in
self
.
runner
.
results
.
items
():
for
host
,
output
in
v
.
items
():
if
k
==
'ok'
:
header
=
"<span style='color: green'>[
%
s =>
%
s]</span>
\n
"
%
(
host
,
'Ok'
)
else
:
header
=
"<span style='color: red'>[
%
s =>
%
s]</span>
\n
"
%
(
host
,
'failed'
)
self
.
write_message
(
header
)
self
.
write_message
(
output
)
self
.
write_message
(
'
\n
~o~ Task finished ~o~
\n
'
)
def
on_close
(
self
):
logger
.
debug
(
'关闭web_exec请求'
)
class
WebTerminalHandler
(
tornado
.
websocket
.
WebSocketHandler
):
class
WebTerminalHandler
(
tornado
.
websocket
.
WebSocketHandler
):
...
...
templates/exec_cmd.html
View file @
267bb024
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
<head>
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<meta
name=
"viewport"
content=
"width=320, initial-scale=1"
>
<meta
name=
"viewport"
content=
"width=320, initial-scale=1"
>
<title>
Chat
</title>
<title>
Jumpserver Exec Terminal
</title>
<style
type=
"text/css"
></style>
<style
type=
"text/css"
></style>
</head>
</head>
...
...
templates/jasset/asset_list.html
View file @
267bb024
...
@@ -194,7 +194,7 @@
...
@@ -194,7 +194,7 @@
title
:
title
,
title
:
title
,
maxmin
:
true
,
maxmin
:
true
,
shade
:
false
,
shade
:
false
,
area
:
[
'800px'
,
'
7
00px'
],
area
:
[
'800px'
,
'
6
00px'
],
content
:
new_url
+
data
+
'&check_assets='
+
check_assets
content
:
new_url
+
data
+
'&check_assets='
+
check_assets
});
});
//window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no');
//window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no');
...
@@ -282,7 +282,7 @@
...
@@ -282,7 +282,7 @@
type
:
2
,
type
:
2
,
title
:
title
,
title
:
title
,
maxmin
:
true
,
maxmin
:
true
,
area
:
[
'800px'
,
'
7
00px'
],
area
:
[
'800px'
,
'
6
00px'
],
shade
:
false
,
shade
:
false
,
content
:
new_url
content
:
new_url
});
});
...
...
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