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
b936d54a
Commit
b936d54a
authored
Jan 20, 2018
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Feature] 添加es支持
parent
ba5ab21b
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
257 additions
and
54 deletions
+257
-54
cluster.py
apps/assets/views/cluster.py
+0
-5
forms.py
apps/common/forms.py
+37
-6
models.py
apps/common/models.py
+12
-3
_add_terminal_command_storage_modal.html
...templates/common/_add_terminal_command_storage_modal.html
+21
-0
basic_setting.html
apps/common/templates/common/basic_setting.html
+1
-1
email_setting.html
apps/common/templates/common/email_setting.html
+1
-1
ldap_setting.html
apps/common/templates/common/ldap_setting.html
+1
-1
terminal_setting.html
apps/common/templates/common/terminal_setting.html
+33
-5
view_urls.py
apps/common/urls/view_urls.py
+1
-1
views.py
apps/common/views.py
+12
-8
settings.py
apps/jumpserver/settings.py
+17
-1
api.py
apps/terminal/api.py
+9
-2
__init__.py
apps/terminal/backends/__init__.py
+27
-3
base.py
apps/terminal/backends/command/base.py
+6
-0
db.py
apps/terminal/backends/command/db.py
+25
-5
models.py
apps/terminal/backends/command/models.py
+15
-0
forms.py
apps/terminal/forms.py
+1
-1
models.py
apps/terminal/models.py
+20
-0
serializers.py
apps/terminal/serializers.py
+2
-2
terminal_modal_accept.html
apps/terminal/templates/terminal/terminal_modal_accept.html
+1
-0
terminal_update.html
apps/terminal/templates/terminal/terminal_update.html
+1
-0
terminal_tags.py
apps/terminal/templatetags/terminal_tags.py
+6
-4
command.py
apps/terminal/views/command.py
+6
-3
session.py
apps/terminal/views/session.py
+2
-2
No files found.
apps/assets/views/cluster.py
View file @
b936d54a
...
...
@@ -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/forms.py
View file @
b936d54a
...
...
@@ -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
not
None
:
field
.
initial
=
to_form_value
(
db_value
)
elif
django_value
is
not
None
:
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
)
...
...
@@ -129,3 +135,28 @@ class LDAPSettingForm(BaseForm):
AUTH_LDAP_START_TLS
=
forms
.
BooleanField
(
label
=
_
(
"Use SSL"
),
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
View file @
b936d54a
...
...
@@ -24,6 +24,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,12 +34,20 @@ 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
()
...
...
@@ -53,9 +62,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
View file @
b936d54a
{% 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
View file @
b936d54a
...
...
@@ -21,7 +21,7 @@
<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:
storage-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Storage
setting' %}
</a>
<a
href=
"{% url 'settings:
terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal
setting' %}
</a>
</li>
</ul>
</div>
...
...
apps/common/templates/common/email_setting.html
View file @
b936d54a
...
...
@@ -21,7 +21,7 @@
<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:
storage-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Storage
setting' %}
</a>
<a
href=
"{% url 'settings:
terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal
setting' %}
</a>
</li>
</ul>
</div>
...
...
apps/common/templates/common/ldap_setting.html
View file @
b936d54a
...
...
@@ -21,7 +21,7 @@
<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:
storage-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Storage
setting' %}
</a>
<a
href=
"{% url 'settings:
terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal
setting' %}
</a>
</li>
</ul>
</div>
...
...
apps/common/templates/common/
storage
_setting.html
→
apps/common/templates/common/
terminal
_setting.html
View file @
b936d54a
...
...
@@ -21,7 +21,7 @@
<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:
storage-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Storage
setting' %}
</a>
<a
href=
"{% url 'settings:
terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal
setting' %}
</a>
</li>
</ul>
</div>
...
...
@@ -35,26 +35,50 @@
</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 'Engine' %}
</th>
<th>
{% trans 'Action' %}
</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 btn-test"
type=
"button"
>
{% trans 'Test connection' %}
</button>
<button
class=
"btn btn-default"
type=
"reset"
>
{% trans 'Reset' %}
</button>
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
...
...
@@ -68,6 +92,7 @@
</div>
</div>
</div>
{% include 'common/_add_terminal_command_storage_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script>
...
...
@@ -97,6 +122,9 @@ $(document).ready(function () {
success
:
success
,
error
:
error
});
})
.
on
(
'click'
,
''
,
function
()
{
})
</script>
{% endblock %}
apps/common/urls/view_urls.py
View file @
b936d54a
...
...
@@ -10,5 +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'^
storage/$'
,
views
.
StorageSettingView
.
as_view
(),
name
=
'storage
-setting'
),
url
(
r'^
terminal/$'
,
views
.
TerminalSettingView
.
as_view
(),
name
=
'terminal
-setting'
),
]
apps/common/views.py
View file @
b936d54a
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
...
...
@@ -89,27 +91,29 @@ class LDAPSettingView(AdminUserRequiredMixin, TemplateView):
return
render
(
request
,
self
.
template_name
,
context
)
class
Storage
SettingView
(
AdminUserRequiredMixin
,
TemplateView
):
form_class
=
LDAP
SettingForm
template_name
=
"common/
storage
_setting.html"
class
Terminal
SettingView
(
AdminUserRequiredMixin
,
TemplateView
):
form_class
=
Terminal
SettingForm
template_name
=
"common/
terminal
_setting.html"
def
get_context_data
(
self
,
**
kwargs
):
command_storage
=
settings
.
TERMINAL_COMMAND_STORAGE
context
=
{
'app'
:
_
(
'Settings'
),
'action'
:
_
(
'
Storage
setting'
),
'action'
:
_
(
'
Terminal
setting'
),
'form'
:
self
.
form_class
(),
'command_storage'
:
Setting
.
objects
.
filter
(
name__endswith
=
"_COMMAND_STORAGE"
)
'command_storage'
:
command_storage
,
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
post
(
self
,
request
):
print
(
request
.
POST
)
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:
storage
-setting'
)
return
redirect
(
'settings:
terminal
-setting'
)
else
:
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
...
...
apps/jumpserver/settings.py
View file @
b936d54a
...
...
@@ -373,7 +373,23 @@ 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'],
# },
# 'ali-hz-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/terminal/api.py
View file @
b936d54a
...
...
@@ -21,7 +21,7 @@ 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_
terminal_
command_store
,
SessionCommandSerializer
logger
=
logging
.
getLogger
(
__file__
)
...
...
@@ -196,7 +196,7 @@ class CommandViewSet(viewsets.ViewSet):
}
"""
command_store
=
get_command_store
()
command_store
=
get_
terminal_
command_store
()
serializer_class
=
SessionCommandSerializer
permission_classes
=
(
IsSuperUserOrAppUser
,)
...
...
@@ -260,3 +260,10 @@ class SessionReplayViewSet(viewsets.ViewSet):
return
redirect
(
url
)
else
:
return
HttpResponseNotFound
()
class
LoadConfig
(
APIView
):
permission_classes
=
(
IsAppUser
,)
def
get
(
self
,
request
):
pass
apps/terminal/backends/__init__.py
View file @
b936d54a
...
...
@@ -2,9 +2,33 @@ from importlib import import_module
from
django.conf
import
settings
from
.command.serializers
import
SessionCommandSerializer
TYPE_ENGINE_MAPPING
=
{
'elasticsearch'
:
'terminal.backends.command.db'
,
}
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
apps/terminal/backends/command/base.py
View file @
b936d54a
...
...
@@ -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
View file @
b936d54a
...
...
@@ -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,7 +37,9 @@ class CommandStore(CommandBase):
))
return
self
.
model
.
objects
.
bulk_create
(
_commands
)
def
filter
(
self
,
date_from
=
None
,
date_to
=
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
=
{}
...
...
@@ -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
def
all
(
self
):
"""返回所有数据"""
return
self
.
model
.
objects
.
iterator
()
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
apps/terminal/backends/command/models.py
View file @
b936d54a
...
...
@@ -18,5 +18,20 @@ 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
__str__
(
self
):
return
self
.
input
apps/terminal/forms.py
View file @
b936d54a
...
...
@@ -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
View file @
b936d54a
...
...
@@ -4,17 +4,27 @@ 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
=
[]
for
k
,
v
in
settings
.
TERMINAL_COMMAND_STORAGE
.
items
():
storage_choices
.
append
((
k
,
k
))
return
storage_choices
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 +43,16 @@ class Terminal(models.Model):
self
.
user
.
is_active
=
active
self
.
user
.
save
()
def
get_common_storage
(
self
):
pass
def
get_replay_storage
(
self
):
pass
@property
def
config
(
self
):
return
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
View file @
b936d54a
...
...
@@ -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_
terminal_
command_store
class
TerminalSerializer
(
serializers
.
ModelSerializer
):
...
...
@@ -43,7 +43,7 @@ class TerminalSerializer(serializers.ModelSerializer):
class
SessionSerializer
(
serializers
.
ModelSerializer
):
command_amount
=
serializers
.
SerializerMethodField
()
command_store
=
get_command_store
()
command_store
=
get_
terminal_
command_store
()
class
Meta
:
model
=
Session
...
...
apps/terminal/templates/terminal/terminal_modal_accept.html
View file @
b936d54a
...
...
@@ -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
View file @
b936d54a
...
...
@@ -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
View file @
b936d54a
# ~*~ coding: utf-8 ~*~
from
django
import
template
from
..backends
import
get_command_store
from
..backends
import
get_
terminal_
command_store
register
=
template
.
Library
()
command_store
=
get
_command_store
()
command_store
_dict
=
get_terminal
_command_store
()
@register.filter
def
get_session_command_amount
(
session_id
):
return
len
(
command_store
.
filter
(
session
=
str
(
session_id
)))
amount
=
0
for
name
,
store
in
command_store_dict
.
items
():
amount
+=
store
.
count
(
session
=
str
(
session_id
))
return
amount
apps/terminal/views/command.py
View file @
b936d54a
...
...
@@ -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_
terminal_
command_store
__all__
=
[
'CommandListView'
]
command_store
=
get
_command_store
()
command_store
_list
=
get_terminal
_command_store
()
class
CommandListView
(
DatetimeSearchMixin
,
ListView
):
...
...
@@ -39,7 +39,10 @@ class CommandListView(DatetimeSearchMixin, ListView):
filter_kwargs
[
'system_user'
]
=
self
.
system_user
if
self
.
command
:
filter_kwargs
[
'input'
]
=
self
.
command
queryset
=
command_store
.
filter
(
**
filter_kwargs
)
queryset
=
[]
for
store
in
command_store_list
:
queryset
.
extend
(
store
.
filter
(
**
filter_kwargs
))
queryset
=
sorted
(
queryset
,
key
=
lambda
c
:
c
.
timestamp
,
reverse
=
True
)
return
queryset
def
get_context_data
(
self
,
**
kwargs
):
...
...
apps/terminal/views/session.py
View file @
b936d54a
...
...
@@ -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_
terminal_
command_store
from
..
import
utils
...
...
@@ -19,7 +19,7 @@ __all__ = [
'SessionDetailView'
,
]
command_store
=
get_command_store
()
command_store
=
get_
terminal_
command_store
()
class
SessionListView
(
AdminUserRequiredMixin
,
DatetimeSearchMixin
,
ListView
):
...
...
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