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
9 years ago
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改exec 和 MyRUnner
parent
255e3a04
master
auditor_jym
audits
dev
dev_beta
dev_beta_db
gengmei
lagacy-0.4.0
node_service
password
rbac
restrict_access
test
v52
wph
1.5.2
1.5.1
1.5.0
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.1
1.1.0
1.0.0
0.3.3
0.3.2
0.3.2-rc2
0.3.1
0.3.0-beta
v1.4.10
v1.4.7
v1.4.4
No related merge requests found
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
99 additions
and
55 deletions
+99
-55
connect.py
connect.py
+0
-0
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
+30
-12
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
This diff is collapsed.
Click to expand it.
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
)
This diff is collapsed.
Click to expand it.
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
):
...
...
This diff is collapsed.
Click to expand it.
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
)
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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,24 +238,38 @@ 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
():
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'
)
...
...
@@ -263,8 +277,12 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
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
):
clients
=
[]
...
...
This diff is collapsed.
Click to expand it.
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>
...
...
This diff is collapsed.
Click to expand it.
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
});
...
...
This diff is collapsed.
Click to expand it.
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