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