Refactor userdbs app to use signals

This commit isolates the celery task invocations of the userdbs app into
signal handlers. All celery interaction is now asynchronously handled in
userdbs.signals.
This commit is contained in:
Jan Dittberner 2015-12-07 00:23:07 +00:00
parent 1649e4592e
commit c9a9fa11b2
4 changed files with 208 additions and 91 deletions

View file

@ -1,33 +1,14 @@
from __future__ import unicode_literals
from django.db import models
from django.db import transaction
from django.db import models, transaction
from django.dispatch import Signal
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext as _
from model_utils import Choices
from model_utils.models import TimeStampedModel
from passlib.utils import generate_password
from osusers.models import User as OsUser
from mysqltasks.tasks import (
create_mysql_database,
create_mysql_user,
delete_mysql_database,
delete_mysql_user,
set_mysql_userpassword,
)
from pgsqltasks.tasks import (
create_pgsql_database,
create_pgsql_user,
delete_pgsql_database,
delete_pgsql_user,
set_pgsql_userpassword,
)
DB_TYPES = Choices(
(0, 'pgsql', _('PostgreSQL')),
(1, 'mysql', _('MySQL')),
@ -37,6 +18,9 @@ Database type choice enumeration.
"""
password_set = Signal(providing_args=['instance', 'password'])
class DatabaseUserManager(models.Manager):
"""
Default Manager for :py:class:`userdbs.models.DatabaseUser`.
@ -93,7 +77,6 @@ class DatabaseUserManager(models.Manager):
db_user = DatabaseUser(
osuser=osuser, db_type=db_type, name=username)
if commit:
db_user.create_in_database(password=password)
db_user.save()
return db_user
@ -120,34 +103,15 @@ class DatabaseUser(TimeStampedModel, models.Model):
'osuser': self.osuser.username,
}
def create_in_database(self, password=None):
"""
Create this user in the target database.
:param str password: initial password for the database user
"""
if password is None:
password = generate_password()
# TODO: send GPG encrypted mail with this information
if self.db_type == DB_TYPES.pgsql:
create_pgsql_user.delay(self.name, password).get()
elif self.db_type == DB_TYPES.mysql:
create_mysql_user.delay(self.name, password).get()
else:
raise ValueError('Unknown database type %d' % self.db_type)
@transaction.atomic
def set_password(self, password):
"""
Set an existing user's password.
:param str password: new password for the database user
"""
if self.db_type == DB_TYPES.pgsql:
set_pgsql_userpassword.delay(self.name, password).get(timeout=5)
elif self.db_type == DB_TYPES.mysql:
set_mysql_userpassword.delay(self.name, password).get(timeout=5)
else:
raise ValueError('Unknown database type %d' % self.db_type)
password_set.send(
sender=self.__class__, password=password, instance=self)
@transaction.atomic
def delete(self, *args, **kwargs):
@ -163,12 +127,6 @@ class DatabaseUser(TimeStampedModel, models.Model):
"""
for database in self.userdatabase_set.all():
database.delete()
if self.db_type == DB_TYPES.pgsql:
delete_pgsql_user.delay(self.name).get(propagate=False, timeout=5)
elif self.db_type == DB_TYPES.mysql:
delete_mysql_user.delay(self.name).get(propagate=False, timeout=5)
else:
raise ValueError('Unknown database type %d' % self.db_type)
super(DatabaseUser, self).delete(*args, **kwargs)
@ -236,7 +194,6 @@ class UserDatabaseManager(models.Manager):
db_name = self._get_next_dbname(db_user)
database = UserDatabase(db_user=db_user, db_name=db_name)
if commit:
database.create_in_database()
database.save()
return database
@ -260,39 +217,3 @@ class UserDatabase(TimeStampedModel, models.Model):
'db_name': self.db_name,
'db_user': self.db_user,
}
def create_in_database(self):
"""
Create this database (schema) in the target database.
"""
# TODO: send GPG encrypted mail with this information
if self.db_user.db_type == DB_TYPES.pgsql:
create_pgsql_database.delay(self.db_name, self.db_user.name).get()
elif self.db_user.db_type == DB_TYPES.mysql:
create_mysql_database.delay(self.db_name, self.db_user.name).get()
else:
raise ValueError('Unknown database type %d' % self.db_type)
@transaction.atomic
def delete(self, *args, **kwargs):
"""
Delete the database (schema) from the target database and the Django
database.
:param args: positional arguments for
:py:meth:`django.db.models.Model.delete`
:param kwargs: keyword arguments for
:py:meth:`django.db.models.Model.delete`
"""
db_user = self.db_user
if db_user.db_type == DB_TYPES.pgsql:
delete_pgsql_database.delay(self.db_name).get()
elif db_user.db_type == DB_TYPES.mysql:
delete_mysql_database.delay(self.db_name, db_user.name).get()
else:
raise ValueError('Unknown database type %d' % self.db_type)
super(UserDatabase, self).delete(*args, **kwargs)
if not db_user.userdatabase_set.exists():
db_user.delete()