perf: 删除一部分 system user

pull/8873/head
ibuler 2022-08-16 16:34:16 +08:00
parent b8f8c2a264
commit 2948d5af7f
20 changed files with 141 additions and 172 deletions

View File

@ -0,0 +1,59 @@
# Generated by Django 3.2.14 on 2022-08-16 08:29
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('tickets', '0019_delete_applyapplicationticket'),
('authentication', '0012_auto_20220816_1629'),
('applications', '0023_auto_20220816_1021'),
]
operations = [
migrations.AlterUniqueTogether(
name='account',
unique_together=None,
),
migrations.RemoveField(
model_name='account',
name='app',
),
migrations.RemoveField(
model_name='account',
name='systemuser',
),
migrations.AlterUniqueTogether(
name='application',
unique_together=None,
),
migrations.RemoveField(
model_name='application',
name='domain',
),
migrations.RemoveField(
model_name='historicalaccount',
name='app',
),
migrations.RemoveField(
model_name='historicalaccount',
name='history_user',
),
migrations.RemoveField(
model_name='historicalaccount',
name='systemuser',
),
migrations.DeleteModel(
name='ApplicationUser',
),
migrations.DeleteModel(
name='Account',
),
migrations.DeleteModel(
name='Application',
),
migrations.DeleteModel(
name='HistoricalAccount',
),
]

View File

@ -1,2 +1,2 @@
from .application import *
from .account import *
# from .application import *
# from .account import *

View File

@ -12,7 +12,6 @@ from .base import AuthSerializerMixin
class DomainSerializer(BulkOrgResourceModelSerializer):
asset_count = serializers.SerializerMethodField(label=_('Assets amount'))
application_count = serializers.SerializerMethodField(label=_('Applications amount'))
gateway_count = serializers.SerializerMethodField(label=_('Gateways count'))
class Meta:
@ -22,7 +21,7 @@ class DomainSerializer(BulkOrgResourceModelSerializer):
'comment', 'date_created'
]
fields_m2m = [
'asset_count', 'assets', 'application_count', 'gateway_count',
'asset_count', 'assets', 'gateway_count',
]
fields = fields_small + fields_m2m
read_only_fields = ('asset_count', 'gateway_count', 'date_created')
@ -34,10 +33,6 @@ class DomainSerializer(BulkOrgResourceModelSerializer):
def get_asset_count(obj):
return obj.assets.count()
@staticmethod
def get_application_count(obj):
return obj.applications.count()
@staticmethod
def get_gateway_count(obj):
return obj.gateway_set.all().count()

View File

@ -10,9 +10,6 @@ from rest_framework import serializers
from assets.models import Account
from assets.serializers import AccountSecretSerializer
from assets.notifications import AccountBackupExecutionTaskMsg
from applications.models import Account
from applications.const import AppType
from applications.serializers import AppAccountSecretSerializer
from users.models import User
from common.utils import get_logger
from common.utils.timezone import local_now_display
@ -76,7 +73,7 @@ class AssetAccountHandler(BaseAccountHandler):
data_map = defaultdict(list)
sheet_name = Account._meta.verbose_name
accounts = Account.get_queryset()
accounts = Account.objects.all()
if not accounts.first():
return data_map
@ -91,34 +88,8 @@ class AssetAccountHandler(BaseAccountHandler):
logger.info('\n\033[33m- 共收集 {} 条资产账号\033[0m'.format(accounts.count()))
return data_map
class AppAccountHandler(BaseAccountHandler):
@staticmethod
def get_filename(plan_name):
filename = os.path.join(
PATH, f'{plan_name}-{_("Application")}-{local_now_display()}-{time.time()}.xlsx'
)
return filename
@classmethod
def create_data_map(cls):
data_map = defaultdict(list)
accounts = Account.get_queryset().select_related('systemuser')
for account in accounts:
account.load_auth()
app_type = account.type
sheet_name = AppType.get_label(app_type)
row = cls.create_row(account, AppAccountSecretSerializer)
if sheet_name not in data_map:
data_map[sheet_name].append(list(row.keys()))
data_map[sheet_name].append(list(row.values()))
logger.info('\n\033[33m- 共收集{}条应用账号\033[0m'.format(accounts.count()))
return data_map
handler_map = {
'asset': AssetAccountHandler,
'application': AppAccountHandler
}

View File

@ -13,13 +13,12 @@ MODELS_NEED_RECORD = (
'Asset', 'Node', 'AdminUser', 'SystemUser', 'Domain', 'Gateway', 'CommandFilterRule',
'CommandFilter', 'Platform', 'Account',
# applications
'Application',
# orgs
'Organization',
# settings
'Setting',
# perms
'AssetPermission', 'ApplicationPermission',
'AssetPermission',
# xpack
'License', 'Account', 'SyncInstanceTask', 'ChangeAuthPlan', 'GatherUserTask',
)

View File

@ -0,0 +1,53 @@
# Generated by Django 3.2.14 on 2022-08-16 08:29
from django.db import migrations, models
def migrate_system_user_to_accounts(apps, schema_editor):
connection_token_model = apps.get_model("perms", "ConnectionToken")
count = 0
bulk_size = 10000
while True:
connection_tokens = connection_token_model.objects \
.prefect_related('system_users')[count:bulk_size]
if not connection_tokens:
break
count += len(connection_tokens)
updated = []
for connection_token in connection_tokens:
connection_token.account = connection_token.system_user.username
updated.append(connection_token)
connection_token_model.objects.bulk_update(updated, ['account'])
class Migration(migrations.Migration):
dependencies = [
('authentication', '0011_auto_20220705_1940'),
]
operations = [
migrations.RemoveField(
model_name='connectiontoken',
name='application',
),
migrations.RemoveField(
model_name='connectiontoken',
name='application_display',
),
migrations.RemoveField(
model_name='connectiontoken',
name='system_user_display',
),
migrations.AddField(
model_name='connectiontoken',
name='account',
field=models.CharField(default='', max_length=128, verbose_name='Account'),
),
migrations.RunPython(migrate_system_user_to_accounts),
migrations.RemoveField(
model_name='connectiontoken',
name='system_user',
)
]

View File

@ -80,25 +80,12 @@ class ConnectionToken(OrgModelMixin, JMSBaseModel):
related_name='connection_tokens', null=True, blank=True
)
user_display = models.CharField(max_length=128, default='', verbose_name=_("User display"))
system_user = models.ForeignKey(
'assets.SystemUser', on_delete=models.SET_NULL, verbose_name=_('System user'),
related_name='connection_tokens', null=True, blank=True
)
system_user_display = models.CharField(
max_length=128, default='', verbose_name=_("System user display")
)
asset = models.ForeignKey(
'assets.Asset', on_delete=models.SET_NULL, verbose_name=_('Asset'),
related_name='connection_tokens', null=True, blank=True
)
asset_display = models.CharField(max_length=128, default='', verbose_name=_("Asset display"))
application = models.ForeignKey(
'applications.Application', on_delete=models.SET_NULL, verbose_name=_('Application'),
related_name='connection_tokens', null=True, blank=True
)
application_display = models.CharField(
max_length=128, default='', verbose_name=_("Application display")
)
account = models.CharField(max_length=128, default='', verbose_name=_("Account"))
class Meta:
ordering = ('-date_expired',)

View File

@ -7,7 +7,6 @@ from common.utils import pretty_string
from common.utils.random import random_string
from assets.models import Asset, SystemUser, Gateway, Domain, CommandFilterRule
from users.models import User
from applications.models import Application
from perms.serializers.base import ActionsField
@ -66,9 +65,6 @@ class ConnectionTokenSerializer(OrgResourceModelSerializerMixin):
if isinstance(asset, Asset):
tp = ConnectionToken.Type.asset
org_id = asset.org_id
elif isinstance(application, Application):
tp = ConnectionToken.Type.application
org_id = application.org_id
else:
raise serializers.ValidationError(_('Asset or application required'))
@ -148,14 +144,6 @@ class ConnectionTokenRemoteAppSerializer(serializers.Serializer):
parameters = serializers.CharField(allow_null=True, allow_blank=True)
class ConnectionTokenApplicationSerializer(serializers.ModelSerializer):
attrs = serializers.JSONField(read_only=True)
class Meta:
model = Application
fields = ['id', 'name', 'category', 'type', 'attrs', 'org_id']
class ConnectionTokenDomainSerializer(serializers.ModelSerializer):
gateways = ConnectionTokenGatewaySerializer(many=True, read_only=True)
@ -176,7 +164,6 @@ class ConnectionTokenCmdFilterRuleSerializer(serializers.ModelSerializer):
class ConnectionTokenSecretSerializer(OrgResourceModelSerializerMixin):
user = ConnectionTokenUserSerializer(read_only=True)
asset = ConnectionTokenAssetSerializer(read_only=True)
application = ConnectionTokenApplicationSerializer(read_only=True)
remote_app = ConnectionTokenRemoteAppSerializer(read_only=True)
system_user = ConnectionTokenSystemUserSerializer(read_only=True)
gateway = ConnectionTokenGatewaySerializer(read_only=True)

View File

@ -17,7 +17,6 @@ from assets.models import (
Asset, Domain, SystemUser, Label, Node, Gateway,
CommandFilter, CommandFilterRule, GatheredUser
)
from applications.models import Application
from perms.models import AssetPermission
from orgs.utils import current_org, tmp_to_root_org
from common.utils import get_logger
@ -31,7 +30,6 @@ org_related_models = [
User, UserGroup, Asset, Label, Domain, Gateway, Node, SystemUser, Label,
CommandFilter, CommandFilterRule, GatheredUser,
AssetPermission,
Application,
]

View File

@ -8,7 +8,6 @@ from common.utils import get_logger
from users.models import UserGroup, User
from assets.models import Node, SystemUser, Domain, Gateway, Asset
from terminal.models import Session
from applications.models import Application
from perms.models import AssetPermission
logger = get_logger(__file__)
@ -57,9 +56,6 @@ class OrgResourceStatisticsCache(OrgRelatedCache):
system_users_amount = IntegerField()
domains_amount = IntegerField(queryset=Domain.objects)
gateways_amount = IntegerField(queryset=Gateway.objects)
applications_amount = IntegerField(queryset=Application.objects)
asset_perms_amount = IntegerField(queryset=AssetPermission.objects)
total_count_online_users = IntegerField()

View File

@ -16,9 +16,7 @@ class ResourceStatisticsSerializer(serializers.Serializer):
domains_amount = serializers.IntegerField(required=False)
gateways_amount = serializers.IntegerField(required=False)
applications_amount = serializers.IntegerField(required=False)
asset_perms_amount = serializers.IntegerField(required=False)
app_perms_amount = serializers.IntegerField(required=False)
class OrgSerializer(ModelSerializer):

View File

@ -6,7 +6,6 @@ from assets.models import Node
from perms.models import AssetPermission
from users.models import UserGroup, User
from users.signals import pre_user_leave_org
from applications.models import Application
from terminal.models import Session
from rbac.models import OrgRoleBinding, SystemRoleBinding, RoleBinding
from assets.models import Asset, SystemUser, Domain, Gateway
@ -76,7 +75,6 @@ def on_user_delete_refresh_cache(sender, instance, **kwargs):
class OrgResourceStatisticsRefreshUtil:
model_cache_field_mapper = {
AssetPermission: ['asset_perms_amount'],
Application: ['applications_amount'],
Gateway: ['gateways_amount'],
Domain: ['domains_amount'],
SystemUser: ['system_users_amount', 'admin_users_amount'],

View File

@ -1,6 +1,4 @@
from urllib.parse import urljoin
from django.conf import settings
from django.utils.translation import ugettext as _
from django.template.loader import render_to_string
@ -82,75 +80,3 @@ class AssetPermsWillExpireForOrgAdminMsg(UserMessage):
perms = AssetPermission.objects.all()[:10]
org = Organization.objects.first()
return cls(user, perms, org)
class PermedAppsWillExpireUserMsg(UserMessage):
def __init__(self, user, apps, day_count=0):
super().__init__(user)
self.apps = apps
self.day_count = day_count
def get_html_msg(self) -> dict:
subject = _("Your permed applications is about to expire")
context = {
'name': self.user.name,
'count': self.day_count,
'item_type': _('permed applications'),
'items': [str(app) for app in self.apps]
}
message = render_to_string('perms/_msg_permed_items_expire.html', context)
return {
'subject': subject,
'message': message
}
@classmethod
def gen_test_msg(cls):
from users.models import User
from applications.models import Application
user = User.objects.first()
apps = Application.objects.all()[:10]
return cls(user, apps)
class AppPermsWillExpireForOrgAdminMsg(UserMessage):
def __init__(self, user, perms, org, day_count=0):
super().__init__(user)
self.perms = perms
self.org = org
self.day_count = day_count
def get_items_with_url(self):
items_with_url = []
perm_detail_url = urljoin(settings.SITE_URL, '/ui/#/perms/app-permissions/{}')
for perm in self.perms:
url = perm_detail_url.format(perm.id) + f'?oid={perm.org_id}'
items_with_url.append([perm.name, url])
return items_with_url
def get_html_msg(self) -> dict:
items = self.get_items_with_url()
subject = _('Application permissions is about to expire')
context = {
'name': self.user.name,
'count': self.day_count,
'item_type': _('application permissions of organization {}').format(self.org),
'items_with_url': items
}
message = render_to_string('perms/_msg_item_permissions_expire.html', context)
return {
'subject': subject,
'message': message
}
@classmethod
def gen_test_msg(cls):
from users.models import User
from perms.models import ApplicationPermission
from orgs.models import Organization
user = User.objects.first()
perms = ApplicationPermission.objects.all()[:10]
org = Organization.objects.first()
return cls(user, perms, org)

View File

@ -6,7 +6,6 @@ from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_object_or_404
from assets.models import Asset
from orgs.utils import tmp_to_root_org
from applications.models import Application
from terminal.models import Session
from common.permissions import IsValidUser
from ..models import Endpoint, EndpointRule
@ -52,21 +51,16 @@ class SmartEndpointViewMixin:
@staticmethod
def get_target_instance(request):
asset_id = request.GET.get('asset_id')
app_id = request.GET.get('app_id')
session_id = request.GET.get('session_id')
token_id = request.GET.get('token')
if token_id:
from authentication.models import ConnectionToken
token = ConnectionToken.objects.filter(id=token_id).first()
if token:
if token.asset:
asset_id = token.asset.id
elif token.application:
app_id = token.application.id
if token and token.asset:
asset_id = token.asset.id
if asset_id:
pk, model = asset_id, Asset
elif app_id:
pk, model = app_id, Application
elif session_id:
pk, model = session_id, Session
else:

View File

@ -12,7 +12,6 @@ from django.core.cache import cache
from assets.models import Asset
from assets.const import Protocol
from applications.models import Application
from users.models import User
from orgs.mixins.models import OrgModelMixin
from django.db.models import TextChoices

View File

@ -15,7 +15,7 @@ from tickets import serializers
from tickets import filters
from tickets.permissions.ticket import IsAssignee, IsApplicant
from tickets.models import (
Ticket, ApplyAssetTicket, ApplyApplicationTicket,
Ticket, ApplyAssetTicket,
ApplyLoginTicket, ApplyLoginAssetTicket, ApplyCommandTicket
)

View File

@ -4,7 +4,7 @@ from django.db.models import Subquery, OuterRef
from common.drf.filters import BaseFilterSet
from tickets.models import (
Ticket, TicketStep, ApplyAssetTicket, ApplyApplicationTicket,
Ticket, TicketStep, ApplyAssetTicket,
ApplyLoginTicket, ApplyLoginAssetTicket, ApplyCommandTicket
)
@ -34,12 +34,6 @@ class ApplyAssetTicketFilter(BaseFilterSet):
fields = ('id',)
class ApplyApplicationTicketFilter(BaseFilterSet):
class Meta:
model = ApplyApplicationTicket
fields = ('id',)
class ApplyLoginTicketFilter(BaseFilterSet):
class Meta:
model = ApplyLoginTicket

View File

@ -0,0 +1,16 @@
# Generated by Django 3.2.14 on 2022-08-16 08:29
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('tickets', '0018_auto_20220728_1125'),
]
operations = [
migrations.DeleteModel(
name='ApplyApplicationTicket',
),
]

View File

@ -1,6 +1,6 @@
from .general import *
from .apply_asset import *
from .apply_application import *
# from .apply_application import *
from .command_confirm import *
from .login_asset_confirm import *
from .login_confirm import *

View File

@ -9,7 +9,7 @@ from django.utils.translation import ugettext as _
from orgs.utils import tmp_to_root_org
from tickets.models import (
Ticket, ApplyAssetTicket, ApplyApplicationTicket,
Ticket, ApplyAssetTicket,
ApplyLoginTicket, ApplyLoginAssetTicket, ApplyCommandTicket
)
from tickets.const import TicketType
@ -27,7 +27,6 @@ class TicketDirectApproveView(TemplateView):
TICKET_SUB_MODEL_MAP = {
TicketType.apply_asset: ApplyAssetTicket,
TicketType.apply_application: ApplyApplicationTicket,
TicketType.login_confirm: ApplyLoginTicket,
TicketType.login_asset_confirm: ApplyLoginAssetTicket,
TicketType.command_confirm: ApplyCommandTicket,