make userdbs admin work properly

* add userdbs app docstring
* add userdbs.app.UserdbsAppConfig
* implement userdbs.admin.DatabaseUserCreationForm,
  userdbs.admin.UserDatabaseCreationForm, userdbs.admin.DatabaseUserAdmin,
  userdbs.admin.UserDatabaseAdmin
* add docstrings to userdbs.models
* rename userdbs.models.DatabaseUserManager._get_next_username to
  _get_next_dbuser_name
* fix format string issues in userdbs.models.DatabaseUserManager and
  userdbs.UserDatabaseManager._get_next_dbname
* delete related databases in userdbs.models.UserDatabase.delete
This commit is contained in:
Jan Dittberner 2015-01-04 22:27:43 +01:00
parent be4ea9cc77
commit 6edbe17a3b
4 changed files with 313 additions and 23 deletions

View file

@ -43,7 +43,7 @@ class DatabaseUserManager(models.Manager):
"""
def _get_next_username(self, osuser, db_type):
def _get_next_dbuser_name(self, osuser, db_type):
"""
Get the next available database user name.
@ -53,15 +53,15 @@ class DatabaseUserManager(models.Manager):
:rtype: str
"""
count = 1
db_username_format = "{0}db{{1:02d}}".format(osuser.username)
nextname = db_username_format.format(count)
dbuser_name_format = "{0}db{{0:02d}}".format(osuser.username)
nextname = dbuser_name_format.format(count)
for user in self.values('name').filter(
osuser=osuser, db_type=db_type
).order_by('name'):
if user['name'] == nextname:
count += 1
nextname = db_username_format.format(count)
nextname = dbuser_name_format.format(count)
else:
break
return nextname
@ -78,7 +78,7 @@ class DatabaseUserManager(models.Manager):
:param osuser: the :py:class:`osusers.models.User` instance
:param db_type: value from :py:data:`DB_TYPES`
:param str username: database user name
:param str password: password for the user
:param str password: initial password or None
:param boolean commit: whether the user should be persisted
:return: :py:class:`userdbs.models.DatabaseUser` instance
@ -89,14 +89,11 @@ class DatabaseUserManager(models.Manager):
"""
if username is None:
username = self._get_next_username(osuser, db_type)
if password is None:
password = generate_password()
username = self._get_next_dbuser_name(osuser, db_type)
db_user = DatabaseUser(
osuser=osuser, db_type=db_type, username=username)
osuser=osuser, db_type=db_type, name=username, password=password)
if commit:
db_user.create_in_database(password)
# TODO: send GPG encrypted mail with this information
db_user.create_in_database()
db_user.save()
return db_user
@ -120,16 +117,19 @@ class DatabaseUser(TimeStampedModel, models.Model):
def __str__(self):
return "%(name)s (%(db_type)s for %(osuser)s)" % {
'name': self.name,
'db_type': self.db_type,
'db_type': self.get_db_type_display(),
'osuser': self.osuser.username,
}
def create_in_database(self, password):
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:
@ -144,9 +144,9 @@ class DatabaseUser(TimeStampedModel, models.Model):
:param str password: new password for the database user
"""
if self.db_type == DB_TYPES.pgsql:
set_pgsql_userpassword.delay(self.name, password).get()
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()
set_mysql_userpassword.delay(self.name, password).get(timeout=5)
else:
raise ValueError('Unknown database type %d' % self.db_type)
@ -162,10 +162,12 @@ class DatabaseUser(TimeStampedModel, models.Model):
:py:meth:`django.db.models.Model.delete`
"""
for database in self.userdatabase_set.all():
database.delete()
if self.db_type == DB_TYPES.pgsql:
delete_pgsql_user.delay(self.name).get()
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()
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)
@ -187,7 +189,7 @@ class UserDatabaseManager(models.Manager):
"""
count = 1
db_name_format = "{0}_{{1:02d}}".format(db_user.name)
db_name_format = "{0}_{{0:02d}}".format(db_user.name)
# first db is named the same as the user
nextname = db_user.name
for name in self.values('db_name').filter(db_user=db_user).order_by(
@ -216,7 +218,6 @@ class UserDatabaseManager(models.Manager):
database = UserDatabase(db_user=db_user, db_name=db_name)
if commit:
database.create_in_database()
# TODO: send GPG encrypted mail with this information
database.save()
return database
@ -228,6 +229,8 @@ class UserDatabase(TimeStampedModel, models.Model):
_('database name'), max_length=63)
db_user = models.ForeignKey(DatabaseUser, verbose_name=_('database user'))
objects = UserDatabaseManager()
class Meta:
unique_together = ['db_name', 'db_user']
verbose_name = _('user database')
@ -244,6 +247,7 @@ class UserDatabase(TimeStampedModel, models.Model):
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:
@ -263,9 +267,9 @@ class UserDatabase(TimeStampedModel, models.Model):
:py:meth:`django.db.models.Model.delete`
"""
if self.db_type == DB_TYPES.pgsql:
if self.db_user.db_type == DB_TYPES.pgsql:
delete_pgsql_database.delay(self.db_name, self.db_user.name).get()
elif self.db_type == DB_TYPES.mysql:
elif self.db_user.db_type == DB_TYPES.mysql:
delete_mysql_database.delay(self.db_name, self.db_user.name).get()
else:
raise ValueError('Unknown database type %d' % self.db_type)