diff --git a/apps/assets/api.py b/apps/assets/api.py
index 3bc6c5639..e5c5a44ff 100644
--- a/apps/assets/api.py
+++ b/apps/assets/api.py
@@ -26,7 +26,7 @@ from .hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \
get_user_granted_assets
from .models import AssetGroup, Asset, Cluster, SystemUser, AdminUser
from . import serializers
-from .tasks import update_asset_hardware_info_manual, test_admin_user_connectability_util, \
+from .tasks import update_asset_hardware_info_manual, test_admin_user_connectability_manual, \
test_asset_connectability_manual, push_system_user_to_cluster_assets_manual, \
test_system_user_connectability_manual
@@ -40,18 +40,14 @@ class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
"""
queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer
- permission_classes = (IsValidUser,)
+ permission_classes = (IsSuperUserOrAppUser,)
def get_queryset(self):
- if self.request.user.is_superuser or self.request.user.is_app:
- queryset = super().get_queryset()
- else:
- assets_granted = get_user_granted_assets(self.request.user)
- queryset = self.queryset.filter(id__in=[asset.id for asset in assets_granted])
-
+ queryset = super().get_queryset()
cluster_id = self.request.query_params.get('cluster_id')
asset_group_id = self.request.query_params.get('asset_group_id')
admin_user_id = self.request.query_params.get('admin_user_id')
+ system_user_id = self.request.query_params.get('system_user_id')
if cluster_id:
queryset = queryset.filter(cluster__id=cluster_id)
@@ -62,6 +58,23 @@ class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
assets_direct = [asset.id for asset in admin_user.asset_set.all()]
clusters = [cluster.id for cluster in admin_user.cluster_set.all()]
queryset = queryset.filter(Q(cluster__id__in=clusters)|Q(id__in=assets_direct))
+ if system_user_id:
+ system_user = get_object_or_404(SystemUser, id=system_user_id)
+ clusters = system_user.get_clusters()
+ queryset = queryset.filter(cluster__in=clusters)
+ return queryset
+
+
+class UserAssetListView(generics.ListAPIView):
+ queryset = Asset.objects.all()
+ serializer_class = serializers.AssetSerializer
+ permission_classes = (IsValidUser,)
+
+ def get_queryset(self):
+ assets_granted = get_user_granted_assets(self.request.user)
+ queryset = self.queryset.filter(
+ id__in=[asset.id for asset in assets_granted]
+ )
return queryset
@@ -99,15 +112,6 @@ class GroupAddAssetsApi(generics.UpdateAPIView):
return Response({'error': serializer.errors}, status=400)
-class ClusterUpdateAssetsApi(generics.RetrieveUpdateAPIView):
- """
- Cluster update asset member
- """
- queryset = Cluster.objects.all()
- serializer_class = serializers.ClusterUpdateAssetsSerializer
- permission_classes = (IsSuperUser,)
-
-
class ClusterViewSet(IDInFilterMixin, BulkModelViewSet):
"""
Cluster api set, for add,delete,update,list,retrieve resource
@@ -117,7 +121,6 @@ class ClusterViewSet(IDInFilterMixin, BulkModelViewSet):
permission_classes = (IsSuperUser,)
-# TOdo
class ClusterTestAssetsAliveApi(generics.RetrieveAPIView):
"""
Test cluster asset can connect using admin user or not
@@ -127,6 +130,9 @@ class ClusterTestAssetsAliveApi(generics.RetrieveAPIView):
def retrieve(self, request, *args, **kwargs):
cluster = self.get_object()
+ admin_user = cluster.admin_user
+ test_admin_user_connectability_manual.delay(admin_user)
+ return Response("Task has been send, seen left assets status")
class ClusterAddAssetsApi(generics.UpdateAPIView):
@@ -256,7 +262,7 @@ class AdminUserTestConnectiveApi(generics.RetrieveAPIView):
def retrieve(self, request, *args, **kwargs):
admin_user = self.get_object()
- test_admin_user_connectability_util.delay(admin_user)
+ test_admin_user_connectability_manual.delay(admin_user)
return Response({"msg": "Task created"})
diff --git a/apps/assets/forms.py b/apps/assets/forms.py
index 431c174a6..68aaddc43 100644
--- a/apps/assets/forms.py
+++ b/apps/assets/forms.py
@@ -36,7 +36,7 @@ class AssetCreateForm(forms.ModelForm):
def clean_admin_user(self):
cluster = self.cleaned_data.get('cluster')
admin_user = self.cleaned_data.get('admin_user')
- if not cluster.admin_user and not admin_user:
+ if not admin_user and (cluster and not cluster.admin_user):
raise forms.ValidationError(_("You need set a admin user if cluster not have"))
return self.cleaned_data['admin_user']
@@ -64,7 +64,7 @@ class AssetUpdateForm(forms.ModelForm):
def clean_admin_user(self):
cluster = self.cleaned_data.get('cluster')
admin_user = self.cleaned_data.get('admin_user')
- if not cluster.admin_user and not admin_user:
+ if not admin_user and (cluster and not cluster.admin_user):
raise forms.ValidationError(_("You need set a admin user if cluster not have"))
return self.cleaned_data['admin_user']
@@ -124,20 +124,25 @@ class AssetGroupForm(forms.ModelForm):
label=_('Asset'),
required=False,
widget=forms.SelectMultiple(
- attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
+ attrs={'class': 'select2', 'data-placeholder': _('Select assets')}
)
+ )
- def __init__(self, *args, **kwargs):
- if kwargs.get('instance', None):
+ def __init__(self, **kwargs):
+ instance = kwargs.get('instance')
+ if instance:
initial = kwargs.get('initial', {})
- initial['assets'] = kwargs['instance'].assets.all()
- super(AssetGroupForm, self).__init__(*args, **kwargs)
+ initial.update({
+ 'assets': instance.assets.all(),
+ })
+ kwargs['initial'] = initial
+ super().__init__(**kwargs)
- def _save_m2m(self):
- super(AssetGroupForm, self)._save_m2m()
- assets = self.cleaned_data['assets']
- self.instance.assets.clear()
- self.instance.assets.add(*tuple(assets))
+ def save(self, commit=True):
+ group = super().save(commit=commit)
+ assets= self.cleaned_data['assets']
+ group.assets.set(assets)
+ return group
class Meta:
model = AssetGroup
@@ -150,10 +155,19 @@ class AssetGroupForm(forms.ModelForm):
class ClusterForm(forms.ModelForm):
+ system_users = forms.ModelMultipleChoiceField(
+ queryset=SystemUser.objects.all(),
+ widget=forms.SelectMultiple(
+ attrs={'class': 'select2', 'data-placeholder': _('Select system users')}
+ ),
+ label=_('System users'),
+ required=False,
+ help_text=_("Selected system users will be create at cluster assets"),
+ )
class Meta:
model = Cluster
- fields = ['name', "bandwidth", "operator", 'contact', 'admin_user',
+ fields = ['name', "bandwidth", "operator", 'contact', 'admin_user', 'system_users',
'phone', 'address', 'intranet', 'extranet', 'comment']
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
@@ -162,9 +176,21 @@ class ClusterForm(forms.ModelForm):
}
help_texts = {
'name': '* required',
- 'admin_user': 'The assets of this cluster will use this admin user as his admin user',
+ 'admin_user': _("Cluster level admin user"),
}
+ def __init__(self, *args, **kwargs):
+ if kwargs.get('instance', None):
+ initial = kwargs.get('initial', {})
+ initial['system_users'] = kwargs['instance'].systemuser_set.all()
+ super().__init__(*args, **kwargs)
+
+ def save(self, commit=True):
+ instance = super().save(commit=commit)
+ system_users = self.cleaned_data['system_users']
+ instance.systemuser_set.set(system_users)
+ return instance
+
class AdminUserForm(forms.ModelForm):
# Form field name can not start with `_`, so redefine it,
@@ -172,9 +198,10 @@ class AdminUserForm(forms.ModelForm):
widget=forms.PasswordInput, max_length=128,
strip=True, required=False,
help_text=_('Password or private key password'),
+ label=_("Password"),
)
# Need use upload private key file except paste private key content
- private_key_file = forms.FileField(required=False)
+ private_key_file = forms.FileField(required=False, label=_("Private key"))
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
@@ -204,12 +231,14 @@ class AdminUserForm(forms.ModelForm):
return private_key_file
def clean(self):
+ super().clean()
password = self.cleaned_data['password']
private_key_file = self.cleaned_data.get('private_key_file', '')
- if not self.instance and not (password or private_key_file):
- raise forms.ValidationError(
- _('Password and private key file must be input one'))
+ if not password and not private_key_file:
+ raise forms.ValidationError(_(
+ 'Password and private key file must be input one'
+ ))
class Meta:
model = AdminUser
@@ -229,9 +258,10 @@ class SystemUserForm(forms.ModelForm):
# Admin user assets define, let user select, save it in form not in view
auto_generate_key = forms.BooleanField(initial=True, required=False)
# Form field name can not start with `_`, so redefine it,
- password = forms.CharField(widget=forms.PasswordInput, required=False, max_length=128, strip=True)
+ password = forms.CharField(widget=forms.PasswordInput, required=False,
+ max_length=128, strip=True, label=_("Password"))
# Need use upload private key file except paste private key content
- private_key_file = forms.FileField(required=False)
+ private_key_file = forms.FileField(required=False, label=_("Private key"))
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
@@ -278,15 +308,18 @@ class SystemUserForm(forms.ModelForm):
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
'cluster': forms.SelectMultiple(
- attrs={'class': 'select2',
- 'data-placeholder': _(' Select clusters')}),
+ attrs={
+ 'class': 'select2',
+ 'data-placeholder': _(' Select clusters')
+ }
+ ),
}
help_texts = {
'name': '* required',
'username': '* required',
- 'cluster': 'If auto push checked, system user will be create at cluster assets',
- 'auto_push': 'Auto push system user to asset',
- 'priority': 'High level will be using login asset as default, if user was granted more than 2 system user',
+ 'cluster': _('If auto push checked, system user will be create at cluster assets'),
+ 'auto_push': _('Auto push system user to asset'),
+ 'priority': _('High level will be using login asset as default, if user was granted more than 2 system user'),
}
diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py
index 6d1ba3f20..c83443077 100644
--- a/apps/assets/models/asset.py
+++ b/apps/assets/models/asset.py
@@ -18,6 +18,16 @@ __all__ = ['Asset']
logger = logging.getLogger(__name__)
+def default_cluster():
+ from .cluster import Cluster
+ name = "Default"
+ defaults = {"name": name}
+ cluster, created = Cluster.objects.get_or_create(
+ defaults=defaults, name=name
+ )
+ return cluster.id
+
+
class Asset(models.Model):
# Todo: Move them to settings
STATUS_CHOICES = (
@@ -44,7 +54,7 @@ class Asset(models.Model):
hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname'))
port = models.IntegerField(default=22, verbose_name=_('Port'))
groups = models.ManyToManyField(AssetGroup, blank=True, related_name='assets', verbose_name=_('Asset groups'))
- cluster = models.ForeignKey(Cluster, blank=True, null=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_('Cluster'))
+ cluster = models.ForeignKey(Cluster, related_name='assets', default=default_cluster, on_delete=models.SET_DEFAULT, verbose_name=_('Cluster'))
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
type = models.CharField(choices=TYPE_CHOICES, max_length=16, blank=True, null=True, default='Server', verbose_name=_('Asset type'),)
env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True, default='Prod', verbose_name=_('Asset environment'),)
@@ -158,6 +168,7 @@ class Asset(models.Model):
class Meta:
unique_together = ('ip', 'port')
+ verbose_name = _("Asset")
@classmethod
def generate_fake(cls, count=100):
diff --git a/apps/assets/models/cluster.py b/apps/assets/models/cluster.py
index 3b66555c3..8d093979e 100644
--- a/apps/assets/models/cluster.py
+++ b/apps/assets/models/cluster.py
@@ -37,6 +37,7 @@ class Cluster(models.Model):
class Meta:
ordering = ['name']
+ verbose_name = _("Cluster")
@classmethod
def generate_fake(cls, count=5):
diff --git a/apps/assets/models/group.py b/apps/assets/models/group.py
index 18b0c5289..c01a2a529 100644
--- a/apps/assets/models/group.py
+++ b/apps/assets/models/group.py
@@ -27,6 +27,7 @@ class AssetGroup(models.Model):
class Meta:
ordering = ['name']
+ verbose_name = _("Asset group")
@classmethod
def initial(cls):
diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py
index 863535ef2..aa44a539c 100644
--- a/apps/assets/models/user.py
+++ b/apps/assets/models/user.py
@@ -81,7 +81,11 @@ class AssetUser(models.Model):
@property
def public_key(self):
- return signer.unsign(self._public_key)
+ key = signer.unsign(self._public_key)
+ if key:
+ return key
+ else:
+ return None
@property
def public_key_obj(self):
@@ -170,7 +174,6 @@ class AdminUser(AssetUser):
info = None
return info
-
def get_related_assets(self):
assets = []
for cluster in self.cluster_set.all():
@@ -184,6 +187,7 @@ class AdminUser(AssetUser):
class Meta:
ordering = ['name']
+ verbose_name = _("Admin user")
@classmethod
def generate_fake(cls, count=10):
@@ -224,7 +228,7 @@ class SystemUser(AssetUser):
def get_clusters_assets(self):
from .asset import Asset
- clusters = self.cluster.all()
+ clusters = self.get_clusters()
return Asset.objects.filter(cluster__in=clusters)
def get_clusters(self):
@@ -262,6 +266,7 @@ class SystemUser(AssetUser):
class Meta:
ordering = ['name']
+ verbose_name = _("System user")
@classmethod
def generate_fake(cls, count=10):
diff --git a/apps/assets/serializers.py b/apps/assets/serializers.py
index 1e6662160..401aeac2a 100644
--- a/apps/assets/serializers.py
+++ b/apps/assets/serializers.py
@@ -64,6 +64,7 @@ class AdminUserSerializer(serializers.ModelSerializer):
"""
assets_amount = serializers.SerializerMethodField()
unreachable_amount = serializers.SerializerMethodField()
+ reachable_amount = serializers.SerializerMethodField()
class Meta:
model = AdminUser
@@ -75,7 +76,15 @@ class AdminUserSerializer(serializers.ModelSerializer):
if data:
return len(data.get('dark'))
else:
- return 'Unknown'
+ return 0
+
+ @staticmethod
+ def get_reachable_amount(obj):
+ data = cache.get(ADMIN_USER_CONN_CACHE_KEY.format(obj.name))
+ if data:
+ return len(data.get('contacted'))
+ else:
+ return 0
@staticmethod
def get_assets_amount(obj):
@@ -183,7 +192,7 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
class Meta(object):
model = Asset
fields = ("id", "hostname", "ip", "port", "system_users_granted",
- "is_inherited", "is_active", "system_users_join",
+ "is_inherited", "is_active", "system_users_join", "os",
"platform", "comment",)
@staticmethod
diff --git a/apps/assets/signals_handler.py b/apps/assets/signals_handler.py
index dfd264677..63dc3e882 100644
--- a/apps/assets/signals_handler.py
+++ b/apps/assets/signals_handler.py
@@ -27,16 +27,17 @@ def test_asset_conn_on_created(asset):
def push_cluster_system_users_to_asset(asset):
- logger.info("Push cluster system user to asset: {}".format(asset))
- task_name = _("Push cluster system users to asset")
- system_users = asset.cluster.systemuser_set.all()
- push_system_user_util.delay(system_users, [asset], task_name)
+ if asset.cluster:
+ logger.info("Push cluster system user to asset: {}".format(asset))
+ task_name = _("Push cluster system users to asset")
+ system_users = asset.cluster.systemuser_set.all()
+ push_system_user_util.delay(system_users, [asset], task_name)
@receiver(post_save, sender=Asset, dispatch_uid="my_unique_identifier")
def on_asset_created(sender, instance=None, created=False, **kwargs):
if instance and created:
- logger.info("Asset `` create signal received".format(instance))
+ logger.info("Asset `{}` create signal received".format(instance))
update_asset_hardware_info_on_created(instance)
test_asset_conn_on_created(instance)
push_cluster_system_users_to_asset(instance)
@@ -77,7 +78,7 @@ def on_system_user_created_or_updated(sender, instance=None, **kwargs):
@receiver(post_init, sender=Cluster, dispatch_uid="my_unique_identifier")
def on_cluster_init(sender, instance, **kwargs):
instance.__original_assets = tuple(instance.assets.values_list('pk', flat=True))
- # instance.__origin_system_users = tuple(instance.systemuser_set.all())
+ instance.__origin_system_users = tuple(instance.systemuser_set.values_list('pk', flat=True))
@receiver(post_save, sender=Cluster, dispatch_uid="my_unique_identifier")
@@ -103,11 +104,11 @@ def on_cluster_assets_changed(sender, instance, **kwargs):
push_system_user_util.delay(system_users, assets, task_name)
-@receiver(post_save, sender=Cluster, dispatch_uid="my_unique_identifier")
+@receiver(post_save, sender=Cluster, dispatch_uid="my_unique_identifier2")
def on_cluster_system_user_changed(sender, instance, **kwargs):
system_users_origin = instance.__origin_system_users
system_user_new = instance.systemuser_set.values_list('pk', flat=True)
- system_users_added = set(system_user_new) - system_users_origin
+ system_users_added = set(system_user_new) - set(system_users_origin)
if system_users_added:
logger.debug("Receive cluster change system users signal")
system_users = []
diff --git a/apps/assets/tasks.py b/apps/assets/tasks.py
index ab74c170a..f06f720d9 100644
--- a/apps/assets/tasks.py
+++ b/apps/assets/tasks.py
@@ -25,7 +25,7 @@ disk_pattern = re.compile(r'^hd|sd|xvd')
@shared_task
def set_assets_hardware_info(result, **kwargs):
"""
- Unsing ops task run result, to update asset info
+ Using ops task run result, to update asset info
@shared_task must be exit, because we using it as a task callback, is must
be a celery task also
@@ -209,8 +209,11 @@ def test_asset_connectability_util(asset, task_name=None):
from ops.utils import update_or_create_ansible_task
if task_name is None:
- task_name = "Test asset connectability"
+ task_name = _("Test asset connectability")
hosts = [asset.hostname]
+ if not hosts:
+ logger.info("No hosts, passed")
+ return {}
tasks = const.TEST_ADMIN_USER_CONN_TASKS
task, created = update_or_create_ansible_task(
task_name=task_name, hosts=hosts, tasks=tasks, pattern='all',
@@ -262,6 +265,9 @@ def test_system_user_connectability_util(system_user, task_name):
assets = system_user.get_clusters_assets()
hosts = [asset.hostname for asset in assets]
tasks = const.TEST_SYSTEM_USER_CONN_TASKS
+ if not hosts:
+ logger.info("No hosts, passed")
+ return {}
task, created = update_or_create_ansible_task(
task_name, hosts=hosts, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS,
@@ -274,7 +280,7 @@ def test_system_user_connectability_util(system_user, task_name):
@shared_task
def test_system_user_connectability_manual(system_user):
- task_name = "Test system user connectability: {}".format(system_user)
+ task_name = _("Test system user connectability: {}").format(system_user)
return test_system_user_connectability_util(system_user, task_name)
@@ -303,6 +309,10 @@ def test_system_user_connectability_period():
#### Push system user tasks ####
def get_push_system_user_tasks(system_user):
+ # Set root as system user is dangerous
+ if system_user.username == "root":
+ return []
+
tasks = [
{
'name': 'Add user {}'.format(system_user.username),
@@ -310,7 +320,7 @@ def get_push_system_user_tasks(system_user):
'module': 'user',
'args': 'name={} shell={} state=present password={}'.format(
system_user.username, system_user.shell,
- encrypt_password(system_user.password),
+ encrypt_password(system_user.password, salt="K3mIlKK"),
),
}
},
@@ -346,11 +356,14 @@ def push_system_user_util(system_users, assets, task_name):
for system_user in system_users:
tasks.extend(get_push_system_user_tasks(system_user))
- print("Task: ", tasks)
if not tasks:
- return
+ logger.info("Not tasks, passed")
+ return {}
hosts = [asset.hostname for asset in assets]
+ if not hosts:
+ logger.info("Not hosts, passed")
+ return {}
task, created = update_or_create_ansible_task(
task_name=task_name, hosts=hosts, tasks=tasks, pattern='all',
options=const.TASK_OPTIONS, run_as_admin=True, created_by='System'
@@ -381,8 +394,8 @@ def push_system_user_period():
for system_user in system_users:
tasks.extend(get_push_system_user_tasks(system_user))
- task_name = _("Push system user to cluster assets period: {}->{}").format(
- cluster.name, ', '.join(s.name for s in system_users)
+ task_name = _("Push cluster system users to assets period: {}").format(
+ cluster.name
)
hosts = [asset.hostname for asset in cluster.assets.all()]
update_or_create_ansible_task(
diff --git a/apps/assets/templates/assets/_system_user.html b/apps/assets/templates/assets/_system_user.html
index 99b64af30..34501ef49 100644
--- a/apps/assets/templates/assets/_system_user.html
+++ b/apps/assets/templates/assets/_system_user.html
@@ -3,8 +3,8 @@
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
diff --git a/apps/assets/templates/assets/admin_user_assets.html b/apps/assets/templates/assets/admin_user_assets.html
index 4b0429605..dcaaef312 100644
--- a/apps/assets/templates/assets/admin_user_assets.html
+++ b/apps/assets/templates/assets/admin_user_assets.html
@@ -21,11 +21,11 @@
{% trans 'Assets list' %}
- Update
+ {% trans 'Update' %}
- Delete
+ {% trans 'Delete' %}
@@ -60,7 +60,7 @@
{% trans 'IP' %} |
{% trans 'Port' %} |
{% trans 'Type' %} |
- {% trans 'Alive' %} |
+ {% trans 'Reachable' %} |
@@ -144,7 +144,7 @@ $(document).ready(function () {
url: the_url,
error: error,
method: 'GET',
- success_message: "{% trans "Task has been send, seen left asset status" %}"
+ success_message: "{% trans 'Task has been send, seen left asset status' %}"
});
})
diff --git a/apps/assets/templates/assets/admin_user_create_update.html b/apps/assets/templates/assets/admin_user_create_update.html
index d7d5094ff..3d1772172 100644
--- a/apps/assets/templates/assets/admin_user_create_update.html
+++ b/apps/assets/templates/assets/admin_user_create_update.html
@@ -3,8 +3,8 @@
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
diff --git a/apps/assets/templates/assets/admin_user_detail.html b/apps/assets/templates/assets/admin_user_detail.html
index b7fca5f7a..18464dde4 100644
--- a/apps/assets/templates/assets/admin_user_detail.html
+++ b/apps/assets/templates/assets/admin_user_detail.html
@@ -21,11 +21,11 @@
{% trans 'Assets list' %}
- Update
+ {% trans 'Update' %}
- Delete
+ {% trans 'Delete' %}
@@ -133,7 +133,6 @@ function bindToCluster(clusters) {
$('.select2-selection__rendered').empty();
$('#cluster_selected').val('');
$.map(jumpserver.cluster_selected, function(cluster_name, index) {
- console.log(index);
$('#opt_' + index).remove();
// change tr html of user groups.
$('#table-clusters tbody').append(
diff --git a/apps/assets/templates/assets/admin_user_list.html b/apps/assets/templates/assets/admin_user_list.html
index cc7cfc8cf..f7c13a32f 100644
--- a/apps/assets/templates/assets/admin_user_list.html
+++ b/apps/assets/templates/assets/admin_user_list.html
@@ -21,8 +21,10 @@
{% trans 'Name' %} |
{% trans 'Username' %} |
- {% trans 'Asset num' %} |
+ {% trans 'Asset' %} |
+ {% trans 'Reachable' %} |
{% trans 'Unreachable' %} |
+ {% trans 'Ratio' %} |
{% trans 'Comment' %} |
{% trans 'Action' %} |
@@ -41,17 +43,50 @@ $(document).ready(function(){
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '' + cellData + '';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
- }},
+ }},
+ {targets: 4, createdCell: function (td, cellData) {
+ var innerHtml = "";
+ if (cellData !== 0) {
+ innerHtml = "" + cellData + "";
+ } else {
+ innerHtml = "" + cellData + "";
+ }
+ $(td).html('' + innerHtml + '');
+ }},
+ {targets: 5, createdCell: function (td, cellData) {
+ var innerHtml = "";
+ if (cellData !== 0) {
+ innerHtml = "" + cellData + "";
+ } else {
+ innerHtml = "" + cellData + "";
+ }
+ $(td).html('' + innerHtml + '');
+ }},
{targets: 6, createdCell: function (td, cellData, rowData) {
-{# var script_btn = '{% trans "Script" %}'.replace('{{ DEFAULT_PK }}', cellData);#}
+ var val = 0;
+ var innerHtml = "";
+ var total = rowData.assets_amount;
+ var reachable = rowData.reachable_amount;
+ if (total !== 0) {
+ val = reachable/total * 100;
+ }
+
+ if (val === 100) {
+ innerHtml = "" + val + "% ";
+ } else {
+ innerHtml = "" + val + "% ";
+ }
+ $(td).html('' + innerHtml + '');
+
+ }},
+ {targets: 8, createdCell: function (td, cellData, rowData) {
var update_btn = '{% trans "Update" %}'.replace('{{ DEFAULT_PK }}', cellData);
var del_btn = '{% trans "Delete" %}'.replace('{{ DEFAULT_PK }}', cellData);
-{# $(td).html(script_btn + update_btn + del_btn)#}
$(td).html(update_btn + del_btn)
}}],
ajax_url: '{% url "api-assets:admin-user-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" },
- {data: "unreachable_amount"}, {data: "comment" }, {data: "id" }]
+ {data: "reachable_amount"}, {data: "unreachable_amount"}, {data: "id"}, {data: "comment" }, {data: "id" }]
};
jumpserver.initDataTable(options);
})
diff --git a/apps/assets/templates/assets/asset_detail.html b/apps/assets/templates/assets/asset_detail.html
index e19691628..fc2320420 100644
--- a/apps/assets/templates/assets/asset_detail.html
+++ b/apps/assets/templates/assets/asset_detail.html
@@ -21,11 +21,11 @@
{% if user.is_superuser %}
- Update
+ {% trans 'Update' %}
- Delete
+ {% trans 'Delete' %}
{% endif %}
diff --git a/apps/assets/templates/assets/asset_group_create.html b/apps/assets/templates/assets/asset_group_create.html
index 3b951d4d1..36ca40fc1 100644
--- a/apps/assets/templates/assets/asset_group_create.html
+++ b/apps/assets/templates/assets/asset_group_create.html
@@ -1,119 +1,31 @@
-{% extends 'base.html' %}
-{% load i18n %}
+{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
-{% block custom_head_css_js %}
-
-
-{% endblock %}
-{% block content %}
-
-
-
-
-
-
-
+
{% endblock %}
{% block custom_foot_js %}
{% endblock %}
\ No newline at end of file
diff --git a/apps/assets/templates/assets/asset_group_detail.html b/apps/assets/templates/assets/asset_group_detail.html
index be8655d20..4a9b719b1 100644
--- a/apps/assets/templates/assets/asset_group_detail.html
+++ b/apps/assets/templates/assets/asset_group_detail.html
@@ -3,8 +3,8 @@
{% load i18n %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
@@ -212,7 +217,6 @@ $(document).ready(function () {
addAssets(assets_id);
})
-
.on('click', '.btn-leave-group', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:group-update-assets' pk=asset_group.id %}";
@@ -223,9 +227,15 @@ $(document).ready(function () {
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
- console.log(assets);
var data = {"assets": assets};
leaveGroup($this, name, the_url, data);
+}).on('click', '.btn-del', function () {
+ var $this = $(this);
+ var name = "{{ asset_group.name}}";
+ var uid = "{{ asset_group.id }}";
+ var the_url = '{% url "api-assets:asset-group-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
+ var redirect_url = "{% url 'assets:asset-group-list' %}";
+ objectDelete($this, name, the_url, redirect_url);
})
diff --git a/apps/assets/templates/assets/asset_group_list.html b/apps/assets/templates/assets/asset_group_list.html
index 83fcacd1a..e27d78867 100644
--- a/apps/assets/templates/assets/asset_group_list.html
+++ b/apps/assets/templates/assets/asset_group_list.html
@@ -75,8 +75,6 @@ $(document).ready(function(){
return false;
}
var the_url = '{% url "api-assets:asset-group-list" %}';
- console.log(plain_id_list);
- console.log(the_url);
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
diff --git a/apps/assets/templates/assets/asset_list.html b/apps/assets/templates/assets/asset_list.html
index 6bab2f5e3..0a19ba3de 100644
--- a/apps/assets/templates/assets/asset_list.html
+++ b/apps/assets/templates/assets/asset_list.html
@@ -109,7 +109,7 @@ function initTable() {
$(document).ready(function(){
initTable();
})
-.on('click', '#btn_export', function () {
+.on('click', '.btn_export', function () {
var $data_table = $('#asset_list_table').DataTable();
var rows = $data_table.rows('.selected').data();
var assets = [];
@@ -129,7 +129,7 @@ $(document).ready(function(){
}
})
})
-.on('click', '#btn_import', function () {
+.on('click', '#btn_asset_import', function () {
var $form = $('#fm_asset_import');
$form.find('.help-block').remove();
function success (data) {
diff --git a/apps/assets/templates/assets/asset_update.html b/apps/assets/templates/assets/asset_update.html
index fea3249e6..b0cbc484b 100644
--- a/apps/assets/templates/assets/asset_update.html
+++ b/apps/assets/templates/assets/asset_update.html
@@ -46,7 +46,6 @@
{% trans 'Other' %}
{% bootstrap_field form.status layout="horizontal" %}
- {% bootstrap_field form.env layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
{% bootstrap_field form.is_active layout="horizontal" %}
diff --git a/apps/assets/templates/assets/cluster_assets.html b/apps/assets/templates/assets/cluster_assets.html
index 72f4ed81f..b194a5034 100644
--- a/apps/assets/templates/assets/cluster_assets.html
+++ b/apps/assets/templates/assets/cluster_assets.html
@@ -3,8 +3,8 @@
{% load i18n %}
{% block custom_head_css_js %}
-
-
+
+
@@ -94,7 +94,7 @@
|
@@ -204,7 +204,12 @@ $(document).ready(function () {
addAssets(assets_id);
})
.on('click', '#btn-test-assets', function () {
- console.log('ok');
+ var the_url = "{% url 'api-assets:cluster-test-connective' pk=cluster.id %}";
+ APIUpdateAttr({
+ url: the_url,
+ method: 'GET',
+ success_message: "{% trans 'Task has been send, seen left assets status' %}"
+ });
})
{% endblock %}
diff --git a/apps/assets/templates/assets/cluster_create_update.html b/apps/assets/templates/assets/cluster_create_update.html
index b36af260e..38fc6e3de 100644
--- a/apps/assets/templates/assets/cluster_create_update.html
+++ b/apps/assets/templates/assets/cluster_create_update.html
@@ -3,8 +3,8 @@
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
@@ -40,6 +40,7 @@
{% bootstrap_field form.admin_user layout="horizontal" %}
+ {% bootstrap_field form.system_users layout="horizontal" %}
@@ -69,10 +70,7 @@
{% block custom_foot_js %}
{% endblock %}
\ No newline at end of file
diff --git a/apps/assets/templates/assets/cluster_detail.html b/apps/assets/templates/assets/cluster_detail.html
index cd2ecd25e..837e36e68 100644
--- a/apps/assets/templates/assets/cluster_detail.html
+++ b/apps/assets/templates/assets/cluster_detail.html
@@ -3,8 +3,8 @@
{% load i18n %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
@@ -22,11 +22,11 @@
- Update
+ {% trans 'Update' %}
- Delete
+ {% trans 'Delete' %}
diff --git a/apps/assets/templates/assets/cluster_list.html b/apps/assets/templates/assets/cluster_list.html
index b6c0abfb2..e4743b346 100644
--- a/apps/assets/templates/assets/cluster_list.html
+++ b/apps/assets/templates/assets/cluster_list.html
@@ -8,7 +8,7 @@
{% block table_search %}{% endblock %}
{% block table_container %}
diff --git a/apps/assets/templates/assets/system_user_asset.html b/apps/assets/templates/assets/system_user_asset.html
index 75e1b264d..afff889f6 100644
--- a/apps/assets/templates/assets/system_user_asset.html
+++ b/apps/assets/templates/assets/system_user_asset.html
@@ -3,8 +3,8 @@
{% load i18n %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
diff --git a/apps/assets/templates/assets/system_user_detail.html b/apps/assets/templates/assets/system_user_detail.html
index c4ee49443..0bf591bb2 100644
--- a/apps/assets/templates/assets/system_user_detail.html
+++ b/apps/assets/templates/assets/system_user_detail.html
@@ -23,7 +23,12 @@
- Update
+ {% trans 'Update' %}
+
+
+
+ {% trans 'Delete' %}
+
@@ -259,6 +264,13 @@ $(document).ready(function () {
return $(this).data('gid');
}).get();
updateSystemUserCluster(clusters);
+}).on('click', '.btn-del', function () {
+ var $this = $(this);
+ var name = "{{ system_user.name}}";
+ var uid = "{{ system_user.id }}";
+ var the_url = '{% url "api-assets:system-user-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
+ var redirect_url = "{% url 'assets:system-user-list' %}";
+ objectDelete($this, name, the_url, redirect_url);
})
{% endblock %}
diff --git a/apps/assets/templates/assets/user_asset_list.html b/apps/assets/templates/assets/user_asset_list.html
index 100e09525..20c7d4d50 100644
--- a/apps/assets/templates/assets/user_asset_list.html
+++ b/apps/assets/templates/assets/user_asset_list.html
@@ -42,7 +42,6 @@ function initTable() {
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
{% url 'assets:asset-detail' pk=DEFAULT_PK as the_url %}
- console.log('{{ the_url }}');
var detail_btn = '' + cellData + '';
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
}},
@@ -67,7 +66,7 @@ function initTable() {
$(td).html(conn_btn)
}}
],
- ajax_url: '{% url "api-assets:asset-list" %}',
+ ajax_url: '{% url "api-assets:user-asset-list" %}',
columns: [
{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "get_type_display" }, {data: "get_env_display"}, {data: "hardware_info"},
diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py
index 24e7a6c3b..503464b31 100644
--- a/apps/assets/urls/api_urls.py
+++ b/apps/assets/urls/api_urls.py
@@ -21,16 +21,18 @@ urlpatterns = [
api.AssetRefreshHardwareApi.as_view(), name='asset-refresh'),
url(r'^v1/assets/(?P[0-9a-zA-Z\-]{36})/alive/$',
api.AssetAdminUserTestApi.as_view(), name='asset-alive-test'),
+ url(r'^v1/assets/user-assets/$',
+ api.UserAssetListView.as_view(), name='user-asset-list'),
# update the asset group, which add or delete the asset to the group
url(r'^v1/groups/(?P[0-9a-zA-Z\-]{36})/assets/$',
api.GroupUpdateAssetsApi.as_view(), name='group-update-assets'),
url(r'^v1/groups/(?P[0-9a-zA-Z\-]{36})/assets/add/$',
api.GroupAddAssetsApi.as_view(), name='group-add-assets'),
# update the Cluster, and add or delete the assets to the Cluster
- url(r'^v1/cluster/(?P[0-9a-zA-Z\-]{36})/assets/$',
- api.ClusterUpdateAssetsApi.as_view(), name='cluster-update-assets'),
url(r'^v1/cluster/(?P[0-9a-zA-Z\-]{36})/assets/$',
api.ClusterAddAssetsApi.as_view(), name='cluster-add-assets'),
+ url(r'^v1/cluster/(?P[0-9a-zA-Z\-]{36})/assets/connective/$',
+ api.ClusterTestAssetsAliveApi.as_view(), name='cluster-test-connective'),
url(r'^v1/admin-user/(?P[0-9a-zA-Z\-]{36})/clusters/$',
api.AdminUserAddClustersApi.as_view(), name='admin-user-add-clusters'),
url(r'^v1/admin-user/(?P[0-9a-zA-Z\-]{36})/connective/$',
diff --git a/apps/assets/views/admin_user.py b/apps/assets/views/admin_user.py
index 713f1fc53..e3f6bc6b3 100644
--- a/apps/assets/views/admin_user.py
+++ b/apps/assets/views/admin_user.py
@@ -2,20 +2,22 @@
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.conf import settings
-from django.views.generic import TemplateView, ListView, View
-from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy
+from django.views.generic import TemplateView, ListView
+from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin
+from common.const import create_success_msg, update_success_msg
from .. import forms
-from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
+from ..models import AdminUser, Cluster
from ..hands import AdminUserRequiredMixin
-__all__ = ['AdminUserCreateView', 'AdminUserDetailView',
- 'AdminUserDeleteView', 'AdminUserListView',
- 'AdminUserUpdateView', 'AdminUserAssetsView',
- ]
+__all__ = [
+ 'AdminUserCreateView', 'AdminUserDetailView',
+ 'AdminUserDeleteView', 'AdminUserListView',
+ 'AdminUserUpdateView', 'AdminUserAssetsView',
+]
class AdminUserListView(AdminUserRequiredMixin, TemplateView):
@@ -38,6 +40,7 @@ class AdminUserCreateView(AdminUserRequiredMixin,
form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html'
success_url = reverse_lazy('assets:admin-user-list')
+ success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
@@ -47,20 +50,13 @@ class AdminUserCreateView(AdminUserRequiredMixin,
kwargs.update(context)
return super().get_context_data(**kwargs)
- def get_success_message(self, cleaned_data):
- success_message = _(
- 'Create admin user {name} successfully.'.format(
- url=reverse_lazy('assets:admin-user-detail',
- kwargs={'pk': self.object.pk}),
- name=self.object.name,
- ))
- return success_message
-
-class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView):
+class AdminUserUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
model = AdminUser
form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html'
+ success_url = reverse_lazy('assets:admin-user-list')
+ success_message = update_success_msg
def get_context_data(self, **kwargs):
context = {
@@ -70,11 +66,6 @@ class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView):
kwargs.update(context)
return super().get_context_data(**kwargs)
- def get_success_url(self):
- success_url = reverse_lazy('assets:admin-user-detail',
- kwargs={'pk': self.object.pk})
- return success_url
-
class AdminUserDetailView(AdminUserRequiredMixin, DetailView):
model = AdminUser
diff --git a/apps/assets/views/asset.py b/apps/assets/views/asset.py
index 0de933395..d251b7a15 100644
--- a/apps/assets/views/asset.py
+++ b/apps/assets/views/asset.py
@@ -21,10 +21,11 @@ from django.core.cache import cache
from django.utils import timezone
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import redirect
-
+from django.contrib.messages.views import SuccessMessageMixin
from common.mixins import JSONResponseMixin
from common.utils import get_object_or_none, get_logger, is_uuid
+from common.const import create_success_msg, update_success_msg
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin
@@ -46,7 +47,6 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
context = {
'app': _('Assets'),
'action': _('Asset list'),
- # 'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
}
kwargs.update(context)
@@ -66,7 +66,7 @@ class UserAssetListView(LoginRequiredMixin, TemplateView):
return super().get_context_data(**kwargs)
-class AssetCreateView(AdminUserRequiredMixin, CreateView):
+class AssetCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = Asset
form_class = forms.AssetCreateForm
template_name = 'assets/asset_create.html'
@@ -87,6 +87,9 @@ class AssetCreateView(AdminUserRequiredMixin, CreateView):
kwargs.update(context)
return super().get_context_data(**kwargs)
+ def get_success_message(self, cleaned_data):
+ return create_success_msg % ({"name": cleaned_data["hostname"]})
+
class AssetModalListView(AdminUserRequiredMixin, ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
@@ -147,7 +150,7 @@ class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
return super().get_context_data(**kwargs)
-class AssetUpdateView(AdminUserRequiredMixin, UpdateView):
+class AssetUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
model = Asset
form_class = forms.AssetUpdateForm
template_name = 'assets/asset_update.html'
@@ -159,7 +162,10 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateView):
'action': _('Update asset'),
}
kwargs.update(context)
- return super(AssetUpdateView, self).get_context_data(**kwargs)
+ return super().get_context_data(**kwargs)
+
+ def get_success_message(self, cleaned_data):
+ return update_success_msg % ({"name": cleaned_data["hostname"]})
class AssetDeleteView(AdminUserRequiredMixin, DeleteView):
@@ -184,14 +190,14 @@ class AssetDetailView(DetailView):
'system_users_all': SystemUser.objects.all(),
}
kwargs.update(context)
- return super(AssetDetailView, self).get_context_data(**kwargs)
+ return super().get_context_data(**kwargs)
@method_decorator(csrf_exempt, name='dispatch')
class AssetExportView(View):
def get(self, request):
spm = request.GET.get('spm', '')
- assets_id_default = [Asset.objects.first().id] if Asset.objects.first() else [1]
+ assets_id_default = [Asset.objects.first().id] if Asset.objects.first() else []
assets_id = cache.get(spm, assets_id_default)
fields = [
field for field in Asset._meta.fields
diff --git a/apps/assets/views/cluster.py b/apps/assets/views/cluster.py
index f8540bed1..e1a2f6fba 100644
--- a/apps/assets/views/cluster.py
+++ b/apps/assets/views/cluster.py
@@ -1,17 +1,21 @@
# coding:utf-8
-from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView, SingleObjectMixin
+from django.contrib.messages.views import SuccessMessageMixin
+
+from common.const import create_success_msg, update_success_msg
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin
-__all__ = ['ClusterListView', 'ClusterCreateView', 'ClusterUpdateView',
- 'ClusterDetailView', 'ClusterDeleteView', 'ClusterAssetsView']
+__all__ = [
+ 'ClusterListView', 'ClusterCreateView', 'ClusterUpdateView',
+ 'ClusterDetailView', 'ClusterDeleteView', 'ClusterAssetsView',
+]
class ClusterListView(AdminUserRequiredMixin, TemplateView):
@@ -21,39 +25,40 @@ class ClusterListView(AdminUserRequiredMixin, TemplateView):
context = {
'app': _('Assets'),
'action': _('Cluster list'),
- # 'keyword': self.request.GET.get('keyword', '')
}
kwargs.update(context)
return super().get_context_data(**kwargs)
-class ClusterCreateView(AdminUserRequiredMixin, CreateView):
+class ClusterCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = Cluster
form_class = forms.ClusterForm
template_name = 'assets/cluster_create_update.html'
success_url = reverse_lazy('assets:cluster-list')
+ success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('assets'),
- 'action': _('Create Cluster'),
+ 'action': _('Create cluster'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
def form_valid(self, form):
cluster = form.save(commit=False)
- cluster.created_by = self.request.user.username or 'System'
+ cluster.created_by = self.request.user.username
cluster.save()
return super().form_valid(form)
-class ClusterUpdateView(AdminUserRequiredMixin, UpdateView):
+class ClusterUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
model = Cluster
form_class = forms.ClusterForm
template_name = 'assets/cluster_create_update.html'
context_object_name = 'cluster'
success_url = reverse_lazy('assets:cluster-list')
+ success_message = update_success_msg
def form_valid(self, form):
cluster = form.save(commit=False)
diff --git a/apps/assets/views/group.py b/apps/assets/views/group.py
index 5e87d9dc7..0ae65eaa0 100644
--- a/apps/assets/views/group.py
+++ b/apps/assets/views/group.py
@@ -7,42 +7,41 @@ from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateVi
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView, SingleObjectMixin
from django.shortcuts import get_object_or_404, reverse, redirect
+from django.contrib.messages.views import SuccessMessageMixin
+from common.const import create_success_msg, update_success_msg
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin
-__all__ = ['AssetGroupCreateView', 'AssetGroupDetailView',
- 'AssetGroupUpdateView', 'AssetGroupListView',
- 'AssetGroupDeleteView',
- ]
+__all__ = [
+ 'AssetGroupCreateView', 'AssetGroupDetailView',
+ 'AssetGroupUpdateView', 'AssetGroupListView',
+ 'AssetGroupDeleteView',
+]
-class AssetGroupCreateView(AdminUserRequiredMixin, CreateView):
+class AssetGroupCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = AssetGroup
form_class = forms.AssetGroupForm
template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list')
+ success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create asset group'),
- 'assets_count': 0,
}
kwargs.update(context)
- return super(AssetGroupCreateView, self).get_context_data(**kwargs)
+ return super().get_context_data(**kwargs)
def form_valid(self, form):
- asset_group = form.save()
- assets_id_list = self.request.POST.getlist('assets', [])
- assets = [get_object_or_404(Asset, id=int(asset_id))
- for asset_id in assets_id_list]
- asset_group.created_by = self.request.user.username or 'Admin'
- asset_group.assets.add(*tuple(assets))
- asset_group.save()
- return super(AssetGroupCreateView, self).form_valid(form)
+ group = form.save()
+ group.created_by = self.request.user.username
+ group.save()
+ return super().form_valid(form)
class AssetGroupListView(AdminUserRequiredMixin, TemplateView):
@@ -54,7 +53,6 @@ class AssetGroupListView(AdminUserRequiredMixin, TemplateView):
'action': _('Asset group list'),
'assets': Asset.objects.all(),
'system_users': SystemUser.objects.all(),
- 'keyword': self.request.GET.get('keyword', '')
}
kwargs.update(context)
return super(AssetGroupListView, self).get_context_data(**kwargs)
@@ -77,27 +75,20 @@ class AssetGroupDetailView(AdminUserRequiredMixin, DetailView):
return super().get_context_data(**kwargs)
-class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView):
+class AssetGroupUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
model = AssetGroup
form_class = forms.AssetGroupForm
template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list')
-
- def get(self, request, *args, **kwargs):
- self.object = self.get_object(queryset=AssetGroup.objects.all())
- return super(AssetGroupUpdateView, self).get(request, *args, **kwargs)
+ success_message = update_success_msg
def get_context_data(self, **kwargs):
- assets_all = self.object.assets.all()
context = {
'app': _('Assets'),
'action': _('Create asset group'),
- 'assets_on_list': assets_all,
- 'assets_count': len(assets_all),
- 'group_id': self.object.id,
}
kwargs.update(context)
- return super(AssetGroupUpdateView, self).get_context_data(**kwargs)
+ return super().get_context_data(**kwargs)
class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView):
diff --git a/apps/assets/views/system_user.py b/apps/assets/views/system_user.py
index 885ae12b7..f7e7eaa35 100644
--- a/apps/assets/views/system_user.py
+++ b/apps/assets/views/system_user.py
@@ -1,24 +1,23 @@
# ~*~ coding: utf-8 ~*~
-from django.contrib import messages
-from django.shortcuts import redirect, reverse
from django.utils.translation import ugettext as _
-from django.db import transaction
-from django.views.generic import TemplateView, ListView, FormView
+from django.views.generic import TemplateView
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin
-from django.views.generic.detail import DetailView, SingleObjectMixin
+from django.views.generic.detail import DetailView
-from ..forms import SystemUserForm, SystemUserUpdateForm, SystemUserAuthForm
+from common.const import create_success_msg, update_success_msg
+from ..forms import SystemUserForm, SystemUserUpdateForm
from ..models import SystemUser, Cluster
from ..hands import AdminUserRequiredMixin
-__all__ = ['SystemUserCreateView', 'SystemUserUpdateView',
- 'SystemUserDetailView', 'SystemUserDeleteView',
- 'SystemUserAssetView', 'SystemUserListView',
- ]
+__all__ = [
+ 'SystemUserCreateView', 'SystemUserUpdateView',
+ 'SystemUserDetailView', 'SystemUserDeleteView',
+ 'SystemUserAssetView', 'SystemUserListView',
+]
class SystemUserListView(AdminUserRequiredMixin, TemplateView):
@@ -38,10 +37,7 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
form_class = SystemUserForm
template_name = 'assets/system_user_create.html'
success_url = reverse_lazy('assets:system-user-list')
-
- @transaction.atomic
- def post(self, request, *args, **kwargs):
- return super(SystemUserCreateView, self).post(request, *args, **kwargs)
+ success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
@@ -51,20 +47,13 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
kwargs.update(context)
return super().get_context_data(**kwargs)
- def get_success_message(self, cleaned_data):
- url = reverse('assets:system-user-detail', kwargs={'pk': self.object.pk})
- success_message = _(
- 'Create system user {name} '
- 'successfully.'.format(url=url, name=self.object.name)
- )
- return success_message
-
-
-class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView):
+class SystemUserUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
model = SystemUser
form_class = SystemUserUpdateForm
template_name = 'assets/system_user_update.html'
+ success_url = reverse_lazy('assets:system-user-list')
+ success_message = update_success_msg
def get_context_data(self, **kwargs):
context = {
@@ -74,11 +63,6 @@ class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView):
kwargs.update(context)
return super().get_context_data(**kwargs)
- def get_success_url(self):
- success_url = reverse_lazy('assets:system-user-detail',
- kwargs={'pk': self.object.pk})
- return success_url
-
class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
template_name = 'assets/system_user_detail.html'
@@ -109,8 +93,8 @@ class SystemUserAssetView(AdminUserRequiredMixin, DetailView):
def get_context_data(self, **kwargs):
context = {
- 'app': 'assets',
- 'action': 'System user asset',
+ 'app': _('assets'),
+ 'action': _('System user asset'),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
diff --git a/apps/common/const.py b/apps/common/const.py
new file mode 100644
index 000000000..a28b0f1db
--- /dev/null
+++ b/apps/common/const.py
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+#
+
+from django.utils.translation import ugettext as _
+
+create_success_msg = _("%(name)s was created successfully")
+update_success_msg = _("%(name)s was updated successfully")
\ No newline at end of file
diff --git a/apps/common/utils.py b/apps/common/utils.py
index 733f91a18..753fdd541 100644
--- a/apps/common/utils.py
+++ b/apps/common/utils.py
@@ -287,10 +287,10 @@ def make_signature(access_key_secret, date=None):
return content_md5(data)
-def encrypt_password(password):
+def encrypt_password(password, salt=None):
from passlib.hash import sha512_crypt
if password:
- return sha512_crypt.using(rounds=5000).hash(password)
+ return sha512_crypt.using(rounds=5000).hash(password, salt=salt)
return None
diff --git a/apps/jumpserver/middleware.py b/apps/jumpserver/middleware.py
index f93edf73a..64accde21 100644
--- a/apps/jumpserver/middleware.py
+++ b/apps/jumpserver/middleware.py
@@ -4,24 +4,44 @@ import os
import re
import pytz
from django.utils import timezone
-from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
-DEMO_MODE = os.environ.get("DEMO_MODE", "")
-SAFE_URL = r'^/users/login|^/api/terminal/v1/.*|/api/terminal/.*|/api/users/v1/auth/|/api/users/v1/profile/'
+class TimezoneMiddleware:
+ def __init__(self, get_response):
+ self.get_response = get_response
-
-class TimezoneMiddleware(MiddlewareMixin):
- def process_request(self, request):
+ def __call__(self, request):
tzname = request.META.get('TZ')
if tzname:
timezone.activate(pytz.timezone(tzname))
else:
timezone.deactivate()
+ response = self.get_response(request)
+ return response
-class DemoMiddleware(MiddlewareMixin):
- def process_request(self, request):
- if DEMO_MODE and request.method not in ["GET", "HEAD"] and not re.match(SAFE_URL, request.path):
- return HttpResponse("Demo mode, only get request accept", status=403)
+class DemoMiddleware:
+ DEMO_MODE_ENABLED = os.environ.get("DEMO_MODE", "") in ("1", "ok", "True")
+ SAFE_URL_PATTERN = re.compile(
+ r'^/users/login|'
+ r'^/api/terminal/v1/.*|'
+ r'^/api/terminal/.*|'
+ r'^/api/users/v1/auth/|'
+ r'^/api/users/v1/profile/'
+ )
+ SAFE_METHOD = ("GET", "HEAD")
+
+ def __init__(self, get_response):
+ self.get_response = get_response
+
+ if self.DEMO_MODE_ENABLED:
+ print("Demo mode enabled, reject unsafe method and url")
+
+ def __call__(self, request):
+ if self.DEMO_MODE_ENABLED and request.method not in self.SAFE_METHOD \
+ and not self.SAFE_URL_PATTERN.match(request.path):
+ return HttpResponse("Demo mode, only safe request accepted", status=403)
+ else:
+ response = self.get_response(request)
+ return response
diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py
index 45c6fba88..ce2d06ed0 100644
--- a/apps/jumpserver/settings.py
+++ b/apps/jumpserver/settings.py
@@ -240,9 +240,8 @@ LOGGING = {
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
-LANGUAGE_CODE = 'en-us'
+LANGUAGE_CODE = 'zh-cn'
-# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
@@ -300,7 +299,8 @@ REST_FRAMEWORK = {
'users.authentication.SessionAuthentication',
),
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
- 'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S',
+ 'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S %z',
+ 'DATETIME_INPUT_FORMATS': ['%Y-%m-%d %H:%M:%S %z'],
}
AUTHENTICATION_BACKENDS = [
@@ -374,4 +374,5 @@ BOOTSTRAP3 = {
'horizontal_field_class': 'col-md-9',
# Set placeholder attributes to label if no placeholder is provided
'set_placeholder': True,
+ 'success_css_class': '',
}
diff --git a/apps/jumpserver/urls.py b/apps/jumpserver/urls.py
index 21d42d0dd..839492e7a 100644
--- a/apps/jumpserver/urls.py
+++ b/apps/jumpserver/urls.py
@@ -36,6 +36,6 @@ urlpatterns = [
if settings.DEBUG:
urlpatterns += [
url(r'^docs/', schema_view, name="docs"),
- ] + static(settings.STATIC_URL, document_root=settings.STATIC_DIR) \
+ ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) \
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index 64af76ad9..0e2eafee3 100644
Binary files a/apps/locale/zh/LC_MESSAGES/django.mo and b/apps/locale/zh/LC_MESSAGES/django.mo differ
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 1962f867a..a997277e8 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-01-01 15:33+0800\n"
+"POT-Creation-Date: 2018-01-10 00:30+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler \n"
"Language-Team: Jumpserver team\n"
@@ -17,8 +17,8 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: assets/forms.py:23 assets/forms.py:53 assets/forms.py:99 perms/forms.py:36
-#: perms/templates/perms/asset_permission_asset.html:127 users/forms.py:240
+#: assets/forms.py:23 assets/forms.py:53 assets/forms.py:99 perms/forms.py:37
+#: perms/templates/perms/asset_permission_asset.html:116 users/forms.py:242
msgid "Select asset groups"
msgstr "选择资产组"
@@ -36,19 +36,19 @@ msgstr "主机级别管理用户,如果没有设置则默认使用集群级别
#: assets/forms.py:40 assets/forms.py:68
msgid "You need set a admin user if cluster not have"
-msgstr ""
+msgstr "集群没有管理用户,你需要为集群设置管理用户或设置一个主机级别的管理用户"
#: assets/forms.py:54
msgid "Default using cluster admin user"
msgstr "默认使用管理用户"
#: assets/forms.py:76 assets/forms.py:81 assets/forms.py:127
-#: assets/templates/assets/asset_group_detail.html:70 perms/forms.py:33
-#: perms/templates/perms/asset_permission_asset.html:99 users/forms.py:237
+#: assets/templates/assets/asset_group_detail.html:70 perms/forms.py:34
+#: perms/templates/perms/asset_permission_asset.html:88 users/forms.py:239
msgid "Select assets"
msgstr "选择资产"
-#: assets/forms.py:86 assets/models/asset.py:45
+#: assets/forms.py:86 assets/models/asset.py:55
#: assets/templates/assets/admin_user_assets.html:61
#: assets/templates/assets/asset_detail.html:69
#: assets/templates/assets/asset_group_detail.html:47
@@ -56,12 +56,13 @@ msgstr "选择资产"
#: assets/templates/assets/cluster_assets.html:53
#: assets/templates/assets/system_user_asset.html:54
#: assets/templates/assets/user_asset_list.html:21
-#: perms/templates/perms/asset_permission_asset.html:56
#: users/templates/users/user_group_granted_asset.html:51
msgid "Port"
msgstr "端口"
-#: assets/forms.py:124 assets/templates/assets/asset_group_list.html:16
+#: assets/forms.py:124 assets/models/asset.py:171
+#: assets/templates/assets/admin_user_list.html:24
+#: assets/templates/assets/asset_group_list.html:16
#: assets/templates/assets/system_user_list.html:26 perms/models.py:17
#: perms/templates/perms/asset_permission_create_update.html:40
#: perms/templates/perms/asset_permission_list.html:28 templates/_nav.html:22
@@ -75,7 +76,22 @@ msgstr "端口"
msgid "Asset"
msgstr "资产"
-#: assets/forms.py:159 assets/forms.py:219 assets/forms.py:278
+#: assets/forms.py:161 perms/forms.py:40
+#: perms/templates/perms/asset_permission_detail.html:144 users/forms.py:245
+msgid "Select system users"
+msgstr "选择系统用户"
+
+#: assets/forms.py:163
+#: assets/templates/assets/_asset_group_bulk_update_modal.html:22
+#: assets/templates/assets/cluster_list.html:22
+msgid "System users"
+msgstr "系统用户"
+
+#: assets/forms.py:165
+msgid "Selected system users will be create at cluster assets"
+msgstr "选择的系统用户将会在该集群资产上创建"
+
+#: assets/forms.py:173 assets/forms.py:248 assets/forms.py:308
#: assets/models/cluster.py:18 assets/models/group.py:20
#: assets/models/user.py:28 assets/templates/assets/admin_user_detail.html:56
#: assets/templates/assets/admin_user_list.html:22
@@ -84,13 +100,13 @@ msgstr "资产"
#: assets/templates/assets/cluster_list.html:19
#: assets/templates/assets/system_user_detail.html:53
#: assets/templates/assets/system_user_list.html:24 ops/models.py:31
-#: ops/templates/ops/task_detail.html:56 ops/templates/ops/task_list.html:39
+#: ops/templates/ops/task_detail.html:56 ops/templates/ops/task_list.html:34
#: perms/models.py:14
#: perms/templates/perms/asset_permission_create_update.html:33
#: perms/templates/perms/asset_permission_detail.html:62
#: perms/templates/perms/asset_permission_list.html:25
#: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:14
-#: terminal/models.py:117 terminal/templates/terminal/terminal_detail.html:43
+#: terminal/models.py:118 terminal/templates/terminal/terminal_detail.html:43
#: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14
#: users/models/user.py:36 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_detail.html:62
@@ -104,19 +120,37 @@ msgstr "资产"
msgid "Name"
msgstr "名称"
-#: assets/forms.py:174
+#: assets/forms.py:179
+msgid "Cluster level admin user"
+msgstr "集群级别管理用户"
+
+#: assets/forms.py:200
msgid "Password or private key password"
msgstr "密码或秘钥不合法"
-#: assets/forms.py:202 assets/forms.py:260 assets/forms.py:321
+#: assets/forms.py:201 assets/forms.py:262 assets/models/user.py:30
+#: users/forms.py:16 users/forms.py:24 users/templates/users/login.html:56
+#: users/templates/users/reset_password.html:52
+#: users/templates/users/user_create.html:11
+#: users/templates/users/user_password_update.html:40
+#: users/templates/users/user_profile_update.html:40
+#: users/templates/users/user_pubkey_update.html:40
+msgid "Password"
+msgstr "密码"
+
+#: assets/forms.py:204 assets/forms.py:264 users/models/user.py:46
+msgid "Private key"
+msgstr "ssh私钥"
+
+#: assets/forms.py:229 assets/forms.py:290 assets/forms.py:354
msgid "Invalid private key"
msgstr "ssh密钥不合法"
-#: assets/forms.py:212
+#: assets/forms.py:240
msgid "Password and private key file must be input one"
msgstr "密码和私钥, 必须输入一个"
-#: assets/forms.py:220 assets/forms.py:279 assets/models/user.py:29
+#: assets/forms.py:249 assets/forms.py:309 assets/models/user.py:29
#: assets/templates/assets/admin_user_detail.html:60
#: assets/templates/assets/admin_user_list.html:23
#: assets/templates/assets/system_user_detail.html:57
@@ -132,59 +166,73 @@ msgstr "密码和私钥, 必须输入一个"
msgid "Username"
msgstr "用户名"
-#: assets/forms.py:267 assets/forms.py:327
+#: assets/forms.py:297 assets/forms.py:360
msgid "Auth info required, private_key or password"
msgstr "密钥和密码必须填写一个"
-#: assets/forms.py:282
+#: assets/forms.py:313
msgid " Select clusters"
msgstr "选择集群"
-#: assets/models/asset.py:24
+#: assets/forms.py:320
+msgid "If auto push checked, system user will be create at cluster assets"
+msgstr "如果选择了自动推送,系统用户将会创建在集群资产上"
+
+#: assets/forms.py:321
+msgid "Auto push system user to asset"
+msgstr "自动推送系统用户到资产"
+
+#: assets/forms.py:322
+msgid ""
+"High level will be using login asset as default, if user was granted more "
+"than 2 system user"
+msgstr "高优先级的系统用户将会作为默认登录用户"
+
+#: assets/models/asset.py:34
msgid "In use"
msgstr "使用中"
-#: assets/models/asset.py:25
+#: assets/models/asset.py:35
msgid "Out of use"
msgstr "未使用"
-#: assets/models/asset.py:28
+#: assets/models/asset.py:38
msgid "Server"
msgstr "物理机"
-#: assets/models/asset.py:29
+#: assets/models/asset.py:39
msgid "VM"
msgstr "虚拟机"
-#: assets/models/asset.py:30
+#: assets/models/asset.py:40
msgid "Switch"
msgstr "交换机"
-#: assets/models/asset.py:31
+#: assets/models/asset.py:41
msgid "Router"
msgstr "路由器"
-#: assets/models/asset.py:32
+#: assets/models/asset.py:42
msgid "Firewall"
msgstr "防火墙"
-#: assets/models/asset.py:33
+#: assets/models/asset.py:43
msgid "Storage"
msgstr "存储"
-#: assets/models/asset.py:36
+#: assets/models/asset.py:46
msgid "Production"
msgstr "生产环境"
-#: assets/models/asset.py:37
+#: assets/models/asset.py:47
msgid "Development"
msgstr "开发环境"
-#: assets/models/asset.py:38
+#: assets/models/asset.py:48
msgid "Testing"
msgstr "测试环境"
-#: assets/models/asset.py:43 assets/templates/assets/admin_user_assets.html:60
+#: assets/models/asset.py:53 assets/templates/assets/admin_user_assets.html:60
#: assets/templates/assets/asset_detail.html:61
#: assets/templates/assets/asset_group_detail.html:46
#: assets/templates/assets/asset_list.html:31
@@ -198,7 +246,7 @@ msgstr "测试环境"
msgid "IP"
msgstr "IP"
-#: assets/models/asset.py:44 assets/templates/assets/admin_user_assets.html:59
+#: assets/models/asset.py:54 assets/templates/assets/admin_user_assets.html:59
#: assets/templates/assets/asset_detail.html:57
#: assets/templates/assets/asset_group_detail.html:45
#: assets/templates/assets/asset_list.html:30
@@ -211,116 +259,116 @@ msgstr "IP"
msgid "Hostname"
msgstr "主机名"
-#: assets/models/asset.py:46 assets/templates/assets/asset_detail.html:213
-#: assets/views/asset.py:212 assets/views/asset.py:252
+#: assets/models/asset.py:56 assets/templates/assets/asset_detail.html:213
+#: assets/views/asset.py:218 assets/views/asset.py:258
msgid "Asset groups"
msgstr "资产组"
-#: assets/models/asset.py:47 assets/models/user.py:215
-#: assets/templates/assets/asset_detail.html:85
+#: assets/models/asset.py:57 assets/models/cluster.py:40
+#: assets/models/user.py:219 assets/templates/assets/asset_detail.html:85
#: assets/templates/assets/asset_list.html:33 templates/_nav.html:24
msgid "Cluster"
msgstr "集群"
-#: assets/models/asset.py:48 assets/templates/assets/asset_detail.html:129
+#: assets/models/asset.py:58 assets/templates/assets/asset_detail.html:129
msgid "Is active"
msgstr "激活"
-#: assets/models/asset.py:49 assets/templates/assets/asset_detail.html:133
+#: assets/models/asset.py:59 assets/templates/assets/asset_detail.html:133
msgid "Asset type"
msgstr "系统类型"
-#: assets/models/asset.py:50 assets/templates/assets/asset_detail.html:137
+#: assets/models/asset.py:60 assets/templates/assets/asset_detail.html:137
msgid "Asset environment"
msgstr "资产环境"
-#: assets/models/asset.py:51 assets/templates/assets/asset_detail.html:125
+#: assets/models/asset.py:61 assets/templates/assets/asset_detail.html:125
msgid "Asset status"
msgstr "资产状态"
-#: assets/models/asset.py:54 assets/models/cluster.py:19
-#: assets/templates/assets/asset_detail.html:73
+#: assets/models/asset.py:64 assets/models/cluster.py:19
+#: assets/models/user.py:190 assets/templates/assets/asset_detail.html:73
#: assets/templates/assets/cluster_list.html:20 templates/_nav.html:25
msgid "Admin user"
msgstr "管理用户"
-#: assets/models/asset.py:57 assets/templates/assets/asset_detail.html:65
+#: assets/models/asset.py:67 assets/templates/assets/asset_detail.html:65
msgid "Public IP"
msgstr "公网IP"
-#: assets/models/asset.py:58
+#: assets/models/asset.py:68
msgid "Remote control card IP"
msgstr "远控卡IP"
-#: assets/models/asset.py:59 assets/templates/assets/asset_detail.html:89
+#: assets/models/asset.py:69 assets/templates/assets/asset_detail.html:89
msgid "Cabinet number"
msgstr "机柜编号"
-#: assets/models/asset.py:60 assets/templates/assets/asset_detail.html:93
+#: assets/models/asset.py:70 assets/templates/assets/asset_detail.html:93
msgid "Cabinet position"
msgstr "机柜层号"
-#: assets/models/asset.py:61 assets/templates/assets/asset_detail.html:145
+#: assets/models/asset.py:71 assets/templates/assets/asset_detail.html:145
msgid "Asset number"
msgstr "资产编号"
-#: assets/models/asset.py:64 assets/templates/assets/asset_detail.html:97
+#: assets/models/asset.py:74 assets/templates/assets/asset_detail.html:97
msgid "Vendor"
msgstr "制造商"
-#: assets/models/asset.py:65 assets/templates/assets/asset_detail.html:101
+#: assets/models/asset.py:75 assets/templates/assets/asset_detail.html:101
msgid "Model"
msgstr "型号"
-#: assets/models/asset.py:66 assets/templates/assets/asset_detail.html:141
+#: assets/models/asset.py:76 assets/templates/assets/asset_detail.html:141
msgid "Serial number"
msgstr "序列号"
-#: assets/models/asset.py:68
+#: assets/models/asset.py:78
msgid "CPU model"
msgstr "CPU型号"
-#: assets/models/asset.py:69
+#: assets/models/asset.py:79
msgid "CPU count"
msgstr "CPU数量"
-#: assets/models/asset.py:70
+#: assets/models/asset.py:80
msgid "CPU cores"
msgstr "CPU核数"
-#: assets/models/asset.py:71 assets/templates/assets/asset_detail.html:109
+#: assets/models/asset.py:81 assets/templates/assets/asset_detail.html:109
msgid "Memory"
msgstr "内存"
-#: assets/models/asset.py:72
+#: assets/models/asset.py:82
msgid "Disk total"
msgstr "硬盘大小"
-#: assets/models/asset.py:73
+#: assets/models/asset.py:83
msgid "Disk info"
msgstr "硬盘信息"
-#: assets/models/asset.py:75 assets/templates/assets/asset_detail.html:117
+#: assets/models/asset.py:85 assets/templates/assets/asset_detail.html:117
msgid "Platform"
msgstr "系统平台"
-#: assets/models/asset.py:76 assets/templates/assets/asset_detail.html:121
+#: assets/models/asset.py:86 assets/templates/assets/asset_detail.html:121
msgid "OS"
msgstr "操作系统"
-#: assets/models/asset.py:77
+#: assets/models/asset.py:87
msgid "OS version"
msgstr "系统版本"
-#: assets/models/asset.py:78
+#: assets/models/asset.py:88
msgid "OS arch"
msgstr "系统架构"
-#: assets/models/asset.py:79
+#: assets/models/asset.py:89
msgid "Hostname raw"
msgstr "主机名原始"
-#: assets/models/asset.py:81 assets/models/cluster.py:28
+#: assets/models/asset.py:91 assets/models/cluster.py:28
#: assets/models/group.py:21 assets/models/user.py:36
#: assets/templates/assets/admin_user_detail.html:68
#: assets/templates/assets/asset_detail.html:149
@@ -332,7 +380,7 @@ msgstr "主机名原始"
msgid "Created by"
msgstr "创建者"
-#: assets/models/asset.py:82 assets/models/cluster.py:26
+#: assets/models/asset.py:92 assets/models/cluster.py:26
#: assets/models/group.py:22 assets/templates/assets/admin_user_detail.html:64
#: assets/templates/assets/cluster_detail.html:89
#: assets/templates/assets/system_user_detail.html:87
@@ -343,10 +391,10 @@ msgstr "创建者"
msgid "Date created"
msgstr "创建日期"
-#: assets/models/asset.py:83 assets/models/cluster.py:29
+#: assets/models/asset.py:93 assets/models/cluster.py:29
#: assets/models/group.py:23 assets/models/user.py:33
#: assets/templates/assets/admin_user_detail.html:72
-#: assets/templates/assets/admin_user_list.html:26
+#: assets/templates/assets/admin_user_list.html:28
#: assets/templates/assets/asset_detail.html:157
#: assets/templates/assets/asset_group_list.html:17
#: assets/templates/assets/cluster_detail.html:97
@@ -391,11 +439,11 @@ msgstr "外网"
msgid "Operator"
msgstr "运营商"
-#: assets/models/cluster.py:36 assets/models/group.py:33
+#: assets/models/cluster.py:36 assets/models/group.py:34
msgid "Default"
msgstr "默认"
-#: assets/models/cluster.py:36 users/models/user.py:259
+#: assets/models/cluster.py:36 users/models/user.py:263
msgid "System"
msgstr "系统"
@@ -403,20 +451,15 @@ msgstr "系统"
msgid "Default Cluster"
msgstr "默认Cluster"
-#: assets/models/group.py:33
+#: assets/models/group.py:30 perms/models.py:18
+#: perms/templates/perms/asset_permission_list.html:29 templates/_nav.html:23
+msgid "Asset group"
+msgstr "资产组"
+
+#: assets/models/group.py:34
msgid "Default asset group"
msgstr "默认资产组"
-#: assets/models/user.py:30 users/forms.py:16 users/forms.py:24
-#: users/templates/users/login.html:56
-#: users/templates/users/reset_password.html:52
-#: users/templates/users/user_create.html:11
-#: users/templates/users/user_password_update.html:40
-#: users/templates/users/user_profile_update.html:40
-#: users/templates/users/user_pubkey_update.html:40
-msgid "Password"
-msgstr "密码"
-
#: assets/models/user.py:31
msgid "SSH private key"
msgstr "ssh密钥"
@@ -425,42 +468,55 @@ msgstr "ssh密钥"
msgid "SSH public key"
msgstr "ssh公钥"
-#: assets/models/user.py:216
+#: assets/models/user.py:220
msgid "Priority"
-msgstr ""
+msgstr "优先级"
-#: assets/models/user.py:217 assets/templates/assets/system_user_detail.html:61
+#: assets/models/user.py:221 assets/templates/assets/system_user_detail.html:61
msgid "Protocol"
msgstr "协议"
-#: assets/models/user.py:218 assets/templates/assets/_system_user.html:59
+#: assets/models/user.py:222 assets/templates/assets/_system_user.html:59
#: assets/templates/assets/system_user_detail.html:113
#: assets/templates/assets/system_user_update.html:11
msgid "Auto push"
msgstr "自动推送"
-#: assets/models/user.py:219 assets/templates/assets/system_user_detail.html:65
+#: assets/models/user.py:223 assets/templates/assets/system_user_detail.html:65
msgid "Sudo"
msgstr "Sudo"
-#: assets/models/user.py:220 assets/templates/assets/system_user_detail.html:70
+#: assets/models/user.py:224 assets/templates/assets/system_user_detail.html:70
msgid "Shell"
msgstr "Shell"
+#: assets/models/user.py:269 perms/models.py:19
+#: perms/templates/perms/asset_permission_detail.html:136
+#: perms/templates/perms/asset_permission_list.html:30 templates/_nav.html:26
+#: terminal/backends/command/models.py:12 terminal/models.py:94
+#: terminal/templates/terminal/command_list.html:48
+#: terminal/templates/terminal/command_list.html:74
+#: terminal/templates/terminal/session_list.html:49
+#: terminal/templates/terminal/session_list.html:73
+#: users/templates/users/user_granted_asset.html:50
+#: users/templates/users/user_group_granted_asset.html:52
+msgid "System user"
+msgstr "系统用户"
+
#: assets/models/utils.py:29
#, python-format
msgid "%(value)s is not an even number"
msgstr "%(value)s is not an even number"
-#: assets/signals_handler.py:31
+#: assets/signals_handler.py:32
msgid "Push cluster system users to asset"
msgstr "推送集群系统用户到资产"
-#: assets/signals_handler.py:63 assets/signals_handler.py:125
+#: assets/signals_handler.py:64 assets/signals_handler.py:126
msgid "Push system user to cluster assets: {}->{}"
msgstr "推送系统用户到: {}->{}"
-#: assets/signals_handler.py:102
+#: assets/signals_handler.py:103
msgid "Push system user to assets"
msgstr "推送系统用户到资产"
@@ -478,23 +534,31 @@ msgstr "定期更新资产硬件信息"
#: assets/tasks.py:189
msgid "Test admin user connectability period: {}"
-msgstr "定期测试管理用户可以连接性"
+msgstr "定期测试管理用户可连接性: {}"
#: assets/tasks.py:203
msgid "Test admin user connectability: {}"
msgstr "测试管理用户可连接性: {}"
-#: assets/tasks.py:289
-msgid "Test system user connectability period: {}"
+#: assets/tasks.py:212
+msgid "Test asset connectability"
+msgstr "测试资产可连接性"
+
+#: assets/tasks.py:283
+msgid "Test system user connectability: {}"
msgstr "测试系统用户可连接性: {}"
-#: assets/tasks.py:363
+#: assets/tasks.py:295
+msgid "Test system user connectability period: {}"
+msgstr "定期测试系统用户可连接性: {}"
+
+#: assets/tasks.py:376
msgid "Push system user to cluster assets: {}"
msgstr "推送系统用户到资产: {}"
-#: assets/tasks.py:384
-msgid "Push system user to cluster assets period: {}->{}"
-msgstr "定期推送系统用户到资产: {}->{}"
+#: assets/tasks.py:397
+msgid "Push cluster system users to assets period: {}"
+msgstr "定期推送集群系统用户到资产: {}"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:5
msgid "Update asset group"
@@ -506,16 +570,16 @@ msgstr "仅修改你需要更新的字段"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:12
#: assets/templates/assets/system_user_asset.html:21
-#: assets/views/admin_user.py:27 assets/views/admin_user.py:44
-#: assets/views/admin_user.py:67 assets/views/admin_user.py:88
-#: assets/views/admin_user.py:115 assets/views/asset.py:47
-#: assets/views/asset.py:61 assets/views/asset.py:84 assets/views/asset.py:141
-#: assets/views/asset.py:158 assets/views/asset.py:179
-#: assets/views/cluster.py:22 assets/views/cluster.py:80
-#: assets/views/cluster.py:97 assets/views/group.py:30 assets/views/group.py:53
-#: assets/views/group.py:71 assets/views/group.py:93
-#: assets/views/system_user.py:29 assets/views/system_user.py:48
-#: assets/views/system_user.py:71 assets/views/system_user.py:91
+#: assets/views/admin_user.py:29 assets/views/admin_user.py:47
+#: assets/views/admin_user.py:63 assets/views/admin_user.py:79
+#: assets/views/admin_user.py:106 assets/views/asset.py:48
+#: assets/views/asset.py:61 assets/views/asset.py:84 assets/views/asset.py:144
+#: assets/views/asset.py:161 assets/views/asset.py:185
+#: assets/views/cluster.py:26 assets/views/cluster.py:85
+#: assets/views/cluster.py:102 assets/views/group.py:34
+#: assets/views/group.py:52 assets/views/group.py:69 assets/views/group.py:87
+#: assets/views/system_user.py:28 assets/views/system_user.py:44
+#: assets/views/system_user.py:60 assets/views/system_user.py:75
#: templates/_nav.html:19
msgid "Assets"
msgstr "资产管理"
@@ -524,11 +588,6 @@ msgstr "资产管理"
msgid "Select Asset"
msgstr "选择资产"
-#: assets/templates/assets/_asset_group_bulk_update_modal.html:22
-#: assets/templates/assets/cluster_list.html:22
-msgid "System users"
-msgstr "系统用户"
-
#: assets/templates/assets/_asset_group_bulk_update_modal.html:24
msgid "Select System Users"
msgstr "选择系统用户"
@@ -561,7 +620,7 @@ msgstr "如果设置了id,则会使用该行信息更新该id的资产"
#: assets/templates/assets/_system_user.html:16
#: assets/templates/assets/system_user_list.html:16
-#: assets/views/system_user.py:49
+#: assets/views/system_user.py:45
msgid "Create system user"
msgstr "创建系统用户"
@@ -588,7 +647,7 @@ msgstr "自动生成秘钥"
#: assets/templates/assets/_system_user.html:65
#: assets/templates/assets/asset_create.html:32
#: assets/templates/assets/asset_update.html:47
-#: assets/templates/assets/cluster_create_update.html:45
+#: assets/templates/assets/cluster_create_update.html:46
#: perms/templates/perms/asset_permission_create_update.html:45
#: terminal/templates/terminal/terminal_update.html:40
msgid "Other"
@@ -598,8 +657,9 @@ msgstr "其它"
#: assets/templates/assets/admin_user_create_update.html:45
#: assets/templates/assets/asset_bulk_update.html:23
#: assets/templates/assets/asset_create.html:40
-#: assets/templates/assets/asset_update.html:56
-#: assets/templates/assets/cluster_create_update.html:53
+#: assets/templates/assets/asset_group_create.html:16
+#: assets/templates/assets/asset_update.html:55
+#: assets/templates/assets/cluster_create_update.html:54
#: perms/templates/perms/asset_permission_create_update.html:67
#: terminal/templates/terminal/terminal_update.html:45
#: users/templates/users/_user.html:49
@@ -616,9 +676,10 @@ msgstr "重置"
#: assets/templates/assets/admin_user_create_update.html:46
#: assets/templates/assets/asset_bulk_update.html:24
#: assets/templates/assets/asset_create.html:41
+#: assets/templates/assets/asset_group_create.html:17
#: assets/templates/assets/asset_list.html:55
-#: assets/templates/assets/asset_update.html:57
-#: assets/templates/assets/cluster_create_update.html:54
+#: assets/templates/assets/asset_update.html:56
+#: assets/templates/assets/cluster_create_update.html:55
#: perms/templates/perms/asset_permission_create_update.html:68
#: terminal/templates/terminal/terminal_update.html:46
#: users/templates/users/_user.html:50
@@ -652,6 +713,52 @@ msgstr "详情"
msgid "Assets list"
msgstr "资产列表"
+#: assets/templates/assets/admin_user_assets.html:24
+#: assets/templates/assets/admin_user_detail.html:24
+#: assets/templates/assets/admin_user_list.html:83
+#: assets/templates/assets/asset_detail.html:24
+#: assets/templates/assets/asset_group_detail.html:18
+#: assets/templates/assets/asset_group_detail.html:172
+#: assets/templates/assets/asset_group_list.html:42
+#: assets/templates/assets/asset_list.html:95
+#: assets/templates/assets/cluster_assets.html:170
+#: assets/templates/assets/cluster_detail.html:25
+#: assets/templates/assets/cluster_list.html:43
+#: assets/templates/assets/system_user_asset.html:25
+#: assets/templates/assets/system_user_detail.html:26
+#: assets/templates/assets/system_user_list.html:84
+#: perms/templates/perms/asset_permission_detail.html:30
+#: perms/templates/perms/asset_permission_list.html:73
+#: terminal/templates/terminal/terminal_detail.html:16
+#: terminal/templates/terminal/terminal_list.html:71
+#: users/templates/users/user_detail.html:25
+#: users/templates/users/user_group_detail.html:28
+#: users/templates/users/user_group_list.html:39
+#: users/templates/users/user_list.html:76
+msgid "Update"
+msgstr "更新"
+
+#: assets/templates/assets/admin_user_assets.html:28
+#: assets/templates/assets/admin_user_detail.html:28
+#: assets/templates/assets/admin_user_list.html:84
+#: assets/templates/assets/asset_detail.html:28
+#: assets/templates/assets/asset_group_list.html:43
+#: assets/templates/assets/asset_list.html:96
+#: assets/templates/assets/cluster_detail.html:29
+#: assets/templates/assets/cluster_list.html:44
+#: assets/templates/assets/system_user_list.html:85
+#: ops/templates/ops/task_list.html:71
+#: perms/templates/perms/asset_permission_detail.html:34
+#: perms/templates/perms/asset_permission_list.html:74
+#: terminal/templates/terminal/terminal_list.html:73
+#: users/templates/users/user_detail.html:29
+#: users/templates/users/user_group_detail.html:32
+#: users/templates/users/user_group_list.html:41
+#: users/templates/users/user_list.html:80
+#: users/templates/users/user_list.html:84
+msgid "Delete"
+msgstr "删除"
+
#: assets/templates/assets/admin_user_assets.html:37
#: assets/templates/assets/asset_group_detail.html:26
#: perms/templates/perms/asset_permission_asset.html:35
@@ -668,11 +775,13 @@ msgid "Type"
msgstr "类型"
#: assets/templates/assets/admin_user_assets.html:63
-#: assets/templates/assets/asset_group_detail.html:49
-#: assets/templates/assets/cluster_assets.html:55
-#: terminal/templates/terminal/terminal_list.html:35
-msgid "Alive"
-msgstr "在线"
+#: assets/templates/assets/admin_user_list.html:25
+#: assets/templates/assets/asset_detail.html:376
+#: assets/templates/assets/asset_list.html:38
+#: assets/templates/assets/system_user_asset.html:55
+#: assets/templates/assets/system_user_list.html:27
+msgid "Reachable"
+msgstr "可连接"
#: assets/templates/assets/admin_user_assets.html:75
#: assets/templates/assets/cluster_assets.html:68
@@ -699,7 +808,7 @@ msgstr "任务已下发,查看左侧资产状态"
#: assets/templates/assets/admin_user_create_update.html:16
#: assets/templates/assets/admin_user_list.html:14
-#: assets/views/admin_user.py:45
+#: assets/views/admin_user.py:48
msgid "Create admin user"
msgstr "创建管理用户"
@@ -709,7 +818,7 @@ msgstr "使用集群管理用户"
#: assets/templates/assets/admin_user_detail.html:101
#: assets/templates/assets/asset_detail.html:230
-#: assets/templates/assets/asset_group_list.html:87
+#: assets/templates/assets/asset_group_list.html:85
#: assets/templates/assets/asset_list.html:202
#: assets/templates/assets/cluster_assets.html:104
#: assets/templates/assets/cluster_list.html:89
@@ -719,25 +828,26 @@ msgstr "使用集群管理用户"
#: users/templates/users/user_detail.html:338
#: users/templates/users/user_detail.html:363
#: users/templates/users/user_detail.html:386
-#: users/templates/users/user_group_create_update.html:46
+#: users/templates/users/user_group_create_update.html:32
#: users/templates/users/user_group_list.html:82
#: users/templates/users/user_list.html:184
#: users/templates/users/user_profile.html:181
msgid "Confirm"
msgstr "确认"
-#: assets/templates/assets/admin_user_list.html:24
-#: assets/templates/assets/cluster_list.html:21
-#: users/templates/users/_select_user_modal.html:17
-msgid "Asset num"
-msgstr "资产数量"
-
-#: assets/templates/assets/admin_user_list.html:25
+#: assets/templates/assets/admin_user_list.html:26
#: assets/templates/assets/system_user_list.html:28
msgid "Unreachable"
msgstr "不可达"
#: assets/templates/assets/admin_user_list.html:27
+#: assets/templates/assets/system_user_list.html:29
+#: ops/templates/ops/adhoc_history.html:54
+#: ops/templates/ops/task_history.html:57
+msgid "Ratio"
+msgstr "比例"
+
+#: assets/templates/assets/admin_user_list.html:29
#: assets/templates/assets/asset_group_detail.html:50
#: assets/templates/assets/asset_group_list.html:18
#: assets/templates/assets/asset_list.html:39
@@ -746,50 +856,22 @@ msgstr "不可达"
#: assets/templates/assets/system_user_list.html:31
#: assets/templates/assets/user_asset_list.html:27
#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:61
-#: ops/templates/ops/task_history.html:62 ops/templates/ops/task_list.html:46
+#: ops/templates/ops/task_history.html:62 ops/templates/ops/task_list.html:41
#: perms/templates/perms/asset_permission_list.html:32
-#: terminal/templates/terminal/session_list.html:78
+#: terminal/templates/terminal/session_list.html:79
#: terminal/templates/terminal/terminal_list.html:36
#: users/templates/users/user_group_list.html:15
#: users/templates/users/user_list.html:28
msgid "Action"
msgstr "动作"
-#: assets/templates/assets/admin_user_list.html:47
-#: assets/templates/assets/asset_group_detail.html:172
-#: assets/templates/assets/asset_group_list.html:42
-#: assets/templates/assets/asset_list.html:95
-#: assets/templates/assets/cluster_assets.html:170
-#: assets/templates/assets/cluster_list.html:43
-#: assets/templates/assets/system_user_list.html:84
-#: perms/templates/perms/asset_permission_list.html:73
-#: terminal/templates/terminal/terminal_list.html:71
-#: users/templates/users/user_group_list.html:39
-#: users/templates/users/user_list.html:76
-msgid "Update"
-msgstr "更新"
-
-#: assets/templates/assets/admin_user_list.html:48
-#: assets/templates/assets/asset_group_list.html:43
-#: assets/templates/assets/asset_list.html:96
-#: assets/templates/assets/cluster_list.html:44
-#: assets/templates/assets/system_user_list.html:85
-#: ops/templates/ops/task_list.html:76
-#: perms/templates/perms/asset_permission_list.html:74
-#: terminal/templates/terminal/terminal_list.html:73
-#: users/templates/users/user_group_list.html:41
-#: users/templates/users/user_list.html:80
-#: users/templates/users/user_list.html:84
-msgid "Delete"
-msgstr "删除"
-
#: assets/templates/assets/asset_create.html:28
#: assets/templates/assets/asset_update.html:33
msgid "Group"
msgstr "组"
-#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:180
-#: assets/views/cluster.py:98
+#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:186
+#: assets/views/cluster.py:103
msgid "Asset detail"
msgstr "资产详情"
@@ -822,6 +904,7 @@ msgstr "快速修改"
#: assets/templates/assets/asset_list.html:37
#: assets/templates/assets/user_asset_list.html:25 perms/models.py:20
#: perms/templates/perms/asset_permission_create_update.html:47
+#: perms/templates/perms/asset_permission_detail.html:116
#: terminal/templates/terminal/terminal_list.html:34
#: users/templates/users/_select_user_modal.html:18
#: users/templates/users/user_detail.html:127
@@ -847,26 +930,25 @@ msgstr "添加到资产组"
msgid "Update successfully!"
msgstr "更新成功"
-#: assets/templates/assets/asset_detail.html:376
-#: assets/templates/assets/asset_list.html:38
-#: assets/templates/assets/system_user_asset.html:55
-#: assets/templates/assets/system_user_list.html:27
-msgid "Reachable"
-msgstr "可连接"
-
#: assets/templates/assets/asset_group_detail.html:16
msgid "Group assets"
msgstr "组下资产"
+#: assets/templates/assets/asset_group_detail.html:49
+#: assets/templates/assets/cluster_assets.html:55
+#: terminal/templates/terminal/terminal_list.html:35
+msgid "Alive"
+msgstr "在线"
+
#: assets/templates/assets/asset_group_detail.html:62
msgid "Add assets to this group"
msgstr "添加资产到该组"
#: assets/templates/assets/asset_group_detail.html:79
-#: perms/templates/perms/asset_permission_asset.html:108
+#: perms/templates/perms/asset_permission_asset.html:97
#: perms/templates/perms/asset_permission_detail.html:153
-#: perms/templates/perms/asset_permission_user.html:108
-#: perms/templates/perms/asset_permission_user.html:136
+#: perms/templates/perms/asset_permission_user.html:97
+#: perms/templates/perms/asset_permission_user.html:125
#: users/templates/users/user_group_detail.html:95
msgid "Add"
msgstr "添加"
@@ -875,12 +957,12 @@ msgstr "添加"
msgid "Remove"
msgstr "移除"
-#: assets/templates/assets/asset_group_list.html:7 assets/views/group.py:31
-#: assets/views/group.py:94
+#: assets/templates/assets/asset_group_list.html:7 assets/views/group.py:35
+#: assets/views/group.py:88
msgid "Create asset group"
msgstr "创建资产组"
-#: assets/templates/assets/asset_group_list.html:82
+#: assets/templates/assets/asset_group_list.html:80
#: assets/templates/assets/asset_list.html:197
#: assets/templates/assets/cluster_list.html:84
#: assets/templates/assets/system_user_list.html:129
@@ -891,29 +973,29 @@ msgstr "创建资产组"
msgid "Are you sure?"
msgstr "你确认吗?"
-#: assets/templates/assets/asset_group_list.html:83
+#: assets/templates/assets/asset_group_list.html:81
#: users/templates/users/user_group_list.html:78
msgid "This will delete the selected groups !!!"
msgstr "删除选择组"
-#: assets/templates/assets/asset_group_list.html:91
+#: assets/templates/assets/asset_group_list.html:89
msgid "Group deleted"
msgstr "组已被删除"
-#: assets/templates/assets/asset_group_list.html:92
-#: assets/templates/assets/asset_group_list.html:97
+#: assets/templates/assets/asset_group_list.html:90
+#: assets/templates/assets/asset_group_list.html:95
msgid "Group Delete"
msgstr "删除"
-#: assets/templates/assets/asset_group_list.html:96
+#: assets/templates/assets/asset_group_list.html:94
msgid "Group deleting failed."
msgstr "删除失败"
-#: assets/templates/assets/asset_group_list.html:159
+#: assets/templates/assets/asset_group_list.html:157
msgid "The selected asset groups has been updated successfully."
msgstr "更新成功"
-#: assets/templates/assets/asset_group_list.html:160
+#: assets/templates/assets/asset_group_list.html:158
msgid "AssetGroup Updated"
msgstr "资产组更新"
@@ -1000,7 +1082,7 @@ msgid "Test assets connective"
msgstr "测试资产可连接性"
#: assets/templates/assets/cluster_assets.html:77
-#: ops/templates/ops/task_list.html:75
+#: ops/templates/ops/task_list.html:70
msgid "Run"
msgstr "执行"
@@ -1012,14 +1094,20 @@ msgstr "添加资产到"
msgid "Select asset"
msgstr "选择资产"
+#: assets/templates/assets/cluster_assets.html:211
+#: assets/templates/assets/system_user_asset.html:162
+msgid "Task has been send, seen left assets status"
+msgstr "任务已下发,查看左侧资产状态"
+
#: assets/templates/assets/cluster_create_update.html:41
#: users/templates/users/user_profile.html:20
msgid "Settings"
msgstr "设置"
-#: assets/templates/assets/cluster_list.html:11 assets/views/cluster.py:39
-msgid "Create Cluster"
-msgstr "创建Cluster"
+#: assets/templates/assets/cluster_list.html:21
+#: users/templates/users/_select_user_modal.html:17
+msgid "Asset num"
+msgstr "资产数量"
#: assets/templates/assets/cluster_list.html:85
msgid "This will delete the selected cluster"
@@ -1064,10 +1152,6 @@ msgstr "推送"
msgid "Task has been send, Go to ops task list seen result"
msgstr "任务已下发,查看ops任务列表"
-#: assets/templates/assets/system_user_asset.html:162
-msgid "Task has been send, seen left assets status"
-msgstr "任务已下发,查看左侧资产状态"
-
#: assets/templates/assets/system_user_detail.html:22
msgid "Attached assets"
msgstr "关联的资产"
@@ -1088,12 +1172,6 @@ msgstr "集群"
msgid "Add to cluster"
msgstr "添加到集群"
-#: assets/templates/assets/system_user_list.html:29
-#: ops/templates/ops/adhoc_history.html:54
-#: ops/templates/ops/task_history.html:57
-msgid "Ratio"
-msgstr "比例"
-
#: assets/templates/assets/system_user_list.html:130
msgid "This will delete the selected System Users !!!"
msgstr "删除选择系统用户"
@@ -1115,84 +1193,93 @@ msgstr "系统用户删除失败"
msgid "Connective"
msgstr "连接性"
-#: assets/templates/assets/user_asset_list.html:66
+#: assets/templates/assets/user_asset_list.html:65
msgid "Connect"
msgstr "连接"
-#: assets/views/admin_user.py:28
+#: assets/views/admin_user.py:30
msgid "Admin user list"
msgstr "管理用户列表"
-#: assets/views/admin_user.py:52
-#, python-brace-format
-msgid "Create admin user {name} successfully."
-msgstr "创建管理用户 {name} 成功"
-
-#: assets/views/admin_user.py:68
+#: assets/views/admin_user.py:64
msgid "Update admin user"
msgstr "更新管理用户"
-#: assets/views/admin_user.py:89 assets/views/admin_user.py:116
+#: assets/views/admin_user.py:80 assets/views/admin_user.py:107
msgid "Admin user detail"
msgstr "管理用户详情"
-#: assets/views/asset.py:48 assets/views/asset.py:62
+#: assets/views/asset.py:49 assets/views/asset.py:62
msgid "Asset list"
msgstr "资产列表"
-#: assets/views/asset.py:142
+#: assets/views/asset.py:145
msgid "Bulk update asset"
msgstr "批量更新资产"
-#: assets/views/asset.py:159
+#: assets/views/asset.py:162
msgid "Update asset"
msgstr "编辑资产"
-#: assets/views/asset.py:292
+#: assets/views/asset.py:298
msgid "already exists"
msgstr "已经存在"
-#: assets/views/cluster.py:23
+#: assets/views/cluster.py:27
msgid "Cluster list"
msgstr "集群列表"
-#: assets/views/cluster.py:38 assets/views/cluster.py:65
+#: assets/views/cluster.py:42 assets/views/cluster.py:70
+#: assets/views/system_user.py:96
msgid "assets"
msgstr "资产管理"
-#: assets/views/cluster.py:66
+#: assets/views/cluster.py:43
+msgid "Create cluster"
+msgstr "创建集群"
+
+#: assets/views/cluster.py:71
msgid "Update Cluster"
msgstr "更新Cluster"
-#: assets/views/cluster.py:81
+#: assets/views/cluster.py:86
msgid "Cluster detail"
msgstr "集群详情"
-#: assets/views/group.py:54
+#: assets/views/group.py:53
msgid "Asset group list"
msgstr "资产组列表"
-#: assets/views/group.py:72
+#: assets/views/group.py:70
msgid "Asset group detail"
msgstr "资产组详情"
-#: assets/views/system_user.py:30
+#: assets/views/system_user.py:29
msgid "System user list"
msgstr "系统用户列表"
-#: assets/views/system_user.py:57
-#, python-brace-format
-msgid "Create system user {name} successfully."
-msgstr "创建系统用户 {name} 成功"
-
-#: assets/views/system_user.py:72
+#: assets/views/system_user.py:61
msgid "Update system user"
msgstr "更新系统用户"
-#: assets/views/system_user.py:92
+#: assets/views/system_user.py:76
msgid "System user detail"
msgstr "系统用户详情"
+#: assets/views/system_user.py:97
+msgid "System user asset"
+msgstr "系统用户集群资产"
+
+#: common/const.py:6
+#, python-format
+msgid "%(name)s was created successfully"
+msgstr "%(name)s 创建成功"
+
+#: common/const.py:7
+#, python-format
+msgid "%(name)s was updated successfully"
+msgstr "%(name)s 更新成功"
+
#: common/mixins.py:29
msgid "is discard"
msgstr ""
@@ -1235,7 +1322,7 @@ msgid "Options"
msgstr "选项"
#: ops/models.py:152 ops/templates/ops/adhoc_detail.html:53
-#: ops/templates/ops/task_adhoc.html:56 ops/templates/ops/task_list.html:42
+#: ops/templates/ops/task_adhoc.html:56 ops/templates/ops/task_list.html:37
msgid "Hosts"
msgstr "主机"
@@ -1257,36 +1344,36 @@ msgstr "Become"
msgid "Create by"
msgstr "创建者"
-#: ops/models.py:306
+#: ops/models.py:307
msgid "Start time"
msgstr "开始时间"
-#: ops/models.py:307
+#: ops/models.py:308
msgid "End time"
msgstr "完成时间"
-#: ops/models.py:308 ops/templates/ops/adhoc_history.html:57
-#: ops/templates/ops/task_history.html:60 ops/templates/ops/task_list.html:45
+#: ops/models.py:309 ops/templates/ops/adhoc_history.html:57
+#: ops/templates/ops/task_history.html:60 ops/templates/ops/task_list.html:40
msgid "Time"
msgstr "时间"
-#: ops/models.py:309 ops/templates/ops/adhoc_detail.html:106
+#: ops/models.py:310 ops/templates/ops/adhoc_detail.html:106
#: ops/templates/ops/adhoc_history.html:55
#: ops/templates/ops/adhoc_history_detail.html:66
#: ops/templates/ops/task_detail.html:80 ops/templates/ops/task_history.html:58
msgid "Is finished"
msgstr "是否完成"
-#: ops/models.py:310 ops/templates/ops/adhoc_history.html:56
+#: ops/models.py:311 ops/templates/ops/adhoc_history.html:56
#: ops/templates/ops/task_history.html:59
msgid "Is success"
msgstr "是否成功"
-#: ops/models.py:311
+#: ops/models.py:312
msgid "Adhoc raw result"
msgstr "结果"
-#: ops/models.py:312
+#: ops/models.py:313
msgid "Adhoc result summary"
msgstr "汇总"
@@ -1296,7 +1383,7 @@ msgid "Version detail"
msgstr "版本详情"
#: ops/templates/ops/adhoc_detail.html:22
-#: ops/templates/ops/adhoc_history.html:22 ops/views.py:120
+#: ops/templates/ops/adhoc_history.html:22 ops/views.py:105
msgid "Version run history"
msgstr "执行历史"
@@ -1308,7 +1395,7 @@ msgstr "执行历史"
msgid "ID"
msgstr "ID"
-#: ops/templates/ops/adhoc_detail.html:94 ops/templates/ops/task_list.html:40
+#: ops/templates/ops/adhoc_detail.html:94 ops/templates/ops/task_list.html:35
msgid "Run times"
msgstr "执行次数"
@@ -1352,8 +1439,8 @@ msgstr "执行历史"
#: ops/templates/ops/adhoc_history.html:52
#: ops/templates/ops/adhoc_history_detail.html:58
-#: ops/templates/ops/task_history.html:55 terminal/models.py:100
-#: terminal/templates/terminal/session_list.html:76
+#: ops/templates/ops/task_history.html:55 terminal/models.py:101
+#: terminal/templates/terminal/session_list.html:77
msgid "Date start"
msgstr "开始日期"
@@ -1368,7 +1455,7 @@ msgstr "失败/成功/总"
msgid "Version"
msgstr "版本"
-#: ops/templates/ops/adhoc_history_detail.html:19 ops/views.py:133
+#: ops/templates/ops/adhoc_history_detail.html:19 ops/views.py:118
msgid "Run history detail"
msgstr "执行历史详情"
@@ -1394,12 +1481,12 @@ msgid "Success assets"
msgstr "成功资产"
#: ops/templates/ops/task_adhoc.html:19 ops/templates/ops/task_detail.html:19
-#: ops/templates/ops/task_history.html:19 ops/views.py:58
+#: ops/templates/ops/task_history.html:19 ops/views.py:53
msgid "Task detail"
msgstr "任务详情"
#: ops/templates/ops/task_adhoc.html:22 ops/templates/ops/task_detail.html:22
-#: ops/templates/ops/task_history.html:22 ops/views.py:71
+#: ops/templates/ops/task_history.html:22 ops/views.py:66
msgid "Task versions"
msgstr "任务各版本"
@@ -1414,6 +1501,7 @@ msgstr "版本"
#: ops/templates/ops/task_adhoc.html:60
#: terminal/templates/terminal/command_list.html:76
+#: terminal/templates/terminal/session_detail.html:50
msgid "Datetime"
msgstr "日期"
@@ -1429,7 +1517,7 @@ msgstr "最新版本"
msgid "Contents"
msgstr "内容"
-#: ops/templates/ops/task_list.html:25 ops/templates/ops/task_list.html:30
+#: ops/templates/ops/task_list.html:20 ops/templates/ops/task_list.html:25
#: templates/_base_list.html:43 templates/_header_bar.html:8
#: terminal/templates/terminal/command_list.html:60
#: users/templates/users/login_log_list.html:35
@@ -1437,73 +1525,74 @@ msgstr "内容"
msgid "Search"
msgstr "搜索"
-#: ops/templates/ops/task_list.html:41
+#: ops/templates/ops/task_list.html:36
msgid "Versions"
msgstr "版本"
-#: ops/templates/ops/task_list.html:43
+#: ops/templates/ops/task_list.html:38
msgid "Success"
msgstr "成功"
-#: ops/templates/ops/task_list.html:44
+#: ops/templates/ops/task_list.html:39
#: users/templates/users/login_log_list.html:54
msgid "Date"
msgstr "日期"
-#: ops/views.py:41 ops/views.py:57 ops/views.py:70 ops/views.py:83
-#: ops/views.py:106 ops/views.py:119 ops/views.py:132
+#: ops/templates/ops/task_list.html:125
+msgid "Task start: "
+msgstr "任务开始: "
+
+#: ops/views.py:36 ops/views.py:52 ops/views.py:65 ops/views.py:78
+#: ops/views.py:91 ops/views.py:104 ops/views.py:117
msgid "Ops"
msgstr "作业中心"
-#: ops/views.py:42
+#: ops/views.py:37
msgid "Task list"
msgstr "任务列表"
-#: ops/views.py:84
+#: ops/views.py:79
msgid "Task run history"
msgstr "执行历史"
#: perms/forms.py:16 users/forms.py:144 users/forms.py:149 users/forms.py:161
-#: users/forms.py:190
+#: users/forms.py:191
msgid "Select users"
msgstr "选择用户"
#: perms/forms.py:18 perms/models.py:15
#: perms/templates/perms/asset_permission_create_update.html:36
#: perms/templates/perms/asset_permission_list.html:26 templates/_nav.html:12
-#: templates/_user_profile.html:14 terminal/backends/command/models.py:10
-#: terminal/models.py:92 terminal/templates/terminal/command_list.html:32
+#: terminal/backends/command/models.py:10 terminal/models.py:92
+#: terminal/templates/terminal/command_list.html:32
#: terminal/templates/terminal/command_list.html:72
#: terminal/templates/terminal/session_list.html:33
-#: terminal/templates/terminal/session_list.html:71 users/models/user.py:31
-#: users/templates/users/user_group_detail.html:78 users/views/user.py:348
+#: terminal/templates/terminal/session_list.html:71 users/forms.py:187
+#: users/models/user.py:31 users/templates/users/user_group_detail.html:78
+#: users/views/user.py:338
msgid "User"
msgstr "用户"
-#: perms/forms.py:30 perms/templates/perms/asset_permission_user.html:127
+#: perms/forms.py:31 perms/templates/perms/asset_permission_user.html:116
msgid "Select user groups"
msgstr "选择用户组"
-#: perms/forms.py:39 perms/templates/perms/asset_permission_detail.html:144
-#: users/forms.py:243
-msgid "Select system users"
-msgstr "选择系统用户"
+#: perms/forms.py:52
+msgid "User or group at least one required"
+msgstr "用户和组至少需要选一个"
-#: perms/forms.py:44
-msgid "User or user group at least one required"
-msgstr ""
+#: perms/forms.py:60
+msgid "Asset or group at least one required"
+msgstr "资产或组至少需要选择一个"
-#: perms/forms.py:45
-msgid "Asset or Asset group at least one required"
-msgstr ""
+#: perms/forms.py:78
+msgid "Asset {} of cluster {} not have [{}] system users, please check \n"
+msgstr "资产 {} 所在集群 {} 不包含系统用户 [{}] 请检查\n"
-#: perms/forms.py:59
-msgid "Asset {} not have [{}] system users, please check \n"
-msgstr ""
-
-#: perms/forms.py:67
-msgid "Asset {}: {} not have [{}] system users, please check"
-msgstr ""
+#: perms/forms.py:87
+msgid ""
+"Asset {}(group {}) of cluster {} not have [{}] system users, please check \n"
+msgstr "资产 {}(组 {}) 所在集群 {} 不包含系统用户 [{}] 请检查\n"
#: perms/models.py:16 perms/templates/perms/asset_permission_list.html:27
#: templates/_nav.html:13 users/models/user.py:38
@@ -1513,23 +1602,6 @@ msgstr ""
msgid "User group"
msgstr "用户组"
-#: perms/models.py:18 perms/templates/perms/asset_permission_list.html:29
-#: templates/_nav.html:23
-msgid "Asset group"
-msgstr "资产组"
-
-#: perms/models.py:19 perms/templates/perms/asset_permission_detail.html:136
-#: perms/templates/perms/asset_permission_list.html:30 templates/_nav.html:26
-#: terminal/backends/command/models.py:12 terminal/models.py:94
-#: terminal/templates/terminal/command_list.html:48
-#: terminal/templates/terminal/command_list.html:74
-#: terminal/templates/terminal/session_list.html:49
-#: terminal/templates/terminal/session_list.html:73
-#: users/templates/users/user_granted_asset.html:50
-#: users/templates/users/user_group_granted_asset.html:52
-msgid "System user"
-msgstr "系统用户"
-
#: perms/models.py:21 perms/templates/perms/asset_permission_detail.html:86
#: users/models/user.py:50 users/templates/users/user_detail.html:94
#: users/templates/users/user_profile.html:96
@@ -1548,21 +1620,15 @@ msgstr "用户或用户组"
msgid "Assets and asset groups"
msgstr "资产或资产组"
-#: perms/templates/perms/asset_permission_asset.html:57
-#: perms/templates/perms/asset_permission_list.html:31
-#: perms/templates/perms/asset_permission_user.html:57
-msgid "Is valid"
-msgstr "有效"
-
-#: perms/templates/perms/asset_permission_asset.html:91
+#: perms/templates/perms/asset_permission_asset.html:80
msgid "Add asset to this permission"
msgstr "添加资产"
-#: perms/templates/perms/asset_permission_asset.html:119
+#: perms/templates/perms/asset_permission_asset.html:108
msgid "Add asset group to this permission"
msgstr "添加资产组"
-#: perms/templates/perms/asset_permission_asset.html:136
+#: perms/templates/perms/asset_permission_asset.html:125
#: users/templates/users/user_detail.html:195
msgid "Join"
msgstr "加入"
@@ -1596,70 +1662,53 @@ msgstr "系统用户数量"
msgid "Create permission"
msgstr "创建授权规则"
+#: perms/templates/perms/asset_permission_list.html:31
+msgid "Is valid"
+msgstr "有效"
+
#: perms/templates/perms/asset_permission_user.html:35
msgid "User list of "
msgstr "用户列表"
-#: perms/templates/perms/asset_permission_user.html:56 users/models/user.py:37
-#: users/templates/users/user_detail.html:70
-#: users/templates/users/user_profile.html:59
-msgid "Email"
-msgstr "邮件"
-
-#: perms/templates/perms/asset_permission_user.html:91
+#: perms/templates/perms/asset_permission_user.html:80
msgid "Add user to asset permission"
msgstr "添加用户"
-#: perms/templates/perms/asset_permission_user.html:99
+#: perms/templates/perms/asset_permission_user.html:88
#: users/templates/users/login_log_list.html:28
msgid "Select user"
msgstr "选择用户"
-#: perms/templates/perms/asset_permission_user.html:119
+#: perms/templates/perms/asset_permission_user.html:108
msgid "Add user group to asset permission"
msgstr "添加用户组"
-#: perms/views.py:27 perms/views.py:77 perms/views.py:103 perms/views.py:128
-#: perms/views.py:165 perms/views.py:195 templates/_nav.html:30
+#: perms/views.py:28 perms/views.py:44 perms/views.py:60 perms/views.py:74
+#: perms/views.py:111 perms/views.py:141 templates/_nav.html:30
msgid "Perms"
msgstr "权限管理"
-#: perms/views.py:28
+#: perms/views.py:29
msgid "Asset permission list"
msgstr "资产授权列表"
-#: perms/views.py:63
-#, python-brace-format
-msgid "Create asset permission {name} successfully."
-msgstr "创建授权 {name} 成功"
-
-#: perms/views.py:78
+#: perms/views.py:45
msgid "Create asset permission"
msgstr "创建权限规则"
-#: perms/views.py:89
-#, python-brace-format
-msgid "Create asset permission {name} success."
-msgstr "创建授权 {name} 成功"
-
-#: perms/views.py:104
+#: perms/views.py:61
msgid "Update asset permission"
msgstr "更新资产授权"
-#: perms/views.py:115
-#, python-brace-format
-msgid "Update asset permission {name} success."
-msgstr "更新授权 {name} 成功"
-
-#: perms/views.py:129
+#: perms/views.py:75
msgid "Asset permission detail"
msgstr "资产授权详情"
-#: perms/views.py:166
+#: perms/views.py:112
msgid "Asset permission user list"
msgstr "资产授权包含用户"
-#: perms/views.py:196
+#: perms/views.py:142
msgid "Asset permission asset list"
msgstr "资产组授权包含资产"
@@ -1671,16 +1720,34 @@ msgstr "欢迎使用Jumpserver开源跳板机系统"
msgid "Help"
msgstr "帮助"
-#: templates/_header_bar.html:24 templates/_user_profile.html:29
+#: templates/_header_bar.html:33 templates/_nav_user.html:9
+#: users/templates/users/_user.html:42
+#: users/templates/users/user_password_update.html:37
+#: users/templates/users/user_profile.html:17
+#: users/templates/users/user_profile_update.html:37
+#: users/templates/users/user_profile_update.html:57
+#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:320
+msgid "Profile"
+msgstr "个人信息"
+
+#: templates/_header_bar.html:37
+msgid "Admin page"
+msgstr "管理页面"
+
+#: templates/_header_bar.html:39
+msgid "User page"
+msgstr "用户页面"
+
+#: templates/_header_bar.html:42
msgid "Logout"
msgstr "注销登录"
-#: templates/_header_bar.html:28 users/templates/users/login.html:42
+#: templates/_header_bar.html:46 users/templates/users/login.html:42
#: users/templates/users/login.html:61
msgid "Login"
msgstr "登录"
-#: templates/_header_bar.html:41 templates/_nav.html:4
+#: templates/_header_bar.html:59 templates/_nav.html:4
msgid "Dashboard"
msgstr "仪表盘"
@@ -1714,11 +1781,11 @@ msgstr ""
msgid "Close"
msgstr "关闭"
-#: templates/_nav.html:9 users/views/group.py:30 users/views/group.py:46
-#: users/views/group.py:72 users/views/group.py:89 users/views/login.py:192
-#: users/views/login.py:241 users/views/user.py:55 users/views/user.py:70
-#: users/views/user.py:95 users/views/user.py:151 users/views/user.py:308
-#: users/views/user.py:322 users/views/user.py:366 users/views/user.py:388
+#: templates/_nav.html:9 users/views/group.py:28 users/views/group.py:44
+#: users/views/group.py:62 users/views/group.py:79 users/views/login.py:193
+#: users/views/login.py:242 users/views/user.py:57 users/views/user.py:72
+#: users/views/user.py:92 users/views/user.py:148 users/views/user.py:305
+#: users/views/user.py:319 users/views/user.py:356 users/views/user.py:378
msgid "Users"
msgstr "用户管理"
@@ -1739,11 +1806,11 @@ msgid "Task"
msgstr "任务"
#: templates/_nav.html:47 templates/_nav.html:50
-#: terminal/templates/terminal/session_list.html:74
-#: terminal/views/command.py:47 terminal/views/session.py:54
-#: terminal/views/session.py:77 terminal/views/session.py:94
-#: terminal/views/session.py:116 terminal/views/terminal.py:31
-#: terminal/views/terminal.py:46 terminal/views/terminal.py:58
+#: terminal/templates/terminal/session_list.html:75
+#: terminal/views/command.py:47 terminal/views/session.py:75
+#: terminal/views/session.py:92 terminal/views/session.py:114
+#: terminal/views/terminal.py:31 terminal/views/terminal.py:46
+#: terminal/views/terminal.py:58
msgid "Terminal"
msgstr "终端"
@@ -1755,43 +1822,18 @@ msgstr "在线会话"
msgid "Session offline"
msgstr "离线会话"
-#: templates/_nav.html:53 terminal/models.py:98
+#: templates/_nav.html:53 terminal/models.py:99
#: terminal/templates/terminal/command_list.html:55
#: terminal/templates/terminal/command_list.html:71
-#: terminal/templates/terminal/session_list.html:75
+#: terminal/templates/terminal/session_detail.html:48
+#: terminal/templates/terminal/session_list.html:76
msgid "Command"
msgstr "命令"
-#: templates/_nav.html:73
-msgid "Visit us"
-msgstr "访问官网"
-
#: templates/_nav_user.html:4
msgid "My assets"
msgstr "我的资产"
-#: templates/_nav_user.html:9 templates/_user_profile.html:19
-#: users/templates/users/_user.html:42
-#: users/templates/users/user_password_update.html:37
-#: users/templates/users/user_profile.html:17
-#: users/templates/users/user_profile_update.html:37
-#: users/templates/users/user_profile_update.html:57
-#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:323
-msgid "Profile"
-msgstr "个人信息"
-
-#: templates/_user_profile.html:20
-msgid "Profile settings"
-msgstr "个人信息设置"
-
-#: templates/_user_profile.html:24
-msgid "Admin page"
-msgstr "管理页面"
-
-#: templates/_user_profile.html:26
-msgid "User page"
-msgstr "用户页面"
-
#: templates/captcha/image.html:3
msgid "Play CAPTCHA as audio file"
msgstr "语言播放验证码"
@@ -1818,16 +1860,12 @@ msgid "Session"
msgstr "会话"
#: terminal/forms.py:15
-msgid "A unique addr of every terminal, user browser can arrive it"
-msgstr ""
+msgid "Coco ssh listen port"
+msgstr "SSH 监听端口"
#: terminal/forms.py:16
-msgid "Coco ssh listen port"
-msgstr ""
-
-#: terminal/forms.py:17
msgid "Coco http/ws listen port"
-msgstr ""
+msgstr "Http/Websocket 监听端口"
#: terminal/models.py:15
msgid "Remote Address"
@@ -1847,7 +1885,7 @@ msgstr "在线会话"
#: terminal/models.py:69
msgid "CPU Usage"
-msgstr ""
+msgstr "CPU使用"
#: terminal/models.py:70
msgid "Memory Used"
@@ -1855,34 +1893,39 @@ msgstr "内存使用"
#: terminal/models.py:71
msgid "Connections"
-msgstr "连接"
+msgstr "连接数"
#: terminal/models.py:72
msgid "Threads"
-msgstr "线程"
+msgstr "线程数"
#: terminal/models.py:73
msgid "Boot Time"
msgstr "运行时间"
-#: terminal/models.py:97 terminal/templates/terminal/session_list.html:98
+#: terminal/models.py:96 terminal/templates/terminal/session_list.html:74
+#: terminal/templates/terminal/terminal_detail.html:47
+msgid "Remote addr"
+msgstr "远端地址"
+
+#: terminal/models.py:98 terminal/templates/terminal/session_list.html:100
msgid "Replay"
msgstr "回放"
-#: terminal/models.py:101
+#: terminal/models.py:102
msgid "Date end"
msgstr "结束日期"
-#: terminal/models.py:118
+#: terminal/models.py:119
msgid "Args"
msgstr "参数"
#: terminal/templates/terminal/command_list.html:88
msgid "Goto"
-msgstr ""
+msgstr "转到"
#: terminal/templates/terminal/session_detail.html:17
-#: terminal/views/session.py:117
+#: terminal/views/session.py:115
msgid "Session detail"
msgstr "会话详情"
@@ -1912,19 +1955,19 @@ msgstr "监控"
msgid "Terminate session"
msgstr "终止会话"
-#: terminal/templates/terminal/session_list.html:77
+#: terminal/templates/terminal/session_list.html:78
msgid "Duration"
msgstr "时长"
-#: terminal/templates/terminal/session_list.html:100
+#: terminal/templates/terminal/session_list.html:102
msgid "Monitor"
msgstr "监控"
-#: terminal/templates/terminal/session_list.html:101
+#: terminal/templates/terminal/session_list.html:103
msgid "Terminate"
msgstr "终断"
-#: terminal/templates/terminal/session_list.html:117
+#: terminal/templates/terminal/session_list.html:119
msgid "Terminate task send, waiting ..."
msgstr "终断任务已发送,请等待"
@@ -1933,10 +1976,6 @@ msgstr "终断任务已发送,请等待"
msgid "Terminal detail"
msgstr "终端详情"
-#: terminal/templates/terminal/terminal_detail.html:47
-msgid "Remote address"
-msgstr "远端地址"
-
#: terminal/templates/terminal/terminal_detail.html:51
#: terminal/templates/terminal/terminal_list.html:31
msgid "SSH port"
@@ -1971,14 +2010,14 @@ msgstr "接受终端注册"
msgid "Info"
msgstr "信息"
-#: terminal/views/session.py:55 terminal/views/session.py:95
-msgid "Session offline list"
-msgstr "离线会话"
-
-#: terminal/views/session.py:78
+#: terminal/views/session.py:76
msgid "Session online list"
msgstr "在线会话"
+#: terminal/views/session.py:93
+msgid "Session offline list"
+msgstr "离线会话"
+
#: terminal/views/terminal.py:32
msgid "Terminal list"
msgstr "终端列表"
@@ -2119,7 +2158,7 @@ msgstr "Agent"
msgid "Date login"
msgstr "登录日期"
-#: users/models/user.py:30 users/models/user.py:255
+#: users/models/user.py:30 users/models/user.py:259
msgid "Administrator"
msgstr "管理员"
@@ -2127,6 +2166,11 @@ msgstr "管理员"
msgid "Application"
msgstr "应用程序"
+#: users/models/user.py:37 users/templates/users/user_detail.html:70
+#: users/templates/users/user_profile.html:59
+msgid "Email"
+msgstr "邮件"
+
#: users/models/user.py:39 users/templates/users/_select_user_modal.html:15
#: users/templates/users/user_detail.html:86
#: users/templates/users/user_list.html:25
@@ -2146,10 +2190,6 @@ msgstr "微信"
msgid "Enable OTP"
msgstr "二次验证"
-#: users/models/user.py:46
-msgid "Private key"
-msgstr "ssh私钥"
-
#: users/models/user.py:47 users/templates/users/user_password_update.html:43
#: users/templates/users/user_profile.html:71
#: users/templates/users/user_profile_update.html:43
@@ -2157,7 +2197,7 @@ msgstr "ssh私钥"
msgid "Public key"
msgstr "ssh公钥"
-#: users/models/user.py:258
+#: users/models/user.py:262
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
@@ -2259,7 +2299,7 @@ msgid "Setting"
msgstr "设置"
#: users/templates/users/user_create.html:4
-#: users/templates/users/user_list.html:16 users/views/user.py:70
+#: users/templates/users/user_list.html:16 users/views/user.py:72
msgid "Create user"
msgstr "创建用户"
@@ -2270,7 +2310,7 @@ msgstr "生成重置密码连接,通过邮件发送给用户"
#: users/templates/users/user_detail.html:19
#: users/templates/users/user_granted_asset.html:18
#: users/templates/users/user_group_granted_asset.html:18
-#: users/views/user.py:152
+#: users/views/user.py:149
msgid "User detail"
msgstr "用户详情"
@@ -2306,13 +2346,13 @@ msgstr "已发送邮件到用户邮箱"
msgid ""
"This will reset the user's password. A password-reset email will be sent to "
"the user\\'s mailbox."
-msgstr ""
+msgstr "重设密码邮件将会发送到用户邮箱"
#: users/templates/users/user_detail.html:348
msgid ""
"The reset-ssh-public-key E-mail has been sent successfully. Please inform "
"the user to update his new ssh public key."
-msgstr ""
+msgstr "重设秘钥邮件将会发送到用户邮箱"
#: users/templates/users/user_detail.html:349
#: users/templates/users/user_profile.html:144
@@ -2345,11 +2385,11 @@ msgstr "授权资产"
msgid "Asset groups granted of "
msgstr "授权资产组"
-#: users/templates/users/user_group_create_update.html:45
+#: users/templates/users/user_group_create_update.html:31
msgid "Cancel"
msgstr "取消"
-#: users/templates/users/user_group_detail.html:22 users/views/group.py:90
+#: users/templates/users/user_group_detail.html:22 users/views/group.py:80
msgid "User group detail"
msgstr "资产组详情"
@@ -2361,7 +2401,7 @@ msgstr "添加用户"
msgid "Valid"
msgstr "可用"
-#: users/templates/users/user_group_list.html:5 users/views/group.py:47
+#: users/templates/users/user_group_list.html:5 users/views/group.py:45
msgid "Create user group"
msgstr "创建用户组"
@@ -2399,8 +2439,8 @@ msgstr "用户删除失败"
msgid "OTP"
msgstr ""
-#: users/templates/users/user_profile.html:100 users/views/user.py:181
-#: users/views/user.py:233
+#: users/templates/users/user_profile.html:100 users/views/user.py:178
+#: users/views/user.py:230
msgid "User groups"
msgstr "用户组"
@@ -2424,7 +2464,7 @@ msgstr "指纹"
msgid "Update public key"
msgstr "更新密钥"
-#: users/templates/users/user_update.html:4 users/views/user.py:95
+#: users/templates/users/user_update.html:4 users/views/user.py:92
msgid "Update user"
msgstr "编辑用户"
@@ -2558,17 +2598,17 @@ msgstr "禁用或失效"
msgid "Password or SSH public key invalid"
msgstr "密码或秘钥不合法"
-#: users/views/group.py:31
+#: users/views/group.py:29
msgid "User group list"
msgstr "用户组列表"
-#: users/views/group.py:73
+#: users/views/group.py:63
msgid "Update user group"
msgstr "编辑用户组"
#: users/views/login.py:54
msgid "Please enable cookies and try again."
-msgstr ""
+msgstr "设置你的浏览器支持cookie"
#: users/views/login.py:83
msgid "Logout success"
@@ -2578,81 +2618,69 @@ msgstr "退出登录成功"
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
-#: users/views/login.py:99
+#: users/views/login.py:100
msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入"
-#: users/views/login.py:112
+#: users/views/login.py:113
msgid "Send reset password message"
msgstr "发送重置密码邮件"
-#: users/views/login.py:113
+#: users/views/login.py:114
msgid "Send reset password mail success, login your mail box and follow it "
msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
-#: users/views/login.py:127
+#: users/views/login.py:128
msgid "Reset password success"
msgstr "重置密码成功"
-#: users/views/login.py:128
+#: users/views/login.py:129
msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面"
-#: users/views/login.py:145 users/views/login.py:158
+#: users/views/login.py:146 users/views/login.py:159
msgid "Token invalid or expired"
msgstr "Token错误或失效"
-#: users/views/login.py:154
+#: users/views/login.py:155
msgid "Password not same"
msgstr "密码不一致"
-#: users/views/login.py:192
+#: users/views/login.py:193
msgid "First login"
msgstr "首次登陆"
-#: users/views/login.py:242
+#: users/views/login.py:243
msgid "Login log list"
msgstr "登录日志"
-#: users/views/user.py:56
+#: users/views/user.py:58
msgid "User list"
msgstr "用户列表"
-#: users/views/user.py:66 users/views/user.py:335
-#, python-brace-format
-msgid "Create user {name} successfully."
-msgstr "创建用户 {name} 成功"
-
-#: users/views/user.py:105
+#: users/views/user.py:102
msgid "Bulk update user success"
msgstr "批量更新用户成功"
-#: users/views/user.py:210
+#: users/views/user.py:207
msgid "Invalid file."
msgstr "文件不合法"
-#: users/views/user.py:309
+#: users/views/user.py:306
msgid "User granted assets"
msgstr "用户授权资产"
-#: users/views/user.py:349
+#: users/views/user.py:339
msgid "Profile setting"
msgstr "个人信息设置"
-#: users/views/user.py:367
+#: users/views/user.py:357
msgid "Password update"
msgstr "密码更新"
-#: users/views/user.py:389
+#: users/views/user.py:379
msgid "Public key update"
msgstr "秘钥更新"
-#~ msgid "Audits"
-#~ msgstr "审计中心"
-#~ msgid "Proxy log list"
-#~ msgstr "Session列表"
-
-#~ msgid "If also set private key, use that first"
-#~ msgstr "如果设置私钥,则优先使用密钥"
diff --git a/apps/ops/api.py b/apps/ops/api.py
index 2ecf2238a..09f5e67e7 100644
--- a/apps/ops/api.py
+++ b/apps/ops/api.py
@@ -2,11 +2,13 @@
from django.shortcuts import get_object_or_404
-from rest_framework import viewsets
+from rest_framework import viewsets, generics
+from rest_framework.views import Response
from .hands import IsSuperUser
from .models import Task, AdHoc, AdHocRunHistory
from .serializers import TaskSerializer, AdHocSerializer, AdHocRunHistorySerializer
+from .tasks import run_ansible_task
class TaskViewSet(viewsets.ModelViewSet):
@@ -15,6 +17,17 @@ class TaskViewSet(viewsets.ModelViewSet):
permission_classes = (IsSuperUser,)
+class TaskRun(generics.RetrieveAPIView):
+ queryset = Task.objects.all()
+ serializer_class = TaskViewSet
+ permission_classes = (IsSuperUser,)
+
+ def retrieve(self, request, *args, **kwargs):
+ task = self.get_object()
+ run_ansible_task.delay(str(task.id))
+ return Response({"msg": "start"})
+
+
class AdHocViewSet(viewsets.ModelViewSet):
queryset = AdHoc.objects.all()
serializer_class = AdHocSerializer
diff --git a/apps/ops/hands.py b/apps/ops/hands.py
index d7175db18..b6e3d3479 100644
--- a/apps/ops/hands.py
+++ b/apps/ops/hands.py
@@ -1,4 +1,4 @@
# ~*~ coding: utf-8 ~*~
from users.permissions import IsSuperUser
-
+from users.utils import AdminUserRequiredMixin
\ No newline at end of file
diff --git a/apps/ops/models.py b/apps/ops/models.py
index 3f83e8ffd..accdfe78f 100644
--- a/apps/ops/models.py
+++ b/apps/ops/models.py
@@ -235,6 +235,7 @@ class AdHoc(models.Model):
return result.results_raw, result.results_summary
except AnsibleError as e:
logger.error("Failed run adhoc {}, {}".format(self.task.name, e))
+ pass
@become.setter
def become(self, item):
diff --git a/apps/ops/templates/ops/adhoc_detail.html b/apps/ops/templates/ops/adhoc_detail.html
index 6134b1ce4..abbb16c04 100644
--- a/apps/ops/templates/ops/adhoc_detail.html
+++ b/apps/ops/templates/ops/adhoc_detail.html
@@ -3,9 +3,9 @@
{% load i18n %}
{% block custom_head_css_js %}
-
+
-
+
{% endblock %}
{% block content %}
diff --git a/apps/ops/templates/ops/adhoc_history.html b/apps/ops/templates/ops/adhoc_history.html
index 95689fb89..802e8e8f6 100644
--- a/apps/ops/templates/ops/adhoc_history.html
+++ b/apps/ops/templates/ops/adhoc_history.html
@@ -3,9 +3,9 @@
{% load i18n %}
{% block custom_head_css_js %}
-
+
-
+
{% endblock %}
{% block content %}
diff --git a/apps/ops/templates/ops/adhoc_history_detail.html b/apps/ops/templates/ops/adhoc_history_detail.html
index 5439ae571..f3d18f8ba 100644
--- a/apps/ops/templates/ops/adhoc_history_detail.html
+++ b/apps/ops/templates/ops/adhoc_history_detail.html
@@ -3,9 +3,9 @@
{% load i18n %}
{% block custom_head_css_js %}
-
+
-
+
{% endblock %}
{% block content %}
diff --git a/apps/ops/templates/ops/task_adhoc.html b/apps/ops/templates/ops/task_adhoc.html
index 2b26b058c..2d2c4de5c 100644
--- a/apps/ops/templates/ops/task_adhoc.html
+++ b/apps/ops/templates/ops/task_adhoc.html
@@ -3,9 +3,9 @@
{% load i18n %}
{% block custom_head_css_js %}
-
+
-
+
{% endblock %}
{% block content %}
diff --git a/apps/ops/templates/ops/task_detail.html b/apps/ops/templates/ops/task_detail.html
index dab26d1dc..4da7e0f58 100644
--- a/apps/ops/templates/ops/task_detail.html
+++ b/apps/ops/templates/ops/task_detail.html
@@ -3,9 +3,9 @@
{% load i18n %}
{% block custom_head_css_js %}
-
+
-
+
{% endblock %}
{% block content %}
@@ -89,7 +89,7 @@
{% for task in object.latest_adhoc.tasks %}
- {{ forloop.counter }}. {{ task.name }} : {{ task.action.module }}
+ {{ forloop.counter }}. {{ task.name }} ::: {{ task.action.module }}
{% endfor %}
|
diff --git a/apps/ops/templates/ops/task_history.html b/apps/ops/templates/ops/task_history.html
index 6aebce351..cc620237d 100644
--- a/apps/ops/templates/ops/task_history.html
+++ b/apps/ops/templates/ops/task_history.html
@@ -3,9 +3,9 @@
{% load i18n %}
{% block custom_head_css_js %}
-
+
-
+
{% endblock %}
{% block content %}
diff --git a/apps/ops/templates/ops/task_list.html b/apps/ops/templates/ops/task_list.html
index a127a0ff6..e564eec73 100644
--- a/apps/ops/templates/ops/task_list.html
+++ b/apps/ops/templates/ops/task_list.html
@@ -67,6 +67,7 @@
{% endif %}
+ {% trans "Run" %}
{% trans "Delete" %}
|
@@ -98,10 +99,32 @@ $(document).ready(function() {
}).on('click', '.btn-del', function () {
var $this = $(this);
- var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
+ var name = $this.closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-ops:task-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
objectDelete($this, name, the_url);
+}).on('click', '.btn-run', function () {
+ var $this = $(this);
+ var name = $this.closest("tr").find(":nth-child(2)").children('a').html();
+ var uid = $this.data('uid');
+ var the_url = '{% url "api-ops:task-run" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
+ var error = function (data) {
+ alert(data)
+ };
+ var success = function () {
+ setTimeout(function () {
+ console.log("ok")
+ }, 1000);
+ window.location = "{% url 'ops:task-detail' pk=DEFAULT_PK %}".replace('{{ DEFAULT_PK }}', uid);
+ };
+ APIUpdateAttr({
+ url: the_url,
+ error: error,
+ method: 'GET',
+ success: success,
+ success_message: "{% trans 'Task start: ' %}" + " " + name
+ });
+
})
{% endblock %}
diff --git a/apps/ops/urls/api_urls.py b/apps/ops/urls/api_urls.py
index 545487f00..ab007c383 100644
--- a/apps/ops/urls/api_urls.py
+++ b/apps/ops/urls/api_urls.py
@@ -1,6 +1,7 @@
# ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals
+from django.conf.urls import url
from rest_framework.routers import DefaultRouter
from .. import api
@@ -12,6 +13,8 @@ router.register(r'v1/tasks', api.TaskViewSet, 'task')
router.register(r'v1/adhoc', api.AdHocViewSet, 'adhoc')
router.register(r'v1/history', api.AdHocRunHistorySet, 'history')
-urlpatterns = []
+urlpatterns = [
+ url(r'^v1/tasks/(?P[0-9a-zA-Z\-]{36})/run/$', api.TaskRun.as_view(), name='task-run'),
+]
urlpatterns += router.urls
diff --git a/apps/ops/views.py b/apps/ops/views.py
index 2c58e496e..4b090a8a3 100644
--- a/apps/ops/views.py
+++ b/apps/ops/views.py
@@ -6,9 +6,10 @@ from django.views.generic import ListView, DetailView
from common.mixins import DatetimeSearchMixin
from .models import Task, AdHoc, AdHocRunHistory
+from .hands import AdminUserRequiredMixin
-class TaskListView(DatetimeSearchMixin, ListView):
+class TaskListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
model = Task
ordering = ('-date_created',)
@@ -42,7 +43,7 @@ class TaskListView(DatetimeSearchMixin, ListView):
return super().get_context_data(**kwargs)
-class TaskDetailView(DetailView):
+class TaskDetailView(AdminUserRequiredMixin, DetailView):
model = Task
template_name = 'ops/task_detail.html'
@@ -55,7 +56,7 @@ class TaskDetailView(DetailView):
return super().get_context_data(**kwargs)
-class TaskAdhocView(DetailView):
+class TaskAdhocView(AdminUserRequiredMixin, DetailView):
model = Task
template_name = 'ops/task_adhoc.html'
@@ -68,7 +69,7 @@ class TaskAdhocView(DetailView):
return super().get_context_data(**kwargs)
-class TaskHistoryView(DetailView):
+class TaskHistoryView(AdminUserRequiredMixin, DetailView):
model = Task
template_name = 'ops/task_history.html'
@@ -81,7 +82,7 @@ class TaskHistoryView(DetailView):
return super().get_context_data(**kwargs)
-class AdHocDetailView(DetailView):
+class AdHocDetailView(AdminUserRequiredMixin, DetailView):
model = AdHoc
template_name = 'ops/adhoc_detail.html'
@@ -94,7 +95,7 @@ class AdHocDetailView(DetailView):
return super().get_context_data(**kwargs)
-class AdHocHistoryView(DetailView):
+class AdHocHistoryView(AdminUserRequiredMixin, DetailView):
model = AdHoc
template_name = 'ops/adhoc_history.html'
@@ -107,7 +108,7 @@ class AdHocHistoryView(DetailView):
return super().get_context_data(**kwargs)
-class AdHocHistoryDetailView(DetailView):
+class AdHocHistoryDetailView(AdminUserRequiredMixin, DetailView):
model = AdHocRunHistory
template_name = 'ops/adhoc_history_detail.html'
diff --git a/apps/perms/forms.py b/apps/perms/forms.py
index fbb0c8226..4e3c0bf72 100644
--- a/apps/perms/forms.py
+++ b/apps/perms/forms.py
@@ -15,7 +15,8 @@ class AssetPermissionForm(forms.ModelForm):
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select users')},
),
- label=_("User")
+ label=_("User"),
+ required=False,
)
class Meta:
@@ -41,35 +42,54 @@ class AssetPermissionForm(forms.ModelForm):
help_texts = {
'name': '* required',
'system_users': '* required',
- 'user_groups': _('User or user group at least one required'),
- 'asset_groups': _('Asset or Asset group at least one required'),
}
+ def clean_user_groups(self):
+ users = self.cleaned_data.get('users')
+ user_groups = self.cleaned_data.get('user_groups')
+
+ if not users and not user_groups:
+ raise forms.ValidationError(_("User or group at least one required"))
+ return self.cleaned_data["user_groups"]
+
+ def clean_asset_groups(self):
+ assets = self.cleaned_data.get('assets')
+ asset_groups = self.cleaned_data.get('asset_groups')
+
+ if not assets and not asset_groups:
+ raise forms.ValidationError(_("Asset or group at least one required"))
+
+ return self.cleaned_data["asset_groups"]
+
def clean_system_users(self):
from assets.utils import check_assets_have_system_user
errors = []
assets = self.cleaned_data['assets']
- asset_groups = self.cleaned_data['asset_groups']
- system_users = self.cleaned_data['system_users']
+ asset_groups = self.cleaned_data.get('asset_groups')
+ system_users = self.cleaned_data.get('system_users')
+
+ if not asset_groups and not assets:
+ return self.cleaned_data.get("system_users")
error_data = check_assets_have_system_user(assets, system_users)
if error_data:
for asset, system_users in error_data.items():
- msg = _("Asset {} not have [{}] system users, please check \n")
+ msg = _("Asset {} of cluster {} not have [{}] system users, please check \n")
error = forms.ValidationError(msg.format(
asset.hostname,
+ asset.cluster.name,
", ".join(system_user.name for system_user in system_users)
))
errors.append(error)
for group in asset_groups:
- msg = _("Asset {}: {} not have [{}] system users, please check")
+ msg = _("Asset {}(group {}) of cluster {} not have [{}] system users, please check \n")
assets = group.assets.all()
error_data = check_assets_have_system_user(assets, system_users)
for asset, system_users in error_data.items():
errors.append(msg.format(
- group.name, asset.hostname,
+ asset.hostname, group.name, asset.cluster.name,
", ".join(system_user.name for system_user in system_users)
))
if errors:
diff --git a/apps/perms/templates/perms/asset_permission_asset.html b/apps/perms/templates/perms/asset_permission_asset.html
index 4ae615f1f..5cfc44c05 100644
--- a/apps/perms/templates/perms/asset_permission_asset.html
+++ b/apps/perms/templates/perms/asset_permission_asset.html
@@ -3,8 +3,8 @@
{% load i18n %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
@@ -53,8 +53,6 @@
{% trans 'Hostname' %} |
{% trans 'IP' %} |
- {% trans 'Port' %} |
- {% trans 'Is valid' %} |
|
@@ -63,15 +61,6 @@
{{ asset.hostname }} |
{{ asset.ip }} |
- {{ user.port }} |
-
- {% if asset.is_active %}
-
- {% else %}
-
- {% endif %}
- |
-
|
diff --git a/apps/perms/templates/perms/asset_permission_detail.html b/apps/perms/templates/perms/asset_permission_detail.html
index 5b945a900..5540ca515 100644
--- a/apps/perms/templates/perms/asset_permission_detail.html
+++ b/apps/perms/templates/perms/asset_permission_detail.html
@@ -3,8 +3,8 @@
{% load i18n %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
@@ -27,11 +27,11 @@
{% trans 'Assets and asset groups' %}
- Update
+ {% trans 'Update' %}
- Delete
+ {% trans 'Delete' %}
@@ -113,7 +113,7 @@
- Active: |
+ {% trans 'Active' %} : |
@@ -139,8 +139,8 @@
{% for system_user in system_users %}
-
+
{{ system_user.name }} |
@@ -237,6 +237,16 @@ $(document).ready(function () {
}).get();
updateSystemUser(system_users);
$tr.remove()
+}).on('click', '#is_active', function () {
+ var the_url = '{% url "api-perms:asset-permission-detail" pk=asset_permission.id %}';
+ var checked = $(this).prop('checked');
+ var body = {
+ 'is_active': checked
+ };
+ APIUpdateAttr({
+ url: the_url,
+ body: JSON.stringify(body),
+ });
})
{% endblock %}
diff --git a/apps/perms/templates/perms/asset_permission_list.html b/apps/perms/templates/perms/asset_permission_list.html
index da4c88f80..a8bdab5a1 100644
--- a/apps/perms/templates/perms/asset_permission_list.html
+++ b/apps/perms/templates/perms/asset_permission_list.html
@@ -69,9 +69,11 @@ function initTable() {
$(td).html('')
}
}},
- {targets: 8, createdCell: function (td, cellData) {
+ {targets: 8, createdCell: function (td, cellData, rowData) {
var update_btn = '{% trans "Update" %}'.replace('{{ DEFAULT_PK }}', cellData);
- var del_btn = '{% trans "Delete" %}'.replace('{{ DEFAULT_PK }}', cellData);
+ var del_btn = '{% trans "Delete" %}'
+ .replace('{{ DEFAULT_PK }}', cellData)
+ .replace('99991938', rowData.name);
$(td).html(update_btn + del_btn);
}}
diff --git a/apps/perms/templates/perms/asset_permission_user.html b/apps/perms/templates/perms/asset_permission_user.html
index 8f24cbeea..2e64368aa 100644
--- a/apps/perms/templates/perms/asset_permission_user.html
+++ b/apps/perms/templates/perms/asset_permission_user.html
@@ -3,8 +3,8 @@
{% load i18n %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
@@ -53,8 +53,6 @@
{% trans 'Name' %} |
{% trans 'Username' %} |
- {% trans 'Email' %} |
- {% trans 'Is valid' %} |
|
@@ -63,15 +61,6 @@
{{ user.name }} |
{{ user.username }} |
- {{ user.email }} |
-
- {% if user.is_expired and user.is_active %}
-
- {% else %}
-
- {% endif %}
- |
-
|
@@ -231,7 +220,6 @@ $(document).ready(function () {
$.map(jumpserver.users_selected, function(value, index) {
users_id.push(index);
});
- console.log(users_id);
addUsers(users_id);
}).on('click', '.btn-remove-user', function () {
var user_id = $(this).data("gid");
diff --git a/apps/perms/urls/api_urls.py b/apps/perms/urls/api_urls.py
index f59bb178e..a9fad1eac 100644
--- a/apps/perms/urls/api_urls.py
+++ b/apps/perms/urls/api_urls.py
@@ -7,9 +7,7 @@ from .. import api
app_name = 'perms'
router = routers.DefaultRouter()
-router.register('v1/asset-permissions',
- api.AssetPermissionViewSet,
- 'asset-permission')
+router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'asset-permission')
urlpatterns = [
# 用户可以使用自己的Token或其它认证查看自己授权的资产,资产组等
diff --git a/apps/perms/views.py b/apps/perms/views.py
index d3759d064..6fb2cbca7 100644
--- a/apps/perms/views.py
+++ b/apps/perms/views.py
@@ -11,6 +11,7 @@ from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin
from django.contrib import messages
+from common.const import create_success_msg, update_success_msg
from .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser, \
Asset, AssetGroup
from .models import AssetPermission
@@ -31,46 +32,12 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView):
return super().get_context_data(**kwargs)
-class MessageMixin:
- def form_valid(self, form):
- response = super().form_valid(form)
- errors = self.object.check_system_user_in_assets()
- if errors:
- message = self.get_warning_messages(errors)
- messages.warning(self.request, message)
- else:
- message = self.get_success_message(form.cleaned_data)
- messages.success(self.request, message)
-
- success_message = self.get_success_message(form.cleaned_data)
- if success_message:
- messages.success(self.request, success_message)
- return response
-
- @staticmethod
- def get_warning_messages(errors):
- message = "WARNING: System user " \
- "should in behind clusters, so that " \
- "system user cat auto push to the cluster assets: "
- for system_user, clusters in errors.items():
- message += " >>> {}: {} ".format(system_user.name, ", ".join((cluster.name for cluster in clusters)))
- return message
-
- def get_success_message(self, cleaned_data):
- url = reverse_lazy('perms:asset-permission-detail',
- kwargs={'pk': self.object.pk})
- success_message = _(
- 'Create asset permission {name} '
- 'successfully.'.format(url=url, name=self.object.name))
- return success_message
-
-
class AssetPermissionCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = AssetPermission
form_class = AssetPermissionForm
template_name = 'perms/asset_permission_create_update.html'
success_url = reverse_lazy('perms:asset-permission-list')
- warning = None
+ success_message = create_success_msg
def get_context_data(self, **kwargs):
context = {
@@ -80,23 +47,13 @@ class AssetPermissionCreateView(AdminUserRequiredMixin, SuccessMessageMixin, Cre
kwargs.update(context)
return super().get_context_data(**kwargs)
- def get_success_message(self, cleaned_data):
- url = reverse_lazy(
- 'perms:asset-permission-detail',
- kwargs={'pk': self.object.pk}
- )
- success_message = _(
- 'Create asset permission {name} '
- 'success.'.format(url=url, name=self.object.name)
- )
- return success_message
-
class AssetPermissionUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
model = AssetPermission
form_class = AssetPermissionForm
template_name = 'perms/asset_permission_create_update.html'
success_url = reverse_lazy("perms:asset-permission-list")
+ success_message = update_success_msg
def get_context_data(self, **kwargs):
context = {
@@ -106,17 +63,6 @@ class AssetPermissionUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, Upd
kwargs.update(context)
return super().get_context_data(**kwargs)
- def get_success_message(self, cleaned_data):
- url = reverse_lazy(
- 'perms:asset-permission-detail',
- kwargs={'pk': self.object.pk}
- )
- success_message = _(
- 'Update asset permission {name} '
- 'success.'.format(url=url, name=self.object.name)
- )
- return success_message
-
class AssetPermissionDetailView(AdminUserRequiredMixin, DetailView):
template_name = 'perms/asset_permission_detail.html'
diff --git a/apps/static/js/jumpserver.js b/apps/static/js/jumpserver.js
index 5812e0191..a76c44187 100644
--- a/apps/static/js/jumpserver.js
+++ b/apps/static/js/jumpserver.js
@@ -61,7 +61,6 @@ function GetTableDataBox() {
id_list.push(i);
}
}
- console.log(id_list);
for (i in id_list) {
console.log(tabProduct);
tableData.push(GetRowData(tabProduct.rows[id_list[i]]));
@@ -357,5 +356,15 @@ String.prototype.format = function(args) {
function setCookie(key, value) {
var expires = new Date();
expires.setTime(expires.getTime() + (24 * 60 * 60 * 1000));
- document.cookie = key + '=' + value + ';expires=' + expires.toUTCString();
+ document.cookie = key + '=' + value + ';expires=' + expires.toUTCString() + ';path=/';
+}
+
+
+function delCookie(key) {
+ var expires = new Date();
+ expires.setTime(expires.getTime() - 1);
+ var val = getCookie(key);
+ if (val !== null) {
+ document.cookie = key + '=' + val + ";expires" + expires.toUTCString() + ';path=/';
+ }
}
diff --git a/apps/templates/_base_create_update.html b/apps/templates/_base_create_update.html
index fdc5269e2..a38a6133d 100644
--- a/apps/templates/_base_create_update.html
+++ b/apps/templates/_base_create_update.html
@@ -3,8 +3,8 @@
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
-
-
+
+
{% block custom_head_css_js_create %} {% endblock %}
{% endblock %}
diff --git a/apps/templates/_base_list.html b/apps/templates/_base_list.html
index 6385994e0..191ba8151 100644
--- a/apps/templates/_base_list.html
+++ b/apps/templates/_base_list.html
@@ -3,8 +3,8 @@
{% load i18n %}
{% block custom_head_css_js %}
-
-
+
+
{% endblock %}
{% block content %}
diff --git a/apps/templates/_header_bar.html b/apps/templates/_header_bar.html
index 9c5f64580..a8866dfcc 100644
--- a/apps/templates/_header_bar.html
+++ b/apps/templates/_header_bar.html
@@ -3,11 +3,11 @@
| |