From 180ded1773572ce3f2b856f9a52167b3c3d931f3 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 22 Mar 2023 14:15:25 +0800 Subject: [PATCH 1/4] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20platform=20pro?= =?UTF-8?q?tocols?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/const/base.py | 8 ++--- .../migrations/0111_auto_20230321_1633.py | 35 +++++++++++++++++++ apps/assets/models/asset/common.py | 19 ---------- apps/assets/models/platform.py | 23 ++---------- apps/assets/serializers/platform.py | 19 +++++++--- apps/ops/ansible/inventory.py | 9 ++++- 6 files changed, 64 insertions(+), 49 deletions(-) create mode 100644 apps/assets/migrations/0111_auto_20230321_1633.py diff --git a/apps/assets/const/base.py b/apps/assets/const/base.py index aa5070d5e..4b147f8ef 100644 --- a/apps/assets/const/base.py +++ b/apps/assets/const/base.py @@ -6,8 +6,10 @@ from .protocol import Protocol class BaseType(TextChoices): """ - 约束应该考虑代是对平台对限制,避免多余对选项,如: mysql 开启 ssh, 或者开启了也没有作用, 比如 k8s 开启了 domain,目前还不支持 + 约束应该考虑代是对平台对限制,避免多余对选项,如: mysql 开启 ssh, + 或者开启了也没有作用, 比如 k8s 开启了 domain,目前还不支持 """ + @classmethod def get_constrains(cls): constrains = {} @@ -36,7 +38,7 @@ class BaseType(TextChoices): if choices == '__self__': choices = [tp] protocols = [{'name': name, **settings.get(name, {})} for name in choices] - protocols[0]['primary'] = True + protocols[0]['default'] = True return protocols @classmethod @@ -74,5 +76,3 @@ class BaseType(TextChoices): choice for choice in cls_choices if choice[0] in tps ] - - diff --git a/apps/assets/migrations/0111_auto_20230321_1633.py b/apps/assets/migrations/0111_auto_20230321_1633.py new file mode 100644 index 000000000..ad7d57982 --- /dev/null +++ b/apps/assets/migrations/0111_auto_20230321_1633.py @@ -0,0 +1,35 @@ +# Generated by Django 3.2.17 on 2023-03-21 08:33 + +from django.db import migrations, models + + +def migrate_platform_charset(apps, schema_editor): + platform_model = apps.get_model('assets', 'Platform') + platform_model.objects.filter(charset='utf8').update(charset='utf-8') + + +def migrate_platform_protocol_required(apps, schema_editor): + platform_model = apps.get_model('assets', 'Platform') + platforms = platform_model.objects.all() + + for platform in platforms: + p = platform.protocols.first() + p.primary = True + p.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0110_auto_20230315_1741'), + ] + + operations = [ + migrations.AddField( + model_name='platformprotocol', + name='primary', + field=models.BooleanField(default=False, verbose_name='Primary'), + ), + migrations.RunPython(migrate_platform_charset), + migrations.RunPython(migrate_platform_protocol_required), + ] diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py index 3a38699e8..8643f4a6c 100644 --- a/apps/assets/models/asset/common.py +++ b/apps/assets/models/asset/common.py @@ -191,25 +191,6 @@ class Asset(NodesRelationMixin, AbsConnectivity, JMSOrgBaseModel): names.append(n.name + ':' + n.value) return names - @lazyproperty - def primary_protocol(self): - from assets.const.types import AllTypes - primary_protocol_name = AllTypes.get_primary_protocol_name(self.category, self.type) - protocol = self.protocols.filter(name=primary_protocol_name).first() - return protocol - - @lazyproperty - def protocol(self): - if not self.primary_protocol: - return 'none' - return self.primary_protocol.name - - @lazyproperty - def port(self): - if not self.primary_protocol: - return 0 - return self.primary_protocol.port - @lazyproperty def type(self): return self.platform.type diff --git a/apps/assets/models/platform.py b/apps/assets/models/platform.py index 488525ccd..e2262af04 100644 --- a/apps/assets/models/platform.py +++ b/apps/assets/models/platform.py @@ -10,29 +10,17 @@ __all__ = ['Platform', 'PlatformProtocol', 'PlatformAutomation'] class PlatformProtocol(models.Model): - SETTING_ATTRS = { - 'console': False, - 'security': 'any,tls,rdp', - 'sftp_enabled': True, - 'sftp_home': '/tmp' - } - default = models.BooleanField(default=False, verbose_name=_('Default')) - required = models.BooleanField(default=False, verbose_name=_('Required')) name = models.CharField(max_length=32, verbose_name=_('Name')) port = models.IntegerField(verbose_name=_('Port')) + primary = models.BooleanField(default=False, verbose_name=_('Primary')) + required = models.BooleanField(default=False, verbose_name=_('Required')) + default = models.BooleanField(default=False, verbose_name=_('Default')) setting = models.JSONField(verbose_name=_('Setting'), default=dict) platform = models.ForeignKey('Platform', on_delete=models.CASCADE, related_name='protocols') def __str__(self): return '{}/{}'.format(self.name, self.port) - @property - def primary(self): - primary_protocol_name = AllTypes.get_primary_protocol_name( - self.platform.category, self.platform.type - ) - return self.name == primary_protocol_name - @property def secret_types(self): return Protocol.settings().get(self.name, {}).get('secret_types') @@ -100,11 +88,6 @@ class Platform(JMSBaseModel): ) return linux.id - @property - def primary_protocol(self): - primary_protocol_name = AllTypes.get_primary_protocol_name(self.category, self.type) - return self.protocols.filter(name=primary_protocol_name).first() - def __str__(self): return self.name diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index 15b4e7cca..c4b51934b 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -72,16 +72,15 @@ class PlatformAutomationSerializer(serializers.ModelSerializer): } -class PlatformProtocolsSerializer(serializers.ModelSerializer): +class PlatformProtocolSerializer(serializers.ModelSerializer): setting = ProtocolSettingSerializer(required=False, allow_null=True) - primary = serializers.BooleanField(read_only=True, label=_("Primary")) class Meta: model = PlatformProtocol fields = [ "id", "name", "port", "primary", - "default", "required", "secret_types", - "setting", + "required", "default", + "secret_types", "setting", ] @@ -91,7 +90,7 @@ class PlatformSerializer(WritableNestedModelSerializer): ) type = LabeledChoiceField(choices=AllTypes.choices(), label=_("Type")) category = LabeledChoiceField(choices=Category.choices, label=_("Category")) - protocols = PlatformProtocolsSerializer( + protocols = PlatformProtocolSerializer( label=_("Protocols"), many=True, required=False ) automation = PlatformAutomationSerializer(label=_("Automation"), required=False) @@ -126,6 +125,16 @@ class PlatformSerializer(WritableNestedModelSerializer): ) return queryset + def validate_protocols(self, protocols): + if not protocols: + raise serializers.ValidationError(_("Protocols is required")) + primary = [p for p in protocols if p.get('primary')] + if not primary: + protocols[0]['primary'] = True + protocols[0]['default'] = False + self.initial_data['protocols'] = protocols + return protocols + class PlatformOpsMethodSerializer(serializers.Serializer): id = serializers.CharField(read_only=True) diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 8c45cba39..6048d9472 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -100,12 +100,19 @@ class JMSInventory: host.update(self.make_proxy_command(gateway)) def asset_to_host(self, asset, account, automation, protocols, platform): + if protocols: + protocol = protocols[0].name + port = protocol[0].port + else: + protocol = 'null' + port = 0 + host = { 'name': '{}'.format(asset.name.replace(' ', '_')), 'jms_asset': { 'id': str(asset.id), 'name': asset.name, 'address': asset.address, 'type': asset.type, 'category': asset.category, - 'protocol': asset.protocol, 'port': asset.port, + 'protocol': protocol, 'port': port, 'spec_info': asset.spec_info, 'secret_info': asset.secret_info, 'protocols': [{'name': p.name, 'port': p.port} for p in protocols], }, From ba076f66129260786d2d55fad72eae0f28604d6f Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 22 Mar 2023 14:56:20 +0800 Subject: [PATCH 2/4] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/migrations/0111_auto_20230321_1633.py | 4 ++-- apps/assets/serializers/platform.py | 1 + apps/ops/ansible/inventory.py | 14 +++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/apps/assets/migrations/0111_auto_20230321_1633.py b/apps/assets/migrations/0111_auto_20230321_1633.py index ad7d57982..0f1ba7f14 100644 --- a/apps/assets/migrations/0111_auto_20230321_1633.py +++ b/apps/assets/migrations/0111_auto_20230321_1633.py @@ -8,7 +8,7 @@ def migrate_platform_charset(apps, schema_editor): platform_model.objects.filter(charset='utf8').update(charset='utf-8') -def migrate_platform_protocol_required(apps, schema_editor): +def migrate_platform_protocol_primary(apps, schema_editor): platform_model = apps.get_model('assets', 'Platform') platforms = platform_model.objects.all() @@ -31,5 +31,5 @@ class Migration(migrations.Migration): field=models.BooleanField(default=False, verbose_name='Primary'), ), migrations.RunPython(migrate_platform_charset), - migrations.RunPython(migrate_platform_protocol_required), + migrations.RunPython(migrate_platform_protocol_primary), ] diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index c4b51934b..21c6a124a 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -132,6 +132,7 @@ class PlatformSerializer(WritableNestedModelSerializer): if not primary: protocols[0]['primary'] = True protocols[0]['default'] = False + # 这里不设置不行,write_nested 不使用 validated 中的 self.initial_data['protocols'] = protocols return protocols diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 6048d9472..e3954c063 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -100,9 +100,17 @@ class JMSInventory: host.update(self.make_proxy_command(gateway)) def asset_to_host(self, asset, account, automation, protocols, platform): - if protocols: - protocol = protocols[0].name - port = protocol[0].port + primary_protocol = [p for p in protocols if p.primary] + if len(primary_protocol) >= 1: + primary = primary_protocol[0] + elif protocols: + primary = protocols[0] + else: + primary = None + + if primary: + protocol = primary.name + port = primary.port else: protocol = 'null' port = 0 From 59d9572d07b04cbadbe43ebe5616acf0465f0427 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 22 Mar 2023 15:26:23 +0800 Subject: [PATCH 3/4] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20protocol=20?= =?UTF-8?q?=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ops/ansible/inventory.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index e3954c063..fb143cda5 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -99,7 +99,8 @@ class JMSInventory: if gateway: host.update(self.make_proxy_command(gateway)) - def asset_to_host(self, asset, account, automation, protocols, platform): + @staticmethod + def get_primary_protocol(protocols): primary_protocol = [p for p in protocols if p.primary] if len(primary_protocol) >= 1: primary = primary_protocol[0] @@ -114,6 +115,10 @@ class JMSInventory: else: protocol = 'null' port = 0 + return protocol, port + + def asset_to_host(self, asset, account, automation, protocols, platform): + protocol, port = self.get_primary_protocol(protocols) host = { 'name': '{}'.format(asset.name.replace(' ', '_')), From aca0d62febac9ea47e9a4fce45c4480ffb6e5e6f Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 22 Mar 2023 15:28:05 +0800 Subject: [PATCH 4/4] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20protocols?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers/platform.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index 21c6a124a..7485224e7 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -131,7 +131,6 @@ class PlatformSerializer(WritableNestedModelSerializer): primary = [p for p in protocols if p.get('primary')] if not primary: protocols[0]['primary'] = True - protocols[0]['default'] = False # 这里不设置不行,write_nested 不使用 validated 中的 self.initial_data['protocols'] = protocols return protocols