perf: 修改 asset 结构

pull/8931/head
ibuler 2022-09-21 11:17:14 +08:00
parent cf5c50b343
commit 1b0195cb82
37 changed files with 95 additions and 109 deletions

View File

@ -18,8 +18,8 @@ __all__ = ['AccountViewSet', 'AccountSecretsViewSet', 'AccountTaskCreateAPI']
class AccountViewSet(OrgBulkModelViewSet):
model = Account
filterset_fields = ("username", "asset", 'ip', 'name')
search_fields = ('username', 'ip', 'name')
filterset_fields = ("username", "asset", 'address', 'name')
search_fields = ('username', 'address', 'name')
filterset_class = AccountFilterSet
serializer_classes = {
'default': serializers.AccountSerializer,

View File

@ -30,7 +30,7 @@ class AssetFilterSet(BaseFilterSet):
class Meta:
model = Asset
fields = ['name', 'ip', 'is_active', 'type', 'category', 'hostname']
fields = ['name', 'address', 'is_active', 'type', 'category', 'hostname']
class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
@ -39,8 +39,8 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
"""
model = Asset
filterset_class = AssetFilterSet
search_fields = ("name", "ip")
ordering_fields = ("name", "ip")
search_fields = ("name", "address")
ordering_fields = ("name", "address")
ordering = ('name',)
serializer_classes = (
('default', serializers.AssetSerializer),

View File

@ -31,8 +31,8 @@ class DomainViewSet(OrgBulkModelViewSet):
class GatewayViewSet(OrgBulkModelViewSet):
model = Gateway
filterset_fields = ("domain__name", "name", "username", "ip", "domain")
search_fields = ("domain__name", "name", "username", "ip")
filterset_fields = ("domain__name", "name", "username", "address", "domain")
search_fields = ("domain__name", "name", "username", "address")
serializer_class = serializers.GatewaySerializer

View File

@ -57,7 +57,7 @@ class SerializeToTreeNodeMixin:
{
'id': str(asset.id),
'name': asset.name,
'title': asset.ip,
'title': asset.address,
'pId': get_pid(asset),
'isParent': False,
'open': False,
@ -68,7 +68,7 @@ class SerializeToTreeNodeMixin:
'data': {
'id': asset.id,
'name': asset.name,
'ip': asset.ip,
'address': asset.address,
'protocols': asset.protocols_as_list,
'platform': asset.platform.id,
'org_name': asset.org_name

View File

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

View File

View File

@ -20,14 +20,13 @@ class Protocol(ChoicesMixin, models.TextChoices):
k8s = 'k8s', 'K8S'
http = 'http', 'HTTP'
https = 'https', 'HTTPS'
@classmethod
def device_settings(cls):
def device_protocols(cls):
return {
cls.ssh: {
'port': 22,
'secret_type': ['password', 'ssh_key'],
'secret_types': ['password', 'ssh_key'],
'setting': {
'sftp_enabled': True,
'sftp_home': '/tmp',
@ -35,7 +34,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
},
cls.rdp: {
'port': 3389,
'secret_type': ['password'],
'secret_types': ['password'],
'setting': {
'console': True,
'security': 'any',
@ -43,64 +42,63 @@ class Protocol(ChoicesMixin, models.TextChoices):
},
cls.vnc: {
'port': 5900,
'secret_type': ['password'],
'secret_types': ['password'],
},
cls.telnet: {
'port': 23,
'secret_type': ['password'],
'secret_types': ['password'],
},
}
@classmethod
def db_settings(cls):
def database_protocols(cls):
return {
cls.mysql: {
'port': 3306,
'secret_type': ['password'],
'secret_types': ['password'],
'setting': {
}
},
cls.mariadb: {
'port': 3306,
'secret_type': ['password'],
'secret_types': ['password'],
},
cls.postgresql: {
'port': 5432,
'secret_type': ['password'],
'secret_types': ['password'],
},
cls.oracle: {
'port': 1521,
'secret_type': ['password'],
'secret_types': ['password'],
},
cls.sqlserver: {
'port': 1433,
'secret_type': ['password'],
'secret_types': ['password'],
},
cls.mongodb: {
'port': 27017,
'secret_type': ['password'],
'secret_types': ['password'],
},
cls.redis: {
'port': 6379,
'secret_type': ['password'],
'secret_types': ['password'],
},
}
@classmethod
def cloud_settings(cls):
def cloud_protocols(cls):
return {
cls.k8s: {
'port': 443,
'secret_type': ['token'],
'setting': {
'via_http': True
}
'secret_types': ['token'],
},
cls.http: {
'port': 80,
'secret_type': ['password'],
'secret_types': ['password'],
'setting': {
'ssl': True
'username_selector': '',
'password_selector': '',
'submit_selector': '',
}
},
}
@ -108,30 +106,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
@classmethod
def settings(cls):
return {
**cls.device_settings(),
**cls.db_settings(),
**cls.cloud_settings()
**cls.device_protocols(),
**cls.database_protocols(),
**cls.cloud_protocols()
}
@classmethod
def default_ports(cls):
return {
cls.ssh: 22,
cls.sftp: 22,
cls.rdp: 3389,
cls.vnc: 5900,
cls.telnet: 21,
cls.mysql: 3306,
cls.mariadb: 3306,
cls.postgresql: 5432,
cls.oracle: 1521,
cls.sqlserver: 1433,
cls.mongodb: 27017,
cls.redis: 6379,
cls.k8s: 0,
cls.http: 80,
}

View File

@ -150,7 +150,7 @@ class IpInFilterBackend(filters.BaseFilterBackend):
name='ips', location='query', required=False, type='string',
schema=coreschema.String(
title='ips',
description='ip in filter'
description='address in filter'
)
)
]
@ -158,7 +158,7 @@ class IpInFilterBackend(filters.BaseFilterBackend):
class AccountFilterSet(BaseFilterSet):
from django_filters import rest_framework as filters
ip = filters.CharFilter(field_name='ip', lookup_expr='exact')
ip = filters.CharFilter(field_name='address', lookup_expr='exact')
hostname = filters.CharFilter(field_name='name', lookup_expr='exact')
username = filters.CharFilter(field_name="username", lookup_expr='exact')
assets = UUIDInFilter(field_name='asset_id', lookup_expr='in')

View File

@ -17,6 +17,11 @@ class Migration(migrations.Migration):
name='info',
field=models.JSONField(blank=True, default=dict, verbose_name='Info'),
),
migrations.RenameField(
model_name='asset',
old_name='ip',
new_name='address',
),
migrations.CreateModel(
name='Host',
fields=[

View File

@ -36,7 +36,6 @@ class Migration(migrations.Migration):
name='Cloud',
fields=[
('asset_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='assets.asset')),
('url', models.CharField(max_length=4096, verbose_name='Cluster')),
],
options={
'abstract': False,
@ -47,7 +46,6 @@ class Migration(migrations.Migration):
name='Web',
fields=[
('asset_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='assets.asset')),
('url', models.CharField(max_length=1024, verbose_name='url')),
('autofill', models.CharField(default='basic', max_length=16)),
('password_selector', models.CharField(blank=True, default='', max_length=128)),
('submit_selector', models.CharField(blank=True, default='', max_length=128)),

View File

@ -35,7 +35,7 @@ class Account(BaseAccount):
@lazyproperty
def ip(self):
return self.asset.ip
return self.asset.address
@lazyproperty
def asset_name(self):

View File

@ -1,11 +1,7 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from .common import Asset
class Cloud(Asset):
url = models.CharField(max_length=4096, verbose_name=_("Url"))
def __str__(self):
return self.name

View File

@ -84,7 +84,7 @@ class Protocol(models.Model):
class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, verbose_name=_('Name'))
ip = models.CharField(max_length=128, verbose_name=_('IP'), db_index=True)
address = models.CharField(max_length=128, verbose_name=_('IP'), db_index=True)
platform = models.ForeignKey(Platform, default=Platform.default, on_delete=models.PROTECT,
verbose_name=_("Platform"), related_name='assets')
domain = models.ForeignKey("assets.Domain", null=True, blank=True, related_name='assets',
@ -101,7 +101,7 @@ class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
return '{0.name}({0.ip})'.format(self)
def get_target_ip(self):
return self.ip
return self.address
def get_target_ssh_port(self):
protocol = self.protocols.all().filter(name='ssh').first()
@ -161,7 +161,7 @@ class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
data = {
'id': str(self.id),
'name': self.name,
'title': self.ip,
'title': self.address,
'pId': parent_node.key,
'isParent': False,
'open': False,
@ -171,7 +171,7 @@ class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
'data': {
'id': self.id,
'name': self.name,
'ip': self.ip,
'address': self.address,
'protocols': self.protocols,
}
}

View File

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

View File

@ -1,4 +1,3 @@
from .common import Asset

View File

@ -3,6 +3,4 @@ from .common import Asset
class Host(Asset):
def save(self, *args, **kwargs):
self.category = Category.HOST
return super().save(*args, **kwargs)
pass

View File

@ -1,11 +1,9 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
from .common import Asset
class Web(Asset):
url = models.CharField(max_length=1024, verbose_name=_("url"))
autofill = models.CharField(max_length=16, default='basic')
username_selector = models.CharField(max_length=128, blank=True, default='')
password_selector = models.CharField(max_length=128, blank=True, default='')

View File

@ -136,7 +136,7 @@ class Gateway(BaseAccount):
socket.gaierror) as e:
err = str(e)
if err.startswith('[Errno None] Unable to connect to port'):
err = _('Unable to connect to port {port} on {ip}')
err = _('Unable to connect to port {port} on {address}')
err = err.format(port=self.port, ip=self.ip)
elif err == 'Authentication failed.':
err = _('Authentication failed')

View File

@ -25,7 +25,7 @@ class GatheredUser(OrgModelMixin):
@property
def ip(self):
return self.asset.ip
return self.asset.address
class Meta:
verbose_name = _('GatherUser')

View File

@ -58,7 +58,7 @@ class AccountSerializer(
):
asset = ObjectRelatedField(
required=False, queryset=Asset.objects,
label=_('Asset'), attrs=('id', 'name', 'ip')
label=_('Asset'), attrs=('id', 'name', 'address')
)
platform = serializers.ReadOnlyField(label=_("Platform"))
@ -77,7 +77,7 @@ class AccountSerializer(
class AccountSecretSerializer(SecretReadableMixin, AccountSerializer):
class Meta(AccountSerializer.Meta):
fields_backup = [
'name', 'ip', 'platform', 'protocols', 'username', 'password',
'name', 'address', 'platform', 'protocols', 'username', 'password',
'private_key', 'public_key', 'date_created', 'date_updated', 'version'
]
extra_kwargs = {

View File

@ -7,5 +7,10 @@ __all__ = ['CloudSerializer']
class CloudSerializer(AssetSerializer):
class Meta(AssetSerializer.Meta):
model = Cloud
fields = AssetSerializer.Meta.fields + ['cluster']
fields = AssetSerializer.Meta.fields
extra_kwargs = {
**AssetSerializer.Meta.extra_kwargs,
'address': {
'label': 'URL'
}
}

View File

@ -68,7 +68,7 @@ class AssetSerializer(JMSWritableNestedModelSerializer):
class Meta:
model = Asset
fields_mini = ['id', 'name', 'ip']
fields_mini = ['id', 'name', 'address']
fields_small = fields_mini + ['is_active', 'comment']
fields_fk = ['domain', 'platform', 'platform']
fields_m2m = [
@ -81,7 +81,7 @@ class AssetSerializer(JMSWritableNestedModelSerializer):
fields = fields_small + fields_fk + fields_m2m + read_only_fields
extra_kwargs = {
'name': {'label': _("Name")},
'ip': {'label': _('IP/Host')},
'address': {'label': _('Address')},
}
@classmethod
@ -142,7 +142,7 @@ class AssetSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = Asset
fields = [
'id', 'name', 'ip', 'port',
'id', 'name', 'address', 'port',
'connectivity', 'date_verified'
]

View File

@ -9,6 +9,12 @@ class WebSerializer(AssetSerializer):
class Meta(AssetSerializer.Meta):
model = Web
fields = AssetSerializer.Meta.fields + [
'url', 'autofill', 'username_selector',
'autofill', 'username_selector',
'password_selector', 'submit_selector'
]
extra_kwargs = {
**AssetSerializer.Meta.extra_kwargs,
'address': {
'label': 'URL'
}
}

View File

@ -25,6 +25,8 @@ class ProtocolSettingSerializer(serializers.Serializer):
sftp_enabled = serializers.BooleanField(default=True, label=_("SFTP enabled"))
sftp_home = serializers.CharField(default='/tmp', label=_("SFTP home"))
via_http = serializers.BooleanField(default=False, label=_("Via HTTP"))
class PlatformAutomationSerializer(serializers.ModelSerializer):
class Meta:

View File

@ -95,7 +95,7 @@ def add_asset_users(assets, results):
for username, data in users.items():
defaults = {'asset': asset, 'username': username, 'present': True}
if data.get("ip"):
defaults["ip_last_login"] = data["ip"][:32]
defaults["ip_last_login"] = data["address"][:32]
if data.get("date"):
defaults["date_last_login"] = data["date"]
GatheredUser.objects.update_or_create(

View File

@ -36,13 +36,13 @@ def write_content_to_excel(response, header=None, login_logs=None, fields=None):
def write_login_log(*args, **kwargs):
from audits.models import UserLoginLog
ip = kwargs.get('ip') or ''
ip = kwargs.get('address') or ''
if not (ip and validate_ip(ip)):
ip = ip[:15]
city = DEFAULT_CITY
else:
city = get_ip_city(ip) or DEFAULT_CITY
kwargs.update({'ip': ip, 'city': city})
kwargs.update({'address': ip, 'city': city})
UserLoginLog.objects.create(**kwargs)

View File

@ -48,7 +48,7 @@ block_user_login_msg = _(
"(please contact admin to unlock it or try again after {} minutes)"
)
block_ip_login_msg = _(
"The ip has been locked "
"The address has been locked "
"(please contact admin to unlock it or try again after {} minutes)"
)
block_mfa_msg = _(

View File

@ -75,7 +75,7 @@ def contains_ip(ip, ip_group):
def get_ip_city(ip):
if not ip or not isinstance(ip, str):
return _("Invalid ip")
return _("Invalid address")
if ':' in ip:
return 'IPv6'

View File

@ -40,7 +40,7 @@ class BaseHost(Host):
def __set_required_variables(self):
host_data = self.host_data
self.set_variable('ansible_host', host_data['ip'])
self.set_variable('ansible_host', host_data['address'])
self.set_variable('ansible_port', host_data['port'])
if host_data.get('username'):

View File

@ -19,7 +19,7 @@ class JMSBaseInventory(BaseInventory):
info = {
'id': asset.id,
'name': asset.name,
'ip': asset.ip,
'ip': asset.address,
'port': asset.ssh_port,
'vars': dict(),
'groups': [],
@ -49,7 +49,7 @@ class JMSBaseInventory(BaseInventory):
proxy_command_list = [
"ssh", "-o", "Port={}".format(gateway.port),
"-o", "StrictHostKeyChecking=no",
"{}@{}".format(gateway.username, gateway.ip),
"{}@{}".format(gateway.username, gateway.address),
"-W", "%h:%p", "-q",
]

View File

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

View File

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

View File

@ -32,7 +32,7 @@ class UserDirectGrantedAssetsQuerysetMixin:
class UserAllGrantedAssetsQuerysetMixin:
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
pagination_class = AllGrantedAssetPagination
ordering_fields = ("hostname", "ip", "port", "cpu_cores")
ordering_fields = ("hostname", "address", "port", "cpu_cores")
ordering = ('hostname', )
user: User
@ -84,8 +84,8 @@ class UserGrantedNodeAssetsMixin:
class AssetsSerializerFormatMixin:
serializer_class = serializers.AssetGrantedSerializer
filterset_fields = ['name', 'ip', 'id', 'comment']
search_fields = ['name', 'ip', 'comment']
filterset_fields = ['name', 'address', 'id', 'comment']
search_fields = ['name', 'address', 'comment']
class AssetsTreeFormatMixin(SerializeToTreeNodeMixin):
@ -95,8 +95,8 @@ class AssetsTreeFormatMixin(SerializeToTreeNodeMixin):
filter_queryset: callable
get_queryset: callable
filterset_fields = ['name', 'ip', 'id', 'comment']
search_fields = ['name', 'ip', 'comment']
filterset_fields = ['name', 'address', 'id', 'comment']
search_fields = ['name', 'address', 'comment']
def list(self, request: Request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())

View File

@ -142,7 +142,7 @@ class AssetPermissionFilter(PermissionBaseFilter):
is_query_all = self.get_query_param('all', True)
asset_id = self.get_query_param('asset_id')
asset_name = self.get_query_param('asset_name')
ip = self.get_query_param('ip')
ip = self.get_query_param('address')
if asset_id:
assets = Asset.objects.filter(pk=asset_id)

View File

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

View File

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

2
jms
View File

@ -117,7 +117,7 @@ def download_ip_db():
path = os.path.join(db_base_dir, *p)
if os.path.isfile(path) and os.path.getsize(path) > 1000:
continue
print("Download ip db: {}".format(path))
print("Download address db: {}".format(path))
download_file(src, path)