From 9062a84bf4cfa71cf8162a638af50a501680b2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Sat, 12 Aug 2023 17:10:58 +0200 Subject: [PATCH] More on migrations --- .../0046_registered_server_migration.py | 7 +- .../fixers/providers_v4/__init__.py | 15 +++ .../fixers/providers_v4/_migrator.py | 93 +++++++++---------- .../uds/migrations/fixers/providers_v4/rds.py | 3 +- 4 files changed, 66 insertions(+), 52 deletions(-) diff --git a/server/src/uds/migrations/0046_registered_server_migration.py b/server/src/uds/migrations/0046_registered_server_migration.py index 363a405d5..73aa50855 100644 --- a/server/src/uds/migrations/0046_registered_server_migration.py +++ b/server/src/uds/migrations/0046_registered_server_migration.py @@ -7,7 +7,7 @@ import uds.core.types.servers import uds.core.util.model from uds.core.util.os_detector import KnownOS -from .fixers import transports_v4 +from .fixers import transports_v4, providers_v4 ACTOR_TYPE: typing.Final[int] = uds.core.types.servers.ServerType.ACTOR.value @@ -51,6 +51,8 @@ def migrate_old_data(apps, schema_editor) -> None: ) # Migrate old transports transports_v4.migrate(apps, schema_editor) + # And old providers and services + providers_v4.migrate(apps, schema_editor) except Exception as e: if 'no such table' not in str(e): # Pytest is running this method twice?? @@ -60,7 +62,7 @@ def migrate_old_data(apps, schema_editor) -> None: def rollback_old_data(apps, schema_editor) -> None: RegisteredServer: 'typing.Type[uds.models.RegisteredServer]' = apps.get_model('uds', 'RegisteredServer') ActorToken = apps.get_model('uds', 'ActorToken') - for server in RegisteredServer.objects.filter(kind=ACTOR_TYPE): + for server in RegisteredServer.objects.filter(type=ACTOR_TYPE): if not server.data: continue # Skip servers without data, they are not actors!! ActorToken.objects.create( @@ -81,6 +83,7 @@ def rollback_old_data(apps, schema_editor) -> None: server.delete() transports_v4.rollback(apps, schema_editor) + providers_v4.rollback(apps, schema_editor) class Migration(migrations.Migration): diff --git a/server/src/uds/migrations/fixers/providers_v4/__init__.py b/server/src/uds/migrations/fixers/providers_v4/__init__.py index 66a35c9f6..525fe417a 100644 --- a/server/src/uds/migrations/fixers/providers_v4/__init__.py +++ b/server/src/uds/migrations/fixers/providers_v4/__init__.py @@ -25,3 +25,18 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +Author: Adolfo Gómez, dkmaster at dkmon dot com +""" +import typing +from . import rds + +ALL: typing.Final = (rds,) + +def migrate(apps, schema_editor): + for i in ALL: + i.migrate(apps, schema_editor) + +def rollback(apps, schema_editor): + for i in reversed(ALL): + i.rollback(apps, schema_editor) diff --git a/server/src/uds/migrations/fixers/providers_v4/_migrator.py b/server/src/uds/migrations/fixers/providers_v4/_migrator.py index 1c9f6b941..8431e5699 100644 --- a/server/src/uds/migrations/fixers/providers_v4/_migrator.py +++ b/server/src/uds/migrations/fixers/providers_v4/_migrator.py @@ -31,60 +31,25 @@ Author: Adolfo Gómez, dkmaster at dkmon dot com import datetime import logging import secrets - -import dns.resolver - -from uds.core import transports -from uds.core.ui import gui -from uds.core.util import validators - -logger = logging.getLogger(__name__) - - -# Copy for migration -# -*- coding: utf-8 -*- -# -# Copyright (c) 2023 Virtual Cable S.L.U. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -""" -Author: Adolfo Gómez, dkmaster at dkmon dot com -""" -import logging import typing -from uds.core import services, types +import dns.resolver +import dns.reversename + +from uds.core import types, consts from uds.core.environment import Environment -from uds.core.ui import gui +from uds.core.util import os_detector, validators logger = logging.getLogger(__name__) + if typing.TYPE_CHECKING: import uds.models -def migrate(apps, model: typing.Literal['Provider', 'Service'], DataType: typing.Type, subtype: str, ipListAttr: str) -> None: + +def migrate( + apps, model: typing.Literal['Provider', 'Service'], DataType: typing.Type, subtype: str, ipListAttr: str +) -> None: try: Table: typing.Type['uds.models.ManagedObjectModel'] = apps.get_model('uds', model) RegisteredServerGroup: 'typing.Type[uds.models.RegisteredServerGroup]' = apps.get_model( @@ -109,8 +74,8 @@ def migrate(apps, model: typing.Literal['Provider', 'Service'], DataType: typin validators.validateIpv4OrIpv6(server) # Is Pure IP, try to get hostname try: - answers = dns.resolver.resolve(server, 'PTR') - server_ip_hostname.append((server, str(answers[0]))) + answers = dns.resolver.resolve(dns.reversename.from_address(server), 'PTR') + server_ip_hostname.append((server, str(answers[0]).rstrip('.'))) except Exception: # No problem, no reverse dns, hostname is the same as IP server_ip_hostname.append((server, server)) @@ -141,6 +106,7 @@ def migrate(apps, model: typing.Literal['Provider', 'Service'], DataType: typin username='migration', ip_from=server[0], ip=server[0], + os_type=os_detector.KnownOS.WINDOWS.os_name(), hostname=server[1], listen_port=0, type=types.servers.ServerType.UNMANAGED, @@ -153,7 +119,7 @@ def migrate(apps, model: typing.Literal['Provider', 'Service'], DataType: typin # Set server group on provider logger.info('Setting server group %s on provider %s', registeredServerGroup.name, record.name) obj.serverGroup.value = registeredServerGroup.uuid - # Save provider + # Save record record.data = obj.serialize() record.save(update_fields=['data']) @@ -161,3 +127,34 @@ def migrate(apps, model: typing.Literal['Provider', 'Service'], DataType: typin print(e) logger.exception('Exception found while migrating HTML5RDP transports') +def rollback(apps, model: typing.Literal['Provider', 'Service'], DataType: typing.Type, subtype: str, ipListAttr: str) -> None: + """ + "Un-Migrates" an new tunnel transport to an old one (without tunnelServer) + """ + try: + Table: typing.Type['uds.models.ManagedObjectModel'] = apps.get_model('uds', model) + RegisteredServerGroup: 'typing.Type[uds.models.RegisteredServerGroup]' = apps.get_model( + 'uds', 'RegisteredServerGroup' + ) + RegisteredServer: 'typing.Type[uds.models.RegisteredServer]' = apps.get_model('uds', 'RegisteredServer') + # For testing + # from uds.models import Transport, RegisteredServerGroup + + for record in Table.objects.filter(data_type=DataType.typeType): + # Extranct data + obj = DataType(Environment(record.uuid), None) + obj.deserialize(record.data) + # Guacamole server is https://: + # Other tunnels are : + iplist = getattr(obj, ipListAttr) + rsg = RegisteredServerGroup.objects.get(uuid=obj.serverGroup.value) + iplist.value=[i.ip for i in rsg.servers.all()] + # Remove registered servers + for i in rsg.servers.all(): + i.delete() + # Save obj + record.data = obj.serialize() + record.save(update_fields=['data']) + except Exception as e: # nosec: ignore this + print(e) + logger.error('Exception found while migrating HTML5RDP transports: %s', e) \ No newline at end of file diff --git a/server/src/uds/migrations/fixers/providers_v4/rds.py b/server/src/uds/migrations/fixers/providers_v4/rds.py index 177560eda..434cc29a7 100644 --- a/server/src/uds/migrations/fixers/providers_v4/rds.py +++ b/server/src/uds/migrations/fixers/providers_v4/rds.py @@ -123,5 +123,4 @@ def migrate(apps, schema_editor) -> None: def rollback(apps, schema_editor) -> None: - pass -# _migrator.tunnel_transport_back(apps, HTML5SSHTransport, 'guacamoleServer', is_html_server=True) + _migrator.rollback(apps, 'Provider', RDSProvider, RDS_SUBTYPE, 'ipList')