perf: 控制平台创建

pull/8605/head
ibuler 2022-05-02 21:37:42 +08:00
parent 7e6964e0fc
commit 7025d46070
6 changed files with 75 additions and 16 deletions

View File

@ -93,6 +93,7 @@ class DatabaseTypes(PlatformMixin, models.TextChoices):
meta[name] = { meta[name] = {
'protocols_limit': [name] 'protocols_limit': [name]
} }
return meta
class RemoteAppTypes(PlatformMixin, models.TextChoices): class RemoteAppTypes(PlatformMixin, models.TextChoices):

View File

@ -3,6 +3,14 @@
from django.db import migrations, models from django.db import migrations, models
def migrate_platform_type_to_lower(apps, *args):
platform_model = apps.get_model('assets', 'Platform')
platforms = platform_model.objects.all()
for p in platforms:
p.type = p.type.lower()
p.save()
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
@ -31,4 +39,5 @@ class Migration(migrations.Migration):
name='protocol', name='protocol',
field=models.CharField(choices=[('ssh', 'SSH'), ('rdp', 'RDP'), ('telnet', 'Telnet'), ('vnc', 'VNC'), ('mysql', 'MySQL'), ('mariadb', 'MariaDB'), ('oracle', 'Oracle'), ('postgresql', 'PostgreSQL'), ('sqlserver', 'SQLServer'), ('redis', 'Redis'), ('mongodb', 'MongoDB'), ('k8s', 'K8S')], default='ssh', max_length=16, verbose_name='Protocol'), field=models.CharField(choices=[('ssh', 'SSH'), ('rdp', 'RDP'), ('telnet', 'Telnet'), ('vnc', 'VNC'), ('mysql', 'MySQL'), ('mariadb', 'MariaDB'), ('oracle', 'Oracle'), ('postgresql', 'PostgreSQL'), ('sqlserver', 'SQLServer'), ('redis', 'Redis'), ('mongodb', 'MongoDB'), ('k8s', 'K8S')], default='ssh', max_length=16, verbose_name='Protocol'),
), ),
migrations.RunPython(migrate_platform_type_to_lower)
] ]

View File

@ -35,13 +35,20 @@ class Platform(models.Model):
verbose_name=_("Admin user default") verbose_name=_("Admin user default")
) )
def get_type_meta(self): @classmethod
meta = Category.platform_meta().get(self.category, {}) def get_type_meta(cls, category, tp):
types = dict(AllTypes.category_types())[self.category] meta = Category.platform_meta().get(category, {})
type_meta = types.platform_meta().get(self.type, {}) types = dict(AllTypes.category_types()).get(category)
# if not types:
# return {}
types_meta = types.platform_meta() or {}
type_meta = types_meta.get(tp, {})
meta.update(type_meta) meta.update(type_meta)
return meta return meta
def get_meta(self):
return self.__class__.get_type_meta(self.category, self.type)
@classmethod @classmethod
def default(cls): def default(cls):
linux, created = cls.objects.get_or_create( linux, created = cls.objects.get_or_create(

View File

@ -14,11 +14,10 @@ __all__ = [
class ProtocolField(serializers.RegexField): class ProtocolField(serializers.RegexField):
protocols = '|'.join(dict(Asset.Protocol.choices).keys())
default_error_messages = { default_error_messages = {
'invalid': _('Protocol format should {}/{}').format(protocols, '1-65535') 'invalid': _('Protocol format should {}/{}').format('protocol', '1-65535')
} }
regex = r'^(%s)/(\d{1,5})$' % protocols regex = r'^(\w+)/(\d{1,5})$'
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(self.regex, **kwargs) super().__init__(self.regex, **kwargs)
@ -43,18 +42,28 @@ def validate_duplicate_protocols(values):
class ProtocolsField(serializers.ListField): class ProtocolsField(serializers.ListField):
default_validators = [validate_duplicate_protocols] default_validators = [validate_duplicate_protocols]
def __init__(self, *args, **kwargs): def __init__(self, protocols=None, *args, **kwargs):
self.choices = []
self.set_protocols(protocols)
kwargs['child'] = ProtocolField() kwargs['child'] = ProtocolField()
kwargs['allow_null'] = True kwargs['allow_null'] = True
kwargs['allow_empty'] = True kwargs['allow_empty'] = True
kwargs['min_length'] = 1 kwargs['min_length'] = 1
kwargs['max_length'] = 4 kwargs['max_length'] = 32
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def set_protocols(self, protocols):
if protocols is None:
protocols = []
self.choices = [(c, c) for c in protocols]
print("Chocies: ", self.choices)
def to_representation(self, value): def to_representation(self, value):
if not value: if not value:
return [] return []
if isinstance(value, str):
return value.split(' ') return value.split(' ')
return value
class AssetSerializer(CategoryDisplayMixin, OrgResourceModelSerializerMixin): class AssetSerializer(CategoryDisplayMixin, OrgResourceModelSerializerMixin):
@ -139,7 +148,7 @@ class AssetSerializer(CategoryDisplayMixin, OrgResourceModelSerializerMixin):
validated_data["protocol"] = protocol[0] validated_data["protocol"] = protocol[0]
validated_data["port"] = int(protocol[1]) validated_data["port"] = int(protocol[1])
if protocols_data: if protocols_data:
validated_data["protocols"] = ' '.join(protocols_data) validated_data["protocols"] = protocols_data
def perform_nodes_display_create(self, instance, nodes_display): def perform_nodes_display_create(self, instance, nodes_display):
if not nodes_display: if not nodes_display:

View File

@ -3,7 +3,8 @@ from django.core.validators import RegexValidator
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from assets.models import Platform from assets.models import Platform
from assets.const import AllTypes from assets.serializers.asset import ProtocolsField
from assets.const import Protocol
from .mixin import CategoryDisplayMixin from .mixin import CategoryDisplayMixin
__all__ = ['PlatformSerializer'] __all__ = ['PlatformSerializer']
@ -11,6 +12,7 @@ __all__ = ['PlatformSerializer']
class PlatformSerializer(CategoryDisplayMixin, serializers.ModelSerializer): class PlatformSerializer(CategoryDisplayMixin, serializers.ModelSerializer):
meta = serializers.DictField(required=False, allow_null=True, label=_('Meta')) meta = serializers.DictField(required=False, allow_null=True, label=_('Meta'))
protocols_default = ProtocolsField(label=_('Protocols'), required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -19,13 +21,43 @@ class PlatformSerializer(CategoryDisplayMixin, serializers.ModelSerializer):
validators = self.fields['name'].validators validators = self.fields['name'].validators
if isinstance(validators[-1], RegexValidator): if isinstance(validators[-1], RegexValidator):
validators.pop() validators.pop()
self.set_platform_meta()
def set_platform_meta(self):
view = self.context.get('view')
if not view:
return
request = view.request
if isinstance(self.instance, Platform):
category = self.instance.category
tp = self.instance.type
else:
tp = request.query_params.get('type')
category = request.query_params.get('category')
print("Request: {}".format(self.context.get('request').method), category, tp)
if not all([tp, category]):
return
meta = Platform.get_type_meta(category, tp)
print("Platform meta: {}".format(meta))
protocols_default = self.fields['protocols_default']
limits = meta.get('protocols_limit', [])
default_ports = Protocol.default_ports()
protocols = []
for protocol in limits:
port = default_ports.get(protocol, 22)
protocols.append(f'{protocol}/{port}')
print("set ptocols: ", protocols)
protocols_default.set_protocols(protocols)
class Meta: class Meta:
model = Platform model = Platform
fields_mini = ['id', 'name', 'internal'] fields_mini = ['id', 'name', 'internal']
fields_small = fields_mini + [ fields_small = fields_mini + [
'meta', 'comment', 'charset', 'meta', 'comment', 'charset',
'category', 'category_display', 'type', 'type_display', 'category', 'category_display',
'type', 'type_display',
] ]
fields_fk = [ fields_fk = [
'domain_enabled', 'domain_default', 'domain_enabled', 'domain_default',

View File

@ -33,6 +33,7 @@ class SimpleMetadataWithFilters(SimpleMetadata):
""" """
actions = {} actions = {}
view.raw_action = getattr(view, 'action', None) view.raw_action = getattr(view, 'action', None)
print("Request in metadata: ", request.path, request.GET)
for method in self.methods & set(view.allowed_methods): for method in self.methods & set(view.allowed_methods):
if hasattr(view, 'action_map'): if hasattr(view, 'action_map'):
view.action = view.action_map.get(method.lower(), view.action) view.action = view.action_map.get(method.lower(), view.action)
@ -80,14 +81,14 @@ class SimpleMetadataWithFilters(SimpleMetadata):
elif getattr(field, 'fields', None): elif getattr(field, 'fields', None):
field_info['children'] = self.get_serializer_info(field) field_info['children'] = self.get_serializer_info(field)
if not isinstance(field, (serializers.RelatedField, serializers.ManyRelatedField)) \ is_related_field = isinstance(field, (serializers.RelatedField, serializers.ManyRelatedField))
and hasattr(field, 'choices'): if not is_related_field and hasattr(field, 'choices'):
field_info['choices'] = [ field_info['choices'] = [
{ {
'value': choice_value, 'value': choice_value,
'display_name': force_text(choice_name, strings_only=True) 'display_name': force_text(choice_name, strings_only=True)
} }
for choice_value, choice_name in field.choices.items() for choice_value, choice_name in dict(field.choices).items()
] ]
return field_info return field_info