mirror of https://github.com/jumpserver/jumpserver
[Update] 修改系统设置-命令/录像存储页面(添加,删除)
parent
c9f4b104c7
commit
284e8be45c
|
@ -1,6 +1,9 @@
|
|||
# -*- 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:
|
||||
|
|
|
@ -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_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_HEARTBEAT_INTERVAL = forms.IntegerField(
|
||||
initial=5, label=_("Heartbeat interval"), help_text=_("Units: seconds")
|
||||
)
|
||||
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):
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
{#{% 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 %}
|
|
@ -0,0 +1,242 @@
|
|||
{#{% 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 ="s3">s3</option>
|
||||
<option value="oss">oss</option>
|
||||
<option value ="azure">azure</option>
|
||||
<option value="ceph">ceph</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="display: none; color: red;">{% trans 'Error: Account invalid' %}</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_host">{% trans "Host" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_host" class="form-control" type="text" name="HOSTNAME" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_port">{% trans "Port" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_port" class="form-control" type="text" name="PORT" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_bucket">{% trans "Bucket" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_bucket" class="form-control" type="text" name="BUCKET" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_access_key">{% trans "Access key" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_access_key" class="form-control" type="text" name="ACCESS_KEY" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_secret_key">{% trans "Secret key" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_secret_key" class="form-control" type="text" name="SECRET_KEY" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_container_name">{% trans "Container name" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_container_name" class="form-control" type="text" name="CONTAINER_NAME" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_account_name">{% trans "Account name" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_account_name" class="form-control" type="text" name="ACCOUNT_NAME" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_account_key">{% trans "Account key" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_account_key" class="form-control" type="text" name="ACCOUNT_KEY" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_endpoint">{% trans "Endpoint" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_endpoint" class="form-control" type="text" name="ENDPOINT" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_endpoint_suffix">{% trans "Endpoint suffix" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_endpoint_suffix" class="form-control" type="text" name="ENDPOINT_SUFFIX" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: none;" >
|
||||
<label class="col-md-2 control-label" for="id_region">{% trans "Region" %}</label>
|
||||
<div class="col-md-9">
|
||||
<input id="id_region" class="form-control" type="text" name="REGION" value="">
|
||||
</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_s3,
|
||||
need_get_field_of_oss, need_get_field_of_azure, need_get_field_of_ceph;
|
||||
|
||||
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 === 's3'){
|
||||
return need_get_field_of_s3
|
||||
}
|
||||
else if(type === 'oss'){
|
||||
return need_get_field_of_oss
|
||||
}
|
||||
else if(type === 'azure'){
|
||||
return need_get_field_of_azure
|
||||
}
|
||||
else if(type === 'ceph'){
|
||||
return need_get_field_of_ceph
|
||||
}
|
||||
}
|
||||
|
||||
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 host_id = '#id_host';
|
||||
var port_id = '#id_port';
|
||||
var bucket_id = '#id_bucket';
|
||||
var access_key_id = '#id_access_key';
|
||||
var secret_key_id = '#id_secret_key';
|
||||
var container_name_id = '#id_container_name';
|
||||
var account_name_id = '#id_account_name';
|
||||
var account_key_id = '#id_account_key';
|
||||
var endpoint_id = '#id_endpoint';
|
||||
var endpoint_suffix_id = '#id_endpoint_suffix';
|
||||
var region_id = '#id_region';
|
||||
|
||||
field_of_all = [name_id, host_id, port_id, bucket_id, access_key_id, secret_key_id, container_name_id, account_name_id, account_key_id, endpoint_id, endpoint_suffix_id, region_id];
|
||||
need_get_field_of_server = [name_id];
|
||||
need_get_field_of_s3 = [name_id, bucket_id, access_key_id, secret_key_id, region_id];
|
||||
need_get_field_of_oss = [name_id, access_key_id, secret_key_id, endpoint_id];
|
||||
need_get_field_of_azure = [name_id, container_name_id, account_name_id, account_key_id, endpoint_suffix_id];
|
||||
need_get_field_of_ceph = [name_id, host_id, port_id, bucket_id, access_key_id, secret_key_id, region_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');
|
||||
data[name] = $(id_field).val();
|
||||
});
|
||||
var url = "{% url 'api-common:replay-storage-create' %}";
|
||||
var success = function(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 %}
|
|
@ -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;
|
||||
});
|
||||
|
||||
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,
|
||||
function ajaxAPI(url, data, success, error, method){
|
||||
$.ajax({
|
||||
url: url,
|
||||
data: data,
|
||||
method: method,
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
success: success,
|
||||
error: error
|
||||
});
|
||||
})
|
||||
.on('click', '', function () {
|
||||
}
|
||||
|
||||
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()
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(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>
|
||||
{% endblock %}
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"),
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue