mirror of https://github.com/jumpserver/jumpserver
commit
2f0fcddc29
|
@ -42,7 +42,6 @@ class AssetViewSet(FilterAssetByNodeMixin, OrgBulkModelViewSet):
|
||||||
ordering_fields = ("hostname", "ip", "port", "cpu_cores")
|
ordering_fields = ("hostname", "ip", "port", "cpu_cores")
|
||||||
serializer_classes = {
|
serializer_classes = {
|
||||||
'default': serializers.AssetSerializer,
|
'default': serializers.AssetSerializer,
|
||||||
'single': serializers.AssetVerboseSerializer,
|
|
||||||
}
|
}
|
||||||
permission_classes = (IsOrgAdminOrAppUser,)
|
permission_classes = (IsOrgAdminOrAppUser,)
|
||||||
extra_filter_backends = [FilterAssetByNodeFilterBackend, LabelFilterBackend, IpInFilterBackend]
|
extra_filter_backends = [FilterAssetByNodeFilterBackend, LabelFilterBackend, IpInFilterBackend]
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Generated by Django 3.1.6 on 2021-06-04 16:46
|
# Generated by Django 3.1.6 on 2021-06-04 16:46
|
||||||
|
|
||||||
from django.db import migrations, models, transaction
|
from django.db import migrations, models, transaction
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db.models import F
|
||||||
|
|
||||||
|
|
||||||
def migrate_admin_user_to_system_user(apps, schema_editor):
|
def migrate_admin_user_to_system_user(apps, schema_editor):
|
||||||
|
@ -40,6 +42,13 @@ def migrate_admin_user_to_system_user(apps, schema_editor):
|
||||||
s.assets.set(assets)
|
s.assets.set(assets)
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_assets_admin_user(apps, schema_editor):
|
||||||
|
asset_model = apps.get_model("assets", "Asset")
|
||||||
|
db_alias = schema_editor.connection.alias
|
||||||
|
assets = asset_model.objects.using(db_alias).all()
|
||||||
|
assets.update(admin_user=F('_admin_user'))
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
@ -62,5 +71,20 @@ class Migration(migrations.Migration):
|
||||||
name='protocol',
|
name='protocol',
|
||||||
field=models.CharField(choices=[('ssh', 'SSH'), ('rdp', 'RDP'), ('telnet', 'Telnet'), ('vnc', 'VNC'), ('mysql', 'MySQL'), ('oracle', 'Oracle'), ('mariadb', 'MariaDB'), ('postgresql', 'PostgreSQL'), ('k8s', 'K8S')], default='ssh', max_length=16, verbose_name='Protocol'),
|
field=models.CharField(choices=[('ssh', 'SSH'), ('rdp', 'RDP'), ('telnet', 'Telnet'), ('vnc', 'VNC'), ('mysql', 'MySQL'), ('oracle', 'Oracle'), ('mariadb', 'MariaDB'), ('postgresql', 'PostgreSQL'), ('k8s', 'K8S')], default='ssh', max_length=16, verbose_name='Protocol'),
|
||||||
),
|
),
|
||||||
migrations.RunPython(migrate_admin_user_to_system_user)
|
migrations.RunPython(migrate_admin_user_to_system_user),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='asset',
|
||||||
|
old_name='admin_user',
|
||||||
|
new_name='_admin_user',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='admin_user',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='admin_assets', to='assets.systemuser', verbose_name='Admin user'),
|
||||||
|
),
|
||||||
|
migrations.RunPython(migrate_assets_admin_user),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='asset',
|
||||||
|
name='_admin_user',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# Generated by Django 3.1.6 on 2021-06-06 03:40
|
# Generated by Django 3.1.6 on 2021-06-06 03:40
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -14,11 +15,7 @@ class Migration(migrations.Migration):
|
||||||
model_name='systemuser',
|
model_name='systemuser',
|
||||||
name='assets',
|
name='assets',
|
||||||
),
|
),
|
||||||
migrations.RenameField(
|
|
||||||
model_name='asset',
|
|
||||||
old_name='admin_user',
|
|
||||||
new_name='_admin_user',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='systemuser',
|
model_name='systemuser',
|
||||||
name='assets',
|
name='assets',
|
||||||
|
|
|
@ -7,7 +7,6 @@ import logging
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.utils import timezone
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from common.db.models import TextChoices
|
from common.db.models import TextChoices
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
@ -191,7 +190,7 @@ class Asset(AbsConnectivity, ProtocolsMixin, NodesRelationMixin, OrgModelMixin):
|
||||||
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
||||||
|
|
||||||
# Auth
|
# Auth
|
||||||
_admin_user = models.ForeignKey('assets.AdminUser', on_delete=models.PROTECT, null=True, verbose_name=_("Admin user"), related_name='assets')
|
admin_user = models.ForeignKey('assets.SystemUser', on_delete=models.SET_NULL, null=True, verbose_name=_("Admin user"), related_name='admin_assets')
|
||||||
|
|
||||||
# Some information
|
# Some information
|
||||||
public_ip = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Public IP'))
|
public_ip = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Public IP'))
|
||||||
|
@ -225,22 +224,15 @@ class Asset(AbsConnectivity, ProtocolsMixin, NodesRelationMixin, OrgModelMixin):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{0.hostname}({0.ip})'.format(self)
|
return '{0.hostname}({0.ip})'.format(self)
|
||||||
|
|
||||||
__admin_user = None
|
def set_admin_user_relation(self):
|
||||||
|
from .authbook import AuthBook
|
||||||
@property
|
if not self.admin_user:
|
||||||
def admin_user(self):
|
|
||||||
# 解决每次获取资产管理用户时都是最新的对象
|
|
||||||
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):
|
|
||||||
if not system_user:
|
|
||||||
return
|
return
|
||||||
if system_user.type != 'admin':
|
if self.admin_user.type != 'admin':
|
||||||
raise ValidationError('System user should be type admin')
|
raise ValidationError('System user should be type admin')
|
||||||
system_user.assets.add(self)
|
|
||||||
|
defaults = {'asset': self, 'systemuser': self.admin_user, 'org_id': self.org_id}
|
||||||
|
AuthBook.objects.get_or_create(defaults=defaults, asset=self, systemuser=self.admin_user)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def admin_user_display(self):
|
def admin_user_display(self):
|
||||||
|
@ -248,10 +240,6 @@ class Asset(AbsConnectivity, ProtocolsMixin, NodesRelationMixin, OrgModelMixin):
|
||||||
return ''
|
return ''
|
||||||
return str(self.admin_user)
|
return str(self.admin_user)
|
||||||
|
|
||||||
def remove_admin_user(self):
|
|
||||||
from ..models import AuthBook
|
|
||||||
AuthBook.objects.filter(asset=self, systemuser__type='admin').delete()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
warning = ''
|
warning = ''
|
||||||
|
|
|
@ -8,7 +8,7 @@ from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
from ..models import Asset, Node, Platform, SystemUser
|
from ..models import Asset, Node, Platform, SystemUser
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'AssetSerializer', 'AssetSimpleSerializer', 'AssetVerboseSerializer',
|
'AssetSerializer', 'AssetSimpleSerializer',
|
||||||
'ProtocolsField', 'PlatformSerializer',
|
'ProtocolsField', 'PlatformSerializer',
|
||||||
'AssetTaskSerializer',
|
'AssetTaskSerializer',
|
||||||
]
|
]
|
||||||
|
@ -62,9 +62,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
|
||||||
platform = serializers.SlugRelatedField(
|
platform = serializers.SlugRelatedField(
|
||||||
slug_field='name', queryset=Platform.objects.all(), label=_("Platform")
|
slug_field='name', queryset=Platform.objects.all(), label=_("Platform")
|
||||||
)
|
)
|
||||||
admin_user = serializers.PrimaryKeyRelatedField(
|
|
||||||
queryset=SystemUser.objects, label=_('Admin user'), write_only=True
|
|
||||||
)
|
|
||||||
protocols = ProtocolsField(label=_('Protocols'), required=False, default=['ssh/22'])
|
protocols = ProtocolsField(label=_('Protocols'), required=False, default=['ssh/22'])
|
||||||
domain_display = serializers.ReadOnlyField(source='domain.name', label=_('Domain name'))
|
domain_display = serializers.ReadOnlyField(source='domain.name', label=_('Domain name'))
|
||||||
nodes_display = serializers.ListField(child=serializers.CharField(), label=_('Nodes name'), required=False)
|
nodes_display = serializers.ListField(child=serializers.CharField(), label=_('Nodes name'), required=False)
|
||||||
|
@ -83,7 +80,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
|
||||||
'hardware_info', 'connectivity', 'date_verified'
|
'hardware_info', 'connectivity', 'date_verified'
|
||||||
]
|
]
|
||||||
fields_fk = [
|
fields_fk = [
|
||||||
'domain', 'domain_display', 'platform', 'admin_user',
|
'domain', 'domain_display', 'platform', 'admin_user', 'admin_user_display'
|
||||||
]
|
]
|
||||||
fields_m2m = [
|
fields_m2m = [
|
||||||
'nodes', 'nodes_display', 'labels',
|
'nodes', 'nodes_display', 'labels',
|
||||||
|
@ -112,7 +109,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_eager_loading(cls, queryset):
|
def setup_eager_loading(cls, queryset):
|
||||||
""" Perform necessary eager loading of data. """
|
""" Perform necessary eager loading of data. """
|
||||||
queryset = queryset.prefetch_related('domain', 'platform')
|
queryset = queryset.prefetch_related('domain', 'platform', 'admin_user')
|
||||||
queryset = queryset.prefetch_related('nodes', 'labels')
|
queryset = queryset.prefetch_related('nodes', 'labels')
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
@ -147,31 +144,18 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
self.compatible_with_old_protocol(validated_data)
|
self.compatible_with_old_protocol(validated_data)
|
||||||
nodes_display = validated_data.pop('nodes_display', '')
|
nodes_display = validated_data.pop('nodes_display', '')
|
||||||
admin_user = validated_data.pop('admin_user', '')
|
|
||||||
instance = super().create(validated_data)
|
instance = super().create(validated_data)
|
||||||
self.perform_nodes_display_create(instance, nodes_display)
|
self.perform_nodes_display_create(instance, nodes_display)
|
||||||
instance.admin_user = admin_user
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
nodes_display = validated_data.pop('nodes_display', '')
|
nodes_display = validated_data.pop('nodes_display', '')
|
||||||
self.compatible_with_old_protocol(validated_data)
|
self.compatible_with_old_protocol(validated_data)
|
||||||
admin_user = validated_data.pop('admin_user', '')
|
|
||||||
instance = super().update(instance, validated_data)
|
instance = super().update(instance, validated_data)
|
||||||
self.perform_nodes_display_create(instance, nodes_display)
|
self.perform_nodes_display_create(instance, nodes_display)
|
||||||
instance.admin_user = admin_user
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class AssetVerboseSerializer(AssetSerializer):
|
|
||||||
admin_user = serializers.PrimaryKeyRelatedField(
|
|
||||||
queryset=SystemUser.objects, label=_('Admin user')
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(AssetSerializer.Meta):
|
|
||||||
fields = AssetSerializer.Meta.fields + ['admin_user_display']
|
|
||||||
|
|
||||||
|
|
||||||
class PlatformSerializer(serializers.ModelSerializer):
|
class PlatformSerializer(serializers.ModelSerializer):
|
||||||
meta = serializers.DictField(required=False, allow_null=True, label=_('Meta'))
|
meta = serializers.DictField(required=False, allow_null=True, label=_('Meta'))
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ def on_asset_created_or_update(sender, instance=None, created=False, **kwargs):
|
||||||
if not has_node:
|
if not has_node:
|
||||||
instance.nodes.add(Node.org_root())
|
instance.nodes.add(Node.org_root())
|
||||||
|
|
||||||
|
instance.set_admin_user_relation()
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=Asset.nodes.through)
|
@receiver(m2m_changed, sender=Asset.nodes.through)
|
||||||
def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs):
|
def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs):
|
||||||
|
@ -96,7 +98,8 @@ def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs):
|
||||||
asset_ids_to_push.append(asset_id)
|
asset_ids_to_push.append(asset_id)
|
||||||
to_create.append(m2m_model(
|
to_create.append(m2m_model(
|
||||||
systemuser_id=system_user_id,
|
systemuser_id=system_user_id,
|
||||||
asset_id=asset_id
|
asset_id=asset_id,
|
||||||
|
org_id=instance.org_id
|
||||||
))
|
))
|
||||||
if asset_ids_to_push:
|
if asset_ids_to_push:
|
||||||
push_system_user_to_assets.delay(system_user_id, asset_ids_to_push)
|
push_system_user_to_assets.delay(system_user_id, asset_ids_to_push)
|
||||||
|
|
|
@ -4,7 +4,6 @@ from simple_history.signals import pre_create_historical_record
|
||||||
from django.db.models.signals import post_save, pre_save
|
from django.db.models.signals import post_save, pre_save
|
||||||
|
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from orgs.utils import tmp_to_root_org
|
|
||||||
from ..models import AuthBook, SystemUser
|
from ..models import AuthBook, SystemUser
|
||||||
|
|
||||||
AuthBookHistory = apps.get_model('assets', 'HistoricalAuthBook')
|
AuthBookHistory = apps.get_model('assets', 'HistoricalAuthBook')
|
||||||
|
@ -31,15 +30,6 @@ def pre_create_historical_record_callback(sender, history_instance=None, **kwarg
|
||||||
|
|
||||||
@receiver(post_save, sender=AuthBook)
|
@receiver(post_save, sender=AuthBook)
|
||||||
def on_authbook_post_create(sender, instance, **kwargs):
|
def on_authbook_post_create(sender, instance, **kwargs):
|
||||||
# 去掉这个资产的管理用户
|
|
||||||
if instance.systemuser and instance.systemuser.is_admin_user:
|
|
||||||
with tmp_to_root_org():
|
|
||||||
deleted_count, other = AuthBook.objects.filter(
|
|
||||||
asset=instance.asset,
|
|
||||||
systemuser__type=SystemUser.Type.admin
|
|
||||||
).exclude(id=instance.id).delete()
|
|
||||||
logger.debug('Remove asset old admin user: {}'.format(deleted_count))
|
|
||||||
|
|
||||||
if not instance.systemuser:
|
if not instance.systemuser:
|
||||||
instance.sync_to_system_user_account()
|
instance.sync_to_system_user_account()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue