mirror of https://github.com/jumpserver/jumpserver
[Update] 修改系统用户推送,拆分assets的部分模块
parent
f82d939d15
commit
c7296c2498
|
@ -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()
|
||||
|
|
|
@ -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"})
|
||||
|
||||
|
||||
|
|
|
@ -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'
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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'),
|
||||
}
|
|
@ -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
|
|
@ -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 *
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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(
|
|
@ -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")
|
||||
|
|
|
@ -3,4 +3,3 @@
|
|||
from django.dispatch import Signal
|
||||
|
||||
on_app_ready = Signal()
|
||||
on_system_user_auth_changed = Signal(providing_args=['system_user'])
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 %}
|
||||
<h3>{% trans 'Auth' %}</h3>
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
<th>{% trans 'Hostname' %}</th>
|
||||
<th>{% trans 'IP' %}</th>
|
||||
<th>{% trans 'Port' %}</th>
|
||||
<th>{% trans 'Type' %}</th>
|
||||
<th>{% trans 'Reachable' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -109,7 +108,7 @@ function initTable() {
|
|||
var detail_btn = '<a href="{% url "assets:asset-detail" pk=DEFAULT_PK %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
|
||||
$(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('<i class="fa fa-times text-danger"></i>')
|
||||
} 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);
|
||||
|
|
|
@ -71,11 +71,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Admin user' %}:</td>
|
||||
{% if asset.admin_user_avail %}
|
||||
<td><b>{{ asset.admin_user_avail.name }}</b></td>
|
||||
{% else %}
|
||||
<td></td>
|
||||
{% endif %}
|
||||
<td><b>{{ asset.admin_user }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Cluster' %}:</td>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -5,3 +5,7 @@ from django.apps import AppConfig
|
|||
|
||||
class PermsConfig(AppConfig):
|
||||
name = 'perms'
|
||||
|
||||
def ready(self):
|
||||
from . import signals_handler
|
||||
return super().ready()
|
||||
|
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
Copyright Jumpserver.org
|
||||
Copyright 北京堆栈科技有限公司
|
||||
</div>
|
||||
<div class="col-md-6 text-right">
|
||||
<small>© 2014-2018</small>
|
||||
|
|
Loading…
Reference in New Issue