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
818ead85
Commit
818ead85
authored
Nov 22, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Feature] 增加上传replay log的api
parent
7f9ce573
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
59 additions
and
20 deletions
+59
-20
.gitignore
.gitignore
+1
-0
api.py
apps/applications/api.py
+44
-6
models.py
apps/applications/models.py
+2
-3
serializers.py
apps/applications/serializers.py
+2
-2
terminal_list.html
apps/applications/templates/applications/terminal_list.html
+2
-2
terminal_update.html
.../applications/templates/applications/terminal_update.html
+2
-2
api_urls.py
apps/applications/urls/api_urls.py
+2
-1
proxy_log_offline_list.html
apps/audits/templates/audits/proxy_log_offline_list.html
+1
-1
proxy_log_online_list.html
apps/audits/templates/audits/proxy_log_online_list.html
+1
-1
views_urls.py
apps/audits/urls/views_urls.py
+0
-1
django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+1
-1
manage.py
apps/manage.py
+1
-0
No files found.
.gitignore
View file @
818ead85
...
...
@@ -24,3 +24,4 @@ tags
jumpserver.iml
.python-version
tmp/*
sessions/*
apps/applications/api.py
View file @
818ead85
...
...
@@ -2,11 +2,15 @@
#
from
collections
import
OrderedDict
import
copy
import
logging
import
os
from
rest_framework
import
viewsets
,
serializers
from
rest_framework.views
import
APIView
,
Response
from
rest_framework.permissions
import
AllowAny
from
django.shortcuts
import
get_object_or_404
from
django.utils
import
timezone
from
django.conf
import
settings
from
.models
import
Terminal
,
TerminalStatus
,
TerminalSession
,
TerminalTask
from
.serializers
import
TerminalSerializer
,
TerminalStatusSerializer
,
\
...
...
@@ -15,6 +19,8 @@ from .hands import IsSuperUserOrAppUser, IsAppUser, ProxyLog, \
IsSuperUserOrAppUserOrUserReadonly
from
common.utils
import
get_object_or_none
logger
=
logging
.
getLogger
(
__file__
)
class
TerminalViewSet
(
viewsets
.
ModelViewSet
):
queryset
=
Terminal
.
objects
.
filter
(
is_deleted
=
False
)
...
...
@@ -62,20 +68,28 @@ class TerminalStatusViewSet(viewsets.ModelViewSet):
session_serializer_class
=
TerminalSessionSerializer
def
create
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
handle_sessions
()
return
super
()
.
create
(
request
,
*
args
,
**
kwargs
)
def
handle_sessions
(
self
):
sessions_active
=
[]
for
session_data
in
request
.
data
.
get
(
"sessions"
,
[]):
for
session_data
in
self
.
request
.
data
.
get
(
"sessions"
,
[]):
session_data
[
"terminal"
]
=
self
.
request
.
user
.
terminal
.
id
_id
=
session_data
[
"id"
]
session
=
get_object_or_none
(
TerminalSession
,
id
=
_id
)
if
session
:
serializer
=
TerminalSessionSerializer
(
data
=
session_data
,
instance
=
session
)
serializer
=
TerminalSessionSerializer
(
data
=
session_data
,
instance
=
session
)
else
:
serializer
=
TerminalSessionSerializer
(
data
=
session_data
)
if
serializer
.
is_valid
():
serializer
.
save
()
else
:
logger
.
error
(
"session serializer is not valid {}"
.
format
(
serializer
.
errors
))
if
session_data
[
"is_finished"
]:
if
not
session_data
[
"is_finished"
]:
sessions_active
.
append
(
session_data
[
"id"
])
sessions_in_db_active
=
TerminalSession
.
objects
.
filter
(
...
...
@@ -83,13 +97,11 @@ class TerminalStatusViewSet(viewsets.ModelViewSet):
)
for
session
in
sessions_in_db_active
:
if
s
ession
.
id
not
in
sessions_active
:
if
s
tr
(
session
.
id
)
not
in
sessions_active
:
session
.
is_finished
=
True
session
.
date_end
=
timezone
.
now
()
session
.
save
()
return
super
()
.
create
(
request
,
*
args
,
**
kwargs
)
def
get_queryset
(
self
):
terminal_id
=
self
.
kwargs
.
get
(
"terminal"
,
None
)
if
terminal_id
:
...
...
@@ -135,3 +147,29 @@ class TerminalTaskViewSet(viewsets.ModelViewSet):
terminal
=
self
.
request
.
user
.
terminal
self
.
queryset
=
terminal
.
terminalstatus_set
.
all
()
return
self
.
queryset
class
SessionReplayAPI
(
APIView
):
permission_classes
=
(
IsSuperUserOrAppUser
,)
def
post
(
self
,
request
,
**
kwargs
):
session_id
=
kwargs
.
get
(
"pk"
,
None
)
session
=
get_object_or_404
(
TerminalSession
,
id
=
session_id
)
record_dir
=
settings
.
CONFIG
.
SESSION_RECORDE_DIR
date
=
session
.
date_start
.
strftime
(
"
%
Y-
%
m-
%
d"
)
record_dir
=
os
.
path
.
join
(
record_dir
,
date
)
record_filename
=
os
.
path
.
join
(
record_dir
,
str
(
session
.
id
))
if
not
os
.
path
.
exists
(
record_dir
):
os
.
makedirs
(
record_dir
)
archive_stream
=
request
.
data
.
get
(
"archive"
)
if
not
archive_stream
:
return
Response
(
"None file upload"
,
status
=
400
)
with
open
(
record_filename
,
'wb'
)
as
f
:
for
chunk
in
archive_stream
.
chunks
():
f
.
write
(
chunk
)
session
.
has_replay
=
True
session
.
save
()
return
Response
({
"session_id"
:
session
.
id
},
status
=
201
)
apps/applications/models.py
View file @
818ead85
...
...
@@ -69,9 +69,6 @@ class TerminalStatus(models.Model):
class
Meta
:
db_table
=
'terminal_status'
# def __str__(self):
# return "<{} status>".format(self.terminal.name)
class
TerminalSession
(
models
.
Model
):
LOGIN_FROM_CHOICES
=
(
...
...
@@ -85,6 +82,8 @@ class TerminalSession(models.Model):
system_user
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"System User"
))
login_from
=
models
.
CharField
(
max_length
=
2
,
choices
=
LOGIN_FROM_CHOICES
,
default
=
"ST"
)
is_finished
=
models
.
BooleanField
(
default
=
False
)
has_replay
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"Replay"
))
has_command
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"Command"
))
terminal
=
models
.
IntegerField
(
null
=
True
,
verbose_name
=
_
(
"Terminal"
))
date_start
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date Start"
))
date_end
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date End"
),
null
=
True
)
...
...
apps/applications/serializers.py
View file @
818ead85
...
...
@@ -19,11 +19,11 @@ class TerminalSerializer(serializers.ModelSerializer):
@staticmethod
def
get_session_connected
(
obj
):
return
ProxyLog
.
objects
.
filter
(
terminal
=
obj
.
name
,
is_finished
=
False
)
.
count
(
)
return
TerminalSession
.
objects
.
filter
(
terminal
=
obj
.
id
,
is_finished
=
False
)
@staticmethod
def
get_is_alive
(
obj
):
log
=
obj
.
terminal
heatbeat
_set
.
last
()
log
=
obj
.
terminal
status
_set
.
last
()
if
log
and
timezone
.
now
()
-
log
.
date_created
<
timezone
.
timedelta
(
seconds
=
600
):
return
True
else
:
...
...
apps/applications/templates/applications/terminal_list.html
View file @
818ead85
...
...
@@ -79,7 +79,7 @@ $(document).ready(function(){
var
reject_btn
=
'<a class="btn btn-xs btn-danger m-l-xs btn-del" data-id="99991937" data-name="99991938">{% trans "Reject" %}</a>'
.
replace
(
'99991937'
,
cellData
)
.
replace
(
'99991938'
,
rowData
.
name
);
var
connect_btn
=
'<a href="
{% url "applications:terminal-connect" pk=99991937 %}"
" class="btn btn-xs btn-warning btn-connect" >{% trans "Connect" %}</a> '
var
connect_btn
=
'<a href="" class="btn btn-xs btn-warning btn-connect" >{% trans "Connect" %}</a> '
.
replace
(
'99991937'
,
cellData
);
if
(
rowData
.
is_accepted
)
{
{
%
if
user
.
is_superuser
%
}
...
...
@@ -96,7 +96,7 @@ $(document).ready(function(){
],
ajax_url
:
'{% url "api-applications:terminal-list" %}'
,
columns
:
[{
data
:
function
(){
return
""
}},
{
data
:
"name"
},
{
data
:
"remote_addr"
},
{
data
:
"ssh_port"
},
{
data
:
"http_port"
},
{
data
:
"session_connected"
},
{
data
:
"is_a
live
"
},
{
data
:
'is_alive'
},
{
data
:
"id"
}],
{
data
:
"session_connected"
},
{
data
:
"is_a
ccepted
"
},
{
data
:
'is_alive'
},
{
data
:
"id"
}],
op_html
:
$
(
'#actions'
).
html
()
};
jumpserver
.
initDataTable
(
options
);
...
...
apps/applications/templates/applications/terminal_update.html
View file @
818ead85
...
...
@@ -33,8 +33,8 @@
<h3>
{% trans 'Info' %}
</h3>
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.
type
layout="horizontal" %}
{% bootstrap_field form.
url
layout="horizontal" %}
{% bootstrap_field form.
ssh_port
layout="horizontal" %}
{% bootstrap_field form.
http_port
layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
...
...
apps/applications/urls/api_urls.py
View file @
818ead85
...
...
@@ -12,11 +12,12 @@ app_name = 'applications'
router
=
routers
.
DefaultRouter
()
router
.
register
(
r'v1/terminal/(?P<terminal>[0-9]+)?/?status'
,
api
.
TerminalStatusViewSet
,
'terminal-status'
)
router
.
register
(
r'v1/terminal/(?P<terminal>[0-9]+)?/?sessions'
,
api
.
TerminalSessionViewSet
,
'terminal-sessions'
)
router
.
register
(
r'v1/terminal
$
'
,
api
.
TerminalViewSet
,
'terminal'
)
router
.
register
(
r'v1/terminal'
,
api
.
TerminalViewSet
,
'terminal'
)
urlpatterns
=
[
# url(r'^v1/terminate/connection/$', api.TerminateConnectionView.as_view(),
# name='terminate-connection')
url
(
r'^v1/sessions/(?P<pk>[0-9a-zA-Z\-_]+)/replay/$'
,
api
.
SessionReplayAPI
.
as_view
(),
name
=
'session-replay'
),
]
urlpatterns
+=
router
.
urls
apps/audits/templates/audits/proxy_log_offline_list.html
View file @
818ead85
...
...
@@ -123,7 +123,7 @@
window
.
location
.
reload
()
},
300
)
}
var
the_url
=
"
{% url 'api-applications:terminate-connection' %}
"
;
var
the_url
=
""
;
APIUpdateAttr
({
url
:
the_url
,
method
:
'POST'
,
body
:
JSON
.
stringify
(
data
),
success
:
success
,
success_message
:
'Terminate success'
});
}
$
(
document
).
ready
(
function
()
{
...
...
apps/audits/templates/audits/proxy_log_online_list.html
View file @
818ead85
...
...
@@ -137,7 +137,7 @@
window
.
location
.
reload
()
},
300
)
}
var
the_url
=
"
{% url 'api-applications:terminate-connection' %}
"
;
var
the_url
=
""
;
APIUpdateAttr
({
url
:
the_url
,
method
:
'POST'
,
body
:
JSON
.
stringify
(
data
),
success
:
success
,
success_message
:
'Terminate success'
});
}
$
(
document
).
ready
(
function
()
{
...
...
apps/audits/urls/views_urls.py
View file @
818ead85
...
...
@@ -10,7 +10,6 @@ urlpatterns = [
name
=
'proxy-log-online-list'
),
url
(
r'^proxy-log/(?P<pk>\d+)/$'
,
views
.
ProxyLogDetailView
.
as_view
(),
name
=
'proxy-log-detail'
),
# url(r'^proxy-log/(?P<pk>\d+)/commands$', views.ProxyLogCommandsListView.as_view(), name='proxy-log-commands-list'),
url
(
r'^command-log/$'
,
views
.
CommandLogListView
.
as_view
(),
name
=
'command-log-list'
),
url
(
r'^login-log/$'
,
views
.
LoginLogListView
.
as_view
(),
...
...
apps/locale/zh/LC_MESSAGES/django.mo
View file @
818ead85
No preview for this file type
apps/locale/zh/LC_MESSAGES/django.po
View file @
818ead85
...
...
@@ -1375,7 +1375,7 @@ msgstr "终止所选"
#: audits/views.py:72 audits/views.py:209 audits/views.py:263
#: templates/_nav.html:56
msgid "Audits"
msgstr "审计"
msgstr "审计
中心
"
#: audits/views.py:73 audits/views.py:264
msgid "Proxy log list"
...
...
apps/manage.py
View file @
818ead85
...
...
@@ -6,6 +6,7 @@ import errno
if
__name__
==
"__main__"
:
try
:
os
.
makedirs
(
'../logs'
)
os
.
makedirs
(
'../sessions'
)
except
:
pass
...
...
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