diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index 1f75b49fc..8e9edc3e2 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -33,7 +33,7 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): """ filter_fields = ("hostname", "ip") search_fields = filter_fields - ordering_fields = ("hostname", "ip", "port", "cluster", "cpu_cores") + ordering_fields = ("hostname", "ip", "port", "cpu_cores") queryset = Asset.objects.all() serializer_class = serializers.AssetSerializer pagination_class = LimitOffsetPagination @@ -47,13 +47,9 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): if admin_user_id: admin_user = get_object_or_404(AdminUser, id=admin_user_id) - 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)) + queryset = queryset.filter(admin_user=admin_user) 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) if node_id: node = get_object_or_404(Node, id=node_id) queryset = queryset.filter(nodes__key__startswith=node.key).distinct() diff --git a/apps/assets/api/system_user.py b/apps/assets/api/system_user.py index d19cf152c..c34690076 100644 --- a/apps/assets/api/system_user.py +++ b/apps/assets/api/system_user.py @@ -20,7 +20,7 @@ from common.utils import get_logger from ..hands import IsSuperUser, IsSuperUserOrAppUser from ..models import SystemUser from .. import serializers -from ..tasks import push_system_user_to_cluster_assets_manual, \ +from ..tasks import push_system_user_to_assets_manual, \ test_system_user_connectability_manual @@ -68,7 +68,7 @@ class SystemUserPushApi(generics.RetrieveAPIView): def retrieve(self, request, *args, **kwargs): system_user = self.get_object() - push_system_user_to_cluster_assets_manual.delay(system_user) + push_system_user_to_assets_manual.delay(system_user) return Response({"msg": "Task created"}) diff --git a/apps/assets/forms/asset.py b/apps/assets/forms/asset.py index 593c35456..8aaf8158b 100644 --- a/apps/assets/forms/asset.py +++ b/apps/assets/forms/asset.py @@ -34,7 +34,9 @@ class AssetCreateForm(forms.ModelForm): 'hostname': '* required', 'ip': '* required', 'port': '* required', - 'admin_user': _('') + 'admin_user': _('Admin user is a privilege user exist on this asset,' + 'Example: root or other NOPASSWD sudo privilege user' + ) } diff --git a/apps/assets/forms/user.py b/apps/assets/forms/user.py index 6488a6004..24807ca08 100644 --- a/apps/assets/forms/user.py +++ b/apps/assets/forms/user.py @@ -114,22 +114,22 @@ class SystemUserForm(PasswordAndKeyAuthForm): fields = [ 'name', 'username', 'protocol', 'auto_generate_key', 'password', 'private_key_file', 'auto_push', 'sudo', - 'comment', 'shell', 'cluster', 'priority', + 'comment', 'shell', 'nodes', 'priority', ] widgets = { 'name': forms.TextInput(attrs={'placeholder': _('Name')}), 'username': forms.TextInput(attrs={'placeholder': _('Username')}), - 'cluster': forms.SelectMultiple( + 'nodes': forms.SelectMultiple( attrs={ 'class': 'select2', - 'data-placeholder': _(' Select clusters') + 'data-placeholder': _('Nodes') } ), } help_texts = { 'name': '* required', 'username': '* required', - 'cluster': _('If auto push checked, system user will be create at cluster assets'), + 'nodes': _('If auto push checked, system user will be create at node 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'), } \ No newline at end of file diff --git a/apps/assets/hands.py b/apps/assets/hands.py index 403a08633..ad44052d3 100644 --- a/apps/assets/hands.py +++ b/apps/assets/hands.py @@ -11,8 +11,7 @@ """ -from users.utils import AdminUserRequiredMixin -from users.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser +from common.mixins import AdminUserRequiredMixin +from common.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser from users.models import User, UserGroup from perms.utils import NodePermissionUtil -from perms.tasks import push_users \ No newline at end of file diff --git a/apps/assets/models/__init__.py b/apps/assets/models/__init__.py index b4b0b8707..dbc703706 100644 --- a/apps/assets/models/__init__.py +++ b/apps/assets/models/__init__.py @@ -5,6 +5,6 @@ from .user import AdminUser, SystemUser from .label import Label from .cluster import * from .group import * -from .tree import * +from .node import * from .asset import * from .utils import * diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index d8e4ebe82..b101d63f9 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -29,8 +29,11 @@ def default_cluster(): def default_node(): - from .tree import Node - return Node.root() + try: + from .tree import Node + return Node.root() + except: + return None class Asset(models.Model): @@ -43,7 +46,7 @@ class Asset(models.Model): is_active = models.BooleanField(default=True, verbose_name=_('Is active')) # Auth - admin_user = models.ForeignKey('assets.AdminUser', on_delete=models.PROTECT, verbose_name=_("Admin user")) + admin_user = models.ForeignKey('assets.AdminUser', on_delete=models.PROTECT, verbose_name=_("Admin user")) # Some information public_ip = models.GenericIPAddressField(max_length=32, blank=True, null=True, verbose_name=_('Public IP')) @@ -102,30 +105,12 @@ class Asset(models.Model): else: return False - @property - def admin_user_avail(self): - if self.admin_user: - admin_user = self.admin_user - elif self.cluster and self.cluster.admin_user: - admin_user = self.cluster.admin_user - else: - return None - return admin_user - - @property - def is_has_private_admin_user(self): - if self.admin_user: - return True - else: - return False - def to_json(self): return { 'id': self.id, 'hostname': self.hostname, 'ip': self.ip, 'port': self.port, - 'groups': [group.name for group in self.groups.all()], } def _to_secret_json(self): @@ -136,13 +121,14 @@ class Asset(models.Model): Todo: May be move to ops implements it """ data = self.to_json() - if self.admin_user_avail: - admin_user = self.admin_user_avail + if self.admin_user: + admin_user = self.admin_user data.update({ 'username': admin_user.username, 'password': admin_user.password, 'private_key': admin_user.private_key_file, 'become': admin_user.become_info, + 'groups': [node.value for node in self.nodes.all()], }) return data @@ -161,7 +147,6 @@ class Asset(models.Model): asset = cls(ip='%s.%s.%s.%s' % (i, i, i, i), hostname=forgery_py.internet.user_name(True), admin_user=choice(AdminUser.objects.all()), - cluster=choice(Cluster.objects.all()), port=22, created_by='Fake') try: diff --git a/apps/assets/models/tree.py b/apps/assets/models/node.py similarity index 85% rename from apps/assets/models/tree.py rename to apps/assets/models/node.py index a62b3c1bd..7c5e8f450 100644 --- a/apps/assets/models/tree.py +++ b/apps/assets/models/node.py @@ -24,7 +24,7 @@ class Node(models.Model): if self == self.__class__.root(): return self.value else: - return '{}/{}'.format( self.value, self.parent.full_value) + return '{}/{}'.format(self.value, self.parent.full_value) @property def level(self): @@ -78,6 +78,19 @@ class Node(models.Model): else: return parent + @property + def ancestor(self): + if self.parent == self.__class__.root(): + return [self.__class__.root()] + else: + return [self.parent, *tuple(self.parent.ancestor)] + + @property + def ancestor_with_node(self): + ancestor = self.ancestor + ancestor.insert(0, self) + return ancestor + @classmethod def root(cls): obj, created = cls.objects.get_or_create( diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index e536f7902..a8c24420f 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -218,7 +218,7 @@ class SystemUser(AssetUser): (RDP_PROTOCOL, 'rdp'), ) - cluster = models.ManyToManyField('assets.Cluster', blank=True, verbose_name=_("Cluster")) + nodes = models.ManyToManyField('assets.Node', blank=True, verbose_name=_("Nodes")) priority = models.IntegerField(default=10, verbose_name=_("Priority")) protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol')) auto_push = models.BooleanField(default=True, verbose_name=_('Auto push')) @@ -228,21 +228,6 @@ class SystemUser(AssetUser): def __str__(self): return self.name - def get_clusters_assets(self): - from .asset import Asset - clusters = self.get_clusters() - return Asset.objects.filter(cluster__in=clusters) - - def get_clusters(self): - return self.cluster.all() - - def get_clusters_joined(self): - return ', '.join([cluster.name for cluster in self.get_clusters()]) - - @property - def assets_amount(self): - return len(self.get_clusters_assets()) - def to_json(self): return { 'id': self.id, @@ -266,6 +251,12 @@ class SystemUser(AssetUser): def reachable_assets(self): return self.assets_connective.get('contacted', []) + def is_need_push(self): + if self.auto_push and self.protocol == self.__class__.SSH_PROTOCOL: + return True + else: + return False + class Meta: ordering = ['name'] verbose_name = _("System user") diff --git a/apps/assets/signals.py b/apps/assets/signals.py index a02a16d20..20da657b1 100644 --- a/apps/assets/signals.py +++ b/apps/assets/signals.py @@ -3,4 +3,3 @@ from django.dispatch import Signal on_app_ready = Signal() -on_system_user_auth_changed = Signal(providing_args=['system_user']) diff --git a/apps/assets/signals_handler.py b/apps/assets/signals_handler.py index 659a40a40..95c57e4cb 100644 --- a/apps/assets/signals_handler.py +++ b/apps/assets/signals_handler.py @@ -1,15 +1,14 @@ # -*- coding: utf-8 -*- # -from django.db.models.signals import post_save, post_init +from django.db.models.signals import post_save, m2m_changed from django.dispatch import receiver -from django.utils.translation import gettext as _ from common.utils import get_logger -from .models import Asset, SystemUser, Cluster +from .models import Asset, SystemUser, Node from .tasks import update_assets_hardware_info_util, \ - test_asset_connectability_util, \ - push_system_user_util + test_asset_connectability_util, push_system_user_to_node, \ + push_node_system_users_to_asset logger = get_logger(__file__) @@ -25,92 +24,42 @@ def test_asset_conn_on_created(asset): test_asset_connectability_util.delay(asset) -def push_cluster_system_users_to_asset(asset): - 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)) update_asset_hardware_info_on_created(instance) test_asset_conn_on_created(instance) - # push_cluster_system_users_to_asset(instance) -# def push_to_cluster_assets_on_system_user_created_or_update(system_user): -# if not system_user.auto_push: -# return -# logger.debug("Push system user `{}` to cluster assets".format(system_user.name)) -# for cluster in system_user.cluster.all(): -# task_name = _("Push system user to cluster assets: {}->{}").format( -# cluster.name, system_user.name -# ) -# assets = cluster.assets.all() -# push_system_user_util.delay([system_user], assets, task_name) +@receiver(post_save, sender=SystemUser, dispatch_uid="my_unique_identifier") +def on_system_user_update(sender, instance=None, created=True, **kwargs): + if instance and not created: + for node in instance.nodes.all(): + push_system_user_to_node(instance, node) -# @receiver(post_save, sender=SystemUser) -# def on_system_user_created_or_updated(sender, instance=None, **kwargs): -# if instance and instance.auto_push: -# logger.info("System user `{}` create or update signal received".format(instance)) -# push_to_cluster_assets_on_system_user_created_or_update(instance) -# -# -# @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.values_list('pk', flat=True)) -# -# -# @receiver(post_save, sender=Cluster, dispatch_uid="my_unique_identifier") -# def on_cluster_assets_changed(sender, instance, **kwargs): -# assets_origin = instance.__original_assets -# assets_new = instance.assets.values_list('pk', flat=True) -# assets_added = set(assets_new) - set(assets_origin) -# if assets_added: -# logger.debug("Receive cluster change assets signal") -# logger.debug("Push cluster `{}` system users to: {}".format( -# instance, ', '.join([str(asset) for asset in assets_added]) -# )) -# assets = [] -# for asset_id in assets_added: -# try: -# asset = Asset.objects.get(pk=asset_id) -# except Asset.DoesNotExist: -# continue -# else: -# assets.append(asset) -# system_users = [s for s in instance.systemuser_set.all() if s.auto_push] -# task_name = _("Push system user to assets") -# push_system_user_util.delay(system_users, assets, task_name) -# -# -# @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) - set(system_users_origin) -# if system_users_added: -# logger.debug("Receive cluster change system users signal") -# system_users = [] -# for system_user_id in system_users_added: -# try: -# system_user = SystemUser.objects.get(pk=system_user_id) -# except SystemUser.DoesNotExist: -# continue -# else: -# system_users.append(system_user) -# logger.debug("Push new system users `{}` to cluster `{}` assets".format( -# ','.join([s.name for s in system_users]), instance -# )) -# task_name = _( -# "Push system user to cluster assets: {}->{}").format( -# instance.name, ', '.join(s.name for s in system_users) -# ) - push_system_user_util.delay(system_users, instance.assets.all(), task_name) +@receiver(m2m_changed, sender=SystemUser.nodes.through) +def on_system_user_node_change(sender, instance=None, **kwargs): + if instance and kwargs["action"] == "post_add": + for pk in kwargs['pk_set']: + node = kwargs['model'].objects.get(pk=pk) + push_system_user_to_node(instance, node) + + +@receiver(m2m_changed, sender=Asset.nodes.through) +def on_asset_node_changed(sender, instance=None, **kwargs): + if isinstance(instance, Asset) and kwargs['action'] == 'post_add': + logger.debug("Asset node change signal received") + for pk in kwargs['pk_set']: + node = kwargs['model'].objects.get(pk=pk) + push_node_system_users_to_asset(node, [instance]) + + +@receiver(m2m_changed, sender=Asset.nodes.through) +def on_node_assets_changed(sender, instance=None, **kwargs): + if isinstance(instance, Node) and kwargs['action'] == 'post_add': + logger.debug("Node assets change signal received") + assets = kwargs['model'].objects.filter(pk__in=kwargs['pk_set']) + push_node_system_users_to_asset(instance, assets) diff --git a/apps/assets/tasks.py b/apps/assets/tasks.py index 4fc5b023b..25dec8af7 100644 --- a/apps/assets/tasks.py +++ b/apps/assets/tasks.py @@ -99,7 +99,7 @@ def update_assets_hardware_info_util(assets, task_name=None): result = task.run() # Todo: may be somewhere using # Manual run callback function - assets_updated = set_assets_hardware_info(result) + set_assets_hardware_info(result) return result @@ -262,21 +262,23 @@ def test_system_user_connectability_util(system_user, task_name): :param task_name: :return: """ - from ops.utils import update_or_create_ansible_task - 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, - run_as=system_user.name, created_by="System", - ) - result = task.run() - set_system_user_connectablity_info(result, system_user=system_user.name) - return result + # todo + # from ops.utils import update_or_create_ansible_task + # 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, + # run_as=system_user.name, created_by="System", + # ) + # result = task.run() + # set_system_user_connectablity_info(result, system_user=system_user.name) + # return result + return {} @shared_task @@ -290,21 +292,23 @@ def test_system_user_connectability_manual(system_user): @after_app_ready_start @after_app_shutdown_clean def test_system_user_connectability_period(): - from ops.utils import update_or_create_ansible_task - system_users = SystemUser.objects.all() - for system_user in system_users: - task_name = _("Test system user connectability period: {}").format( - system_user.name - ) - assets = system_user.get_clusters_assets() - hosts = [asset.hostname for asset in assets] - tasks = const.TEST_SYSTEM_USER_CONN_TASKS - update_or_create_ansible_task( - task_name=task_name, hosts=hosts, tasks=tasks, pattern='all', - options=const.TASK_OPTIONS, run_as_admin=False, run_as=system_user.name, - created_by='System', interval=3600, is_periodic=True, - callback=set_admin_user_connectability_info.name, - ) + # Todo + pass + # from ops.utils import update_or_create_ansible_task + # system_users = SystemUser.objects.all() + # for system_user in system_users: + # task_name = _("Test system user connectability period: {}").format( + # system_user.name + # ) + # assets = system_user.get_clusters_assets() + # hosts = [asset.hostname for asset in assets] + # tasks = const.TEST_SYSTEM_USER_CONN_TASKS + # update_or_create_ansible_task( + # task_name=task_name, hosts=hosts, tasks=tasks, pattern='all', + # options=const.TASK_OPTIONS, run_as_admin=False, run_as=system_user.name, + # created_by='System', interval=3600, is_periodic=True, + # callback=set_admin_user_connectability_info.name, + # ) #### Push system user tasks #### @@ -315,7 +319,6 @@ def get_push_system_user_tasks(system_user): return [] tasks = [] - if system_user.password: tasks.append({ 'name': 'Add user {}'.format(system_user.username), @@ -358,7 +361,8 @@ def push_system_user_util(system_users, assets, task_name): from ops.utils import update_or_create_ansible_task tasks = [] for system_user in system_users: - tasks.extend(get_push_system_user_tasks(system_user)) + if system_user.is_need_push(): + tasks.extend(get_push_system_user_tasks(system_user)) if not tasks: logger.info("Not tasks, passed") @@ -375,11 +379,41 @@ def push_system_user_util(system_users, assets, task_name): return task.run() +def get_node_push_system_user_task_name(system_user, node): + return _("Push system user to node: {} => {}").format( + system_user.name, + node.value + ) + + +def push_system_user_to_node(system_user, node): + assets = node.get_all_assets() + task_name = get_node_push_system_user_task_name(system_user, node) + push_system_user_util.delay([system_user], assets, task_name) + + @shared_task -def push_system_user_to_cluster_assets_manual(system_user): - task_name = _("Push system user to cluster assets: {}").format(system_user.name) - assets = system_user.get_clusters_assets() - return push_system_user_util([system_user], assets, task_name) +def push_system_user_related_nodes(system_user): + nodes = system_user.nodes.all() + for node in nodes: + push_system_user_to_node(system_user, node) + + +@shared_task +def push_system_user_to_assets_manual(system_user): + push_system_user_related_nodes(system_user) + + +def push_node_system_users_to_asset(node, assets): + system_users = [] + nodes = node.ancestor_with_node + # 获取该节点所有父节点有的系统用户, 然后推送 + for n in nodes: + system_users.extend(list(n.systemuser_set.all())) + + if system_users: + task_name = _("Push system users to node: {}").format(node.value) + push_system_user_util.delay(system_users, assets, task_name) @shared_task @@ -387,23 +421,5 @@ def push_system_user_to_cluster_assets_manual(system_user): @after_app_ready_start @after_app_shutdown_clean def push_system_user_period(): - from ops.utils import update_or_create_ansible_task - clusters = Cluster.objects.all() - - for cluster in clusters: - tasks = [] - system_users = [system_user for system_user in cluster.systemuser_set.all() if system_user.auto_push] - if not system_users: - return - for system_user in system_users: - tasks.extend(get_push_system_user_tasks(system_user)) - - 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( - task_name=task_name, hosts=hosts, tasks=tasks, pattern='all', - options=const.TASK_OPTIONS, run_as_admin=True, created_by='System', - interval=60*60*24, is_periodic=True, - ) + for system_user in SystemUser.objects.all(): + push_system_user_related_nodes(system_user) diff --git a/apps/assets/templates/assets/_system_user.html b/apps/assets/templates/assets/_system_user.html index 4ebb64279..fe06a6fc7 100644 --- a/apps/assets/templates/assets/_system_user.html +++ b/apps/assets/templates/assets/_system_user.html @@ -39,7 +39,6 @@ {% bootstrap_field form.username layout="horizontal" %} {% bootstrap_field form.priority layout="horizontal" %} {% bootstrap_field form.protocol layout="horizontal" %} - {% bootstrap_field form.cluster layout="horizontal" %} {% block auth %}

{% trans 'Auth' %}

diff --git a/apps/assets/templates/assets/admin_user_assets.html b/apps/assets/templates/assets/admin_user_assets.html index 7ec123fe2..3140c36c3 100644 --- a/apps/assets/templates/assets/admin_user_assets.html +++ b/apps/assets/templates/assets/admin_user_assets.html @@ -59,7 +59,6 @@ {% trans 'Hostname' %} {% trans 'IP' %} {% trans 'Port' %} - {% trans 'Type' %} {% trans 'Reachable' %} @@ -109,7 +108,7 @@ function initTable() { var detail_btn = '' + cellData + ''; $(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id)); }}, - {targets: 5, createdCell: function (td, cellData) { + {targets: 4, createdCell: function (td, cellData) { if (!cellData) { $(td).html('') } else { @@ -117,8 +116,9 @@ function initTable() { } }}], ajax_url: '{% url "api-assets:asset-list" %}?admin_user_id={{ admin_user.id }}', - columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" }, - {data: "type" }, {data: "is_connective" }], + columns: [ + {data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, + {data: "port" }, {data: "is_connective" }], op_html: $('#actions').html() }; jumpserver.initServerSideDataTable(options); diff --git a/apps/assets/templates/assets/asset_detail.html b/apps/assets/templates/assets/asset_detail.html index e7b136555..675cb99a1 100644 --- a/apps/assets/templates/assets/asset_detail.html +++ b/apps/assets/templates/assets/asset_detail.html @@ -71,11 +71,7 @@ {% trans 'Admin user' %}: - {% if asset.admin_user_avail %} - {{ asset.admin_user_avail.name }} - {% else %} - - {% endif %} + {{ asset.admin_user }} {% trans 'Cluster' %}: diff --git a/apps/assets/utils.py b/apps/assets/utils.py index 79be4f82c..e3899bd8a 100644 --- a/apps/assets/utils.py +++ b/apps/assets/utils.py @@ -23,17 +23,6 @@ def get_system_user_by_name(name): return system_user -def check_assets_have_system_user(assets, system_users): - errors = defaultdict(list) - - for system_user in system_users: - clusters = system_user.cluster.all() - for asset in assets: - if asset.cluster not in clusters: - errors[asset].append(system_user) - return errors - - class LabelFilter: def filter_queryset(self, queryset): queryset = super().filter_queryset(queryset) @@ -53,3 +42,7 @@ class LabelFilter: for kwargs in conditions: queryset = queryset.filter(**kwargs) return queryset + + + + diff --git a/apps/assets/views/admin_user.py b/apps/assets/views/admin_user.py index ce7b8bfb4..ec27a1466 100644 --- a/apps/assets/views/admin_user.py +++ b/apps/assets/views/admin_user.py @@ -74,11 +74,9 @@ class AdminUserDetailView(AdminUserRequiredMixin, DetailView): object = None def get_context_data(self, **kwargs): - cluster_remain = Cluster.objects.exclude(admin_user=self.object) context = { 'app': _('Assets'), 'action': _('Admin user detail'), - 'cluster_remain': cluster_remain, } kwargs.update(context) return super().get_context_data(**kwargs) @@ -95,11 +93,8 @@ class AdminUserAssetsView(AdminUserRequiredMixin, SingleObjectMixin, ListView): return super().get(request, *args, **kwargs) def get_queryset(self): - queryset = [] - for cluster in self.object.cluster_set.all(): - queryset.extend([asset for asset in cluster.assets.all() if not asset.admin_user]) - self.queryset = queryset - return queryset + self.queryset = self.object.asset_set.all() + return self.queryset def get_context_data(self, **kwargs): context = { diff --git a/apps/assets/views/system_user.py b/apps/assets/views/system_user.py index b7744735a..3b79d0391 100644 --- a/apps/assets/views/system_user.py +++ b/apps/assets/views/system_user.py @@ -70,11 +70,9 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView): model = SystemUser def get_context_data(self, **kwargs): - cluster_remain = Cluster.objects.exclude(systemuser=self.object) context = { 'app': _('Assets'), 'action': _('System user detail'), - 'cluster_remain': cluster_remain, } kwargs.update(context) return super().get_context_data(**kwargs) diff --git a/apps/perms/apps.py b/apps/perms/apps.py index d40373e08..216e9c3d7 100644 --- a/apps/perms/apps.py +++ b/apps/perms/apps.py @@ -5,3 +5,7 @@ from django.apps import AppConfig class PermsConfig(AppConfig): name = 'perms' + + def ready(self): + from . import signals_handler + return super().ready() diff --git a/apps/perms/signals_handler.py b/apps/perms/signals_handler.py new file mode 100644 index 000000000..ab16a85e7 --- /dev/null +++ b/apps/perms/signals_handler.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# + +from django.db.models.signals import post_save, post_delete +from django.dispatch import receiver + +from common.utils import get_logger +from .models import NodePermission + + +logger = get_logger(__file__) + + +@receiver(post_save, sender=NodePermission, dispatch_uid="my_unique_identifier") +def on_asset_permission_create_or_update(sender, instance=None, **kwargs): + if instance and instance.node and instance.system_user: + instance.system_user.nodes.add(instance.node) + diff --git a/apps/perms/tasks.py b/apps/perms/tasks.py index 4b66b5727..b8696e7c8 100644 --- a/apps/perms/tasks.py +++ b/apps/perms/tasks.py @@ -7,7 +7,4 @@ from common.utils import get_logger, encrypt_password logger = get_logger(__file__) -@shared_task(bind=True) -def push_users(self, assets, users): - pass diff --git a/apps/perms/utils.py b/apps/perms/utils.py index 75299e761..c067bbd11 100644 --- a/apps/perms/utils.py +++ b/apps/perms/utils.py @@ -3,11 +3,11 @@ from __future__ import absolute_import, unicode_literals import collections from django.utils import timezone +from django.utils.translation import ugettext as _ +import copy from common.utils import setattr_bulk, get_logger -import copy -from .tasks import push_users -from .hands import AssetGroup +from .models import NodePermission logger = get_logger(__file__) @@ -111,173 +111,3 @@ class NodePermissionUtil: assets.update(perm.node.get_all_assets()) return assets - -# def get_user_group_granted_asset_groups(user_group): -# """Return asset groups granted of the user group -# -# :param user_group: Instance of :class: ``UserGroup`` -# :return: {asset_group1: {system_user1, }, -# asset_group2: {system_user1, system_user2}} -# """ -# asset_groups = {} -# asset_permissions = user_group.asset_permissions.all() -# -# for asset_permission in asset_permissions: -# if not asset_permission.is_valid: -# continue -# for asset_group in asset_permission.asset_groups.all(): -# if asset_group in asset_groups: -# asset_groups[asset_group] |= set(asset_permission.system_users.all()) -# else: -# asset_groups[asset_group] = set(asset_permission.system_users.all()) -# return asset_groups -# -# -# def get_user_group_granted_assets(user_group): -# """Return assets granted of the user group -# -# :param user_group: Instance of :class: ``UserGroup`` -# :return: {asset1: {system_user1, }, asset1: {system_user1, system_user2]} -# """ -# assets = {} -# asset_permissions = user_group.asset_permissions.all() -# -# for asset_permission in asset_permissions: -# if not asset_permission.is_valid: -# continue -# for asset in asset_permission.get_granted_assets(): -# if not asset.is_active: -# continue -# if asset in assets: -# assets[asset] |= set(asset_permission.system_users.all()) -# else: -# assets[asset] = set(asset_permission.system_users.all()) -# return assets -# -# -# def get_user_granted_assets_direct(user): -# """Return assets granted of the user directly -# -# :param user: Instance of :class: ``User`` -# :return: {asset1: {system_user1, system_user2}, asset2: {...}} -# """ -# assets = {} -# asset_permissions_direct = user.asset_permissions.all() -# -# for asset_permission in asset_permissions_direct: -# if not asset_permission.is_valid: -# continue -# for asset in asset_permission.get_granted_assets(): -# if not asset.is_active: -# continue -# if asset in assets: -# assets[asset] |= set(asset_permission.system_users.all()) -# else: -# setattr(asset, 'inherited', False) -# assets[asset] = set(asset_permission.system_users.all()) -# return assets -# -# -# def get_user_granted_assets_inherit_from_user_groups(user): -# """Return assets granted of the user inherit from user groups -# -# :param user: Instance of :class: ``User`` -# :return: {asset1: {system_user1, system_user2}, asset2: {...}} -# """ -# assets = {} -# user_groups = user.groups.all() -# -# for user_group in user_groups: -# assets_inherited = get_user_group_granted_assets(user_group) -# for asset in assets_inherited: -# if not asset.is_active: -# continue -# if asset in assets: -# assets[asset] |= assets_inherited[asset] -# else: -# setattr(asset, 'inherited', True) -# assets[asset] = assets_inherited[asset] -# return assets -# -# -# def get_user_granted_assets(user): -# """Return assets granted of the user inherit from user groups -# -# :param user: Instance of :class: ``User`` -# :return: {asset1: {system_user1, system_user2}, asset2: {...}} -# """ -# assets_direct = get_user_granted_assets_direct(user) -# assets_inherited = get_user_granted_assets_inherit_from_user_groups(user) -# assets = assets_inherited -# -# for asset in assets_direct: -# if not asset.is_active: -# continue -# if asset in assets: -# assets[asset] |= assets_direct[asset] -# else: -# assets[asset] = assets_direct[asset] -# return assets -# -# -# def get_user_granted_asset_groups(user): -# """Return asset groups with assets and system users, it's not the asset -# group direct permed in rules. We get all asset and then get it asset group -# -# :param user: Instance of :class: ``User`` -# :return: {asset_group1: [asset1, asset2], asset_group2: []} -# """ -# asset_groups = collections.defaultdict(list) -# ungroups = [AssetGroup(name="UnGrouped")] -# for asset, system_users in get_user_granted_assets(user).items(): -# groups = asset.groups.all() -# if not groups: -# groups = ungroups -# for asset_group in groups: -# asset_groups[asset_group].append((asset, system_users)) -# return asset_groups -# -# -# def get_user_group_asset_permissions(user_group): -# permissions = user_group.asset_permissions.all() -# return permissions -# -# -# def get_user_asset_permissions(user): -# user_group_permissions = set() -# direct_permissions = set(setattr_bulk(user.asset_permissions.all(), 'inherited', 0)) -# -# for user_group in user.groups.all(): -# permissions = get_user_group_asset_permissions(user_group) -# user_group_permissions |= set(permissions) -# user_group_permissions = set(setattr_bulk(user_group_permissions, 'inherited', 1)) -# return direct_permissions | user_group_permissions -# -# -# def get_user_granted_system_users(user): -# """ -# :param user: the user -# :return: {"system_user": ["asset", "asset1"], "system_user": []} -# """ -# assets = get_user_granted_assets(user) -# system_users_dict = {} -# for asset, system_users in assets.items(): -# for system_user in system_users: -# if system_user in system_users_dict: -# system_users_dict[system_user].append(asset) -# else: -# system_users_dict[system_user] = [asset] -# return system_users_dict - - -def push_system_user(assets, system_user): - logger.info('Push system user %s' % system_user.name) - for asset in assets: - logger.info('\tAsset: %s' % asset.ip) - if not assets: - return None - - assets = [asset._to_secret_json() for asset in assets] - system_user = system_user._to_secret_json() - task = push_users.delay(assets, system_user) - return task.id diff --git a/apps/users/templates/users/login.html b/apps/users/templates/users/login.html index 1259ba773..18339356a 100644 --- a/apps/users/templates/users/login.html +++ b/apps/users/templates/users/login.html @@ -75,7 +75,7 @@
- Copyright Jumpserver.org + Copyright 北京堆栈科技有限公司
© 2014-2018