perf: 修改 migrations, 修改 Connect token

pull/9155/head^2
ibuler 2022-12-05 12:42:15 +08:00
parent d25d580ba4
commit 38b1701b33
12 changed files with 117 additions and 97 deletions

View File

@ -1,6 +1,7 @@
# Generated by Django 3.2.13 on 2022-09-29 11:03
from django.db import migrations
from assets.const.host import GATEWAY_NAME
@ -70,4 +71,18 @@ class Migration(migrations.Migration):
operations = [
migrations.RunPython(migrate_gateway_to_asset),
migrations.DeleteModel(
name='Gateway',
),
migrations.CreateModel(
name='Gateway',
fields=[
],
options={
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('assets.host',),
),
]

View File

@ -1,10 +1,9 @@
# Generated by Django 3.2.14 on 2022-11-28 10:39
from django.db import migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0112_gateway_to_asset'),
]
@ -12,6 +11,33 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterModelOptions(
name='accounttemplate',
options={'permissions': [('view_accounttemplatesecret', 'Can view asset account template secret'), ('change_accounttemplatesecret', 'Can change asset account template secret')], 'verbose_name': 'Account template'},
options={'permissions': [('view_accounttemplatesecret', 'Can view asset account template secret'),
('change_accounttemplatesecret', 'Can change asset account template secret')],
'verbose_name': 'Account template'},
),
migrations.AddField(
model_name='database',
name='allow_invalid_cert',
field=models.BooleanField(default=False, verbose_name='Allow invalid cert'),
),
migrations.AddField(
model_name='database',
name='ca_cert',
field=models.TextField(blank=True, verbose_name='CA cert'),
),
migrations.AddField(
model_name='database',
name='client_cert',
field=models.TextField(blank=True, verbose_name='Client cert'),
),
migrations.AddField(
model_name='database',
name='client_key',
field=models.TextField(blank=True, verbose_name='Client key'),
),
migrations.AddField(
model_name='database',
name='use_ssl',
field=models.BooleanField(default=False, verbose_name='Use SSL'),
),
]

View File

@ -1,14 +1,37 @@
# Generated by Django 3.2.14 on 2022-11-29 05:14
from django.db import migrations, models
import django.db.models.deletion
# TODO 最后去掉这个迁移
class Migration(migrations.Migration):
dependencies = [
('assets', '0113_alter_accounttemplate_options'),
]
operations = [
migrations.AddField(
model_name='database',
name='allow_invalid_cert',
field=models.BooleanField(default=False, verbose_name='Allow invalid cert'),
),
migrations.AddField(
model_name='database',
name='ca_cert',
field=models.TextField(blank=True, verbose_name='CA cert'),
),
migrations.AddField(
model_name='database',
name='client_cert',
field=models.TextField(blank=True, verbose_name='Client cert'),
),
migrations.AddField(
model_name='database',
name='client_key',
field=models.TextField(blank=True, verbose_name='Client key'),
),
migrations.AddField(
model_name='database',
name='use_ssl',
field=models.BooleanField(default=False, verbose_name='Use SSL'),
),
]

View File

@ -1,38 +0,0 @@
# Generated by Django 3.2.14 on 2022-11-30 03:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0114_node_domain'),
]
operations = [
migrations.AddField(
model_name='database',
name='allow_invalid_cert',
field=models.BooleanField(default=False, verbose_name='Allow invalid cert'),
),
migrations.AddField(
model_name='database',
name='ca_cert',
field=models.TextField(blank=True, verbose_name='CA cert'),
),
migrations.AddField(
model_name='database',
name='client_cert',
field=models.TextField(blank=True, verbose_name='Client cert'),
),
migrations.AddField(
model_name='database',
name='client_key',
field=models.TextField(blank=True, verbose_name='Client key'),
),
migrations.AddField(
model_name='database',
name='use_ssl',
field=models.BooleanField(default=False, verbose_name='Use SSL'),
),
]

View File

@ -1,16 +0,0 @@
# Generated by Django 3.2.14 on 2022-12-01 07:08
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assets', '0115_auto_20221130_1118'),
]
operations = [
migrations.DeleteModel(
name='Gateway',
),
]

View File

@ -1,24 +0,0 @@
# Generated by Django 3.2.14 on 2022-12-01 07:21
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assets', '0116_delete_gateway'),
]
operations = [
migrations.CreateModel(
name='Gateway',
fields=[
],
options={
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('assets.host',),
),
]

View File

@ -278,7 +278,7 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView
data = serializer.validated_data
user = self.get_user(serializer)
asset = data.get('asset')
account_name = data.get('account_name')
account_name = data.get('account')
data['org_id'] = asset.org_id
data['user'] = user
data['value'] = random_string(16)

View File

@ -0,0 +1,17 @@
# Generated by Django 3.2.14 on 2022-12-05 03:36
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('authentication', '0014_auto_20221122_2152'),
]
operations = [
migrations.RenameField(
model_name='connectiontoken',
old_name='account_name',
new_name='account',
),
]

View File

@ -28,7 +28,7 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
'assets.Asset', on_delete=models.SET_NULL, null=True, blank=True,
related_name='connection_tokens', verbose_name=_('Asset'),
)
account_name = models.CharField(max_length=128, verbose_name=_("Account name")) # 登录账号Name
account = models.CharField(max_length=128, verbose_name=_("Account name")) # 登录账号Name
input_username = models.CharField(max_length=128, default='', blank=True, verbose_name=_("Input username"))
input_secret = EncryptCharField(max_length=64, default='', blank=True, verbose_name=_("Input secret"))
protocol = models.CharField(max_length=16, default=Protocol.ssh, verbose_name=_("Protocol"))
@ -74,7 +74,7 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
def permed_account(self):
from perms.utils import PermAccountUtil
permed_account = PermAccountUtil().validate_permission(
self.user, self.asset, self.account_name
self.user, self.asset, self.account
)
return permed_account
@ -86,6 +86,12 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
def expire_at(self):
return self.permed_account.date_expired.timestamp()
@lazyproperty
def connect_method_object(self):
from terminal.const import TerminalType
method = TerminalType.get_connect_method(self.connect_method, protocol=self.protocol)
return method
def is_valid(self):
if self.is_expired:
error = _('Connection token expired at: {}').format(as_current_tz(self.date_expired))
@ -97,13 +103,13 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
is_valid = False
error = _('No asset or inactive asset')
return is_valid, error
if not self.account_name:
if not self.account:
error = _('No account')
raise PermissionDenied(error)
if not self.permed_account or not self.permed_account.actions:
msg = 'user `{}` not has asset `{}` permission for login `{}`'.format(
self.user, self.asset, self.account_name
self.user, self.asset, self.account
)
raise PermissionDenied(msg)
@ -116,15 +122,15 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
return self.asset.platform
@lazyproperty
def account(self):
def account_object(self):
from assets.models import Account
if not self.asset:
return None
account = self.asset.accounts.filter(name=self.account_name).first()
if self.account_name == '@INPUT' or not account:
account = self.asset.accounts.filter(name=self.account).first()
if self.account == '@INPUT' or not account:
data = {
'name': self.account_name,
'name': self.account,
'username': self.input_username,
'secret_type': 'password',
'secret': self.input_secret,

View File

@ -84,14 +84,14 @@ class _ConnectionTokenPlatformSerializer(PlatformSerializer):
class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin):
user = _ConnectionTokenUserSerializer(read_only=True)
asset = _ConnectionTokenAssetSerializer(read_only=True)
account = _ConnectionTokenAccountSerializer(read_only=True)
account = _ConnectionTokenAccountSerializer(read_only=True, source='account_object')
gateway = _ConnectionTokenGatewaySerializer(read_only=True)
platform = _ConnectionTokenPlatformSerializer(read_only=True)
acl_command_groups = _ConnectionTokenACLCmdGroupSerializer(read_only=True, many=True)
actions = ActionChoicesField()
expire_at = serializers.IntegerField()
expire_now = serializers.BooleanField(label=_('Expired now'), write_only=True, default=True)
connect_method = serializers.CharField(label=_('Connect method'), write_only=True, default='ssh')
connect_method = serializers.SerializerMethodField(label=_('Connect method'))
class Meta:
model = ConnectionToken
@ -99,7 +99,19 @@ class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin):
'id', 'value', 'user', 'asset', 'account',
'platform', 'acl_command_groups', 'protocol',
'gateway', 'actions', 'expire_at', 'expire_now',
'connect_method'
]
extra_kwargs = {
'value': {'read_only': True},
}
def get_connect_method(self, obj):
from terminal.const import TerminalType
from common.utils import get_request_os
request = self.context.get('request')
if request:
os = get_request_os(request)
else:
os = 'windows'
method = TerminalType.get_connect_method(obj.connect_method, protocol=obj.protocol, os=os)
return method

View File

@ -16,7 +16,7 @@ class ConnectionTokenSerializer(OrgResourceModelSerializerMixin):
model = ConnectionToken
fields_mini = ['id', 'value']
fields_small = fields_mini + [
'user', 'asset', 'account_name', 'input_username',
'user', 'asset', 'account', 'input_username',
'input_secret', 'connect_method', 'protocol', 'actions',
'date_expired', 'date_created', 'date_updated', 'created_by',
'updated_by', 'org_id', 'org_name',

View File

@ -229,7 +229,7 @@ class TerminalType(TextChoices):
return protocols
@classmethod
def get_connect_method(cls, name, protocol, os):
def get_connect_method(cls, name, protocol, os='linux'):
methods = cls.get_protocols_connect_methods(os)
protocol_methods = methods.get(protocol, [])
for method in protocol_methods:
@ -267,7 +267,6 @@ class TerminalType(TextChoices):
protocol_web_methods = set(web_methods.get(protocol, [])) \
& set(component_protocol.get('web_methods', []))
print("protocol_web_methods", protocol, protocol_web_methods)
methods[protocol.value].extend([
{
'component': component.value,