diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index e2ce1b62a..a4701add9 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -48,7 +48,7 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): return node = get_object_or_404(Node, id=node_id) - show_current_asset = self.request.query_params.get("show_current_asset") + show_current_asset = self.request.query_params.get("show_current_asset") in ('1', 'true') if node.is_root(): if show_current_asset: diff --git a/apps/assets/forms/domain.py b/apps/assets/forms/domain.py index 1b005ec2f..66f490bad 100644 --- a/apps/assets/forms/domain.py +++ b/apps/assets/forms/domain.py @@ -36,6 +36,10 @@ class DomainForm(forms.ModelForm): class GatewayForm(PasswordAndKeyAuthForm, OrgModelForm): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + password_field = self.fields.get('password') + password_field.help_text = _('Password should not contain special characters') def save(self, commit=True): # Because we define custom field, so we need rewrite :method: `save` diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index 97bcd4b47..b554c5c3a 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -6,8 +6,10 @@ import uuid import logging import random from functools import reduce +from collections import defaultdict from django.db import models +from django.db.models import Q from django.utils.translation import ugettext_lazy as _ from django.core.cache import cache @@ -100,6 +102,7 @@ class Asset(OrgModelMixin): verbose_name=_('CPU model')) cpu_count = models.IntegerField(null=True, verbose_name=_('CPU count')) cpu_cores = models.IntegerField(null=True, verbose_name=_('CPU cores')) + cpu_vcpus = models.IntegerField(null=True, verbose_name=_('CPU vcpus')) memory = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Memory')) disk_total = models.CharField(max_length=1024, null=True, blank=True, @@ -161,17 +164,25 @@ class Asset(OrgModelMixin): nodes = list(reduce(lambda x, y: set(x) | set(y), nodes)) return nodes - @property - def org_name(self): - from orgs.models import Organization - org = Organization.get_instance(self.org_id) - return org.name + @classmethod + def get_queryset_by_fullname_list(cls, fullname_list): + org_fullname_map = defaultdict(list) + for fullname in fullname_list: + hostname, org = cls.split_fullname(fullname) + org_fullname_map[org].append(hostname) + filter_arg = Q() + for org, hosts in org_fullname_map.items(): + if org.is_real(): + filter_arg |= Q(hostname__in=hosts, org_id=org.id) + else: + filter_arg |= Q(Q(org_id__isnull=True) | Q(org_id=''), hostname__in=hosts) + return Asset.objects.filter(filter_arg) @property def hardware_info(self): if self.cpu_count: return '{} Core {} {}'.format( - self.cpu_count * self.cpu_cores, + self.cpu_vcpus or self.cpu_count * self.cpu_cores, self.memory, self.disk_total ) else: diff --git a/apps/assets/models/label.py b/apps/assets/models/label.py index 7f1d08fa1..abc71e694 100644 --- a/apps/assets/models/label.py +++ b/apps/assets/models/label.py @@ -35,4 +35,4 @@ class Label(OrgModelMixin): class Meta: db_table = "assets_label" - unique_together = [('name', 'value')] + unique_together = [('name', 'value', 'org_id')] diff --git a/apps/assets/tasks.py b/apps/assets/tasks.py index f1773df11..463c3006a 100644 --- a/apps/assets/tasks.py +++ b/apps/assets/tasks.py @@ -44,7 +44,7 @@ def set_assets_hardware_info(result, **kwargs): logger.error("Get asset info failed: {}".format(hostname)) continue - asset = get_object_or_none(Asset, hostname=hostname) + asset = Asset.objects.get_object_by_fullname(hostname) if not asset: continue @@ -60,6 +60,7 @@ def set_assets_hardware_info(result, **kwargs): ___cpu_model = ___cpu_model[:64] ___cpu_count = info.get('ansible_processor_count', 0) ___cpu_cores = info.get('ansible_processor_cores', None) or len(info.get('ansible_processor', [])) + ___cpu_vcpus = info.get('ansible_processor_vcpus', 0) ___memory = '%s %s' % capacity_convert('{} MB'.format(info.get('ansible_memtotal_mb'))) disk_info = {} for dev, dev_info in info.get('ansible_devices', {}).items(): @@ -95,7 +96,7 @@ def update_assets_hardware_info_util(assets, task_name=None): # task_name = _("Update some assets hardware info") task_name = _("更新资产硬件信息") tasks = const.UPDATE_ASSETS_HARDWARE_TASKS - hostname_list = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] + hostname_list = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()] if not hostname_list: logger.info("Not hosts get, may be asset is not active or not unixlike platform") return {} @@ -134,7 +135,7 @@ def update_assets_hardware_info_period(): # task_name = _("Update assets hardware info period") task_name = _("定期更新资产硬件信息") hostname_list = [ - asset.hostname for asset in Asset.objects.all() + asset.fullname for asset in Asset.objects.all() if asset.is_active and asset.is_unixlike() ] tasks = const.UPDATE_ASSETS_HARDWARE_TASKS @@ -181,7 +182,7 @@ def test_admin_user_connectability_util(admin_user, task_name): from ops.utils import update_or_create_ansible_task assets = admin_user.get_related_assets() - hosts = [asset.hostname for asset in assets + hosts = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()] if not hosts: return @@ -228,7 +229,7 @@ def test_asset_connectability_util(assets, task_name=None): if task_name is None: # task_name = _("Test assets connectability") task_name = _("测试资产可连接性") - hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] + hosts = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()] if not hosts: logger.info("No hosts, passed") return {} @@ -280,7 +281,7 @@ def test_system_user_connectability_util(system_user, task_name): """ from ops.utils import update_or_create_ansible_task assets = system_user.get_assets() - hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] + hosts = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()] tasks = const.TEST_SYSTEM_USER_CONN_TASKS if not hosts: logger.info("No hosts, passed") @@ -378,7 +379,7 @@ def push_system_user_util(system_users, assets, task_name): logger.info("Not tasks, passed") return {} - hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] + hosts = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()] if not hosts: logger.info("Not hosts, passed") return {} diff --git a/apps/assets/templates/assets/asset_list.html b/apps/assets/templates/assets/asset_list.html index 3e1a8cfcd..79c34c043 100644 --- a/apps/assets/templates/assets/asset_list.html +++ b/apps/assets/templates/assets/asset_list.html @@ -451,10 +451,11 @@ $(document).ready(function(){ $.each(rows, function (index, obj) { assets.push(obj.id) }); + var _node_id = current_node ? current_node : null; $.ajax({ url: "{% url "assets:asset-export" %}", method: 'POST', - data: JSON.stringify({assets_id: assets, node_id: current_node.node_id}), + data: JSON.stringify({assets_id: assets, node_id: _node_id}), dataType: "json", success: function (data, textStatus) { window.open(data.redirect) diff --git a/apps/assets/templates/assets/asset_update.html b/apps/assets/templates/assets/asset_update.html index 7ed1da05a..caff4286d 100644 --- a/apps/assets/templates/assets/asset_update.html +++ b/apps/assets/templates/assets/asset_update.html @@ -12,7 +12,7 @@ {% block form %}