# Generated by Django 3.1.14 on 2022-06-23 02:27 import re from datetime import datetime from collections import defaultdict from django.utils import timezone as dj_timezone from django.db import migrations from tickets.const import TicketType pt = re.compile(r'(\w+)\((\w+)\)') def time_conversion(t): if not t: return try: return datetime.strptime(t, '%Y-%m-%d %H:%M:%S'). \ astimezone(dj_timezone.get_current_timezone()) except Exception: return nodes_dict = defaultdict(set) assets_dict = defaultdict(set) system_users_dict = defaultdict(set) apps_dict = defaultdict(set) global_inited = {} def init_global_dict(apps): if global_inited: return node_model = apps.get_model('assets', 'Node') asset_model = apps.get_model('assets', 'Asset') system_user_model = apps.get_model('assets', 'SystemUser') application_model = apps.get_model('applications', 'Application') node_qs = node_model.objects.values('id', 'org_id') asset_qs = asset_model.objects.values('id', 'org_id') system_user_qs = system_user_model.objects.values('id', 'org_id') app_qs = application_model.objects.values('id', 'org_id') for d, qs in [ (nodes_dict, node_qs), (assets_dict, asset_qs), (system_users_dict, system_user_qs), (apps_dict, app_qs) ]: for i in qs: _id = str(i['id']) org_id = str(i['org_id']) d[org_id].add(_id) global_inited['inited'] = True def apply_asset_migrate(apps, *args): init_global_dict(apps) ticket_model = apps.get_model('tickets', 'Ticket') tickets = ticket_model.objects.filter(type=TicketType.apply_asset) ticket_apply_asset_model = apps.get_model('tickets', 'ApplyAssetTicket') for instance in tickets: meta = instance.meta org_id = instance.org_id apply_actions = meta.get('apply_actions') # 数据库中数据结构有问题,可能是 list,可能是 int if isinstance(apply_actions, list): apply_actions = Action.choices_to_value(value=apply_actions) elif isinstance(apply_actions, int): apply_actions = apply_actions else: apply_actions = 0 data = { 'ticket_ptr_id': instance.pk, 'apply_permission_name': meta.get('apply_permission_name', ''), 'apply_date_start': time_conversion(meta.get('apply_date_start')), 'apply_date_expired': time_conversion(meta.get('apply_date_expired')), 'apply_actions': apply_actions, } child = ticket_apply_asset_model(**data) child.__dict__.update(instance.__dict__) child.save() apply_nodes = list(set(meta.get('apply_nodes', [])) & nodes_dict[org_id]) apply_assets = list(set(meta.get('apply_assets', [])) & assets_dict[org_id]) apply_system_users = list(set(meta.get('apply_system_users', [])) & system_users_dict[org_id]) child.apply_nodes.set(apply_nodes) child.apply_assets.set(apply_assets) child.apply_system_users.set(apply_system_users) if (not apply_nodes and not apply_assets) or not apply_system_users: continue rel_snapshot = { 'applicant': instance.applicant_display, 'apply_nodes': meta.get('apply_nodes_display', []), 'apply_assets': meta.get('apply_assets_display', []), 'apply_system_users': meta.get('apply_system_users_display', []), } instance.rel_snapshot = rel_snapshot instance.save(update_fields=['rel_snapshot']) def apply_application_migrate(apps, *args): init_global_dict(apps) ticket_model = apps.get_model('tickets', 'Ticket') tickets = ticket_model.objects.filter(type='apply_application') ticket_apply_app_model = apps.get_model('tickets', 'ApplyApplicationTicket') for instance in tickets: meta = instance.meta org_id = instance.org_id data = { 'ticket_ptr_id': instance.pk, 'apply_permission_name': meta.get('apply_permission_name', ''), 'apply_category': meta.get('apply_category'), 'apply_type': meta.get('apply_type'), 'apply_date_start': time_conversion(meta.get('apply_date_start')), 'apply_date_expired': time_conversion(meta.get('apply_date_expired')), } child = ticket_apply_app_model(**data) child.__dict__.update(instance.__dict__) child.save() apply_applications = list(set(meta.get('apply_applications', [])) & apps_dict[org_id]) apply_system_users = list(set(meta.get('apply_system_users', [])) & system_users_dict[org_id]) if not apply_applications or not apply_system_users: continue child.apply_applications.set(apply_applications) child.apply_system_users.set(apply_system_users) rel_snapshot = { 'applicant': instance.applicant_display, 'apply_applications': meta.get('apply_applications_display', []), 'apply_system_users': meta.get('apply_system_users_display', []), } instance.rel_snapshot = rel_snapshot instance.save(update_fields=['rel_snapshot']) def login_confirm_migrate(apps, *args): ticket_model = apps.get_model('tickets', 'Ticket') tickets = ticket_model.objects.filter(type=TicketType.login_confirm) ticket_apply_login_model = apps.get_model('tickets', 'ApplyLoginTicket') for instance in tickets: meta = instance.meta data = { 'ticket_ptr_id': instance.pk, 'apply_login_ip': meta.get('apply_login_ip'), 'apply_login_city': meta.get('apply_login_city'), 'apply_login_datetime': time_conversion(meta.get('apply_login_datetime')), } rel_snapshot = { 'applicant': instance.applicant_display } instance.rel_snapshot = rel_snapshot instance.save(update_fields=['rel_snapshot']) child = ticket_apply_login_model(**data) child.__dict__.update(instance.__dict__) child.save() def analysis_instance_name(name: str): if not name: return None matched = pt.match(name) if not matched: return None return matched.groups() def login_asset_confirm_migrate(apps, *args): user_model = apps.get_model('users', 'User') asset_model = apps.get_model('assets', 'Asset') system_user_model = apps.get_model('assets', 'SystemUser') ticket_model = apps.get_model('tickets', 'Ticket') tickets = ticket_model.objects.filter(type=TicketType.login_asset_confirm) ticket_apply_login_asset_model = apps.get_model('tickets', 'ApplyLoginAssetTicket') for instance in tickets: meta = instance.meta name_username = analysis_instance_name(meta.get('apply_login_user')) apply_login_user = user_model.objects.filter( name=name_username[0], username=name_username[1] ).first() if name_username else None hostname_ip = analysis_instance_name(meta.get('apply_login_asset')) apply_login_asset = asset_model.objects.filter( org_id=instance.org_id, hostname=hostname_ip[0], ip=hostname_ip[1] ).first() if hostname_ip else None name_username = analysis_instance_name(meta.get('apply_login_system_user')) apply_login_system_user = system_user_model.objects.filter( org_id=instance.org_id, name=name_username[0], username=name_username[1] ).first() if name_username else None data = { 'ticket_ptr_id': instance.pk, 'apply_login_user': apply_login_user, 'apply_login_asset': apply_login_asset, 'apply_login_system_user': apply_login_system_user, } child = ticket_apply_login_asset_model(**data) child.__dict__.update(instance.__dict__) child.save() rel_snapshot = { 'applicant': instance.applicant_display, 'apply_login_user': meta.get('apply_login_user', ''), 'apply_login_asset': meta.get('apply_login_asset', ''), 'apply_login_system_user': meta.get('apply_login_system_user', ''), } instance.rel_snapshot = rel_snapshot instance.save(update_fields=['rel_snapshot']) def command_confirm_migrate(apps, *args): user_model = apps.get_model('users', 'User') asset_model = apps.get_model('assets', 'Asset') system_user_model = apps.get_model('assets', 'SystemUser') ticket_model = apps.get_model('tickets', 'Ticket') session_model = apps.get_model('terminal', 'Session') command_filter_model = apps.get_model('assets', 'CommandFilter') command_filter_rule_model = apps.get_model('assets', 'CommandFilterRule') tickets = ticket_model.objects.filter(type=TicketType.command_confirm) session_ids = tickets.values_list('meta__apply_from_session_id', flat=True) session_ids = session_model.objects.filter(id__in=list(session_ids)).values_list('id', flat=True) session_ids = [str(i) for i in session_ids] command_filter_ids = tickets.values_list('meta__apply_from_cmd_filter_id', flat=True) command_filter_ids = command_filter_model.objects\ .filter(id__in=list(command_filter_ids))\ .values_list('id', flat=True) command_filter_ids = [str(i) for i in command_filter_ids] command_filter_rule_ids = tickets.values_list('meta__apply_from_cmd_filter_rule_id', flat=True) command_filter_rule_ids = command_filter_rule_model.objects\ .filter(id__in=list(command_filter_rule_ids))\ .values_list('id', flat=True) command_filter_rule_ids = [str(i) for i in command_filter_rule_ids] ticket_apply_command_model = apps.get_model('tickets', 'ApplyCommandTicket') for instance in tickets: meta = instance.meta name_username = analysis_instance_name(meta.get('apply_run_user')) apply_run_user = user_model.objects.filter( name=name_username[0], username=name_username[1] ).first() if name_username else None name_username = analysis_instance_name(meta.get('apply_run_system_user')) apply_run_system_user = system_user_model.objects.filter( org_id=instance.org_id, name=name_username[0], username=name_username[1] ).first() if name_username else None apply_from_session_id = meta.get('apply_from_session_id') apply_from_cmd_filter_id = meta.get('apply_from_cmd_filter_id') apply_from_cmd_filter_rule_id = meta.get('apply_from_cmd_filter_rule_id') if apply_from_session_id not in session_ids: apply_from_session_id = None if apply_from_cmd_filter_id not in command_filter_ids: apply_from_cmd_filter_id = None if apply_from_cmd_filter_rule_id not in command_filter_rule_ids: apply_from_cmd_filter_rule_id = None data = { 'ticket_ptr_id': instance.pk, 'apply_run_user': apply_run_user, 'apply_run_asset': meta.get('apply_run_asset', ''), 'apply_run_system_user': apply_run_system_user, 'apply_run_command': meta.get('apply_run_command', '')[:4090], 'apply_from_session_id': apply_from_session_id, 'apply_from_cmd_filter_id': apply_from_cmd_filter_id, 'apply_from_cmd_filter_rule_id': apply_from_cmd_filter_rule_id, } rel_snapshot = { 'applicant': instance.applicant_display, 'apply_run_user': meta.get('apply_run_user', ''), 'apply_run_system_user': meta.get('apply_run_system_user', ''), 'apply_from_session': meta.get('apply_from_session_id', ''), 'apply_from_cmd_filter': meta.get('apply_from_cmd_filter_id', ''), 'apply_from_cmd_filter_rule': meta.get('apply_from_cmd_filter_rule_id', ''), } child = ticket_apply_command_model(**data) child.__dict__.update(instance.__dict__) child.save() instance.rel_snapshot = rel_snapshot instance.save(update_fields=['rel_snapshot']) def migrate_ticket_state(apps, *args): ticket_model = apps.get_model('tickets', 'Ticket') ticket_step_model = apps.get_model('tickets', 'TicketStep') ticket_assignee_model = apps.get_model('tickets', 'TicketAssignee') ticket_model.objects.filter(state='open').update(state='pending') ticket_step_model.objects.filter(state='notified').update(state='pending') ticket_assignee_model.objects.filter(state='notified').update(state='pending') class Migration(migrations.Migration): dependencies = [ ('tickets', '0016_auto_20220609_1758'), ] operations = [ migrations.RunPython(migrate_ticket_state), migrations.RunPython(apply_asset_migrate), migrations.RunPython(apply_application_migrate), migrations.RunPython(login_confirm_migrate), migrations.RunPython(login_asset_confirm_migrate), migrations.RunPython(command_confirm_migrate), migrations.RemoveField( model_name='ticket', name='applicant_display', ), ]