perf: 修改 platform 表结构

pull/8873/head
ibuler 2022-09-15 16:22:01 +08:00
parent 37bbf75f66
commit 9edd786bb4
5 changed files with 178 additions and 57 deletions

View File

@ -16,8 +16,10 @@ class PlatformMixin:
def platform_constraints(cls): def platform_constraints(cls):
return { return {
'domain_enabled': False, 'domain_enabled': False,
'gather_facts_enabled': False,
'su_enabled': False, 'su_enabled': False,
'vendor_enabled': False,
'ping_enabled': False,
'gather_facts_enabled': False,
'change_password_enabled': False, 'change_password_enabled': False,
'verify_account_enabled': False, 'verify_account_enabled': False,
'create_account_enabled': False, 'create_account_enabled': False,
@ -49,6 +51,15 @@ class Category(PlatformMixin, ChoicesMixin, models.TextChoices):
}, },
cls.NETWORKING: { cls.NETWORKING: {
'domain_enabled': True, 'domain_enabled': True,
'brand_enabled': True,
'brands': [
('huawei', 'Huawei'),
('cisco', 'Cisco'),
('juniper', 'Juniper'),
('h3c', 'H3C'),
('dell', 'Dell'),
('other', 'Other'),
],
'su_enabled': False, 'su_enabled': False,
'ping_enabled': True, 'ping_method': 'ping', 'ping_enabled': True, 'ping_method': 'ping',
'gather_facts_enabled': False, 'gather_facts_enabled': False,
@ -125,7 +136,6 @@ class NetworkingTypes(PlatformMixin, ChoicesMixin, models.TextChoices):
SWITCH = 'switch', _("Switch") SWITCH = 'switch', _("Switch")
ROUTER = 'router', _("Router") ROUTER = 'router', _("Router")
FIREWALL = 'firewall', _("Firewall") FIREWALL = 'firewall', _("Firewall")
OTHER_NETWORK = 'other', _("Other device")
class DatabaseTypes(PlatformMixin, ChoicesMixin, models.TextChoices): class DatabaseTypes(PlatformMixin, ChoicesMixin, models.TextChoices):

View File

@ -0,0 +1,90 @@
# Generated by Django 3.2.14 on 2022-09-15 02:32
from django.db import migrations, models
import django
class Migration(migrations.Migration):
dependencies = [
('assets', '0107_alter_accountbackupplan_types'),
]
operations = [
migrations.AddField(
model_name='platform',
name='brand',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Brand'),
),
migrations.CreateModel(
name='PlatformAutomation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ping_enabled', models.BooleanField(default=False, verbose_name='Ping enabled')),
('ping_method', models.CharField(blank=True, max_length=32, null=True, verbose_name='Ping method')),
('gather_facts_enabled', models.BooleanField(default=False, verbose_name='Gather facts enabled')),
('gather_facts_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Gather facts method')),
('create_account_enabled', models.BooleanField(default=False, verbose_name='Create account enabled')),
('create_account_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Create account method')),
('change_password_enabled', models.BooleanField(default=False, verbose_name='Change password enabled')),
('change_password_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Change password method')),
('verify_account_enabled', models.BooleanField(default=False, verbose_name='Verify account enabled')),
('verify_account_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Verify account method')),
('gather_accounts_enabled', models.BooleanField(default=False, verbose_name='Gather facts enabled')),
('gather_accounts_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Gather facts method')),
],
),
migrations.RemoveField(
model_name='platform',
name='change_password_enabled',
),
migrations.RemoveField(
model_name='platform',
name='change_password_method',
),
migrations.RemoveField(
model_name='platform',
name='create_account_enabled',
),
migrations.RemoveField(
model_name='platform',
name='create_account_method',
),
migrations.RemoveField(
model_name='platform',
name='gather_accounts_enabled',
),
migrations.RemoveField(
model_name='platform',
name='gather_accounts_method',
),
migrations.RemoveField(
model_name='platform',
name='gather_facts_enabled',
),
migrations.RemoveField(
model_name='platform',
name='gather_facts_method',
),
migrations.RemoveField(
model_name='platform',
name='ping_enabled',
),
migrations.RemoveField(
model_name='platform',
name='ping_method',
),
migrations.RemoveField(
model_name='platform',
name='verify_account_enabled',
),
migrations.RemoveField(
model_name='platform',
name='verify_account_method',
),
migrations.AddField(
model_name='platform',
name='automation',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='platform', to='assets.platformautomation', verbose_name='Automation'),
),
]

View File

@ -101,7 +101,6 @@ class CommandFilterRule(OrgModelMixin):
s = self.construct_command_regex(content=self.content) s = self.construct_command_regex(content=self.content)
else: else:
s = r'{0}'.format(self.content) s = r'{0}'.format(self.content)
return s return s
@classmethod @classmethod

View File

@ -5,7 +5,7 @@ from assets.const import AllTypes
from common.db.fields import JsonDictTextField from common.db.fields import JsonDictTextField
__all__ = ['Platform', 'PlatformProtocol'] __all__ = ['Platform', 'PlatformProtocol', 'PlatformAutomation']
class PlatformProtocol(models.Model): class PlatformProtocol(models.Model):
@ -20,6 +20,21 @@ class PlatformProtocol(models.Model):
setting = models.JSONField(verbose_name=_('Setting'), default=dict) setting = models.JSONField(verbose_name=_('Setting'), default=dict)
class PlatformAutomation(models.Model):
ping_enabled = models.BooleanField(default=False, verbose_name=_("Ping enabled"))
ping_method = models.CharField(max_length=32, blank=True, null=True, verbose_name=_("Ping method"))
gather_facts_enabled = models.BooleanField(default=False, verbose_name=_("Gather facts enabled"))
gather_facts_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Gather facts method"))
create_account_enabled = models.BooleanField(default=False, verbose_name=_("Create account enabled"))
create_account_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Create account method"))
change_password_enabled = models.BooleanField(default=False, verbose_name=_("Change password enabled"))
change_password_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Change password method"))
verify_account_enabled = models.BooleanField(default=False, verbose_name=_("Verify account enabled"))
verify_account_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Verify account method"))
gather_accounts_enabled = models.BooleanField(default=False, verbose_name=_("Gather facts enabled"))
gather_accounts_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Gather facts method"))
class Platform(models.Model): class Platform(models.Model):
""" """
对资产提供 约束和默认值 对资产提供 约束和默认值
@ -37,24 +52,14 @@ class Platform(models.Model):
comment = models.TextField(blank=True, null=True, verbose_name=_("Comment")) comment = models.TextField(blank=True, null=True, verbose_name=_("Comment"))
# 资产有关的 # 资产有关的
charset = models.CharField(default='utf8', choices=CHARSET_CHOICES, max_length=8, verbose_name=_("Charset")) charset = models.CharField(default='utf8', choices=CHARSET_CHOICES, max_length=8, verbose_name=_("Charset"))
brand = models.CharField(max_length=128, blank=True, null=True, verbose_name=_("Brand")) # 厂商主要是给网络设备
domain_enabled = models.BooleanField(default=True, verbose_name=_("Domain enabled")) domain_enabled = models.BooleanField(default=True, verbose_name=_("Domain enabled"))
protocols_enabled = models.BooleanField(default=True, verbose_name=_("Protocols enabled")) protocols_enabled = models.BooleanField(default=True, verbose_name=_("Protocols enabled"))
protocols = models.ManyToManyField(PlatformProtocol, blank=True, verbose_name=_("Protocols")) protocols = models.ManyToManyField(PlatformProtocol, blank=True, verbose_name=_("Protocols"))
ping_enabled = models.BooleanField(default=False, verbose_name=_("Ping enabled"))
ping_method = models.CharField(max_length=32, blank=True, null=True, verbose_name=_("Ping method"))
gather_facts_enabled = models.BooleanField(default=False, verbose_name=_("Gather facts enabled"))
gather_facts_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Gather facts method"))
# 账号有关的 # 账号有关的
su_enabled = models.BooleanField(default=False, verbose_name=_("Su enabled")) su_enabled = models.BooleanField(default=False, verbose_name=_("Su enabled"))
su_method = models.CharField(max_length=32, blank=True, null=True, verbose_name=_("SU method")) su_method = models.CharField(max_length=32, blank=True, null=True, verbose_name=_("SU method"))
create_account_enabled = models.BooleanField(default=False, verbose_name=_("Create account enabled")) automation = models.OneToOneField(PlatformAutomation, on_delete=models.CASCADE, related_name='platform', blank=True, null=True, verbose_name=_("Automation"))
create_account_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Create account method"))
change_password_enabled = models.BooleanField(default=False, verbose_name=_("Change password enabled"))
change_password_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Change password method"))
verify_account_enabled = models.BooleanField(default=False, verbose_name=_("Verify account enabled"))
verify_account_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Verify account method"))
gather_accounts_enabled = models.BooleanField(default=False, verbose_name=_("Gather facts enabled"))
gather_accounts_method = models.TextField(max_length=32, blank=True, null=True, verbose_name=_("Gather facts method"))
@property @property
def type_constraints(self): def type_constraints(self):

View File

@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _
from common.drf.fields import LabeledChoiceField from common.drf.fields import LabeledChoiceField
from common.drf.serializers import JMSWritableNestedModelSerializer from common.drf.serializers import JMSWritableNestedModelSerializer
from ..models import Platform, PlatformProtocol from ..models import Platform, PlatformProtocol, PlatformAutomation
from ..const import Category, AllTypes from ..const import Category, AllTypes
@ -26,43 +26,18 @@ class ProtocolSettingSerializer(serializers.Serializer):
sftp_home = serializers.CharField(default='/tmp', label=_("SFTP home")) sftp_home = serializers.CharField(default='/tmp', label=_("SFTP home"))
class PlatformProtocolsSerializer(serializers.ModelSerializer): class PlatformAutomationSerializer(serializers.ModelSerializer):
setting = ProtocolSettingSerializer(required=False, allow_null=True)
class Meta: class Meta:
model = PlatformProtocol model = PlatformAutomation
fields = ['id', 'name', 'port', 'setting'] fields = [
'id', 'ping_enabled', 'ping_method',
class PlatformSerializer(JMSWritableNestedModelSerializer):
type = LabeledChoiceField(choices=AllTypes.choices, label=_("Type"))
category = LabeledChoiceField(choices=Category.choices, label=_("Category"))
protocols = PlatformProtocolsSerializer(label=_('Protocols'), many=True, required=False)
su_method = LabeledChoiceField(
choices=[('sudo', 'sudo su -'), ('su', 'su - ')],
label='切换方式', required=False, default='sudo'
)
class Meta:
model = Platform
fields_mini = ['id', 'name', 'internal']
fields_small = fields_mini + [
'category', 'type', 'charset',
]
fields = fields_small + [
'protocols_enabled', 'protocols', 'domain_enabled',
'gather_facts_enabled', 'gather_facts_method', 'gather_facts_enabled', 'gather_facts_method',
'su_enabled', 'su_method',
'gather_accounts_enabled', 'gather_accounts_method',
'create_account_enabled', 'create_account_method', 'create_account_enabled', 'create_account_method',
'verify_account_enabled', 'verify_account_method',
'change_password_enabled', 'change_password_method', 'change_password_enabled', 'change_password_method',
'comment', 'verify_account_enabled', 'verify_account_method',
'gather_accounts_enabled', 'gather_accounts_method',
] ]
extra_kwargs = { extra_kwargs = {
'su_enabled': {'label': '启用切换账号'},
'domain_enabled': {'label': "启用网域"},
'domain_default': {'label': "默认网域"},
'gather_facts_enabled': {'label': '启用收集信息'}, 'gather_facts_enabled': {'label': '启用收集信息'},
'gather_facts_method': {'label': '收集信息方式'}, 'gather_facts_method': {'label': '收集信息方式'},
'verify_account_enabled': {'label': '启用校验账号'}, 'verify_account_enabled': {'label': '启用校验账号'},
@ -75,16 +50,58 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
'gather_accounts_method': {'label': '收集账号方式'}, 'gather_accounts_method': {'label': '收集账号方式'},
} }
def validate(self, attrs):
fields_to_check = [ class PlatformProtocolsSerializer(serializers.ModelSerializer):
('verify_account_enabled', 'verify_account_method'), setting = ProtocolSettingSerializer(required=False, allow_null=True)
('create_account_enabled', 'create_account_method'),
('change_password_enabled', 'change_password_method'), class Meta:
model = PlatformProtocol
fields = ['id', 'name', 'port', 'setting']
class PlatformSerializer(JMSWritableNestedModelSerializer):
type = LabeledChoiceField(choices=AllTypes.choices, label=_("Type"))
category = LabeledChoiceField(choices=Category.choices, label=_("Category"))
protocols = PlatformProtocolsSerializer(label=_('Protocols'), many=True, required=False)
automation = PlatformAutomationSerializer(label=_('Automation'), required=False)
su_method = LabeledChoiceField(
choices=[('sudo', 'sudo su -'), ('su', 'su - ')],
label='切换方式', required=False, default='sudo'
)
brand = LabeledChoiceField(choices=[], label='厂商', required=False, allow_null=True)
class Meta:
model = Platform
fields_mini = ['id', 'name', 'internal']
fields_small = fields_mini + [
'category', 'type', 'charset',
] ]
for method_enabled, method_name in fields_to_check: fields = fields_small + [
if attrs.get(method_enabled, False) and not attrs.get(method_name, False): 'protocols_enabled', 'protocols', 'domain_enabled',
raise serializers.ValidationError({method_name: _('This field is required.')}) 'su_enabled', 'su_method', 'brand', 'automation', 'comment',
return attrs ]
extra_kwargs = {
'su_enabled': {'label': '启用切换账号'},
'domain_enabled': {'label': "启用网域"},
'domain_default': {'label': "默认网域"},
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_brand_choices()
def set_brand_choices(self):
field = self.fields.get('brand')
request = self.context.get('request')
if not field or not request:
return
category = request.query_params.get('category', '')
constraints = Category.platform_constraints().get(category)
if not constraints:
return
field.choices = constraints.get('brands', [])
if field.choices:
field.required = True
class PlatformOpsMethodSerializer(serializers.Serializer): class PlatformOpsMethodSerializer(serializers.Serializer):