Merge pull request #6447 from jumpserver/dev

v2.12.0 rc4
pull/6468/head
Jiangjie.Bai 2021-07-14 19:02:45 +08:00 committed by GitHub
commit a0638dd5c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 97 additions and 148 deletions

View File

@ -39,7 +39,6 @@ class SystemUserViewSet(OrgBulkModelViewSet):
serializer_class = serializers.SystemUserSerializer
serializer_classes = {
'default': serializers.SystemUserSerializer,
'list': serializers.SystemUserListSerializer,
}
permission_classes = (IsOrgAdminOrAppUser,)

View File

@ -225,9 +225,14 @@ class Asset(AbsConnectivity, ProtocolsMixin, NodesRelationMixin, OrgModelMixin):
def __str__(self):
return '{0.hostname}({0.ip})'.format(self)
__admin_user = None
@property
def admin_user(self):
return self.system_users.filter(type='admin').first()
# 解决每次获取资产管理用户时都是最新的对象
if self.__admin_user is None:
self.__admin_user = self.system_users.filter(type='admin').first()
return self.__admin_user
@admin_user.setter
def admin_user(self, system_user):

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
import socket
import uuid
import random
import re
@ -80,7 +80,8 @@ class Gateway(BaseUser):
except(paramiko.AuthenticationException,
paramiko.BadAuthenticationType,
paramiko.SSHException,
paramiko.ssh_exception.NoValidConnectionsError) as e:
paramiko.ssh_exception.NoValidConnectionsError,
socket.gaierror) as e:
return False, str(e)
try:

View File

@ -1,40 +1,25 @@
# -*- coding: utf-8 -*-
#
from django.utils.translation import ugettext_lazy as _
from ..models import SystemUser
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .base import AuthSerializerMixin
from .system_user import SystemUserSerializer as SuS
class AdminUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
class AdminUserSerializer(SuS):
"""
管理用户
"""
class Meta:
model = SystemUser
fields_mini = ['id', 'name', 'username']
fields_write_only = ['password', 'private_key', 'public_key']
fields_small = fields_mini + fields_write_only + [
'date_created', 'date_updated',
'comment', 'created_by'
]
fields_fk = ['assets_amount']
fields = fields_small + fields_fk
read_only_fields = ['date_created', 'date_updated', 'created_by', 'assets_amount']
class Meta(SuS.Meta):
fields = SuS.Meta.fields_mini + \
SuS.Meta.fields_write_only + \
SuS.Meta.fields_m2m + \
[
'type', 'protocol', "priority", 'sftp_root', 'ssh_key_fingerprint',
'date_created', 'date_updated', 'comment', 'created_by',
]
extra_kwargs = {
'username': {"required": True},
'password': {"write_only": True},
'private_key': {"write_only": True},
'public_key': {"write_only": True},
'assets_amount': {'label': _('Asset')},
}
def validate_type(self, val):
return SystemUser.Type.admin
def create(self, validated_data):
data = {k: v for k, v in validated_data.items()}
data['protocol'] = 'ssh'
data['type'] = SystemUser.Type.admin
return super().create(data)
def validate_protocol(self, val):
return 'ssh'

View File

@ -9,7 +9,7 @@ from ..models import SystemUser, Asset
from .base import AuthSerializerMixin
__all__ = [
'SystemUserSerializer', 'SystemUserListSerializer',
'SystemUserSerializer',
'SystemUserSimpleSerializer', 'SystemUserAssetRelationSerializer',
'SystemUserNodeRelationSerializer', 'SystemUserTaskSerializer',
'SystemUserUserRelationSerializer', 'SystemUserWithAuthInfoSerializer',
@ -22,7 +22,7 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
系统用户
"""
auto_generate_key = serializers.BooleanField(initial=True, required=False, write_only=True)
type_display = serializers.ReadOnlyField(source='get_type_display')
type_display = serializers.ReadOnlyField(source='get_type_display', label=_('Type display'))
ssh_key_fingerprint = serializers.ReadOnlyField(label=_('SSH key fingerprint'))
class Meta:
@ -173,33 +173,6 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
attrs = self.validate_gen_key(attrs)
return attrs
class SystemUserListSerializer(SystemUserSerializer):
class Meta(SystemUserSerializer.Meta):
fields_mini = ['id', 'name', 'username']
fields_write_only = ['password', 'public_key', 'private_key']
fields_small = fields_mini + fields_write_only + [
'protocol', 'login_mode', 'login_mode_display', 'priority',
'sudo', 'shell', 'home', 'system_groups',
'ad_domain', 'sftp_root', 'ssh_key_fingerprint',
"username_same_with_user", 'auto_push', 'auto_generate_key',
'date_created', 'date_updated',
'comment', 'created_by',
]
fields_m2m = ["assets_amount"]
fields = fields_small + fields_m2m
extra_kwargs = {
'password': {"write_only": True},
'public_key': {"write_only": True},
'private_key': {"write_only": True},
'nodes_amount': {'label': _('Nodes amount')},
'assets_amount': {'label': _('Assets amount')},
'login_mode_display': {'label': _('Login mode display')},
'created_by': {'read_only': True},
'ad_domain': {'label': _('Ad domain')},
}
@classmethod
def setup_eager_loading(cls, queryset):
""" Perform necessary eager loading of data. """
@ -236,16 +209,17 @@ class SystemUserSimpleSerializer(serializers.ModelSerializer):
class RelationMixin(BulkSerializerMixin, serializers.Serializer):
systemuser_display = serializers.ReadOnlyField(label=_("System user"))
systemuser_display = serializers.ReadOnlyField(label=_("System user name"))
org_name = serializers.ReadOnlyField(label=_("Org name"))
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend(['systemuser', "systemuser_display"])
fields.extend(['systemuser', "systemuser_display", "org_name"])
return fields
class SystemUserAssetRelationSerializer(RelationMixin, serializers.ModelSerializer):
asset_display = serializers.ReadOnlyField(label=_('Asset'))
asset_display = serializers.ReadOnlyField(label=_('Asset hostname'))
class Meta:
model = SystemUser.assets.through

View File

@ -83,7 +83,7 @@ def test_system_user_connectivity_util(system_user, assets, task_name):
_task, created = update_or_create_ansible_task(
task_name=_task_name, hosts=_hosts, tasks=_tasks,
pattern='all', options=const.TASK_OPTIONS,
run_as=_username,
run_as=_username, system_user=system_user
)
raw, summary = _task.run()
success = summary.get('success', False)

Binary file not shown.

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-07-13 16:52+0800\n"
"POT-Creation-Date: 2021-07-14 11:27+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -25,7 +25,7 @@ msgstr ""
#: orgs/models.py:23 perms/models/base.py:49 settings/models.py:29
#: terminal/models/storage.py:23 terminal/models/task.py:16
#: terminal/models/terminal.py:100 users/forms/profile.py:32
#: users/models/group.py:15 users/models/user.py:550
#: users/models/group.py:15 users/models/user.py:551
#: users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_asset_permission.html:37
#: users/templates/users/user_asset_permission.html:154
@ -61,7 +61,7 @@ msgstr "激活中"
#: orgs/models.py:26 perms/models/base.py:57 settings/models.py:34
#: terminal/models/storage.py:26 terminal/models/terminal.py:114
#: tickets/models/ticket.py:73 users/models/group.py:16
#: users/models/user.py:583 xpack/plugins/change_auth_plan/models.py:77
#: users/models/user.py:584 xpack/plugins/change_auth_plan/models.py:77
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:98
#: xpack/plugins/gathered_user/models.py:26
msgid "Comment"
@ -99,7 +99,7 @@ msgstr "动作"
#: terminal/backends/command/models.py:18
#: terminal/backends/command/serializers.py:12 terminal/models/session.py:38
#: tickets/models/comment.py:17 users/models/user.py:176
#: users/models/user.py:746 users/models/user.py:772
#: users/models/user.py:747 users/models/user.py:773
#: users/serializers/group.py:19
#: users/templates/users/user_asset_permission.html:38
#: users/templates/users/user_asset_permission.html:64
@ -121,9 +121,9 @@ msgstr "系统用户"
#: applications/serializers/attrs/application_category/remote_app.py:33
#: assets/models/asset.py:357 assets/models/authbook.py:15
#: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:33
#: assets/serializers/system_user.py:223 assets/serializers/system_user.py:248
#: audits/models.py:38 perms/models/asset_permission.py:99
#: templates/index.html:82 terminal/backends/command/models.py:19
#: assets/serializers/system_user.py:223 audits/models.py:38
#: perms/models/asset_permission.py:99 templates/index.html:82
#: terminal/backends/command/models.py:19
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:40
#: users/templates/users/user_asset_permission.html:40
#: users/templates/users/user_asset_permission.html:70
@ -179,7 +179,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
#: applications/serializers/attrs/application_type/vmware_client.py:26
#: assets/models/base.py:173 assets/models/gathered_user.py:15
#: audits/models.py:100 authentication/forms.py:15 authentication/forms.py:17
#: ops/models/adhoc.py:148 users/forms/profile.py:31 users/models/user.py:548
#: ops/models/adhoc.py:148 users/forms/profile.py:31 users/models/user.py:549
#: users/templates/users/_select_user_modal.html:14
#: xpack/plugins/change_auth_plan/models.py:47
#: xpack/plugins/change_auth_plan/models.py:278
@ -490,7 +490,7 @@ msgstr "标签管理"
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:26
#: assets/models/cmd_filter.py:67 assets/models/group.py:21
#: common/db/models.py:70 common/mixins/models.py:49 orgs/models.py:24
#: orgs/models.py:422 perms/models/base.py:55 users/models/user.py:591
#: orgs/models.py:422 perms/models/base.py:55 users/models/user.py:592
#: users/serializers/group.py:33 xpack/plugins/change_auth_plan/models.py:81
#: xpack/plugins/cloud/models.py:104 xpack/plugins/gathered_user/models.py:30
msgid "Created by"
@ -504,12 +504,11 @@ msgstr "创建者"
#: assets/models/label.py:25 common/db/models.py:72 common/mixins/models.py:50
#: ops/models/adhoc.py:38 ops/models/command.py:29 orgs/models.py:25
#: orgs/models.py:420 perms/models/base.py:56 users/models/group.py:18
#: users/models/user.py:773 xpack/plugins/cloud/models.py:107
#: users/models/user.py:774 xpack/plugins/cloud/models.py:107
msgid "Date created"
msgstr "创建日期"
#: assets/models/authbook.py:16 assets/models/user.py:276
#: assets/serializers/system_user.py:239 audits/models.py:39
#: assets/models/authbook.py:16 assets/models/user.py:276 audits/models.py:39
#: perms/models/application_permission.py:31
#: perms/models/asset_permission.py:101 templates/_nav.html:45
#: terminal/backends/command/models.py:20
@ -577,7 +576,7 @@ msgstr "带宽"
msgid "Contact"
msgstr "联系人"
#: assets/models/cluster.py:22 users/models/user.py:569
#: assets/models/cluster.py:22 users/models/user.py:570
msgid "Phone"
msgstr "手机"
@ -603,7 +602,7 @@ msgid "Default"
msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14
#: users/models/user.py:758
#: users/models/user.py:759
msgid "System"
msgstr "系统"
@ -875,6 +874,14 @@ msgstr "路径应该以 / 开头"
msgid "Password or private key required"
msgstr "密码或密钥密码需要一个"
#: assets/serializers/system_user.py:239
msgid "System user name"
msgstr "系统用户名称"
#: assets/serializers/system_user.py:248
msgid "Asset hostname"
msgstr "资产主机名"
#: assets/tasks/account_connectivity.py:30
msgid "The asset {} system platform {} does not support run Ansible tasks"
msgstr "资产 {} 系统平台 {} 不支持运行 Ansible 任务"
@ -1110,7 +1117,7 @@ msgstr "用户代理"
#: audits/models.py:105
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: authentication/templates/authentication/login_otp.html:6
#: users/forms/profile.py:64 users/models/user.py:572
#: users/forms/profile.py:64 users/models/user.py:573
#: users/serializers/profile.py:102
msgid "MFA"
msgstr "多因子认证"
@ -1435,13 +1442,13 @@ msgid "Show"
msgstr "显示"
#: authentication/templates/authentication/_access_key_modal.html:66
#: users/models/user.py:462 users/serializers/profile.py:99
#: users/models/user.py:463 users/serializers/profile.py:99
#: users/templates/users/user_verify_mfa.html:32
msgid "Disable"
msgstr "禁用"
#: authentication/templates/authentication/_access_key_modal.html:67
#: users/models/user.py:463 users/serializers/profile.py:100
#: users/models/user.py:464 users/serializers/profile.py:100
msgid "Enable"
msgstr "启用"
@ -1814,7 +1821,7 @@ msgstr ""
"div>"
#: notifications/backends/__init__.py:11 users/forms/profile.py:101
#: users/models/user.py:552
#: users/models/user.py:553
msgid "Email"
msgstr "邮件"
@ -2007,7 +2014,7 @@ msgstr "组织审计员"
msgid "GLOBAL"
msgstr "全局组织"
#: orgs/models.py:419 users/models/user.py:560
#: orgs/models.py:419 users/models/user.py:561
#: users/templates/users/_select_user_modal.html:15
msgid "Role"
msgstr "角色"
@ -2079,7 +2086,7 @@ msgid "Favorite"
msgstr "收藏夹"
#: perms/models/base.py:51 templates/_nav.html:21 users/models/group.py:31
#: users/models/user.py:556 users/templates/users/_select_user_modal.html:16
#: users/models/user.py:557 users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_asset_permission.html:39
#: users/templates/users/user_asset_permission.html:67
#: users/templates/users/user_database_app_permission.html:38
@ -2092,7 +2099,7 @@ msgstr "用户组"
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:77
#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:43
#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:81
#: users/models/user.py:588
#: users/models/user.py:589
msgid "Date expired"
msgstr "失效日期"
@ -3885,7 +3892,7 @@ msgstr "不能和原来的密钥相同"
msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法"
#: users/forms/profile.py:160 users/models/user.py:580
#: users/forms/profile.py:160 users/models/user.py:581
#: users/templates/users/user_password_update.html:48
msgid "Public key"
msgstr "SSH公钥"
@ -3898,43 +3905,43 @@ msgstr "系统管理员"
msgid "System auditor"
msgstr "系统审计员"
#: users/models/user.py:464
#: users/models/user.py:465
msgid "Force enable"
msgstr "强制启用"
#: users/models/user.py:529
#: users/models/user.py:530
msgid "Local"
msgstr "数据库"
#: users/models/user.py:563
#: users/models/user.py:564
msgid "Avatar"
msgstr "头像"
#: users/models/user.py:566
#: users/models/user.py:567
msgid "Wechat"
msgstr "微信"
#: users/models/user.py:577
#: users/models/user.py:578
msgid "Private key"
msgstr "ssh私钥"
#: users/models/user.py:596
#: users/models/user.py:597
msgid "Source"
msgstr "来源"
#: users/models/user.py:600
#: users/models/user.py:601
msgid "Date password last updated"
msgstr "最后更新密码日期"
#: users/models/user.py:603
#: users/models/user.py:604
msgid "Need update password"
msgstr "需要更新密码"
#: users/models/user.py:754
#: users/models/user.py:755
msgid "Administrator"
msgstr "管理员"
#: users/models/user.py:757
#: users/models/user.py:758
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
@ -5089,45 +5096,3 @@ msgstr "旗舰版"
#: xpack/plugins/license/models.py:77
msgid "Community edition"
msgstr "社区版"
#~ msgid "Latest version"
#~ msgstr "最新版本"
#~ msgid "Test admin user connectivity period: {}"
#~ msgstr "定期测试管理账号可连接性: {}"
#~ msgid "Test admin user connectivity: {}"
#~ msgstr "测试管理帐号可连接性: {}"
#~ msgid "Test asset user connectivity: {}"
#~ msgstr "测试资产用户可连接性: {}"
#~ msgid "{} Start task: {}"
#~ msgstr "{} 任务开始: {}"
#~ msgid "{} Task finish"
#~ msgstr "{} 任务结束"
#~ msgid "Deleted failed, There are related assets"
#~ msgstr "删除失败,存在关联资产"
#~ msgid "System user(Dynamic)"
#~ msgstr "系统用户(动态)"
#~ msgid "Could not remove asset admin user"
#~ msgstr "不能移除资产的管理用户账号"
#~ msgid "Latest version could not be delete"
#~ msgstr "最新版本的不能被删除"
#~ msgid "Bulk delete deny"
#~ msgstr "拒绝批量删除"
#~ msgid "Admin user name"
#~ msgstr "管理用户名称"
#~ msgid "Backend"
#~ msgstr "后端"
#~ msgid "Terminal command alert"
#~ msgstr "终端命令告警"

View File

@ -0,0 +1,20 @@
# Generated by Django 3.1.6 on 2021-07-14 08:44
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('assets', '0076_delete_assetuser'),
('ops', '0019_adhocexecution_celery_task_id'),
]
operations = [
migrations.AddField(
model_name='adhoc',
name='run_system_user',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='assets.systemuser'),
),
]

View File

@ -146,6 +146,7 @@ class AdHoc(OrgModelMixin):
hosts = models.ManyToManyField('assets.Asset', verbose_name=_("Host"))
run_as_admin = models.BooleanField(default=False, verbose_name=_('Run as admin'))
run_as = models.CharField(max_length=64, default='', blank=True, null=True, verbose_name=_('Username'))
run_system_user = models.ForeignKey('assets.SystemUser', null=True, on_delete=models.CASCADE)
become = EncryptJsonDictCharField(max_length=1024, default='', blank=True, null=True, verbose_name=_("Become"))
created_by = models.CharField(max_length=64, default='', blank=True, null=True, verbose_name=_('Create by'))
date_created = models.DateTimeField(auto_now_add=True, db_index=True)
@ -167,7 +168,7 @@ class AdHoc(OrgModelMixin):
inventory = JMSInventory(
self.hosts.all(), run_as_admin=self.run_as_admin,
run_as=self.run_as, become_info=become_info
run_as=self.run_as, become_info=become_info, system_user=self.run_system_user
)
return inventory

View File

@ -28,7 +28,7 @@ def update_or_create_ansible_task(
task_name, hosts, tasks,
interval=None, crontab=None, is_periodic=False,
callback=None, pattern='all', options=None,
run_as_admin=False, run_as=None, become_info=None,
run_as_admin=False, run_as=None, system_user=None, become_info=None,
):
if not hosts or not tasks or not task_name:
return None, None
@ -49,7 +49,7 @@ def update_or_create_ansible_task(
adhoc = task.get_latest_adhoc()
new_adhoc = AdHoc(task=task, pattern=pattern,
run_as_admin=run_as_admin,
run_as=run_as)
run_as=run_as, run_system_user=system_user)
new_adhoc.tasks = tasks
new_adhoc.options = options
new_adhoc.become = become_info

View File

@ -54,8 +54,8 @@ class OrgResourceStatisticsCache(OrgRelatedCache):
assets_amount = IntegerField()
nodes_amount = IntegerField(queryset=Node.objects)
admin_users_amount = IntegerField(queryset=AdminUser.objects)
system_users_amount = IntegerField(queryset=SystemUser.objects)
admin_users_amount = IntegerField(queryset=SystemUser.objects.filter(type=SystemUser.Type.admin))
system_users_amount = IntegerField(queryset=SystemUser.objects.filter(type=SystemUser.Type.common))
domains_amount = IntegerField(queryset=Domain.objects)
gateways_amount = IntegerField(queryset=Gateway.objects)

View File

@ -55,8 +55,7 @@ class OrgResourceStatisticsRefreshUtil:
Application: ['applications_amount'],
Gateway: ['gateways_amount'],
Domain: ['domains_amount'],
SystemUser: ['system_users_amount'],
AdminUser: ['admin_users_amount'],
SystemUser: ['system_users_amount', 'admin_users_amount'],
Node: ['nodes_amount'],
Asset: ['assets_amount'],
UserGroup: ['groups_amount'],

View File

@ -15,7 +15,7 @@ logger = get_logger(__file__)
@register_as_period_task(interval=settings.PERM_EXPIRED_CHECK_PERIODIC)
@shared_task(queue='celery_check_asset_perm_expired')
@shared_task()
@atomic()
def check_asset_permission_expired():
"""