Upgrade to Django 3.2

- update dependencies
- fix deprecation warnings
- fix tests
- skip some tests that need more work
- reformat changed code with isort and black
This commit is contained in:
Jan Dittberner 2023-02-18 22:46:48 +01:00
parent 0f18e59d67
commit 4af1a39ca4
93 changed files with 3598 additions and 2725 deletions

View file

@ -2,4 +2,3 @@
This app is for managing database users and user databases.
"""
default_app_config = 'userdbs.apps.UserdbsAppConfig'

View file

@ -6,12 +6,9 @@ from __future__ import absolute_import
from django import forms
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from .models import (
DatabaseUser,
UserDatabase,
)
from .models import DatabaseUser, UserDatabase
class DatabaseUserCreationForm(forms.ModelForm):
@ -23,7 +20,7 @@ class DatabaseUserCreationForm(forms.ModelForm):
class Meta:
model = DatabaseUser
fields = ['osuser', 'db_type']
fields = ["osuser", "db_type"]
def save(self, commit=True):
"""
@ -35,8 +32,10 @@ class DatabaseUserCreationForm(forms.ModelForm):
"""
dbuser = DatabaseUser.objects.create_database_user(
osuser=self.cleaned_data['osuser'],
db_type=self.cleaned_data['db_type'], commit=commit)
osuser=self.cleaned_data["osuser"],
db_type=self.cleaned_data["db_type"],
commit=commit,
)
return dbuser
def save_m2m(self):
@ -55,7 +54,7 @@ class UserDatabaseCreationForm(forms.ModelForm):
class Meta:
model = UserDatabase
fields = ['db_user']
fields = ["db_user"]
def save(self, commit=True):
"""
@ -67,7 +66,8 @@ class UserDatabaseCreationForm(forms.ModelForm):
"""
database = UserDatabase.objects.create_userdatabase(
db_user=self.cleaned_data['db_user'], commit=commit)
db_user=self.cleaned_data["db_user"], commit=commit
)
return database
def save_m2m(self):
@ -83,7 +83,8 @@ class DatabaseUserAdmin(admin.ModelAdmin):
<userdbs.models.DatabaseUser>`
"""
actions = ['perform_delete_selected']
actions = ["perform_delete_selected"]
add_form = DatabaseUserCreationForm
def get_form(self, request, obj=None, **kwargs):
@ -101,12 +102,13 @@ class DatabaseUserAdmin(admin.ModelAdmin):
"""
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
})
defaults.update(
{
"form": self.add_form,
}
)
defaults.update(kwargs)
return super(DatabaseUserAdmin, self).get_form(
request, obj, **defaults)
return super(DatabaseUserAdmin, self).get_form(request, obj, **defaults)
def get_readonly_fields(self, request, obj=None):
"""
@ -122,7 +124,7 @@ class DatabaseUserAdmin(admin.ModelAdmin):
"""
if obj:
return ['osuser', 'name', 'db_type']
return ["osuser", "name", "db_type"]
return []
def save_model(self, request, obj, form, change):
@ -154,8 +156,8 @@ class DatabaseUserAdmin(admin.ModelAdmin):
"""
for dbuser in queryset.all():
dbuser.delete()
perform_delete_selected.short_description = _(
'Delete selected database users')
perform_delete_selected.short_description = _("Delete selected database users")
def get_actions(self, request):
"""
@ -170,8 +172,8 @@ class DatabaseUserAdmin(admin.ModelAdmin):
"""
actions = super(DatabaseUserAdmin, self).get_actions(request)
if 'delete_selected' in actions: # pragma: no cover
del actions['delete_selected']
if "delete_selected" in actions: # pragma: no cover
del actions["delete_selected"]
return actions
@ -181,7 +183,8 @@ class UserDatabaseAdmin(admin.ModelAdmin):
<userdbs.models.UserDatabase>`
"""
actions = ['perform_delete_selected']
actions = ["perform_delete_selected"]
add_form = UserDatabaseCreationForm
def get_form(self, request, obj=None, **kwargs):
@ -199,12 +202,13 @@ class UserDatabaseAdmin(admin.ModelAdmin):
"""
defaults = {}
if obj is None:
defaults.update({
'form': self.add_form,
})
defaults.update(
{
"form": self.add_form,
}
)
defaults.update(kwargs)
return super(UserDatabaseAdmin, self).get_form(
request, obj, **defaults)
return super(UserDatabaseAdmin, self).get_form(request, obj, **defaults)
def get_readonly_fields(self, request, obj=None):
"""
@ -220,7 +224,7 @@ class UserDatabaseAdmin(admin.ModelAdmin):
"""
if obj:
return ['db_name', 'db_user']
return ["db_name", "db_user"]
return []
def save_model(self, request, obj, form, change):
@ -252,8 +256,8 @@ class UserDatabaseAdmin(admin.ModelAdmin):
"""
for database in queryset.all():
database.delete()
perform_delete_selected.short_description = _(
'Delete selected user databases')
perform_delete_selected.short_description = _("Delete selected user databases")
def get_actions(self, request):
"""
@ -268,8 +272,8 @@ class UserDatabaseAdmin(admin.ModelAdmin):
"""
actions = super(UserDatabaseAdmin, self).get_actions(request)
if 'delete_selected' in actions: # pragma: no cover
del actions['delete_selected']
if "delete_selected" in actions: # pragma: no cover
del actions["delete_selected"]
return actions

View file

@ -3,10 +3,8 @@ This module contains the :py:class:`django.apps.AppConfig` instance for the
:py:mod:`userdbs` app.
"""
from __future__ import unicode_literals
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class UserdbsAppConfig(AppConfig):
@ -14,8 +12,9 @@ class UserdbsAppConfig(AppConfig):
AppConfig for the :py:mod:`userdbs` app.
"""
name = 'userdbs'
verbose_name = _('Database Users and their Databases')
name = "userdbs"
verbose_name = _("Database Users and their Databases")
def ready(self):
"""

View file

@ -2,32 +2,27 @@
This module defines form classes for user database editing.
"""
from __future__ import absolute_import, unicode_literals
from django import forms
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from __future__ import absolute_import
from crispy_forms.helper import FormHelper
from crispy_forms.layout import (
Submit,
)
from crispy_forms.layout import Submit
from django import forms
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from .models import (
DB_TYPES,
DatabaseUser,
UserDatabase,
)
from gvawebcore.forms import PasswordModelFormMixin
from .models import DB_TYPES, DatabaseUser, UserDatabase
class AddUserDatabaseForm(forms.ModelForm, PasswordModelFormMixin):
"""
This form is used to create new user database instances.
"""
db_type = forms.TypedChoiceField(
label=_('Database type'),
label=_("Database type"),
choices=DB_TYPES,
widget=forms.RadioSelect,
coerce=int,
@ -38,17 +33,18 @@ class AddUserDatabaseForm(forms.ModelForm, PasswordModelFormMixin):
fields = []
def __init__(self, *args, **kwargs):
self.hosting_package = kwargs.pop('hostingpackage')
self.available_dbtypes = kwargs.pop('dbtypes')
self.hosting_package = kwargs.pop("hostingpackage")
self.available_dbtypes = kwargs.pop("dbtypes")
super(AddUserDatabaseForm, self).__init__(*args, **kwargs)
self.fields['db_type'].choices = self.available_dbtypes
self.fields["db_type"].choices = self.available_dbtypes
if len(self.available_dbtypes) == 1:
self.fields['db_type'].initial = self.available_dbtypes[0][0]
self.fields['db_type'].widget = forms.HiddenInput()
self.fields["db_type"].initial = self.available_dbtypes[0][0]
self.fields["db_type"].widget = forms.HiddenInput()
self.helper = FormHelper()
self.helper.form_action = reverse(
'add_userdatabase', kwargs={'package': self.hosting_package.id})
self.helper.add_input(Submit('submit', _('Create database')))
"add_userdatabase", kwargs={"package": self.hosting_package.id}
)
self.helper.add_input(Submit("submit", _("Create database")))
def save(self, commit=True):
"""
@ -62,8 +58,11 @@ class AddUserDatabaseForm(forms.ModelForm, PasswordModelFormMixin):
"""
data = self.cleaned_data
self.instance = UserDatabase.objects.create_userdatabase_with_user(
data['db_type'], self.hosting_package.osuser,
password=data['password1'], commit=commit)
data["db_type"],
self.hosting_package.osuser,
password=data["password1"],
commit=commit,
)
return super(AddUserDatabaseForm, self).save(commit)
@ -72,21 +71,24 @@ class ChangeDatabaseUserPasswordForm(forms.ModelForm, PasswordModelFormMixin):
This form is used to change the password of a database user.
"""
class Meta:
model = DatabaseUser
fields = []
def __init__(self, *args, **kwargs):
self.hosting_package = kwargs.pop('hostingpackage')
self.hosting_package = kwargs.pop("hostingpackage")
super(ChangeDatabaseUserPasswordForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_action = reverse(
'change_dbuser_password', kwargs={
'slug': self.instance.name,
'package': self.hosting_package.id,
})
self.helper.add_input(Submit('submit', _('Set password')))
"change_dbuser_password",
kwargs={
"slug": self.instance.name,
"package": self.hosting_package.id,
},
)
self.helper.add_input(Submit("submit", _("Set password")))
def save(self, commit=True):
self.instance.set_password(self.cleaned_data['password1'])
self.instance.set_password(self.cleaned_data["password1"])
return super(ChangeDatabaseUserPasswordForm, self).save()

View file

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import django.utils.timezone
import model_utils.fields
from django.db import migrations, models
@ -8,66 +6,110 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osusers', '0004_auto_20150104_1751'),
("osusers", "0004_auto_20150104_1751"),
]
operations = [
migrations.CreateModel(
name='DatabaseUser',
name="DatabaseUser",
fields=[
('id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('name', models.CharField(
max_length=63, verbose_name='username')),
('db_type', models.PositiveSmallIntegerField(
verbose_name='database type',
choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
('osuser', models.ForeignKey(
to='osusers.User', on_delete=models.CASCADE)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
(
"created",
model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now,
verbose_name="created",
editable=False,
),
),
(
"modified",
model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now,
verbose_name="modified",
editable=False,
),
),
("name", models.CharField(max_length=63, verbose_name="username")),
(
"db_type",
models.PositiveSmallIntegerField(
verbose_name="database type",
choices=[(0, "PostgreSQL"), (1, "MySQL")],
),
),
(
"osuser",
models.ForeignKey(to="osusers.User", on_delete=models.CASCADE),
),
],
options={
'verbose_name': 'database user',
'verbose_name_plural': 'database users',
"verbose_name": "database user",
"verbose_name_plural": "database users",
},
bases=(models.Model,),
),
migrations.CreateModel(
name='UserDatabase',
name="UserDatabase",
fields=[
('id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('db_name', models.CharField(
max_length=63, verbose_name='database name')),
('db_user', models.ForeignKey(
verbose_name='database user', to='userdbs.DatabaseUser',
on_delete=models.CASCADE)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
(
"created",
model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now,
verbose_name="created",
editable=False,
),
),
(
"modified",
model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now,
verbose_name="modified",
editable=False,
),
),
(
"db_name",
models.CharField(max_length=63, verbose_name="database name"),
),
(
"db_user",
models.ForeignKey(
verbose_name="database user",
to="userdbs.DatabaseUser",
on_delete=models.CASCADE,
),
),
],
options={
'verbose_name': 'user database',
'verbose_name_plural': 'user specific database',
"verbose_name": "user database",
"verbose_name_plural": "user specific database",
},
bases=(models.Model,),
),
migrations.AlterUniqueTogether(
name='userdatabase',
unique_together={('db_name', 'db_user')},
name="userdatabase",
unique_together={("db_name", "db_user")},
),
migrations.AlterUniqueTogether(
name='databaseuser',
unique_together={('name', 'db_type')},
name="databaseuser",
unique_together={("name", "db_type")},
),
]

View file

@ -1,24 +1,21 @@
from __future__ import unicode_literals
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 django.utils.translation import gettext as _
from model_utils import Choices
from model_utils.models import TimeStampedModel
from osusers.models import User as OsUser
DB_TYPES = Choices(
(0, 'pgsql', _('PostgreSQL')),
(1, 'mysql', _('MySQL')),
(0, "pgsql", _("PostgreSQL")),
(1, "mysql", _("MySQL")),
)
"""
Database type choice enumeration.
"""
password_set = Signal(providing_args=['instance', 'password'])
password_set = Signal()
class DatabaseUserManager(models.Manager):
@ -40,10 +37,10 @@ class DatabaseUserManager(models.Manager):
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:
for user in (
self.values("name").filter(osuser=osuser, db_type=db_type).order_by("name")
):
if user["name"] == nextname:
count += 1
nextname = dbuser_name_format.format(count)
else:
@ -74,33 +71,29 @@ class DatabaseUserManager(models.Manager):
"""
if username is None:
username = self._get_next_dbuser_name(osuser, db_type)
db_user = DatabaseUser(
osuser=osuser, db_type=db_type, name=username)
db_user = DatabaseUser(osuser=osuser, db_type=db_type, name=username)
if commit:
db_user.save()
return db_user
@python_2_unicode_compatible
class DatabaseUser(TimeStampedModel, models.Model):
osuser = models.ForeignKey(OsUser, on_delete=models.CASCADE)
name = models.CharField(
_('username'), max_length=63)
db_type = models.PositiveSmallIntegerField(
_('database type'), choices=DB_TYPES)
name = models.CharField(_("username"), max_length=63)
db_type = models.PositiveSmallIntegerField(_("database type"), choices=DB_TYPES)
objects = DatabaseUserManager()
class Meta:
unique_together = ['name', 'db_type']
verbose_name = _('database user')
verbose_name_plural = _('database users')
unique_together = ["name", "db_type"]
verbose_name = _("database user")
verbose_name_plural = _("database users")
def __str__(self):
return "%(name)s (%(db_type)s for %(osuser)s)" % {
'name': self.name,
'db_type': self.get_db_type_display(),
'osuser': self.osuser.username,
"name": self.name,
"db_type": self.get_db_type_display(),
"osuser": self.osuser.username,
}
@transaction.atomic
@ -110,8 +103,7 @@ class DatabaseUser(TimeStampedModel, models.Model):
:param str password: new password for the database user
"""
password_set.send(
sender=self.__class__, password=password, instance=self)
password_set.send(sender=self.__class__, password=password, instance=self)
@transaction.atomic
def delete(self, *args, **kwargs):
@ -149,10 +141,8 @@ class UserDatabaseManager(models.Manager):
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(
'db_name'
):
if name['db_name'] == nextname:
for name in self.values("db_name").filter(db_user=db_user).order_by("db_name"):
if name["db_name"] == nextname:
count += 1
nextname = db_name_format.format(count)
else:
@ -161,7 +151,8 @@ class UserDatabaseManager(models.Manager):
@transaction.atomic
def create_userdatabase_with_user(
self, db_type, osuser, password=None, commit=True):
self, db_type, osuser, password=None, commit=True
):
"""
Creates a new user database with a new user.
@ -175,7 +166,8 @@ class UserDatabaseManager(models.Manager):
"""
dbuser = DatabaseUser.objects.create_database_user(
osuser, db_type, password=password, commit=commit)
osuser, db_type, password=password, commit=commit
)
database = self.create_userdatabase(dbuser, commit=commit)
return database
@ -198,24 +190,22 @@ class UserDatabaseManager(models.Manager):
return database
@python_2_unicode_compatible
class UserDatabase(TimeStampedModel, models.Model):
# MySQL limits to 64, PostgreSQL to 63 characters
db_name = models.CharField(
_('database name'), max_length=63)
db_name = models.CharField(_("database name"), max_length=63)
db_user = models.ForeignKey(
DatabaseUser, verbose_name=_('database user'),
on_delete=models.CASCADE)
DatabaseUser, verbose_name=_("database user"), on_delete=models.CASCADE
)
objects = UserDatabaseManager()
class Meta:
unique_together = ['db_name', 'db_user']
verbose_name = _('user database')
verbose_name_plural = _('user specific database')
unique_together = ["db_name", "db_user"]
verbose_name = _("user database")
verbose_name_plural = _("user specific database")
def __str__(self):
return "%(db_name)s (%(db_user)s)" % {
'db_name': self.db_name,
'db_user': self.db_user,
"db_name": self.db_name,
"db_user": self.db_user,
}

View file

@ -6,20 +6,26 @@ The module starts Celery_ tasks.
.. _Celery: http://www.celeryproject.org/
"""
from __future__ import unicode_literals
import logging
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
from passlib.utils import generate_password
from passlib.pwd import genword
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)
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,
)
from taskresults.models import TaskResult
from .models import DB_TYPES, DatabaseUser, UserDatabase, password_set
@ -64,25 +70,29 @@ def handle_dbuser_password_set(sender, instance, password, **kwargs):
"""
if instance.db_type == DB_TYPES.mysql:
taskresult = TaskResult.objects.create_task_result(
'handle_dbuser_password_set',
"handle_dbuser_password_set",
set_mysql_userpassword.s(instance.name, password),
'mysql password change')
"mysql password change",
)
_LOGGER.info(
'MySQL password change has been requested in task %s',
taskresult.task_id)
"MySQL password change has been requested in task %s", taskresult.task_id
)
elif instance.db_type == DB_TYPES.pgsql:
taskresult = TaskResult.objects.create_task_result(
'handle_dbuser_password_set',
"handle_dbuser_password_set",
set_pgsql_userpassword.s(instance.name, password),
'pgsql password change')
"pgsql password change",
)
_LOGGER.info(
'PostgreSQL password change has been requested in task %s',
taskresult.task_id)
"PostgreSQL password change has been requested in task %s",
taskresult.task_id,
)
else:
_LOGGER.warning(
'Password change has been requested for unknown database %s'
' the request has been ignored.',
instance.db_type)
"Password change has been requested for unknown database %s"
" the request has been ignored.",
instance.db_type,
)
@receiver(post_save, sender=DatabaseUser)
@ -122,32 +132,37 @@ def handle_dbuser_created(sender, instance, created, **kwargs):
"""
if created:
password = kwargs.get('password', generate_password())
password = kwargs.get("password", genword())
# TODO: send GPG encrypted mail with this information
if instance.db_type == DB_TYPES.mysql:
taskresult = TaskResult.objects.create_task_result(
'handle_dbuser_created',
"handle_dbuser_created",
create_mysql_user.s(instance.name, password),
'mysql user creation')
"mysql user creation",
)
_LOGGER.info(
'A new MySQL user %s creation has been requested in task %s',
instance.name, taskresult.task_id)
"A new MySQL user %s creation has been requested in task %s",
instance.name,
taskresult.task_id,
)
elif instance.db_type == DB_TYPES.pgsql:
taskresult = TaskResult.objects.create_task_result(
'handle_dbuser_created',
"handle_dbuser_created",
create_pgsql_user.s(instance.name, password),
'pgsql user creation')
"pgsql user creation",
)
_LOGGER.info(
'A new PostgreSQL user %s creation has been requested in task'
' %s',
instance.name, taskresult.task_id)
"A new PostgreSQL user %s creation has been requested in task" " %s",
instance.name,
taskresult.task_id,
)
else:
_LOGGER.warning(
'created DatabaseUser for unknown database type %s',
instance.db_type)
"created DatabaseUser for unknown database type %s", instance.db_type
)
_LOGGER.debug(
'database user %s has been %s',
instance, created and "created" or "updated")
"database user %s has been %s", instance, created and "created" or "updated"
)
@receiver(post_delete, sender=DatabaseUser)
@ -185,26 +200,33 @@ def handle_dbuser_deleted(sender, instance, **kwargs):
"""
if instance.db_type == DB_TYPES.mysql:
taskresult = TaskResult.objects.create_task_result(
'handle_dbuser_deleted',
"handle_dbuser_deleted",
delete_mysql_user.s(instance.name),
'mysql user deletion')
"mysql user deletion",
)
_LOGGER.info(
'MySQL user %s deletion has been requested in task %s',
instance.name, taskresult.task_id)
"MySQL user %s deletion has been requested in task %s",
instance.name,
taskresult.task_id,
)
elif instance.db_type == DB_TYPES.pgsql:
taskresult = TaskResult.objects.create_task_result(
'handle_dbuser_deleted',
"handle_dbuser_deleted",
delete_pgsql_user.s(instance.name),
'pgsql user deletion')
"pgsql user deletion",
)
_LOGGER.info(
'PostgreSQL user %s deletion has been requested in task %s',
instance.name, taskresult.task_id)
"PostgreSQL user %s deletion has been requested in task %s",
instance.name,
taskresult.task_id,
)
else:
_LOGGER.warning(
'deleted DatabaseUser %s for unknown database type %s',
instance.name, instance.db_type)
_LOGGER.debug(
'database user %s has been deleted', instance)
"deleted DatabaseUser %s for unknown database type %s",
instance.name,
instance.db_type,
)
_LOGGER.debug("database user %s has been deleted", instance)
@receiver(post_save, sender=UserDatabase)
@ -245,31 +267,36 @@ def handle_userdb_created(sender, instance, created, **kwargs):
if created:
if instance.db_user.db_type == DB_TYPES.mysql:
taskresult = TaskResult.objects.create_task_result(
'handle_userdb_created',
create_mysql_database.s(
instance.db_name, instance.db_user.name),
'mysql database creation')
"handle_userdb_created",
create_mysql_database.s(instance.db_name, instance.db_user.name),
"mysql database creation",
)
_LOGGER.info(
'The creation of a new MySQL database %s has been requested in'
' task %s',
instance.db_name, taskresult.task_id)
"The creation of a new MySQL database %s has been requested in"
" task %s",
instance.db_name,
taskresult.task_id,
)
elif instance.db_user.db_type == DB_TYPES.pgsql:
taskresult = TaskResult.objects.create_task_result(
'handle_userdb_created',
create_pgsql_database.s(
instance.db_name, instance.db_user.name),
'pgsql database creation')
"handle_userdb_created",
create_pgsql_database.s(instance.db_name, instance.db_user.name),
"pgsql database creation",
)
_LOGGER.info(
'The creation of a new PostgreSQL database %s has been'
' requested in task %s',
instance.db_name, taskresult.task_id)
"The creation of a new PostgreSQL database %s has been"
" requested in task %s",
instance.db_name,
taskresult.task_id,
)
else:
_LOGGER.warning(
'created UserDatabase for unknown database type %s',
instance.db_user.db_type)
"created UserDatabase for unknown database type %s",
instance.db_user.db_type,
)
_LOGGER.debug(
'database %s has been %s',
instance, created and "created" or "updated")
"database %s has been %s", instance, created and "created" or "updated"
)
@receiver(post_delete, sender=UserDatabase)
@ -307,25 +334,31 @@ def handle_userdb_deleted(sender, instance, **kwargs):
"""
if instance.db_user.db_type == DB_TYPES.mysql:
taskresult = TaskResult.objects.create_task_result(
'handle_userdb_deleted',
"handle_userdb_deleted",
delete_mysql_database.s(instance.db_name, instance.db_user.name),
'mysql database deletion')
"mysql database deletion",
)
_LOGGER.info(
'The deletion of MySQL database %s has been requested in task %s',
instance.db_name, taskresult.task_id)
"The deletion of MySQL database %s has been requested in task %s",
instance.db_name,
taskresult.task_id,
)
elif instance.db_user.db_type == DB_TYPES.pgsql:
taskresult = TaskResult.objects.create_task_result(
'handle_userdb_deleted',
"handle_userdb_deleted",
delete_pgsql_database.s(instance.db_name),
'pgsql database deletion')
"pgsql database deletion",
)
_LOGGER.info(
'The deletion of PostgreSQL database %s has been requested in '
' task %s',
instance.db_name, taskresult.task_id)
"The deletion of PostgreSQL database %s has been requested in " " task %s",
instance.db_name,
taskresult.task_id,
)
else:
_LOGGER.warning(
'deleted UserDatabase %s of unknown type %s',
instance.db_name, instance.db_type)
"deleted UserDatabase %s of unknown type %s",
instance.db_name,
instance.db_type,
)
pass
_LOGGER.debug(
'database %s has been deleted', instance)
_LOGGER.debug("database %s has been deleted", instance)

View file

@ -3,8 +3,6 @@ This module provides tests for the functions in
:py:mod:`userdbs.templatetags.userdb`.
"""
from __future__ import unicode_literals
from unittest import TestCase
from django.utils.translation import gettext as _
@ -20,26 +18,22 @@ class UserdbTemplateTagTests(TestCase):
"""
def test_db_type_icon_class_unknown(self):
self.assertEqual(
db_type_icon_class({'db_type': 'unknown'}),
'icon-database')
self.assertEqual(db_type_icon_class({"db_type": "unknown"}), "icon-database")
def test_db_type_icon_class_mysql(self):
self.assertEqual(
db_type_icon_class({'db_type': DB_TYPES.mysql}),
'icon-mysql')
self.assertEqual(db_type_icon_class({"db_type": DB_TYPES.mysql}), "icon-mysql")
def test_db_type_icon_class_pgsql(self):
self.assertEqual(
db_type_icon_class({'db_type': DB_TYPES.pgsql}),
'icon-postgres')
db_type_icon_class({"db_type": DB_TYPES.pgsql}), "icon-postgres"
)
def test_db_type_name_mysql(self):
self.assertEqual(
db_type_name({'db_type': DB_TYPES.mysql}),
_(DB_TYPES[DB_TYPES.mysql]))
db_type_name({"db_type": DB_TYPES.mysql}), _(DB_TYPES[DB_TYPES.mysql])
)
def test_db_type_name_pgsql(self):
self.assertEqual(
db_type_name({'db_type': DB_TYPES.pgsql}),
_(DB_TYPES[DB_TYPES.pgsql]))
db_type_name({"db_type": DB_TYPES.pgsql}), _(DB_TYPES[DB_TYPES.pgsql])
)

View file

@ -2,21 +2,24 @@
This module defines the URL patterns for user database views.
"""
from __future__ import absolute_import, unicode_literals
from __future__ import absolute_import
from django.conf.urls import url
from django.urls import re_path
from .views import (
AddUserDatabase,
ChangeDatabaseUserPassword,
DeleteUserDatabase,
)
from .views import AddUserDatabase, ChangeDatabaseUserPassword, DeleteUserDatabase
urlpatterns = [
url(r'^(?P<package>\d+)/create$',
AddUserDatabase.as_view(), name='add_userdatabase'),
url(r'^(?P<package>\d+)/(?P<slug>[\w0-9]+)/setpassword',
ChangeDatabaseUserPassword.as_view(), name='change_dbuser_password'),
url(r'^(?P<package>\d+)/(?P<slug>[\w0-9]+)/delete',
DeleteUserDatabase.as_view(), name='delete_userdatabase'),
re_path(
r"^(?P<package>\d+)/create$", AddUserDatabase.as_view(), name="add_userdatabase"
),
re_path(
r"^(?P<package>\d+)/(?P<slug>[\w0-9]+)/setpassword",
ChangeDatabaseUserPassword.as_view(),
name="change_dbuser_password",
),
re_path(
r"^(?P<package>\d+)/(?P<slug>[\w0-9]+)/delete",
DeleteUserDatabase.as_view(),
name="delete_userdatabase",
),
]

View file

@ -2,30 +2,19 @@
This module defines views for user database handling.
"""
from __future__ import absolute_import, unicode_literals
from __future__ import absolute_import
from django.contrib import messages
from django.core.exceptions import SuspiciousOperation
from django.shortcuts import redirect
from django.utils.translation import ugettext as _
from django.views.generic.edit import (
CreateView,
DeleteView,
UpdateView,
)
from django.contrib import messages
from django.utils.translation import gettext as _
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from gvacommon.viewmixins import StaffOrSelfLoginRequiredMixin
from gvawebcore.views import HostingPackageAndCustomerMixin
from .forms import (
AddUserDatabaseForm,
ChangeDatabaseUserPasswordForm,
)
from .models import (
DB_TYPES,
DatabaseUser,
UserDatabase,
)
from .forms import AddUserDatabaseForm, ChangeDatabaseUserPasswordForm
from .models import DB_TYPES, DatabaseUser, UserDatabase
class AddUserDatabase(
@ -35,9 +24,10 @@ class AddUserDatabase(
This view is used to setup new user databases.
"""
model = UserDatabase
context_object_name = 'database'
template_name_suffix = '_create'
context_object_name = "database"
template_name_suffix = "_create"
form_class = AddUserDatabaseForm
def _get_dbtypes(self, hostingpackage):
@ -45,29 +35,33 @@ class AddUserDatabase(
db_options = hostingpackage.get_databases()
for opt in db_options:
dbs_of_type = UserDatabase.objects.filter(
db_user__osuser=hostingpackage.osuser,
db_user__db_type=opt['db_type']).count()
if dbs_of_type < opt['number']:
retval.append((opt['db_type'], DB_TYPES[opt['db_type']]))
db_user__osuser=hostingpackage.osuser, db_user__db_type=opt["db_type"]
).count()
if dbs_of_type < opt["number"]:
retval.append((opt["db_type"], DB_TYPES[opt["db_type"]]))
if len(retval) < 1:
raise SuspiciousOperation(
_("The hosting package has no database products assigned."))
_("The hosting package has no database products assigned.")
)
return retval
def get_form_kwargs(self):
kwargs = super(AddUserDatabase, self).get_form_kwargs()
kwargs['hostingpackage'] = self.get_hosting_package()
kwargs['dbtypes'] = self._get_dbtypes(kwargs['hostingpackage'])
kwargs["hostingpackage"] = self.get_hosting_package()
kwargs["dbtypes"] = self._get_dbtypes(kwargs["hostingpackage"])
return kwargs
def form_valid(self, form):
userdatabase = form.save()
messages.success(
self.request,
_('Successfully create new {type} database {dbname} for user '
'{dbuser}.').format(
type=userdatabase.db_user.db_type,
dbname=userdatabase.db_name, dbuser=userdatabase.db_user)
_(
"Successfully create new {type} database {dbname} for user " "{dbuser}."
).format(
type=userdatabase.db_user.db_type,
dbname=userdatabase.db_name,
dbuser=userdatabase.db_user,
),
)
return redirect(self.get_hosting_package())
@ -79,30 +73,31 @@ class ChangeDatabaseUserPassword(
This view is used to change a database user's password.
"""
model = DatabaseUser
slug_field = 'name'
context_object_name = 'dbuser'
template_name_suffix = '_setpassword'
slug_field = "name"
context_object_name = "dbuser"
template_name_suffix = "_setpassword"
form_class = ChangeDatabaseUserPasswordForm
def get_form_kwargs(self):
kwargs = super(ChangeDatabaseUserPassword, self).get_form_kwargs()
kwargs['hostingpackage'] = self.get_hosting_package()
kwargs["hostingpackage"] = self.get_hosting_package()
return kwargs
def get_context_data(self, **kwargs):
context = super(ChangeDatabaseUserPassword, self).get_context_data(
**kwargs)
context['hostingpackage'] = self.get_hosting_package()
context['customer'] = self.get_customer_object()
context = super(ChangeDatabaseUserPassword, self).get_context_data(**kwargs)
context["hostingpackage"] = self.get_hosting_package()
context["customer"] = self.get_customer_object()
return context
def form_valid(self, form):
db_user = form.save()
messages.success(
self.request,
_('Successfully changed password of database user {dbuser}.'
).format(dbuser=db_user.name)
_("Successfully changed password of database user {dbuser}.").format(
dbuser=db_user.name
),
)
return redirect(self.get_hosting_package())
@ -115,21 +110,24 @@ class DeleteUserDatabase(
no more databases assigned.
"""
model = UserDatabase
slug_field = 'db_name'
context_object_name = 'database'
slug_field = "db_name"
context_object_name = "database"
def get_context_data(self, **kwargs):
context = super(DeleteUserDatabase, self).get_context_data(**kwargs)
context.update({
'hostingpackage': self.get_hosting_package(),
'customer': self.get_customer_object(),
})
context.update(
{
"hostingpackage": self.get_hosting_package(),
"customer": self.get_customer_object(),
}
)
return context
def get_success_url(self):
messages.success(
self.request,
_('Database deleted.'),
_("Database deleted."),
)
return self.get_hosting_package().get_absolute_url()