diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py index 9538a265c..78cd7a27a 100644 --- a/apps/assets/api/node.py +++ b/apps/assets/api/node.py @@ -19,7 +19,7 @@ from rest_framework.response import Response from rest_framework_bulk import BulkModelViewSet from django.utils.translation import ugettext_lazy as _ -from common.utils import get_logger +from common.utils import get_logger, get_object_or_none from ..hands import IsSuperUser from ..models import Node from .. import serializers @@ -29,6 +29,7 @@ logger = get_logger(__file__) __all__ = [ 'NodeViewSet', 'NodeChildrenApi', 'NodeAddAssetsApi', 'NodeRemoveAssetsApi', + 'NodeAddChildrenApi', ] @@ -75,6 +76,24 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): return Response(response, status=200) +class NodeAddChildrenApi(generics.UpdateAPIView): + queryset = Node.objects.all() + permission_classes = (IsSuperUser,) + serializer_class = serializers.NodeAddChildrenSerializer + instance = None + + def put(self, request, *args, **kwargs): + instance = self.get_object() + nodes_id = request.data.get("nodes") + children = [get_object_or_none(Node, id=pk) for pk in nodes_id] + for node in children: + if not node: + continue + node.parent = instance + node.save() + return Response("OK") + + class NodeAddAssetsApi(generics.UpdateAPIView): serializer_class = serializers.NodeAssetsSerializer queryset = Node.objects.all() diff --git a/apps/assets/forms/asset.py b/apps/assets/forms/asset.py index 763608daf..34865c544 100644 --- a/apps/assets/forms/asset.py +++ b/apps/assets/forms/asset.py @@ -15,7 +15,7 @@ class AssetCreateForm(forms.ModelForm): model = Asset fields = [ 'hostname', 'ip', 'public_ip', 'port', 'comment', - 'nodes', 'is_active', 'admin_user', 'labels', + 'nodes', 'is_active', 'admin_user', 'labels', 'platform', ] widgets = { @@ -44,7 +44,7 @@ class AssetUpdateForm(forms.ModelForm): class Meta: model = Asset fields = [ - 'hostname', 'ip', 'port', 'nodes', 'is_active', + 'hostname', 'ip', 'port', 'nodes', 'is_active', 'platform', 'public_ip', 'number', 'comment', 'admin_user', 'labels', ] widgets = { diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index 01c9ad255..3f7dec4ec 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -38,6 +38,14 @@ def default_node(): class Asset(models.Model): # Important + PLATFORM_CHOICES = ( + ('Linux', 'Linux'), + ('Unix', 'Unix'), + ('MacOS', 'MacOS'), + ('BSD', 'BSD'), + ('Windows', 'Windows'), + ('Other', 'Other'), + ) id = models.UUIDField(default=uuid.uuid4, primary_key=True) ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True) hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname')) @@ -64,7 +72,7 @@ class Asset(models.Model): disk_total = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk total')) disk_info = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk info')) - platform = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Platform')) + platform = models.CharField(max_length=128, choices=PLATFORM_CHOICES, default='Linux', verbose_name=_('Platform')) os = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('OS')) os_version = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('OS version')) os_arch = models.CharField(max_length=16, blank=True, null=True, verbose_name=_('OS arch')) @@ -87,6 +95,12 @@ class Asset(models.Model): return True, '' return False, warning + def is_unixlike(self): + if self.platform not in ("Windows", "Other"): + return True + else: + return False + @property def hardware_info(self): if self.cpu_count: @@ -99,6 +113,8 @@ class Asset(models.Model): @property def is_connective(self): + if not self.is_unixlike(): + return True val = cache.get(ASSET_ADMIN_CONN_CACHE_KEY.format(self.hostname)) if val == 1: return True diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py index a502694c9..5ce195783 100644 --- a/apps/assets/models/node.py +++ b/apps/assets/models/node.py @@ -61,6 +61,9 @@ class Node(models.Model): assets = Asset.objects.filter(nodes__id=self.id) return assets + def get_active_assets(self): + return self.get_assets().filter(is_active=True) + def get_all_assets(self): from .asset import Asset if self.is_root(): @@ -70,6 +73,9 @@ class Node(models.Model): assets = Asset.objects.filter(nodes__in=nodes) return assets + def get_all_active_assets(self): + return self.get_all_assets().filter(is_active=True) + def is_root(self): return self.key == '0' @@ -88,6 +94,10 @@ class Node(models.Model): else: return parent + @parent.setter + def parent(self, parent): + self.key = parent.get_next_child_key() + @property def ancestor(self): if self.parent == self.__class__.root(): diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index 999b9e016..7eaff63e6 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -26,14 +26,14 @@ signer = get_signer() class AssetUser(models.Model): id = models.UUIDField(default=uuid.uuid4, primary_key=True) name = models.CharField(max_length=128, unique=True, verbose_name=_('Name')) - username = models.CharField(max_length=16, verbose_name=_('Username')) + username = models.CharField(max_length=128, verbose_name=_('Username')) _password = models.CharField(max_length=256, blank=True, null=True, verbose_name=_('Password')) _private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'), validators=[private_key_validator, ]) _public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key')) comment = models.TextField(blank=True, verbose_name=_('Comment')) date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) - created_by = models.CharField(max_length=32, null=True, verbose_name=_('Created by')) + created_by = models.CharField(max_length=128, null=True, verbose_name=_('Created by')) @property def password(self): @@ -175,15 +175,12 @@ class AdminUser(AssetUser): return info def get_related_assets(self): - assets = [] - for cluster in self.cluster_set.all(): - assets.extend(cluster.assets.all()) - assets.extend(self.asset_set.all()) - return list(set(assets)) + assets = self.asset_set.all() + return assets @property def assets_amount(self): - return len(self.get_related_assets()) + return self.get_related_assets().count() class Meta: ordering = ['name'] diff --git a/apps/assets/serializers/node.py b/apps/assets/serializers/node.py index 6e69008bb..f6654aef9 100644 --- a/apps/assets/serializers/node.py +++ b/apps/assets/serializers/node.py @@ -65,4 +65,8 @@ class NodeAssetsSerializer(serializers.ModelSerializer): class Meta: model = Node - fields = ['assets'] \ No newline at end of file + fields = ['assets'] + + +class NodeAddChildrenSerializer(serializers.Serializer): + nodes = serializers.ListField() diff --git a/apps/assets/templates/assets/_system_user.html b/apps/assets/templates/assets/_system_user.html index fe06a6fc7..528e271e6 100644 --- a/apps/assets/templates/assets/_system_user.html +++ b/apps/assets/templates/assets/_system_user.html @@ -13,7 +13,7 @@