Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gjl2004yn
jumpserver
提交
968b395b
J
jumpserver
项目概览
gjl2004yn
/
jumpserver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jumpserver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
968b395b
编写于
1月 22, 2018
作者:
baltery
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'es' into dev
上级
7f188219
0a931bbf
变更
32
隐藏空白更改
内联
并排
Showing
32 changed file
with
615 addition
and
142 deletion
+615
-142
apps/assets/views/cluster.py
apps/assets/views/cluster.py
+0
-5
apps/common/api.py
apps/common/api.py
+0
-5
apps/common/fields.py
apps/common/fields.py
+0
-1
apps/common/forms.py
apps/common/forms.py
+36
-8
apps/common/models.py
apps/common/models.py
+19
-6
apps/common/templates/common/_add_terminal_command_storage_modal.html
...templates/common/_add_terminal_command_storage_modal.html
+21
-0
apps/common/templates/common/basic_setting.html
apps/common/templates/common/basic_setting.html
+3
-0
apps/common/templates/common/email_setting.html
apps/common/templates/common/email_setting.html
+3
-0
apps/common/templates/common/ldap_setting.html
apps/common/templates/common/ldap_setting.html
+3
-0
apps/common/templates/common/terminal_setting.html
apps/common/templates/common/terminal_setting.html
+130
-0
apps/common/urls/view_urls.py
apps/common/urls/view_urls.py
+1
-0
apps/common/views.py
apps/common/views.py
+33
-2
apps/jumpserver/settings.py
apps/jumpserver/settings.py
+14
-1
apps/locale/zh/LC_MESSAGES/django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
apps/locale/zh/LC_MESSAGES/django.po
apps/locale/zh/LC_MESSAGES/django.po
+138
-85
apps/terminal/api.py
apps/terminal/api.py
+14
-3
apps/terminal/backends/__init__.py
apps/terminal/backends/__init__.py
+33
-3
apps/terminal/backends/command/base.py
apps/terminal/backends/command/base.py
+6
-0
apps/terminal/backends/command/db.py
apps/terminal/backends/command/db.py
+28
-8
apps/terminal/backends/command/es.py
apps/terminal/backends/command/es.py
+38
-0
apps/terminal/backends/command/models.py
apps/terminal/backends/command/models.py
+21
-0
apps/terminal/backends/command/multi.py
apps/terminal/backends/command/multi.py
+27
-0
apps/terminal/forms.py
apps/terminal/forms.py
+1
-1
apps/terminal/models.py
apps/terminal/models.py
+31
-0
apps/terminal/serializers.py
apps/terminal/serializers.py
+3
-3
apps/terminal/templates/terminal/terminal_modal_accept.html
apps/terminal/templates/terminal/terminal_modal_accept.html
+1
-0
apps/terminal/templates/terminal/terminal_update.html
apps/terminal/templates/terminal/terminal_update.html
+1
-0
apps/terminal/templatetags/terminal_tags.py
apps/terminal/templatetags/terminal_tags.py
+3
-4
apps/terminal/urls/api_urls.py
apps/terminal/urls/api_urls.py
+2
-1
apps/terminal/views/command.py
apps/terminal/views/command.py
+3
-3
apps/terminal/views/session.py
apps/terminal/views/session.py
+2
-2
apps/users/forms.py
apps/users/forms.py
+0
-1
未找到文件。
apps/assets/views/cluster.py
浏览文件 @
968b395b
...
...
@@ -60,11 +60,6 @@ class ClusterUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView)
success_url
=
reverse_lazy
(
'assets:cluster-list'
)
success_message
=
update_success_msg
def
form_valid
(
self
,
form
):
cluster
=
form
.
save
(
commit
=
False
)
cluster
.
save
()
return
super
().
form_valid
(
form
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'assets'
),
...
...
apps/common/api.py
浏览文件 @
968b395b
...
...
@@ -63,8 +63,6 @@ class LDAPTestingAPI(APIView):
search_filter
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_FILTER"
]
attr_map
=
serializer
.
validated_data
[
"AUTH_LDAP_USER_ATTR_MAP"
]
print
(
serializer
.
validated_data
)
try
:
attr_map
=
json
.
loads
(
attr_map
)
except
json
.
JSONDecodeError
:
...
...
@@ -77,9 +75,6 @@ class LDAPTestingAPI(APIView):
except
Exception
as
e
:
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
print
(
search_ou
)
print
(
search_filter
%
({
"user"
:
"*"
}))
print
(
attr_map
.
values
())
ok
=
conn
.
search
(
search_ou
,
search_filter
%
({
"user"
:
"*"
}),
attributes
=
list
(
attr_map
.
values
()))
if
not
ok
:
...
...
apps/common/fields.py
浏览文件 @
968b395b
...
...
@@ -18,7 +18,6 @@ class DictField(forms.Field):
# we don't need to handle that explicitly.
if
isinstance
(
value
,
six
.
string_types
):
try
:
print
(
value
)
value
=
json
.
loads
(
value
)
return
value
except
json
.
JSONDecodeError
:
...
...
apps/common/forms.py
浏览文件 @
968b395b
...
...
@@ -4,7 +4,9 @@ import json
from
django
import
forms
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.html
import
escape
from
django.db
import
transaction
from
django.conf
import
settings
from
.models
import
Setting
from
.fields
import
DictField
...
...
@@ -30,28 +32,32 @@ def to_form_value(value):
class
BaseForm
(
forms
.
Form
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
().
__init__
(
*
args
,
**
kwargs
)
settings
=
Setting
.
objects
.
all
()
db_
settings
=
Setting
.
objects
.
all
()
for
name
,
field
in
self
.
fields
.
items
():
db_value
=
getattr
(
settings
,
name
).
value
if
db_value
:
db_value
=
getattr
(
db_settings
,
name
).
value
django_value
=
getattr
(
settings
,
name
)
if
hasattr
(
settings
,
name
)
else
None
if
db_value
is
False
or
db_value
:
field
.
initial
=
to_form_value
(
db_value
)
elif
django_value
is
False
or
django_value
:
field
.
initial
=
django_value
def
save
(
self
):
def
save
(
self
,
category
=
"default"
):
if
not
self
.
is_bound
:
raise
ValueError
(
"Form is not bound"
)
settings
=
Setting
.
objects
.
all
()
db_
settings
=
Setting
.
objects
.
all
()
if
self
.
is_valid
():
with
transaction
.
atomic
():
for
name
,
value
in
self
.
cleaned_data
.
items
():
field
=
self
.
fields
[
name
]
if
isinstance
(
field
.
widget
,
forms
.
PasswordInput
)
and
not
value
:
continue
if
value
==
to_form_value
(
getattr
(
settings
,
name
).
value
):
if
value
==
to_form_value
(
getattr
(
db_
settings
,
name
).
value
):
continue
defaults
=
{
'name'
:
name
,
'category'
:
category
,
'value'
:
to_model_value
(
value
)
}
Setting
.
objects
.
update_or_create
(
defaults
=
defaults
,
name
=
name
)
...
...
@@ -126,6 +132,28 @@ class LDAPSettingForm(BaseForm):
AUTH_LDAP_START_TLS
=
forms
.
BooleanField
(
label
=
_
(
"Use SSL"
),
initial
=
False
,
required
=
False
)
AUTH_LDAP
=
forms
.
BooleanField
(
label
=
_
(
"Enable LDAP Auth"
),
initial
=
False
,
required
=
False
class
TerminalSettingForm
(
BaseForm
):
SORT_BY_CHOICES
=
(
(
'hostname'
,
_
(
'Hostname'
)),
(
'ip'
,
_
(
'IP'
)),
)
TERMINAL_ASSET_LIST_SORT_BY
=
forms
.
ChoiceField
(
choices
=
SORT_BY_CHOICES
,
initial
=
'hostname'
,
label
=
_
(
"List sort by"
)
)
TERMINAL_HEARTBEAT_INTERVAL
=
forms
.
IntegerField
(
initial
=
5
,
label
=
_
(
"Heartbeat interval"
),
help_text
=
_
(
"Units: seconds"
)
)
TERMINAL_PASSWORD_AUTH
=
forms
.
BooleanField
(
initial
=
True
,
required
=
False
,
label
=
_
(
"Password auth"
)
)
TERMINAL_PUBLIC_KEY_AUTH
=
forms
.
BooleanField
(
initial
=
True
,
required
=
False
,
label
=
_
(
"Public key auth"
)
)
TERMINAL_COMMAND_STORAGE
=
DictField
(
label
=
_
(
"Command storage"
),
help_text
=
_
(
"Set terminal storage setting, `default` is the using as default,"
"You can set other storage and some terminal using"
)
)
apps/common/models.py
浏览文件 @
968b395b
...
...
@@ -2,6 +2,7 @@ import json
import
ldap
from
django.db
import
models
from
django.db.utils
import
ProgrammingError
,
OperationalError
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
django_auth_ldap.config
import
LDAPSearch
...
...
@@ -24,6 +25,7 @@ class SettingManager(models.Manager):
class
Setting
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
"Name"
))
value
=
models
.
TextField
(
verbose_name
=
_
(
"Value"
))
category
=
models
.
CharField
(
max_length
=
128
,
default
=
"default"
)
enabled
=
models
.
BooleanField
(
verbose_name
=
_
(
"Enabled"
),
default
=
True
)
comment
=
models
.
TextField
(
verbose_name
=
_
(
"Comment"
))
...
...
@@ -33,17 +35,28 @@ class Setting(models.Model):
return
self
.
name
@
property
def
value_
(
self
):
def
cleaned_value
(
self
):
try
:
return
json
.
loads
(
self
.
value
)
except
json
.
JSONDecodeError
:
return
None
@
cleaned_value
.
setter
def
cleaned_value
(
self
,
item
):
try
:
v
=
json
.
dumps
(
item
)
self
.
value
=
v
except
json
.
JSONDecodeError
as
e
:
raise
ValueError
(
"Json dump error: {}"
.
format
(
str
(
e
)))
@
classmethod
def
refresh_all_settings
(
cls
):
settings_list
=
cls
.
objects
.
all
()
for
setting
in
settings_list
:
setting
.
refresh_setting
()
try
:
settings_list
=
cls
.
objects
.
all
()
for
setting
in
settings_list
:
setting
.
refresh_setting
()
except
(
ProgrammingError
,
OperationalError
):
pass
def
refresh_setting
(
self
):
try
:
...
...
@@ -53,9 +66,9 @@ class Setting(models.Model):
setattr
(
settings
,
self
.
name
,
value
)
if
self
.
name
==
"AUTH_LDAP"
:
if
self
.
value_
and
settings
.
AUTH_LDAP_BACKEND
not
in
settings
.
AUTHENTICATION_BACKENDS
:
if
self
.
cleaned_value
and
settings
.
AUTH_LDAP_BACKEND
not
in
settings
.
AUTHENTICATION_BACKENDS
:
settings
.
AUTHENTICATION_BACKENDS
.
insert
(
0
,
settings
.
AUTH_LDAP_BACKEND
)
elif
not
self
.
value_
and
settings
.
AUTH_LDAP_BACKEND
in
settings
.
AUTHENTICATION_BACKENDS
:
elif
not
self
.
cleaned_value
and
settings
.
AUTH_LDAP_BACKEND
in
settings
.
AUTHENTICATION_BACKENDS
:
settings
.
AUTHENTICATION_BACKENDS
.
remove
(
settings
.
AUTH_LDAP_BACKEND
)
if
self
.
name
==
"AUTH_LDAP_SEARCH_FILTER"
:
...
...
apps/common/templates/common/_add_terminal_command_storage_modal.html
0 → 100644
浏览文件 @
968b395b
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}add_command_storage_model{% endblock %}
{% block modal_title%}{% trans "Add command storage" %}{% endblock %}
{% block modal_body %}
<form
method=
"post"
action=
""
id=
"add_command_storage_form"
>
{% csrf_token %}
<div
class=
"form-group"
>
<label
class=
"control-label"
for=
"id_assets"
>
{% trans "Template" %}
</label>
<a
href=
"{% url 'assets:asset-export' %}"
style=
"display: block"
>
{% trans 'Download' %}
</a>
</div>
<div
class=
"form-group"
>
<label
class=
"control-label"
for=
"id_users"
>
{% trans "Asset csv file" %}
</label>
<input
id=
"id_assets"
type=
"file"
name=
"file"
/>
<span
class=
"help-block red-fonts"
>
{% trans 'If set id, will use this id update asset existed' %}
</span>
</div>
</form>
{% endblock %}
{% block modal_confirm_id %}btn_asset_import{% endblock %}
apps/common/templates/common/basic_setting.html
浏览文件 @
968b395b
...
...
@@ -20,6 +20,9 @@
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
apps/common/templates/common/email_setting.html
浏览文件 @
968b395b
...
...
@@ -20,6 +20,9 @@
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
apps/common/templates/common/ldap_setting.html
浏览文件 @
968b395b
...
...
@@ -20,6 +20,9 @@
<li
class=
"active"
>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
apps/common/templates/common/terminal_setting.html
0 → 100644
浏览文件 @
968b395b
{% extends 'base.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% load common_tags %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li>
<a
href=
"{% url 'settings:basic-setting' %}"
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Basic setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:email-setting' %}"
class=
"text-center"
><i
class=
"fa fa-envelope"
></i>
{% trans 'Email setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
<li
class=
"active"
>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
<div
class=
"col-sm-12"
style=
"padding-left:0"
>
<div
class=
"ibox-content"
style=
"border-width: 0;padding-top: 40px;"
>
<form
action=
""
method=
"post"
class=
"form-horizontal"
>
{% if form.non_field_errors %}
<div
class=
"alert alert-danger"
>
{{ form.non_field_errors }}
</div>
{% endif %}
{% csrf_token %}
<h3>
{% trans "Basic setting" %}
</h3>
{% for field in form %}
{% if not field.field|is_bool_field %}
{% bootstrap_field field layout="horizontal" %}
{% else %}
<div
class=
"form-group"
>
<label
for=
"{{ field.id_for_label }}"
class=
"col-sm-2 control-label"
>
{{ field.label }}
</label>
<div
class=
"col-sm-8"
>
<div
class=
"col-sm-1"
>
{{ field }}
</div>
<div
class=
"col-sm-9"
>
<span
class=
"help-block"
>
{{ field.help_text }}
</span>
</div>
</div>
</div>
{% endif %}
{% endfor %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans "Command storage" %}
</h3>
<table
class=
"table table-hover "
id=
"task-history-list-table"
>
<thead>
<tr>
<th>
{% trans 'Name' %}
</th>
<th>
{% trans 'Type' %}
</th>
</tr>
</thead>
<tbody>
{% for name, setting in command_storage.items %}
<tr>
<td>
{{ name }}
</td>
<td>
{{ setting.TYPE }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{#
<button
class=
"btn btn-default btn-circle btn-add-command-storage"
data-toggle=
"modal"
data-target=
"#add_command_storage_model"
tabindex=
"0"
type=
"button"
><i
class=
"fa fa-plus"
></i></button>
#}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans "Replay storage" %}
</h3>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<button
class=
"btn btn-default"
type=
"reset"
>
{% trans 'Reset' %}
</button>
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% include 'common/_add_terminal_command_storage_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
})
.
on
(
"
click
"
,
"
.btn-test
"
,
function
()
{
var
data
=
{};
var
form
=
$
(
"
form
"
).
serializeArray
();
$
.
each
(
form
,
function
(
i
,
field
)
{
data
[
field
.
name
]
=
field
.
value
;
});
var
the_url
=
"
{% url 'api-common:ldap-testing' %}
"
;
function
error
(
message
)
{
toastr
.
error
(
message
)
}
function
success
(
message
)
{
toastr
.
success
(
message
.
msg
)
}
APIUpdateAttr
({
url
:
the_url
,
body
:
JSON
.
stringify
(
data
),
method
:
"
POST
"
,
flash_message
:
false
,
success
:
success
,
error
:
error
});
})
.
on
(
'
click
'
,
''
,
function
()
{
})
</script>
{% endblock %}
apps/common/urls/view_urls.py
浏览文件 @
968b395b
...
...
@@ -10,4 +10,5 @@ urlpatterns = [
url
(
r
'^$'
,
views
.
BasicSettingView
.
as_view
(),
name
=
'basic-setting'
),
url
(
r
'^email/$'
,
views
.
EmailSettingView
.
as_view
(),
name
=
'email-setting'
),
url
(
r
'^ldap/$'
,
views
.
LDAPSettingView
.
as_view
(),
name
=
'ldap-setting'
),
url
(
r
'^terminal/$'
,
views
.
TerminalSettingView
.
as_view
(),
name
=
'terminal-setting'
),
]
apps/common/views.py
浏览文件 @
968b395b
from
django.views.generic
import
View
,
TemplateView
from
django.views.generic
import
TemplateView
from
django.shortcuts
import
render
,
redirect
from
django.contrib
import
messages
from
django.utils.translation
import
ugettext
as
_
from
django.conf
import
settings
from
.forms
import
EmailSettingForm
,
LDAPSettingForm
,
BasicSettingForm
from
.forms
import
EmailSettingForm
,
LDAPSettingForm
,
BasicSettingForm
,
\
TerminalSettingForm
from
.models
import
Setting
from
.mixins
import
AdminUserRequiredMixin
from
.signals
import
ldap_auth_enable
...
...
@@ -86,3 +89,31 @@ class LDAPSettingView(AdminUserRequiredMixin, TemplateView):
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
return
render
(
request
,
self
.
template_name
,
context
)
class
TerminalSettingView
(
AdminUserRequiredMixin
,
TemplateView
):
form_class
=
TerminalSettingForm
template_name
=
"common/terminal_setting.html"
def
get_context_data
(
self
,
**
kwargs
):
command_storage
=
settings
.
TERMINAL_COMMAND_STORAGE
context
=
{
'app'
:
_
(
'Settings'
),
'action'
:
_
(
'Terminal setting'
),
'form'
:
self
.
form_class
(),
'command_storage'
:
command_storage
,
}
kwargs
.
update
(
context
)
return
super
().
get_context_data
(
**
kwargs
)
def
post
(
self
,
request
):
form
=
self
.
form_class
(
request
.
POST
)
if
form
.
is_valid
():
form
.
save
()
msg
=
_
(
"Update setting successfully, please restart program"
)
messages
.
success
(
request
,
msg
)
return
redirect
(
'settings:terminal-setting'
)
else
:
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
return
render
(
request
,
self
.
template_name
,
context
)
apps/jumpserver/settings.py
浏览文件 @
968b395b
...
...
@@ -373,7 +373,20 @@ CAPTCHA_FOREGROUND_COLOR = '#001100'
CAPTCHA_NOISE_FUNCTIONS
=
(
'captcha.helpers.noise_dots'
,)
CAPTCHA_TEST_MODE
=
CONFIG
.
CAPTCHA_TEST_MODE
COMMAND_STORAGE_BACKEND
=
'terminal.backends.command.db'
COMMAND_STORAGE
=
{
'ENGINE'
:
'terminal.backends.command.db'
,
}
TERMINAL_COMMAND_STORAGE
=
{
'default'
:
{
'TYPE'
:
'server'
,
},
# 'ali-es': {
# 'TYPE': 'elasticsearch',
# 'HOSTS': ['http://elastic:changeme@localhost:9200'],
# },
}
# Django bootstrap3 setting, more see http://django-bootstrap3.readthedocs.io/en/latest/settings.html
BOOTSTRAP3
=
{
...
...
apps/locale/zh/LC_MESSAGES/django.mo
浏览文件 @
968b395b
无法预览此类型文件
apps/locale/zh/LC_MESSAGES/django.po
浏览文件 @
968b395b
...
...
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-01-
17 17:26
+0800\n"
"POT-Creation-Date: 2018-01-
22 11:04
+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
...
...
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
#: assets/forms.py:23 assets/forms.py:53 assets/forms.py:99 perms/forms.py:37
#: perms/templates/perms/asset_permission_asset.html:116 users/forms.py:24
6
#: perms/templates/perms/asset_permission_asset.html:116 users/forms.py:24
5
msgid "Select asset groups"
msgstr "选择资产组"
...
...
@@ -44,7 +44,7 @@ msgstr "默认使用管理用户"
#: assets/forms.py:76 assets/forms.py:81 assets/forms.py:127
#: assets/templates/assets/asset_group_detail.html:75 perms/forms.py:34
#: perms/templates/perms/asset_permission_asset.html:88 users/forms.py:24
3
#: perms/templates/perms/asset_permission_asset.html:88 users/forms.py:24
2
msgid "Select assets"
msgstr "选择资产"
...
...
@@ -66,7 +66,7 @@ msgstr "端口"
#: assets/templates/assets/system_user_list.html:26 perms/models.py:17
#: perms/templates/perms/asset_permission_create_update.html:40
#: perms/templates/perms/asset_permission_list.html:28 templates/_nav.html:22
#: terminal/backends/command/models.py:11 terminal/models.py:
93
#: terminal/backends/command/models.py:11 terminal/models.py:
124
#: terminal/templates/terminal/command_list.html:40
#: terminal/templates/terminal/command_list.html:73
#: terminal/templates/terminal/session_list.html:41
...
...
@@ -77,7 +77,7 @@ msgid "Asset"
msgstr "资产"
#: assets/forms.py:161 perms/forms.py:40
#: perms/templates/perms/asset_permission_detail.html:144 users/forms.py:24
9
#: perms/templates/perms/asset_permission_detail.html:144 users/forms.py:24
8
msgid "Select system users"
msgstr "选择系统用户"
...
...
@@ -99,14 +99,15 @@ msgstr "选择的系统用户将会在该集群资产上创建"
#: assets/templates/assets/cluster_detail.html:57
#: assets/templates/assets/cluster_list.html:19
#: assets/templates/assets/system_user_detail.html:58
#: assets/templates/assets/system_user_list.html:24 common/models.py:25
#: ops/models.py:31 ops/templates/ops/task_detail.html:56
#: ops/templates/ops/task_list.html:34 perms/models.py:14
#: assets/templates/assets/system_user_list.html:24 common/models.py:26
#: common/templates/common/terminal_setting.html:62 ops/models.py:31
#: ops/templates/ops/task_detail.html:56 ops/templates/ops/task_list.html:34
#: perms/models.py:14
#: perms/templates/perms/asset_permission_create_update.html:33
#: perms/templates/perms/asset_permission_detail.html:62
#: perms/templates/perms/asset_permission_list.html:25
#: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:
14
#: terminal/models.py:1
18
terminal/templates/terminal/terminal_detail.html:43
#: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:
23
#: terminal/models.py:1
49
terminal/templates/terminal/terminal_detail.html:43
#: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14
#: users/models/user.py:35 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_detail.html:62
...
...
@@ -126,10 +127,10 @@ msgstr "集群级别管理用户"
#: assets/forms.py:200
msgid "Password or private key password"
msgstr "密码或秘钥
不合法
"
msgstr "密码或秘钥
密码
"
#: assets/forms.py:201 assets/forms.py:262 assets/models/user.py:30
#: common/forms.py:1
07
users/forms.py:16 users/forms.py:24
#: common/forms.py:1
13
users/forms.py:16 users/forms.py:24
#: users/templates/users/login.html:56
#: users/templates/users/reset_password.html:52
#: users/templates/users/user_create.html:11
...
...
@@ -239,7 +240,7 @@ msgstr "测试环境"
#: assets/templates/assets/asset_list.html:31
#: assets/templates/assets/cluster_assets.html:52
#: assets/templates/assets/system_user_asset.html:53
#: assets/templates/assets/user_asset_list.html:20
#: assets/templates/assets/user_asset_list.html:20
common/forms.py:140
#: perms/templates/perms/asset_permission_asset.html:55
#: users/templates/users/login_log_list.html:52
#: users/templates/users/user_granted_asset.html:49
...
...
@@ -253,7 +254,7 @@ msgstr "IP"
#: assets/templates/assets/asset_list.html:30
#: assets/templates/assets/cluster_assets.html:51
#: assets/templates/assets/system_user_asset.html:52
#: assets/templates/assets/user_asset_list.html:19
#: assets/templates/assets/user_asset_list.html:19
common/forms.py:139
#: perms/templates/perms/asset_permission_asset.html:54
#: users/templates/users/user_granted_asset.html:48
#: users/templates/users/user_group_granted_asset.html:49
...
...
@@ -400,9 +401,9 @@ msgstr "创建日期"
#: assets/templates/assets/asset_group_list.html:17
#: assets/templates/assets/cluster_detail.html:97
#: assets/templates/assets/system_user_detail.html:100
#: assets/templates/assets/system_user_list.html:30 common/models.py:
28
#: assets/templates/assets/system_user_list.html:30 common/models.py:
30
#: ops/models.py:37 perms/models.py:24
#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:
22
#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:
33
#: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15
#: users/models/user.py:47 users/templates/users/user_detail.html:110
#: users/templates/users/user_group_detail.html:67
...
...
@@ -494,7 +495,7 @@ msgstr "Shell"
#: assets/models/user.py:269 perms/models.py:19
#: perms/templates/perms/asset_permission_detail.html:136
#: perms/templates/perms/asset_permission_list.html:30 templates/_nav.html:26
#: terminal/backends/command/models.py:12 terminal/models.py:
94
#: terminal/backends/command/models.py:12 terminal/models.py:
125
#: terminal/templates/terminal/command_list.html:48
#: terminal/templates/terminal/command_list.html:74
#: terminal/templates/terminal/session_list.html:49
...
...
@@ -576,9 +577,9 @@ msgstr "仅修改你需要更新的字段"
#: assets/views/admin_user.py:106 assets/views/asset.py:48
#: assets/views/asset.py:61 assets/views/asset.py:84 assets/views/asset.py:144
#: assets/views/asset.py:161 assets/views/asset.py:185
#: assets/views/cluster.py:26 assets/views/cluster.py:8
5
#: assets/views/cluster.py:
102 assets/views/group.py:34
#: assets/views/group.py:
52 assets/views/group.py:
69 assets/views/group.py:87
#: assets/views/cluster.py:26 assets/views/cluster.py:8
0
#: assets/views/cluster.py:
97 assets/views/group.py:34 assets/views/group.py:52
#: assets/views/group.py:69 assets/views/group.py:87
#: assets/views/system_user.py:28 assets/views/system_user.py:44
#: assets/views/system_user.py:60 assets/views/system_user.py:75
#: templates/_nav.html:19
...
...
@@ -602,20 +603,24 @@ msgid "Import asset"
msgstr "导入资产"
#: assets/templates/assets/_asset_import_modal.html:9
#: common/templates/common/_add_terminal_command_storage_modal.html:9
#: users/templates/users/_user_import_modal.html:10
msgid "Template"
msgstr "模板"
#: assets/templates/assets/_asset_import_modal.html:10
#: common/templates/common/_add_terminal_command_storage_modal.html:10
#: users/templates/users/_user_import_modal.html:11
msgid "Download"
msgstr "下载"
#: assets/templates/assets/_asset_import_modal.html:13
#: common/templates/common/_add_terminal_command_storage_modal.html:13
msgid "Asset csv file"
msgstr "资产csv文件"
#: assets/templates/assets/_asset_import_modal.html:16
#: common/templates/common/_add_terminal_command_storage_modal.html:16
msgid "If set id, will use this id update asset existed"
msgstr "如果设置了id,则会使用该行信息更新该id的资产"
...
...
@@ -650,7 +655,7 @@ msgstr "自动生成秘钥"
#: assets/templates/assets/asset_update.html:47
#: assets/templates/assets/cluster_create_update.html:46
#: perms/templates/perms/asset_permission_create_update.html:45
#: terminal/templates/terminal/terminal_update.html:4
0
#: terminal/templates/terminal/terminal_update.html:4
1
msgid "Other"
msgstr "其它"
...
...
@@ -661,11 +666,12 @@ msgstr "其它"
#: assets/templates/assets/asset_group_create.html:16
#: assets/templates/assets/asset_update.html:55
#: assets/templates/assets/cluster_create_update.html:54
#: common/templates/common/basic_setting.html:55
#: common/templates/common/email_setting.html:56
#: common/templates/common/ldap_setting.html:56
#: common/templates/common/basic_setting.html:58
#: common/templates/common/email_setting.html:59
#: common/templates/common/ldap_setting.html:59
#: common/templates/common/terminal_setting.html:82
#: perms/templates/perms/asset_permission_create_update.html:67
#: terminal/templates/terminal/terminal_update.html:4
5
#: terminal/templates/terminal/terminal_update.html:4
6
#: users/templates/users/_user.html:49
#: users/templates/users/user_bulk_update.html:23
#: users/templates/users/user_password_update.html:58
...
...
@@ -684,11 +690,12 @@ msgstr "重置"
#: assets/templates/assets/asset_list.html:53
#: assets/templates/assets/asset_update.html:56
#: assets/templates/assets/cluster_create_update.html:55
#: common/templates/common/basic_setting.html:56
#: common/templates/common/email_setting.html:57
#: common/templates/common/ldap_setting.html:57
#: common/templates/common/basic_setting.html:59
#: common/templates/common/email_setting.html:60
#: common/templates/common/ldap_setting.html:60
#: common/templates/common/terminal_setting.html:83
#: perms/templates/perms/asset_permission_create_update.html:68
#: terminal/templates/terminal/terminal_update.html:4
6
#: terminal/templates/terminal/terminal_update.html:4
7
#: users/templates/users/_user.html:50
#: users/templates/users/first_login.html:62
#: users/templates/users/forgot_password.html:44
...
...
@@ -778,6 +785,7 @@ msgstr "资产列表"
#: assets/templates/assets/asset_group_detail.html:53
#: assets/templates/assets/cluster_assets.html:54
#: assets/templates/assets/user_asset_list.html:22
#: common/templates/common/terminal_setting.html:63
#: users/templates/users/login_log_list.html:50
msgid "Type"
msgstr "类型"
...
...
@@ -878,7 +886,7 @@ msgid "Group"
msgstr "组"
#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:186
#: assets/views/cluster.py:
103
#: assets/views/cluster.py:
98
msgid "Asset detail"
msgstr "资产详情"
...
...
@@ -1236,16 +1244,16 @@ msgstr "已经存在"
msgid "Cluster list"
msgstr "集群列表"
#: assets/views/cluster.py:42 assets/views/cluster.py:
70
#: assets/views/cluster.py:42 assets/views/cluster.py:
65
#: assets/views/system_user.py:96
msgid "assets"
msgstr "资产管理"
#: assets/views/cluster.py:
71
#: assets/views/cluster.py:
66
msgid "Update Cluster"
msgstr "更新Cluster"
#: assets/views/cluster.py:8
6
#: assets/views/cluster.py:8
1
msgid "Cluster detail"
msgstr "集群详情"
...
...
@@ -1291,81 +1299,108 @@ msgstr "<b>%(name)s</b> 创建成功"
msgid "<b>%(name)s</b> was updated successfully"
msgstr "<b>%(name)s</b> 更新成功"
#: common/forms.py:
64
#: common/forms.py:
70
msgid "Current SITE URL"
msgstr "当前站点URL"
#: common/forms.py:
68
#: common/forms.py:
74
msgid "User Guide URL"
msgstr "用户向导URL"
#: common/forms.py:
69
#: common/forms.py:
75
msgid "User first login update profile done redirect to it"
msgstr "用户第一次登录,修改profile后重定向到地址"
#: common/forms.py:7
2
#: common/forms.py:7
8
msgid "Email Subject Prefix"
msgstr "Email主题前缀"
#: common/forms.py:
79
#: common/forms.py:
85
msgid "SMTP host"
msgstr "SMTP主机"
#: common/forms.py:8
1
#: common/forms.py:8
7
msgid "SMTP port"
msgstr "SMTP端口"
#: common/forms.py:8
3
#: common/forms.py:8
9
msgid "SMTP user"
msgstr "SMTP账号"
#: common/forms.py:
86
#: common/forms.py:
92
msgid "SMTP password"
msgstr "SMTP密码"
#: common/forms.py:
87
#: common/forms.py:
93
msgid "Some provider use token except password"
msgstr "一些邮件提供商需要输入的是Token"
#: common/forms.py:9
0 common/forms.py:127
#: common/forms.py:9
6 common/forms.py:133
msgid "Use SSL"
msgstr "使用SSL"
#: common/forms.py:9
1
#: common/forms.py:9
7
msgid "If SMTP port is 465, may be select"
msgstr "如果SMTP端口是465,通常需要启用SSL"
#: common/forms.py:
94
#: common/forms.py:
100
msgid "Use TLS"
msgstr "使用TLS"
#: common/forms.py:
95
#: common/forms.py:
101
msgid "If SMTP port is 587, may be select"
msgstr "如果SMTP端口是587,通常需要启用TLS"
#: common/forms.py:10
1
#: common/forms.py:10
7
msgid "LDAP server"
msgstr "LDAP地址"
#: common/forms.py:1
04
#: common/forms.py:1
10
msgid "Bind DN"
msgstr "绑定DN"
#: common/forms.py:11
1
#: common/forms.py:11
7
msgid "User OU"
msgstr "用户OU"
#: common/forms.py:1
14
#: common/forms.py:1
20
msgid "User search filter"
msgstr "用户过滤器"
#: common/forms.py:1
17
#: common/forms.py:1
23
msgid "User attr map"
msgstr "LDAP属性映射"
#: common/forms.py:130
msgid "Enable LDAP Auth"
msgstr "开启LDAP认证"
#: common/forms.py:143
msgid "List sort by"
msgstr "资产列表排序"
#: common/forms.py:146
msgid "Heartbeat interval"
msgstr "心跳间隔"
#: common/forms.py:146 ops/models.py:32
msgid "Units: seconds"
msgstr "单位: 秒"
#: common/forms.py:149
msgid "Password auth"
msgstr "密码认证"
#: common/forms.py:152
msgid "Public key auth"
msgstr "秘钥认证"
#: common/forms.py:155 common/templates/common/terminal_setting.html:58
#: terminal/models.py:27
msgid "Command storage"
msgstr "命令存储"
#: common/forms.py:156
msgid ""
"Set terminal storage setting, `default` is the using as default,You can set "
"other storage and some terminal using"
msgstr "设置终端命令存储,default是默认用的存储方式"
#: common/mixins.py:29
msgid "is discard"
...
...
@@ -1375,43 +1410,62 @@ msgstr ""
msgid "discard time"
msgstr ""
#: common/models.py:2
6
#: common/models.py:2
7
msgid "Value"
msgstr "值"
#: common/models.py:2
7
#: common/models.py:2
9
msgid "Enabled"
msgstr "启用"
#: common/templates/common/_add_terminal_command_storage_modal.html:4
msgid "Add command storage"
msgstr "添加命令存储"
#: common/templates/common/basic_setting.html:15
#: common/templates/common/email_setting.html:15
#: common/templates/common/ldap_setting.html:15 common/views.py:18
#: common/templates/common/ldap_setting.html:15
#: common/templates/common/terminal_setting.html:15
#: common/templates/common/terminal_setting.html:38 common/views.py:21
msgid "Basic setting"
msgstr "基本设置"
#: common/templates/common/basic_setting.html:18
#: common/templates/common/email_setting.html:18
#: common/templates/common/ldap_setting.html:18 common/views.py:44
#: common/templates/common/ldap_setting.html:18
#: common/templates/common/terminal_setting.html:18 common/views.py:47
msgid "Email setting"
msgstr "邮件设置"
#: common/templates/common/basic_setting.html:21
#: common/templates/common/email_setting.html:21
#: common/templates/common/ldap_setting.html:21 common/views.py:70
#: common/templates/common/ldap_setting.html:21
#: common/templates/common/terminal_setting.html:21 common/views.py:73
msgid "LDAP setting"
msgstr "LDAP设置"
#: common/templates/common/email_setting.html:55
#: common/templates/common/ldap_setting.html:55
#: common/templates/common/basic_setting.html:24
#: common/templates/common/email_setting.html:24
#: common/templates/common/ldap_setting.html:24
#: common/templates/common/terminal_setting.html:24 common/views.py:102
msgid "Terminal setting"
msgstr "终端设置"
#: common/templates/common/email_setting.html:58
#: common/templates/common/ldap_setting.html:58
msgid "Test connection"
msgstr "测试连接"
#: common/views.py:17 common/views.py:43 common/views.py:69
#: common/templates/common/terminal_setting.html:77 terminal/models.py:28
msgid "Replay storage"
msgstr "录像存储"
#: common/views.py:20 common/views.py:46 common/views.py:72 common/views.py:101
#: templates/_nav.html:69
msgid "Settings"
msgstr "系统设置"
#: common/views.py:
28 common/views.py:54 common/views.py:82
#: common/views.py:
31 common/views.py:57 common/views.py:85 common/views.py:113
msgid "Update setting successfully, please restart program"
msgstr "更新设置成功, 请手动重启程序"
...
...
@@ -1419,10 +1473,6 @@ msgstr "更新设置成功, 请手动重启程序"
msgid "Interval"
msgstr "间隔"
#: ops/models.py:32
msgid "Units: seconds"
msgstr "单位: 秒"
#: ops/models.py:33
msgid "Crontab"
msgstr "Crontab"
...
...
@@ -1566,7 +1616,7 @@ msgstr "执行历史"
#: ops/templates/ops/adhoc_history.html:52
#: ops/templates/ops/adhoc_history_detail.html:58
#: ops/templates/ops/task_history.html:55 terminal/models.py:1
01
#: ops/templates/ops/task_history.html:55 terminal/models.py:1
32
#: terminal/templates/terminal/session_list.html:77
msgid "Date start"
msgstr "开始日期"
...
...
@@ -1683,18 +1733,18 @@ msgid "Task run history"
msgstr "执行历史"
#: perms/forms.py:16 users/forms.py:147 users/forms.py:152 users/forms.py:164
#: users/forms.py:19
5
#: users/forms.py:19
4
msgid "Select users"
msgstr "选择用户"
#: perms/forms.py:18 perms/models.py:15
#: perms/templates/perms/asset_permission_create_update.html:36
#: perms/templates/perms/asset_permission_list.html:26 templates/_nav.html:12
#: terminal/backends/command/models.py:10 terminal/models.py:
92
#: terminal/backends/command/models.py:10 terminal/models.py:
123
#: terminal/templates/terminal/command_list.html:32
#: terminal/templates/terminal/command_list.html:72
#: terminal/templates/terminal/session_list.html:33
#: terminal/templates/terminal/session_list.html:71 users/forms.py:19
1
#: terminal/templates/terminal/session_list.html:71 users/forms.py:19
0
#: users/models/user.py:30 users/templates/users/user_group_detail.html:78
#: users/views/user.py:337
msgid "User"
...
...
@@ -1949,7 +1999,7 @@ msgstr "在线会话"
msgid "Session offline"
msgstr "离线会话"
#: templates/_nav.html:53 terminal/models.py:
99
#: templates/_nav.html:53 terminal/models.py:
130
#: terminal/templates/terminal/command_list.html:55
#: terminal/templates/terminal/command_list.html:71
#: terminal/templates/terminal/session_detail.html:48
...
...
@@ -1998,56 +2048,56 @@ msgstr "SSH 监听端口"
msgid "Coco http/ws listen port"
msgstr "Http/Websocket 监听端口"
#: terminal/models.py:
15
#: terminal/models.py:
24
msgid "Remote Address"
msgstr "远端地址"
#: terminal/models.py:
16
#: terminal/models.py:
25
msgid "SSH Port"
msgstr "SSH端口"
#: terminal/models.py:
17
#: terminal/models.py:
26
msgid "HTTP Port"
msgstr "HTTP端口"
#: terminal/models.py:
68
#: terminal/models.py:
99
msgid "Session Online"
msgstr "在线会话"
#: terminal/models.py:
69
#: terminal/models.py:
100
msgid "CPU Usage"
msgstr "CPU使用"
#: terminal/models.py:
70
#: terminal/models.py:
101
msgid "Memory Used"
msgstr "内存使用"
#: terminal/models.py:
71
#: terminal/models.py:
102
msgid "Connections"
msgstr "连接数"
#: terminal/models.py:
72
#: terminal/models.py:
103
msgid "Threads"
msgstr "线程数"
#: terminal/models.py:
73
#: terminal/models.py:
104
msgid "Boot Time"
msgstr "运行时间"
#: terminal/models.py:
96
terminal/templates/terminal/session_list.html:74
#: terminal/models.py:
127
terminal/templates/terminal/session_list.html:74
#: terminal/templates/terminal/terminal_detail.html:47
msgid "Remote addr"
msgstr "远端地址"
#: terminal/models.py:
98
terminal/templates/terminal/session_list.html:100
#: terminal/models.py:
129
terminal/templates/terminal/session_list.html:100
msgid "Replay"
msgstr "回放"
#: terminal/models.py:1
02
#: terminal/models.py:1
33
msgid "Date end"
msgstr "结束日期"
#: terminal/models.py:1
19
#: terminal/models.py:1
50
msgid "Args"
msgstr "参数"
...
...
@@ -2810,5 +2860,8 @@ msgstr "密码更新"
msgid "Public key update"
msgstr "秘钥更新"
#~ msgid "Enable LDAP Auth"
#~ msgstr "LDAP认证"
#~ msgid "Connect"
#~ msgstr "连接"
apps/terminal/api.py
浏览文件 @
968b395b
# -*- coding: utf-8 -*-
#
from
collections
import
OrderedDict
import
copy
import
logging
import
os
import
uuid
...
...
@@ -21,7 +20,8 @@ from .serializers import TerminalSerializer, StatusSerializer, \
SessionSerializer
,
TaskSerializer
,
ReplaySerializer
from
.hands
import
IsSuperUserOrAppUser
,
IsAppUser
,
\
IsSuperUserOrAppUserOrUserReadonly
from
.backends
import
get_command_store
,
SessionCommandSerializer
from
.backends
import
get_command_store
,
get_multi_command_store
,
\
SessionCommandSerializer
logger
=
logging
.
getLogger
(
__file__
)
...
...
@@ -197,6 +197,7 @@ class CommandViewSet(viewsets.ViewSet):
"""
command_store
=
get_command_store
()
multi_command_storage
=
get_multi_command_store
()
serializer_class
=
SessionCommandSerializer
permission_classes
=
(
IsSuperUserOrAppUser
,)
...
...
@@ -217,7 +218,7 @@ class CommandViewSet(viewsets.ViewSet):
return
Response
({
"msg"
:
msg
},
status
=
401
)
def
list
(
self
,
request
,
*
args
,
**
kwargs
):
queryset
=
list
(
self
.
command_store
.
all
()
)
queryset
=
self
.
multi_command_storage
.
filter
(
)
serializer
=
self
.
serializer_class
(
queryset
,
many
=
True
)
return
Response
(
serializer
.
data
)
...
...
@@ -260,3 +261,13 @@ class SessionReplayViewSet(viewsets.ViewSet):
return
redirect
(
url
)
else
:
return
HttpResponseNotFound
()
class
TerminalConfig
(
APIView
):
permission_classes
=
(
IsAppUser
,)
def
get
(
self
,
request
):
user
=
request
.
user
terminal
=
user
.
terminal
configs
=
terminal
.
config
return
Response
(
configs
,
status
=
200
)
apps/terminal/backends/__init__.py
浏览文件 @
968b395b
...
...
@@ -2,9 +2,39 @@ from importlib import import_module
from
django.conf
import
settings
from
.command.serializers
import
SessionCommandSerializer
TYPE_ENGINE_MAPPING
=
{
'elasticsearch'
:
'terminal.backends.command.es'
,
}
def
get_command_store
():
command_engine
=
import_module
(
settings
.
COMMAND_STORAGE_BACKEND
)
command_store
=
command_engine
.
CommandStore
()
return
command_store
params
=
settings
.
COMMAND_STORAGE
engine_class
=
import_module
(
params
[
'ENGINE'
])
storage
=
engine_class
.
CommandStore
(
params
)
return
storage
def
get_terminal_command_store
():
storage_list
=
{}
for
name
,
params
in
settings
.
TERMINAL_COMMAND_STORAGE
.
items
():
tp
=
params
[
'TYPE'
]
if
tp
==
'server'
:
storage
=
get_command_store
()
else
:
if
not
TYPE_ENGINE_MAPPING
.
get
(
tp
):
raise
AssertionError
(
"Command storage type should in {}"
.
format
(
', '
.
join
(
TYPE_ENGINE_MAPPING
.
keys
()))
)
engine_class
=
import_module
(
TYPE_ENGINE_MAPPING
[
tp
])
storage
=
engine_class
.
CommandStore
(
params
)
storage_list
[
name
]
=
storage
return
storage_list
def
get_multi_command_store
():
from
.command.multi
import
CommandStore
storage_list
=
get_terminal_command_store
().
values
()
storage
=
CommandStore
(
storage_list
)
return
storage
apps/terminal/backends/command/base.py
浏览文件 @
968b395b
...
...
@@ -19,3 +19,9 @@ class CommandBase(object):
input
=
None
,
session
=
None
):
pass
@
abc
.
abstractmethod
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
pass
apps/terminal/backends/command/db.py
浏览文件 @
968b395b
...
...
@@ -8,7 +8,7 @@ from .base import CommandBase
class
CommandStore
(
CommandBase
):
def
__init__
(
self
):
def
__init__
(
self
,
params
):
from
terminal.models
import
Command
self
.
model
=
Command
...
...
@@ -37,9 +37,11 @@ class CommandStore(CommandBase):
))
return
self
.
model
.
objects
.
bulk_create
(
_commands
)
def
filter
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
@
staticmethod
def
make_filter_kwargs
(
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
filter_kwargs
=
{}
date_from_default
=
timezone
.
now
()
-
datetime
.
timedelta
(
days
=
7
)
date_to_default
=
timezone
.
now
()
...
...
@@ -60,10 +62,28 @@ class CommandStore(CommandBase):
if
session
:
filter_kwargs
[
'session'
]
=
session
return
filter_kwargs
def
filter
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
filter_kwargs
=
self
.
make_filter_kwargs
(
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
,
)
queryset
=
self
.
model
.
objects
.
filter
(
**
filter_kwargs
)
return
queryset
return
[
command
.
to_dict
()
for
command
in
queryset
]
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
filter_kwargs
=
self
.
make_filter_kwargs
(
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
,
)
count
=
self
.
model
.
objects
.
filter
(
**
filter_kwargs
).
count
()
return
count
def
all
(
self
):
"""返回所有数据"""
return
self
.
model
.
objects
.
iterator
()
apps/terminal/backends/command/es.py
0 → 100644
浏览文件 @
968b395b
# -*- coding: utf-8 -*-
#
from
jms_es_sdk
import
ESStore
from
.base
import
CommandBase
class
CommandStore
(
CommandBase
,
ESStore
):
def
__init__
(
self
,
params
):
hosts
=
params
.
get
(
'HOSTS'
,
[
'http://localhost'
])
ESStore
.
__init__
(
self
,
hosts
=
hosts
)
def
save
(
self
,
command
):
return
ESStore
.
save
(
self
,
command
)
def
bulk_save
(
self
,
commands
):
return
ESStore
.
bulk_save
(
self
,
commands
)
def
filter
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
data
=
ESStore
.
filter
(
self
,
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
)
return
[
item
[
"_source"
]
for
item
in
data
[
"hits"
]
if
item
]
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
amount
=
ESStore
.
count
(
self
,
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
)
return
amount
apps/terminal/backends/command/models.py
浏览文件 @
968b395b
...
...
@@ -18,5 +18,26 @@ class AbstractSessionCommand(models.Model):
class
Meta
:
abstract
=
True
@
classmethod
def
from_dict
(
cls
,
d
):
self
=
cls
()
for
k
,
v
in
d
.
items
():
setattr
(
self
,
k
,
v
)
return
self
@
classmethod
def
from_multi_dict
(
cls
,
l
):
commands
=
[]
for
d
in
l
:
command
=
cls
.
from_dict
(
d
)
commands
.
append
(
command
)
return
commands
def
to_dict
(
self
):
d
=
{}
for
field
in
self
.
_meta
.
fields
:
d
[
field
.
name
]
=
getattr
(
self
,
field
.
name
)
return
d
def
__str__
(
self
):
return
self
.
input
apps/terminal/backends/command/multi.py
0 → 100644
浏览文件 @
968b395b
# -*- coding: utf-8 -*-
#
from
.base
import
CommandBase
class
CommandStore
(
CommandBase
):
def
__init__
(
self
,
storage_list
):
self
.
storage_list
=
storage_list
def
filter
(
self
,
**
kwargs
):
queryset
=
[]
for
storage
in
self
.
storage_list
:
queryset
.
extend
(
storage
.
filter
(
**
kwargs
))
return
sorted
(
queryset
,
key
=
lambda
command
:
command
[
"timestamp"
])
def
count
(
self
,
**
kwargs
):
amount
=
0
for
storage
in
self
.
storage_list
:
amount
+=
storage
.
count
(
**
kwargs
)
return
amount
def
save
(
self
,
command
):
pass
def
bulk_save
(
self
,
commands
):
pass
\ No newline at end of file
apps/terminal/forms.py
浏览文件 @
968b395b
...
...
@@ -10,7 +10,7 @@ from .models import Terminal
class
TerminalForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
Terminal
fields
=
[
'name'
,
'remote_addr'
,
'ssh_port'
,
'http_port'
,
'comment'
]
fields
=
[
'name'
,
'remote_addr'
,
'ssh_port'
,
'http_port'
,
'comment'
,
'command_storage'
]
help_texts
=
{
'ssh_port'
:
_
(
"Coco ssh listen port"
),
'http_port'
:
_
(
"Coco http/ws listen port"
),
...
...
apps/terminal/models.py
浏览文件 @
968b395b
...
...
@@ -4,17 +4,28 @@ import uuid
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
users.models
import
User
from
.backends.command.models
import
AbstractSessionCommand
def
get_all_command_storage
():
# storage_choices = []
from
common.models
import
Setting
Setting
.
refresh_all_settings
()
for
k
,
v
in
settings
.
TERMINAL_COMMAND_STORAGE
.
items
():
yield
(
k
,
k
)
class
Terminal
(
models
.
Model
):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
32
,
verbose_name
=
_
(
'Name'
))
remote_addr
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Remote Address'
))
ssh_port
=
models
.
IntegerField
(
verbose_name
=
_
(
'SSH Port'
),
default
=
2222
)
http_port
=
models
.
IntegerField
(
verbose_name
=
_
(
'HTTP Port'
),
default
=
5000
)
command_storage
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"Command storage"
),
default
=
'default'
,
choices
=
get_all_command_storage
())
replay_storage
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"Replay storage"
),
default
=
'default'
)
user
=
models
.
OneToOneField
(
User
,
related_name
=
'terminal'
,
verbose_name
=
'Application User'
,
null
=
True
,
on_delete
=
models
.
CASCADE
)
is_accepted
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
'Is Accepted'
)
is_deleted
=
models
.
BooleanField
(
default
=
False
)
...
...
@@ -33,6 +44,26 @@ class Terminal(models.Model):
self
.
user
.
is_active
=
active
self
.
user
.
save
()
def
get_common_storage
(
self
):
storage_all
=
settings
.
TERMINAL_COMMAND_STORAGE
if
self
.
command_storage
in
storage_all
:
storage
=
storage_all
.
get
(
self
.
command_storage
)
else
:
storage
=
storage_all
.
get
(
'default'
)
return
{
"TERMINAL_COMMAND_STORAGE"
:
storage
}
def
get_replay_storage
(
self
):
pass
@
property
def
config
(
self
):
configs
=
{}
for
k
in
dir
(
settings
):
if
k
.
startswith
(
'TERMINAL'
):
configs
[
k
]
=
getattr
(
settings
,
k
)
configs
.
update
(
self
.
get_common_storage
())
return
configs
def
create_app_user
(
self
):
random
=
uuid
.
uuid4
().
hex
[:
6
]
user
,
access_key
=
User
.
create_app_user
(
name
=
"{}-{}"
.
format
(
self
.
name
,
random
),
comment
=
self
.
comment
)
...
...
apps/terminal/serializers.py
浏览文件 @
968b395b
...
...
@@ -5,7 +5,7 @@ from django.utils import timezone
from
rest_framework
import
serializers
from
.models
import
Terminal
,
Status
,
Session
,
Task
from
.backends
import
get_command_store
from
.backends
import
get_
multi_
command_store
class
TerminalSerializer
(
serializers
.
ModelSerializer
):
...
...
@@ -43,14 +43,14 @@ class TerminalSerializer(serializers.ModelSerializer):
class
SessionSerializer
(
serializers
.
ModelSerializer
):
command_amount
=
serializers
.
SerializerMethodField
()
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
class
Meta
:
model
=
Session
fields
=
'__all__'
def
get_command_amount
(
self
,
obj
):
return
len
(
self
.
command_store
.
filter
(
session
=
obj
.
session
))
return
self
.
command_store
.
count
(
session
=
str
(
obj
.
id
))
class
StatusSerializer
(
serializers
.
ModelSerializer
):
...
...
apps/terminal/templates/terminal/terminal_modal_accept.html
浏览文件 @
968b395b
...
...
@@ -12,6 +12,7 @@
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.ssh_port layout="horizontal" %}
{% bootstrap_field form.http_port layout="horizontal" %}
{% bootstrap_field form.command_storage layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
</form>
...
...
apps/terminal/templates/terminal/terminal_update.html
浏览文件 @
968b395b
...
...
@@ -35,6 +35,7 @@
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.ssh_port layout="horizontal" %}
{% bootstrap_field form.http_port layout="horizontal" %}
{% bootstrap_field form.command_storage layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
...
...
apps/terminal/templatetags/terminal_tags.py
浏览文件 @
968b395b
# ~*~ coding: utf-8 ~*~
from
django
import
template
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
register
=
template
.
Library
()
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
@
register
.
filter
def
get_session_command_amount
(
session_id
):
return
len
(
command_store
.
filter
(
session
=
str
(
session_id
)))
return
command_store
.
count
(
session
=
session_id
)
apps/terminal/urls/api_urls.py
浏览文件 @
968b395b
...
...
@@ -20,7 +20,8 @@ urlpatterns = [
url
(
r
'^v1/sessions/(?P<pk>[0-9a-zA-Z\-]{36})/replay/$'
,
api
.
SessionReplayViewSet
.
as_view
({
'get'
:
'retrieve'
,
'post'
:
'create'
}),
name
=
'session-replay'
),
url
(
r
'^v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})/access-key'
,
api
.
TerminalTokenApi
.
as_view
(),
name
=
'terminal-access-key'
)
url
(
r
'^v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})/access-key'
,
api
.
TerminalTokenApi
.
as_view
(),
name
=
'terminal-access-key'
),
url
(
r
'^v1/terminal/config'
,
api
.
TerminalConfig
.
as_view
(),
name
=
'terminal-config'
),
]
urlpatterns
+=
router
.
urls
apps/terminal/views/command.py
浏览文件 @
968b395b
...
...
@@ -9,10 +9,10 @@ from django.utils.translation import ugettext as _
from
common.mixins
import
DatetimeSearchMixin
from
..models
import
Command
from
..
import
utils
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
__all__
=
[
'CommandListView'
]
comm
and_store
=
get
_command_store
()
comm
on_storage
=
get_multi
_command_store
()
class
CommandListView
(
DatetimeSearchMixin
,
ListView
):
...
...
@@ -39,7 +39,7 @@ class CommandListView(DatetimeSearchMixin, ListView):
filter_kwargs
[
'system_user'
]
=
self
.
system_user
if
self
.
command
:
filter_kwargs
[
'input'
]
=
self
.
command
queryset
=
comm
and_stor
e
.
filter
(
**
filter_kwargs
)
queryset
=
comm
on_storag
e
.
filter
(
**
filter_kwargs
)
return
queryset
def
get_context_data
(
self
,
**
kwargs
):
...
...
apps/terminal/views/session.py
浏览文件 @
968b395b
...
...
@@ -10,7 +10,7 @@ from django.conf import settings
from
users.utils
import
AdminUserRequiredMixin
from
common.mixins
import
DatetimeSearchMixin
from
..models
import
Session
,
Command
,
Terminal
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
from
..
import
utils
...
...
@@ -19,7 +19,7 @@ __all__ = [
'SessionDetailView'
,
]
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
class
SessionListView
(
AdminUserRequiredMixin
,
DatetimeSearchMixin
,
ListView
):
...
...
apps/users/forms.py
浏览文件 @
968b395b
...
...
@@ -172,7 +172,6 @@ class UserBulkUpdateForm(forms.ModelForm):
if
self
.
data
.
get
(
field
)
is
not
None
:
changed_fields
.
append
(
field
)
print
(
changed_fields
)
cleaned_data
=
{
k
:
v
for
k
,
v
in
self
.
cleaned_data
.
items
()
if
k
in
changed_fields
}
users
=
cleaned_data
.
pop
(
'users'
,
''
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录