mirror of https://github.com/jumpserver/jumpserver
perf: stash it
parent
762d84b5c3
commit
5d48d1ab15
|
@ -1,30 +1,51 @@
|
||||||
|
from django.db.models import TextChoices
|
||||||
|
|
||||||
|
from .protocol import Protocol
|
||||||
|
|
||||||
|
|
||||||
class ConstrainMixin:
|
class BaseType(TextChoices):
|
||||||
def get_constrains(self):
|
"""
|
||||||
pass
|
约束应该考虑代是对平台对限制,避免多余对选项,如: mysql 开启 ssh, 或者开启了也没有作用, 比如 k8s 开启了 domain,目前还不支持
|
||||||
|
"""
|
||||||
|
@classmethod
|
||||||
|
def get_constrains(cls):
|
||||||
|
constrains = {}
|
||||||
|
|
||||||
def _get_category_constrains(self) -> dict:
|
base = cls._get_base_constrains()
|
||||||
raise NotImplementedError
|
protocols = cls._get_protocol_constrains()
|
||||||
|
automation = cls._get_automation_constrains()
|
||||||
|
|
||||||
def _get_protocol_constrains(self) -> dict:
|
base_default = base.pop('*', {})
|
||||||
raise NotImplementedError
|
protocols_default = protocols.pop('*', {})
|
||||||
|
automation_default = automation.pop('*', {})
|
||||||
|
|
||||||
def _get_automation_constrains(self) -> dict:
|
for k, v in cls.choices:
|
||||||
|
tp_base = {**base_default, **base.get(k, {})}
|
||||||
|
tp_auto = {**automation_default, **automation.get(k, {})}
|
||||||
|
tp_protocols = {**protocols_default, **protocols.get(k, {})}
|
||||||
|
tp_protocols = cls._parse_protocols(tp_protocols, k)
|
||||||
|
tp_constrains = {**tp_base, 'protocols': tp_protocols, 'automation': tp_auto}
|
||||||
|
constrains[k] = tp_constrains
|
||||||
|
return constrains
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _parse_protocols(cls, protocol, tp):
|
||||||
|
default_ports = Protocol.default_ports()
|
||||||
|
choices = protocol.get('choices', [])
|
||||||
|
if choices == '__self__':
|
||||||
|
choices = [tp]
|
||||||
|
protocols = [{'name': name, 'port': default_ports.get(name, 0)} for name in choices]
|
||||||
|
return protocols
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_base_constrains(cls) -> dict:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def platform_constraints(cls):
|
def _get_protocol_constrains(cls) -> dict:
|
||||||
return {
|
raise NotImplementedError
|
||||||
'domain_enabled': False,
|
|
||||||
'su_enabled': False,
|
@classmethod
|
||||||
'brand_enabled': False,
|
def _get_automation_constrains(cls) -> dict:
|
||||||
'ping_enabled': False,
|
raise NotImplementedError
|
||||||
'gather_facts_enabled': False,
|
|
||||||
'change_password_enabled': False,
|
|
||||||
'verify_account_enabled': False,
|
|
||||||
'create_account_enabled': False,
|
|
||||||
'gather_accounts_enabled': False,
|
|
||||||
'_protocols': []
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from common.db.models import IncludesTextChoicesMeta, ChoicesMixin
|
from common.db.models import ChoicesMixin
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['Category']
|
||||||
__all__ = [
|
|
||||||
'Category', 'ConstrainMixin'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
class Category(ChoicesMixin, models.TextChoices):
|
||||||
class Category(ConstrainMixin, ChoicesMixin, models.TextChoices):
|
|
||||||
HOST = 'host', _('Host')
|
HOST = 'host', _('Host')
|
||||||
DEVICE = 'device', _("Device")
|
DEVICE = 'device', _("Device")
|
||||||
DATABASE = 'database', _("Database")
|
DATABASE = 'database', _("Database")
|
||||||
|
|
|
@ -1,31 +1,40 @@
|
||||||
from django.db import models
|
from .base import BaseType
|
||||||
|
|
||||||
from common.db.models import ChoicesMixin
|
|
||||||
|
|
||||||
|
|
||||||
from .category import ConstrainMixin
|
class CloudTypes(BaseType):
|
||||||
|
PUBLIC = 'public', 'Public cloud'
|
||||||
|
PRIVATE = 'private', 'Private cloud'
|
||||||
class CloudTypes(ConstrainMixin, ChoicesMixin, models.TextChoices):
|
|
||||||
K8S = 'k8s', 'Kubernetes'
|
K8S = 'k8s', 'Kubernetes'
|
||||||
|
|
||||||
def category_constrains(self):
|
@classmethod
|
||||||
|
def _get_base_constrains(cls) -> dict:
|
||||||
return {
|
return {
|
||||||
'domain_enabled': False,
|
'*': {
|
||||||
'su_enabled': False,
|
'domain_enabled': False,
|
||||||
'ping_enabled': False,
|
'su_enabled': False,
|
||||||
'gather_facts_enabled': False,
|
}
|
||||||
'verify_account_enabled': False,
|
|
||||||
'change_password_enabled': False,
|
|
||||||
'create_account_enabled': False,
|
|
||||||
'gather_accounts_enabled': False,
|
|
||||||
'_protocols': []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def platform_constraints(cls):
|
def _get_automation_constrains(cls) -> dict:
|
||||||
return {
|
constrains = {
|
||||||
cls.K8S: {
|
'*': {
|
||||||
'_protocols': ['k8s']
|
'gather_facts_enabled': False,
|
||||||
|
'verify_account_enabled': False,
|
||||||
|
'change_password_enabled': False,
|
||||||
|
'create_account_enabled': False,
|
||||||
|
'gather_accounts_enabled': False,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return constrains
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_protocol_constrains(cls) -> dict:
|
||||||
|
return {
|
||||||
|
'*': {
|
||||||
|
'choices': ['http', 'api'],
|
||||||
|
},
|
||||||
|
cls.K8S: {
|
||||||
|
'choices': ['k8s']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
|
from .base import BaseType
|
||||||
|
|
||||||
|
|
||||||
class DatabaseTypes(ConstrainMixin, ChoicesMixin, models.TextChoices):
|
class DatabaseTypes(BaseType):
|
||||||
MYSQL = 'mysql', 'MySQL'
|
MYSQL = 'mysql', 'MySQL'
|
||||||
MARIADB = 'mariadb', 'MariaDB'
|
MARIADB = 'mariadb', 'MariaDB'
|
||||||
POSTGRESQL = 'postgresql', 'PostgreSQL'
|
POSTGRESQL = 'postgresql', 'PostgreSQL'
|
||||||
|
@ -9,28 +11,33 @@ class DatabaseTypes(ConstrainMixin, ChoicesMixin, models.TextChoices):
|
||||||
MONGODB = 'mongodb', 'MongoDB'
|
MONGODB = 'mongodb', 'MongoDB'
|
||||||
REDIS = 'redis', 'Redis'
|
REDIS = 'redis', 'Redis'
|
||||||
|
|
||||||
def category_constrains(self):
|
@classmethod
|
||||||
|
def _get_base_constrains(cls) -> dict:
|
||||||
return {
|
return {
|
||||||
'domain_enabled': True,
|
'*': {
|
||||||
'su_enabled': False,
|
'domain_enabled': True,
|
||||||
'gather_facts_enabled': True,
|
'su_enabled': False,
|
||||||
'verify_account_enabled': True,
|
}
|
||||||
'change_password_enabled': True,
|
|
||||||
'create_account_enabled': True,
|
|
||||||
'gather_accounts_enabled': True,
|
|
||||||
'_protocols': []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def platform_constraints(cls):
|
def _get_automation_constrains(cls) -> dict:
|
||||||
meta = {}
|
constrains = {
|
||||||
for name, label in cls.choices:
|
'*': {
|
||||||
meta[name] = {
|
'gather_facts_enabled': True,
|
||||||
'_protocols': [name],
|
'gather_accounts_enabled': True,
|
||||||
'gather_facts_method': f'gather_facts_{name}',
|
'verify_account_enabled': True,
|
||||||
'verify_account_method': f'verify_account_{name}',
|
'change_password_enabled': True,
|
||||||
'change_password_method': f'change_password_{name}',
|
'create_account_enabled': True,
|
||||||
'create_account_method': f'create_account_{name}',
|
|
||||||
'gather_accounts_method': f'gather_accounts_{name}',
|
|
||||||
}
|
}
|
||||||
return meta
|
}
|
||||||
|
return constrains
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_protocol_constrains(cls) -> dict:
|
||||||
|
return {
|
||||||
|
'*': {
|
||||||
|
'choices': '__self__',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,40 @@
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from .base import BaseType
|
||||||
|
|
||||||
|
|
||||||
class DeviceTypes(ConstrainMixin, ChoicesMixin, models.TextChoices):
|
class DeviceTypes(BaseType):
|
||||||
GENERAL = 'general', _("General device")
|
GENERAL = 'general', _("General device")
|
||||||
SWITCH = 'switch', _("Switch")
|
SWITCH = 'switch', _("Switch")
|
||||||
ROUTER = 'router', _("Router")
|
ROUTER = 'router', _("Router")
|
||||||
FIREWALL = 'firewall', _("Firewall")
|
FIREWALL = 'firewall', _("Firewall")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def category_constrains(cls):
|
def _get_base_constrains(cls) -> dict:
|
||||||
return {
|
return {
|
||||||
'domain_enabled': True,
|
'*': {
|
||||||
'brand_enabled': True,
|
'domain_enabled': True,
|
||||||
'brands': [
|
'su_enabled': False,
|
||||||
('huawei', 'Huawei'),
|
}
|
||||||
('cisco', 'Cisco'),
|
}
|
||||||
('juniper', 'Juniper'),
|
|
||||||
('h3c', 'H3C'),
|
@classmethod
|
||||||
('dell', 'Dell'),
|
def _get_protocol_constrains(cls) -> dict:
|
||||||
('other', 'Other'),
|
return {
|
||||||
],
|
'*': {
|
||||||
'su_enabled': False,
|
'choices': ['ssh', 'telnet']
|
||||||
'ping_enabled': True, 'ping_method': 'ping',
|
}
|
||||||
'gather_facts_enabled': False,
|
}
|
||||||
'verify_account_enabled': False,
|
|
||||||
'change_password_enabled': False,
|
@classmethod
|
||||||
'create_account_enabled': False,
|
def _get_automation_constrains(cls) -> dict:
|
||||||
'gather_accounts_enabled': False,
|
return {
|
||||||
'_protocols': ['ssh', 'telnet']
|
'*': {
|
||||||
|
'ping_enabled': True,
|
||||||
|
'gather_facts_enabled': False,
|
||||||
|
'gather_accounts_enabled': False,
|
||||||
|
'verify_account_enabled': False,
|
||||||
|
'change_password_enabled': False,
|
||||||
|
'create_account_enabled': False,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,44 @@
|
||||||
|
from .base import BaseType
|
||||||
|
|
||||||
class HostTypes(ConstrainMixin, ChoicesMixin, models.TextChoices):
|
|
||||||
|
class HostTypes(BaseType):
|
||||||
LINUX = 'linux', 'Linux'
|
LINUX = 'linux', 'Linux'
|
||||||
WINDOWS = 'windows', 'Windows'
|
WINDOWS = 'windows', 'Windows'
|
||||||
UNIX = 'unix', 'Unix'
|
UNIX = 'unix', 'Unix'
|
||||||
OTHER_HOST = 'other', _("Other")
|
OTHER_HOST = 'other', "Other"
|
||||||
|
|
||||||
@staticmethod
|
@classmethod
|
||||||
def category_constrains():
|
def _get_base_constrains(cls) -> dict:
|
||||||
return {
|
return {
|
||||||
'domain_enabled': True,
|
'*': {
|
||||||
'su_enabled': True, 'su_method': 'sudo',
|
'domain_enabled': True,
|
||||||
'ping_enabled': True, 'ping_method': 'ping',
|
'su_enabled': True,
|
||||||
'gather_facts_enabled': True, 'gather_facts_method': 'gather_facts_posix',
|
},
|
||||||
'verify_account_enabled': True, 'verify_account_method': 'verify_account_posix',
|
cls.WINDOWS: {
|
||||||
'change_password_enabled': True, 'change_password_method': 'change_password_posix',
|
'su_enabled': False,
|
||||||
'create_account_enabled': True, 'create_account_method': 'create_account_posix',
|
},
|
||||||
'gather_accounts_enabled': True, 'gather_accounts_method': 'gather_accounts_posix',
|
cls.OTHER_HOST: {
|
||||||
'_protocols': ['ssh', 'telnet'],
|
'su_enabled': False,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def platform_constraints(cls):
|
def _get_protocol_constrains(cls) -> dict:
|
||||||
return {
|
return {
|
||||||
cls.LINUX: {
|
'*': {
|
||||||
'_protocols': ['ssh', 'rdp', 'vnc', 'telnet']
|
'choices': ['ssh', 'telnet', 'vnc', 'rdp']
|
||||||
},
|
|
||||||
cls.WINDOWS: {
|
|
||||||
'gather_facts_method': 'gather_facts_windows',
|
|
||||||
'verify_account_method': 'verify_account_windows',
|
|
||||||
'change_password_method': 'change_password_windows',
|
|
||||||
'create_account_method': 'create_account_windows',
|
|
||||||
'gather_accounts_method': 'gather_accounts_windows',
|
|
||||||
'_protocols': ['rdp', 'ssh', 'vnc'],
|
|
||||||
'su_enabled': False
|
|
||||||
},
|
|
||||||
cls.UNIX: {
|
|
||||||
'_protocols': ['ssh', 'vnc']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_automation_constrains(cls) -> dict:
|
||||||
|
return {
|
||||||
|
'*': {
|
||||||
|
'ping_enabled': True,
|
||||||
|
'gather_facts_enabled': True,
|
||||||
|
'gather_accounts_enabled': True,
|
||||||
|
'verify_account_enabled': True,
|
||||||
|
'change_password_enabled': True,
|
||||||
|
'create_account_enabled': True,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
from common.db.models import IncludesTextChoicesMeta, ChoicesMixin
|
from common.db.models import IncludesTextChoicesMeta, ChoicesMixin
|
||||||
from common.tree import TreeNode
|
from common.tree import TreeNode
|
||||||
|
|
||||||
|
from .base import BaseType
|
||||||
from .category import Category
|
from .category import Category
|
||||||
from .host import HostTypes
|
from .host import HostTypes
|
||||||
from .device import DeviceTypes
|
from .device import DeviceTypes
|
||||||
from .database import DatabaseTypes
|
from .database import DatabaseTypes
|
||||||
from .web import WebTypes
|
from .web import WebTypes
|
||||||
from .cloud import CloudTypes
|
from .cloud import CloudTypes
|
||||||
|
from .protocol import Protocol
|
||||||
|
|
||||||
|
|
||||||
class AllTypes(ChoicesMixin, metaclass=IncludesTextChoicesMeta):
|
class AllTypes(ChoicesMixin, metaclass=IncludesTextChoicesMeta):
|
||||||
|
@ -18,24 +20,11 @@ class AllTypes(ChoicesMixin, metaclass=IncludesTextChoicesMeta):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_constraints(cls, category, tp):
|
def get_constraints(cls, category, tp):
|
||||||
constraints = ConstrainMixin.platform_constraints()
|
|
||||||
category_constraints = Category.platform_constraints().get(category) or {}
|
|
||||||
constraints.update(category_constraints)
|
|
||||||
|
|
||||||
types_cls = dict(cls.category_types()).get(category)
|
types_cls = dict(cls.category_types()).get(category)
|
||||||
if not types_cls:
|
if not types_cls:
|
||||||
return constraints
|
return {}
|
||||||
type_constraints = types_cls.platform_constraints().get(tp) or {}
|
type_constraints = types_cls.get_constrains()
|
||||||
constraints.update(type_constraints)
|
return type_constraints.get(tp, {})
|
||||||
|
|
||||||
_protocols = constraints.pop('_protocols', [])
|
|
||||||
default_ports = Protocol.default_ports()
|
|
||||||
protocols = []
|
|
||||||
for p in _protocols:
|
|
||||||
port = default_ports.get(p, 0)
|
|
||||||
protocols.append({'name': p, 'port': port})
|
|
||||||
constraints['protocols'] = protocols
|
|
||||||
return constraints
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def category_types(cls):
|
def category_types(cls):
|
||||||
|
|
|
@ -1,16 +1,37 @@
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
class WebTypes(ConstrainMixin, ChoicesMixin, models.TextChoices):
|
from .base import BaseType
|
||||||
|
|
||||||
|
|
||||||
|
class WebTypes(BaseType):
|
||||||
WEBSITE = 'website', _('General website')
|
WEBSITE = 'website', _('General website')
|
||||||
|
|
||||||
def category_constrains(self):
|
@classmethod
|
||||||
|
def _get_base_constrains(cls) -> dict:
|
||||||
return {
|
return {
|
||||||
'domain_enabled': False,
|
'*': {
|
||||||
'su_enabled': False,
|
'domain_enabled': False,
|
||||||
'ping_enabled': False,
|
'su_enabled': False,
|
||||||
'gather_facts_enabled': False,
|
}
|
||||||
'verify_account_enabled': False,
|
}
|
||||||
'change_password_enabled': False,
|
|
||||||
'create_account_enabled': False,
|
@classmethod
|
||||||
'gather_accounts_enabled': False,
|
def _get_automation_constrains(cls) -> dict:
|
||||||
'_protocols': ['http', 'https']
|
constrains = {
|
||||||
}
|
'*': {
|
||||||
|
'gather_facts_enabled': False,
|
||||||
|
'verify_account_enabled': False,
|
||||||
|
'change_password_enabled': False,
|
||||||
|
'create_account_enabled': False,
|
||||||
|
'gather_accounts_enabled': False,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return constrains
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_protocol_constrains(cls) -> dict:
|
||||||
|
return {
|
||||||
|
'*': {
|
||||||
|
'choices': ['http', 'api'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,14 +10,6 @@ class Migration(migrations.Migration):
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
|
||||||
name='Protocol',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(max_length=32, verbose_name='Name')),
|
|
||||||
('port', models.IntegerField(verbose_name='Port')),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(
|
||||||
model_name='asset',
|
model_name='asset',
|
||||||
name='port',
|
name='port',
|
||||||
|
@ -26,24 +18,24 @@ class Migration(migrations.Migration):
|
||||||
model_name='asset',
|
model_name='asset',
|
||||||
name='protocol',
|
name='protocol',
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.RenameField(
|
||||||
model_name='asset',
|
model_name='asset',
|
||||||
name='_protocols',
|
old_name='protocols',
|
||||||
field=models.CharField(blank=True, default='ssh/22', max_length=128, verbose_name='Protocols'),
|
new_name='_protocols',
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='asset',
|
|
||||||
name='protocols',
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='systemuser',
|
model_name='systemuser',
|
||||||
name='protocol',
|
name='protocol',
|
||||||
field=models.CharField(default='ssh', max_length=16, verbose_name='Protocol'),
|
field=models.CharField(default='ssh', max_length=16, verbose_name='Protocol'),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.CreateModel(
|
||||||
model_name='asset',
|
name='Protocol',
|
||||||
name='protocols',
|
fields=[
|
||||||
field=models.ManyToManyField(blank=True, to='assets.Protocol', verbose_name='Protocols'),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=32, verbose_name='Name')),
|
||||||
|
('port', models.IntegerField(verbose_name='Port')),
|
||||||
|
('asset', models.ForeignKey(on_delete=models.deletion.CASCADE, related_name='protocols', to='assets.asset', verbose_name='Asset')),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
migrations.DeleteModel(
|
migrations.DeleteModel(
|
||||||
name='Cluster',
|
name='Cluster',
|
||||||
|
|
|
@ -31,7 +31,7 @@ def migrate_asset_protocols(apps, schema_editor):
|
||||||
protocol = protocol_map.get(name_port)
|
protocol = protocol_map.get(name_port)
|
||||||
if not protocol:
|
if not protocol:
|
||||||
protocol = protocol_model.objects.get_or_create(
|
protocol = protocol_model.objects.get_or_create(
|
||||||
defaults={'name': name, 'port': port},
|
defaults={'name': name, 'port': port, 'asset': asset},
|
||||||
name=name, port=port
|
name=name, port=port
|
||||||
)[0]
|
)[0]
|
||||||
assets_protocols.append(asset_protocol_through(asset_id=asset.id, protocol_id=protocol.id))
|
assets_protocols.append(asset_protocol_through(asset_id=asset.id, protocol_id=protocol.id))
|
||||||
|
|
|
@ -13,6 +13,5 @@ from .backup import *
|
||||||
from ._user import *
|
from ._user import *
|
||||||
# 废弃以下
|
# 废弃以下
|
||||||
# from ._authbook import *
|
# from ._authbook import *
|
||||||
from .protocol import *
|
|
||||||
from .cmd_filter import *
|
from .cmd_filter import *
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ from orgs.mixins.models import OrgManager, JMSOrgBaseModel
|
||||||
from ..platform import Platform
|
from ..platform import Platform
|
||||||
from ..base import AbsConnectivity
|
from ..base import AbsConnectivity
|
||||||
|
|
||||||
__all__ = ['Asset', 'AssetQuerySet', 'default_node']
|
__all__ = ['Asset', 'AssetQuerySet', 'default_node', 'Protocol']
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,11 +72,16 @@ class NodesRelationMixin:
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
|
||||||
|
class Protocol(models.Model):
|
||||||
|
name = models.CharField(max_length=32, verbose_name=_("Name"))
|
||||||
|
port = models.IntegerField(verbose_name=_("Port"))
|
||||||
|
asset = models.ForeignKey('Asset', on_delete=models.CASCADE, related_name='protocols', verbose_name=_("Asset"))
|
||||||
|
|
||||||
|
|
||||||
class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
|
class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
|
||||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||||
name = models.CharField(max_length=128, verbose_name=_('Name'))
|
name = models.CharField(max_length=128, verbose_name=_('Name'))
|
||||||
ip = models.CharField(max_length=128, verbose_name=_('IP'), db_index=True)
|
ip = models.CharField(max_length=128, verbose_name=_('IP'), db_index=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')
|
||||||
domain = models.ForeignKey("assets.Domain", null=True, blank=True, related_name='assets',
|
domain = models.ForeignKey("assets.Domain", null=True, blank=True, related_name='assets',
|
||||||
|
|
|
@ -58,6 +58,8 @@ class BaseAccount(OrgModelMixin):
|
||||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||||
name = models.CharField(max_length=128, verbose_name=_("Name"))
|
name = models.CharField(max_length=128, verbose_name=_("Name"))
|
||||||
username = models.CharField(max_length=128, blank=True, verbose_name=_('Username'), db_index=True)
|
username = models.CharField(max_length=128, blank=True, verbose_name=_('Username'), db_index=True)
|
||||||
|
secret_type = models.CharField(max_length=16, default='password', verbose_name=_('Secret type'))
|
||||||
|
secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret'))
|
||||||
password = fields.EncryptCharField(max_length=256, blank=True, null=True, verbose_name=_('Password'))
|
password = fields.EncryptCharField(max_length=256, blank=True, null=True, verbose_name=_('Password'))
|
||||||
private_key = fields.EncryptTextField(blank=True, null=True, verbose_name=_('SSH private key'))
|
private_key = fields.EncryptTextField(blank=True, null=True, verbose_name=_('SSH private key'))
|
||||||
public_key = fields.EncryptTextField(blank=True, null=True, verbose_name=_('SSH public key'))
|
public_key = fields.EncryptTextField(blank=True, null=True, verbose_name=_('SSH public key'))
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
from django.db import models
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
|
|
||||||
|
|
||||||
class Protocol(models.Model):
|
|
||||||
name = models.CharField(max_length=32, verbose_name=_("Name"))
|
|
||||||
port = models.IntegerField(verbose_name=_("Port"))
|
|
|
@ -8,7 +8,7 @@ from django.db.models import F
|
||||||
from common.drf.serializers import JMSWritableNestedModelSerializer
|
from common.drf.serializers import JMSWritableNestedModelSerializer
|
||||||
from common.drf.fields import LabeledChoiceField, ObjectRelatedField
|
from common.drf.fields import LabeledChoiceField, ObjectRelatedField
|
||||||
from ..account import AccountSerializer
|
from ..account import AccountSerializer
|
||||||
from ...models import Asset, Node, Platform, Protocol, Label, Domain, Account
|
from ...models import Asset, Node, Platform, Label, Domain, Account, Protocol
|
||||||
from ...const import Category, AllTypes
|
from ...const import Category, AllTypes
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|
|
@ -89,23 +89,6 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
||||||
'domain_default': {'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):
|
||||||
id = serializers.CharField(read_only=True)
|
id = serializers.CharField(read_only=True)
|
||||||
|
|
Loading…
Reference in New Issue