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
1f26e49f
Commit
1f26e49f
authored
Dec 02, 2015
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成web批量命令执行
parent
104ee779
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
106 additions
and
75 deletions
+106
-75
connect.py
connect.py
+1
-1
urls.py
jumpserver/urls.py
+1
-0
views.py
jumpserver/views.py
+5
-0
run_websocket.py
run_websocket.py
+58
-18
asset_list.html
templates/jasset/asset_list.html
+41
-0
log_monitor.html
templates/jlog/log_monitor.html
+0
-56
No files found.
connect.py
View file @
1f26e49f
...
@@ -24,7 +24,7 @@ if django.get_version() != '1.6':
...
@@ -24,7 +24,7 @@ if django.get_version() != '1.6':
from
django.contrib.sessions.models
import
Session
from
django.contrib.sessions.models
import
Session
from
jumpserver.api
import
ServerError
,
User
,
Asset
,
PermRole
,
AssetGroup
,
get_object
,
mkdir
,
get_asset_info
,
get_role
from
jumpserver.api
import
ServerError
,
User
,
Asset
,
PermRole
,
AssetGroup
,
get_object
,
mkdir
,
get_asset_info
,
get_role
from
jumpserver.api
import
logger
,
Log
,
TtyLog
,
get_role_key
,
CRYPTOR
,
bash
,
get_tmp_dir
from
jumpserver.api
import
logger
,
Log
,
TtyLog
,
get_role_key
,
CRYPTOR
,
bash
,
get_tmp_dir
from
jperm.perm_api
import
gen_resource
,
get_group_asset_perm
,
get_group_user_perm
,
user_have_perm
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
...
...
jumpserver/urls.py
View file @
1f26e49f
...
@@ -8,6 +8,7 @@ urlpatterns = patterns('',
...
@@ -8,6 +8,7 @@ urlpatterns = patterns('',
(
r'^skin_config/$'
,
'jumpserver.views.skin_config'
),
(
r'^skin_config/$'
,
'jumpserver.views.skin_config'
),
(
r'^login/$'
,
'jumpserver.views.Login'
),
(
r'^login/$'
,
'jumpserver.views.Login'
),
(
r'^logout/$'
,
'jumpserver.views.Logout'
),
(
r'^logout/$'
,
'jumpserver.views.Logout'
),
(
r'^exec_cmd/$'
,
'jumpserver.views.exec_cmd'
),
(
r'^file/upload/$'
,
'jumpserver.views.upload'
),
(
r'^file/upload/$'
,
'jumpserver.views.upload'
),
(
r'^file/download/$'
,
'jumpserver.views.download'
),
(
r'^file/download/$'
,
'jumpserver.views.download'
),
(
r'^setting'
,
'jumpserver.views.setting'
),
(
r'^setting'
,
'jumpserver.views.setting'
),
...
...
jumpserver/views.py
View file @
1f26e49f
...
@@ -360,3 +360,8 @@ def download(request):
...
@@ -360,3 +360,8 @@ def download(request):
return
render_to_response
(
'download.html'
,
locals
(),
context_instance
=
RequestContext
(
request
))
return
render_to_response
(
'download.html'
,
locals
(),
context_instance
=
RequestContext
(
request
))
@login_required
(
login_url
=
'/login'
)
def
exec_cmd
(
request
):
role_name
=
request
.
GET
.
get
(
'role_name'
)
web_terminal_uri
=
'ws://
%
s/exec?role=
%
s'
%
(
WEB_SOCKET_HOST
,
role_name
)
return
my_render
(
'exec_cmd.html'
,
locals
(),
request
)
run_websocket.py
View file @
1f26e49f
...
@@ -23,8 +23,8 @@ from tornado.options import define, options
...
@@ -23,8 +23,8 @@ 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
import
select
from
connect
import
Tty
,
User
,
Asset
,
PermRole
,
logger
,
get_object
from
connect
import
Tty
,
User
,
Asset
,
PermRole
,
logger
,
get_object
,
PermRole
,
gen_resource
from
connect
import
TtyLog
,
Log
,
Session
,
user_have_perm
from
connect
import
TtyLog
,
Log
,
Session
,
user_have_perm
,
get_group_user_perm
,
Command
try
:
try
:
import
simplejson
as
json
import
simplejson
as
json
...
@@ -67,22 +67,6 @@ def require_auth(role='user'):
...
@@ -67,22 +67,6 @@ def require_auth(role='user'):
except
AttributeError
:
except
AttributeError
:
pass
pass
logger
.
warning
(
'Websocket: Request auth failed.'
)
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
_deco2
return
_deco
return
_deco
...
@@ -138,6 +122,7 @@ class Application(tornado.web.Application):
...
@@ -138,6 +122,7 @@ class Application(tornado.web.Application):
(
r'/monitor'
,
MonitorHandler
),
(
r'/monitor'
,
MonitorHandler
),
(
r'/terminal'
,
WebTerminalHandler
),
(
r'/terminal'
,
WebTerminalHandler
),
(
r'/kill'
,
WebTerminalKillHandler
),
(
r'/kill'
,
WebTerminalKillHandler
),
(
r'/exec'
,
ExecHandler
),
]
]
setting
=
{
setting
=
{
...
@@ -225,6 +210,61 @@ class WebTerminalKillHandler(tornado.web.RequestHandler):
...
@@ -225,6 +210,61 @@ class WebTerminalKillHandler(tornado.web.RequestHandler):
logger
.
debug
(
'Websocket: web terminal client num:
%
s'
%
len
(
WebTerminalHandler
.
clients
))
logger
.
debug
(
'Websocket: web terminal client num:
%
s'
%
len
(
WebTerminalHandler
.
clients
))
class
ExecHandler
(
tornado
.
websocket
.
WebSocketHandler
):
clients
=
[]
tasks
=
[]
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
id
=
0
self
.
user
=
None
self
.
role
=
None
self
.
cmd
=
None
self
.
assets
=
[]
self
.
perm
=
{}
super
(
ExecHandler
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
check_origin
(
self
,
origin
):
return
True
@require_auth
(
'user'
)
def
open
(
self
):
logger
.
debug
(
'Websocket: Open exec request'
)
role_name
=
self
.
get_argument
(
'role'
,
'dev'
)
self
.
role
=
get_object
(
PermRole
,
name
=
role_name
)
self
.
perm
=
get_group_user_perm
(
self
.
user
)
roles
=
self
.
perm
.
get
(
'role'
)
.
keys
()
if
self
.
role
not
in
roles
:
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
.
write_message
(
message
)
def
on_message
(
self
,
message
):
data
=
json
.
loads
(
message
)
pattern
=
data
.
get
(
'pattern'
,
''
)
command
=
data
.
get
(
'command'
,
''
)
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
)
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\n
'
)
class
WebTerminalHandler
(
tornado
.
websocket
.
WebSocketHandler
):
class
WebTerminalHandler
(
tornado
.
websocket
.
WebSocketHandler
):
clients
=
[]
clients
=
[]
tasks
=
[]
tasks
=
[]
...
...
templates/jasset/asset_list.html
View file @
1f26e49f
...
@@ -148,6 +148,7 @@
...
@@ -148,6 +148,7 @@
<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"
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=
"更新全部"
/>
<input
type=
"button"
id=
"asset_update_all"
class=
"btn btn-primary btn-sm"
name=
"update_button"
value=
"更新全部"
/>
<input
type=
"button"
id=
"exec_cmd"
class=
"btn btn-sm btn-danger"
name=
"exec_cmd"
value=
"执行命令"
/>
</div>
</div>
{% include 'paginator.html' %}
{% include 'paginator.html' %}
</div>
</div>
...
@@ -175,6 +176,46 @@
...
@@ -175,6 +176,46 @@
}
}
});
});
$
(
'#exec_cmd'
).
click
(
function
(){
var
url
=
'/jlog/get_role_name/?id={{ user.id }}'
;
var
href
=
$
(
this
).
attr
(
'href'
);
$
.
ajax
({
type
:
'GET'
,
url
:
url
,
data
:
{},
success
:
function
(
data
){
var
dataArray
=
data
.
split
(
','
);
if
(
dataArray
.
length
==
1
&&
data
!=
'error'
){
var
title
=
'Jumpserver Exec Terminal'
;
layer
.
open
({
type
:
2
,
title
:
title
,
maxmin
:
true
,
shade
:
false
,
area
:
[
'628px'
,
'452px'
],
content
:
new_url
+
data
});
//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');
}
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='
+
hostname
+
'>'
+
value
+
'</a> '
});
layer
.
alert
(
aUrl
,
{
skin
:
'layui-layer-molv'
,
title
:
'多个角色,请选择一个连接'
,
shade
:
false
,
closeBtn
:
0
})
}
}
});
return
false
});
$
(
'.conn'
).
click
(
function
(){
$
(
'.conn'
).
click
(
function
(){
var
url
=
'/jlog/get_role_name/?id='
+
$
(
this
).
attr
(
'value'
);
var
url
=
'/jlog/get_role_name/?id='
+
$
(
this
).
attr
(
'value'
);
var
href
=
$
(
this
).
attr
(
'href'
);
var
href
=
$
(
this
).
attr
(
'href'
);
...
...
templates/jlog/log_monitor.html
deleted
100644 → 0
View file @
104ee779
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
Jumpserver | 开源跳板机系统
</title>
<link
rel=
"shortcut icon"
href=
"/static/img/facio.ico"
type=
"image/x-icon"
>
{% include 'link_css.html' %}
{% include 'head_script.html' %}
</head>
<body>
<div
id=
"wrapper"
>
<div
class=
"col-lg-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
实时监控
</h5>
</div>
<div
class=
"ibox-content blank-panel"
id=
"content"
style=
"background-color: #0b0b0b; color: #006621; height: 500px; padding: 20px;"
>
你好
<br>
</div>
</div>
</div>
</div>
</body>
{% block self_footer_js %}
<script>
function
monitor
(){
var
wsUri
=
'ws://j:8080/send'
;
var
ws
=
new
WebSocket
(
wsUri
);
ws
.
onopen
=
function
(
evt
){
$
(
'#content'
).
append
(
'Connect websocket success'
+
'<br />'
);
ws
.
send
(
'Start'
)
};
ws
.
onmessage
=
function
(
evt
){
console
.
log
(
evt
.
data
);
$
(
'#content'
).
append
(
evt
.
data
.
replace
(
/
\n
|
\r
|
(\r\n)
|
(\u
0085
)
|
(\u
2028
)
|
(\u
2029
)
/g
,
'<br>'
));
};
ws
.
onclose
=
function
(
evt
){
$
(
'#content'
).
append
(
'Disconnect with websocket'
)
}
}
monitor
();
</script>
{% endblock %}
</html>
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