From d44b694456512def4c25d2cfd83da8cfdd2bbda9 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Jaillet Date: Mon, 20 Mar 2017 19:10:41 +0100 Subject: [PATCH] multitenant: add delete_tenant command (#15513) --- .../management/commands/delete_tenant.py | 29 ++++++++++++++++++++++ hobo/multitenant/models.py | 14 ++++++++++- tests_multitenant/conftest.py | 3 ++- tests_multitenant/test_tenant_command.py | 9 +++++++ 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 hobo/multitenant/management/commands/delete_tenant.py diff --git a/hobo/multitenant/management/commands/delete_tenant.py b/hobo/multitenant/management/commands/delete_tenant.py new file mode 100644 index 0000000..4d3096d --- /dev/null +++ b/hobo/multitenant/management/commands/delete_tenant.py @@ -0,0 +1,29 @@ +import sys +from optparse import make_option + +from django.core.management.base import CommandError, BaseCommand +from hobo.multitenant.middleware import TenantMiddleware + + +class Command(BaseCommand): + help = "Delete tenant(s) by hostname(s)" + args = ['...'] + option_list = BaseCommand.option_list + ( + make_option('--force-drop', action='store_true', default=False, + help='If you want the schema to be deleted from database'), + ) + + def handle(self, *args, **options): + + if not args: + raise CommandError("you must give at least one tenant hostname") + + # if - is given on the command line, get list of hostnames from stdin + if '-' in args: + args = list(args) + args.remove('-') + args.extend([x.strip() for x in sys.stdin.readlines()]) + for hostname in args: + tenant = TenantMiddleware.get_tenant_by_hostname(hostname) + tenant.delete(force_drop=options['force_drop']) + diff --git a/hobo/multitenant/models.py b/hobo/multitenant/models.py index 2fa97c8..7ebd52e 100644 --- a/hobo/multitenant/models.py +++ b/hobo/multitenant/models.py @@ -1,9 +1,11 @@ import os from urlparse import urljoin import json +from shutil import rmtree from django.conf import settings from django.db import connection +from django.utils import timezone from tenant_schemas.utils import get_public_schema_name from tenant_schemas.models import TenantMixin @@ -65,8 +67,18 @@ class Tenant(TenantMixin): "the public schema. Current schema is %s." % connection.schema_name) - os.rename(self.get_directory(), self.get_directory() + '.invalid') + if force_drop: + rmtree(self.get_directory()) + else: + deletion_date = timezone.now().strftime('%Y%m%d_%H%M%S_%f') + os.rename(self.get_directory(), self.get_directory() + '.removed_%s.invalid' % deletion_date) if schema_exists(self.schema_name) and (self.auto_drop_schema or force_drop): cursor = connection.cursor() cursor.execute('DROP SCHEMA %s CASCADE' % self.schema_name) + + if schema_exists(self.schema_name) and (not self.auto_drop_schema and not force_drop): + cursor = connection.cursor() + schema_new_name = 'removed_%s_%s' % (self.schema_name, deletion_date, self.schema_name) + cursor.execute('ALTER SCHEMA %s RENAME TO %s' % schema_new_name[:63]) + diff --git a/tests_multitenant/conftest.py b/tests_multitenant/conftest.py index ca70a4c..77b326f 100644 --- a/tests_multitenant/conftest.py +++ b/tests_multitenant/conftest.py @@ -54,8 +54,9 @@ def tenants(transactional_db, request, settings): tenants = [make_tenant('tenant1.example.net'), make_tenant('tenant2.example.net')] def fin(): from django.db import connection + from hobo.multitenant.middleware import TenantMiddleware connection.set_schema_to_public() - for t in tenants: + for t in TenantMiddleware.get_tenants(): t.delete(True) shutil.rmtree(base) request.addfinalizer(fin) diff --git a/tests_multitenant/test_tenant_command.py b/tests_multitenant/test_tenant_command.py index 8bac572..bb67e05 100644 --- a/tests_multitenant/test_tenant_command.py +++ b/tests_multitenant/test_tenant_command.py @@ -29,3 +29,12 @@ def test_one_tenant(handle, tenants, tenant_in_call=None): assert handle.call_count == 1 assert len(handle.side_effect.tenants) == 1 assert handle.side_effect.tenants[0].domain_url == 'tenant2.example.net' + +def test_delete_tenant(tenants): + from django.core.management import execute_from_command_line + from hobo.multitenant.middleware import TenantMiddleware + all_tenants = list(TenantMiddleware.get_tenants()) + assert len(all_tenants) == 2 + execute_from_command_line(['manage.py', 'delete_tenant', 'tenant2.example.net']) + all_tenants = list(TenantMiddleware.get_tenants()) + assert len(all_tenants) == 1 -- 2.11.0