Browse Source

Started port to Django 2.1, Python 3, Docker

This commit is a rough port to Django 2.1, Python 3 and a Docker based local
development setup. Tests fail/error but migrations and the web frontend are
already runnable. Task queue functionality is untested and translations seem to
have trouble.
master
Jan Dittberner 3 years ago
parent
commit
6cebd80c89
  1. 2
      .gitignore
  2. 31
      Dockerfile
  3. 4
      Pipfile
  4. 20
      Pipfile.lock
  5. 26
      Vagrantfile
  6. 43
      docker-compose.yml
  7. 8
      gnuviechadmin.sh
  8. 2
      gnuviechadmin/contact_form/forms.py
  9. 4
      gnuviechadmin/contact_form/views.py
  10. 2
      gnuviechadmin/domains/forms.py
  11. 40
      gnuviechadmin/domains/migrations/0002_auto_20150124_1909.py
  12. 96
      gnuviechadmin/domains/migrations/0003_auto_20151105_2133.py
  13. 19
      gnuviechadmin/domains/models.py
  14. 7
      gnuviechadmin/domains/views.py
  15. 169
      gnuviechadmin/gnuviechadmin/settings.py
  16. 3
      gnuviechadmin/gnuviechadmin/settings/__init__.py
  17. 68
      gnuviechadmin/gnuviechadmin/settings/local.py
  18. 40
      gnuviechadmin/gnuviechadmin/settings/production.py
  19. 29
      gnuviechadmin/gnuviechadmin/settings/test.py
  20. 9
      gnuviechadmin/gnuviechadmin/urls.py
  21. 2
      gnuviechadmin/hostingpackages/forms.py
  22. 208
      gnuviechadmin/hostingpackages/migrations/0001_initial.py
  23. 241
      gnuviechadmin/hostingpackages/migrations/0001_squashed_0005_auto_20150118_1303.py
  24. 31
      gnuviechadmin/hostingpackages/migrations/0002_auto_20150118_1149.py
  25. 10
      gnuviechadmin/hostingpackages/migrations/0003_auto_20150118_1407.py
  26. 7
      gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackage_osuser.py
  27. 24
      gnuviechadmin/hostingpackages/migrations/0004_customerhostingpackagedomain.py
  28. 7
      gnuviechadmin/hostingpackages/migrations/0005_auto_20150118_1303.py
  29. 56
      gnuviechadmin/hostingpackages/models.py
  30. 2
      gnuviechadmin/managemails/forms.py
  31. 69
      gnuviechadmin/managemails/migrations/0001_initial.py
  32. 11
      gnuviechadmin/managemails/migrations/0003_auto_20150124_2029.py
  33. 7
      gnuviechadmin/managemails/migrations/0004_auto_20150125_1825.py
  34. 13
      gnuviechadmin/managemails/models.py
  35. 4
      gnuviechadmin/osusers/forms.py
  36. 158
      gnuviechadmin/osusers/migrations/0001_initial.py
  37. 5
      gnuviechadmin/osusers/migrations/0003_user_customer.py
  38. 7
      gnuviechadmin/osusers/migrations/0004_auto_20150104_1751.py
  39. 31
      gnuviechadmin/osusers/migrations/0005_auto_20150131_2009.py
  40. 17
      gnuviechadmin/osusers/models.py
  41. 2
      gnuviechadmin/osusers/views.py
  42. 2
      gnuviechadmin/userdbs/forms.py
  43. 48
      gnuviechadmin/userdbs/migrations/0001_initial.py
  44. 6
      gnuviechadmin/userdbs/models.py
  45. 2
      gnuviechadmin/websites/forms.py
  46. 23
      gnuviechadmin/websites/migrations/0001_initial.py
  47. 5
      gnuviechadmin/websites/models.py
  48. 39
      salt/bootstrap.sh

2
.gitignore

@ -48,3 +48,5 @@ _build/
gnuviechadmin/assets/
coverage-report/
.idea/
.env

31
Dockerfile

@ -0,0 +1,31 @@
FROM debian:stretch
LABEL maintainer "Jan Dittberner <jan@dittberner.info>"
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
dumb-init \
gettext \
git \
libpq-dev \
python3-dev \
python3-pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*.*
VOLUME /srv/gnuviechadmin/media /srv/gnuviechadmin/static
WORKDIR /srv/gnuviechadmin
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
RUN python3 -m pip install -U pip && pip3 install pipenv
COPY gnuviechadmin.sh /srv/
COPY Pipfile Pipfile.lock /srv/gnuviechadmin/
RUN pipenv install --system --deploy --ignore-pipfile --dev
EXPOSE 8000
VOLUME /srv/gnuviechadmin
ENTRYPOINT ["dumb-init", "/srv/gnuviechadmin.sh"]

4
Pipfile

@ -13,6 +13,8 @@ redis = "*"
gvacommon = {ref = "0.4.0", git = "https://git.dittberner.info/gnuviech/gvacommon.git"}
requests-oauthlib = "*"
django-allauth = "*"
django-crispy-forms = "*"
django-braces = "*"
[dev-packages]
coverage = "*"
@ -23,4 +25,4 @@ sphinxcontrib-blockdiag = "*"
pylama = "*"
[requires]
python_version = "3.6"
python_version = "3.5"

20
Pipfile.lock

@ -1,11 +1,11 @@
{
"_meta": {
"hash": {
"sha256": "ed0a23d288cc817ebfbf92a4acd140eee9e083d6331eaa5f06bdbc0d37c4767f"
"sha256": "3b941559bcaf1c164285aef53553496fbf1414f362da1433b705ac7c796e33e6"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
"python_version": "3.5"
},
"sources": [
{
@ -73,6 +73,22 @@
"index": "pypi",
"version": "==0.38.0"
},
"django-braces": {
"hashes": [
"sha256:a457d74ea29478123c0c4652272681b3cea0bf1232187fd9f9b6f1d97d32a890",
"sha256:ba68e98b817c6f01d71d10849f359979617b3fe4cefb7f289adefddced092ddc"
],
"index": "pypi",
"version": "==1.13.0"
},
"django-crispy-forms": {
"hashes": [
"sha256:5952bab971110d0b86c278132dae0aa095beee8f723e625c3d3fa28888f1675f",
"sha256:705ededc554ad8736157c666681165fe22ead2dec0d5446d65fc9dd976a5a876"
],
"index": "pypi",
"version": "==1.7.2"
},
"django-model-utils": {
"hashes": [
"sha256:2c057f3bf0859aba27f04389f0cedd2d48f8c9b3848acb86fd9970794e58f477",

26
Vagrantfile

@ -1,26 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "debian/stretch64"
config.vm.hostname = "gva.local"
config.vm.network "private_network", ip: "172.16.3.2", lxc__bridge_name: 'vlxcbr1'
config.vm.network "forwarded_port", guest: 443, host: 8443
config.vm.network "forwarded_port", guest: 8000, host: 8000
config.vm.network "forwarded_port", guest: 15672, host: 15672
config.vm.synced_folder "../gvasalt/states/", "/srv/salt/"
config.vm.synced_folder "../gvasalt/pillar/", "/srv/pillar/"
config.vm.provision :salt do |salt|
salt.bootstrap_script = "salt/bootstrap.sh"
salt.minion_id = "gva.local"
salt.masterless = true
salt.run_highstate = true
salt.verbose = true
salt.colorize = true
salt.log_level = "warning"
end
end

43
docker-compose.yml

@ -0,0 +1,43 @@
version: "3"
services:
db:
image: gnuviech/pgsql:stretch
ports:
- "15432:5432"
env_file: .env
volumes:
- "pg_data:/var/lib/postgresql/9.6/main"
mq:
image: gnuviech/mq:stretch
env_file: .env
volumes:
- "mq_data:/var/lib/rabbitmq/mnesia"
redis:
image: gnuviech/redis:stretch
env_file: .env
volumes:
- "redis_data:/var/lib/redis"
gva:
build:
context: .
ports:
- "8000:8000"
depends_on:
- db
- mq
- redis
env_file: .env
environment:
DJANGO_SETTINGS_MODULE: gnuviechadmin.settings
GVA_DOMAIN_NAME: localhost
GVA_SITE_NAME: localhost
volumes:
- "django_media:/srv/gnuviechadmin/media"
- "django_static:/srv/gnuviechadmin/static"
- "./gnuviechadmin:/srv/gnuviechadmin"
volumes:
django_media:
django_static:
pg_data:
redis_data:
mq_data:

8
gnuviechadmin.sh

@ -0,0 +1,8 @@
#!/bin/sh
set -e
python3 manage.py compilemessages
python3 manage.py collectstatic --noinput
python3 manage.py migrate --noinput
python3 manage.py runserver 0.0.0.0:8000

2
gnuviechadmin/contact_form/forms.py

@ -7,9 +7,9 @@ from __future__ import absolute_import, unicode_literals
from django import forms
from django.conf import settings
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.template import loader
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.contrib.sites.models import Site

4
gnuviechadmin/contact_form/views.py

@ -5,7 +5,7 @@ This module defines the views of the contact_form app.
from __future__ import absolute_import, unicode_literals
from django.shortcuts import redirect
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.views.generic import (
FormView,
TemplateView,
@ -31,7 +31,7 @@ class ContactFormView(FormView):
def get_initial(self):
initial = super(ContactFormView, self).get_initial()
currentuser = self.request.user
if currentuser.is_authenticated():
if currentuser.is_authenticated:
initial['name'] = (
currentuser.get_full_name() or currentuser.username)
initial['email'] = currentuser.email

2
gnuviechadmin/domains/forms.py

@ -7,7 +7,7 @@ from __future__ import absolute_import, unicode_literals
import re
from django import forms
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.utils.translation import ugettext as _
from crispy_forms.helper import FormHelper

40
gnuviechadmin/domains/migrations/0002_auto_20150124_1909.py

@ -8,7 +8,6 @@ import model_utils.fields
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('domains', '0001_initial'),
@ -18,12 +17,31 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='HostingDomain',
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)),
('domain', models.CharField(unique=True, max_length=128, verbose_name='domain name')),
('customer', models.ForeignKey(verbose_name='customer', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
('maildomain', models.OneToOneField(null=True, to='domains.MailDomain', blank=True, help_text='assigned mail domain for this domain', verbose_name='mail domain')),
('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)),
('domain',
models.CharField(
unique=True, max_length=128, verbose_name='domain name')),
('customer',
models.ForeignKey(
verbose_name='customer', blank=True,
to=settings.AUTH_USER_MODEL, null=True,
on_delete=models.CASCADE)),
('maildomain',
models.OneToOneField(
null=True, to='domains.MailDomain', blank=True,
help_text='assigned mail domain for this domain',
verbose_name='mail domain',
on_delete=models.CASCADE)),
],
options={
'verbose_name': 'Hosting domain',
@ -34,13 +52,17 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='maildomain',
name='customer',
field=models.ForeignKey(verbose_name='customer', blank=True, to=settings.AUTH_USER_MODEL, null=True),
field=models.ForeignKey(
verbose_name='customer', blank=True,
to=settings.AUTH_USER_MODEL, null=True,
on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AlterField(
model_name='maildomain',
name='domain',
field=models.CharField(unique=True, max_length=128, verbose_name='domain name'),
field=models.CharField(
unique=True, max_length=128, verbose_name='domain name'),
preserve_default=True,
),
]

96
gnuviechadmin/domains/migrations/0003_auto_20151105_2133.py

@ -8,7 +8,6 @@ import model_utils.fields
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('domains', '0002_auto_20150124_1909'),
@ -18,22 +17,29 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='DNSComment',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('id', models.AutoField(
verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
('name', models.CharField(max_length=255)),
('commenttype', models.CharField(max_length=10, db_column='type')),
('commenttype',
models.CharField(max_length=10, db_column='type')),
('modified_at', models.IntegerField()),
('comment', models.CharField(max_length=65535)),
('customer', models.ForeignKey(verbose_name='customer', to=settings.AUTH_USER_MODEL)),
('customer', models.ForeignKey(
verbose_name='customer',
to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
],
),
migrations.RunSQL(
'''ALTER TABLE domains_dnscomment ADD CONSTRAINT c_lowercase_name
CHECK (((name)::TEXT = LOWER((name)::TEXT)))'''
CHECK (((name)::TEXT = LOWER((name)::TEXT)))'''
),
migrations.CreateModel(
name='DNSCryptoKey',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('id', models.AutoField(
verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
('flags', models.IntegerField()),
('active', models.BooleanField(default=True)),
('content', models.TextField()),
@ -42,15 +48,30 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='DNSDomain',
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)),
('domain', models.CharField(unique=True, max_length=255, verbose_name='domain name')),
('master', models.CharField(max_length=128, null=True, blank=True)),
('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)),
('domain', models.CharField(
unique=True, max_length=255, verbose_name='domain name')),
('master',
models.CharField(max_length=128, null=True, blank=True)),
('last_check', models.IntegerField(null=True)),
('domaintype', models.CharField(max_length=6, db_column='type', choices=[('MASTER', 'Master'), ('SLAVE', 'Slave'), ('NATIVE', 'Native')])),
('domaintype', models.CharField(
max_length=6, db_column='type',
choices=[('MASTER', 'Master'),
('SLAVE', 'Slave'),
('NATIVE', 'Native')])),
('notified_serial', models.IntegerField(null=True)),
('customer', models.ForeignKey(verbose_name='customer', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
('customer', models.ForeignKey(
verbose_name='customer', blank=True,
to=settings.AUTH_USER_MODEL, null=True,
on_delete=models.CASCADE)),
],
options={
'verbose_name': 'DNS domain',
@ -64,26 +85,35 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='DNSDomainMetadata',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('id', models.AutoField(
verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
('kind', models.CharField(max_length=32)),
('content', models.TextField()),
('domain', models.ForeignKey(to='domains.DNSDomain')),
('domain', models.ForeignKey(
to='domains.DNSDomain', on_delete=models.CASCADE)),
],
),
migrations.CreateModel(
name='DNSRecord',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(db_index=True, max_length=255, null=True, blank=True)),
('recordtype', models.CharField(max_length=10, null=True, db_column='type', blank=True)),
('content', models.CharField(max_length=65535, null=True, blank=True)),
('id', models.AutoField(
verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
('name', models.CharField(
db_index=True, max_length=255, null=True, blank=True)),
('recordtype', models.CharField(
max_length=10, null=True, db_column='type', blank=True)),
('content', models.CharField(
max_length=65535, null=True, blank=True)),
('ttl', models.IntegerField(null=True)),
('prio', models.IntegerField(null=True)),
('change_date', models.IntegerField(null=True)),
('disabled', models.BooleanField(default=False)),
('ordername', models.CharField(max_length=255)),
('auth', models.BooleanField(default=True)),
('domain', models.ForeignKey(to='domains.DNSDomain')),
('domain', models.ForeignKey(
to='domains.DNSDomain', on_delete=models.CASCADE)),
],
options={
'verbose_name': 'DNS record',
@ -101,16 +131,22 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='DNSSupermaster',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('id', models.AutoField(
verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
('ip', models.GenericIPAddressField()),
('nameserver', models.CharField(max_length=255)),
('customer', models.ForeignKey(verbose_name='customer', to=settings.AUTH_USER_MODEL)),
('customer', models.ForeignKey(
verbose_name='customer', to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
],
),
migrations.CreateModel(
name='DNSTSIGKey',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('id', models.AutoField(
verbose_name='ID', serialize=False,
auto_created=True, primary_key=True)),
('name', models.CharField(max_length=255)),
('algorithm', models.CharField(max_length=50)),
('secret', models.CharField(max_length=255)),
@ -123,22 +159,26 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='hostingdomain',
name='domain',
field=models.CharField(unique=True, max_length=255, verbose_name='domain name'),
field=models.CharField(
unique=True, max_length=255, verbose_name='domain name'),
),
migrations.AlterField(
model_name='maildomain',
name='domain',
field=models.CharField(unique=True, max_length=255, verbose_name='domain name'),
field=models.CharField(
unique=True, max_length=255, verbose_name='domain name'),
),
migrations.AddField(
model_name='dnscryptokey',
name='domain',
field=models.ForeignKey(to='domains.DNSDomain'),
field=models.ForeignKey(
to='domains.DNSDomain', on_delete=models.CASCADE),
),
migrations.AddField(
model_name='dnscomment',
name='domain',
field=models.ForeignKey(to='domains.DNSDomain'),
field=models.ForeignKey(
to='domains.DNSDomain', on_delete=models.CASCADE),
),
migrations.AlterUniqueTogether(
name='dnssupermaster',
@ -154,6 +194,6 @@ class Migration(migrations.Migration):
),
migrations.AlterIndexTogether(
name='dnscomment',
index_together=set([('name', 'commenttype'), ('domain', 'modified_at')]),
index_together={('name', 'commenttype'), ('domain', 'modified_at')},
),
]

19
gnuviechadmin/domains/models.py

@ -58,7 +58,7 @@ class DomainBase(TimeStampedModel):
domain = models.CharField(_('domain name'), max_length=255, unique=True)
customer = models.ForeignKey(
settings.AUTH_USER_MODEL, verbose_name=_('customer'), blank=True,
null=True)
null=True, on_delete=models.CASCADE)
class Meta:
abstract = True
@ -119,7 +119,8 @@ class HostingDomain(DomainBase):
"""
maildomain = models.OneToOneField(
MailDomain, verbose_name=_('mail domain'), blank=True, null=True,
help_text=_('assigned mail domain for this domain')
help_text=_('assigned mail domain for this domain'),
on_delete=models.CASCADE,
)
objects = HostingDomainManager()
@ -208,7 +209,7 @@ class DNSRecord(models.Model):
domain_id, ordername text_pattern_ops);
"""
domain = models.ForeignKey('DNSDomain')
domain = models.ForeignKey('DNSDomain', on_delete=models.CASCADE)
name = models.CharField(
max_length=255, blank=True, null=True, db_index=True)
recordtype = models.CharField(
@ -255,7 +256,8 @@ class DNSSupermaster(models.Model):
nameserver = models.CharField(max_length=255)
# account is replaced by customer
customer = models.ForeignKey(
settings.AUTH_USER_MODEL, verbose_name=_('customer'))
settings.AUTH_USER_MODEL, verbose_name=_('customer'),
on_delete=models.CASCADE)
class Meta:
verbose_name = _('DNS supermaster')
@ -299,13 +301,14 @@ class DNSComment(models.Model):
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
"""
domain = models.ForeignKey('DNSDomain')
domain = models.ForeignKey('DNSDomain', on_delete=models.CASCADE)
name = models.CharField(max_length=255)
commenttype = models.CharField(max_length=10, db_column='type')
modified_at = models.IntegerField()
# account is replaced by customer
customer = models.ForeignKey(
settings.AUTH_USER_MODEL, verbose_name=_('customer'))
settings.AUTH_USER_MODEL, verbose_name=_('customer'),
on_delete=models.CASCADE)
comment = models.CharField(max_length=65535)
# check constraint is added via RunSQL in migration
@ -343,7 +346,7 @@ class DNSDomainMetadata(models.Model):
CREATE INDEX domainidmetaindex ON domainmetadata(domain_id);
"""
domain = models.ForeignKey('DNSDomain')
domain = models.ForeignKey('DNSDomain', on_delete=models.CASCADE)
kind = models.CharField(max_length=32, choices=DNS_DOMAIN_METADATA_KINDS)
content = models.TextField()
@ -376,7 +379,7 @@ class DNSCryptoKey(models.Model):
CREATE INDEX domainidindex ON cryptokeys(domain_id);
"""
domain = models.ForeignKey('DNSDomain')
domain = models.ForeignKey('DNSDomain', on_delete=models.CASCADE)
flags = models.IntegerField()
active = models.BooleanField(default=True)
content = models.TextField()

7
gnuviechadmin/domains/views.py

@ -4,16 +4,13 @@ This module defines views related to domains.
"""
from __future__ import absolute_import, unicode_literals
from braces.views import StaffuserRequiredMixin
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import redirect, get_object_or_404
from django.views.generic.edit import CreateView
from django.utils.translation import ugettext as _
from django.contrib import messages
from braces.views import (
LoginRequiredMixin,
StaffuserRequiredMixin,
)
from hostingpackages.models import CustomerHostingPackage
from .forms import CreateHostingDomainForm

169
gnuviechadmin/gnuviechadmin/settings/base.py → gnuviechadmin/gnuviechadmin/settings.py

@ -38,7 +38,8 @@ DEBUG = False
# ######### MANAGER CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = (
(get_env_variable('GVA_ADMIN_NAME'), get_env_variable('GVA_ADMIN_EMAIL')),
(get_env_variable('GVA_ADMIN_NAME', default='Admin'),
get_env_variable('GVA_ADMIN_EMAIL', default='admin@example.org')),
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#managers
@ -50,12 +51,12 @@ MANAGERS = ADMINS
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': get_env_variable('GVA_PGSQL_DATABASE'),
'USER': get_env_variable('GVA_PGSQL_USER'),
'ENGINE': 'django.db.backends.postgresql',
'NAME': get_env_variable('GVA_PGSQL_DATABASE', default='gnuviechadmin'),
'USER': get_env_variable('GVA_PGSQL_USER', default='gnuviechadmin'),
'PASSWORD': get_env_variable('GVA_PGSQL_PASSWORD'),
'HOST': get_env_variable('GVA_PGSQL_HOSTNAME'),
'PORT': get_env_variable('GVA_PGSQL_PORT'),
'HOST': get_env_variable('GVA_PGSQL_HOSTNAME', default='db'),
'PORT': get_env_variable('GVA_PGSQL_PORT', int, default=5432),
}
}
# ######### END DATABASE CONFIGURATION
@ -98,16 +99,13 @@ MEDIA_URL = '/media/'
# ######### END MEDIA CONFIGURATION
# ######### STATIC FILE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = normpath(join(SITE_ROOT, 'assets'))
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = '/static/'
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS # noqa
STATICFILES_DIRS = (
normpath(join(SITE_ROOT, 'static')),
normpath(join(SITE_ROOT, 'gnuviechadmin', 'assets')),
)
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders # noqa
@ -146,7 +144,7 @@ TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
normpath(join(SITE_ROOT, 'templates')),
normpath(join(DJANGO_ROOT, 'templates')),
],
'APP_DIRS': True,
'OPTIONS': {
@ -171,7 +169,7 @@ TEMPLATES = [
# ######### MIDDLEWARE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes
MIDDLEWARE_CLASSES = (
MIDDLEWARE = [
# Default Django middleware.
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
@ -181,7 +179,7 @@ MIDDLEWARE_CLASSES = (
# uncomment next line to enable translation to browser locale
'django.middleware.locale.LocaleMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
]
# ######### END MIDDLEWARE CONFIGURATION
@ -330,8 +328,12 @@ WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
# ######### CELERY CONFIGURATION
BROKER_URL = get_env_variable('GVA_BROKER_URL')
CELERY_RESULT_BACKEND = get_env_variable('GVA_RESULTS_REDIS_URL')
BROKER_URL = get_env_variable(
'GVA_BROKER_URL',
default='amqp://gnuviechadmin:gnuviechadmin@mq/gnuviechadmin')
CELERY_RESULT_BACKEND = get_env_variable(
'GVA_RESULTS_REDIS_URL',
default='redis://:gnuviechadmin@redis:6379/0')
CELERY_TASK_RESULT_EXPIRES = None
CELERY_ROUTES = (
'gvacommon.celeryrouters.GvaRouter',
@ -345,17 +347,134 @@ CELERY_RESULT_SERIALIZER = 'json'
# ######### CUSTOM APP CONFIGURATION
OSUSER_MINUID = int(get_env_variable('GVA_MIN_OS_UID'))
OSUSER_MINGID = int(get_env_variable('GVA_MIN_OS_GID'))
OSUSER_USERNAME_PREFIX = get_env_variable('GVA_OSUSER_PREFIX')
OSUSER_HOME_BASEPATH = get_env_variable('GVA_OSUSER_HOME_BASEPATH')
OSUSER_DEFAULT_SHELL = get_env_variable('GVA_OSUSER_DEFAULT_SHELL')
OSUSER_MINUID = get_env_variable('GVA_MIN_OS_UID', int, default=10000)
OSUSER_MINGID = get_env_variable('GVA_MIN_OS_GID', int, default=10000)
OSUSER_USERNAME_PREFIX = get_env_variable('GVA_OSUSER_PREFIX', default='usr')
OSUSER_HOME_BASEPATH = get_env_variable(
'GVA_OSUSER_HOME_BASEPATH', default='/home')
OSUSER_DEFAULT_SHELL = get_env_variable(
'GVA_OSUSER_DEFAULT_SHELL', default='/usr/bin/rssh')
OSUSER_SFTP_GROUP = 'sftponly'
OSUSER_SSH_GROUP = 'sshusers'
OSUSER_DEFAULT_GROUPS = [OSUSER_SFTP_GROUP]
OSUSER_UPLOAD_SERVER = get_env_variable('GVA_OSUSER_UPLOADSERVER')
GVA_LINK_WEBMAIL = get_env_variable('GVA_WEBMAIL_URL')
GVA_LINK_PHPMYADMIN = get_env_variable('GVA_PHPMYADMIN_URL')
GVA_LINK_PHPPGADMIN = get_env_variable('GVA_PHPPGADMIN_URL')
OSUSER_UPLOAD_SERVER = get_env_variable(
'GVA_OSUSER_UPLOADSERVER', default='file')
GVA_LINK_WEBMAIL = get_env_variable(
'GVA_WEBMAIL_URL', default='https://webmail.example.org/')
GVA_LINK_PHPMYADMIN = get_env_variable(
'GVA_PHPMYADMIN_URL', default='https://phpmyadmin.example.org/')
GVA_LINK_PHPPGADMIN = get_env_variable(
'GVA_PHPPGADMIN_URL', default='https://phppgadmin.example.org/')
# ######### END CUSTOM APP CONFIGURATION
GVA_ENVIRONMENT = get_env_variable('GVA_ENVIRONMENT', default='prod')
# ######### STATIC FILE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = '/srv/gnuviechadmin/static/'
if GVA_ENVIRONMENT == 'local':
# ######### DEBUG CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = True
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG
# ######### END DEBUG CONFIGURATION
# ######### EMAIL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# ######### END EMAIL CONFIGURATION
# ######### CACHE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#caches
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}
# ######### END CACHE CONFIGURATION
# ######### TOOLBAR CONFIGURATION
# See: http://django-debug-toolbar.readthedocs.org/en/latest/installation.html#explicit-setup # noqa
INSTALLED_APPS += (
'debug_toolbar',
)
MIDDLEWARE += [
'debug_toolbar.middleware.DebugToolbarMiddleware',
]
LOGGING['handlers'].update({
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple',
}
})
LOGGING['loggers'].update(dict(
[(key, {'handlers': ['console'], 'level': 'DEBUG', 'propagate': True, })
for key in [
'dashboard', 'domains', 'fileservertasks', 'gvacommon',
'gvawebcore', 'hostingpackages', 'ldaptasks', 'managemails',
'mysqltasks', 'osusers', 'pgsqltasks', 'taskresults',
'userdbs', 'websites']]))
DEBUG_TOOLBAR_PATCH_SETTINGS = False
# http://django-debug-toolbar.readthedocs.org/en/latest/installation.html
INTERNAL_IPS = ('127.0.0.1', '10.0.2.2')
# ######### END TOOLBAR CONFIGURATION
elif GVA_ENVIRONMENT == 'test':
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.MD5PasswordHasher',
)
LOGGING['handlers'].update({
'console': {
'level': 'ERROR',
'class': 'logging.StreamHandler',
'formatter': 'simple',
}
})
LOGGING['loggers'].update(dict(
[(key, {'handlers': ['console'], 'level': 'ERROR', 'propagate': True, })
for key in [
'dashboard', 'domains', 'fileservertasks', 'gvacommon',
'gvawebcore', 'hostingpackages', 'ldaptasks', 'managemails',
'mysqltasks', 'osusers', 'pgsqltasks', 'taskresults',
'userdbs', 'websites']]))
BROKER_URL = BROKER_URL + '_test'
CELERY_RESULT_PERSISTENT = False
else:
# ######### HOST CONFIGURATION
# See: https://docs.djangoproject.com/en/1.5/releases/1.5/#allowed-hosts-required-in-production # noqa
ALLOWED_HOSTS = [SITES_DOMAIN_NAME]
# ######### END HOST CONFIGURATION
# ######### EMAIL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix
EMAIL_SUBJECT_PREFIX = '[%s] ' % SITE_NAME
# See: https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email
DEFAULT_FROM_EMAIL = get_env_variable(
'GVA_SITE_ADMINMAIL', default='admin@example.org')
# See: https://docs.djangoproject.com/en/dev/ref/settings/#server-email
SERVER_EMAIL = get_env_variable(
'GVA_SITE_ADMINMAIL', default='admin@example.org')
# ######### END EMAIL CONFIGURATION
# ######### CACHE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#caches
# CACHES = {}
# ######### END CACHE CONFIGURATION
# ######### ALLAUTH PRODUCTION CONFIGURATION
ACCOUNT_EMAIL_SUBJECT_PREFIX = '[Jan Dittberner IT-Consulting & -Solutions] '
ACCOUNT_DEFAULT_HTTP_PROTOCOL = 'https'
# ######### END ALLAUTH PRODUCTION CONFIGURATION

3
gnuviechadmin/gnuviechadmin/settings/__init__.py

@ -1,3 +0,0 @@
"""
This module contains settings for various environments.
"""

68
gnuviechadmin/gnuviechadmin/settings/local.py

@ -1,68 +0,0 @@
# -*- python -*-
# pymode:lint_ignore=W0401,E501
"""
Development settings and globals based on :py:mod:`gvaldap.settings.base`.
"""
from __future__ import absolute_import
# use import * to import all settings from base
from .base import * # NOQA
# ######### DEBUG CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = True
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG
# ######### END DEBUG CONFIGURATION
# ######### EMAIL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# ######### END EMAIL CONFIGURATION
# ######### CACHE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#caches
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}
# ######### END CACHE CONFIGURATION
# ######### TOOLBAR CONFIGURATION
# See: http://django-debug-toolbar.readthedocs.org/en/latest/installation.html#explicit-setup # noqa
INSTALLED_APPS += (
'debug_toolbar',
)
MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
LOGGING['handlers'].update({
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple',
}
})
LOGGING['loggers'].update(dict(
[(key, {'handlers': ['console'], 'level': 'DEBUG', 'propagate': True, })
for key in [
'dashboard', 'domains', 'fileservertasks', 'gvacommon',
'gvawebcore', 'hostingpackages', 'ldaptasks', 'managemails',
'mysqltasks', 'osusers', 'pgsqltasks', 'taskresults',
'userdbs', 'websites']]))
DEBUG_TOOLBAR_PATCH_SETTINGS = False
# http://django-debug-toolbar.readthedocs.org/en/latest/installation.html
INTERNAL_IPS = ('127.0.0.1', '10.0.2.2')
# ######### END TOOLBAR CONFIGURATION

40
gnuviechadmin/gnuviechadmin/settings/production.py

@ -1,40 +0,0 @@
# -*- python -*-
# pymode:lint_ignore=W0401,E501
"""
Production settings and globals based on :py:mod:`gvaldap.settings.base`.
"""
from __future__ import absolute_import
# use import * to import all settings from base
from .base import * # NOQA
# ######### HOST CONFIGURATION
# See: https://docs.djangoproject.com/en/1.5/releases/1.5/#allowed-hosts-required-in-production # noqa
ALLOWED_HOSTS = [SITES_DOMAIN_NAME]
# ######### END HOST CONFIGURATION
# ######### EMAIL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix
EMAIL_SUBJECT_PREFIX = '[%s] ' % SITE_NAME
# See: https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email
DEFAULT_FROM_EMAIL = get_env_variable('GVA_SITE_ADMINMAIL')
# See: https://docs.djangoproject.com/en/dev/ref/settings/#server-email
SERVER_EMAIL = get_env_variable('GVA_SITE_ADMINMAIL')
# ######### END EMAIL CONFIGURATION
# ######### CACHE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#caches
# CACHES = {}
# ######### END CACHE CONFIGURATION
# ######### ALLAUTH PRODUCTION CONFIGURATION
ACCOUNT_EMAIL_SUBJECT_PREFIX = '[Jan Dittberner IT-Consulting & -Solutions] '
ACCOUNT_DEFAULT_HTTP_PROTOCOL = 'https'
# ######### END ALLAUTH PRODUCTION CONFIGURATION

29
gnuviechadmin/gnuviechadmin/settings/test.py

@ -1,29 +0,0 @@
# pymode:lint_ignore=W0401
"""
Test settings based on :py:mod:`gvaldap.settings.base`.
"""
from __future__ import absolute_import
# use import * to import all settings from base
from .base import * # NOQA
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.MD5PasswordHasher',
)
LOGGING['handlers'].update({
'console': {
'level': 'ERROR',
'class': 'logging.StreamHandler',
'formatter': 'simple',
}
})
LOGGING['loggers'].update(dict(
[(key, {'handlers': ['console'], 'level': 'ERROR', 'propagate': True, })
for key in [
'dashboard', 'domains', 'fileservertasks', 'gvacommon',
'gvawebcore', 'hostingpackages', 'ldaptasks', 'managemails',
'mysqltasks', 'osusers', 'pgsqltasks', 'taskresults',
'userdbs', 'websites']]))
BROKER_URL = BROKER_URL + '_test'
CELERY_RESULT_PERSISTENT = False

9
gnuviechadmin/gnuviechadmin/urls.py

@ -5,6 +5,8 @@ from django.conf import settings
from django.contrib import admin
from django.contrib.flatpages import views
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
admin.autodiscover()
urlpatterns = [
@ -28,6 +30,7 @@ urlpatterns = [
if settings.DEBUG: # pragma: no cover
import debug_toolbar
urlpatterns += [
url(r'^__debug__/', debug_toolbar.urls),
]
urlpatterns = [
url(r'^__debug__/', include(debug_toolbar.urls)),
] + staticfiles_urlpatterns() + urlpatterns

2
gnuviechadmin/hostingpackages/forms.py

@ -5,7 +5,7 @@ This module contains the form classes related to hosting packages.
from __future__ import absolute_import, unicode_literals
from django import forms
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.utils.translation import ugettext as _
from crispy_forms.helper import FormHelper

208
gnuviechadmin/hostingpackages/migrations/0001_initial.py

@ -1,14 +1,13 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone
from django.conf import settings
import model_utils.fields
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
@ -17,15 +16,30 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='CustomerHostingPackage',
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(unique=True, max_length=128, verbose_name='name')),
('description', models.TextField(verbose_name='description', blank=True)),
('mailboxcount', models.PositiveIntegerField(verbose_name='mailbox count')),
('diskspace', models.PositiveIntegerField(help_text='disk space for the hosting package', verbose_name='disk space')),
('diskspace_unit', models.PositiveSmallIntegerField(verbose_name='unit of disk space', choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
('customer', models.ForeignKey(verbose_name='customer', to=settings.AUTH_USER_MODEL)),
('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(
unique=True, max_length=128, verbose_name='name')),
('description', models.TextField(
verbose_name='description', blank=True)),
('mailboxcount', models.PositiveIntegerField(
verbose_name='mailbox count')),
('diskspace', models.PositiveIntegerField(
help_text='disk space for the hosting package',
verbose_name='disk space')),
('diskspace_unit', models.PositiveSmallIntegerField(
verbose_name='unit of disk space',
choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
('customer', models.ForeignKey(
verbose_name='customer', to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)),
],
options={
'verbose_name': 'customer hosting package',
@ -36,9 +50,15 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='CustomerHostingPackageOption',
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)),
('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)),
],
options={
'verbose_name': 'customer hosting option',
@ -49,9 +69,16 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='CustomerDiskSpaceOption',
fields=[
('customerhostingpackageoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.CustomerHostingPackageOption')),
('diskspace', models.PositiveIntegerField(verbose_name='disk space')),
('diskspace_unit', models.PositiveSmallIntegerField(verbose_name='unit of disk space', choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
('customerhostingpackageoption_ptr', models.OneToOneField(
parent_link=True, auto_created=True, primary_key=True,
serialize=False,
to='hostingpackages.CustomerHostingPackageOption',
on_delete=models.CASCADE)),
('diskspace', models.PositiveIntegerField(
verbose_name='disk space')),
('diskspace_unit', models.PositiveSmallIntegerField(
verbose_name='unit of disk space',
choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
],
options={
'ordering': ['diskspace_unit', 'diskspace'],
@ -59,13 +86,19 @@ class Migration(migrations.Migration):
'verbose_name': 'Disk space option',
'verbose_name_plural': 'Disk space options',
},
bases=('hostingpackages.customerhostingpackageoption', models.Model),
bases=(
'hostingpackages.customerhostingpackageoption', models.Model),
),
migrations.CreateModel(
name='CustomerMailboxOption',
fields=[
('customerhostingpackageoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.CustomerHostingPackageOption')),
('number', models.PositiveIntegerField(unique=True, verbose_name='number of mailboxes')),
('customerhostingpackageoption_ptr', models.OneToOneField(
parent_link=True, auto_created=True, primary_key=True,
serialize=False,
to='hostingpackages.CustomerHostingPackageOption',
on_delete=models.CASCADE)),
('number', models.PositiveIntegerField(
unique=True, verbose_name='number of mailboxes')),
],
options={
'ordering': ['number'],
@ -73,14 +106,22 @@ class Migration(migrations.Migration):
'verbose_name': 'Mailbox option',
'verbose_name_plural': 'Mailbox options',
},
bases=('hostingpackages.customerhostingpackageoption', models.Model),
bases=(
'hostingpackages.customerhostingpackageoption', models.Model),
),
migrations.CreateModel(
name='CustomerUserDatabaseOption',
fields=[
('customerhostingpackageoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.CustomerHostingPackageOption')),
('number', models.PositiveIntegerField(default=1, verbose_name='number of databases')),
('db_type', models.PositiveSmallIntegerField(verbose_name='database type', choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
('customerhostingpackageoption_ptr', models.OneToOneField(
parent_link=True, auto_created=True, primary_key=True,
serialize=False,
to='hostingpackages.CustomerHostingPackageOption',
on_delete=models.CASCADE)),
('number', models.PositiveIntegerField(
default=1, verbose_name='number of databases')),
('db_type', models.PositiveSmallIntegerField(
verbose_name='database type',
choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
],
options={
'ordering': ['db_type', 'number'],
@ -88,14 +129,21 @@ class Migration(migrations.Migration):
'verbose_name': 'Database option',
'verbose_name_plural': 'Database options',
},
bases=('hostingpackages.customerhostingpackageoption', models.Model),
bases=(
'hostingpackages.customerhostingpackageoption', models.Model),
),
migrations.CreateModel(
name='HostingOption',
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)),
('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)),
],
options={
'verbose_name': 'Hosting option',
@ -106,9 +154,15 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='DiskSpaceOption',
fields=[
('hostingoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.HostingOption')),
('diskspace', models.PositiveIntegerField(verbose_name='disk space')),
('diskspace_unit', models.PositiveSmallIntegerField(verbose_name='unit of disk space', choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
('hostingoption_ptr', models.OneToOneField(
parent_link=True, auto_created=True, primary_key=True,
serialize=False, to='hostingpackages.HostingOption',
on_delete=models.CASCADE)),
('diskspace', models.PositiveIntegerField(
verbose_name='disk space')),
('diskspace_unit', models.PositiveSmallIntegerField(
verbose_name='unit of disk space',
choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
],
options={
'ordering': ['diskspace_unit', 'diskspace'],
@ -121,14 +175,27 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='HostingPackageTemplate',
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(unique=True, max_length=128, verbose_name='name')),
('description', models.TextField(verbose_name='description', blank=True)),
('mailboxcount', models.PositiveIntegerField(verbose_name='mailbox count')),
('diskspace', models.PositiveIntegerField(help_text='disk space for the hosting package', verbose_name='disk space')),
('diskspace_unit', models.PositiveSmallIntegerField(verbose_name='unit of disk space', choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
('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(
unique=True, max_length=128, verbose_name='name')),
('description', models.TextField(
verbose_name='description', blank=True)),
('mailboxcount', models.PositiveIntegerField(
verbose_name='mailbox count')),
('diskspace', models.PositiveIntegerField(
help_text='disk space for the hosting package',
verbose_name='disk space')),
('diskspace_unit', models.PositiveSmallIntegerField(
verbose_name='unit of disk space',
choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])),
],
options={
'verbose_name': 'Hosting package',
@ -139,8 +206,12 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='MailboxOption',
fields=[
('hostingoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.HostingOption')),
('number', models.PositiveIntegerField(unique=True, verbose_name='number of mailboxes')),
('hostingoption_ptr', models.OneToOneField(
parent_link=True, auto_created=True, primary_key=True,
serialize=False, to='hostingpackages.HostingOption',
on_delete=models.CASCADE)),
('number', models.PositiveIntegerField(
unique=True, verbose_name='number of mailboxes')),
],
options={
'ordering': ['number'],
@ -153,9 +224,15 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='UserDatabaseOption',
fields=[
('hostingoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.HostingOption')),
('number', models.PositiveIntegerField(default=1, verbose_name='number of databases')),
('db_type', models.PositiveSmallIntegerField(verbose_name='database type', choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
('hostingoption_ptr', models.OneToOneField(
parent_link=True, auto_created=True, primary_key=True,
serialize=False, to='hostingpackages.HostingOption',
on_delete=models.CASCADE)),
('number', models.PositiveIntegerField(
default=1, verbose_name='number of databases')),
('db_type', models.PositiveSmallIntegerField(
verbose_name='database type',
choices=[(0, 'PostgreSQL'), (1, 'MySQL')])),
],
options={
'ordering': ['db_type', 'number'],
@ -167,48 +244,71 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name='userdatabaseoption',
unique_together=set([('number', 'db_type')]),
unique_together={('number', 'db_type')},
),
migrations.AlterUniqueTogether(
name='diskspaceoption',
unique_together=set([('diskspace', 'diskspace_unit')]),
unique_together={('diskspace', 'diskspace_unit')},
),
migrations.AddField(
model_name='customeruserdatabaseoption',
name='template',
field=models.ForeignKey(verbose_name='user database option template', to='hostingpackages.UserDatabaseOption', help_text='The user database option template that this hosting option is based on'),
field=models.ForeignKey(
verbose_name='user database option template',
to='hostingpackages.UserDatabaseOption',
help_text='The user database option template that this '
'hosting option is based on',
on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AlterUniqueTogether(
name='customeruserdatabaseoption',
unique_together=set([('number', 'db_type')]),
unique_together={('number', 'db_type')},
),
migrations.AddField(
model_name='customermailboxoption',
name='template',
field=models.ForeignKey(verbose_name='mailbox option template', to='hostingpackages.UserDatabaseOption', help_text='The mailbox option template that this hosting option is based on'),
field=models.ForeignKey(
verbose_name='mailbox option template',
to='hostingpackages.UserDatabaseOption',
help_text='The mailbox option template that this hosting '
'option is based on',
on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
model_name='customerhostingpackageoption',
name='hosting_package',
field=models.ForeignKey(verbose_name='hosting package', to='hostingpackages.CustomerHostingPackage'),
field=models.ForeignKey(