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
284e8be4
Commit
284e8be4
authored
Oct 23, 2018
by
BaiJiangJie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改系统设置-命令/录像存储页面(添加,删除)
parent
c9f4b104
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
468 additions
and
71 deletions
+468
-71
api.py
apps/common/api.py
+76
-0
forms.py
apps/common/forms.py
+20
-16
models.py
apps/common/models.py
+24
-0
command_storage_create.html
apps/common/templates/common/command_storage_create.html
+177
-0
replay_storage_create.html
apps/common/templates/common/replay_storage_create.html
+0
-0
terminal_setting.html
apps/common/templates/common/terminal_setting.html
+68
-36
api_urls.py
apps/common/urls/api_urls.py
+4
-0
view_urls.py
apps/common/urls/view_urls.py
+2
-0
utils.py
apps/common/utils.py
+43
-0
views.py
apps/common/views.py
+30
-3
_base_create_update.html
apps/templates/_base_create_update.html
+2
-2
__init__.py
apps/terminal/backends/__init__.py
+6
-1
forms.py
apps/terminal/forms.py
+16
-13
No files found.
apps/common/api.py
View file @
284e8be4
# -*- coding: utf-8 -*-
#
import
os
import
json
import
jms_storage
from
rest_framework.views
import
Response
,
APIView
from
ldap3
import
Server
,
Connection
...
...
@@ -10,6 +13,7 @@ from django.conf import settings
from
.permissions
import
IsOrgAdmin
from
.serializers
import
MailTestSerializer
,
LDAPTestSerializer
from
.models
import
Setting
class
MailTestingAPI
(
APIView
):
...
...
@@ -85,6 +89,78 @@ class LDAPTestingAPI(APIView):
return
Response
({
"error"
:
str
(
serializer
.
errors
)},
status
=
401
)
class
ReplayStorageCreateAPI
(
APIView
):
permission_classes
=
(
IsOrgAdmin
,)
def
post
(
self
,
request
):
storage_data
=
request
.
data
if
storage_data
.
get
(
'TYPE'
)
==
'ceph'
:
port
=
storage_data
.
get
(
'PORT'
)
if
port
.
isdigit
():
storage_data
[
'PORT'
]
=
int
(
storage_data
.
get
(
'PORT'
))
storage_name
=
storage_data
.
pop
(
'NAME'
)
data
=
{
storage_name
:
storage_data
}
if
not
self
.
is_valid
(
storage_data
):
return
Response
({
"error"
:
_
(
"Error: Account invalid"
)},
status
=
401
)
Setting
.
save_storage
(
'TERMINAL_REPLAY_STORAGE'
,
data
)
return
Response
({
"msg"
:
_
(
'Create succeed'
)},
status
=
200
)
@staticmethod
def
is_valid
(
storage_data
):
if
storage_data
.
get
(
'TYPE'
)
==
'server'
:
return
True
storage
=
jms_storage
.
get_object_storage
(
storage_data
)
target
=
'tests.py'
src
=
os
.
path
.
join
(
settings
.
BASE_DIR
,
'common'
,
target
)
ok
,
msg
=
storage
.
upload
(
src
=
src
,
target
=
target
)
if
not
ok
:
return
False
storage
.
delete
(
path
=
target
)
return
True
class
ReplayStorageDeleteAPI
(
APIView
):
def
post
(
self
,
request
):
storage_name
=
str
(
request
.
data
.
get
(
'name'
))
Setting
.
delete_storage
(
'TERMINAL_REPLAY_STORAGE'
,
storage_name
)
return
Response
({
"msg"
:
_
(
'Delete succeed'
)},
status
=
200
)
class
CommandStorageCreateAPI
(
APIView
):
permission_classes
=
(
IsOrgAdmin
,)
def
post
(
self
,
request
):
storage_data
=
request
.
data
storage_name
=
storage_data
.
pop
(
'NAME'
)
data
=
{
storage_name
:
storage_data
}
if
not
self
.
is_valid
(
storage_data
):
return
Response
({
"error"
:
_
(
"Error: Account invalid"
)},
status
=
401
)
Setting
.
save_storage
(
'TERMINAL_COMMAND_STORAGE'
,
data
)
return
Response
({
"msg"
:
_
(
'Create succeed'
)},
status
=
200
)
@staticmethod
def
is_valid
(
storage_data
):
if
storage_data
.
get
(
'TYPE'
)
==
'server'
:
return
True
storage
=
jms_storage
.
get_log_storage
(
storage_data
)
return
storage
.
ping
()
class
CommandStorageDeleteAPI
(
APIView
):
permission_classes
=
(
IsOrgAdmin
,)
def
post
(
self
,
request
):
storage_name
=
str
(
request
.
data
.
get
(
'name'
))
Setting
.
delete_storage
(
'TERMINAL_COMMAND_STORAGE'
,
storage_name
)
return
Response
({
"msg"
:
_
(
'Delete succeed'
)},
status
=
200
)
class
DjangoSettingsAPI
(
APIView
):
def
get
(
self
,
request
):
if
not
settings
.
DEBUG
:
...
...
apps/common/forms.py
View file @
284e8be4
...
...
@@ -135,30 +135,34 @@ class TerminalSettingForm(BaseForm):
(
'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
=
FormEncryptDictField
(
label
=
_
(
"Command storage"
),
help_text
=
_
(
"Set terminal storage setting, `default` is the using as default,"
"You can set other storage and some terminal using"
)
TERMINAL_HEARTBEAT_INTERVAL
=
forms
.
IntegerField
(
initial
=
5
,
label
=
_
(
"Heartbeat interval"
),
help_text
=
_
(
"Units: seconds"
)
)
TERMINAL_REPLAY_STORAGE
=
FormEncryptDictField
(
label
=
_
(
"Replay storage"
),
help_text
=
_
(
"Set replay storage setting, `default` is the using as default,"
"You can set other storage and some terminal using"
)
TERMINAL_ASSET_LIST_SORT_BY
=
forms
.
ChoiceField
(
choices
=
SORT_BY_CHOICES
,
initial
=
'hostname'
,
label
=
_
(
"List sort by"
)
)
# TERMINAL_COMMAND_STORAGE = FormEncryptDictField(
# label=_("Command storage"), help_text=_(
# "Set terminal storage setting, `default` is the using as default,"
# "You can set other storage and some terminal using"
# )
# )
# TERMINAL_REPLAY_STORAGE = FormEncryptDictField(
# label=_("Replay storage"), help_text=_(
# "Set replay storage setting, `default` is the using as default,"
# "You can set other storage and some terminal using"
# )
# )
class
TerminalCommandStorage
(
BaseForm
):
pass
class
SecuritySettingForm
(
BaseForm
):
...
...
apps/common/models.py
View file @
284e8be4
...
...
@@ -67,6 +67,30 @@ class Setting(models.Model):
except
json
.
JSONDecodeError
as
e
:
raise
ValueError
(
"Json dump error: {}"
.
format
(
str
(
e
)))
@classmethod
def
save_storage
(
cls
,
name
,
data
):
obj
=
cls
.
objects
.
filter
(
name
=
name
)
.
first
()
if
not
obj
:
obj
=
cls
()
obj
.
name
=
name
obj
.
encrypted
=
True
obj
.
cleaned_value
=
data
else
:
value
=
obj
.
cleaned_value
value
.
update
(
data
)
obj
.
cleaned_value
=
value
obj
.
save
()
return
obj
@classmethod
def
delete_storage
(
cls
,
name
,
storage_name
):
obj
=
cls
.
objects
.
get
(
name
=
name
)
value
=
obj
.
cleaned_value
value
.
pop
(
storage_name
,
''
)
obj
.
cleaned_value
=
value
obj
.
save
()
return
True
@classmethod
def
refresh_all_settings
(
cls
):
try
:
...
...
apps/common/templates/common/command_storage_create.html
0 → 100644
View file @
284e8be4
{#{% extends 'base.html' %}#}
{% extends '_base_create_update.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=
"ibox-title"
>
<h5>
{{ action }}
</h5>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<form
action=
""
method=
"POST"
class=
"form-horizontal"
>
<div
class=
"form-group"
>
<label
class=
"col-md-2 control-label"
for=
"id_type"
>
{% trans "Type" %}
</label>
<div
class=
"col-md-9"
>
<select
id=
"id_type"
class=
"selector form-control"
>
<option
value =
"server"
selected=
"selected"
>
server
</option>
<option
value =
"es"
>
es (elasticsearch)
</option>
</select>
</div>
</div>
<div
class=
"form-group"
>
<label
class=
"col-md-2 control-label"
for=
"id_name"
>
{% trans "Name" %}
</label>
<div
class=
"col-md-9"
>
<input
id=
"id_name"
class=
"form-control"
type=
"text"
name=
"NAME"
value=
""
>
<div
class=
"help-block"
>
* required
</div>
<div
id=
"id_error"
style=
"color: red;"
></div>
</div>
</div>
<div
class=
"form-group"
style=
"display: none;"
>
<label
class=
"col-md-2 control-label"
for=
"id_hosts"
>
{% trans "Hosts" %}
</label>
<div
class=
"col-md-9"
>
<input
id=
"id_hosts"
class=
"form-control"
type=
"text"
name=
"HOSTS"
value=
""
>
<div
class=
"help-block"
>
如果有多台主机,请使用逗号 ( , ) 进行分割
</div>
</div>
</div>
{#
<div
class=
"form-group"
style=
"display: none;"
>
#}
{#
<label
class=
"col-md-2 control-label"
for=
"id_other"
>
{% trans "Other" %}
</label>
#}
{#
<div
class=
"col-md-9"
>
#}
{#
<input
id=
"id_other"
class=
"form-control"
type=
"text"
name=
"OTHER"
value=
""
>
#}
{#
</div>
#}
{#
</div>
#}
<div
class=
"form-group"
style=
"display: none;"
>
<label
class=
"col-md-2 control-label"
for=
"id_bucket"
>
{% trans "Index" %}
</label>
<div
class=
"col-md-9"
>
<input
id=
"id_index"
class=
"form-control"
type=
"text"
name=
"INDEX"
value=
"jumpserver"
>
</div>
</div>
<div
class=
"form-group"
style=
"display: none;"
>
<label
class=
"col-md-2 control-label"
for=
"id_doc_type"
>
{% trans "Doc type" %}
</label>
<div
class=
"col-md-9"
>
<input
id=
"id_doc_type"
class=
"form-control"
type=
"text"
name=
"DOC_TYPE"
value=
"command_store"
>
</div>
</div>
<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>
<a
class=
"btn btn-primary"
type=
""
id=
"id_submit_button"
>
{% trans 'Submit' %}
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
var
field_of_all
,
need_get_field_of_server
,
need_get_field_of_es
;
function
showField
(
field
){
$
.
each
(
field
,
function
(
index
,
value
){
$
(
value
).
parent
(
'div'
).
parent
(
'div'
).
css
(
'display'
,
''
);
});
}
function
hiddenField
(
field
){
$
.
each
(
field
,
function
(
index
,
value
){
$
(
value
).
parent
(
'div'
).
parent
(
'div'
).
css
(
'display'
,
'none'
);
})
}
function
getFieldByType
(
type
){
if
(
type
===
'server'
){
return
need_get_field_of_server
}
else
if
(
type
===
'es'
){
return
need_get_field_of_es
}
}
function
ajaxAPI
(
url
,
data
,
success
,
error
){
$
.
ajax
({
url
:
url
,
data
:
data
,
method
:
'POST'
,
contentType
:
'application/json; charset=utf-8'
,
success
:
success
,
error
:
error
})
}
$
(
document
).
ready
(
function
()
{
var
name_id
=
'#id_name'
;
var
hosts_id
=
'#id_hosts'
;
{
#
var
other_id
=
'#id_other'
;
#
}
var
index_id
=
'#id_index'
;
var
doc_type_id
=
'#id_doc_type'
;
field_of_all
=
[
name_id
,
hosts_id
,
index_id
,
doc_type_id
];
need_get_field_of_server
=
[
name_id
];
need_get_field_of_es
=
[
name_id
,
hosts_id
,
index_id
,
doc_type_id
];
})
.
on
(
'change'
,
'.selector'
,
function
(){
var
type
=
$
(
'.selector'
).
val
();
console
.
log
(
type
);
hiddenField
(
field_of_all
);
var
field
=
getFieldByType
(
type
);
showField
(
field
)
})
.
on
(
'click'
,
'#id_submit_button'
,
function
(){
var
type
=
$
(
'.selector'
).
val
();
var
field
=
getFieldByType
(
type
);
var
data
=
{
'TYPE'
:
type
};
$
.
each
(
field
,
function
(
index
,
id_field
){
var
name
=
$
(
id_field
).
attr
(
'name'
);
var
value
=
$
(
id_field
).
val
();
if
(
name
===
'HOSTS'
){
data
[
name
]
=
value
.
split
(
','
);
}
else
{
data
[
name
]
=
value
}
});
var
url
=
"{% url 'api-common:command-storage-create' %}"
;
var
success
=
function
(
data
,
textStatus
)
{
console
.
log
(
data
,
textStatus
);
location
=
"{% url 'common:terminal-setting' %}"
;
};
var
error
=
function
(
data
,
textStatus
)
{
var
error_msg
=
data
.
responseJSON
.
error
;
$
(
'#id_error'
).
html
(
error_msg
)
};
ajaxAPI
(
url
,
JSON
.
stringify
(
data
),
success
,
error
)
})
</script>
{% endblock %}
apps/common/templates/common/replay_storage_create.html
0 → 100644
View file @
284e8be4
This diff is collapsed.
Click to expand it.
apps/common/templates/common/terminal_setting.html
View file @
284e8be4
...
...
@@ -63,6 +63,14 @@
{% endif %}
{% endfor %}
<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>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans "Command storage" %}
</h3>
...
...
@@ -71,6 +79,7 @@
<tr>
<th>
{% trans 'Name' %}
</th>
<th>
{% trans 'Type' %}
</th>
<th>
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
...
...
@@ -78,10 +87,13 @@
<tr>
<td>
{{ name }}
</td>
<td>
{{ setting.TYPE }}
</td>
<td><a
class=
"btn btn-xs btn-danger m-l-xs btn-del-command"
data-name=
"{{ name }}"
>
{% trans 'Delete' %}
</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<a
href=
"{% url 'common:command-storage-create' %}"
class=
"btn btn-primary"
>
{% trans 'Add' %}
</a>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans "Replay storage" %}
</h3>
<table
class=
"table table-hover "
id=
"task-history-list-table"
>
...
...
@@ -89,6 +101,7 @@
<tr>
<th>
{% trans 'Name' %}
</th>
<th>
{% trans 'Type' %}
</th>
<th>
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
...
...
@@ -96,18 +109,14 @@
<tr>
<td>
{{ name }}
</td>
<td>
{{ setting.TYPE }}
</td>
<td><a
class=
"btn btn-xs btn-danger m-l-xs btn-del-replay"
data-name=
"{{ name }}"
>
{% trans 'Delete' %}
</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<a
href=
"{% url 'common:replay-storage-create' %}"
class=
"btn btn-primary"
>
{% trans 'Add' %}
</a>
<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>
...
...
@@ -116,40 +125,63 @@
</div>
</div>
</div>
</div>
{% 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
;
});
<script>
var
the_url
=
"{% url 'api-common:ldap-testing' %}"
;
function
ajaxAPI
(
url
,
data
,
success
,
error
,
method
){
$
.
ajax
({
url
:
url
,
data
:
data
,
method
:
method
,
contentType
:
'application/json; charset=utf-8'
,
success
:
success
,
error
:
error
})
}
function
error
(
message
)
{
toastr
.
error
(
message
)
}
function
deleteStorage
(
$this
,
the_url
){
var
name
=
$this
.
data
(
'name'
);
function
doDelete
(){
console
.
log
(
'delete storage'
);
var
data
=
{
"name"
:
name
};
var
method
=
'POST'
;
var
success
=
function
(){
$this
.
parent
().
parent
().
remove
();
toastr
.
success
(
"{% trans 'Delete success' %}"
);
};
var
error
=
function
(){
toastr
.
error
(
"{% trans 'Delete failed' %}}"
);
};
ajaxAPI
(
the_url
,
JSON
.
stringify
(
data
),
success
,
error
,
method
);
}
swal
({
title
:
"{% trans 'Are you sure about deleting it?' %}"
,
text
:
" ["
+
name
+
"] "
,
type
:
"warning"
,
showCancelButton
:
true
,
cancelButtonText
:
"{% trans 'Cancel' %}"
,
confirmButtonColor
:
"#ed5565"
,
confirmButtonText
:
"{% trans 'Confirm' %}"
,
closeOnConfirm
:
true
},
function
()
{
doDelete
()
});
}
function
success
(
message
)
{
toastr
.
success
(
message
.
msg
)
}
$
(
document
).
ready
(
function
()
{
APIUpdateAttr
({
url
:
the_url
,
body
:
JSON
.
stringify
(
data
),
method
:
"POST"
,
flash_message
:
false
,
success
:
success
,
error
:
error
});
})
.
on
(
'click'
,
''
,
function
()
{
})
.
on
(
'click'
,
'.btn-del-replay'
,
function
(){
var
$this
=
$
(
this
);
var
the_url
=
"{% url 'api-common:replay-storage-delete' %}"
;
deleteStorage
(
$this
,
the_url
);
})
.
on
(
'click'
,
'.btn-del-command'
,
function
()
{
var
$this
=
$
(
this
);
var
the_url
=
"{% url 'api-common:command-storage-delete' %}"
;
deleteStorage
(
$this
,
the_url
)
});
})
</script>
</script>
{% endblock %}
apps/common/urls/api_urls.py
View file @
284e8be4
...
...
@@ -9,5 +9,9 @@ app_name = 'common'
urlpatterns
=
[
path
(
'mail/testing/'
,
api
.
MailTestingAPI
.
as_view
(),
name
=
'mail-testing'
),
path
(
'ldap/testing/'
,
api
.
LDAPTestingAPI
.
as_view
(),
name
=
'ldap-testing'
),
path
(
'terminal/replay-storage/create/'
,
api
.
ReplayStorageCreateAPI
.
as_view
(),
name
=
'replay-storage-create'
),
path
(
'terminal/replay-storage/delete/'
,
api
.
ReplayStorageDeleteAPI
.
as_view
(),
name
=
'replay-storage-delete'
),
path
(
'terminal/command-storage/create/'
,
api
.
CommandStorageCreateAPI
.
as_view
(),
name
=
'command-storage-create'
),
path
(
'terminal/command-storage/delete/'
,
api
.
CommandStorageDeleteAPI
.
as_view
(),
name
=
'command-storage-delete'
),
# path('django-settings/', api.DjangoSettingsAPI.as_view(), name='django-settings'),
]
apps/common/urls/view_urls.py
View file @
284e8be4
...
...
@@ -11,5 +11,7 @@ urlpatterns = [
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'
),
url
(
r'^terminal/replay-storage/create$'
,
views
.
ReplayStorageCreateView
.
as_view
(),
name
=
'replay-storage-create'
),
url
(
r'^terminal/command-storage/create$'
,
views
.
CommandStorageCreateView
.
as_view
(),
name
=
'command-storage-create'
),
url
(
r'^security/$'
,
views
.
SecuritySettingView
.
as_view
(),
name
=
'security-setting'
),
]
apps/common/utils.py
View file @
284e8be4
...
...
@@ -387,6 +387,49 @@ def get_request_ip(request):
return
login_ip
def
get_command_storage_or_create_default_storage
():
from
common.models
import
common_settings
,
Setting
name
=
'TERMINAL_COMMAND_STORAGE'
default
=
{
'default'
:
{
'TYPE'
:
'server'
}}
command_storage
=
common_settings
.
TERMINAL_COMMAND_STORAGE
if
command_storage
is
None
:
obj
=
Setting
()
obj
.
name
=
name
obj
.
encrypted
=
True
obj
.
cleaned_value
=
default
obj
.
save
()
if
isinstance
(
command_storage
,
dict
)
and
not
command_storage
:
obj
=
Setting
.
objects
.
get
(
name
=
name
)
value
=
obj
.
cleaned_value
value
.
update
(
default
)
obj
.
cleaned_value
=
value
obj
.
save
()
command_storage
=
common_settings
.
TERMINAL_COMMAND_STORAGE
return
command_storage
def
get_replay_storage_or_create_default_storage
():
from
common.models
import
common_settings
,
Setting
name
=
'TERMINAL_REPLAY_STORAGE'
default
=
{
'default'
:
{
'TYPE'
:
'server'
}}
replay_storage
=
common_settings
.
TERMINAL_REPLAY_STORAGE
if
replay_storage
is
None
:
obj
=
Setting
()
obj
.
name
=
name
obj
.
encrypted
=
True
obj
.
cleaned_value
=
default
obj
.
save
()
replay_storage
=
common_settings
.
TERMINAL_REPLAY_STORAGE
if
isinstance
(
replay_storage
,
dict
)
and
not
replay_storage
:
obj
=
Setting
.
objects
.
get
(
name
=
name
)
value
=
obj
.
cleaned_value
value
.
update
(
default
)
obj
.
cleaned_value
=
value
obj
.
save
()
replay_storage
=
common_settings
.
TERMINAL_REPLAY_STORAGE
return
replay_storage
class
TeeObj
:
origin_stdout
=
sys
.
stdout
...
...
apps/common/views.py
View file @
284e8be4
...
...
@@ -4,10 +4,12 @@ from django.contrib import messages
from
django.utils.translation
import
ugettext
as
_
from
django.conf
import
settings
from
common.models
import
common_settings
from
.forms
import
EmailSettingForm
,
LDAPSettingForm
,
BasicSettingForm
,
\
TerminalSettingForm
,
SecuritySettingForm
from
common.permissions
import
SuperUserRequiredMixin
from
.signals
import
ldap_auth_enable
from
.
import
utils
class
BasicSettingView
(
SuperUserRequiredMixin
,
TemplateView
):
...
...
@@ -95,14 +97,15 @@ class TerminalSettingView(SuperUserRequiredMixin, TemplateView):
template_name
=
"common/terminal_setting.html"
def
get_context_data
(
self
,
**
kwargs
):
command_storage
=
settings
.
TERMINAL_COMMAND_STORAGE
replay_storage
=
settings
.
TERMINAL_REPLAY_STORAGE
command_storage
=
utils
.
get_command_storage_or_create_default_storage
()
replay_storage
=
utils
.
get_replay_storage_or_create_default_storage
()
context
=
{
'app'
:
_
(
'Settings'
),
'action'
:
_
(
'Terminal setting'
),
'form'
:
self
.
form_class
(),
'replay_storage'
:
replay_storage
,
'command_storage'
:
command_storage
,
'command_storage'
:
command_storage
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
...
...
@@ -120,6 +123,30 @@ class TerminalSettingView(SuperUserRequiredMixin, TemplateView):
return
render
(
request
,
self
.
template_name
,
context
)
class
ReplayStorageCreateView
(
SuperUserRequiredMixin
,
TemplateView
):
template_name
=
'common/replay_storage_create.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Settings'
),
'action'
:
_
(
'Create replay storage'
)
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
CommandStorageCreateView
(
SuperUserRequiredMixin
,
TemplateView
):
template_name
=
'common/command_storage_create.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Settings'
),
'action'
:
_
(
'Create command storage'
)
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
SecuritySettingView
(
SuperUserRequiredMixin
,
TemplateView
):
form_class
=
SecuritySettingForm
template_name
=
"common/security_setting.html"
...
...
apps/templates/_base_create_update.html
View file @
284e8be4
...
...
@@ -31,8 +31,8 @@
<div
class=
"ibox-content"
>
{% if form.errors.all %}
<div
class=
"alert alert-danger"
style=
"margin: 20px auto 0px"
>
{{ form.errors.all }}
</div>
{{ form.errors.all }}
</div>
{% endif %}
{% block form %}
{% endblock %}
...
...
apps/terminal/backends/__init__.py
View file @
284e8be4
...
...
@@ -2,6 +2,9 @@ from importlib import import_module
from
django.conf
import
settings
from
.command.serializers
import
SessionCommandSerializer
from
common
import
utils
from
common.models
import
common_settings
,
Setting
TYPE_ENGINE_MAPPING
=
{
'elasticsearch'
:
'terminal.backends.command.es'
,
}
...
...
@@ -16,7 +19,9 @@ def get_command_storage():
def
get_terminal_command_storages
():
storage_list
=
{}
for
name
,
params
in
settings
.
TERMINAL_COMMAND_STORAGE
.
items
():
command_storage
=
utils
.
get_command_storage_or_create_default_storage
()
for
name
,
params
in
command_storage
.
items
():
tp
=
params
[
'TYPE'
]
if
tp
==
'server'
:
storage
=
get_command_storage
()
...
...
apps/terminal/forms.py
View file @
284e8be4
...
...
@@ -2,36 +2,39 @@
#
from
django
import
forms
from
django.conf
import
settings
from
django.utils.translation
import
ugettext_lazy
as
_
from
.models
import
Terminal
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
)
from
common
import
utils
command_storage
=
utils
.
get_command_storage_or_create_default_storage
()
command_storage_choice
=
[]
for
k
,
v
in
command_storage
.
items
():
command_storage_choice
.
append
((
k
,
k
))
return
command_storage_choice
def
get_all_replay_storage
():
# storage_choices = []
from
common.models
import
Setting
Setting
.
refresh_all_settings
()
for
k
,
v
in
settings
.
TERMINAL_REPLAY_STORAGE
.
items
():
yield
(
k
,
k
)
from
common
import
utils
replay_storage
=
utils
.
get_replay_storage_or_create_default_storage
()
replay_storage_choice
=
[]
for
k
,
v
in
replay_storage
.
items
():
replay_storage_choice
.
append
((
k
,
k
))
return
replay_storage_choice
class
TerminalForm
(
forms
.
ModelForm
):
command_storage
=
forms
.
ChoiceField
(
choices
=
get_all_command_storage
()
,
choices
=
get_all_command_storage
,
label
=
_
(
"Command storage"
),
help_text
=
_
(
"Command can store in server db or ES, default to server, more see docs"
),
)
replay_storage
=
forms
.
ChoiceField
(
choices
=
get_all_replay_storage
()
,
choices
=
get_all_replay_storage
,
label
=
_
(
"Replay storage"
),
help_text
=
_
(
"Replay file can store in server disk, AWS S3, Aliyun OSS, default to server, more see docs"
),
)
...
...
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