Commit 21c71aba authored by BaiJiangJie's avatar BaiJiangJie

[Update] Merge branch dev_cloud_manager (baijiangjie_local) to dev

parents f8db9f48 7bafa546
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
__version__ = "1.4.1" __version__ = "1.4.3"
...@@ -4,3 +4,4 @@ from .label import * ...@@ -4,3 +4,4 @@ from .label import *
from .system_user import * from .system_user import *
from .node import * from .node import *
from .domain import * from .domain import *
from .cmd_filter import *
# -*- coding: utf-8 -*-
#
from rest_framework_bulk import BulkModelViewSet
from django.shortcuts import get_object_or_404
from ..hands import IsOrgAdmin
from ..models import CommandFilter, CommandFilterRule
from .. import serializers
__all__ = ['CommandFilterViewSet', 'CommandFilterRuleViewSet']
class CommandFilterViewSet(BulkModelViewSet):
permission_classes = (IsOrgAdmin,)
queryset = CommandFilter.objects.all()
serializer_class = serializers.CommandFilterSerializer
class CommandFilterRuleViewSet(BulkModelViewSet):
permission_classes = (IsOrgAdmin,)
serializer_class = serializers.CommandFilterRuleSerializer
def get_queryset(self):
fpk = self.kwargs.get('filter_pk')
if not fpk:
return CommandFilterRule.objects.none()
group = get_object_or_404(CommandFilter, pk=fpk)
return group.rules.all().order_by('priority')
...@@ -33,7 +33,8 @@ __all__ = [ ...@@ -33,7 +33,8 @@ __all__ = [
'SystemUserViewSet', 'SystemUserAuthInfoApi', 'SystemUserViewSet', 'SystemUserAuthInfoApi',
'SystemUserPushApi', 'SystemUserTestConnectiveApi', 'SystemUserPushApi', 'SystemUserTestConnectiveApi',
'SystemUserAssetsListView', 'SystemUserPushToAssetApi', 'SystemUserAssetsListView', 'SystemUserPushToAssetApi',
'SystemUserTestAssetConnectabilityApi', 'SystemUserTestAssetConnectabilityApi', 'SystemUserCommandFilterRuleListApi',
] ]
...@@ -126,4 +127,17 @@ class SystemUserTestAssetConnectabilityApi(generics.RetrieveAPIView): ...@@ -126,4 +127,17 @@ class SystemUserTestAssetConnectabilityApi(generics.RetrieveAPIView):
asset_id = self.kwargs.get('aid') asset_id = self.kwargs.get('aid')
asset = get_object_or_404(Asset, id=asset_id) asset = get_object_or_404(Asset, id=asset_id)
task = test_system_user_connectability_a_asset.delay(system_user, asset) task = test_system_user_connectability_a_asset.delay(system_user, asset)
return Response({"task": task.id}) return Response({"task": task.id})
\ No newline at end of file
class SystemUserCommandFilterRuleListApi(generics.ListAPIView):
permission_classes = (IsOrgAdminOrAppUser,)
def get_serializer_class(self):
from ..serializers import CommandFilterRuleSerializer
return CommandFilterRuleSerializer
def get_queryset(self):
pk = self.kwargs.get('pk', None)
system_user = get_object_or_404(SystemUser, pk=pk)
return system_user.cmd_filter_rules
...@@ -4,3 +4,4 @@ from .asset import * ...@@ -4,3 +4,4 @@ from .asset import *
from .label import * from .label import *
from .user import * from .user import *
from .domain import * from .domain import *
from .cmd_filter import *
...@@ -48,7 +48,7 @@ class AssetCreateForm(OrgModelForm): ...@@ -48,7 +48,7 @@ class AssetCreateForm(OrgModelForm):
'root or other NOPASSWD sudo privilege user existed in asset,' 'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu' 'If asset is windows or other set any one, more see admin user left menu'
), ),
# 'platform': _("* required Must set exact system platform, Windows, Linux ..."), 'platform': _("Windows 2016 RDP protocol is different, If is window 2016, set it"),
'domain': _("If your have some network not connect with each other, you can set domain") 'domain': _("If your have some network not connect with each other, you can set domain")
} }
...@@ -88,7 +88,7 @@ class AssetUpdateForm(OrgModelForm): ...@@ -88,7 +88,7 @@ class AssetUpdateForm(OrgModelForm):
'root or other NOPASSWD sudo privilege user existed in asset,' 'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu' 'If asset is windows or other set any one, more see admin user left menu'
), ),
# 'platform': _("* required Must set exact system platform, Windows, Linux ..."), 'platform': _("Windows 2016 RDP protocol is different, If is window 2016, set it"),
'domain': _("If your have some network not connect with each other, you can set domain") 'domain': _("If your have some network not connect with each other, you can set domain")
} }
......
# -*- coding: utf-8 -*-
#
from django import forms
from orgs.mixins import OrgModelForm
from ..models import CommandFilter, CommandFilterRule
__all__ = ['CommandFilterForm', 'CommandFilterRuleForm']
class CommandFilterForm(OrgModelForm):
class Meta:
model = CommandFilter
fields = ['name', 'comment']
class CommandFilterRuleForm(OrgModelForm):
class Meta:
model = CommandFilterRule
fields = [
'filter', 'type', 'content', 'priority', 'action', 'comment'
]
widgets = {
'content': forms.Textarea(attrs={
'placeholder': 'eg:\r\nreboot\r\nrm -rf'
}),
}
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from ..models import AdminUser, SystemUser
from common.utils import validate_ssh_private_key, ssh_pubkey_gen, get_logger from common.utils import validate_ssh_private_key, ssh_pubkey_gen, get_logger
from orgs.mixins import OrgModelForm
from ..models import AdminUser, SystemUser
logger = get_logger(__file__) logger = get_logger(__file__)
__all__ = [ __all__ = [
...@@ -85,7 +86,7 @@ class AdminUserForm(PasswordAndKeyAuthForm): ...@@ -85,7 +86,7 @@ class AdminUserForm(PasswordAndKeyAuthForm):
} }
class SystemUserForm(PasswordAndKeyAuthForm): class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm):
# Admin user assets define, let user select, save it in form not in view # Admin user assets define, let user select, save it in form not in view
auto_generate_key = forms.BooleanField(initial=True, required=False) auto_generate_key = forms.BooleanField(initial=True, required=False)
...@@ -136,11 +137,14 @@ class SystemUserForm(PasswordAndKeyAuthForm): ...@@ -136,11 +137,14 @@ class SystemUserForm(PasswordAndKeyAuthForm):
fields = [ fields = [
'name', 'username', 'protocol', 'auto_generate_key', 'name', 'username', 'protocol', 'auto_generate_key',
'password', 'private_key_file', 'auto_push', 'sudo', 'password', 'private_key_file', 'auto_push', 'sudo',
'comment', 'shell', 'priority', 'login_mode', 'comment', 'shell', 'priority', 'login_mode', 'cmd_filters',
] ]
widgets = { widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}), 'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'username': forms.TextInput(attrs={'placeholder': _('Username')}), 'username': forms.TextInput(attrs={'placeholder': _('Username')}),
'cmd_filters': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Command filter')
}),
} }
help_texts = { help_texts = {
'name': '* required', 'name': '* required',
......
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from .user import AdminUser, SystemUser from .user import *
from .label import Label from .label import Label
from .cluster import * from .cluster import *
from .group import * from .group import *
from .domain import * from .domain import *
from .node import * from .node import *
from .asset import * from .asset import *
from .cmd_filter import *
from .utils import * from .utils import *
...@@ -15,7 +15,7 @@ from django.core.cache import cache ...@@ -15,7 +15,7 @@ from django.core.cache import cache
from ..const import ASSET_ADMIN_CONN_CACHE_KEY from ..const import ASSET_ADMIN_CONN_CACHE_KEY
from .user import AdminUser, SystemUser from .user import AdminUser, SystemUser
from orgs.mixins import OrgModelMixin,OrgManager from orgs.mixins import OrgModelMixin, OrgManager
__all__ = ['Asset'] __all__ = ['Asset']
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
......
# -*- coding: utf-8 -*-
#
import uuid
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.utils.translation import ugettext_lazy as _
from orgs.mixins import OrgModelMixin
__all__ = [
'CommandFilter', 'CommandFilterRule'
]
class CommandFilter(OrgModelMixin):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=64, verbose_name=_("Name"))
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
comment = models.TextField(blank=True, default='', verbose_name=_("Comment"))
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
created_by = models.CharField(max_length=128, blank=True, default='', verbose_name=_('Created by'))
def __str__(self):
return self.name
class CommandFilterRule(OrgModelMixin):
TYPE_REGEX = 'regex'
TYPE_COMMAND = 'command'
TYPE_CHOICES = (
(TYPE_REGEX, _('Regex')),
(TYPE_COMMAND, _('Command')),
)
ACTION_DENY, ACTION_ALLOW = range(2)
ACTION_CHOICES = (
(ACTION_DENY, _('Deny')),
(ACTION_ALLOW, _('Allow')),
)
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
filter = models.ForeignKey('CommandFilter', on_delete=models.CASCADE, verbose_name=_("Filter"), related_name='rules')
type = models.CharField(max_length=16, default=TYPE_COMMAND, choices=TYPE_CHOICES, verbose_name=_("Type"))
priority = models.IntegerField(default=50, verbose_name=_("Priority"), help_text=_("1-100, the lower will be match first"),
validators=[MinValueValidator(1), MaxValueValidator(100)])
content = models.TextField(max_length=1024, verbose_name=_("Content"), help_text=_("One line one command"))
action = models.IntegerField(default=ACTION_DENY, choices=ACTION_CHOICES, verbose_name=_("Action"))
comment = models.CharField(max_length=64, blank=True, default='', verbose_name=_("Comment"))
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
created_by = models.CharField(max_length=128, blank=True, default='', verbose_name=_('Created by'))
class Meta:
ordering = ('priority', 'action')
def __str__(self):
return '{} % {}'.format(self.type, self.content)
...@@ -40,12 +40,10 @@ class Node(OrgModelMixin): ...@@ -40,12 +40,10 @@ class Node(OrgModelMixin):
return True return True
self_key = [int(k) for k in self.key.split(':')] self_key = [int(k) for k in self.key.split(':')]
other_key = [int(k) for k in other.key.split(':')] other_key = [int(k) for k in other.key.split(':')]
if len(self_key) < len(other_key): return self_key.__lt__(other_key)
return True
elif len(self_key) > len(other_key): def __lt__(self, other):
return False return not self.__gt__(other)
else:
return self_key[-1] < other_key[-1]
@property @property
def name(self): def name(self):
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
# #
import logging import logging
import uuid
from django.core.cache import cache from django.core.cache import cache
from django.db import models from django.db import models
...@@ -118,6 +117,7 @@ class SystemUser(AssetUser): ...@@ -118,6 +117,7 @@ class SystemUser(AssetUser):
sudo = models.TextField(default='/bin/whoami', verbose_name=_('Sudo')) sudo = models.TextField(default='/bin/whoami', verbose_name=_('Sudo'))
shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell')) shell = models.CharField(max_length=64, default='/bin/bash', verbose_name=_('Shell'))
login_mode = models.CharField(choices=LOGIN_MODE_CHOICES, default=AUTO_LOGIN, max_length=10, verbose_name=_('Login mode')) login_mode = models.CharField(choices=LOGIN_MODE_CHOICES, default=AUTO_LOGIN, max_length=10, verbose_name=_('Login mode'))
cmd_filters = models.ManyToManyField('CommandFilter', related_name='system_users', verbose_name=_("Command filter"), blank=True)
cache_key = "__SYSTEM_USER_CACHED_{}" cache_key = "__SYSTEM_USER_CACHED_{}"
...@@ -163,6 +163,14 @@ class SystemUser(AssetUser): ...@@ -163,6 +163,14 @@ class SystemUser(AssetUser):
def expire_cache(self): def expire_cache(self):
cache.delete(self.cache_key.format(self.id)) cache.delete(self.cache_key.format(self.id))
@property
def cmd_filter_rules(self):
from .cmd_filter import CommandFilterRule
rules = CommandFilterRule.objects.filter(
filter__in=self.cmd_filters.all()
).order_by('priority').distinct()
return rules
@classmethod @classmethod
def get_system_user_by_id_or_cached(cls, sid): def get_system_user_by_id_or_cached(cls, sid):
cached = cache.get(cls.cache_key.format(sid)) cached = cache.get(cls.cache_key.format(sid))
......
...@@ -7,3 +7,4 @@ from .label import * ...@@ -7,3 +7,4 @@ from .label import *
from .system_user import * from .system_user import *
from .node import * from .node import *
from .domain import * from .domain import *
from .cmd_filter import *
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from common.fields import ChoiceDisplayField
from ..models import CommandFilter, CommandFilterRule, SystemUser
class CommandFilterSerializer(serializers.ModelSerializer):
rules = serializers.PrimaryKeyRelatedField(queryset=CommandFilterRule.objects.all(), many=True)
system_users = serializers.PrimaryKeyRelatedField(queryset=SystemUser.objects.all(), many=True)
class Meta:
model = CommandFilter
fields = '__all__'
class CommandFilterRuleSerializer(serializers.ModelSerializer):
serializer_choice_field = ChoiceDisplayField
class Meta:
model = CommandFilterRule
fields = '__all__'
...@@ -62,6 +62,10 @@ ...@@ -62,6 +62,10 @@
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
<div id="command-filter-block">
<h3>{% trans 'Command filter' %}</h3>
{% bootstrap_field form.cmd_filters layout="horizontal" %}
</div>
<h3>{% trans 'Other' %}</h3> <h3>{% trans 'Other' %}</h3>
{% bootstrap_field form.sudo layout="horizontal" %} {% bootstrap_field form.sudo layout="horizontal" %}
{% bootstrap_field form.shell layout="horizontal" %} {% bootstrap_field form.shell layout="horizontal" %}
...@@ -101,6 +105,7 @@ var need_change_field_login_mode = [ ...@@ -101,6 +105,7 @@ var need_change_field_login_mode = [
function protocolChange() { function protocolChange() {
if ($(protocol_id + " option:selected").text() === 'rdp') { if ($(protocol_id + " option:selected").text() === 'rdp') {
$('.auth-fields').removeClass('hidden'); $('.auth-fields').removeClass('hidden');
$('#command-filter-block').addClass('hidden');
$.each(need_change_field, function (index, value) { $.each(need_change_field, function (index, value) {
$(value).closest('.form-group').addClass('hidden') $(value).closest('.form-group').addClass('hidden')
}); });
......
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
<td colspan="2" class="no-borders"> <td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Select nodes' %}" id="nodes_selected" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select nodes' %}" id="nodes_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for node in nodes %} {% for node in nodes %}
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node.value }}</option> <option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
......
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% block form %}
<form id="groupForm" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
<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>
{% endblock %}
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href='{% static "css/plugins/select2/select2.min.css" %}' rel="stylesheet">
<script src='{% static "js/plugins/select2/select2.full.min.js" %}'></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active">
<a href="{% url 'assets:cmd-filter-detail' pk=object.id %}" class="text-center">
<i class="fa fa-laptop"></i> {% trans 'Detail' %}
</a>
</li>
<li>
<li>
<a href="{% url 'assets:cmd-filter-rule-list' pk=object.id %}" class="text-center">
<i class="fa fa-laptop"></i> {% trans 'Rules' %}
</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'assets:cmd-filter-update' pk=object.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
</li>
<li class="pull-right">
<a class="btn btn-outline btn-danger btn-del">
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-8" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label"><b>{{ object.name }}</b></span>
<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>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td>{% trans 'Name' %}:</td>
<td><b>{{ object.name }}</b></td>
</tr>
<tr>
<td>{% trans 'Comment' %}:</td>
<td><b>{{ object.comment }}</b></td>
</tr>
<tr>
<td>{% trans 'Date created' %}:</td>
<td><b>{{ object.date_created }}</b></td>
</tr>
<tr>
<td>{% trans 'Date updated' %}:</td>
<td><b>{{ object.date_updated }}</b></td>
</tr>
<tr>
<td>{% trans 'Created by' %}:</td>
<td><b>{{ object.created_by }}</b></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-4" style="padding-left: 0; padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'System users' %}
</div>
<div class="panel-body">
<table class="table group_edit" id="table-clusters">
<tbody>
<form>
<tr>
<td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Binding to system user' %}" id="system_users_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for system_user in system_users_remain %}
<option value="{{ system_user.id }}" id="opt_{{ system_user.id }}">{{ system_user }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td colspan="2" class="no-borders">
<button type="button" class="btn btn-primary btn-sm" id="btn-binding-system-users">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
{% for system_user in object.system_users.all %}
<tr>
<td><b class="bdg-system-users" data-gid={{ system_user.id }}>{{ system_user }}</b></td>
<td>
<button class="btn btn-danger pull-right btn-xs btn-unbound-system-user" data-gid={{ system_user.id }} type="button"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
function updateCMDFilterSystemUsers(system_users) {
var the_url = "{% url 'api-assets:cmd-filter-detail' pk=object.id %}";
var body = {
system_users: Object.assign([], system_users)
};
var success = function(data) {
location.reload();
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH',
success: success
});
}
$(document).ready(function () {
$(".select2").select2();
}).on('click', '#btn-binding-system-users', function () {
var origin_system_users = $.map($(".bdg-system-users"), function (s) {
return $(s).data('gid')
});
var new_selected_system_users_id = $.map($("#system_users_selected").select2('data'), function (s) {
return s.id;
});
var system_users = origin_system_users.concat(new_selected_system_users_id);
updateCMDFilterSystemUsers(system_users)
}).on('click', '.btn-unbound-system-user', function () {
var unbound_system_user = $(this).data('gid');
var origin_system_users = $.map($(".bdg-system-users"), function (s) {
return $(s).data('gid')
});
var system_users = $.grep(origin_system_users, function (n, i) {
return n !== unbound_system_user
});
updateCMDFilterSystemUsers(system_users)
})
</script>
{% endblock %}
{% extends '_base_list.html' %}
{% load i18n static %}
{% block table_search %}{% endblock %}
{% block help_message %}
<div class="alert alert-info help-message">
{% trans 'System user bound some command filter, each command filter has some rules,'%}
{% trans 'When user login asset with this system user, then run a command,' %}
{% trans 'The command will be filter by rules, higher priority(lower number) rule run first,' %}
{% trans 'When a rule matched, if rule action is allow, then allow command execute,' %}
{% trans 'else if action is deny, then command with be deny,' %}
{% trans 'else match next rule, if none matched, allowed' %}
</div>
{% endblock %}
{% block table_container %}
<div class="uc pull-left m-r-5">
<a href="{% url 'assets:cmd-filter-create' %}" class="btn btn-sm btn-primary"> {% trans "Create command filter" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="cmd_filter_list_table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th class="text-center">{% trans 'Name' %}</th>
<th class="text-center">{% trans 'Rules' %}</th>
<th class="text-center">{% trans 'System users' %}</th>
<th class="text-center">{% trans 'Comment' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
function initTable() {
var options = {
ele: $('#cmd_filter_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url 'assets:cmd-filter-detail' pk=DEFAULT_PK %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
{targets: 2, createdCell: function (td, cellData, rowData) {
var filters_list_btn = '<a href="{% url "assets:cmd-filter-rule-list" pk=DEFAULT_PK %}">' + cellData.length + '</a>';
filters_list_btn = filters_list_btn.replace("{{ DEFAULT_PK }}", rowData.id);
$(td).html(filters_list_btn);
}},
{targets: 3, createdCell: function (td, cellData, rowData) {
var system_users_list_btn = '<a href="{% url "assets:cmd-filter-detail" pk=DEFAULT_PK %}">' + cellData.length + '</a>';
system_users_list_btn = system_users_list_btn.replace("{{ DEFAULT_PK }}", rowData.id);
$(td).html(system_users_list_btn);
}},
{targets: 5, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:cmd-filter-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:cmd-filter-list" %}',
columns: [
{data: "id"}, {data: "name" }, {data: "rules" },
{data: "system_users" }, {data: "comment"}, {data: "id"}
],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
}
$(document).ready(function(){
initTable();
})
.on('click', '.btn-delete', function () {
var $this = $(this);
var $data_table = $('#cmd_filter_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:cmd-filter-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
});
</script>
{% endblock %}
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{% endblock %}
{% 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 enctype="multipart/form-data" method="post" class="form-horizontal" action="" >
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">
{{ form.non_field_errors }}
</div>
{% endif %}
{% bootstrap_form form layout="horizontal" %}
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
var content_origin_placeholder = '';
var content_origin_help_text = '';
var content_ref = '';
var content_help_ref = '';
$(document).ready(function(){
content_ref = $('#id_content');
content_help_ref = content_ref.next();
content_origin_placeholder = content_ref.attr('placeholder');
content_origin_help_text = content_help_ref.html();
}).on('change', '#id_type', function () {
if ($('#id_type :selected').val() === 'regex') {
content_ref.attr('placeholder', 'rm.*|reboot|shutdown');
content_help_ref.html("");
} else {
content_ref.attr('placeholder', content_origin_placeholder);
content_help_ref.html(content_origin_help_text);
}
})
</script>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href='{% static "css/plugins/select2/select2.min.css" %}' rel="stylesheet">
<script src='{% static "js/plugins/select2/select2.full.min.js" %}'></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li>
<a href="{% url 'assets:cmd-filter-detail' pk=object.id %}" class="text-center">
<i class="fa fa-laptop"></i> {% trans 'Detail' %}
</a>
</li>
<li class="active">
<a href="{% url 'assets:cmd-filter-rule-list' pk=object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Rules' %} </a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-12" style="padding-left: 0;">
<div class="" id="content_start">
</div>
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left"><b>{% trans 'Command filter rule list' %}</b></span>
<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>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="uc pull-left m-r-5">
<a href="{% url 'assets:cmd-filter-rule-create' filter_pk=object.id %}" class="btn btn-sm btn-primary"> {% trans "Create rule" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="cmd_filter_rule_list_table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th class="text-center">{% trans 'Type' %}</th>
<th class="text-center">{% trans 'Content' %}</th>
<th class="text-center">{% trans 'Priority' %}</th>
<th class="text-center">{% trans 'Strategy' %}</th>
<th class="text-center">{% trans 'Comment' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
function initTable() {
var options = {
ele: $('#cmd_filter_rule_list_table'),
columnDefs: [
{targets: 6, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:cmd-filter-rule-update" filter_pk=object.id pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:cmd-filter-rule-list" filter_pk=object.id %}',
columns: [
{data: "id"}, {data: "type.display" }, {data: 'content'}, {data: 'priority'},
{data: 'action.display'}, {data: "comment" }, {data: "id"}
],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
}
$(document).ready(function(){
initTable();
})
.on('click', '.btn-delete', function () {
var $this = $(this);
var $data_table = $('#cmd_filter_rule_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:cmd-filter-rule-detail" filter_pk=object.id pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
setTimeout( function () {
$data_table.ajax.reload();
}, 3000);
})
</script>
{% endblock %}
{% extends 'base.html' %} {% extends 'base.html' %}
{% load common_tags %}
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
...@@ -113,7 +114,7 @@ ...@@ -113,7 +114,7 @@
</tr> </tr>
</form> </form>
{% for node in system_user.nodes.all %} {% for node in system_user.nodes.all|sort %}
<tr> <tr>
<td ><b class="bdg_node" data-gid={{ node.id }}>{{ node }}</b></td> <td ><b class="bdg_node" data-gid={{ node.id }}>{{ node }}</b></td>
<td> <td>
......
...@@ -156,44 +156,47 @@ ...@@ -156,44 +156,47 @@
</table> </table>
</div> </div>
</div> </div>
{# <div class="panel panel-info">#}
{# <div class="panel-heading">#}
{# <i class="fa fa-info-circle"></i> {% trans 'Nodes' %}#}
{# </div>#}
{# <div class="panel-body">#}
{# <table class="table node_edit" id="add-asset2group">#}
{# <tbody>#}
{# <form>#}
{# <tr>#}
{# <td colspan="2" class="no-borders">#}
{# <select data-placeholder="{% trans 'Add to node' %}" id="node_selected" class="select2" style="width: 100%" multiple="" tabindex="4">#}
{# {% for node in nodes_remain %}#}
{# <option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node }}</option>#}
{# {% endfor %}#}
{# </select>#}
{# </td>#}
{# </tr>#}
{# <tr>#}
{# <td colspan="2" class="no-borders">#}
{# <button type="button" class="btn btn-info btn-sm" id="btn-add-to-node">{% trans 'Confirm' %}</button>#}
{# </td>#}
{# </tr>#}
{# </form>#}
{##}
{# {% for node in system_user.nodes.all %}#}
{# <tr>#}
{# <td ><b class="bdg_node" data-gid={{ node.id }}>{{ node }}</b></td>#}
{# <td>#}
{# <button class="btn btn-danger pull-right btn-xs btn-remove-from-node" type="button"><i class="fa fa-minus"></i></button>#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
{# </tbody>#}
{# </table>#}
{# </div>#}
{# </div>#}
</div> </div>
</div> </div>
{% if system_user.protocol != 'rdp' %}
<div class="col-sm-4" style="padding-left: 0; padding-right: 0">
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Command filter' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<form>
<tr>
<td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Binding command filters' %}" id="command_filters_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for cf in cmd_filters_remain %}
<option value="{{ cf.id }}" id="opt_{{ cf.id }}" >{{ cf }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-sm" id="btn-binding-command-filters">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
{% for cf in object.cmd_filters.all %}
<tr>
<td><b class="bdg-command-filters" data-gid={{ cf.id }}>{{ cf }}</b></td>
<td>
<button class="btn btn-danger pull-right btn-xs btn-unbound-command-filter" data-gid={{ cf.id }} type="button"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
...@@ -201,27 +204,13 @@ ...@@ -201,27 +204,13 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
function updateSystemUserNode(nodes) { function updateCommandFilters(command_filters) {
var the_url = "{% url 'api-assets:system-user-detail' pk=system_user.id %}"; var the_url = "{% url 'api-assets:system-user-detail' pk=system_user.id %}";
var body = { var body = {
nodes: Object.assign([], nodes) cmd_filters: Object.assign([], command_filters)
}; };
var success = function(data) { var success = function(data) {
// remove all the selected groups from select > option and rendered ul element; location.reload();
$('.select2-selection__rendered').empty();
$('#node_selected').val('');
$.map(jumpserver.nodes_selected, function(node_name, index) {
$('#opt_' + index).remove();
// change tr html of user groups.
$('.node_edit tbody').append(
'<tr>' +
'<td><b class="bdg_node" data-gid="' + index + '">' + node_name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn-remove-from-node" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
// clear jumpserver.groups_selected
jumpserver.nodes_selected = {};
}; };
APIUpdateAttr({ APIUpdateAttr({
url: the_url, url: the_url,
...@@ -229,21 +218,12 @@ function updateSystemUserNode(nodes) { ...@@ -229,21 +218,12 @@ function updateSystemUserNode(nodes) {
success: success success: success
}); });
} }
jumpserver.nodes_selected = {};
$(document).ready(function () { $(document).ready(function () {
if($('#id_protocol_type').text() === 'rdp'){ if($('#id_protocol_type').text() === 'rdp'){
$('.only-ssh').addClass('hidden') $('.only-ssh').addClass('hidden')
} }
$(".panel-body .table tr:visible:first").addClass('no-borders-tr'); $(".panel-body .table tr:visible:first").addClass('no-borders-tr');
$('.select2').select2() $('.select2').select2()
.on('select2:select', function(evt) {
var data = evt.params.data;
jumpserver.nodes_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.nodes_selected[data.id];
});
}) })
.on('click', '#btn-auto-push', function () { .on('click', '#btn-auto-push', function () {
var checked = $(this).prop('checked'); var checked = $(this).prop('checked');
...@@ -255,33 +235,6 @@ $(document).ready(function () { ...@@ -255,33 +235,6 @@ $(document).ready(function () {
url: the_url, url: the_url,
body: JSON.stringify(body) body: JSON.stringify(body)
}); });
})
.on('click', '#btn-add-to-node', function() {
if (Object.keys(jumpserver.nodes_selected).length === 0) {
return false;
}
var nodes = $('.bdg_node').map(function() {
return $(this).data('gid');
}).get();
$.map(jumpserver.nodes_selected, function(value, index) {
nodes.push(index);
});
updateSystemUserNode(nodes);
})
.on('click', '.btn-remove-from-node', function() {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_node');
var gid = $badge.data('gid');
var node_name = $badge.html() || $badge.text();
$('#groups_selected').append(
'<option value="' + gid + '" id="opt_' + gid + '">' + node_name + '</option>'
);
$tr.remove();
var nodes = $('.bdg_node').map(function () {
return $(this).data('gid');
}).get();
updateSystemUserNode(nodes);
}).on('click', '.btn-del', function () { }).on('click', '.btn-del', function () {
var $this = $(this); var $this = $(this);
var name = "{{ system_user.name}}"; var name = "{{ system_user.name}}";
...@@ -317,25 +270,24 @@ $(document).ready(function () { ...@@ -317,25 +270,24 @@ $(document).ready(function () {
success: success, success: success,
flash_message: false flash_message: false
}); });
}).on('click', '.btn-clear-auth', function () { }).on('click', '#btn-binding-command-filters', function () {
var the_url = '{% url "api-assets:system-user-auth-info" pk=system_user.id %}'; var new_selected_cmd_filters = $.map($('#command_filters_selected').select2('data'), function (i) {
var name = '{{ system_user.name }}'; return i.id;
swal({ });
title: "{% trans 'Are you sure to remove authentication information for the system user ?' %}", var origin_cmd_filters = $.map($(".bdg-command-filters"), function (s) {
text: " [" + name + "] ", return $(s).data('gid')
type: "warning", });
showCancelButton: true, var command_filters = new_selected_cmd_filters.concat(origin_cmd_filters);
cancelButtonText: "{% trans 'Cancel' %}", updateCommandFilters(command_filters)
confirmButtonColor: "#ed5565", }).on('click', '.btn-unbound-command-filter', function () {
confirmButtonText: "{% trans 'Confirm' %}", var unbound_command_filter = $(this).data('gid');
closeOnConfirm: true var origin_command_filters = $.map($(".bdg-command-filters"), function (s) {
}, function () { return $(s).data('gid')
APIUpdateAttr({ });
url: the_url, var command_filters = $.grep(origin_command_filters, function (n, i) {
method: 'DELETE', return n !== unbound_command_filter
success_message: "{% trans 'Clear auth' %}" + " {% trans 'success' %}"
});
}); });
updateCommandFilters(command_filters)
}) })
</script> </script>
{% endblock %} {% endblock %}
# coding:utf-8 # coding:utf-8
from django.urls import path from django.urls import path
from .. import api from rest_framework_nested import routers
# from rest_framework.routers import DefaultRouter
from rest_framework_bulk.routes import BulkRouter from rest_framework_bulk.routes import BulkRouter
from .. import api
app_name = 'assets' app_name = 'assets'
router = BulkRouter() router = BulkRouter()
...@@ -13,6 +16,11 @@ router.register(r'labels', api.LabelViewSet, 'label') ...@@ -13,6 +16,11 @@ router.register(r'labels', api.LabelViewSet, 'label')
router.register(r'nodes', api.NodeViewSet, 'node') router.register(r'nodes', api.NodeViewSet, 'node')
router.register(r'domain', api.DomainViewSet, 'domain') router.register(r'domain', api.DomainViewSet, 'domain')
router.register(r'gateway', api.GatewayViewSet, 'gateway') router.register(r'gateway', api.GatewayViewSet, 'gateway')
router.register(r'cmd-filter', api.CommandFilterViewSet, 'cmd-filter')
cmd_filter_router = routers.NestedDefaultRouter(router, r'cmd-filter', lookup='filter')
cmd_filter_router.register(r'rules', api.CommandFilterRuleViewSet, 'cmd-filter-rule')
urlpatterns = [ urlpatterns = [
path('assets-bulk/', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'), path('assets-bulk/', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'),
...@@ -42,6 +50,9 @@ urlpatterns = [ ...@@ -42,6 +50,9 @@ urlpatterns = [
path('system-user/<uuid:pk>/connective/', path('system-user/<uuid:pk>/connective/',
api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'), api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'),
path('system-user/<uuid:pk>/cmd-filter-rules/',
api.SystemUserCommandFilterRuleListApi.as_view(), name='system-user-cmd-filter-rule-list'),
path('nodes/<uuid:pk>/children/', path('nodes/<uuid:pk>/children/',
api.NodeChildrenApi.as_view(), name='node-children'), api.NodeChildrenApi.as_view(), name='node-children'),
path('nodes/children/', api.NodeChildrenApi.as_view(), name='node-children-2'), path('nodes/children/', api.NodeChildrenApi.as_view(), name='node-children-2'),
...@@ -64,5 +75,5 @@ urlpatterns = [ ...@@ -64,5 +75,5 @@ urlpatterns = [
api.GatewayTestConnectionApi.as_view(), name='test-gateway-connective'), api.GatewayTestConnectionApi.as_view(), name='test-gateway-connective'),
] ]
urlpatterns += router.urls urlpatterns += router.urls + cmd_filter_router.urls
...@@ -49,4 +49,12 @@ urlpatterns = [ ...@@ -49,4 +49,12 @@ urlpatterns = [
path('domain/<uuid:pk>/gateway/create/', views.DomainGatewayCreateView.as_view(), name='domain-gateway-create'), path('domain/<uuid:pk>/gateway/create/', views.DomainGatewayCreateView.as_view(), name='domain-gateway-create'),
path('domain/gateway/<uuid:pk>/update/', views.DomainGatewayUpdateView.as_view(), name='domain-gateway-update'), path('domain/gateway/<uuid:pk>/update/', views.DomainGatewayUpdateView.as_view(), name='domain-gateway-update'),
path('cmd-filter/', views.CommandFilterListView.as_view(), name='cmd-filter-list'),
path('cmd-filter/create/', views.CommandFilterCreateView.as_view(), name='cmd-filter-create'),
path('cmd-filter/<uuid:pk>/update/', views.CommandFilterUpdateView.as_view(), name='cmd-filter-update'),
path('cmd-filter/<uuid:pk>/', views.CommandFilterDetailView.as_view(), name='cmd-filter-detail'),
path('cmd-filter/<uuid:pk>/rule/', views.CommandFilterRuleListView.as_view(), name='cmd-filter-rule-list'),
path('cmd-filter/<uuid:filter_pk>/rule/create/', views.CommandFilterRuleCreateView.as_view(), name='cmd-filter-rule-create'),
path('cmd-filter/<uuid:filter_pk>/rule/<uuid:pk>/update/', views.CommandFilterRuleUpdateView.as_view(), name='cmd-filter-rule-update'),
] ]
...@@ -4,3 +4,4 @@ from .system_user import * ...@@ -4,3 +4,4 @@ from .system_user import *
from .admin_user import * from .admin_user import *
from .label import * from .label import *
from .domain import * from .domain import *
from .cmd_filter import *
# -*- coding: utf-8 -*-
#
from django.views.generic import TemplateView, CreateView, \
UpdateView, DeleteView, DetailView
from django.views.generic.detail import SingleObjectMixin
from django.utils.translation import ugettext_lazy as _
from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404, reverse
from common.permissions import AdminUserRequiredMixin
from common.const import create_success_msg, update_success_msg
from ..models import CommandFilter, CommandFilterRule, SystemUser
from ..forms import CommandFilterForm, CommandFilterRuleForm
__all__ = (
"CommandFilterListView", "CommandFilterCreateView",
"CommandFilterUpdateView",
"CommandFilterRuleListView", "CommandFilterRuleCreateView",
"CommandFilterRuleUpdateView", "CommandFilterDetailView",
)
class CommandFilterListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/cmd_filter_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Command filter list'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class CommandFilterCreateView(AdminUserRequiredMixin, CreateView):
model = CommandFilter
template_name = 'assets/cmd_filter_create_update.html'
form_class = CommandFilterForm
success_url = reverse_lazy('assets:cmd-filter-list')
success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create command filter'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class CommandFilterUpdateView(AdminUserRequiredMixin, UpdateView):
model = CommandFilter
template_name = 'assets/cmd_filter_create_update.html'
form_class = CommandFilterForm
success_url = reverse_lazy('assets:cmd-filter-list')
success_message = update_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Update command filter'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class CommandFilterDetailView(AdminUserRequiredMixin, DetailView):
model = CommandFilter
template_name = 'assets/cmd_filter_detail.html'
def get_context_data(self, **kwargs):
system_users_remain = SystemUser.objects\
.exclude(cmd_filters=self.object)\
.exclude(protocol='rdp')
context = {
'app': _('Assets'),
'action': _('Command filter detail'),
'system_users_remain': system_users_remain
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class CommandFilterRuleListView(AdminUserRequiredMixin, SingleObjectMixin, TemplateView):
template_name = 'assets/cmd_filter_rule_list.html'
model = CommandFilter
object = None
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=self.model.objects.all())
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Command filter rule list'),
'object': self.get_object()
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class CommandFilterRuleCreateView(AdminUserRequiredMixin, CreateView):
template_name = 'assets/cmd_filter_rule_create_update.html'
model = CommandFilterRule
form_class = CommandFilterRuleForm
success_message = create_success_msg
cmd_filter = None
def get_success_url(self):
return reverse('assets:cmd-filter-rule-list', kwargs={
'pk': self.cmd_filter.id
})
def get_form(self, form_class=None):
form = super().get_form(form_class=form_class)
form['filter'].initial = self.cmd_filter
form['filter'].field.widget.attrs['readonly'] = 1
return form
def dispatch(self, request, *args, **kwargs):
filter_pk = self.kwargs.get('filter_pk')
self.cmd_filter = get_object_or_404(CommandFilter, pk=filter_pk)
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create command filter rule'),
'object': self.cmd_filter,
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class CommandFilterRuleUpdateView(AdminUserRequiredMixin, UpdateView):
template_name = 'assets/cmd_filter_rule_create_update.html'
model = CommandFilterRule
form_class = CommandFilterRuleForm
success_message = create_success_msg
cmd_filter = None
def get_success_url(self):
return reverse('assets:cmd-filter-rule-list', kwargs={
'pk': self.cmd_filter.id
})
def get_form(self, form_class=None):
form = super().get_form(form_class=form_class)
form['filter'].initial = self.cmd_filter
form['filter'].field.widget.attrs['readonly'] = 1
return form
def dispatch(self, request, *args, **kwargs):
filter_pk = self.kwargs.get('filter_pk')
self.cmd_filter = get_object_or_404(CommandFilter, pk=filter_pk)
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Update command filter rule'),
'object': self.cmd_filter,
}
kwargs.update(context)
return super().get_context_data(**kwargs)
\ No newline at end of file
...@@ -9,7 +9,7 @@ from django.views.generic.detail import DetailView ...@@ -9,7 +9,7 @@ from django.views.generic.detail import DetailView
from common.const import create_success_msg, update_success_msg from common.const import create_success_msg, update_success_msg
from ..forms import SystemUserForm from ..forms import SystemUserForm
from ..models import SystemUser, Node from ..models import SystemUser, Node, CommandFilter
from common.permissions import AdminUserRequiredMixin from common.permissions import AdminUserRequiredMixin
...@@ -73,7 +73,7 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView): ...@@ -73,7 +73,7 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('System user detail'), 'action': _('System user detail'),
'nodes_remain': Node.objects.exclude(systemuser=self.object) 'cmd_filters_remain': CommandFilter.objects.exclude(system_users=self.object)
} }
kwargs.update(context) kwargs.update(context)
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
...@@ -91,10 +91,11 @@ class SystemUserAssetView(AdminUserRequiredMixin, DetailView): ...@@ -91,10 +91,11 @@ class SystemUserAssetView(AdminUserRequiredMixin, DetailView):
context_object_name = 'system_user' context_object_name = 'system_user'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
nodes_remain = sorted(Node.objects.exclude(systemuser=self.object), reverse=True)
context = { context = {
'app': _('assets'), 'app': _('assets'),
'action': _('System user asset'), 'action': _('System user asset'),
'nodes_remain': Node.objects.exclude(systemuser=self.object) 'nodes_remain': nodes_remain
} }
kwargs.update(context) kwargs.update(context)
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
...@@ -86,3 +86,21 @@ class FormEncryptCharField(FormEncryptMixin, forms.CharField): ...@@ -86,3 +86,21 @@ class FormEncryptCharField(FormEncryptMixin, forms.CharField):
class FormEncryptDictField(FormEncryptMixin, FormDictField): class FormEncryptDictField(FormEncryptMixin, FormDictField):
pass pass
class ChoiceDisplayField(serializers.ChoiceField):
def __init__(self, *args, **kwargs):
super(ChoiceDisplayField, self).__init__(*args, **kwargs)
self.choice_strings_to_display = {
six.text_type(key): value for key, value in self.choices.items()
}
def to_representation(self, value):
if value is None:
return value
return {
'value': self.choice_strings_to_values.get(six.text_type(value),
value),
'display': self.choice_strings_to_display.get(six.text_type(value),
value),
}
...@@ -100,3 +100,9 @@ def is_bool_field(field): ...@@ -100,3 +100,9 @@ def is_bool_field(field):
@register.filter @register.filter
def to_dict(data): def to_dict(data):
return dict(data) return dict(data)
@register.filter
def sort(data):
print(data)
return sorted(data)
...@@ -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-12 16:54+0800\n" "POT-Creation-Date: 2018-10-12 18:37+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"
...@@ -33,19 +33,19 @@ msgstr "更新节点资产硬件信息: {}" ...@@ -33,19 +33,19 @@ msgstr "更新节点资产硬件信息: {}"
msgid "Test if the assets under the node are connectable: {}" msgid "Test if the assets under the node are connectable: {}"
msgstr "测试节点下资产是否可连接: {}" msgstr "测试节点下资产是否可连接: {}"
#: assets/forms/asset.py:27 assets/models/asset.py:82 assets/models/user.py:113 #: assets/forms/asset.py:27 assets/models/asset.py:82 assets/models/user.py:112
#: assets/templates/assets/asset_detail.html:183 #: assets/templates/assets/asset_detail.html:183
#: assets/templates/assets/asset_detail.html:191 #: assets/templates/assets/asset_detail.html:191
#: assets/templates/assets/system_user_asset.html:94 perms/models.py:32 #: assets/templates/assets/system_user_asset.html:95 perms/models.py:32
msgid "Nodes" msgid "Nodes"
msgstr "节点管理" 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:87 #: assets/forms/asset.py:116 assets/models/asset.py:87
#: assets/models/cluster.py:19 assets/models/user.py:73 #: assets/models/cluster.py:19 assets/models/user.py:72
#: assets/templates/assets/asset_detail.html:73 templates/_nav.html:24 #: assets/templates/assets/asset_detail.html:73 templates/_nav.html:24
#: xpack/plugins/cloud/models.py:128 #: xpack/plugins/cloud/models.py:128
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:75 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:67
#: xpack/plugins/orgs/templates/orgs/org_list.html:18 #: xpack/plugins/orgs/templates/orgs/org_list.html:18
msgid "Admin user" msgid "Admin user"
msgstr "管理用户" msgstr "管理用户"
...@@ -76,7 +76,7 @@ msgstr "网域" ...@@ -76,7 +76,7 @@ msgstr "网域"
#: perms/templates/perms/asset_permission_list.html:57 #: perms/templates/perms/asset_permission_list.html:57
#: perms/templates/perms/asset_permission_list.html:151 #: perms/templates/perms/asset_permission_list.html:151
#: xpack/plugins/cloud/models.py:127 #: xpack/plugins/cloud/models.py:127
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:71 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:63
#: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:66 #: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:66
msgid "Node" msgid "Node"
msgstr "节点" msgstr "节点"
...@@ -89,6 +89,10 @@ msgstr "" ...@@ -89,6 +89,10 @@ msgstr ""
"root或其他拥有NOPASSWD: ALL权限的用户, 如果是windows或其它硬件可以随意设置一" "root或其他拥有NOPASSWD: ALL权限的用户, 如果是windows或其它硬件可以随意设置一"
"个, 更多信息查看左侧 `管理用户` 菜单" "个, 更多信息查看左侧 `管理用户` 菜单"
#: assets/forms/asset.py:51 assets/forms/asset.py:91
msgid "Windows 2016 RDP protocol is different, If is window 2016, set it"
msgstr "Windows 2016的RDP协议与之前不同,如果是请设置"
#: assets/forms/asset.py:52 assets/forms/asset.py:92 #: assets/forms/asset.py:52 assets/forms/asset.py:92
msgid "" msgid ""
"If your have some network not connect with each other, you can set domain" "If your have some network not connect with each other, you can set domain"
...@@ -104,7 +108,7 @@ msgstr "选择资产" ...@@ -104,7 +108,7 @@ msgstr "选择资产"
#: assets/models/domain.py:48 assets/templates/assets/admin_user_assets.html:53 #: assets/models/domain.py:48 assets/templates/assets/admin_user_assets.html:53
#: assets/templates/assets/asset_detail.html:69 #: assets/templates/assets/asset_detail.html:69
#: assets/templates/assets/domain_gateway_list.html:58 #: assets/templates/assets/domain_gateway_list.html:58
#: assets/templates/assets/system_user_asset.html:51 #: assets/templates/assets/system_user_asset.html:52
#: assets/templates/assets/user_asset_list.html:163 #: assets/templates/assets/user_asset_list.html:163
msgid "Port" msgid "Port"
msgstr "端口" msgstr "端口"
...@@ -126,7 +130,7 @@ msgstr "端口" ...@@ -126,7 +130,7 @@ msgstr "端口"
#: terminal/templates/terminal/command_list.html:73 #: terminal/templates/terminal/command_list.html:73
#: terminal/templates/terminal/session_list.html:41 #: terminal/templates/terminal/session_list.html:41
#: terminal/templates/terminal/session_list.html:72 #: terminal/templates/terminal/session_list.html:72
#: xpack/plugins/cloud/models.py:173 #: xpack/plugins/cloud/models.py:191
#: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:65 #: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:65
#: xpack/plugins/orgs/templates/orgs/org_list.html:16 #: xpack/plugins/orgs/templates/orgs/org_list.html:16
msgid "Asset" msgid "Asset"
...@@ -136,11 +140,14 @@ msgstr "资产" ...@@ -136,11 +140,14 @@ msgstr "资产"
msgid "Password should not contain special characters" msgid "Password should not contain special characters"
msgstr "不能包含特殊字符" msgstr "不能包含特殊字符"
#: assets/forms/domain.py:59 assets/forms/user.py:79 assets/forms/user.py:142 #: assets/forms/domain.py:59 assets/forms/user.py:80 assets/forms/user.py:143
#: assets/models/base.py:22 assets/models/cluster.py:18 #: assets/models/base.py:22 assets/models/cluster.py:18
#: assets/models/domain.py:18 assets/models/group.py:20 #: assets/models/cmd_filter.py:19 assets/models/domain.py:18
#: assets/models/label.py:18 assets/templates/assets/admin_user_detail.html:56 #: assets/models/group.py:20 assets/models/label.py:18
#: assets/templates/assets/admin_user_detail.html:56
#: assets/templates/assets/admin_user_list.html:26 #: assets/templates/assets/admin_user_list.html:26
#: assets/templates/assets/cmd_filter_detail.html:61
#: assets/templates/assets/cmd_filter_list.html:24
#: assets/templates/assets/domain_detail.html:56 #: assets/templates/assets/domain_detail.html:56
#: assets/templates/assets/domain_gateway_list.html:56 #: assets/templates/assets/domain_gateway_list.html:56
#: assets/templates/assets/domain_list.html:25 #: assets/templates/assets/domain_list.html:25
...@@ -174,7 +181,7 @@ msgstr "不能包含特殊字符" ...@@ -174,7 +181,7 @@ msgstr "不能包含特殊字符"
msgid "Name" msgid "Name"
msgstr "名称" msgstr "名称"
#: assets/forms/domain.py:60 assets/forms/user.py:80 assets/forms/user.py:143 #: assets/forms/domain.py:60 assets/forms/user.py:81 assets/forms/user.py:144
#: assets/models/base.py:23 assets/templates/assets/admin_user_detail.html:60 #: assets/models/base.py:23 assets/templates/assets/admin_user_detail.html:60
#: assets/templates/assets/admin_user_list.html:27 #: assets/templates/assets/admin_user_list.html:27
#: assets/templates/assets/domain_gateway_list.html:60 #: assets/templates/assets/domain_gateway_list.html:60
...@@ -191,11 +198,11 @@ msgstr "名称" ...@@ -191,11 +198,11 @@ msgstr "名称"
msgid "Username" msgid "Username"
msgstr "用户名" msgstr "用户名"
#: assets/forms/user.py:24 #: assets/forms/user.py:25
msgid "Password or private key passphrase" msgid "Password or private key passphrase"
msgstr "密码或密钥密码" msgstr "密码或密钥密码"
#: assets/forms/user.py:25 assets/models/base.py:24 common/forms.py:104 #: assets/forms/user.py:26 assets/models/base.py:24 common/forms.py:104
#: users/forms.py:17 users/forms.py:35 users/forms.py:47 #: users/forms.py:17 users/forms.py:35 users/forms.py:47
#: users/templates/users/login.html:65 #: users/templates/users/login.html:65
#: users/templates/users/reset_password.html:53 #: users/templates/users/reset_password.html:53
...@@ -207,33 +214,39 @@ msgstr "密码或密钥密码" ...@@ -207,33 +214,39 @@ msgstr "密码或密钥密码"
msgid "Password" msgid "Password"
msgstr "密码" msgstr "密码"
#: assets/forms/user.py:28 users/models/user.py:78 #: assets/forms/user.py:29 users/models/user.py:78
msgid "Private key" msgid "Private key"
msgstr "ssh私钥" msgstr "ssh私钥"
#: assets/forms/user.py:38 #: assets/forms/user.py:39
msgid "Invalid private key" msgid "Invalid private key"
msgstr "ssh密钥不合法" msgstr "ssh密钥不合法"
#: assets/forms/user.py:47 #: assets/forms/user.py:48
msgid "Password and private key file must be input one" msgid "Password and private key file must be input one"
msgstr "密码和私钥, 必须输入一个" msgstr "密码和私钥, 必须输入一个"
#: assets/forms/user.py:128 #: assets/forms/user.py:129
msgid "* Automatic login mode, must fill in the username." msgid "* Automatic login mode, must fill in the username."
msgstr "自动登录模式,必须填写用户名" msgstr "自动登录模式,必须填写用户名"
#: assets/forms/user.py:148 #: assets/forms/user.py:146 assets/models/user.py:120
#: assets/templates/assets/_system_user.html:66
#: assets/templates/assets/system_user_detail.html:165
msgid "Command filter"
msgstr "命令过滤器"
#: assets/forms/user.py:152
msgid "Auto push system user to asset" msgid "Auto push system user to asset"
msgstr "自动推送系统用户到资产" msgstr "自动推送系统用户到资产"
#: assets/forms/user.py:149 #: assets/forms/user.py:153
msgid "" msgid ""
"High level will be using login asset as default, if user was granted more " "High level will be using login asset as default, if user was granted more "
"than 2 system user" "than 2 system user"
msgstr "高优先级的系统用户将会作为默认登录用户" msgstr "高优先级的系统用户将会作为默认登录用户"
#: assets/forms/user.py:151 #: assets/forms/user.py:155
msgid "" msgid ""
"If you choose manual login mode, you do not need to fill in the username and " "If you choose manual login mode, you do not need to fill in the username and "
"password." "password."
...@@ -245,7 +258,7 @@ msgstr "如果选择手动登录模式,用户名和密码则不需要填写" ...@@ -245,7 +258,7 @@ msgstr "如果选择手动登录模式,用户名和密码则不需要填写"
#: assets/templates/assets/asset_detail.html:61 #: assets/templates/assets/asset_detail.html:61
#: assets/templates/assets/asset_list.html:93 #: assets/templates/assets/asset_list.html:93
#: assets/templates/assets/domain_gateway_list.html:57 #: assets/templates/assets/domain_gateway_list.html:57
#: assets/templates/assets/system_user_asset.html:50 #: assets/templates/assets/system_user_asset.html:51
#: assets/templates/assets/user_asset_list.html:46 #: assets/templates/assets/user_asset_list.html:46
#: assets/templates/assets/user_asset_list.html:162 #: assets/templates/assets/user_asset_list.html:162
#: audits/templates/audits/login_log_list.html:52 common/forms.py:133 #: audits/templates/audits/login_log_list.html:52 common/forms.py:133
...@@ -259,7 +272,7 @@ msgstr "IP" ...@@ -259,7 +272,7 @@ msgstr "IP"
#: assets/templates/assets/admin_user_assets.html:51 #: assets/templates/assets/admin_user_assets.html:51
#: assets/templates/assets/asset_detail.html:57 #: assets/templates/assets/asset_detail.html:57
#: assets/templates/assets/asset_list.html:92 #: assets/templates/assets/asset_list.html:92
#: assets/templates/assets/system_user_asset.html:49 #: assets/templates/assets/system_user_asset.html:50
#: assets/templates/assets/user_asset_list.html:45 #: assets/templates/assets/user_asset_list.html:45
#: assets/templates/assets/user_asset_list.html:161 common/forms.py:132 #: assets/templates/assets/user_asset_list.html:161 common/forms.py:132
#: perms/templates/perms/asset_permission_asset.html:54 #: perms/templates/perms/asset_permission_asset.html:54
...@@ -269,7 +282,7 @@ msgid "Hostname" ...@@ -269,7 +282,7 @@ msgid "Hostname"
msgstr "主机名" msgstr "主机名"
#: assets/models/asset.py:74 assets/models/domain.py:49 #: assets/models/asset.py:74 assets/models/domain.py:49
#: assets/models/user.py:116 #: assets/models/user.py:115
#: 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
...@@ -283,8 +296,9 @@ msgstr "协议" ...@@ -283,8 +296,9 @@ msgstr "协议"
msgid "Platform" msgid "Platform"
msgstr "系统平台" msgstr "系统平台"
#: assets/models/asset.py:83 assets/models/domain.py:52 #: assets/models/asset.py:83 assets/models/cmd_filter.py:20
#: assets/models/label.py:21 assets/templates/assets/asset_detail.html:105 #: assets/models/domain.py:52 assets/models/label.py:21
#: assets/templates/assets/asset_detail.html:105
#: assets/templates/assets/user_asset_list.html:169 #: assets/templates/assets/user_asset_list.html:169
msgid "Is active" msgid "Is active"
msgstr "激活" msgstr "激活"
...@@ -361,9 +375,11 @@ msgid "Labels" ...@@ -361,9 +375,11 @@ msgid "Labels"
msgstr "标签管理" msgstr "标签管理"
#: assets/models/asset.py:126 assets/models/base.py:30 #: assets/models/asset.py:126 assets/models/base.py:30
#: assets/models/cluster.py:28 assets/models/group.py:21 #: assets/models/cluster.py:28 assets/models/cmd_filter.py:24
#: 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:117
#: 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
#: ops/templates/ops/adhoc_detail.html:86 orgs/models.py:15 perms/models.py:37 #: ops/templates/ops/adhoc_detail.html:86 orgs/models.py:15 perms/models.py:37
...@@ -376,6 +392,7 @@ msgstr "创建者" ...@@ -376,6 +392,7 @@ msgstr "创建者"
#: assets/models/asset.py:129 assets/models/cluster.py:26 #: assets/models/asset.py:129 assets/models/cluster.py:26
#: assets/models/domain.py:21 assets/models/group.py:22 #: assets/models/domain.py:21 assets/models/group.py:22
#: assets/models/label.py:24 assets/templates/assets/admin_user_detail.html:64 #: assets/models/label.py:24 assets/templates/assets/admin_user_detail.html:64
#: assets/templates/assets/cmd_filter_detail.html:69
#: assets/templates/assets/domain_detail.html:68 #: assets/templates/assets/domain_detail.html:68
#: assets/templates/assets/system_user_detail.html:96 #: assets/templates/assets/system_user_detail.html:96
#: ops/templates/ops/adhoc_detail.html:90 ops/templates/ops/task_detail.html:63 #: ops/templates/ops/adhoc_detail.html:90 ops/templates/ops/task_detail.html:63
...@@ -385,18 +402,21 @@ msgstr "创建者" ...@@ -385,18 +402,21 @@ msgstr "创建者"
#: users/templates/users/user_group_detail.html:63 #: users/templates/users/user_group_detail.html:63
#: xpack/plugins/cloud/models.py:42 xpack/plugins/cloud/models.py:132 #: xpack/plugins/cloud/models.py:42 xpack/plugins/cloud/models.py:132
#: xpack/plugins/cloud/templates/cloud/account_detail.html:68 #: xpack/plugins/cloud/templates/cloud/account_detail.html:68
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:87 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:79
#: xpack/plugins/cloud/templates/cloud/sync_task_list.html:19
#: xpack/plugins/orgs/templates/orgs/org_detail.html:60 #: xpack/plugins/orgs/templates/orgs/org_detail.html:60
msgid "Date created" msgid "Date created"
msgstr "创建日期" msgstr "创建日期"
#: assets/models/asset.py:131 assets/models/base.py:27 #: assets/models/asset.py:131 assets/models/base.py:27
#: assets/models/cluster.py:29 assets/models/domain.py:19 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:21
#: assets/models/cmd_filter.py:51 assets/models/domain.py:19
#: 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:125
#: assets/templates/assets/cmd_filter_detail.html:65
#: assets/templates/assets/cmd_filter_list.html:27
#: assets/templates/assets/cmd_filter_rule_list.html:62
#: assets/templates/assets/domain_detail.html:76 #: assets/templates/assets/domain_detail.html:76
#: assets/templates/assets/domain_gateway_list.html:61 #: assets/templates/assets/domain_gateway_list.html:61
#: assets/templates/assets/domain_list.html:28 #: assets/templates/assets/domain_list.html:28
...@@ -414,7 +434,7 @@ msgstr "创建日期" ...@@ -414,7 +434,7 @@ msgstr "创建日期"
#: xpack/plugins/cloud/models.py:129 #: xpack/plugins/cloud/models.py:129
#: xpack/plugins/cloud/templates/cloud/account_detail.html:72 #: xpack/plugins/cloud/templates/cloud/account_detail.html:72
#: xpack/plugins/cloud/templates/cloud/account_list.html:15 #: xpack/plugins/cloud/templates/cloud/account_list.html:15
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:79 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:71
#: xpack/plugins/cloud/templates/cloud/sync_task_list.html:20 #: xpack/plugins/cloud/templates/cloud/sync_task_list.html:20
#: xpack/plugins/orgs/templates/orgs/org_detail.html:64 #: xpack/plugins/orgs/templates/orgs/org_detail.html:64
#: xpack/plugins/orgs/templates/orgs/org_list.html:22 #: xpack/plugins/orgs/templates/orgs/org_list.html:22
...@@ -488,6 +508,82 @@ msgstr "北京电信" ...@@ -488,6 +508,82 @@ msgstr "北京电信"
msgid "BGP full netcom" msgid "BGP full netcom"
msgstr "BGP全网通" msgstr "BGP全网通"
#: assets/models/cmd_filter.py:34
msgid "Regex"
msgstr "正则表达式"
#: assets/models/cmd_filter.py:35 terminal/models.py:139
#: terminal/templates/terminal/command_list.html:55
#: terminal/templates/terminal/command_list.html:71
#: terminal/templates/terminal/session_detail.html:48
#: terminal/templates/terminal/session_list.html:77
msgid "Command"
msgstr "命令"
#: assets/models/cmd_filter.py:40
msgid "Deny"
msgstr "拒绝"
#: assets/models/cmd_filter.py:41
msgid "Allow"
msgstr "允许"
#: assets/models/cmd_filter.py:45
msgid "Filter"
msgstr "过滤器"
#: assets/models/cmd_filter.py:46
#: assets/templates/assets/cmd_filter_rule_list.html:58
#: audits/templates/audits/login_log_list.html:50
#: common/templates/common/terminal_setting.html:73
#: common/templates/common/terminal_setting.html:91
msgid "Type"
msgstr "类型"
#: assets/models/cmd_filter.py:47 assets/models/user.py:114
#: assets/templates/assets/cmd_filter_rule_list.html:60
msgid "Priority"
msgstr "优先级"
#: assets/models/cmd_filter.py:47
msgid "1-100, the lower will be match first"
msgstr "优先级可选范围为1-100,1最高优先级 100最低优先级"
#: assets/models/cmd_filter.py:49
#: assets/templates/assets/cmd_filter_rule_list.html:59
msgid "Content"
msgstr "内容"
#: assets/models/cmd_filter.py:49
msgid "One line one command"
msgstr "每行一个命令"
#: assets/models/cmd_filter.py:50
#: assets/templates/assets/admin_user_list.html:33
#: assets/templates/assets/asset_list.html:97
#: assets/templates/assets/cmd_filter_list.html:28
#: assets/templates/assets/cmd_filter_rule_list.html:63
#: assets/templates/assets/domain_gateway_list.html:62
#: assets/templates/assets/domain_list.html:29
#: assets/templates/assets/label_list.html:17
#: assets/templates/assets/system_user_asset.html:54
#: 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:67
#: 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
#: perms/templates/perms/asset_permission_list.html:60
#: terminal/templates/terminal/session_list.html:81
#: terminal/templates/terminal/terminal_list.html:36
#: users/templates/users/user_group_list.html:15
#: users/templates/users/user_list.html:29
#: xpack/plugins/cloud/templates/cloud/account_list.html:16
#: xpack/plugins/cloud/templates/cloud/sync_task_list.html:21
#: xpack/plugins/orgs/templates/orgs/org_list.html:23
#: xpack/templates/orgs/org_list.html:15
msgid "Action"
msgstr "动作"
#: assets/models/domain.py:59 assets/templates/assets/domain_detail.html:21 #: assets/models/domain.py:59 assets/templates/assets/domain_detail.html:21
#: assets/templates/assets/domain_detail.html:64 #: assets/templates/assets/domain_detail.html:64
#: assets/templates/assets/domain_gateway_list.html:21 #: assets/templates/assets/domain_gateway_list.html:21
...@@ -542,57 +638,56 @@ msgstr "分类" ...@@ -542,57 +638,56 @@ msgstr "分类"
msgid "Key" msgid "Key"
msgstr "" msgstr ""
#: assets/models/user.py:109 #: assets/models/user.py:108
msgid "Automatic login" msgid "Automatic login"
msgstr "自动登录" msgstr "自动登录"
#: assets/models/user.py:110 #: assets/models/user.py:109
msgid "Manually login" msgid "Manually login"
msgstr "手动登录" msgstr "手动登录"
#: assets/models/user.py:114 #: assets/models/user.py:113
#: assets/templates/assets/_asset_group_bulk_update_modal.html:11 #: assets/templates/assets/_asset_group_bulk_update_modal.html:11
#: assets/templates/assets/system_user_asset.html:21 #: assets/templates/assets/system_user_asset.html:22
#: assets/templates/assets/system_user_detail.html:22 #: assets/templates/assets/system_user_detail.html:22
#: assets/views/admin_user.py:29 assets/views/admin_user.py:47 #: assets/views/admin_user.py:29 assets/views/admin_user.py:47
#: assets/views/admin_user.py:63 assets/views/admin_user.py:78 #: assets/views/admin_user.py:63 assets/views/admin_user.py:78
#: assets/views/admin_user.py:102 assets/views/asset.py:53 #: assets/views/admin_user.py:102 assets/views/asset.py:53
#: assets/views/asset.py:92 assets/views/asset.py:136 assets/views/asset.py:153 #: assets/views/asset.py:92 assets/views/asset.py:136 assets/views/asset.py:153
#: assets/views/asset.py:177 assets/views/domain.py:29 #: assets/views/asset.py:177 assets/views/cmd_filter.py:30
#: assets/views/domain.py:45 assets/views/domain.py:61 #: assets/views/cmd_filter.py:46 assets/views/cmd_filter.py:62
#: assets/views/domain.py:74 assets/views/domain.py:98 #: assets/views/cmd_filter.py:78 assets/views/cmd_filter.py:97
#: assets/views/domain.py:126 assets/views/domain.py:145 #: assets/views/cmd_filter.py:130 assets/views/cmd_filter.py:163
#: assets/views/label.py:26 assets/views/label.py:42 assets/views/label.py:58 #: assets/views/domain.py:29 assets/views/domain.py:45
#: assets/views/system_user.py:28 assets/views/system_user.py:44 #: assets/views/domain.py:61 assets/views/domain.py:74
#: assets/views/system_user.py:60 assets/views/system_user.py:74 #: assets/views/domain.py:98 assets/views/domain.py:126
#: templates/_nav.html:19 #: assets/views/domain.py:145 assets/views/label.py:26 assets/views/label.py:42
#: assets/views/label.py:58 assets/views/system_user.py:28
#: assets/views/system_user.py:44 assets/views/system_user.py:60
#: assets/views/system_user.py:74 templates/_nav.html:19
msgid "Assets" msgid "Assets"
msgstr "资产管理" msgstr "资产管理"
#: assets/models/user.py:115 #: assets/models/user.py:116 assets/templates/assets/_system_user.html:59
msgid "Priority"
msgstr "优先级"
#: assets/models/user.py:117 assets/templates/assets/_system_user.html:59
#: assets/templates/assets/system_user_detail.html:122 #: assets/templates/assets/system_user_detail.html:122
#: assets/templates/assets/system_user_update.html:10 #: assets/templates/assets/system_user_update.html:10
msgid "Auto push" msgid "Auto push"
msgstr "自动推送" msgstr "自动推送"
#: assets/models/user.py:118 assets/templates/assets/system_user_detail.html:74 #: assets/models/user.py:117 assets/templates/assets/system_user_detail.html:74
msgid "Sudo" msgid "Sudo"
msgstr "Sudo" msgstr "Sudo"
#: assets/models/user.py:119 assets/templates/assets/system_user_detail.html:79 #: assets/models/user.py:118 assets/templates/assets/system_user_detail.html:79
msgid "Shell" msgid "Shell"
msgstr "Shell" msgstr "Shell"
#: assets/models/user.py:120 assets/templates/assets/system_user_detail.html:66 #: assets/models/user.py:119 assets/templates/assets/system_user_detail.html:66
#: assets/templates/assets/system_user_list.html:32 #: assets/templates/assets/system_user_list.html:32
msgid "Login mode" msgid "Login mode"
msgstr "登录模式" msgstr "登录模式"
#: assets/models/user.py:181 assets/templates/assets/user_asset_list.html:167 #: assets/models/user.py:189 assets/templates/assets/user_asset_list.html:167
#: audits/models.py:19 audits/templates/audits/ftp_log_list.html:49 #: audits/models.py:19 audits/templates/audits/ftp_log_list.html:49
#: audits/templates/audits/ftp_log_list.html:72 perms/forms.py:40 #: audits/templates/audits/ftp_log_list.html:72 perms/forms.py:40
#: perms/models.py:33 perms/models.py:81 #: perms/models.py:33 perms/models.py:81
...@@ -670,6 +765,8 @@ msgid "Select Asset" ...@@ -670,6 +765,8 @@ msgid "Select Asset"
msgstr "选择资产" msgstr "选择资产"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:21 #: assets/templates/assets/_asset_group_bulk_update_modal.html:21
#: assets/templates/assets/cmd_filter_detail.html:89
#: assets/templates/assets/cmd_filter_list.html:26
#: assets/templates/assets/user_asset_list.html:48 #: assets/templates/assets/user_asset_list.html:48
#: users/templates/users/user_granted_asset.html:47 #: users/templates/users/user_granted_asset.html:47
msgid "System users" msgid "System users"
...@@ -730,7 +827,7 @@ msgstr "认证" ...@@ -730,7 +827,7 @@ msgstr "认证"
msgid "Auto generate key" msgid "Auto generate key"
msgstr "自动生成密钥" msgstr "自动生成密钥"
#: assets/templates/assets/_system_user.html:65 #: assets/templates/assets/_system_user.html:69
#: assets/templates/assets/asset_create.html:60 #: assets/templates/assets/asset_create.html:60
#: assets/templates/assets/asset_update.html:64 #: assets/templates/assets/asset_update.html:64
#: assets/templates/assets/gateway_create_update.html:53 #: assets/templates/assets/gateway_create_update.html:53
...@@ -739,11 +836,13 @@ msgstr "自动生成密钥" ...@@ -739,11 +836,13 @@ msgstr "自动生成密钥"
msgid "Other" msgid "Other"
msgstr "其它" msgstr "其它"
#: assets/templates/assets/_system_user.html:71 #: assets/templates/assets/_system_user.html:75
#: assets/templates/assets/admin_user_create_update.html:45 #: assets/templates/assets/admin_user_create_update.html:45
#: assets/templates/assets/asset_bulk_update.html:23 #: assets/templates/assets/asset_bulk_update.html:23
#: assets/templates/assets/asset_create.html:67 #: assets/templates/assets/asset_create.html:67
#: assets/templates/assets/asset_update.html:71 #: assets/templates/assets/asset_update.html:71
#: assets/templates/assets/cmd_filter_create_update.html:15
#: assets/templates/assets/cmd_filter_rule_create_update.html:40
#: assets/templates/assets/domain_create_update.html:16 #: assets/templates/assets/domain_create_update.html:16
#: 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
...@@ -767,12 +866,14 @@ msgstr "其它" ...@@ -767,12 +866,14 @@ msgstr "其它"
msgid "Reset" msgid "Reset"
msgstr "重置" msgstr "重置"
#: assets/templates/assets/_system_user.html:72 #: assets/templates/assets/_system_user.html:76
#: assets/templates/assets/admin_user_create_update.html:46 #: assets/templates/assets/admin_user_create_update.html:46
#: assets/templates/assets/asset_bulk_update.html:24 #: assets/templates/assets/asset_bulk_update.html:24
#: assets/templates/assets/asset_create.html:68 #: assets/templates/assets/asset_create.html:68
#: assets/templates/assets/asset_list.html:114 #: assets/templates/assets/asset_list.html:114
#: assets/templates/assets/asset_update.html:72 #: assets/templates/assets/asset_update.html:72
#: assets/templates/assets/cmd_filter_create_update.html:16
#: assets/templates/assets/cmd_filter_rule_create_update.html:41
#: assets/templates/assets/domain_create_update.html:17 #: assets/templates/assets/domain_create_update.html:17
#: 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
...@@ -807,9 +908,11 @@ msgstr "关闭" ...@@ -807,9 +908,11 @@ msgstr "关闭"
#: assets/templates/assets/admin_user_assets.html:18 #: assets/templates/assets/admin_user_assets.html:18
#: assets/templates/assets/admin_user_detail.html:18 #: assets/templates/assets/admin_user_detail.html:18
#: assets/templates/assets/cmd_filter_detail.html:19
#: assets/templates/assets/cmd_filter_rule_list.html:19
#: assets/templates/assets/domain_detail.html:18 #: assets/templates/assets/domain_detail.html:18
#: assets/templates/assets/domain_gateway_list.html:18 #: assets/templates/assets/domain_gateway_list.html:18
#: assets/templates/assets/system_user_asset.html:17 #: assets/templates/assets/system_user_asset.html:18
#: assets/templates/assets/system_user_detail.html:18 #: assets/templates/assets/system_user_detail.html:18
#: ops/templates/ops/adhoc_history.html:130 #: ops/templates/ops/adhoc_history.html:130
#: ops/templates/ops/task_adhoc.html:116 #: ops/templates/ops/task_adhoc.html:116
...@@ -832,14 +935,14 @@ msgstr "资产列表" ...@@ -832,14 +935,14 @@ msgstr "资产列表"
#: assets/templates/assets/admin_user_assets.html:54 #: assets/templates/assets/admin_user_assets.html:54
#: assets/templates/assets/admin_user_list.html:29 #: assets/templates/assets/admin_user_list.html:29
#: assets/templates/assets/system_user_asset.html:52 #: assets/templates/assets/system_user_asset.html:53
#: assets/templates/assets/system_user_list.html:34 #: assets/templates/assets/system_user_list.html:34
#: users/templates/users/user_group_granted_asset.html:47 #: users/templates/users/user_group_granted_asset.html:47
msgid "Reachable" msgid "Reachable"
msgstr "可连接" msgstr "可连接"
#: assets/templates/assets/admin_user_assets.html:66 #: assets/templates/assets/admin_user_assets.html:66
#: assets/templates/assets/system_user_asset.html:65 #: assets/templates/assets/system_user_asset.html:66
#: assets/templates/assets/system_user_detail.html:116 #: assets/templates/assets/system_user_detail.html:116
#: perms/templates/perms/asset_permission_detail.html:114 #: perms/templates/perms/asset_permission_detail.html:114
msgid "Quick update" msgid "Quick update"
...@@ -852,8 +955,8 @@ msgstr "测试可连接性" ...@@ -852,8 +955,8 @@ 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:171
#: assets/templates/assets/system_user_asset.html:74 #: assets/templates/assets/system_user_asset.html:75
#: assets/templates/assets/system_user_asset.html:160 #: assets/templates/assets/system_user_asset.html:161
#: assets/templates/assets/system_user_detail.html:151 #: assets/templates/assets/system_user_detail.html:151
msgid "Test" msgid "Test"
msgstr "测试" msgstr "测试"
...@@ -862,6 +965,9 @@ msgstr "测试" ...@@ -862,6 +965,9 @@ msgstr "测试"
#: assets/templates/assets/admin_user_list.html:88 #: assets/templates/assets/admin_user_list.html:88
#: assets/templates/assets/asset_detail.html:24 #: assets/templates/assets/asset_detail.html:24
#: assets/templates/assets/asset_list.html:171 #: assets/templates/assets/asset_list.html:171
#: assets/templates/assets/cmd_filter_detail.html:29
#: assets/templates/assets/cmd_filter_list.html:57
#: assets/templates/assets/cmd_filter_rule_list.html:86
#: assets/templates/assets/domain_detail.html:24 #: assets/templates/assets/domain_detail.html:24
#: assets/templates/assets/domain_detail.html:103 #: assets/templates/assets/domain_detail.html:103
#: assets/templates/assets/domain_gateway_list.html:85 #: assets/templates/assets/domain_gateway_list.html:85
...@@ -892,6 +998,9 @@ msgstr "更新" ...@@ -892,6 +998,9 @@ msgstr "更新"
#: assets/templates/assets/admin_user_list.html:89 #: assets/templates/assets/admin_user_list.html:89
#: assets/templates/assets/asset_detail.html:28 #: assets/templates/assets/asset_detail.html:28
#: assets/templates/assets/asset_list.html:172 #: assets/templates/assets/asset_list.html:172
#: assets/templates/assets/cmd_filter_detail.html:33
#: assets/templates/assets/cmd_filter_list.html:58
#: assets/templates/assets/cmd_filter_rule_list.html:87
#: assets/templates/assets/domain_detail.html:28 #: assets/templates/assets/domain_detail.html:28
#: assets/templates/assets/domain_detail.html:104 #: assets/templates/assets/domain_detail.html:104
#: assets/templates/assets/domain_gateway_list.html:86 #: assets/templates/assets/domain_gateway_list.html:86
...@@ -911,7 +1020,7 @@ msgstr "更新" ...@@ -911,7 +1020,7 @@ msgstr "更新"
#: xpack/plugins/cloud/templates/cloud/account_detail.html:29 #: xpack/plugins/cloud/templates/cloud/account_detail.html:29
#: xpack/plugins/cloud/templates/cloud/account_list.html:40 #: xpack/plugins/cloud/templates/cloud/account_list.html:40
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:32 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:32
#: xpack/plugins/cloud/templates/cloud/sync_task_list.html:45 #: xpack/plugins/cloud/templates/cloud/sync_task_list.html:49
#: xpack/plugins/orgs/templates/orgs/org_detail.html:29 #: xpack/plugins/orgs/templates/orgs/org_detail.html:29
#: xpack/plugins/orgs/templates/orgs/org_list.html:87 #: xpack/plugins/orgs/templates/orgs/org_list.html:87
#: xpack/templates/orgs/org_list.html:45 #: xpack/templates/orgs/org_list.html:45
...@@ -930,8 +1039,9 @@ msgstr "选择节点" ...@@ -930,8 +1039,9 @@ 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:200
#: assets/templates/assets/asset_list.html:633 #: assets/templates/assets/asset_list.html:633
#: assets/templates/assets/system_user_asset.html:111 #: assets/templates/assets/cmd_filter_detail.html:106
#: assets/templates/assets/system_user_detail.html:330 #: assets/templates/assets/system_user_asset.html:112
#: 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 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
...@@ -983,29 +1093,6 @@ msgstr "不可达" ...@@ -983,29 +1093,6 @@ msgstr "不可达"
msgid "Ratio" msgid "Ratio"
msgstr "比例" msgstr "比例"
#: assets/templates/assets/admin_user_list.html:33
#: assets/templates/assets/asset_list.html:97
#: assets/templates/assets/domain_gateway_list.html:62
#: assets/templates/assets/domain_list.html:29
#: assets/templates/assets/label_list.html:17
#: assets/templates/assets/system_user_asset.html:53
#: 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:67
#: 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
#: perms/templates/perms/asset_permission_list.html:60
#: terminal/templates/terminal/session_list.html:81
#: terminal/templates/terminal/terminal_list.html:36
#: users/templates/users/user_group_list.html:15
#: users/templates/users/user_list.html:29
#: xpack/plugins/cloud/templates/cloud/account_list.html:16
#: xpack/plugins/cloud/templates/cloud/sync_task_list.html:21
#: xpack/plugins/orgs/templates/orgs/org_list.html:23
#: xpack/templates/orgs/org_list.html:15
msgid "Action"
msgstr "动作"
#: assets/templates/assets/asset_bulk_update.html:8 #: assets/templates/assets/asset_bulk_update.html:8
#: users/templates/users/user_bulk_update.html:8 #: users/templates/users/user_bulk_update.html:8
msgid "Select properties that need to be modified" msgid "Select properties that need to be modified"
...@@ -1191,7 +1278,6 @@ msgid "This will delete the selected assets !!!" ...@@ -1191,7 +1278,6 @@ msgid "This will delete the selected assets !!!"
msgstr "删除选择资产" msgstr "删除选择资产"
#: assets/templates/assets/asset_list.html:631 #: assets/templates/assets/asset_list.html:631
#: assets/templates/assets/system_user_detail.html:328
#: assets/templates/assets/system_user_list.html:141 #: assets/templates/assets/system_user_list.html:141
#: 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
...@@ -1220,6 +1306,66 @@ msgstr "删除失败" ...@@ -1220,6 +1306,66 @@ msgstr "删除失败"
msgid "Configuration" msgid "Configuration"
msgstr "配置" msgstr "配置"
#: assets/templates/assets/cmd_filter_detail.html:25
#: assets/templates/assets/cmd_filter_list.html:25
#: assets/templates/assets/cmd_filter_rule_list.html:23
msgid "Rules"
msgstr "规则"
#: assets/templates/assets/cmd_filter_detail.html:73
msgid "Date updated"
msgstr "更新日期"
#: assets/templates/assets/cmd_filter_detail.html:97
msgid "Binding to system user"
msgstr "绑定到系统用户"
#: assets/templates/assets/cmd_filter_list.html:6
msgid ""
"System user bound some command filter, each command filter has some rules,"
msgstr "系统用户可以绑定一些命令过滤器,一个过滤器可以定义一些规则"
#: assets/templates/assets/cmd_filter_list.html:7
msgid "When user login asset with this system user, then run a command,"
msgstr "当用户使用这个系统用户登录资产,然后执行一个命令"
#: assets/templates/assets/cmd_filter_list.html:8
msgid ""
"The command will be filter by rules, higher priority(lower number) rule run "
"first,"
msgstr "这个命令需要被绑定过滤器的所有规则匹配,高优先级(数字越低)先被匹配,"
#: assets/templates/assets/cmd_filter_list.html:9
msgid ""
"When a rule matched, if rule action is allow, then allow command execute,"
msgstr "当一个规则匹配到了,如果规则的动作是 允许, 这个命令会被放行,"
#: assets/templates/assets/cmd_filter_list.html:10
msgid "else if action is deny, then command with be deny,"
msgstr "如果规则的动作是 禁止,命令将会被禁止执行,"
#: assets/templates/assets/cmd_filter_list.html:11
msgid "else match next rule, if none matched, allowed"
msgstr "否则就匹配下一个规则,如果最后没有匹配到规则,则允许执行"
#: assets/templates/assets/cmd_filter_list.html:16
#: assets/views/cmd_filter.py:47
msgid "Create command filter"
msgstr "创建命令过滤器"
#: assets/templates/assets/cmd_filter_rule_list.html:33
#: assets/views/cmd_filter.py:98
msgid "Command filter rule list"
msgstr "命令过滤器列表"
#: assets/templates/assets/cmd_filter_rule_list.html:50
msgid "Create rule"
msgstr "创建规则"
#: assets/templates/assets/cmd_filter_rule_list.html:61
msgid "Strategy"
msgstr "策略"
#: assets/templates/assets/delete_confirm.html:6 #: assets/templates/assets/delete_confirm.html:6
#: perms/templates/perms/delete_confirm.html:6 templates/delete_confirm.html:6 #: perms/templates/perms/delete_confirm.html:6 templates/delete_confirm.html:6
msgid "Confirm delete" msgid "Confirm delete"
...@@ -1275,27 +1421,27 @@ msgstr "创建网域" ...@@ -1275,27 +1421,27 @@ msgstr "创建网域"
msgid "Create label" msgid "Create label"
msgstr "创建标签" msgstr "创建标签"
#: assets/templates/assets/system_user_asset.html:30 #: assets/templates/assets/system_user_asset.html:31
msgid "Assets of " msgid "Assets of "
msgstr "资产" msgstr "资产"
#: assets/templates/assets/system_user_asset.html:71 #: assets/templates/assets/system_user_asset.html:72
#: assets/templates/assets/system_user_detail.html:148 #: assets/templates/assets/system_user_detail.html:148
msgid "Test assets connective" msgid "Test assets connective"
msgstr "测试资产可连接性" msgstr "测试资产可连接性"
#: assets/templates/assets/system_user_asset.html:80 #: assets/templates/assets/system_user_asset.html:81
#: assets/templates/assets/system_user_detail.html:139 #: assets/templates/assets/system_user_detail.html:139
msgid "Push system user now" msgid "Push system user now"
msgstr "立刻推送系统" msgstr "立刻推送系统"
#: assets/templates/assets/system_user_asset.html:83 #: assets/templates/assets/system_user_asset.html:84
#: assets/templates/assets/system_user_asset.html:158 #: assets/templates/assets/system_user_asset.html:159
#: assets/templates/assets/system_user_detail.html:142 #: assets/templates/assets/system_user_detail.html:142
msgid "Push" msgid "Push"
msgstr "推送" msgstr "推送"
#: assets/templates/assets/system_user_asset.html:102 #: assets/templates/assets/system_user_asset.html:103
msgid "Add to node" msgid "Add to node"
msgstr "添加到节点" msgstr "添加到节点"
...@@ -1307,17 +1453,9 @@ msgstr "家目录" ...@@ -1307,17 +1453,9 @@ msgstr "家目录"
msgid "Uid" msgid "Uid"
msgstr "Uid" msgstr "Uid"
#: assets/templates/assets/system_user_detail.html:324 #: assets/templates/assets/system_user_detail.html:173
msgid "Are you sure to remove authentication information for the system user ?" msgid "Binding command filters"
msgstr "你确定清除该系统用户的认证信息吗 ?" msgstr "绑定命令过滤器"
#: assets/templates/assets/system_user_detail.html:336
msgid "Clear auth"
msgstr "清除认证信息"
#: assets/templates/assets/system_user_detail.html:336
msgid "success"
msgstr "成功"
#: assets/templates/assets/system_user_list.html:10 #: assets/templates/assets/system_user_list.html:10
msgid "" msgid ""
...@@ -1403,6 +1541,26 @@ msgstr "更新资产" ...@@ -1403,6 +1541,26 @@ msgstr "更新资产"
msgid "already exists" msgid "already exists"
msgstr "已经存在" msgstr "已经存在"
#: assets/views/cmd_filter.py:31
msgid "Command filter list"
msgstr "命令过滤器列表"
#: assets/views/cmd_filter.py:63
msgid "Update command filter"
msgstr "更新命令过滤器"
#: assets/views/cmd_filter.py:79
msgid "Command filter detail"
msgstr "命令过滤器详情"
#: assets/views/cmd_filter.py:131
msgid "Create command filter rule"
msgstr "创建命令过滤器规则"
#: assets/views/cmd_filter.py:164
msgid "Update command filter rule"
msgstr "更新命令过滤器规则"
#: assets/views/domain.py:30 templates/_nav.html:23 #: assets/views/domain.py:30 templates/_nav.html:23
msgid "Domain list" msgid "Domain list"
msgstr "网域列表" msgstr "网域列表"
...@@ -1443,11 +1601,11 @@ msgstr "更新系统用户" ...@@ -1443,11 +1601,11 @@ msgstr "更新系统用户"
msgid "System user detail" msgid "System user detail"
msgstr "系统用户详情" msgstr "系统用户详情"
#: assets/views/system_user.py:95 #: assets/views/system_user.py:96
msgid "assets" msgid "assets"
msgstr "资产管理" msgstr "资产管理"
#: assets/views/system_user.py:96 #: assets/views/system_user.py:97
msgid "System user asset" msgid "System user asset"
msgstr "系统用户集群资产" msgstr "系统用户集群资产"
...@@ -1471,8 +1629,8 @@ msgstr "文件名" ...@@ -1471,8 +1629,8 @@ msgstr "文件名"
#: audits/models.py:22 audits/templates/audits/ftp_log_list.html:76 #: audits/models.py:22 audits/templates/audits/ftp_log_list.html:76
#: ops/templates/ops/task_list.html:39 users/models/authentication.py:66 #: ops/templates/ops/task_list.html:39 users/models/authentication.py:66
#: users/templates/users/user_detail.html:452 xpack/plugins/cloud/api.py:55 #: users/templates/users/user_detail.html:452 xpack/plugins/cloud/api.py:60
#: xpack/plugins/cloud/api.py:84 #: xpack/plugins/cloud/api.py:89
msgid "Success" msgid "Success"
msgstr "成功" msgstr "成功"
...@@ -1530,12 +1688,6 @@ msgstr "搜索" ...@@ -1530,12 +1688,6 @@ msgstr "搜索"
msgid "ID" msgid "ID"
msgstr "ID" msgstr "ID"
#: audits/templates/audits/login_log_list.html:50
#: common/templates/common/terminal_setting.html:73
#: common/templates/common/terminal_setting.html:91
msgid "Type"
msgstr "类型"
#: audits/templates/audits/login_log_list.html:51 #: audits/templates/audits/login_log_list.html:51
msgid "UA" msgid "UA"
msgstr "Agent" msgstr "Agent"
...@@ -1551,14 +1703,14 @@ msgid "MFA" ...@@ -1551,14 +1703,14 @@ msgid "MFA"
msgstr "MFA" msgstr "MFA"
#: audits/templates/audits/login_log_list.html:55 #: audits/templates/audits/login_log_list.html:55
#: users/models/authentication.py:76 xpack/plugins/cloud/models.py:158 #: users/models/authentication.py:76 xpack/plugins/cloud/models.py:176
#: xpack/plugins/cloud/templates/cloud/sync_task_history.html:67 #: xpack/plugins/cloud/templates/cloud/sync_task_history.html:67
msgid "Reason" msgid "Reason"
msgstr "原因" msgstr "原因"
#: audits/templates/audits/login_log_list.html:56 #: audits/templates/audits/login_log_list.html:56
#: users/models/authentication.py:77 xpack/plugins/cloud/models.py:157 #: users/models/authentication.py:77 xpack/plugins/cloud/models.py:175
#: xpack/plugins/cloud/models.py:174 #: xpack/plugins/cloud/models.py:192
#: xpack/plugins/cloud/templates/cloud/sync_task_history.html:68 #: xpack/plugins/cloud/templates/cloud/sync_task_history.html:68
#: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:67 #: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:67
msgid "Status" msgid "Status"
...@@ -1578,19 +1730,19 @@ msgid "Datetime" ...@@ -1578,19 +1730,19 @@ msgid "Datetime"
msgstr "日期" msgstr "日期"
#: audits/views.py:66 audits/views.py:110 audits/views.py:143 #: audits/views.py:66 audits/views.py:110 audits/views.py:143
#: templates/_nav.html:67 #: templates/_nav.html:73
msgid "Audits" msgid "Audits"
msgstr "日志审计" msgstr "日志审计"
#: audits/views.py:67 templates/_nav.html:71 #: audits/views.py:67 templates/_nav.html:77
msgid "FTP log" msgid "FTP log"
msgstr "FTP日志" msgstr "FTP日志"
#: audits/views.py:111 templates/_nav.html:72 #: audits/views.py:111 templates/_nav.html:78
msgid "Operate log" msgid "Operate log"
msgstr "操作日志" msgstr "操作日志"
#: audits/views.py:144 templates/_nav.html:73 #: audits/views.py:144 templates/_nav.html:79
msgid "Password change log" msgid "Password change log"
msgstr "改密日志" msgstr "改密日志"
...@@ -1602,7 +1754,7 @@ msgstr "改密日志" ...@@ -1602,7 +1754,7 @@ msgstr "改密日志"
msgid "Users" msgid "Users"
msgstr "用户管理" msgstr "用户管理"
#: audits/views.py:184 templates/_nav.html:70 #: audits/views.py:184 templates/_nav.html:76
msgid "Login log" msgid "Login log"
msgstr "登录日志" msgstr "登录日志"
...@@ -1924,7 +2076,7 @@ msgid "Special char not allowed" ...@@ -1924,7 +2076,7 @@ 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:19 common/views.py:45 common/views.py:71 common/views.py:101
#: common/views.py:129 templates/_nav.html:104 #: common/views.py:129 templates/_nav.html:108
msgid "Settings" msgid "Settings"
msgstr "系统设置" msgstr "系统设置"
...@@ -1970,7 +2122,7 @@ msgstr "任务" ...@@ -1970,7 +2122,7 @@ msgstr "任务"
#: ops/models/adhoc.py:157 ops/templates/ops/adhoc_detail.html:57 #: ops/models/adhoc.py:157 ops/templates/ops/adhoc_detail.html:57
#: ops/templates/ops/task_adhoc.html:60 #: ops/templates/ops/task_adhoc.html:60
msgid "Pattern" msgid "Pattern"
msgstr "" msgstr "模式"
#: ops/models/adhoc.py:158 ops/templates/ops/adhoc_detail.html:61 #: ops/models/adhoc.py:158 ops/templates/ops/adhoc_detail.html:61
msgid "Options" msgid "Options"
...@@ -2168,7 +2320,7 @@ msgid "Versions" ...@@ -2168,7 +2320,7 @@ msgid "Versions"
msgstr "版本" msgstr "版本"
#: ops/templates/ops/task_list.html:71 #: ops/templates/ops/task_list.html:71
#: xpack/plugins/cloud/templates/cloud/sync_task_list.html:43 #: xpack/plugins/cloud/templates/cloud/sync_task_list.html:47
msgid "Run" msgid "Run"
msgstr "执行" msgstr "执行"
...@@ -2181,7 +2333,7 @@ msgstr "任务开始: " ...@@ -2181,7 +2333,7 @@ msgstr "任务开始: "
msgid "Ops" msgid "Ops"
msgstr "作业中心" msgstr "作业中心"
#: ops/views.py:37 templates/_nav.html:61 #: ops/views.py:37 templates/_nav.html:67
msgid "Task list" msgid "Task list"
msgstr "任务列表" msgstr "任务列表"
...@@ -2219,7 +2371,7 @@ msgstr "资产和节点至少选一个" ...@@ -2219,7 +2371,7 @@ msgstr "资产和节点至少选一个"
msgid "Date expired" msgid "Date expired"
msgstr "失效日期" msgstr "失效日期"
#: perms/models.py:45 perms/models.py:92 templates/_nav.html:33 #: perms/models.py:45 perms/models.py:92 templates/_nav.html:34
msgid "Asset permission" msgid "Asset permission"
msgstr "资产授权" msgstr "资产授权"
...@@ -2307,7 +2459,7 @@ msgid "Select user groups" ...@@ -2307,7 +2459,7 @@ msgid "Select user groups"
msgstr "选择用户组" msgstr "选择用户组"
#: perms/views.py:23 perms/views.py:53 perms/views.py:68 perms/views.py:83 #: perms/views.py:23 perms/views.py:53 perms/views.py:68 perms/views.py:83
#: perms/views.py:118 perms/views.py:150 templates/_nav.html:30 #: perms/views.py:118 perms/views.py:150 templates/_nav.html:31
#: xpack/plugins/orgs/templates/orgs/org_list.html:21 #: xpack/plugins/orgs/templates/orgs/org_list.html:21
msgid "Perms" msgid "Perms"
msgstr "权限管理" msgstr "权限管理"
...@@ -2410,46 +2562,54 @@ msgstr "" ...@@ -2410,46 +2562,54 @@ msgstr ""
msgid "User list" msgid "User list"
msgstr "用户列表" msgstr "用户列表"
#: templates/_nav.html:39 #: templates/_nav.html:27
msgid "Command filters"
msgstr "命令过滤"
#: templates/_nav.html:40
msgid "Sessions" msgid "Sessions"
msgstr "会话管理" msgstr "会话管理"
#: templates/_nav.html:42 #: templates/_nav.html:43
msgid "Session online" msgid "Session online"
msgstr "在线会话" msgstr "在线会话"
#: templates/_nav.html:43 #: templates/_nav.html:44
msgid "Session offline" msgid "Session offline"
msgstr "历史会话" msgstr "历史会话"
#: templates/_nav.html:44 #: templates/_nav.html:45
msgid "Commands" msgid "Commands"
msgstr "命令记录" msgstr "命令记录"
#: templates/_nav.html:47 templates/_nav_user.html:14 #: templates/_nav.html:48 templates/_nav_user.html:14
msgid "Web terminal" msgid "Web terminal"
msgstr "Web终端" msgstr "Web终端"
#: templates/_nav.html:51 terminal/views/command.py:50 #: templates/_nav.html:53
msgid "File manager"
msgstr "文件管理"
#: templates/_nav.html:57 terminal/views/command.py:50
#: terminal/views/session.py:75 terminal/views/session.py:93 #: terminal/views/session.py:75 terminal/views/session.py:93
#: terminal/views/session.py:115 terminal/views/terminal.py:31 #: terminal/views/session.py:115 terminal/views/terminal.py:31
#: terminal/views/terminal.py:46 terminal/views/terminal.py:58 #: terminal/views/terminal.py:46 terminal/views/terminal.py:58
msgid "Terminal" msgid "Terminal"
msgstr "终端管理" msgstr "终端管理"
#: templates/_nav.html:58 #: templates/_nav.html:64
msgid "Job Center" msgid "Job Center"
msgstr "作业中心" msgstr "作业中心"
#: templates/_nav.html:88 #: templates/_nav.html:94
msgid "XPack" msgid "XPack"
msgstr "" msgstr ""
#: templates/_nav.html:95 xpack/plugins/cloud/views.py:26 #: templates/_nav.html:100 xpack/plugins/cloud/views.py:26
msgid "Account list" msgid "Account list"
msgstr "账户列表" msgstr "账户列表"
#: templates/_nav.html:96 xpack/plugins/cloud/views.py:85 #: templates/_nav.html:101 xpack/plugins/cloud/views.py:85
msgid "Sync task list" msgid "Sync task list"
msgstr "同步任务列表" msgstr "同步任务列表"
...@@ -2691,13 +2851,6 @@ msgstr "运行时间" ...@@ -2691,13 +2851,6 @@ msgstr "运行时间"
msgid "Replay" msgid "Replay"
msgstr "回放" msgstr "回放"
#: terminal/models.py:139 terminal/templates/terminal/command_list.html:55
#: terminal/templates/terminal/command_list.html:71
#: terminal/templates/terminal/session_detail.html:48
#: terminal/templates/terminal/session_list.html:77
msgid "Command"
msgstr "命令"
#: terminal/models.py:142 #: terminal/models.py:142
msgid "Date last active" msgid "Date last active"
msgstr "最后活跃日期" msgstr "最后活跃日期"
...@@ -2779,10 +2932,8 @@ msgid "Terminate task send, waiting ..." ...@@ -2779,10 +2932,8 @@ msgid "Terminate task send, waiting ..."
msgstr "终断任务已发送,请等待" msgstr "终断任务已发送,请等待"
#: terminal/templates/terminal/session_list.html:156 #: terminal/templates/terminal/session_list.html:156
#, fuzzy
#| msgid "MFA enable success"
msgid "Finish session success" msgid "Finish session success"
msgstr "MFA 绑定成功" msgstr "标记会话完成成功"
#: terminal/templates/terminal/terminal_detail.html:13 #: terminal/templates/terminal/terminal_detail.html:13
#: terminal/views/terminal.py:59 #: terminal/views/terminal.py:59
...@@ -2837,15 +2988,15 @@ msgstr "终端列表" ...@@ -2837,15 +2988,15 @@ msgstr "终端列表"
msgid "Update terminal" msgid "Update terminal"
msgstr "更新终端" msgstr "更新终端"
#: terminal/views/terminal.py:102 terminal/views/terminal.py:103 #: terminal/views/terminal.py:105 terminal/views/terminal.py:106
msgid "Redirect to web terminal" msgid "Redirect to web terminal"
msgstr "重定向到web terminal" msgstr "重定向到web terminal"
#: terminal/views/terminal.py:110 #: terminal/views/terminal.py:113
msgid "Connect ssh terminal" msgid "Connect ssh terminal"
msgstr "连接ssh终端" msgstr "连接ssh终端"
#: terminal/views/terminal.py:111 #: terminal/views/terminal.py:114
msgid "" msgid ""
"You should use your ssh client tools connect terminal: {} <br /> <br />{}" "You should use your ssh client tools connect terminal: {} <br /> <br />{}"
msgstr "你可以使用ssh客户端工具连接终端" msgstr "你可以使用ssh客户端工具连接终端"
...@@ -3047,8 +3198,8 @@ msgstr "用户名/密码 校验失败" ...@@ -3047,8 +3198,8 @@ msgstr "用户名/密码 校验失败"
msgid "MFA authentication failed" msgid "MFA authentication failed"
msgstr "MFA 认证失败" msgstr "MFA 认证失败"
#: users/models/authentication.py:67 xpack/plugins/cloud/models.py:150 #: users/models/authentication.py:67 xpack/plugins/cloud/models.py:168
#: xpack/plugins/cloud/models.py:164 #: xpack/plugins/cloud/models.py:182
msgid "Failed" msgid "Failed"
msgstr "失败" msgstr "失败"
...@@ -3891,19 +4042,15 @@ msgstr "MFA 解绑成功" ...@@ -3891,19 +4042,15 @@ msgstr "MFA 解绑成功"
msgid "MFA disable success, return login page" msgid "MFA disable success, return login page"
msgstr "MFA 解绑成功,返回登录页面" msgstr "MFA 解绑成功,返回登录页面"
#: xpack/plugins/cloud/api.py:54 xpack/plugins/cloud/providers/provider.py:76 #: xpack/plugins/cloud/api.py:59 xpack/plugins/cloud/providers/provider.py:75
#, fuzzy
#| msgid "Unavailable"
msgid "Account unavailable" msgid "Account unavailable"
msgstr "无效" msgstr "账户无效"
#: xpack/plugins/cloud/api.py:79 #: xpack/plugins/cloud/api.py:84
#, fuzzy
#| msgid "Create sync task"
msgid "Get sync task error" msgid "Get sync task error"
msgstr "创建同步任务" msgstr "获取同步任务"
#: xpack/plugins/cloud/api.py:82 #: xpack/plugins/cloud/api.py:87
msgid "New provider error" msgid "New provider error"
msgstr "" msgstr ""
...@@ -3992,37 +4139,38 @@ msgid "Instances" ...@@ -3992,37 +4139,38 @@ msgid "Instances"
msgstr "实例" msgstr "实例"
#: xpack/plugins/cloud/models.py:130 #: xpack/plugins/cloud/models.py:130
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:83 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:75
#: xpack/plugins/cloud/templates/cloud/sync_task_list.html:19
msgid "Date last sync" msgid "Date last sync"
msgstr "最后同步日期" msgstr "最后同步日期"
#: xpack/plugins/cloud/models.py:151 xpack/plugins/cloud/models.py:165 #: xpack/plugins/cloud/models.py:169 xpack/plugins/cloud/models.py:183
msgid "Succeed" msgid "Succeed"
msgstr "成功" msgstr "成功"
#: xpack/plugins/cloud/models.py:152 #: xpack/plugins/cloud/models.py:170
msgid "Partial succeed" msgid "Partial succeed"
msgstr "" msgstr ""
#: xpack/plugins/cloud/models.py:155 xpack/plugins/cloud/models.py:169 #: xpack/plugins/cloud/models.py:173 xpack/plugins/cloud/models.py:187
msgid "Sync task" msgid "Sync task"
msgstr "同步任务" msgstr "同步任务"
#: xpack/plugins/cloud/models.py:156 #: xpack/plugins/cloud/models.py:174
msgid "Result" msgid "Result"
msgstr "" msgstr ""
#: xpack/plugins/cloud/models.py:159 xpack/plugins/cloud/models.py:175 #: xpack/plugins/cloud/models.py:177 xpack/plugins/cloud/models.py:193
#: xpack/plugins/cloud/templates/cloud/sync_task_history.html:69 #: xpack/plugins/cloud/templates/cloud/sync_task_history.html:69
#: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:68 #: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:68
msgid "Date sync" msgid "Date sync"
msgstr "同步日期" msgstr "同步日期"
#: xpack/plugins/cloud/models.py:166 #: xpack/plugins/cloud/models.py:184
msgid "Exist" msgid "Exist"
msgstr "存在" msgstr "存在"
#: xpack/plugins/cloud/models.py:170 #: xpack/plugins/cloud/models.py:188
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:25 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:25
#: xpack/plugins/cloud/templates/cloud/sync_task_history.html:26 #: xpack/plugins/cloud/templates/cloud/sync_task_history.html:26
#: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:26 #: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:26
...@@ -4030,14 +4178,14 @@ msgstr "存在" ...@@ -4030,14 +4178,14 @@ msgstr "存在"
msgid "Sync task history" msgid "Sync task history"
msgstr "同步历史列表" msgstr "同步历史列表"
#: xpack/plugins/cloud/models.py:171 #: xpack/plugins/cloud/models.py:189
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:67 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:91
#: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:63 #: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:63
msgid "Instance" msgid "Instance"
msgstr "实例" msgstr "实例"
#: xpack/plugins/cloud/models.py:172 #: xpack/plugins/cloud/models.py:190
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:63 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:83
#: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:64 #: xpack/plugins/cloud/templates/cloud/sync_task_instance.html:64
msgid "Region" msgid "Region"
msgstr "地域" msgstr "地域"
...@@ -4057,10 +4205,8 @@ msgid "Loading..." ...@@ -4057,10 +4205,8 @@ msgid "Loading..."
msgstr "" msgstr ""
#: xpack/plugins/cloud/templates/cloud/sync_task_create.html:106 #: xpack/plugins/cloud/templates/cloud/sync_task_create.html:106
#, fuzzy
#| msgid "Create node failed"
msgid "Load failed" msgid "Load failed"
msgstr "创建节点失败" msgstr "加载失败"
#: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:22 #: xpack/plugins/cloud/templates/cloud/sync_task_detail.html:22
#: xpack/plugins/cloud/templates/cloud/sync_task_history.html:23 #: xpack/plugins/cloud/templates/cloud/sync_task_history.html:23
...@@ -4097,7 +4243,7 @@ msgstr "存在" ...@@ -4097,7 +4243,7 @@ msgstr "存在"
msgid "Create sync task" msgid "Create sync task"
msgstr "创建同步任务" msgstr "创建同步任务"
#: xpack/plugins/cloud/templates/cloud/sync_task_list.html:80 #: xpack/plugins/cloud/templates/cloud/sync_task_list.html:84
msgid "Sync success" msgid "Sync success"
msgstr "同步成功" msgstr "同步成功"
...@@ -4149,6 +4295,16 @@ msgstr "创建组织" ...@@ -4149,6 +4295,16 @@ msgstr "创建组织"
msgid "Update org" msgid "Update org"
msgstr "更新组织" msgstr "更新组织"
#~ msgid ""
#~ "Are you sure to remove authentication information for the system user ?"
#~ msgstr "你确定清除该系统用户的认证信息吗 ?"
#~ msgid "Clear auth"
#~ msgstr "清除认证信息"
#~ msgid "success"
#~ msgstr "成功"
#~ msgid "Task has been send, Go to ops task list seen result" #~ msgid "Task has been send, Go to ops task list seen result"
#~ msgstr "任务已下发,查看ops任务列表" #~ msgstr "任务已下发,查看ops任务列表"
......
...@@ -14,7 +14,8 @@ class SwitchOrgView(DetailView): ...@@ -14,7 +14,8 @@ class SwitchOrgView(DetailView):
pk = kwargs.get('pk') pk = kwargs.get('pk')
self.object = Organization.get_instance(pk) self.object = Organization.get_instance(pk)
request.session['oid'] = self.object.id.__str__() request.session['oid'] = self.object.id.__str__()
return redirect('index') referer = request.META.get('HTTP_REFERER', reverse('index'))
return redirect(referer)
class SwitchToAOrgView(View): class SwitchToAOrgView(View):
......
...@@ -1528,9 +1528,15 @@ a.ui-button:active .ui-icon, ...@@ -1528,9 +1528,15 @@ a.ui-button:active .ui-icon,
.std42-dialog .ui-dialog-titlebar .elfinder-titlebar-minimize:hover .ui-icon { .std42-dialog .ui-dialog-titlebar .elfinder-titlebar-minimize:hover .ui-icon {
background-color: #ff9800; background-color: #ff9800;
} }
.elfinder-dialog-title { .elfinder-dialog-title {
color: #f1f1f1; color: #f1f1f1;
} }
.ui-dialog-buttonpane {
background: #fff;
}
.std42-dialog .ui-dialog-content { .std42-dialog .ui-dialog-content {
background: #fff; background: #fff;
} }
......
...@@ -375,7 +375,7 @@ ...@@ -375,7 +375,7 @@
'pass' : '密码', // added 18.04.2012 'pass' : '密码', // added 18.04.2012
'confirmUnmount' : '确实要卸载 $1?', // from v2.1 added 30.04.2012 'confirmUnmount' : '确实要卸载 $1?', // from v2.1 added 30.04.2012
'dropFilesBrowser': '从浏览器中拖放或粘贴文件', // from v2.1 added 30.05.2012 'dropFilesBrowser': '从浏览器中拖放或粘贴文件', // from v2.1 added 30.05.2012
'dropPasteFiles' : '拖放文件,粘贴网址或剪贴板图像', // from v2.1 added 07.04.2014 'dropPasteFiles' : '拖放文件,或粘贴剪贴板图像', // from v2.1 added 07.04.2014
'encoding' : '编码', // from v2.1 added 19.12.2014 'encoding' : '编码', // from v2.1 added 19.12.2014
'locale' : '语言环境', // from v2.1 added 19.12.2014 'locale' : '语言环境', // from v2.1 added 19.12.2014
'searchTarget' : '目标: $1', // from v2.1 added 22.5.2015 'searchTarget' : '目标: $1', // from v2.1 added 22.5.2015
......
{% load i18n %} {% load i18n %}
<div class="footer fixed"> <div class="footer fixed">
<div class="pull-right"> <div class="pull-right">
Version <strong>1.4.1-{% include '_build.html' %}</strong> GPLv2. Version <strong>1.4.3-{% include '_build.html' %}</strong> GPLv2.
<!--<img style="display: none" src="http://www.jumpserver.org/img/evaluate_avatar1.jpg">--> <!--<img style="display: none" src="http://www.jumpserver.org/img/evaluate_avatar1.jpg">-->
</div> </div>
<div> <div>
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
<li id="admin-user"><a href="{% url 'assets:admin-user-list' %}">{% trans 'Admin user' %}</a></li> <li id="admin-user"><a href="{% url 'assets:admin-user-list' %}">{% trans 'Admin user' %}</a></li>
<li id="system-user"><a href="{% url 'assets:system-user-list' %}">{% trans 'System user' %}</a></li> <li id="system-user"><a href="{% url 'assets:system-user-list' %}">{% trans 'System user' %}</a></li>
<li id="label"><a href="{% url 'assets:label-list' %}">{% trans 'Labels' %}</a></li> <li id="label"><a href="{% url 'assets:label-list' %}">{% trans 'Labels' %}</a></li>
<li id="cmd-filter"><a href="{% url 'assets:cmd-filter-list' %}">{% trans 'Command filters' %}</a></li>
</ul> </ul>
</li> </li>
<li id="perms"> <li id="perms">
...@@ -47,6 +48,11 @@ ...@@ -47,6 +48,11 @@
<span class="nav-label">{% trans 'Web terminal' %}</span> <span class="nav-label">{% trans 'Web terminal' %}</span>
</a> </a>
</li> </li>
<li>
<a href="{% url 'terminal:web-sftp' %}" target="_blank">
<span class="nav-label">{% trans 'File manager' %}</span>
</a>
</li>
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<li id="terminal"><a href="{% url 'terminal:terminal-list' %}">{% trans 'Terminal' %}</a></li> <li id="terminal"><a href="{% url 'terminal:terminal-list' %}">{% trans 'Terminal' %}</a></li>
{% endif %} {% endif %}
...@@ -91,10 +97,8 @@ ...@@ -91,10 +97,8 @@
{% for plugin in XPACK_PLUGINS %} {% for plugin in XPACK_PLUGINS %}
<li id="{{ plugin.name }}"><a href="{{ plugin.endpoint }}">{% trans plugin.verbose_name %}</a></li> <li id="{{ plugin.name }}"><a href="{{ plugin.endpoint }}">{% trans plugin.verbose_name %}</a></li>
{% endfor %} {% endfor %}
<li id="id_cloud_account"><a href="{% url 'xpack:cloud:account-list' %}">{% trans 'Account list' %}</a></li> <li id="id_cloud_account"><a href="{% url 'xpack:cloud:account-list' %}">{% trans 'Account list' %}</a></li>
<li id="id_cloud_sync_task"><a href="{% url 'xpack:cloud:sync-task-list' %}">{% trans 'Sync task list' %}</a></li> <li id="id_cloud_sync_task"><a href="{% url 'xpack:cloud:sync-task-list' %}">{% trans 'Sync task list' %}</a></li>
</ul> </ul>
</li> </li>
{% endif %} {% endif %}
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.core.cache import cache
from django.utils import timezone from django.utils import timezone
from rest_framework import serializers from rest_framework import serializers
from rest_framework_bulk.serializers import BulkListSerializer from rest_framework_bulk.serializers import BulkListSerializer
...@@ -28,19 +29,8 @@ class TerminalSerializer(serializers.ModelSerializer): ...@@ -28,19 +29,8 @@ class TerminalSerializer(serializers.ModelSerializer):
@staticmethod @staticmethod
def get_is_alive(obj): def get_is_alive(obj):
try: key = StatusSerializer.CACHE_KEY_PREFIX + str(obj.id)
status = obj.status_set.latest() return cache.get(key)
except Status.DoesNotExist:
status = None
if not status:
return False
delta = timezone.now() - status.date_created
if delta < timezone.timedelta(seconds=600):
return True
else:
return False
class SessionSerializer(BulkSerializerMixin, serializers.ModelSerializer): class SessionSerializer(BulkSerializerMixin, serializers.ModelSerializer):
...@@ -57,11 +47,18 @@ class SessionSerializer(BulkSerializerMixin, serializers.ModelSerializer): ...@@ -57,11 +47,18 @@ class SessionSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class StatusSerializer(serializers.ModelSerializer): class StatusSerializer(serializers.ModelSerializer):
CACHE_KEY_PREFIX = 'terminal_status_'
class Meta: class Meta:
fields = '__all__' fields = '__all__'
model = Status model = Status
def create(self, validated_data):
terminal_id = str(validated_data['terminal'].id)
key = self.CACHE_KEY_PREFIX + terminal_id
cache.set(key, 1, 60)
return validated_data
class TaskSerializer(BulkSerializerMixin, serializers.ModelSerializer): class TaskSerializer(BulkSerializerMixin, serializers.ModelSerializer):
......
...@@ -16,6 +16,7 @@ urlpatterns = [ ...@@ -16,6 +16,7 @@ urlpatterns = [
path('terminal/<uuid:pk>/update/', views.TerminalUpdateView.as_view(), name='terminal-update'), path('terminal/<uuid:pk>/update/', views.TerminalUpdateView.as_view(), name='terminal-update'),
path('<uuid:pk>/accept/', views.TerminalAcceptView.as_view(), name='terminal-accept'), path('<uuid:pk>/accept/', views.TerminalAcceptView.as_view(), name='terminal-accept'),
path('web-terminal/', views.WebTerminalView.as_view(), name='web-terminal'), path('web-terminal/', views.WebTerminalView.as_view(), name='web-terminal'),
path('web-sftp/', views.WebSFTPView.as_view(), name='web-sftp'),
# Session view # Session view
path('session-online/', views.SessionOnlineListView.as_view(), name='session-online-list'), path('session-online/', views.SessionOnlineListView.as_view(), name='session-online-list'),
......
...@@ -16,7 +16,7 @@ from common.permissions import SuperUserRequiredMixin ...@@ -16,7 +16,7 @@ from common.permissions import SuperUserRequiredMixin
__all__ = [ __all__ = [
"TerminalListView", "TerminalUpdateView", "TerminalDetailView", "TerminalListView", "TerminalUpdateView", "TerminalDetailView",
"TerminalDeleteView", "TerminalConnectView", "TerminalAcceptView", "TerminalDeleteView", "TerminalConnectView", "TerminalAcceptView",
"WebTerminalView", "WebTerminalView", 'WebSFTPView',
] ]
...@@ -93,6 +93,9 @@ class TerminalAcceptView(SuperUserRequiredMixin, JSONResponseMixin, UpdateView): ...@@ -93,6 +93,9 @@ class TerminalAcceptView(SuperUserRequiredMixin, JSONResponseMixin, UpdateView):
class TerminalConnectView(LoginRequiredMixin, SuperUserRequiredMixin, DetailView): class TerminalConnectView(LoginRequiredMixin, SuperUserRequiredMixin, DetailView):
"""
Abandon
"""
template_name = 'flash_message_standalone.html' template_name = 'flash_message_standalone.html'
model = Terminal model = Terminal
...@@ -121,3 +124,8 @@ class TerminalConnectView(LoginRequiredMixin, SuperUserRequiredMixin, DetailView ...@@ -121,3 +124,8 @@ class TerminalConnectView(LoginRequiredMixin, SuperUserRequiredMixin, DetailView
class WebTerminalView(LoginRequiredMixin, View): class WebTerminalView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
return redirect('/luna/?' + request.GET.urlencode()) return redirect('/luna/?' + request.GET.urlencode())
class WebSFTPView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
return redirect('/coco/elfinder/sftp/?' + request.GET.urlencode())
...@@ -71,3 +71,4 @@ urllib3==1.22 ...@@ -71,3 +71,4 @@ urllib3==1.22
vine==1.1.4 vine==1.1.4
drf-yasg==1.9.1 drf-yasg==1.9.1
Werkzeug==0.14.1 Werkzeug==0.14.1
drf-nested-routers==0.90.2
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