perf: 修改资产名称

pull/8873/head
ibuler 2 years ago
parent 4021baf758
commit d402ba5d92

@ -61,7 +61,7 @@ class LoginAssetACL(BaseACL, OrgModelMixin):
@classmethod @classmethod
def filter_asset(cls, asset, queryset): def filter_asset(cls, asset, queryset):
queryset = queryset.filter( queryset = queryset.filter(
Q(assets__hostname_group__contains=asset.hostname) | Q(assets__hostname_group__contains=asset.name) |
Q(assets__hostname_group__contains='*') Q(assets__hostname_group__contains='*')
) )
ids = [q.id for q in queryset if contains_ip(asset.ip, q.assets.get('ip_group', []))] ids = [q.id for q in queryset if contains_ip(asset.ip, q.assets.get('ip_group', []))]

@ -21,7 +21,7 @@ __all__ = ['AccountFilterSet', 'AccountViewSet', 'AccountSecretsViewSet', 'Accou
class AccountFilterSet(BaseFilterSet): class AccountFilterSet(BaseFilterSet):
username = filters.CharFilter(method='do_nothing') username = filters.CharFilter(method='do_nothing')
ip = filters.CharFilter(field_name='ip', lookup_expr='exact') ip = filters.CharFilter(field_name='ip', lookup_expr='exact')
hostname = filters.CharFilter(field_name='hostname', lookup_expr='exact') hostname = filters.CharFilter(field_name='name', lookup_expr='exact')
node = filters.CharFilter(method='do_nothing') node = filters.CharFilter(method='do_nothing')
@property @property
@ -58,8 +58,8 @@ class AccountFilterSet(BaseFilterSet):
class AccountViewSet(OrgBulkModelViewSet): class AccountViewSet(OrgBulkModelViewSet):
model = Account model = Account
filterset_fields = ("username", "asset", 'ip', 'hostname') filterset_fields = ("username", "asset", 'ip', 'name')
search_fields = ('username', 'ip', 'hostname') search_fields = ('username', 'ip', 'name')
filterset_class = AccountFilterSet filterset_class = AccountFilterSet
serializer_classes = { serializer_classes = {
'default': serializers.AccountSerializer, 'default': serializers.AccountSerializer,

@ -27,15 +27,15 @@ class AssetViewSet(SuggestionMixin, FilterAssetByNodeMixin, OrgBulkModelViewSet)
""" """
model = Asset model = Asset
filterset_fields = { filterset_fields = {
'hostname': ['exact'], 'name': ['exact'],
'ip': ['exact'], 'ip': ['exact'],
'system_users__id': ['exact'], 'system_users__id': ['exact'],
'is_active': ['exact'], 'is_active': ['exact'],
'protocols': ['exact', 'icontains'] 'protocols': ['exact', 'icontains']
} }
search_fields = ("hostname", "ip") search_fields = ("name", "ip")
ordering_fields = ("hostname", "ip", "port") ordering_fields = ("name", "ip", "port")
ordering = ('hostname', ) ordering = ('name', )
serializer_classes = ( serializer_classes = (
('default', serializers.AssetSerializer), ('default', serializers.AssetSerializer),
('suggestion', serializers.MiniAssetSerializer), ('suggestion', serializers.MiniAssetSerializer),

@ -56,7 +56,7 @@ class SerializeToTreeNodeMixin:
data = [ data = [
{ {
'id': str(asset.id), 'id': str(asset.id),
'name': asset.hostname, 'name': asset.name,
'title': asset.ip, 'title': asset.ip,
'pId': get_pid(asset), 'pId': get_pid(asset),
'isParent': False, 'isParent': False,
@ -67,7 +67,7 @@ class SerializeToTreeNodeMixin:
'type': 'asset', 'type': 'asset',
'data': { 'data': {
'id': asset.id, 'id': asset.id,
'hostname': asset.hostname, 'name': asset.name,
'ip': asset.ip, 'ip': asset.ip,
'protocols': asset.protocols_as_list, 'protocols': asset.protocols_as_list,
'platform': asset.platform_base, 'platform': asset.platform_base,

@ -192,7 +192,7 @@ class NodeChildrenAsTreeApi(SerializeToTreeNodeMixin, NodeChildrenApi):
if not self.instance or not include_assets: if not self.instance or not include_assets:
return [] return []
assets = self.instance.get_assets().only( assets = self.instance.get_assets().only(
"id", "hostname", "ip", "os", "platform_id", "id", "name", "ip", "os", "platform_id",
"org_id", "protocols", "is_active", "org_id", "protocols", "is_active",
).prefetch_related('platform') ).prefetch_related('platform')
return self.serialize_assets(assets, self.instance.key) return self.serialize_assets(assets, self.instance.key)

@ -40,6 +40,7 @@ class Migration(migrations.Migration):
('os_arch', models.CharField(blank=True, max_length=16, null=True, verbose_name='OS arch')), ('os_arch', models.CharField(blank=True, max_length=16, null=True, verbose_name='OS arch')),
('hostname_raw', models.CharField(blank=True, max_length=128, null=True, verbose_name='Hostname raw')), ('hostname_raw', models.CharField(blank=True, max_length=128, null=True, verbose_name='Hostname raw')),
('host', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.host', verbose_name='Host')), ('host', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.host', verbose_name='Host')),
('number', models.CharField(blank=True, max_length=128, null=True, verbose_name='Asset number')),
], ],
options={ options={
'verbose_name': 'DeviceInfo', 'verbose_name': 'DeviceInfo',

@ -0,0 +1,37 @@
# Generated by Django 3.2.14 on 2022-08-11 06:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0106_auto_20220811_1358'),
]
operations = [
migrations.RemoveField(
model_name='asset',
name='_protocols',
),
migrations.RemoveField(
model_name='asset',
name='admin_user',
),
migrations.RemoveField(
model_name='asset',
name='category',
),
migrations.RemoveField(
model_name='asset',
name='number',
),
migrations.RemoveField(
model_name='asset',
name='public_ip',
),
migrations.RemoveField(
model_name='asset',
name='type',
),
]

@ -0,0 +1,41 @@
# Generated by Django 3.2.14 on 2022-08-11 07:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0107_auto_20220811_1449'),
]
operations = [
migrations.AlterModelOptions(
name='asset',
options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetsystemuser', 'Can push system user to asset'), ('match_asset', 'Can match asset'), ('add_assettonode', 'Add asset to node'), ('move_assettonode', 'Move asset to node')], 'verbose_name': 'Asset'},
),
migrations.RenameField(
model_name='asset',
old_name='hostname',
new_name='name',
),
migrations.AddField(
model_name='asset',
name='date_updated',
field=models.DateTimeField(auto_now=True, verbose_name='Date updated'),
),
migrations.AddField(
model_name='asset',
name='updated_by',
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='Updated by'),
),
migrations.AlterField(
model_name='asset',
name='created_by',
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by'),
),
migrations.AlterUniqueTogether(
name='asset',
unique_together={('org_id', 'name')},
),
]

@ -15,3 +15,4 @@ from .backup import *
from ._authbook import * from ._authbook import *
from .protocol import * from .protocol import *
from .cmd_filter import * from .cmd_filter import *

@ -30,7 +30,7 @@ class Account(BaseUser, AbsConnectivity):
] ]
def __str__(self): def __str__(self):
return '{}@{}'.format(self.username, self.asset.hostname) return '{}@{}'.format(self.username, self.asset.name)
class AccountTemplate(JMSBaseModel): class AccountTemplate(JMSBaseModel):

@ -8,4 +8,4 @@ class Cloud(Asset):
cluster = models.CharField(max_length=4096, verbose_name=_("Cluster")) cluster = models.CharField(max_length=4096, verbose_name=_("Cluster"))
def __str__(self): def __str__(self):
return self.hostname return self.name

@ -2,16 +2,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import uuid
import logging import logging
import uuid
from functools import reduce from functools import reduce
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import lazyproperty from orgs.mixins.models import OrgManager, JMSOrgBaseModel
from orgs.mixins.models import OrgModelMixin, OrgManager
from assets.const import Category, AllTypes
from ..platform import Platform from ..platform import Platform
from ..base import AbsConnectivity from ..base import AbsConnectivity
@ -67,14 +65,10 @@ class NodesRelationMixin:
return nodes return nodes
class Asset(AbsConnectivity, NodesRelationMixin, OrgModelMixin): class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
Category = Category
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
hostname = models.CharField(max_length=128, verbose_name=_('Hostname')) name = models.CharField(max_length=128, verbose_name=_('Hostname'))
ip = models.CharField(max_length=128, verbose_name=_('IP'), db_index=True) ip = models.CharField(max_length=128, verbose_name=_('IP'), db_index=True)
category = models.CharField(max_length=16, choices=Category.choices, verbose_name=_("Category"))
type = models.CharField(max_length=128, choices=AllTypes.choices, verbose_name=_("Type"))
_protocols = models.CharField(max_length=128, default='ssh/22', blank=True, verbose_name=_("Protocols"))
protocols = models.ManyToManyField('Protocol', verbose_name=_("Protocols"), blank=True) protocols = models.ManyToManyField('Protocol', verbose_name=_("Protocols"), blank=True)
platform = models.ForeignKey(Platform, default=Platform.default, on_delete=models.PROTECT, platform = models.ForeignKey(Platform, default=Platform.default, on_delete=models.PROTECT,
verbose_name=_("Platform"), related_name='assets') verbose_name=_("Platform"), related_name='assets')
@ -84,16 +78,7 @@ class Asset(AbsConnectivity, NodesRelationMixin, OrgModelMixin):
verbose_name=_("Nodes")) verbose_name=_("Nodes"))
is_active = models.BooleanField(default=True, verbose_name=_('Is active')) is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
# Auth
admin_user = models.ForeignKey('assets.SystemUser', on_delete=models.SET_NULL, null=True,
verbose_name=_("Admin user"), related_name='admin_assets')
# Some information
public_ip = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Public IP'))
number = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Asset number'))
labels = models.ManyToManyField('assets.Label', blank=True, related_name='assets', verbose_name=_("Labels")) labels = models.ManyToManyField('assets.Label', blank=True, related_name='assets', verbose_name=_("Labels"))
created_by = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Created by'))
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date created'))
comment = models.TextField(default='', blank=True, verbose_name=_('Comment')) comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
objects = AssetManager.from_queryset(AssetQuerySet)() objects = AssetManager.from_queryset(AssetQuerySet)()
@ -104,12 +89,6 @@ class Asset(AbsConnectivity, NodesRelationMixin, OrgModelMixin):
def get_target_ip(self): def get_target_ip(self):
return self.ip return self.ip
@property
def admin_user_display(self):
if not self.admin_user:
return ''
return str(self.admin_user)
@property @property
def is_valid(self): def is_valid(self):
warning = '' warning = ''
@ -119,17 +98,6 @@ class Asset(AbsConnectivity, NodesRelationMixin, OrgModelMixin):
return False, warning return False, warning
return True, warning return True, warning
@lazyproperty
def platform_base(self):
return self.platform.type
@lazyproperty
def admin_user_username(self):
"""求可连接性时直接用用户名去取避免再查一次admin user
serializer 中直接通过annotate方式返回了这个
"""
return self.admin_user.username
def nodes_display(self): def nodes_display(self):
names = [] names = []
for n in self.nodes.all(): for n in self.nodes.all():
@ -142,12 +110,20 @@ class Asset(AbsConnectivity, NodesRelationMixin, OrgModelMixin):
names.append(n.name + ':' + n.value) names.append(n.name + ':' + n.value)
return names return names
@property
def type(self):
return self.platform.type
@property
def category(self):
return self.platform.category
def as_node(self): def as_node(self):
from assets.models import Node from assets.models import Node
fake_node = Node() fake_node = Node()
fake_node.id = self.id fake_node.id = self.id
fake_node.key = self.id fake_node.key = self.id
fake_node.value = self.hostname fake_node.value = self.name
fake_node.asset = self fake_node.asset = self
fake_node.is_node = False fake_node.is_node = False
return fake_node return fake_node
@ -155,13 +131,14 @@ class Asset(AbsConnectivity, NodesRelationMixin, OrgModelMixin):
def as_tree_node(self, parent_node): def as_tree_node(self, parent_node):
from common.tree import TreeNode from common.tree import TreeNode
icon_skin = 'file' icon_skin = 'file'
if self.platform_base.lower() == 'windows': platform_type = self.platform.type.lower()
if platform_type == 'windows':
icon_skin = 'windows' icon_skin = 'windows'
elif self.platform_base.lower() == 'linux': elif platform_type == 'linux':
icon_skin = 'linux' icon_skin = 'linux'
data = { data = {
'id': str(self.id), 'id': str(self.id),
'name': self.hostname, 'name': self.name,
'title': self.ip, 'title': self.ip,
'pId': parent_node.key, 'pId': parent_node.key,
'isParent': False, 'isParent': False,
@ -171,10 +148,9 @@ class Asset(AbsConnectivity, NodesRelationMixin, OrgModelMixin):
'type': 'asset', 'type': 'asset',
'data': { 'data': {
'id': self.id, 'id': self.id,
'hostname': self.hostname, 'name': self.name,
'ip': self.ip, 'ip': self.ip,
'protocols': self.protocols, 'protocols': self.protocols,
'platform': self.platform_base,
} }
} }
} }
@ -188,20 +164,10 @@ class Asset(AbsConnectivity, NodesRelationMixin, OrgModelMixin):
system_users = SystemUser.objects.filter(id__in=system_user_ids) system_users = SystemUser.objects.filter(id__in=system_user_ids)
return system_users return system_users
def save(self, *args, **kwargs):
self.type = self.platform.type
self.category = self.platform.category
return super().save(*args, **kwargs)
# TODO 暂时为了接口文档添加
@property
def os(self):
return
class Meta: class Meta:
unique_together = [('org_id', 'hostname')] unique_together = [('org_id', 'name')]
verbose_name = _("Asset") verbose_name = _("Asset")
ordering = ["hostname", ] ordering = ["name", ]
permissions = [ permissions = [
('refresh_assethardwareinfo', _('Can refresh asset hardware info')), ('refresh_assethardwareinfo', _('Can refresh asset hardware info')),
('test_assetconnectivity', _('Can test asset connectivity')), ('test_assetconnectivity', _('Can test asset connectivity')),

@ -8,7 +8,7 @@ class Database(Asset):
db_name = models.CharField(max_length=1024, verbose_name=_("Database"), blank=True) db_name = models.CharField(max_length=1024, verbose_name=_("Database"), blank=True)
def __str__(self): def __str__(self):
return '{}({}://{}/{})'.format(self.hostname, self.type, self.ip, self.db_name) return '{}({}://{}/{})'.format(self.name, self.type, self.ip, self.db_name)
class Meta: class Meta:
verbose_name = _("Database") verbose_name = _("Database")

@ -31,6 +31,7 @@ class DeviceInfo(CommonModelMixin):
os_version = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('OS version')) 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')) os_arch = models.CharField(max_length=16, blank=True, null=True, verbose_name=_('OS arch'))
hostname_raw = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Hostname raw')) hostname_raw = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Hostname raw'))
number = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Asset number'))
@property @property
def cpu_info(self): def cpu_info(self):
@ -52,7 +53,7 @@ class DeviceInfo(CommonModelMixin):
return '' return ''
def __str__(self): def __str__(self):
return '{} of {}'.format(self.hardware_info, self.host.hostname) return '{} of {}'.format(self.hardware_info, self.host.name)
class Meta: class Meta:
verbose_name = _("DeviceInfo") verbose_name = _("DeviceInfo")

@ -21,7 +21,7 @@ class GatheredUser(OrgModelMixin):
@property @property
def hostname(self): def hostname(self):
return self.asset.hostname return self.asset.name
@property @property
def ip(self): def ip(self):
@ -32,7 +32,7 @@ class GatheredUser(OrgModelMixin):
ordering = ['asset'] ordering = ['asset']
def __str__(self): def __str__(self):
return '{}: {}'.format(self.asset.hostname, self.username) return '{}: {}'.format(self.asset.name, self.username)

@ -12,7 +12,7 @@ from common.drf.serializers import SecretReadableMixin
class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
ip = serializers.ReadOnlyField(label=_("IP")) ip = serializers.ReadOnlyField(label=_("IP"))
hostname = serializers.ReadOnlyField(label=_("Hostname")) asset = serializers.ReadOnlyField(label=_("Asset"))
platform = serializers.ReadOnlyField(label=_("Platform")) platform = serializers.ReadOnlyField(label=_("Platform"))
date_created = serializers.DateTimeField( date_created = serializers.DateTimeField(
label=_('Date created'), format="%Y/%m/%d %H:%M:%S", read_only=True label=_('Date created'), format="%Y/%m/%d %H:%M:%S", read_only=True
@ -24,7 +24,7 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
class Meta: class Meta:
model = Account model = Account
fields_mini = [ fields_mini = [
'id', 'type', 'username', 'ip', 'hostname', 'id', 'type', 'username', 'ip', 'name',
'platform', 'version' 'platform', 'version'
] ]
fields_write_only = ['password', 'private_key', 'public_key', 'passphrase'] fields_write_only = ['password', 'private_key', 'public_key', 'passphrase']
@ -59,14 +59,14 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
""" Perform necessary eager loading of data. """ """ Perform necessary eager loading of data. """
queryset = queryset.prefetch_related('asset')\ queryset = queryset.prefetch_related('asset')\
.annotate(ip=F('asset__ip')) \ .annotate(ip=F('asset__ip')) \
.annotate(hostname=F('asset__hostname')) .annotate(asset=F('asset__name'))
return queryset return queryset
class AccountSecretSerializer(SecretReadableMixin, AccountSerializer): class AccountSecretSerializer(SecretReadableMixin, AccountSerializer):
class Meta(AccountSerializer.Meta): class Meta(AccountSerializer.Meta):
fields_backup = [ fields_backup = [
'hostname', 'ip', 'platform', 'protocols', 'username', 'password', 'name', 'ip', 'platform', 'protocols', 'username', 'password',
'private_key', 'public_key', 'date_created', 'date_updated', 'version' 'private_key', 'public_key', 'date_created', 'date_updated', 'version'
] ]
extra_kwargs = { extra_kwargs = {

@ -14,7 +14,7 @@ class DeviceSerializer(serializers.ModelSerializer):
fields = [ fields = [
'id', 'vendor', 'model', 'sn', 'cpu_model', 'cpu_count', 'id', 'vendor', 'model', 'sn', 'cpu_model', 'cpu_count',
'cpu_cores', 'cpu_vcpus', 'memory', 'disk_total', 'disk_info', 'cpu_cores', 'cpu_vcpus', 'memory', 'disk_total', 'disk_info',
'os', 'os_version', 'os_arch', 'hostname_raw', 'os', 'os_version', 'os_arch', 'hostname_raw', 'number',
'cpu_info', 'hardware_info', 'date_updated' 'cpu_info', 'hardware_info', 'date_updated'
] ]
@ -31,7 +31,7 @@ class DatabaseSerializer(AssetSerializer):
class Meta(AssetSerializer.Meta): class Meta(AssetSerializer.Meta):
model = Database model = Database
fields_mini = [ fields_mini = [
'id', 'hostname', 'ip', 'port', 'db_name', 'id', 'name', 'ip', 'port', 'db_name',
] ]
fields_small = fields_mini + [ fields_small = fields_mini + [
'is_active', 'comment', 'is_active', 'comment',

@ -57,8 +57,6 @@ class AssetNodesSerializer(serializers.ModelSerializer):
class AssetSerializer(JMSWritableNestedModelSerializer): class AssetSerializer(JMSWritableNestedModelSerializer):
# category = ChoiceDisplayField(choices=Category.choices, required=False)
# type = ChoiceDisplayField(choices=AllTypes.choices, required=False)
domain = AssetDomainSerializer(required=False) domain = AssetDomainSerializer(required=False)
platform = AssetPlatformSerializer(required=False) platform = AssetPlatformSerializer(required=False)
labels = AssetLabelSerializer(many=True, required=False) labels = AssetLabelSerializer(many=True, required=False)
@ -72,10 +70,10 @@ class AssetSerializer(JMSWritableNestedModelSerializer):
class Meta: class Meta:
model = Asset model = Asset
fields_mini = [ fields_mini = [
'id', 'hostname', 'ip', 'id', 'name', 'ip',
] ]
fields_small = fields_mini + [ fields_small = fields_mini + [
'is_active', 'number', 'comment', 'is_active', 'comment',
] ]
fields_fk = [ fields_fk = [
'domain', 'platform', 'platform', 'domain', 'platform', 'platform',
@ -90,7 +88,7 @@ class AssetSerializer(JMSWritableNestedModelSerializer):
] ]
fields = fields_small + fields_fk + fields_m2m + read_only_fields fields = fields_small + fields_fk + fields_m2m + read_only_fields
extra_kwargs = { extra_kwargs = {
'hostname': {'label': _("Name")}, 'name': {'label': _("Name")},
'ip': {'label': _('IP/Host')}, 'ip': {'label': _('IP/Host')},
'protocol': {'write_only': True}, 'protocol': {'write_only': True},
'port': {'write_only': True}, 'port': {'write_only': True},
@ -102,12 +100,6 @@ class AssetSerializer(JMSWritableNestedModelSerializer):
self.accounts_data = data.pop('accounts', []) self.accounts_data = data.pop('accounts', [])
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def validate_type(self, value):
return value
def validate_category(self, value):
return value
@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. """
@ -164,7 +156,7 @@ class AssetSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Asset model = Asset
fields = [ fields = [
'id', 'hostname', 'ip', 'port', 'id', 'name', 'ip', 'port',
'connectivity', 'date_verified' 'connectivity', 'date_verified'
] ]

@ -16,10 +16,10 @@ class GatheredUserSerializer(OrgResourceModelSerializerMixin):
'present', 'present',
'date_last_login', 'date_created', 'date_updated' 'date_last_login', 'date_created', 'date_updated'
] ]
fields_fk = ['asset', 'hostname', 'ip'] fields_fk = ['asset', 'name', 'ip']
fields = fields_small + fields_fk fields = fields_small + fields_fk
read_only_fields = fields read_only_fields = fields
extra_kwargs = { extra_kwargs = {
'hostname': {'label': _("Hostname")}, 'name': {'label': _("Hostname")},
'ip': {'label': 'IP'}, 'ip': {'label': 'IP'},
} }

@ -28,7 +28,7 @@ def get_test_account_connectivity_tasks(asset):
else: else:
msg = _( msg = _(
"The asset {} system platform {} does not " "The asset {} system platform {} does not "
"support run Ansible tasks".format(asset.hostname, asset.platform) "support run Ansible tasks".format(asset.name, asset.platform)
) )
logger.info(msg) logger.info(msg)
tasks = [] tasks = []

@ -26,7 +26,7 @@ def set_assets_accounts_connectivity(assets, results_summary):
asset_hostnames_ok = results_summary.get('contacted', {}).keys() asset_hostnames_ok = results_summary.get('contacted', {}).keys()
for asset in assets: for asset in assets:
if asset.hostname in asset_hostnames_ok: if asset.name in asset_hostnames_ok:
asset_ids_ok.add(asset.id) asset_ids_ok.add(asset.id)
else: else:
asset_ids_failed.add(asset.id) asset_ids_failed.add(asset.id)
@ -100,7 +100,7 @@ def test_asset_connectivity_manual(asset):
@shared_task(queue="ansible") @shared_task(queue="ansible")
def test_assets_connectivity_manual(assets): def test_assets_connectivity_manual(assets):
task_name = gettext_noop("Test assets connectivity: ") + str([asset.hostname for asset in assets]) task_name = gettext_noop("Test assets connectivity: ") + str([asset.name for asset in assets])
summary = test_asset_connectivity_util(assets, task_name=task_name) summary = test_asset_connectivity_util(assets, task_name=task_name)
if summary.get('dark'): if summary.get('dark'):

@ -39,7 +39,7 @@ def set_assets_hardware_info(assets, result, **kwargs):
success_result = result_raw.get('ok', {}) success_result = result_raw.get('ok', {})
for asset in assets: for asset in assets:
hostname = asset.hostname hostname = asset.name
info = success_result.get(hostname, {}) info = success_result.get(hostname, {})
info = info.get('setup', {}).get('ansible_facts', {}) info = info.get('setup', {}).get('ansible_facts', {})
if not info: if not info:
@ -111,13 +111,13 @@ def update_assets_hardware_info_util(assets, task_name=None):
@shared_task(queue="ansible") @shared_task(queue="ansible")
def update_asset_hardware_info_manual(asset): def update_asset_hardware_info_manual(asset):
task_name = gettext_noop("Update asset hardware info: ") + str(asset.hostname) task_name = gettext_noop("Update asset hardware info: ") + str(asset.name)
update_assets_hardware_info_util([asset], task_name=task_name) update_assets_hardware_info_util([asset], task_name=task_name)
@shared_task(queue="ansible") @shared_task(queue="ansible")
def update_assets_hardware_info_manual(assets): def update_assets_hardware_info_manual(assets):
task_name = gettext_noop("Update assets hardware info: ") + str([asset.hostname for asset in assets]) task_name = gettext_noop("Update assets hardware info: ") + str([asset.name for asset in assets])
update_assets_hardware_info_util(assets, task_name=task_name) update_assets_hardware_info_util(assets, task_name=task_name)

@ -70,7 +70,7 @@ def parse_windows_result_to_users(result):
def add_asset_users(assets, results): def add_asset_users(assets, results):
assets_map = {a.hostname: a for a in assets} assets_map = {a.name: a for a in assets}
parser_map = { parser_map = {
'linux': parse_linux_result_to_users, 'linux': parse_linux_result_to_users,
'windows': parse_windows_result_to_users 'windows': parse_windows_result_to_users

@ -160,7 +160,7 @@ class ConnectionTokenMixin:
rdp_options['audiomode:i'] = self.parse_env_bool('JUMPSERVER_DISABLE_AUDIO', 'false', '2', '0') rdp_options['audiomode:i'] = self.parse_env_bool('JUMPSERVER_DISABLE_AUDIO', 'false', '2', '0')
if token.asset: if token.asset:
name = token.asset.hostname name = token.asset.name
elif token.application and token.application.category_remote_app: elif token.application and token.application.category_remote_app:
app = '||jmservisor' app = '||jmservisor'
name = token.application.name name = token.application.name
@ -182,7 +182,7 @@ class ConnectionTokenMixin:
def get_ssh_token(self, token: ConnectionToken): def get_ssh_token(self, token: ConnectionToken):
if token.asset: if token.asset:
name = token.asset.hostname name = token.asset.name
elif token.application: elif token.application:
name = token.application.name name = token.application.name
else: else:

@ -124,7 +124,7 @@ class ConnectionTokenAssetSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Asset model = Asset
fields = ['id', 'hostname', 'ip', 'protocols', 'org_id'] fields = ['id', 'name', 'ip', 'protocols', 'org_id']
class ConnectionTokenSystemUserSerializer(serializers.ModelSerializer): class ConnectionTokenSystemUserSerializer(serializers.ModelSerializer):

@ -315,7 +315,7 @@ class Config(dict):
'TERMINAL_PASSWORD_AUTH': True, 'TERMINAL_PASSWORD_AUTH': True,
'TERMINAL_PUBLIC_KEY_AUTH': True, 'TERMINAL_PUBLIC_KEY_AUTH': True,
'TERMINAL_HEARTBEAT_INTERVAL': 20, 'TERMINAL_HEARTBEAT_INTERVAL': 20,
'TERMINAL_ASSET_LIST_SORT_BY': 'hostname', 'TERMINAL_ASSET_LIST_SORT_BY': 'name',
'TERMINAL_ASSET_LIST_PAGE_SIZE': 'auto', 'TERMINAL_ASSET_LIST_PAGE_SIZE': 'auto',
'TERMINAL_SESSION_KEEP_DURATION': 200, 'TERMINAL_SESSION_KEEP_DURATION': 200,
'TERMINAL_HOST_KEY': '', 'TERMINAL_HOST_KEY': '',

@ -15,7 +15,7 @@ class BaseHost(Host):
""" """
初始化 初始化
:param host_data: { :param host_data: {
"hostname": "", "name": "",
"ip": "", "ip": "",
"port": "", "port": "",
# behind is not must be required # behind is not must be required
@ -32,7 +32,7 @@ class BaseHost(Host):
} }
""" """
self.host_data = host_data self.host_data = host_data
hostname = host_data.get('hostname') or host_data.get('ip') hostname = host_data.get('name') or host_data.get('ip')
port = host_data.get('port') or 22 port = host_data.get('port') or 22
super().__init__(hostname, port) super().__init__(hostname, port)
self.__set_required_variables() self.__set_required_variables()
@ -82,7 +82,7 @@ class BaseInventory(InventoryManager):
""" """
用于生成动态构建Ansible Inventory. super().__init__ 会自动调用 用于生成动态构建Ansible Inventory. super().__init__ 会自动调用
host_list: [{ host_list: [{
"hostname": "", "name": "",
"ip": "", "ip": "",
"port": "", "port": "",
"username": "", "username": "",
@ -136,7 +136,7 @@ class BaseInventory(InventoryManager):
ungrouped = self.get_or_create_group('ungrouped') ungrouped = self.get_or_create_group('ungrouped')
for host_data in self.host_list: for host_data in self.host_list:
host = self.host_manager_class(host_data=host_data) host = self.host_manager_class(host_data=host_data)
self.hosts[host_data['hostname']] = host self.hosts[host_data['name']] = host
groups_data = host_data.get('groups') groups_data = host_data.get('groups')
if groups_data: if groups_data:
for group_name in groups_data: for group_name in groups_data:

@ -12,7 +12,7 @@ from ops.ansible.inventory import BaseInventory
class TestJMSInventory(unittest.TestCase): class TestJMSInventory(unittest.TestCase):
def setUp(self): def setUp(self):
host_list = [{ host_list = [{
"hostname": "testserver1", "name": "testserver1",
"ip": "102.1.1.1", "ip": "102.1.1.1",
"port": 22, "port": 22,
"username": "root", "username": "root",
@ -26,7 +26,7 @@ class TestJMSInventory(unittest.TestCase):
"groups": ["group1", "group2"], "groups": ["group1", "group2"],
"vars": {"sexy": "yes"}, "vars": {"sexy": "yes"},
}, { }, {
"hostname": "testserver2", "name": "testserver2",
"ip": "8.8.8.8", "ip": "8.8.8.8",
"port": 2222, "port": 2222,
"username": "root", "username": "root",

@ -14,7 +14,7 @@ class TestAdHocRunner(unittest.TestCase):
def setUp(self): def setUp(self):
host_data = [ host_data = [
{ {
"hostname": "testserver", "name": "testserver",
"ip": "192.168.244.185", "ip": "192.168.244.185",
"port": 22, "port": 22,
"username": "root", "username": "root",
@ -38,7 +38,7 @@ class TestCommandRunner(unittest.TestCase):
def setUp(self): def setUp(self):
host_data = [ host_data = [
{ {
"hostname": "testserver", "name": "testserver",
"ip": "192.168.244.168", "ip": "192.168.244.168",
"port": 22, "port": 22,
"username": "root", "username": "root",

@ -20,7 +20,7 @@ class JMSBaseInventory(BaseInventory):
def convert_to_ansible(self, asset, run_as_admin=False): def convert_to_ansible(self, asset, run_as_admin=False):
info = { info = {
'id': asset.id, 'id': asset.id,
'hostname': asset.hostname, 'name': asset.name,
'ip': asset.ip, 'ip': asset.ip,
'port': asset.ssh_port, 'port': asset.ssh_port,
'vars': dict(), 'vars': dict(),

@ -57,7 +57,7 @@ class CommandExecution(OrgModelMixin):
@lazyproperty @lazyproperty
def hosts_display(self): def hosts_display(self):
return ','.join(self.hosts.all().values_list('hostname', flat=True)) return ','.join(self.hosts.all().values_list('name', flat=True))
@property @property
def result(self): def result(self):
@ -77,7 +77,7 @@ class CommandExecution(OrgModelMixin):
return True return True
def get_hosts_names(self): def get_hosts_names(self):
return ','.join(self.hosts.all().values_list('hostname', flat=True)) return ','.join(self.hosts.all().values_list('name', flat=True))
def cmd_filter_rules(self, asset_id=None): def cmd_filter_rules(self, asset_id=None):
from assets.models import CommandFilterRule from assets.models import CommandFilterRule

@ -0,0 +1,16 @@
# Generated by Django 3.2.14 on 2022-08-11 07:11
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('orgs', '0012_auto_20220118_1054'),
]
operations = [
migrations.DeleteModel(
name='OrganizationMember',
),
]

@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from common.utils import get_logger from common.utils import get_logger
from common.db.models import JMSBaseModel
from ..utils import ( from ..utils import (
set_current_org, get_current_org, current_org, filter_org_queryset set_current_org, get_current_org, current_org, filter_org_queryset
) )
@ -14,7 +15,7 @@ from ..models import Organization
logger = get_logger(__file__) logger = get_logger(__file__)
__all__ = [ __all__ = [
'OrgManager', 'OrgModelMixin', 'Organization' 'OrgManager', 'OrgModelMixin', 'JMSOrgBaseModel'
] ]
@ -40,7 +41,6 @@ class OrgManager(models.Manager):
set_current_org(org) set_current_org(org)
return self return self
def bulk_create(self, objs, batch_size=None, ignore_conflicts=False): def bulk_create(self, objs, batch_size=None, ignore_conflicts=False):
org = get_current_org() org = get_current_org()
for obj in objs: for obj in objs:
@ -87,7 +87,7 @@ class OrgModelMixin(models.Model):
name = getattr(self, attr) name = getattr(self, attr)
elif hasattr(self, 'name'): elif hasattr(self, 'name'):
name = self.name name = self.name
elif hasattr(self, 'hostname'): elif hasattr(self, 'name'):
name = self.hostname name = self.hostname
return name + self.sep + self.org_name return name + self.sep + self.org_name
@ -113,3 +113,8 @@ class OrgModelMixin(models.Model):
class Meta: class Meta:
abstract = True abstract = True
class JMSOrgBaseModel(JMSBaseModel, OrgModelMixin):
class Meta:
abstract = True

@ -199,30 +199,3 @@ class Organization(OrgRoleMixin, models.Model):
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
self.delete_related_models() self.delete_related_models()
return super().delete(*args, **kwargs) return super().delete(*args, **kwargs)
class OrganizationMember(models.Model):
"""
注意直接调用该 `Model.delete` `Model.objects.delete` 不会触发清理该用户的信号
"""
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
org = models.ForeignKey(
Organization, related_name='m2m_org_members', on_delete=models.CASCADE, verbose_name=_('Organization')
)
user = models.ForeignKey(
'users.User', related_name='m2m_org_members', on_delete=models.CASCADE, verbose_name=_('User')
)
role = models.CharField(max_length=16, default='User', verbose_name=_("Role"))
date_created = models.DateTimeField(auto_now_add=True, verbose_name=_("Date created"))
date_updated = models.DateTimeField(auto_now=True, verbose_name=_("Date updated"))
created_by = models.CharField(max_length=128, null=True, verbose_name=_('Created by'))
# objects = OrgMemberManager()
class Meta:
unique_together = [('org', 'user', 'role')]
db_table = 'orgs_organization_members'
def __str__(self):
return '{} | {}'.format(self.user, self.org)

@ -91,7 +91,7 @@ class AssetPermissionAssetRelationViewSet(RelationMixin):
class AssetPermissionAllAssetListApi(generics.ListAPIView): class AssetPermissionAllAssetListApi(generics.ListAPIView):
serializer_class = serializers.AssetPermissionAllAssetSerializer serializer_class = serializers.AssetPermissionAllAssetSerializer
filterset_fields = ("hostname", "ip") filterset_fields = ("name", "ip")
search_fields = filterset_fields search_fields = filterset_fields
def get_queryset(self): def get_queryset(self):

@ -33,8 +33,8 @@ class UserGroupMixin:
class UserGroupGrantedAssetsApi(ListAPIView): class UserGroupGrantedAssetsApi(ListAPIView):
serializer_class = serializers.AssetGrantedSerializer serializer_class = serializers.AssetGrantedSerializer
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
filterset_fields = ['hostname', 'ip', 'id', 'comment'] filterset_fields = ['name', 'ip', 'id', 'comment']
search_fields = ['hostname', 'ip', 'comment'] search_fields = ['name', 'ip', 'comment']
rbac_perms = { rbac_perms = {
'list': 'perms.view_usergroupassets', 'list': 'perms.view_usergroupassets',
} }
@ -70,8 +70,8 @@ class UserGroupGrantedAssetsApi(ListAPIView):
class UserGroupGrantedNodeAssetsApi(ListAPIView): class UserGroupGrantedNodeAssetsApi(ListAPIView):
serializer_class = serializers.AssetGrantedSerializer serializer_class = serializers.AssetGrantedSerializer
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
filterset_fields = ['hostname', 'ip', 'id', 'comment'] filterset_fields = ['name', 'ip', 'id', 'comment']
search_fields = ['hostname', 'ip', 'comment'] search_fields = ['name', 'ip', 'comment']
rbac_perms = { rbac_perms = {
'list': 'perms.view_usergroupassets', 'list': 'perms.view_usergroupassets',
} }

@ -81,16 +81,16 @@ class UserGrantedNodeAssetsMixin:
class AssetsSerializerFormatMixin: class AssetsSerializerFormatMixin:
serializer_class = serializers.AssetGrantedSerializer serializer_class = serializers.AssetGrantedSerializer
filterset_fields = ['hostname', 'ip', 'id', 'comment'] filterset_fields = ['name', 'ip', 'id', 'comment']
search_fields = ['hostname', 'ip', 'comment'] search_fields = ['name', 'ip', 'comment']
class AssetsTreeFormatMixin(SerializeToTreeNodeMixin): class AssetsTreeFormatMixin(SerializeToTreeNodeMixin):
""" """
资产 序列化成树的结构返回 资产 序列化成树的结构返回
""" """
filterset_fields = ['hostname', 'ip', 'id', 'comment'] filterset_fields = ['name', 'ip', 'id', 'comment']
search_fields = ['hostname', 'ip', 'comment'] search_fields = ['name', 'ip', 'comment']
def list(self, request: Request, *args, **kwargs): def list(self, request: Request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset()) queryset = self.filter_queryset(self.get_queryset())
@ -99,6 +99,6 @@ class AssetsTreeFormatMixin(SerializeToTreeNodeMixin):
# 如果用户搜索的条件不精准,会导致返回大量的无意义数据。 # 如果用户搜索的条件不精准,会导致返回大量的无意义数据。
# 这里限制一下返回数据的最大条数 # 这里限制一下返回数据的最大条数
queryset = queryset[:999] queryset = queryset[:999]
queryset = sorted(queryset, key=lambda asset: asset.hostname) queryset = sorted(queryset, key=lambda asset: asset.name)
data = self.serialize_assets(queryset, None) data = self.serialize_assets(queryset, None)
return Response(data=data) return Response(data=data)

@ -117,7 +117,7 @@ class AssetPermissionFilter(PermissionBaseFilter):
model = AssetPermission model = AssetPermission
fields = ( fields = (
'user_id', 'username', 'system_user_id', 'system_user', 'user_group_id', 'user_id', 'username', 'system_user_id', 'system_user', 'user_group_id',
'user_group', 'node_id', 'node', 'asset_id', 'hostname', 'ip', 'name', 'user_group', 'node_id', 'node', 'asset_id', 'name', 'ip', 'name',
'all', 'asset_id', 'is_valid', 'is_effective', 'from_ticket' 'all', 'asset_id', 'is_valid', 'is_effective', 'from_ticket'
) )
@ -157,7 +157,7 @@ class AssetPermissionFilter(PermissionBaseFilter):
def filter_asset(self, queryset): def filter_asset(self, queryset):
is_query_all = self.get_query_param('all', True) is_query_all = self.get_query_param('all', True)
asset_id = self.get_query_param('asset_id') asset_id = self.get_query_param('asset_id')
hostname = self.get_query_param('hostname') hostname = self.get_query_param('name')
ip = self.get_query_param('ip') ip = self.get_query_param('ip')
if asset_id: if asset_id:

@ -185,7 +185,7 @@ class AssetPermission(OrgModelMixin):
return names return names
def assets_display(self): def assets_display(self):
names = [asset.hostname for asset in self.assets.all()] names = [asset.name for asset in self.assets.all()]
return names return names
def nodes_display(self): def nodes_display(self):

@ -83,7 +83,7 @@ class AssetPermissionAllAssetSerializer(serializers.Serializer):
asset_display = serializers.SerializerMethodField() asset_display = serializers.SerializerMethodField()
class Meta: class Meta:
only_fields = ['id', 'hostname', 'ip'] only_fields = ['id', 'name', 'ip']
@staticmethod @staticmethod
def get_asset_display(obj): def get_asset_display(obj):

@ -44,7 +44,7 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Asset model = Asset
only_fields = [ only_fields = [
"id", "hostname", "ip", "protocols", "os", 'domain', "id", "name", "ip", "protocols", "os", 'domain',
"platform", "comment", "org_id", "is_active" "platform", "comment", "org_id", "is_active"
] ]
fields = only_fields + ['org_name'] fields = only_fields + ['org_name']

@ -513,7 +513,7 @@ class UserGrantedAssetsQueryUtils(UserGrantedUtilsBase):
assets = self._get_indirect_granted_node_assets(node.id) assets = self._get_indirect_granted_node_assets(node.id)
else: else:
assets = Asset.objects.none() assets = Asset.objects.none()
assets = assets.order_by('hostname') assets = assets.order_by('name')
return assets return assets
def _get_indirect_granted_node_assets(self, id) -> AssetQuerySet: def _get_indirect_granted_node_assets(self, id) -> AssetQuerySet:

@ -4,7 +4,7 @@ from rest_framework import serializers
class TerminalSettingSerializer(serializers.Serializer): class TerminalSettingSerializer(serializers.Serializer):
SORT_BY_CHOICES = ( SORT_BY_CHOICES = (
('hostname', _('Hostname')), ('name', _('Hostname')),
('ip', _('IP')) ('ip', _('IP'))
) )

@ -28,7 +28,7 @@ def sync_node(src, target, cut=False):
asset.save() asset.save()
new_asset = asset new_asset = asset
else: else:
new_asset = get_object_or_none(Asset, hostname=asset.hostname, org_id=target.org_id) new_asset = get_object_or_none(Asset, hostname=asset.name, org_id=target.org_id)
if new_asset is None: if new_asset is None:
asset.id = None asset.id = None
asset.org_id = target.org_id asset.org_id = target.org_id

Loading…
Cancel
Save