Unverified Commit 354b728f authored by 老广's avatar 老广 Committed by GitHub

Merge pull request #1945 from jumpserver/dev_storage

[Update] 更新命令/录像存储设置
parents ce553710 4f806f11
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import os
import json import json
import jms_storage
from rest_framework.views import Response, APIView from rest_framework.views import Response, APIView
from ldap3 import Server, Connection from ldap3 import Server, Connection
...@@ -8,8 +11,9 @@ from django.core.mail import get_connection, send_mail ...@@ -8,8 +11,9 @@ from django.core.mail import get_connection, send_mail
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.conf import settings from django.conf import settings
from .permissions import IsOrgAdmin from .permissions import IsOrgAdmin, IsSuperUser
from .serializers import MailTestSerializer, LDAPTestSerializer from .serializers import MailTestSerializer, LDAPTestSerializer
from .models import Setting
class MailTestingAPI(APIView): class MailTestingAPI(APIView):
...@@ -85,6 +89,79 @@ class LDAPTestingAPI(APIView): ...@@ -85,6 +89,79 @@ class LDAPTestingAPI(APIView):
return Response({"error": str(serializer.errors)}, status=401) return Response({"error": str(serializer.errors)}, status=401)
class ReplayStorageCreateAPI(APIView):
permission_classes = (IsSuperUser,)
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)
return storage.is_valid(src, target)
class ReplayStorageDeleteAPI(APIView):
permission_classes = (IsSuperUser,)
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 = (IsSuperUser,)
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
try:
storage = jms_storage.get_log_storage(storage_data)
except Exception:
return False
return storage.ping()
class CommandStorageDeleteAPI(APIView):
permission_classes = (IsSuperUser,)
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): class DjangoSettingsAPI(APIView):
def get(self, request): def get(self, request):
if not settings.DEBUG: if not settings.DEBUG:
......
...@@ -135,32 +135,24 @@ class TerminalSettingForm(BaseForm): ...@@ -135,32 +135,24 @@ class TerminalSettingForm(BaseForm):
('hostname', _('Hostname')), ('hostname', _('Hostname')),
('ip', _('IP')), ('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( TERMINAL_PASSWORD_AUTH = forms.BooleanField(
initial=True, required=False, label=_("Password auth") initial=True, required=False, label=_("Password auth")
) )
TERMINAL_PUBLIC_KEY_AUTH = forms.BooleanField( TERMINAL_PUBLIC_KEY_AUTH = forms.BooleanField(
initial=True, required=False, label=_("Public key auth") initial=True, required=False, label=_("Public key auth")
) )
TERMINAL_COMMAND_STORAGE = FormEncryptDictField( TERMINAL_HEARTBEAT_INTERVAL = forms.IntegerField(
label=_("Command storage"), help_text=_( initial=5, label=_("Heartbeat interval"), help_text=_("Units: seconds")
"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_ASSET_LIST_SORT_BY = forms.ChoiceField(
choices=SORT_BY_CHOICES, initial='hostname', label=_("List sort by")
) )
class TerminalCommandStorage(BaseForm):
pass
class SecuritySettingForm(BaseForm): class SecuritySettingForm(BaseForm):
# MFA global setting # MFA global setting
SECURITY_MFA_AUTH = forms.BooleanField( SECURITY_MFA_AUTH = forms.BooleanField(
......
...@@ -67,6 +67,30 @@ class Setting(models.Model): ...@@ -67,6 +67,30 @@ class Setting(models.Model):
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
raise ValueError("Json dump error: {}".format(str(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 @classmethod
def refresh_all_settings(cls): def refresh_all_settings(cls):
try: try:
......
...@@ -3,6 +3,7 @@ from django.conf import settings ...@@ -3,6 +3,7 @@ from django.conf import settings
from celery import shared_task from celery import shared_task
from .utils import get_logger from .utils import get_logger
from .models import Setting from .models import Setting
from common.models import common_settings
logger = get_logger(__file__) logger = get_logger(__file__)
...@@ -28,7 +29,7 @@ def send_mail_async(*args, **kwargs): ...@@ -28,7 +29,7 @@ def send_mail_async(*args, **kwargs):
if len(args) == 3: if len(args) == 3:
args = list(args) args = list(args)
args[0] = settings.EMAIL_SUBJECT_PREFIX + args[0] args[0] = common_settings.EMAIL_SUBJECT_PREFIX + args[0]
args.insert(2, settings.EMAIL_HOST_USER) args.insert(2, settings.EMAIL_HOST_USER)
args = tuple(args) args = tuple(args)
......
...@@ -75,32 +75,6 @@ ...@@ -75,32 +75,6 @@
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
$(document).ready(function () { $(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:mail-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
});
}) })
</script> </script>
{% endblock %} {% endblock %}
{#{% 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">{% trans 'Tips: If there are multiple hosts, separate them with a comma (,)' %}</div>
<div class="help-block">eg: http://www.jumpserver.a.com, http://www.jumpserver.b.com</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 %}
{#{% 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="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="" placeholder="Host">
</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="" placeholder="7480">
</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="" placeholder="Bucket">
</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="" placeholder="Access key">
</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="", placeholder="Secret key">
</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="" placeholder="Container">
</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="" placeholder="Account name">
</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="" placeholder="Account key">
</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="" placeholder="Endpoint">
</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 class="help-block">{% trans '' %}</div>#}
{# </div>#}
<div class="col-md-9">
<select id="id_endpoint_suffix" name="ENDPOINT_SUFFIX" class="endpoint-suffix-selector form-control">
<option value="core.chinacloudapi.cn" selected="selected">core.chinacloudapi.cn</option>
<option value="core.windows.net">core.windows.net</option>
</select>
</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="" placeholder="">
</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 @@ ...@@ -63,6 +63,14 @@
{% endif %} {% endif %}
{% endfor %} {% 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> <div class="hr-line-dashed"></div>
<h3>{% trans "Command storage" %}</h3> <h3>{% trans "Command storage" %}</h3>
...@@ -71,6 +79,7 @@ ...@@ -71,6 +79,7 @@
<tr> <tr>
<th>{% trans 'Name' %}</th> <th>{% trans 'Name' %}</th>
<th>{% trans 'Type' %}</th> <th>{% trans 'Type' %}</th>
<th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -78,10 +87,13 @@ ...@@ -78,10 +87,13 @@
<tr> <tr>
<td>{{ name }}</td> <td>{{ name }}</td>
<td>{{ setting.TYPE }}</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> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<a href="{% url 'common:command-storage-create' %}" class="btn btn-primary">{% trans 'Add' %}</a>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<h3>{% trans "Replay storage" %}</h3> <h3>{% trans "Replay storage" %}</h3>
<table class="table table-hover " id="task-history-list-table"> <table class="table table-hover " id="task-history-list-table">
...@@ -89,6 +101,7 @@ ...@@ -89,6 +101,7 @@
<tr> <tr>
<th>{% trans 'Name' %}</th> <th>{% trans 'Name' %}</th>
<th>{% trans 'Type' %}</th> <th>{% trans 'Type' %}</th>
<th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -96,18 +109,14 @@ ...@@ -96,18 +109,14 @@
<tr> <tr>
<td>{{ name }}</td> <td>{{ name }}</td>
<td>{{ setting.TYPE }}</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> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<a href="{% url 'common:replay-storage-create' %}" class="btn btn-primary">{% trans 'Add' %}</a>
<div class="hr-line-dashed"></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>
<button id="submit_button" class="btn btn-primary"
type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form> </form>
</div> </div>
</div> </div>
...@@ -116,40 +125,63 @@ ...@@ -116,40 +125,63 @@
</div> </div>
</div> </div>
</div> </div>
</div>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <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 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) { function deleteStorage($this, the_url){
toastr.error(message) 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 succeed' %}");
};
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) { $(document).ready(function () {
toastr.success(message.msg)
}
APIUpdateAttr({ })
url: the_url, .on('click', '.btn-del-replay', function(){
body: JSON.stringify(data), var $this = $(this);
method: "POST", var the_url = "{% url 'api-common:replay-storage-delete' %}";
flash_message: false, deleteStorage($this, the_url);
success: success, })
error: error .on('click', '.btn-del-command', function() {
}); var $this = $(this);
}) var the_url = "{% url 'api-common:command-storage-delete' %}";
.on('click', '', function () { deleteStorage($this, the_url)
});
}) </script>
</script>
{% endblock %} {% endblock %}
...@@ -9,5 +9,9 @@ app_name = 'common' ...@@ -9,5 +9,9 @@ app_name = 'common'
urlpatterns = [ urlpatterns = [
path('mail/testing/', api.MailTestingAPI.as_view(), name='mail-testing'), path('mail/testing/', api.MailTestingAPI.as_view(), name='mail-testing'),
path('ldap/testing/', api.LDAPTestingAPI.as_view(), name='ldap-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'), # path('django-settings/', api.DjangoSettingsAPI.as_view(), name='django-settings'),
] ]
...@@ -11,5 +11,7 @@ urlpatterns = [ ...@@ -11,5 +11,7 @@ urlpatterns = [
url(r'^email/$', views.EmailSettingView.as_view(), name='email-setting'), url(r'^email/$', views.EmailSettingView.as_view(), name='email-setting'),
url(r'^ldap/$', views.LDAPSettingView.as_view(), name='ldap-setting'), url(r'^ldap/$', views.LDAPSettingView.as_view(), name='ldap-setting'),
url(r'^terminal/$', views.TerminalSettingView.as_view(), name='terminal-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'), url(r'^security/$', views.SecuritySettingView.as_view(), name='security-setting'),
] ]
...@@ -37,7 +37,8 @@ def reverse(view_name, urlconf=None, args=None, kwargs=None, ...@@ -37,7 +37,8 @@ def reverse(view_name, urlconf=None, args=None, kwargs=None,
kwargs=kwargs, current_app=current_app) kwargs=kwargs, current_app=current_app)
if external: if external:
url = settings.SITE_URL.strip('/') + url from common.models import common_settings
url = common_settings.SITE_URL.strip('/') + url
return url return url
...@@ -387,6 +388,49 @@ def get_request_ip(request): ...@@ -387,6 +388,49 @@ def get_request_ip(request):
return login_ip 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: class TeeObj:
origin_stdout = sys.stdout origin_stdout = sys.stdout
......
...@@ -4,10 +4,12 @@ from django.contrib import messages ...@@ -4,10 +4,12 @@ from django.contrib import messages
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.conf import settings from django.conf import settings
from common.models import common_settings
from .forms import EmailSettingForm, LDAPSettingForm, BasicSettingForm, \ from .forms import EmailSettingForm, LDAPSettingForm, BasicSettingForm, \
TerminalSettingForm, SecuritySettingForm TerminalSettingForm, SecuritySettingForm
from common.permissions import SuperUserRequiredMixin from common.permissions import SuperUserRequiredMixin
from .signals import ldap_auth_enable from .signals import ldap_auth_enable
from . import utils
class BasicSettingView(SuperUserRequiredMixin, TemplateView): class BasicSettingView(SuperUserRequiredMixin, TemplateView):
...@@ -95,14 +97,15 @@ class TerminalSettingView(SuperUserRequiredMixin, TemplateView): ...@@ -95,14 +97,15 @@ class TerminalSettingView(SuperUserRequiredMixin, TemplateView):
template_name = "common/terminal_setting.html" template_name = "common/terminal_setting.html"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
command_storage = settings.TERMINAL_COMMAND_STORAGE command_storage = utils.get_command_storage_or_create_default_storage()
replay_storage = settings.TERMINAL_REPLAY_STORAGE replay_storage = utils.get_replay_storage_or_create_default_storage()
context = { context = {
'app': _('Settings'), 'app': _('Settings'),
'action': _('Terminal setting'), 'action': _('Terminal setting'),
'form': self.form_class(), 'form': self.form_class(),
'replay_storage': replay_storage, 'replay_storage': replay_storage,
'command_storage': command_storage, 'command_storage': command_storage
} }
kwargs.update(context) kwargs.update(context)
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
...@@ -120,6 +123,30 @@ class TerminalSettingView(SuperUserRequiredMixin, TemplateView): ...@@ -120,6 +123,30 @@ class TerminalSettingView(SuperUserRequiredMixin, TemplateView):
return render(request, self.template_name, context) 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): class SecuritySettingView(SuperUserRequiredMixin, TemplateView):
form_class = SecuritySettingForm form_class = SecuritySettingForm
template_name = "common/security_setting.html" template_name = "common/security_setting.html"
......
...@@ -8,7 +8,7 @@ msgid "" ...@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n" "Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-10-16 16:03+0800\n" "POT-Creation-Date: 2018-10-24 11:03+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n" "Language-Team: Jumpserver team<ibuler@qq.com>\n"
...@@ -34,8 +34,8 @@ msgid "Test if the assets under the node are connectable: {}" ...@@ -34,8 +34,8 @@ msgid "Test if the assets under the node are connectable: {}"
msgstr "测试节点下资产是否可连接: {}" msgstr "测试节点下资产是否可连接: {}"
#: assets/forms/asset.py:27 assets/models/asset.py:83 assets/models/user.py:113 #: assets/forms/asset.py:27 assets/models/asset.py:83 assets/models/user.py:113
#: assets/templates/assets/asset_detail.html:183 #: assets/templates/assets/asset_detail.html:187
#: assets/templates/assets/asset_detail.html:191 #: assets/templates/assets/asset_detail.html:195
#: assets/templates/assets/system_user_asset.html:95 perms/models.py:32 #: assets/templates/assets/system_user_asset.html:95 perms/models.py:32
msgid "Nodes" msgid "Nodes"
msgstr "节点管理" msgstr "节点管理"
...@@ -43,7 +43,7 @@ msgstr "节点管理" ...@@ -43,7 +43,7 @@ msgstr "节点管理"
#: assets/forms/asset.py:30 assets/forms/asset.py:69 assets/forms/asset.py:112 #: assets/forms/asset.py:30 assets/forms/asset.py:69 assets/forms/asset.py:112
#: assets/forms/asset.py:116 assets/models/asset.py:88 #: assets/forms/asset.py:116 assets/models/asset.py:88
#: assets/models/cluster.py:19 assets/models/user.py:73 #: assets/models/cluster.py:19 assets/models/user.py:73
#: assets/templates/assets/asset_detail.html:73 templates/_nav.html:24 #: assets/templates/assets/asset_detail.html:77 templates/_nav.html:24
#: xpack/plugins/cloud/models.py:137 #: xpack/plugins/cloud/models.py:137
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:67 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:67
#: xpack/plugins/orgs/templates/orgs/org_list.html:18 #: xpack/plugins/orgs/templates/orgs/org_list.html:18
...@@ -110,6 +110,7 @@ msgstr "选择资产" ...@@ -110,6 +110,7 @@ msgstr "选择资产"
#: assets/templates/assets/domain_gateway_list.html:58 #: assets/templates/assets/domain_gateway_list.html:58
#: assets/templates/assets/system_user_asset.html:52 #: assets/templates/assets/system_user_asset.html:52
#: assets/templates/assets/user_asset_list.html:163 #: assets/templates/assets/user_asset_list.html:163
#: common/templates/common/replay_storage_create.html:60
msgid "Port" msgid "Port"
msgstr "端口" msgstr "端口"
...@@ -154,8 +155,10 @@ msgstr "不能包含特殊字符" ...@@ -154,8 +155,10 @@ msgstr "不能包含特殊字符"
#: assets/templates/assets/label_list.html:14 #: assets/templates/assets/label_list.html:14
#: assets/templates/assets/system_user_detail.html:58 #: assets/templates/assets/system_user_detail.html:58
#: assets/templates/assets/system_user_list.html:29 common/models.py:30 #: assets/templates/assets/system_user_list.html:29 common/models.py:30
#: common/templates/common/terminal_setting.html:72 #: common/templates/common/command_storage_create.html:41
#: common/templates/common/terminal_setting.html:90 ops/models/adhoc.py:37 #: common/templates/common/replay_storage_create.html:44
#: common/templates/common/terminal_setting.html:80
#: common/templates/common/terminal_setting.html:102 ops/models/adhoc.py:37
#: ops/templates/ops/task_detail.html:59 ops/templates/ops/task_list.html:35 #: ops/templates/ops/task_detail.html:59 ops/templates/ops/task_list.html:35
#: orgs/models.py:12 perms/models.py:28 #: orgs/models.py:12 perms/models.py:28
#: perms/templates/perms/asset_permission_detail.html:62 #: perms/templates/perms/asset_permission_detail.html:62
...@@ -243,7 +246,9 @@ msgstr "自动推送系统用户到资产" ...@@ -243,7 +246,9 @@ msgstr "自动推送系统用户到资产"
msgid "" msgid ""
"1-100, High level will be using login asset as default, if user was granted " "1-100, High level will be using login asset as default, if user was granted "
"more than 2 system user" "more than 2 system user"
msgstr "1-100, 1最低优先级,100最高优先级。授权多个用户时,高优先级的系统用户将会作为默认登录用户" msgstr ""
"1-100, 1最低优先级,100最高优先级。授权多个用户时,高优先级的系统用户将会作为"
"默认登录用户"
#: assets/forms/user.py:155 #: assets/forms/user.py:155
msgid "" msgid ""
...@@ -281,7 +286,7 @@ msgid "Hostname" ...@@ -281,7 +286,7 @@ msgid "Hostname"
msgstr "主机名" msgstr "主机名"
#: assets/models/asset.py:75 assets/models/domain.py:49 #: assets/models/asset.py:75 assets/models/domain.py:49
#: assets/models/user.py:117 #: assets/models/user.py:117 assets/templates/assets/asset_detail.html:73
#: assets/templates/assets/domain_gateway_list.html:59 #: assets/templates/assets/domain_gateway_list.html:59
#: assets/templates/assets/system_user_detail.html:70 #: assets/templates/assets/system_user_detail.html:70
#: assets/templates/assets/system_user_list.html:31 #: assets/templates/assets/system_user_list.html:31
...@@ -290,14 +295,14 @@ msgstr "主机名" ...@@ -290,14 +295,14 @@ msgstr "主机名"
msgid "Protocol" msgid "Protocol"
msgstr "协议" msgstr "协议"
#: assets/models/asset.py:77 assets/templates/assets/asset_detail.html:97 #: assets/models/asset.py:77 assets/templates/assets/asset_detail.html:101
#: assets/templates/assets/user_asset_list.html:165 #: assets/templates/assets/user_asset_list.html:165
msgid "Platform" msgid "Platform"
msgstr "系统平台" msgstr "系统平台"
#: assets/models/asset.py:84 assets/models/cmd_filter.py:20 #: assets/models/asset.py:84 assets/models/cmd_filter.py:20
#: assets/models/domain.py:52 assets/models/label.py:21 #: assets/models/domain.py:52 assets/models/label.py:21
#: assets/templates/assets/asset_detail.html:105 #: assets/templates/assets/asset_detail.html:109
#: assets/templates/assets/user_asset_list.html:169 #: assets/templates/assets/user_asset_list.html:169
msgid "Is active" msgid "Is active"
msgstr "激活" msgstr "激活"
...@@ -306,19 +311,19 @@ msgstr "激活" ...@@ -306,19 +311,19 @@ msgstr "激活"
msgid "Public IP" msgid "Public IP"
msgstr "公网IP" msgstr "公网IP"
#: assets/models/asset.py:92 assets/templates/assets/asset_detail.html:113 #: assets/models/asset.py:92 assets/templates/assets/asset_detail.html:117
msgid "Asset number" msgid "Asset number"
msgstr "资产编号" msgstr "资产编号"
#: assets/models/asset.py:96 assets/templates/assets/asset_detail.html:77 #: assets/models/asset.py:96 assets/templates/assets/asset_detail.html:81
msgid "Vendor" msgid "Vendor"
msgstr "制造商" msgstr "制造商"
#: assets/models/asset.py:98 assets/templates/assets/asset_detail.html:81 #: assets/models/asset.py:98 assets/templates/assets/asset_detail.html:85
msgid "Model" msgid "Model"
msgstr "型号" msgstr "型号"
#: assets/models/asset.py:100 assets/templates/assets/asset_detail.html:109 #: assets/models/asset.py:100 assets/templates/assets/asset_detail.html:113
msgid "Serial number" msgid "Serial number"
msgstr "序列号" msgstr "序列号"
...@@ -338,7 +343,7 @@ msgstr "CPU核数" ...@@ -338,7 +343,7 @@ msgstr "CPU核数"
msgid "CPU vcpus" msgid "CPU vcpus"
msgstr "CPU总数" msgstr "CPU总数"
#: assets/models/asset.py:108 assets/templates/assets/asset_detail.html:89 #: assets/models/asset.py:108 assets/templates/assets/asset_detail.html:93
msgid "Memory" msgid "Memory"
msgstr "内存" msgstr "内存"
...@@ -350,7 +355,7 @@ msgstr "硬盘大小" ...@@ -350,7 +355,7 @@ msgstr "硬盘大小"
msgid "Disk info" msgid "Disk info"
msgstr "硬盘信息" msgstr "硬盘信息"
#: assets/models/asset.py:115 assets/templates/assets/asset_detail.html:101 #: assets/models/asset.py:115 assets/templates/assets/asset_detail.html:105
#: assets/templates/assets/user_asset_list.html:166 #: assets/templates/assets/user_asset_list.html:166
msgid "OS" msgid "OS"
msgstr "操作系统" msgstr "操作系统"
...@@ -368,7 +373,7 @@ msgid "Hostname raw" ...@@ -368,7 +373,7 @@ msgid "Hostname raw"
msgstr "主机名原始" msgstr "主机名原始"
#: assets/models/asset.py:125 assets/templates/assets/asset_create.html:34 #: assets/models/asset.py:125 assets/templates/assets/asset_create.html:34
#: assets/templates/assets/asset_detail.html:220 #: assets/templates/assets/asset_detail.html:224
#: assets/templates/assets/asset_update.html:39 templates/_nav.html:26 #: assets/templates/assets/asset_update.html:39 templates/_nav.html:26
msgid "Labels" msgid "Labels"
msgstr "标签管理" msgstr "标签管理"
...@@ -377,7 +382,7 @@ msgstr "标签管理" ...@@ -377,7 +382,7 @@ msgstr "标签管理"
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:24 #: assets/models/cluster.py:28 assets/models/cmd_filter.py:24
#: assets/models/cmd_filter.py:54 assets/models/group.py:21 #: assets/models/cmd_filter.py:54 assets/models/group.py:21
#: assets/templates/assets/admin_user_detail.html:68 #: assets/templates/assets/admin_user_detail.html:68
#: assets/templates/assets/asset_detail.html:117 #: assets/templates/assets/asset_detail.html:121
#: assets/templates/assets/cmd_filter_detail.html:77 #: assets/templates/assets/cmd_filter_detail.html:77
#: assets/templates/assets/domain_detail.html:72 #: assets/templates/assets/domain_detail.html:72
#: assets/templates/assets/system_user_detail.html:100 #: assets/templates/assets/system_user_detail.html:100
...@@ -412,7 +417,7 @@ msgstr "创建日期" ...@@ -412,7 +417,7 @@ msgstr "创建日期"
#: assets/models/domain.py:51 assets/models/group.py:23 #: assets/models/domain.py:51 assets/models/group.py:23
#: assets/models/label.py:22 assets/templates/assets/admin_user_detail.html:72 #: assets/models/label.py:22 assets/templates/assets/admin_user_detail.html:72
#: assets/templates/assets/admin_user_list.html:32 #: assets/templates/assets/admin_user_list.html:32
#: assets/templates/assets/asset_detail.html:125 #: assets/templates/assets/asset_detail.html:129
#: assets/templates/assets/cmd_filter_detail.html:65 #: assets/templates/assets/cmd_filter_detail.html:65
#: assets/templates/assets/cmd_filter_list.html:27 #: assets/templates/assets/cmd_filter_list.html:27
#: assets/templates/assets/cmd_filter_rule_list.html:62 #: assets/templates/assets/cmd_filter_rule_list.html:62
...@@ -533,8 +538,10 @@ msgstr "过滤器" ...@@ -533,8 +538,10 @@ msgstr "过滤器"
#: assets/models/cmd_filter.py:46 #: assets/models/cmd_filter.py:46
#: assets/templates/assets/cmd_filter_rule_list.html:58 #: assets/templates/assets/cmd_filter_rule_list.html:58
#: audits/templates/audits/login_log_list.html:50 #: audits/templates/audits/login_log_list.html:50
#: common/templates/common/terminal_setting.html:73 #: common/templates/common/command_storage_create.html:31
#: common/templates/common/terminal_setting.html:91 #: common/templates/common/replay_storage_create.html:31
#: common/templates/common/terminal_setting.html:81
#: common/templates/common/terminal_setting.html:103
msgid "Type" msgid "Type"
msgstr "类型" msgstr "类型"
...@@ -568,6 +575,8 @@ msgstr "每行一个命令" ...@@ -568,6 +575,8 @@ msgstr "每行一个命令"
#: assets/templates/assets/system_user_list.html:38 audits/models.py:37 #: assets/templates/assets/system_user_list.html:38 audits/models.py:37
#: audits/templates/audits/operate_log_list.html:41 #: audits/templates/audits/operate_log_list.html:41
#: audits/templates/audits/operate_log_list.html:67 #: audits/templates/audits/operate_log_list.html:67
#: common/templates/common/terminal_setting.html:82
#: common/templates/common/terminal_setting.html:104
#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:64 #: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:64
#: ops/templates/ops/task_history.html:65 ops/templates/ops/task_list.html:42 #: ops/templates/ops/task_history.html:65 ops/templates/ops/task_list.html:42
#: perms/templates/perms/asset_permission_list.html:60 #: perms/templates/perms/asset_permission_list.html:60
...@@ -843,10 +852,12 @@ msgstr "其它" ...@@ -843,10 +852,12 @@ msgstr "其它"
#: assets/templates/assets/gateway_create_update.html:58 #: assets/templates/assets/gateway_create_update.html:58
#: assets/templates/assets/label_create_update.html:18 #: assets/templates/assets/label_create_update.html:18
#: common/templates/common/basic_setting.html:61 #: common/templates/common/basic_setting.html:61
#: common/templates/common/command_storage_create.html:80
#: common/templates/common/email_setting.html:62 #: common/templates/common/email_setting.html:62
#: common/templates/common/ldap_setting.html:62 #: common/templates/common/ldap_setting.html:62
#: common/templates/common/replay_storage_create.html:139
#: common/templates/common/security_setting.html:70 #: common/templates/common/security_setting.html:70
#: common/templates/common/terminal_setting.html:106 #: common/templates/common/terminal_setting.html:68
#: perms/templates/perms/asset_permission_create_update.html:69 #: perms/templates/perms/asset_permission_create_update.html:69
#: terminal/templates/terminal/terminal_update.html:47 #: terminal/templates/terminal/terminal_update.html:47
#: users/templates/users/_user.html:46 #: users/templates/users/_user.html:46
...@@ -874,10 +885,12 @@ msgstr "重置" ...@@ -874,10 +885,12 @@ msgstr "重置"
#: assets/templates/assets/gateway_create_update.html:59 #: assets/templates/assets/gateway_create_update.html:59
#: assets/templates/assets/label_create_update.html:19 #: assets/templates/assets/label_create_update.html:19
#: common/templates/common/basic_setting.html:62 #: common/templates/common/basic_setting.html:62
#: common/templates/common/command_storage_create.html:81
#: common/templates/common/email_setting.html:63 #: common/templates/common/email_setting.html:63
#: common/templates/common/ldap_setting.html:63 #: common/templates/common/ldap_setting.html:63
#: common/templates/common/replay_storage_create.html:140
#: common/templates/common/security_setting.html:71 #: common/templates/common/security_setting.html:71
#: common/templates/common/terminal_setting.html:108 #: common/templates/common/terminal_setting.html:70
#: perms/templates/perms/asset_permission_create_update.html:70 #: perms/templates/perms/asset_permission_create_update.html:70
#: terminal/templates/terminal/command_list.html:103 #: terminal/templates/terminal/command_list.html:103
#: terminal/templates/terminal/session_list.html:127 #: terminal/templates/terminal/session_list.html:127
...@@ -945,12 +958,12 @@ msgid "Quick update" ...@@ -945,12 +958,12 @@ msgid "Quick update"
msgstr "快速更新" msgstr "快速更新"
#: assets/templates/assets/admin_user_assets.html:72 #: assets/templates/assets/admin_user_assets.html:72
#: assets/templates/assets/asset_detail.html:168 #: assets/templates/assets/asset_detail.html:172
msgid "Test connective" msgid "Test connective"
msgstr "测试可连接性" msgstr "测试可连接性"
#: assets/templates/assets/admin_user_assets.html:75 #: assets/templates/assets/admin_user_assets.html:75
#: assets/templates/assets/asset_detail.html:171 #: assets/templates/assets/asset_detail.html:175
#: assets/templates/assets/system_user_asset.html:75 #: assets/templates/assets/system_user_asset.html:75
#: assets/templates/assets/system_user_asset.html:161 #: assets/templates/assets/system_user_asset.html:161
#: assets/templates/assets/system_user_detail.html:151 #: assets/templates/assets/system_user_detail.html:151
...@@ -1003,6 +1016,8 @@ msgstr "更新" ...@@ -1003,6 +1016,8 @@ msgstr "更新"
#: assets/templates/assets/label_list.html:39 #: assets/templates/assets/label_list.html:39
#: assets/templates/assets/system_user_detail.html:30 #: assets/templates/assets/system_user_detail.html:30
#: assets/templates/assets/system_user_list.html:93 audits/models.py:33 #: assets/templates/assets/system_user_list.html:93 audits/models.py:33
#: common/templates/common/terminal_setting.html:90
#: common/templates/common/terminal_setting.html:112
#: ops/templates/ops/task_list.html:72 #: ops/templates/ops/task_list.html:72
#: perms/templates/perms/asset_permission_detail.html:34 #: perms/templates/perms/asset_permission_detail.html:34
#: perms/templates/perms/asset_permission_list.html:201 #: perms/templates/perms/asset_permission_list.html:201
...@@ -1031,12 +1046,13 @@ msgid "Select nodes" ...@@ -1031,12 +1046,13 @@ msgid "Select nodes"
msgstr "选择节点" msgstr "选择节点"
#: assets/templates/assets/admin_user_detail.html:100 #: assets/templates/assets/admin_user_detail.html:100
#: assets/templates/assets/asset_detail.html:200 #: assets/templates/assets/asset_detail.html:204
#: assets/templates/assets/asset_list.html:633 #: assets/templates/assets/asset_list.html:633
#: assets/templates/assets/cmd_filter_detail.html:106 #: assets/templates/assets/cmd_filter_detail.html:106
#: assets/templates/assets/system_user_asset.html:112 #: assets/templates/assets/system_user_asset.html:112
#: assets/templates/assets/system_user_detail.html:182 #: assets/templates/assets/system_user_detail.html:182
#: assets/templates/assets/system_user_list.html:143 templates/_modal.html:22 #: assets/templates/assets/system_user_list.html:143
#: common/templates/common/terminal_setting.html:165 templates/_modal.html:22
#: terminal/templates/terminal/session_detail.html:108 #: terminal/templates/terminal/session_detail.html:108
#: users/templates/users/user_detail.html:382 #: users/templates/users/user_detail.html:382
#: users/templates/users/user_detail.html:408 #: users/templates/users/user_detail.html:408
...@@ -1096,28 +1112,28 @@ msgstr "选择需要修改属性" ...@@ -1096,28 +1112,28 @@ msgstr "选择需要修改属性"
msgid "Select all" msgid "Select all"
msgstr "全选" msgstr "全选"
#: assets/templates/assets/asset_detail.html:85 #: assets/templates/assets/asset_detail.html:89
msgid "CPU" msgid "CPU"
msgstr "CPU" msgstr "CPU"
#: assets/templates/assets/asset_detail.html:93 #: assets/templates/assets/asset_detail.html:97
msgid "Disk" msgid "Disk"
msgstr "硬盘" msgstr "硬盘"
#: assets/templates/assets/asset_detail.html:121 #: assets/templates/assets/asset_detail.html:125
#: users/templates/users/user_detail.html:115 #: users/templates/users/user_detail.html:115
#: users/templates/users/user_profile.html:104 #: users/templates/users/user_profile.html:104
msgid "Date joined" msgid "Date joined"
msgstr "创建日期" msgstr "创建日期"
#: assets/templates/assets/asset_detail.html:137 #: assets/templates/assets/asset_detail.html:141
#: terminal/templates/terminal/session_detail.html:81 #: terminal/templates/terminal/session_detail.html:81
#: users/templates/users/user_detail.html:134 #: users/templates/users/user_detail.html:134
#: users/templates/users/user_profile.html:142 #: users/templates/users/user_profile.html:142
msgid "Quick modify" msgid "Quick modify"
msgstr "快速修改" msgstr "快速修改"
#: assets/templates/assets/asset_detail.html:143 #: assets/templates/assets/asset_detail.html:147
#: assets/templates/assets/asset_list.html:95 #: assets/templates/assets/asset_list.html:95
#: assets/templates/assets/user_asset_list.html:47 perms/models.py:34 #: assets/templates/assets/user_asset_list.html:47 perms/models.py:34
#: perms/models.py:82 #: perms/models.py:82
...@@ -1134,15 +1150,15 @@ msgstr "快速修改" ...@@ -1134,15 +1150,15 @@ msgstr "快速修改"
msgid "Active" msgid "Active"
msgstr "激活中" msgstr "激活中"
#: assets/templates/assets/asset_detail.html:160 #: assets/templates/assets/asset_detail.html:164
msgid "Refresh hardware" msgid "Refresh hardware"
msgstr "更新硬件信息" msgstr "更新硬件信息"
#: assets/templates/assets/asset_detail.html:163 #: assets/templates/assets/asset_detail.html:167
msgid "Refresh" msgid "Refresh"
msgstr "刷新" msgstr "刷新"
#: assets/templates/assets/asset_detail.html:300 #: assets/templates/assets/asset_detail.html:304
#: users/templates/users/user_detail.html:301 #: users/templates/users/user_detail.html:301
#: users/templates/users/user_detail.html:328 #: users/templates/users/user_detail.html:328
msgid "Update successfully!" msgid "Update successfully!"
...@@ -1271,6 +1287,7 @@ msgstr "删除选择资产" ...@@ -1271,6 +1287,7 @@ msgstr "删除选择资产"
#: assets/templates/assets/asset_list.html:631 #: assets/templates/assets/asset_list.html:631
#: assets/templates/assets/system_user_list.html:141 #: assets/templates/assets/system_user_list.html:141
#: common/templates/common/terminal_setting.html:163
#: users/templates/users/user_detail.html:380 #: users/templates/users/user_detail.html:380
#: users/templates/users/user_detail.html:406 #: users/templates/users/user_detail.html:406
#: users/templates/users/user_detail.html:474 #: users/templates/users/user_detail.html:474
...@@ -1737,7 +1754,7 @@ msgstr "改密日志" ...@@ -1737,7 +1754,7 @@ msgstr "改密日志"
#: audits/views.py:183 templates/_nav.html:10 users/views/group.py:28 #: audits/views.py:183 templates/_nav.html:10 users/views/group.py:28
#: users/views/group.py:44 users/views/group.py:60 users/views/group.py:76 #: users/views/group.py:44 users/views/group.py:60 users/views/group.py:76
#: users/views/group.py:92 users/views/login.py:327 users/views/user.py:68 #: users/views/group.py:92 users/views/login.py:328 users/views/user.py:68
#: users/views/user.py:83 users/views/user.py:111 users/views/user.py:193 #: users/views/user.py:83 users/views/user.py:111 users/views/user.py:193
#: users/views/user.py:354 users/views/user.py:404 users/views/user.py:439 #: users/views/user.py:354 users/views/user.py:404 users/views/user.py:439
msgid "Users" msgid "Users"
...@@ -1747,22 +1764,35 @@ msgstr "用户管理" ...@@ -1747,22 +1764,35 @@ msgstr "用户管理"
msgid "Login log" msgid "Login log"
msgstr "登录日志" msgstr "登录日志"
#: common/api.py:18 #: common/api.py:22
msgid "Test mail sent to {}, please check" msgid "Test mail sent to {}, please check"
msgstr "邮件已经发送{}, 请检查" msgstr "邮件已经发送{}, 请检查"
#: common/api.py:42 #: common/api.py:46
msgid "Test ldap success" msgid "Test ldap success"
msgstr "连接LDAP成功" msgstr "连接LDAP成功"
#: common/api.py:72 #: common/api.py:76
msgid "Search no entry matched in ou {}" msgid "Search no entry matched in ou {}"
msgstr "在ou:{}中没有匹配条目" msgstr "在ou:{}中没有匹配条目"
#: common/api.py:81 #: common/api.py:85
msgid "Match {} s users" msgid "Match {} s users"
msgstr "匹配 {} 个用户" msgstr "匹配 {} 个用户"
#: common/api.py:107 common/api.py:138
msgid "Error: Account invalid"
msgstr ""
#: common/api.py:110 common/api.py:141
msgid "Create succeed"
msgstr "创建成功"
#: common/api.py:127 common/api.py:161
#: common/templates/common/terminal_setting.html:151
msgid "Delete succeed"
msgstr "删除成功"
#: common/const.py:6 #: common/const.py:6
#, python-format #, python-format
msgid "<b>%(name)s</b> was created successfully" msgid "<b>%(name)s</b> was created successfully"
...@@ -1879,120 +1909,98 @@ msgid "Enable LDAP auth" ...@@ -1879,120 +1909,98 @@ msgid "Enable LDAP auth"
msgstr "启用LDAP认证" msgstr "启用LDAP认证"
#: common/forms.py:139 #: common/forms.py:139
msgid "List sort by" msgid "Password auth"
msgstr "资产列表排序" msgstr "密码认证"
#: common/forms.py:142 #: common/forms.py:142
msgid "Public key auth"
msgstr "密钥认证"
#: common/forms.py:145
msgid "Heartbeat interval" msgid "Heartbeat interval"
msgstr "心跳间隔" msgstr "心跳间隔"
#: common/forms.py:142 ops/models/adhoc.py:38 #: common/forms.py:145 ops/models/adhoc.py:38
msgid "Units: seconds" msgid "Units: seconds"
msgstr "单位: 秒" msgstr "单位: 秒"
#: common/forms.py:145
msgid "Password auth"
msgstr "密码认证"
#: common/forms.py:148 #: common/forms.py:148
msgid "Public key auth" msgid "List sort by"
msgstr "密钥认证" msgstr "资产列表排序"
#: common/forms.py:151 common/templates/common/terminal_setting.html:68
#: terminal/forms.py:30 terminal/models.py:22
msgid "Command storage"
msgstr "命令存储"
#: common/forms.py:152
msgid ""
"Set terminal storage setting, `default` is the using as default,You can set "
"other storage and some terminal using"
msgstr "设置终端命令存储,default是默认用的存储方式"
#: common/forms.py:157 common/templates/common/terminal_setting.html:86
#: terminal/forms.py:35 terminal/models.py:23
msgid "Replay storage"
msgstr "录像存储"
#: common/forms.py:158
msgid ""
"Set replay storage setting, `default` is the using as default,You can set "
"other storage and some terminal using"
msgstr "设置终端录像存储,default是默认用的存储方式"
#: common/forms.py:168 #: common/forms.py:160
msgid "MFA Secondary certification" msgid "MFA Secondary certification"
msgstr "MFA 二次认证" msgstr "MFA 二次认证"
#: common/forms.py:170 #: common/forms.py:162
msgid "" msgid ""
"After opening, the user login must use MFA secondary authentication (valid " "After opening, the user login must use MFA secondary authentication (valid "
"for all users, including administrators)" "for all users, including administrators)"
msgstr "开启后,用户登录必须使用MFA二次认证(对所有用户有效,包括管理员)" msgstr "开启后,用户登录必须使用MFA二次认证(对所有用户有效,包括管理员)"
#: common/forms.py:177 #: common/forms.py:169
msgid "Limit the number of login failures" msgid "Limit the number of login failures"
msgstr "限制登录失败次数" msgstr "限制登录失败次数"
#: common/forms.py:182 #: common/forms.py:174
msgid "No logon interval" msgid "No logon interval"
msgstr "禁止登录时间间隔" msgstr "禁止登录时间间隔"
#: common/forms.py:184 #: common/forms.py:176
msgid "" msgid ""
"Tip :(unit/minute) if the user has failed to log in for a limited number of " "Tip :(unit/minute) if the user has failed to log in for a limited number of "
"times, no login is allowed during this time interval." "times, no login is allowed during this time interval."
msgstr "" msgstr ""
"提示: (单位: 分钟) 当用户登录失败次数达到限制后,那么在此时间间隔内禁止登录." "提示: (单位: 分钟) 当用户登录失败次数达到限制后,那么在此时间间隔内禁止登录."
#: common/forms.py:190 #: common/forms.py:182
msgid "Connection max idle time" msgid "Connection max idle time"
msgstr "SSH最大空闲时间" msgstr "SSH最大空闲时间"
#: common/forms.py:192 #: common/forms.py:184
msgid "" msgid ""
"If idle time more than it, disconnect connection(only ssh now) Unit: minute" "If idle time more than it, disconnect connection(only ssh now) Unit: minute"
msgstr "提示: (单位: 分钟) 如果超过该配置没有操作,连接会被断开(仅ssh) " msgstr "提示: (单位: 分钟) 如果超过该配置没有操作,连接会被断开(仅ssh) "
#: common/forms.py:198 #: common/forms.py:190
msgid "Password minimum length" msgid "Password minimum length"
msgstr "密码最小长度 " msgstr "密码最小长度 "
#: common/forms.py:204 #: common/forms.py:196
msgid "Must contain capital letters" msgid "Must contain capital letters"
msgstr "必须包含大写字母" msgstr "必须包含大写字母"
#: common/forms.py:206 #: common/forms.py:198
msgid "" msgid ""
"After opening, the user password changes and resets must contain uppercase " "After opening, the user password changes and resets must contain uppercase "
"letters" "letters"
msgstr "开启后,用户密码修改、重置必须包含大写字母" msgstr "开启后,用户密码修改、重置必须包含大写字母"
#: common/forms.py:212 #: common/forms.py:204
msgid "Must contain lowercase letters" msgid "Must contain lowercase letters"
msgstr "必须包含小写字母" msgstr "必须包含小写字母"
#: common/forms.py:213 #: common/forms.py:205
msgid "" msgid ""
"After opening, the user password changes and resets must contain lowercase " "After opening, the user password changes and resets must contain lowercase "
"letters" "letters"
msgstr "开启后,用户密码修改、重置必须包含小写字母" msgstr "开启后,用户密码修改、重置必须包含小写字母"
#: common/forms.py:219 #: common/forms.py:211
msgid "Must contain numeric characters" msgid "Must contain numeric characters"
msgstr "必须包含数字字符" msgstr "必须包含数字字符"
#: common/forms.py:220 #: common/forms.py:212
msgid "" msgid ""
"After opening, the user password changes and resets must contain numeric " "After opening, the user password changes and resets must contain numeric "
"characters" "characters"
msgstr "开启后,用户密码修改、重置必须包含数字字符" msgstr "开启后,用户密码修改、重置必须包含数字字符"
#: common/forms.py:226 #: common/forms.py:218
msgid "Must contain special characters" msgid "Must contain special characters"
msgstr "必须包含特殊字符" msgstr "必须包含特殊字符"
#: common/forms.py:227 #: common/forms.py:219
msgid "" msgid ""
"After opening, the user password changes and resets must contain special " "After opening, the user password changes and resets must contain special "
"characters" "characters"
...@@ -2016,7 +2024,7 @@ msgstr "启用" ...@@ -2016,7 +2024,7 @@ msgstr "启用"
#: common/templates/common/ldap_setting.html:15 #: common/templates/common/ldap_setting.html:15
#: common/templates/common/security_setting.html:15 #: common/templates/common/security_setting.html:15
#: common/templates/common/terminal_setting.html:16 #: common/templates/common/terminal_setting.html:16
#: common/templates/common/terminal_setting.html:46 common/views.py:20 #: common/templates/common/terminal_setting.html:46 common/views.py:22
msgid "Basic setting" msgid "Basic setting"
msgstr "基本设置" msgstr "基本设置"
...@@ -2024,7 +2032,7 @@ msgstr "基本设置" ...@@ -2024,7 +2032,7 @@ msgstr "基本设置"
#: common/templates/common/email_setting.html:18 #: common/templates/common/email_setting.html:18
#: common/templates/common/ldap_setting.html:18 #: common/templates/common/ldap_setting.html:18
#: common/templates/common/security_setting.html:18 #: common/templates/common/security_setting.html:18
#: common/templates/common/terminal_setting.html:20 common/views.py:46 #: common/templates/common/terminal_setting.html:20 common/views.py:48
msgid "Email setting" msgid "Email setting"
msgstr "邮件设置" msgstr "邮件设置"
...@@ -2032,7 +2040,7 @@ msgstr "邮件设置" ...@@ -2032,7 +2040,7 @@ msgstr "邮件设置"
#: common/templates/common/email_setting.html:21 #: common/templates/common/email_setting.html:21
#: common/templates/common/ldap_setting.html:21 #: common/templates/common/ldap_setting.html:21
#: common/templates/common/security_setting.html:21 #: common/templates/common/security_setting.html:21
#: common/templates/common/terminal_setting.html:24 common/views.py:72 #: common/templates/common/terminal_setting.html:24 common/views.py:74
msgid "LDAP setting" msgid "LDAP setting"
msgstr "LDAP设置" msgstr "LDAP设置"
...@@ -2040,7 +2048,7 @@ msgstr "LDAP设置" ...@@ -2040,7 +2048,7 @@ msgstr "LDAP设置"
#: common/templates/common/email_setting.html:24 #: common/templates/common/email_setting.html:24
#: common/templates/common/ldap_setting.html:24 #: common/templates/common/ldap_setting.html:24
#: common/templates/common/security_setting.html:24 #: common/templates/common/security_setting.html:24
#: common/templates/common/terminal_setting.html:28 common/views.py:102 #: common/templates/common/terminal_setting.html:28 common/views.py:105
msgid "Terminal setting" msgid "Terminal setting"
msgstr "终端设置" msgstr "终端设置"
...@@ -2048,10 +2056,72 @@ msgstr "终端设置" ...@@ -2048,10 +2056,72 @@ msgstr "终端设置"
#: common/templates/common/email_setting.html:27 #: common/templates/common/email_setting.html:27
#: common/templates/common/ldap_setting.html:27 #: common/templates/common/ldap_setting.html:27
#: common/templates/common/security_setting.html:27 #: common/templates/common/security_setting.html:27
#: common/templates/common/terminal_setting.html:31 common/views.py:130 #: common/templates/common/terminal_setting.html:31 common/views.py:157
msgid "Security setting" msgid "Security setting"
msgstr "安全设置" msgstr "安全设置"
#: common/templates/common/command_storage_create.html:50
#: ops/models/adhoc.py:159 ops/templates/ops/adhoc_detail.html:53
#: ops/templates/ops/task_adhoc.html:59 ops/templates/ops/task_list.html:38
msgid "Hosts"
msgstr "主机"
#: common/templates/common/command_storage_create.html:53
msgid "Tips: If there are multiple hosts, separate them with a comma (,)"
msgstr "提示: 如果有多台主机,请使用逗号 ( , ) 进行分割"
#: common/templates/common/command_storage_create.html:64
msgid "Index"
msgstr "索引"
#: common/templates/common/command_storage_create.html:71
msgid "Doc type"
msgstr "文档类型"
#: common/templates/common/replay_storage_create.html:53
#: templates/index.html:91
msgid "Host"
msgstr "主机"
#: common/templates/common/replay_storage_create.html:67
msgid "Bucket"
msgstr "桶名称"
#: common/templates/common/replay_storage_create.html:74
msgid "Access key"
msgstr ""
#: common/templates/common/replay_storage_create.html:81
msgid "Secret key"
msgstr ""
#: common/templates/common/replay_storage_create.html:88
msgid "Container name"
msgstr "容器名称"
#: common/templates/common/replay_storage_create.html:95
msgid "Account name"
msgstr "账户名称"
#: common/templates/common/replay_storage_create.html:102
msgid "Account key"
msgstr "账户密钥"
#: common/templates/common/replay_storage_create.html:109
msgid "Endpoint"
msgstr "端点"
#: common/templates/common/replay_storage_create.html:116
msgid "Endpoint suffix"
msgstr "端点后缀"
#: common/templates/common/replay_storage_create.html:130
#: xpack/plugins/cloud/models.py:206
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:83
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:64
msgid "Region"
msgstr "地域"
#: common/templates/common/security_setting.html:42 #: common/templates/common/security_setting.html:42
msgid "User login settings" msgid "User login settings"
msgstr "用户登录设置" msgstr "用户登录设置"
...@@ -2060,20 +2130,59 @@ msgstr "用户登录设置" ...@@ -2060,20 +2130,59 @@ msgstr "用户登录设置"
msgid "Password check rule" msgid "Password check rule"
msgstr "密码校验规则" msgstr "密码校验规则"
#: common/templates/common/terminal_setting.html:76 terminal/forms.py:27
#: terminal/models.py:22
msgid "Command storage"
msgstr "命令存储"
#: common/templates/common/terminal_setting.html:95
#: common/templates/common/terminal_setting.html:117
#: perms/templates/perms/asset_permission_asset.html:97
#: perms/templates/perms/asset_permission_detail.html:157
#: perms/templates/perms/asset_permission_user.html:97
#: perms/templates/perms/asset_permission_user.html:125
#: users/templates/users/user_group_detail.html:95
#: xpack/plugins/orgs/templates/orgs/org_detail.html:93
#: xpack/plugins/orgs/templates/orgs/org_detail.html:130
msgid "Add"
msgstr "添加"
#: common/templates/common/terminal_setting.html:98 terminal/forms.py:32
#: terminal/models.py:23
msgid "Replay storage"
msgstr "录像存储"
#: common/templates/common/terminal_setting.html:154
msgid "Delete failed"
msgstr "删除失败"
#: common/templates/common/terminal_setting.html:159
msgid "Are you sure about deleting it?"
msgstr "您确定删除吗?"
#: common/validators.py:7 #: common/validators.py:7
msgid "Special char not allowed" msgid "Special char not allowed"
msgstr "不能包含特殊字符" msgstr "不能包含特殊字符"
#: common/views.py:19 common/views.py:45 common/views.py:71 common/views.py:101 #: common/views.py:21 common/views.py:47 common/views.py:73 common/views.py:104
#: common/views.py:129 templates/_nav.html:116 #: common/views.py:131 common/views.py:143 common/views.py:156
#: templates/_nav.html:116
msgid "Settings" msgid "Settings"
msgstr "系统设置" msgstr "系统设置"
#: common/views.py:30 common/views.py:56 common/views.py:84 common/views.py:114 #: common/views.py:32 common/views.py:58 common/views.py:86 common/views.py:117
#: common/views.py:140 #: common/views.py:167
msgid "Update setting successfully, please restart program" msgid "Update setting successfully, please restart program"
msgstr "更新设置成功, 请手动重启程序" msgstr "更新设置成功, 请手动重启程序"
#: common/views.py:132
msgid "Create replay storage"
msgstr "创建录像存储"
#: common/views.py:144
msgid "Create command storage"
msgstr "创建命令存储"
#: jumpserver/views.py:180 #: jumpserver/views.py:180
msgid "" msgid ""
"<div>Luna is a separately deployed program, you need to deploy Luna, coco, " "<div>Luna is a separately deployed program, you need to deploy Luna, coco, "
...@@ -2117,11 +2226,6 @@ msgstr "模式" ...@@ -2117,11 +2226,6 @@ msgstr "模式"
msgid "Options" msgid "Options"
msgstr "选项" msgstr "选项"
#: ops/models/adhoc.py:159 ops/templates/ops/adhoc_detail.html:53
#: ops/templates/ops/task_adhoc.html:59 ops/templates/ops/task_list.html:38
msgid "Hosts"
msgstr "主机"
#: ops/models/adhoc.py:160 #: ops/models/adhoc.py:160
msgid "Run as admin" msgid "Run as admin"
msgstr "再次执行" msgstr "再次执行"
...@@ -2380,16 +2484,6 @@ msgstr "资产或资产组" ...@@ -2380,16 +2484,6 @@ msgstr "资产或资产组"
msgid "Add asset to this permission" msgid "Add asset to this permission"
msgstr "添加资产" msgstr "添加资产"
#: perms/templates/perms/asset_permission_asset.html:97
#: perms/templates/perms/asset_permission_detail.html:157
#: perms/templates/perms/asset_permission_user.html:97
#: perms/templates/perms/asset_permission_user.html:125
#: users/templates/users/user_group_detail.html:95
#: xpack/plugins/orgs/templates/orgs/org_detail.html:93
#: xpack/plugins/orgs/templates/orgs/org_detail.html:130
msgid "Add"
msgstr "添加"
#: perms/templates/perms/asset_permission_asset.html:108 #: perms/templates/perms/asset_permission_asset.html:108
msgid "Add node to this permission" msgid "Add node to this permission"
msgstr "添加节点" msgstr "添加节点"
...@@ -2665,10 +2759,6 @@ msgid "" ...@@ -2665,10 +2759,6 @@ msgid ""
"assets per user host per month, respectively." "assets per user host per month, respectively."
msgstr "以下图形分别描述一个月活跃用户和资产占所有用户主机的百分比" msgstr "以下图形分别描述一个月活跃用户和资产占所有用户主机的百分比"
#: templates/index.html:91
msgid "Host"
msgstr "主机"
#: templates/index.html:106 templates/index.html:121 #: templates/index.html:106 templates/index.html:121
msgid "Top 10 assets in a week" msgid "Top 10 assets in a week"
msgstr "一周Top10资产" msgstr "一周Top10资产"
...@@ -2787,12 +2877,12 @@ msgstr "输入" ...@@ -2787,12 +2877,12 @@ msgstr "输入"
msgid "Session" msgid "Session"
msgstr "会话" msgstr "会话"
#: terminal/forms.py:31 #: terminal/forms.py:28
msgid "Command can store in server db or ES, default to server, more see docs" msgid "Command can store in server db or ES, default to server, more see docs"
msgstr "" msgstr ""
"命令支持存储到服务器端数据库、ES中,默认存储的服务器端数据库,更多查看文档" "命令支持存储到服务器端数据库、ES中,默认存储的服务器端数据库,更多查看文档"
#: terminal/forms.py:36 #: terminal/forms.py:33
msgid "" msgid ""
"Replay file can store in server disk, AWS S3, Aliyun OSS, default to server, " "Replay file can store in server disk, AWS S3, Aliyun OSS, default to server, "
"more see docs" "more see docs"
...@@ -3925,56 +4015,56 @@ msgstr "更新用户组" ...@@ -3925,56 +4015,56 @@ msgstr "更新用户组"
msgid "User group granted asset" msgid "User group granted asset"
msgstr "用户组授权资产" msgstr "用户组授权资产"
#: users/views/login.py:69 #: users/views/login.py:70
msgid "Please enable cookies and try again." msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie" msgstr "设置你的浏览器支持cookie"
#: users/views/login.py:175 users/views/user.py:526 users/views/user.py:551 #: users/views/login.py:176 users/views/user.py:526 users/views/user.py:551
msgid "MFA code invalid, or ntp sync server time" msgid "MFA code invalid, or ntp sync server time"
msgstr "MFA验证码不正确,或者服务器端时间不对" msgstr "MFA验证码不正确,或者服务器端时间不对"
#: users/views/login.py:204 #: users/views/login.py:205
msgid "Logout success" msgid "Logout success"
msgstr "退出登录成功" msgstr "退出登录成功"
#: users/views/login.py:205 #: users/views/login.py:206
msgid "Logout success, return login page" msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面" msgstr "退出登录成功,返回到登录页面"
#: users/views/login.py:221 #: users/views/login.py:222
msgid "Email address invalid, please input again" msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入" msgstr "邮箱地址错误,重新输入"
#: users/views/login.py:234 #: users/views/login.py:235
msgid "Send reset password message" msgid "Send reset password message"
msgstr "发送重置密码邮件" msgstr "发送重置密码邮件"
#: users/views/login.py:235 #: users/views/login.py:236
msgid "Send reset password mail success, login your mail box and follow it " msgid "Send reset password mail success, login your mail box and follow it "
msgstr "" msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)" "发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views/login.py:248 #: users/views/login.py:249
msgid "Reset password success" msgid "Reset password success"
msgstr "重置密码成功" msgstr "重置密码成功"
#: users/views/login.py:249 #: users/views/login.py:250
msgid "Reset password success, return to login page" msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面" msgstr "重置密码成功,返回到登录页面"
#: users/views/login.py:270 users/views/login.py:283 #: users/views/login.py:271 users/views/login.py:284
msgid "Token invalid or expired" msgid "Token invalid or expired"
msgstr "Token错误或失效" msgstr "Token错误或失效"
#: users/views/login.py:279 #: users/views/login.py:280
msgid "Password not same" msgid "Password not same"
msgstr "密码不一致" msgstr "密码不一致"
#: users/views/login.py:289 users/views/user.py:127 users/views/user.py:422 #: users/views/login.py:290 users/views/user.py:127 users/views/user.py:422
msgid "* Your password does not meet the requirements" msgid "* Your password does not meet the requirements"
msgstr "* 您的密码不符合要求" msgstr "* 您的密码不符合要求"
#: users/views/login.py:327 #: users/views/login.py:328
msgid "First login" msgid "First login"
msgstr "首次登陆" msgstr "首次登陆"
...@@ -4160,12 +4250,6 @@ msgstr "同步实例任务历史" ...@@ -4160,12 +4250,6 @@ msgstr "同步实例任务历史"
msgid "Instance" msgid "Instance"
msgstr "实例" msgstr "实例"
#: xpack/plugins/cloud/models.py:206
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:83
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:64
msgid "Region"
msgstr "地域"
#: xpack/plugins/cloud/providers/base.py:73 #: xpack/plugins/cloud/providers/base.py:73
msgid "任务执行开始: {}" msgid "任务执行开始: {}"
msgstr "" msgstr ""
...@@ -4339,6 +4423,21 @@ msgstr "创建组织" ...@@ -4339,6 +4423,21 @@ msgstr "创建组织"
msgid "Update org" msgid "Update org"
msgstr "更新组织" msgstr "更新组织"
#, fuzzy
#~| msgid "Delete succeed"
#~ msgid "Delete success"
#~ msgstr "删除成功"
#~ msgid ""
#~ "Set terminal storage setting, `default` is the using as default,You can "
#~ "set other storage and some terminal using"
#~ msgstr "设置终端命令存储,default是默认用的存储方式"
#~ msgid ""
#~ "Set replay storage setting, `default` is the using as default,You can set "
#~ "other storage and some terminal using"
#~ msgstr "设置终端录像存储,default是默认用的存储方式"
#~ msgid "Sync instance task detail" #~ msgid "Sync instance task detail"
#~ msgstr "同步实例任务详情" #~ msgstr "同步实例任务详情"
......
...@@ -152,6 +152,9 @@ function activeNav() { ...@@ -152,6 +152,9 @@ function activeNav() {
$('#' + app + ' #' + resource).addClass('active'); $('#' + app + ' #' + resource).addClass('active');
$('#' + app + ' #' + resource + ' #' + item + ' a').css('color', '#ffffff'); $('#' + app + ' #' + resource + ' #' + item + ' a').css('color', '#ffffff');
} }
else if (app === 'settings'){
$("#" + app).addClass('active');
}
else { else {
$("#" + app).addClass('active'); $("#" + app).addClass('active');
$('#' + app + ' #' + resource).addClass('active'); $('#' + app + ' #' + resource).addClass('active');
......
...@@ -2,6 +2,9 @@ from importlib import import_module ...@@ -2,6 +2,9 @@ from importlib import import_module
from django.conf import settings from django.conf import settings
from .command.serializers import SessionCommandSerializer from .command.serializers import SessionCommandSerializer
from common import utils
from common.models import common_settings, Setting
TYPE_ENGINE_MAPPING = { TYPE_ENGINE_MAPPING = {
'elasticsearch': 'terminal.backends.command.es', 'elasticsearch': 'terminal.backends.command.es',
} }
...@@ -16,7 +19,9 @@ def get_command_storage(): ...@@ -16,7 +19,9 @@ def get_command_storage():
def get_terminal_command_storages(): def get_terminal_command_storages():
storage_list = {} 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'] tp = params['TYPE']
if tp == 'server': if tp == 'server':
storage = get_command_storage() storage = get_command_storage()
......
...@@ -2,36 +2,33 @@ ...@@ -2,36 +2,33 @@
# #
from django import forms from django import forms
from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from .models import Terminal from .models import Terminal
def get_all_command_storage(): def get_all_command_storage():
# storage_choices = [] from common import utils
from common.models import Setting command_storage = utils.get_command_storage_or_create_default_storage()
Setting.refresh_all_settings() for k, v in command_storage.items():
for k, v in settings.TERMINAL_COMMAND_STORAGE.items():
yield (k, k) yield (k, k)
def get_all_replay_storage(): def get_all_replay_storage():
# storage_choices = [] from common import utils
from common.models import Setting replay_storage = utils.get_replay_storage_or_create_default_storage()
Setting.refresh_all_settings() for k, v in replay_storage.items():
for k, v in settings.TERMINAL_REPLAY_STORAGE.items():
yield (k, k) yield (k, k)
class TerminalForm(forms.ModelForm): class TerminalForm(forms.ModelForm):
command_storage = forms.ChoiceField( command_storage = forms.ChoiceField(
choices=get_all_command_storage(), choices=get_all_command_storage,
label=_("Command storage"), label=_("Command storage"),
help_text=_("Command can store in server db or ES, default to server, more see docs"), help_text=_("Command can store in server db or ES, default to server, more see docs"),
) )
replay_storage = forms.ChoiceField( replay_storage = forms.ChoiceField(
choices=get_all_replay_storage(), choices=get_all_replay_storage,
label=_("Replay storage"), label=_("Replay storage"),
help_text=_("Replay file can store in server disk, AWS S3, Aliyun OSS, default to server, more see docs"), help_text=_("Replay file can store in server disk, AWS S3, Aliyun OSS, default to server, more see docs"),
) )
......
...@@ -21,6 +21,7 @@ from formtools.wizard.views import SessionWizardView ...@@ -21,6 +21,7 @@ from formtools.wizard.views import SessionWizardView
from django.conf import settings from django.conf import settings
from common.utils import get_object_or_none, get_request_ip from common.utils import get_object_or_none, get_request_ip
from common.models import common_settings
from ..models import User, LoginLog from ..models import User, LoginLog
from ..utils import send_reset_password_mail, check_otp_code, \ from ..utils import send_reset_password_mail, check_otp_code, \
redirect_user_first_login_or_index, get_user_or_tmp_user, \ redirect_user_first_login_or_index, get_user_or_tmp_user, \
...@@ -318,7 +319,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView): ...@@ -318,7 +319,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
user.is_public_key_valid = True user.is_public_key_valid = True
user.save() user.save()
context = { context = {
'user_guide_url': settings.USER_GUIDE_URL 'user_guide_url': common_settings.USER_GUIDE_URL
} }
return render(self.request, 'users/first_login_done.html', context) return render(self.request, 'users/first_login_done.html', context)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment