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.
This commit is contained in:
Jan Dittberner 2018-11-19 23:28:40 +01:00
parent adc57657dd
commit 6cebd80c89
48 changed files with 1081 additions and 576 deletions

2
.gitignore vendored
View File

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

31
Dockerfile Normal file
View File

@ -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"]

View File

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

20
Pipfile.lock generated
View File

@ -1,11 +1,11 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "ed0a23d288cc817ebfbf92a4acd140eee9e083d6331eaa5f06bdbc0d37c4767f" "sha256": "3b941559bcaf1c164285aef53553496fbf1414f362da1433b705ac7c796e33e6"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
"python_version": "3.6" "python_version": "3.5"
}, },
"sources": [ "sources": [
{ {
@ -73,6 +73,22 @@
"index": "pypi", "index": "pypi",
"version": "==0.38.0" "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": { "django-model-utils": {
"hashes": [ "hashes": [
"sha256:2c057f3bf0859aba27f04389f0cedd2d48f8c9b3848acb86fd9970794e58f477", "sha256:2c057f3bf0859aba27f04389f0cedd2d48f8c9b3848acb86fd9970794e58f477",

26
Vagrantfile vendored
View File

@ -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 Normal file
View File

@ -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 Executable file
View File

@ -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

View File

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

View File

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

View File

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

View File

@ -8,7 +8,6 @@ import model_utils.fields
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('domains', '0001_initial'), ('domains', '0001_initial'),
@ -18,12 +17,31 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='HostingDomain', name='HostingDomain',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id',
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), models.AutoField(verbose_name='ID', serialize=False,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), auto_created=True, primary_key=True)),
('domain', models.CharField(unique=True, max_length=128, verbose_name='domain name')), ('created',
('customer', models.ForeignKey(verbose_name='customer', blank=True, to=settings.AUTH_USER_MODEL, null=True)), model_utils.fields.AutoCreatedField(
('maildomain', models.OneToOneField(null=True, to='domains.MailDomain', blank=True, help_text='assigned mail domain for this domain', verbose_name='mail domain')), 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={ options={
'verbose_name': 'Hosting domain', 'verbose_name': 'Hosting domain',
@ -34,13 +52,17 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='maildomain', model_name='maildomain',
name='customer', 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, preserve_default=True,
), ),
migrations.AlterField( migrations.AlterField(
model_name='maildomain', model_name='maildomain',
name='domain', 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, preserve_default=True,
), ),
] ]

View File

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

View File

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

View File

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

View File

@ -38,7 +38,8 @@ DEBUG = False
# ######### MANAGER CONFIGURATION # ######### MANAGER CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins # See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
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 # 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 # See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql',
'NAME': get_env_variable('GVA_PGSQL_DATABASE'), 'NAME': get_env_variable('GVA_PGSQL_DATABASE', default='gnuviechadmin'),
'USER': get_env_variable('GVA_PGSQL_USER'), 'USER': get_env_variable('GVA_PGSQL_USER', default='gnuviechadmin'),
'PASSWORD': get_env_variable('GVA_PGSQL_PASSWORD'), 'PASSWORD': get_env_variable('GVA_PGSQL_PASSWORD'),
'HOST': get_env_variable('GVA_PGSQL_HOSTNAME'), 'HOST': get_env_variable('GVA_PGSQL_HOSTNAME', default='db'),
'PORT': get_env_variable('GVA_PGSQL_PORT'), 'PORT': get_env_variable('GVA_PGSQL_PORT', int, default=5432),
} }
} }
# ######### END DATABASE CONFIGURATION # ######### END DATABASE CONFIGURATION
@ -98,16 +99,13 @@ MEDIA_URL = '/media/'
# ######### END MEDIA CONFIGURATION # ######### 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 # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = '/static/' STATIC_URL = '/static/'
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS # noqa # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS # noqa
STATICFILES_DIRS = ( 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 # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders # noqa
@ -146,7 +144,7 @@ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [ 'DIRS': [
normpath(join(SITE_ROOT, 'templates')), normpath(join(DJANGO_ROOT, 'templates')),
], ],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
@ -171,7 +169,7 @@ TEMPLATES = [
# ######### MIDDLEWARE CONFIGURATION # ######### MIDDLEWARE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes # See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes
MIDDLEWARE_CLASSES = ( MIDDLEWARE = [
# Default Django middleware. # Default Django middleware.
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
@ -181,7 +179,7 @@ MIDDLEWARE_CLASSES = (
# uncomment next line to enable translation to browser locale # uncomment next line to enable translation to browser locale
'django.middleware.locale.LocaleMiddleware', 'django.middleware.locale.LocaleMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
) ]
# ######### END MIDDLEWARE CONFIGURATION # ######### END MIDDLEWARE CONFIGURATION
@ -330,8 +328,12 @@ WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
# ######### CELERY CONFIGURATION # ######### CELERY CONFIGURATION
BROKER_URL = get_env_variable('GVA_BROKER_URL') BROKER_URL = get_env_variable(
CELERY_RESULT_BACKEND = get_env_variable('GVA_RESULTS_REDIS_URL') '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_TASK_RESULT_EXPIRES = None
CELERY_ROUTES = ( CELERY_ROUTES = (
'gvacommon.celeryrouters.GvaRouter', 'gvacommon.celeryrouters.GvaRouter',
@ -345,17 +347,134 @@ CELERY_RESULT_SERIALIZER = 'json'
# ######### CUSTOM APP CONFIGURATION # ######### CUSTOM APP CONFIGURATION
OSUSER_MINUID = int(get_env_variable('GVA_MIN_OS_UID')) OSUSER_MINUID = get_env_variable('GVA_MIN_OS_UID', int, default=10000)
OSUSER_MINGID = int(get_env_variable('GVA_MIN_OS_GID')) OSUSER_MINGID = get_env_variable('GVA_MIN_OS_GID', int, default=10000)
OSUSER_USERNAME_PREFIX = get_env_variable('GVA_OSUSER_PREFIX') OSUSER_USERNAME_PREFIX = get_env_variable('GVA_OSUSER_PREFIX', default='usr')
OSUSER_HOME_BASEPATH = get_env_variable('GVA_OSUSER_HOME_BASEPATH') OSUSER_HOME_BASEPATH = get_env_variable(
OSUSER_DEFAULT_SHELL = get_env_variable('GVA_OSUSER_DEFAULT_SHELL') '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_SFTP_GROUP = 'sftponly'
OSUSER_SSH_GROUP = 'sshusers' OSUSER_SSH_GROUP = 'sshusers'
OSUSER_DEFAULT_GROUPS = [OSUSER_SFTP_GROUP] OSUSER_DEFAULT_GROUPS = [OSUSER_SFTP_GROUP]
OSUSER_UPLOAD_SERVER = get_env_variable('GVA_OSUSER_UPLOADSERVER') OSUSER_UPLOAD_SERVER = get_env_variable(
'GVA_OSUSER_UPLOADSERVER', default='file')
GVA_LINK_WEBMAIL = get_env_variable('GVA_WEBMAIL_URL') GVA_LINK_WEBMAIL = get_env_variable(
GVA_LINK_PHPMYADMIN = get_env_variable('GVA_PHPMYADMIN_URL') 'GVA_WEBMAIL_URL', default='https://webmail.example.org/')
GVA_LINK_PHPPGADMIN = get_env_variable('GVA_PHPPGADMIN_URL') 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 # ######### 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

View File

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

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -1,15 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone import django.utils.timezone
from django.conf import settings
import model_utils.fields import model_utils.fields
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
replaces = [('hostingpackages', '0001_initial'),
replaces = [('hostingpackages', '0001_initial'), ('hostingpackages', '0002_auto_20150118_1149'), ('hostingpackages', '0003_auto_20150118_1221'), ('hostingpackages', '0004_customerhostingpackage_osuser'), ('hostingpackages', '0005_auto_20150118_1303')] ('hostingpackages', '0002_auto_20150118_1149'),
('hostingpackages', '0003_auto_20150118_1221'),
('hostingpackages', '0004_customerhostingpackage_osuser'),
('hostingpackages', '0005_auto_20150118_1303')]
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
@ -20,15 +23,30 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='CustomerHostingPackage', name='CustomerHostingPackage',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), primary_key=True)),
('name', models.CharField(unique=True, max_length=128, verbose_name='name')), ('created', model_utils.fields.AutoCreatedField(
('description', models.TextField(verbose_name='description', blank=True)), default=django.utils.timezone.now, verbose_name='created',
('mailboxcount', models.PositiveIntegerField(verbose_name='mailbox count')), editable=False)),
('diskspace', models.PositiveIntegerField(help_text='disk space for the hosting package', verbose_name='disk space')), ('modified', model_utils.fields.AutoLastModifiedField(
('diskspace_unit', models.PositiveSmallIntegerField(verbose_name='unit of disk space', choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])), default=django.utils.timezone.now, verbose_name='modified',
('customer', models.ForeignKey(verbose_name='customer', to=settings.AUTH_USER_MODEL)), 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={ options={
'verbose_name': 'customer hosting package', 'verbose_name': 'customer hosting package',
@ -39,9 +57,15 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='CustomerHostingPackageOption', name='CustomerHostingPackageOption',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), 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={ options={
'verbose_name': 'customer hosting option', 'verbose_name': 'customer hosting option',
@ -52,9 +76,17 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='CustomerDiskSpaceOption', name='CustomerDiskSpaceOption',
fields=[ fields=[
('customerhostingpackageoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.CustomerHostingPackageOption')), ('customerhostingpackageoption_ptr',
('diskspace', models.PositiveIntegerField(verbose_name='disk space')), models.OneToOneField(
('diskspace_unit', models.PositiveSmallIntegerField(verbose_name='unit of disk space', choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])), 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={ options={
'ordering': ['diskspace_unit', 'diskspace'], 'ordering': ['diskspace_unit', 'diskspace'],
@ -62,13 +94,20 @@ class Migration(migrations.Migration):
'verbose_name': 'Disk space option', 'verbose_name': 'Disk space option',
'verbose_name_plural': 'Disk space options', 'verbose_name_plural': 'Disk space options',
}, },
bases=('hostingpackages.customerhostingpackageoption', models.Model), bases=(
'hostingpackages.customerhostingpackageoption', models.Model),
), ),
migrations.CreateModel( migrations.CreateModel(
name='CustomerMailboxOption', name='CustomerMailboxOption',
fields=[ fields=[
('customerhostingpackageoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.CustomerHostingPackageOption')), ('customerhostingpackageoption_ptr',
('number', models.PositiveIntegerField(unique=True, verbose_name='number of mailboxes')), 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={ options={
'ordering': ['number'], 'ordering': ['number'],
@ -76,14 +115,23 @@ class Migration(migrations.Migration):
'verbose_name': 'Mailbox option', 'verbose_name': 'Mailbox option',
'verbose_name_plural': 'Mailbox options', 'verbose_name_plural': 'Mailbox options',
}, },
bases=('hostingpackages.customerhostingpackageoption', models.Model), bases=(
'hostingpackages.customerhostingpackageoption', models.Model),
), ),
migrations.CreateModel( migrations.CreateModel(
name='CustomerUserDatabaseOption', name='CustomerUserDatabaseOption',
fields=[ fields=[
('customerhostingpackageoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.CustomerHostingPackageOption')), ('customerhostingpackageoption_ptr',
('number', models.PositiveIntegerField(default=1, verbose_name='number of databases')), models.OneToOneField(
('db_type', models.PositiveSmallIntegerField(verbose_name='database type', choices=[(0, 'PostgreSQL'), (1, 'MySQL')])), 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={ options={
'ordering': ['db_type', 'number'], 'ordering': ['db_type', 'number'],
@ -91,14 +139,21 @@ class Migration(migrations.Migration):
'verbose_name': 'Database option', 'verbose_name': 'Database option',
'verbose_name_plural': 'Database options', 'verbose_name_plural': 'Database options',
}, },
bases=('hostingpackages.customerhostingpackageoption', models.Model), bases=(
'hostingpackages.customerhostingpackageoption', models.Model),
), ),
migrations.CreateModel( migrations.CreateModel(
name='HostingOption', name='HostingOption',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), 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={ options={
'verbose_name': 'Hosting option', 'verbose_name': 'Hosting option',
@ -109,9 +164,16 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='DiskSpaceOption', name='DiskSpaceOption',
fields=[ fields=[
('hostingoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.HostingOption')), ('hostingoption_ptr',
('diskspace', models.PositiveIntegerField(verbose_name='disk space')), models.OneToOneField(
('diskspace_unit', models.PositiveSmallIntegerField(verbose_name='unit of disk space', choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])), 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={ options={
'ordering': ['diskspace_unit', 'diskspace'], 'ordering': ['diskspace_unit', 'diskspace'],
@ -124,14 +186,27 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='HostingPackageTemplate', name='HostingPackageTemplate',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), primary_key=True)),
('name', models.CharField(unique=True, max_length=128, verbose_name='name')), ('created', model_utils.fields.AutoCreatedField(
('description', models.TextField(verbose_name='description', blank=True)), default=django.utils.timezone.now, verbose_name='created',
('mailboxcount', models.PositiveIntegerField(verbose_name='mailbox count')), editable=False)),
('diskspace', models.PositiveIntegerField(help_text='disk space for the hosting package', verbose_name='disk space')), ('modified', model_utils.fields.AutoLastModifiedField(
('diskspace_unit', models.PositiveSmallIntegerField(verbose_name='unit of disk space', choices=[(0, 'MiB'), (1, 'GiB'), (2, 'TiB')])), 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={ options={
'verbose_name': 'Hosting package', 'verbose_name': 'Hosting package',
@ -142,8 +217,13 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='MailboxOption', name='MailboxOption',
fields=[ fields=[
('hostingoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.HostingOption')), ('hostingoption_ptr',
('number', models.PositiveIntegerField(unique=True, verbose_name='number of mailboxes')), 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={ options={
'ordering': ['number'], 'ordering': ['number'],
@ -156,9 +236,17 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='UserDatabaseOption', name='UserDatabaseOption',
fields=[ fields=[
('hostingoption_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='hostingpackages.HostingOption')), ('hostingoption_ptr',
('number', models.PositiveIntegerField(default=1, verbose_name='number of databases')), models.OneToOneField(
('db_type', models.PositiveSmallIntegerField(verbose_name='database type', choices=[(0, 'PostgreSQL'), (1, 'MySQL')])), 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={ options={
'ordering': ['db_type', 'number'], 'ordering': ['db_type', 'number'],
@ -170,60 +258,93 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='userdatabaseoption', name='userdatabaseoption',
unique_together=set([('number', 'db_type')]), unique_together={('number', 'db_type')},
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='diskspaceoption', name='diskspaceoption',
unique_together=set([('diskspace', 'diskspace_unit')]), unique_together={('diskspace', 'diskspace_unit')},
), ),
migrations.AddField( migrations.AddField(
model_name='customeruserdatabaseoption', model_name='customeruserdatabaseoption',
name='template', 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, preserve_default=True,
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='customeruserdatabaseoption', name='customeruserdatabaseoption',
unique_together=set([('number', 'db_type')]), unique_together={('number', 'db_type')},
), ),
migrations.AddField( migrations.AddField(
model_name='customermailboxoption', model_name='customermailboxoption',
name='template', name='template',
field=models.ForeignKey(verbose_name='mailbox option template', to='hostingpackages.UserDatabaseOption', help_text='The mailbox option template that this mailbox option is based on'), field=models.ForeignKey(
verbose_name='mailbox option template',
to='hostingpackages.UserDatabaseOption',
help_text='The mailbox option template that this mailbox '
'option is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AddField( migrations.AddField(
model_name='customerhostingpackageoption', model_name='customerhostingpackageoption',
name='hosting_package', name='hosting_package',
field=models.ForeignKey(verbose_name='hosting package', to='hostingpackages.CustomerHostingPackage'), field=models.ForeignKey(
verbose_name='hosting package',
to='hostingpackages.CustomerHostingPackage',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AddField( migrations.AddField(
model_name='customerhostingpackage', model_name='customerhostingpackage',
name='template', name='template',
field=models.ForeignKey(verbose_name='hosting package template', to='hostingpackages.HostingPackageTemplate', help_text='The hosting package template that this hosting package is based on'), field=models.ForeignKey(
verbose_name='hosting package template',
to='hostingpackages.HostingPackageTemplate',
help_text='The hosting package template that this hosting '
'package is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AddField( migrations.AddField(
model_name='customerdiskspaceoption', model_name='customerdiskspaceoption',
name='template', name='template',
field=models.ForeignKey(verbose_name='disk space option template', to='hostingpackages.DiskSpaceOption', help_text='The disk space option template that this hosting option is based on'), field=models.ForeignKey(
verbose_name='disk space option template',
to='hostingpackages.DiskSpaceOption',
help_text='The disk space option template that this hosting '
'option is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='customerdiskspaceoption', name='customerdiskspaceoption',
unique_together=set([('diskspace', 'diskspace_unit')]), unique_together={('diskspace', 'diskspace_unit')},
), ),
migrations.AlterField( migrations.AlterField(
model_name='customerdiskspaceoption', model_name='customerdiskspaceoption',
name='template', name='template',
field=models.ForeignKey(verbose_name='disk space option template', to='hostingpackages.DiskSpaceOption', help_text='The disk space option template that this disk space option is based on'), field=models.ForeignKey(
verbose_name='disk space option template',
to='hostingpackages.DiskSpaceOption',
help_text='The disk space option template that this disk '
'space option is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterField( migrations.AlterField(
model_name='customeruserdatabaseoption', model_name='customeruserdatabaseoption',
name='template', name='template',
field=models.ForeignKey(verbose_name='user database option template', to='hostingpackages.UserDatabaseOption', help_text='The user database option template that this database 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 '
'database option is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterField( migrations.AlterField(
@ -234,12 +355,14 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='customerhostingpackage', name='customerhostingpackage',
unique_together=set([('customer', 'name')]), unique_together={('customer', 'name')},
), ),
migrations.AddField( migrations.AddField(
model_name='customerhostingpackage', model_name='customerhostingpackage',
name='osuser', name='osuser',
field=models.OneToOneField(null=True, blank=True, to='osusers.User', verbose_name='Operating system user'), field=models.OneToOneField(
null=True, blank=True, to='osusers.User',
verbose_name='Operating system user', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('hostingpackages', '0001_initial'), ('hostingpackages', '0001_initial'),
] ]
@ -14,25 +13,45 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='customerdiskspaceoption', model_name='customerdiskspaceoption',
name='template', name='template',
field=models.ForeignKey(verbose_name='disk space option template', to='hostingpackages.DiskSpaceOption', help_text='The disk space option template that this disk space option is based on'), field=models.ForeignKey(
verbose_name='disk space option template',
to='hostingpackages.DiskSpaceOption',
help_text='The disk space option template that this disk '
'space option is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterField( migrations.AlterField(
model_name='customerhostingpackage', model_name='customerhostingpackage',
name='template', name='template',
field=models.ForeignKey(verbose_name='hosting package template', to='hostingpackages.HostingPackageTemplate', help_text='The hosting package template that this hosting package is based on'), field=models.ForeignKey(
verbose_name='hosting package template',
to='hostingpackages.HostingPackageTemplate',
help_text='The hosting package template that this hosting '
'package is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterField( migrations.AlterField(
model_name='customermailboxoption', model_name='customermailboxoption',
name='template', name='template',
field=models.ForeignKey(verbose_name='mailbox option template', to='hostingpackages.UserDatabaseOption', help_text='The mailbox option template that this mailbox option is based on'), field=models.ForeignKey(
verbose_name='mailbox option template',
to='hostingpackages.UserDatabaseOption',
help_text='The mailbox option template that this mailbox '
'option is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterField( migrations.AlterField(
model_name='customeruserdatabaseoption', model_name='customeruserdatabaseoption',
name='template', name='template',
field=models.ForeignKey(verbose_name='user database option template', to='hostingpackages.UserDatabaseOption', help_text='The user database option template that this database 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 '
'database option is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('hostingpackages', '0002_auto_20150118_1319'), ('hostingpackages', '0002_auto_20150118_1319'),
] ]
@ -14,7 +13,12 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='customermailboxoption', model_name='customermailboxoption',
name='template', name='template',
field=models.ForeignKey(verbose_name='mailbox option template', to='hostingpackages.MailboxOption', help_text='The mailbox option template that this mailbox option is based on'), field=models.ForeignKey(
verbose_name='mailbox option template',
to='hostingpackages.MailboxOption',
help_text='The mailbox option template that this mailbox '
'option is based on',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('osusers', '0004_auto_20150104_1751'), ('osusers', '0004_auto_20150104_1751'),
('hostingpackages', '0003_auto_20150118_1221'), ('hostingpackages', '0003_auto_20150118_1221'),
@ -15,7 +14,9 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='customerhostingpackage', model_name='customerhostingpackage',
name='osuser', name='osuser',
field=models.ForeignKey(verbose_name='Operating system user', blank=True, to='osusers.User', null=True), field=models.ForeignKey(
verbose_name='Operating system user', blank=True,
to='osusers.User', null=True, on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

View File

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone import django.utils.timezone
import model_utils.fields import model_utils.fields
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('domains', '0002_auto_20150124_1909'), ('domains', '0002_auto_20150124_1909'),
('hostingpackages', '0003_auto_20150118_1407'), ('hostingpackages', '0003_auto_20150118_1407'),
@ -17,11 +16,22 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='CustomerHostingPackageDomain', name='CustomerHostingPackageDomain',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), primary_key=True)),
('domain', models.OneToOneField(verbose_name='hosting domain', to='domains.HostingDomain')), ('created', model_utils.fields.AutoCreatedField(
('hosting_package', models.ForeignKey(related_name='domains', verbose_name='hosting package', to='hostingpackages.CustomerHostingPackage')), 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.OneToOneField(
verbose_name='hosting domain', to='domains.HostingDomain',
on_delete=models.CASCADE)),
('hosting_package', models.ForeignKey(
related_name='domains', verbose_name='hosting package',
to='hostingpackages.CustomerHostingPackage',
on_delete=models.CASCADE)),
], ],
options={ options={
'abstract': False, 'abstract': False,

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('hostingpackages', '0004_customerhostingpackage_osuser'), ('hostingpackages', '0004_customerhostingpackage_osuser'),
] ]
@ -14,7 +13,9 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='customerhostingpackage', model_name='customerhostingpackage',
name='osuser', name='osuser',
field=models.OneToOneField(null=True, blank=True, to='osusers.User', verbose_name='Operating system user'), field=models.OneToOneField(
null=True, blank=True, to='osusers.User',
verbose_name='Operating system user', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

View File

@ -5,9 +5,9 @@ This module contains the hosting package models.
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import transaction from django.db import transaction
from django.db import models from django.db import models
from django.urls import reverse
from django.utils.encoding import python_2_unicode_compatible from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _, ungettext from django.utils.translation import ugettext_lazy as _, ungettext
@ -26,7 +26,6 @@ from userdbs.models import (
UserDatabase, UserDatabase,
) )
DISK_SPACE_UNITS = Choices( DISK_SPACE_UNITS = Choices(
(0, 'M', _('MiB')), (0, 'M', _('MiB')),
(1, 'G', _('GiB')), (1, 'G', _('GiB')),
@ -94,6 +93,7 @@ class DiskSpaceOption(DiskSpaceOptionBase, HostingOption):
existing hosting packages. existing hosting packages.
""" """
class Meta: class Meta:
unique_together = ['diskspace', 'diskspace_unit'] unique_together = ['diskspace', 'diskspace_unit']
@ -127,6 +127,7 @@ class UserDatabaseOption(UserDatabaseOptionBase, HostingOption):
hosting packages. hosting packages.
""" """
class Meta: class Meta:
unique_together = ['number', 'db_type'] unique_together = ['number', 'db_type']
@ -203,17 +204,19 @@ class CustomerHostingPackage(HostingPackageBase):
""" """
customer = models.ForeignKey( customer = models.ForeignKey(
settings.AUTH_USER_MODEL, verbose_name=_('customer')) settings.AUTH_USER_MODEL, verbose_name=_('customer'),
on_delete=models.CASCADE)
template = models.ForeignKey( template = models.ForeignKey(
HostingPackageTemplate, verbose_name=_('hosting package template'), HostingPackageTemplate, verbose_name=_('hosting package template'),
help_text=_( help_text=_(
'The hosting package template that this hosting package is based' 'The hosting package template that this hosting package is based'
' on' ' on'
)) ),
on_delete=models.CASCADE)
name = models.CharField(_('name'), max_length=128) name = models.CharField(_('name'), max_length=128)
osuser = models.OneToOneField( osuser = models.OneToOneField(
OsUser, verbose_name=_('Operating system user'), OsUser, verbose_name=_('Operating system user'),
blank=True, null=True) blank=True, null=True, on_delete=models.CASCADE)
objects = CustomerHostingPackageManager() objects = CustomerHostingPackageManager()
@ -250,6 +253,7 @@ class CustomerHostingPackage(HostingPackageBase):
]: ]:
opts.extend(opt_type.objects.filter(hosting_package=self)) opts.extend(opt_type.objects.filter(hosting_package=self))
return opts return opts
hostingoptions = property(get_hostingoptions) hostingoptions = property(get_hostingoptions)
def get_disk_space(self, unit=None): def get_disk_space(self, unit=None):
@ -272,15 +276,16 @@ class CustomerHostingPackage(HostingPackageBase):
diskspace += option.diskspace diskspace += option.diskspace
elif option.diskspace_unit > min_unit: elif option.diskspace_unit > min_unit:
diskspace += ( diskspace += (
DISK_SPACE_FACTORS[option.diskspace_unit][min_unit] * DISK_SPACE_FACTORS[option.diskspace_unit][min_unit] *
option.diskspace) option.diskspace)
else: else:
diskspace = ( diskspace = (
DISK_SPACE_FACTORS[min_unit][option.diskspace_unit] * DISK_SPACE_FACTORS[min_unit][
diskspace) + option.diskspace option.diskspace_unit] *
diskspace) + option.diskspace
min_unit = option.diskspace_unit min_unit = option.diskspace_unit
if unit is None: if unit is None:
return DISK_SPACE_FACTORS[min_unit][0] * diskspace * 1024**2 return DISK_SPACE_FACTORS[min_unit][0] * diskspace * 1024 ** 2
if unit > min_unit: if unit > min_unit:
return DISK_SPACE_FACTORS[unit][min_unit] * diskspace return DISK_SPACE_FACTORS[unit][min_unit] * diskspace
return DISK_SPACE_FACTORS[min_unit][unit] * diskspace return DISK_SPACE_FACTORS[min_unit][unit] * diskspace
@ -298,7 +303,7 @@ class CustomerHostingPackage(HostingPackageBase):
""" """
if unit is None: if unit is None:
return (DISK_SPACE_FACTORS[self.diskspace_unit][0] * return (DISK_SPACE_FACTORS[self.diskspace_unit][0] *
self.diskspace * 1024**2) self.diskspace * 1024 ** 2)
if unit > self.diskspace_unit: if unit > self.diskspace_unit:
return (DISK_SPACE_FACTORS[unit][self.diskspace_unit] * return (DISK_SPACE_FACTORS[unit][self.diskspace_unit] *
self.diskspace) self.diskspace)
@ -312,6 +317,7 @@ class CustomerHostingPackage(HostingPackageBase):
def get_mailboxes(self): def get_mailboxes(self):
if self.osuser: if self.osuser:
return Mailbox.objects.filter(osuser=self.osuser).all() return Mailbox.objects.filter(osuser=self.osuser).all()
mailboxes = property(get_mailboxes) mailboxes = property(get_mailboxes)
def get_used_mailbox_count(self): def get_used_mailbox_count(self):
@ -322,6 +328,7 @@ class CustomerHostingPackage(HostingPackageBase):
if self.osuser: if self.osuser:
return Mailbox.objects.filter(osuser=self.osuser).count() return Mailbox.objects.filter(osuser=self.osuser).count()
return 0 return 0
used_mailbox_count = property(get_used_mailbox_count) used_mailbox_count = property(get_used_mailbox_count)
def get_mailbox_count(self): def get_mailbox_count(self):
@ -336,6 +343,7 @@ class CustomerHostingPackage(HostingPackageBase):
mailbox_sum=models.Sum('number') mailbox_sum=models.Sum('number')
) )
return self.mailboxcount + (result['mailbox_sum'] or 0) return self.mailboxcount + (result['mailbox_sum'] or 0)
mailbox_count = property(get_mailbox_count) mailbox_count = property(get_mailbox_count)
def may_add_mailbox(self): def may_add_mailbox(self):
@ -357,14 +365,15 @@ class CustomerHostingPackage(HostingPackageBase):
if self.osuser: if self.osuser:
return UserDatabase.objects.filter( return UserDatabase.objects.filter(
db_user__osuser=self.osuser).all() db_user__osuser=self.osuser).all()
databases = property(get_databases_flat) databases = property(get_databases_flat)
def may_add_database(self): def may_add_database(self):
return ( return (
CustomerUserDatabaseOption.objects.filter( CustomerUserDatabaseOption.objects.filter(
hosting_package=self).count() > hosting_package=self).count() >
UserDatabase.objects.filter( UserDatabase.objects.filter(
db_user__osuser=self.osuser).count() db_user__osuser=self.osuser).count()
) )
@transaction.atomic @transaction.atomic
@ -402,9 +411,10 @@ class CustomerHostingPackageDomain(TimeStampedModel):
""" """
hosting_package = models.ForeignKey( hosting_package = models.ForeignKey(
CustomerHostingPackage, verbose_name=_('hosting package'), CustomerHostingPackage, verbose_name=_('hosting package'),
related_name='domains') related_name='domains', on_delete=models.CASCADE)
domain = models.OneToOneField( domain = models.OneToOneField(
HostingDomain, verbose_name=_('hosting domain')) HostingDomain, verbose_name=_('hosting domain'),
on_delete=models.CASCADE)
def __str__(self): def __str__(self):
return self.domain.domain return self.domain.domain
@ -423,7 +433,8 @@ class CustomerHostingPackageOption(TimeStampedModel):
""" """
hosting_package = models.ForeignKey( hosting_package = models.ForeignKey(
CustomerHostingPackage, verbose_name=_('hosting package')) CustomerHostingPackage, verbose_name=_('hosting package'),
on_delete=models.CASCADE)
class Meta: class Meta:
verbose_name = _('customer hosting option') verbose_name = _('customer hosting option')
@ -443,7 +454,8 @@ class CustomerDiskSpaceOption(DiskSpaceOptionBase,
help_text=_( help_text=_(
'The disk space option template that this disk space option is' 'The disk space option template that this disk space option is'
' based on' ' based on'
)) ),
on_delete=models.CASCADE)
class CustomerUserDatabaseOption(UserDatabaseOptionBase, class CustomerUserDatabaseOption(UserDatabaseOptionBase,
@ -459,7 +471,8 @@ class CustomerUserDatabaseOption(UserDatabaseOptionBase,
help_text=_( help_text=_(
'The user database option template that this database option is' 'The user database option template that this database option is'
' based on' ' based on'
)) ),
on_delete=models.CASCADE)
class CustomerMailboxOption(MailboxOptionBase, class CustomerMailboxOption(MailboxOptionBase,
@ -474,4 +487,5 @@ class CustomerMailboxOption(MailboxOptionBase,
verbose_name=_('mailbox option template'), verbose_name=_('mailbox option template'),
help_text=_( help_text=_(
'The mailbox option template that this mailbox option is based on' 'The mailbox option template that this mailbox option is based on'
)) ),
on_delete=models.CASCADE)

View File

@ -5,8 +5,8 @@ This module defines form classes for mailbox and mail address editing.
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from django import forms from django import forms
from django.core.urlresolvers import reverse
from django.core.validators import validate_email from django.core.validators import validate_email
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper

View File

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone import django.utils.timezone
import model_utils.fields import model_utils.fields
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('domains', '0001_initial'), ('domains', '0001_initial'),
('osusers', '0001_initial'), ('osusers', '0001_initial'),
@ -17,9 +16,15 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='MailAddress', name='MailAddress',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), 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)),
('active', models.BooleanField(default=True)), ('active', models.BooleanField(default=True)),
('localpart', models.CharField(max_length=128)), ('localpart', models.CharField(max_length=128)),
], ],
@ -32,9 +37,15 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='MailAddressForward', name='MailAddressForward',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), 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)),
('target', models.EmailField(max_length=254)), ('target', models.EmailField(max_length=254)),
], ],
options={ options={
@ -44,9 +55,15 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='MailAddressMailbox', name='MailAddressMailbox',
fields=[ fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('created', model_utils.fields.AutoCreatedField(
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), default=django.utils.timezone.now, verbose_name='created',
('mailaddress', models.OneToOneField(primary_key=True, serialize=False, to='managemails.MailAddress')), editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('mailaddress', models.OneToOneField(
primary_key=True, serialize=False,
to='managemails.MailAddress', on_delete=models.CASCADE)),
], ],
options={ options={
}, },
@ -55,13 +72,20 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='Mailbox', name='Mailbox',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), 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)),
('active', models.BooleanField(default=True)), ('active', models.BooleanField(default=True)),
('username', models.CharField(unique=True, max_length=128)), ('username', models.CharField(unique=True, max_length=128)),
('password', models.CharField(max_length=255)), ('password', models.CharField(max_length=255)),
('osuser', models.ForeignKey(to='osusers.User')), ('osuser', models.ForeignKey(
to='osusers.User', on_delete=models.CASCADE)),
], ],
options={ options={
'verbose_name': 'Mailbox', 'verbose_name': 'Mailbox',
@ -72,31 +96,34 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='mailaddressmailbox', model_name='mailaddressmailbox',
name='mailbox', name='mailbox',
field=models.ForeignKey(to='managemails.Mailbox'), field=models.ForeignKey(
to='managemails.Mailbox', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='mailaddressmailbox', name='mailaddressmailbox',
unique_together=set([('mailaddress', 'mailbox')]), unique_together={('mailaddress', 'mailbox')},
), ),
migrations.AddField( migrations.AddField(
model_name='mailaddressforward', model_name='mailaddressforward',
name='mailaddress', name='mailaddress',
field=models.ForeignKey(to='managemails.MailAddress'), field=models.ForeignKey(
to='managemails.MailAddress', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='mailaddressforward', name='mailaddressforward',
unique_together=set([('mailaddress', 'target')]), unique_together={('mailaddress', 'target')},
), ),
migrations.AddField( migrations.AddField(
model_name='mailaddress', model_name='mailaddress',
name='domain', name='domain',
field=models.ForeignKey(to='domains.MailDomain'), field=models.ForeignKey(
to='domains.MailDomain', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='mailaddress', name='mailaddress',
unique_together=set([('localpart', 'domain')]), unique_together={('localpart', 'domain')},
), ),
] ]

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('managemails', '0002_auto_20150117_1238'), ('managemails', '0002_auto_20150117_1238'),
] ]
@ -14,13 +13,17 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='mailaddressmailbox', model_name='mailaddressmailbox',
name='mailaddress', name='mailaddress',
field=models.OneToOneField(primary_key=True, serialize=False, to='managemails.MailAddress', verbose_name='mailaddress'), field=models.OneToOneField(
primary_key=True, serialize=False, to='managemails.MailAddress',
verbose_name='mailaddress', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterField( migrations.AlterField(
model_name='mailaddressmailbox', model_name='mailaddressmailbox',
name='mailbox', name='mailbox',
field=models.ForeignKey(verbose_name='mailbox', to='managemails.Mailbox'), field=models.ForeignKey(
verbose_name='mailbox', to='managemails.Mailbox',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('managemails', '0003_auto_20150124_2029'), ('managemails', '0003_auto_20150124_2029'),
] ]
@ -14,7 +13,9 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='mailaddress', model_name='mailaddress',
name='domain', name='domain',
field=models.ForeignKey(verbose_name='domain', to='domains.MailDomain'), field=models.ForeignKey(
verbose_name='domain', to='domains.MailDomain',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterField( migrations.AlterField(

View File

@ -109,7 +109,7 @@ class Mailbox(ActivateAbleMixin, TimeStampedModel):
This is the model class for a mailbox. This is the model class for a mailbox.
""" """
osuser = models.ForeignKey(OsUser) osuser = models.ForeignKey(OsUser, on_delete=models.CASCADE)
username = models.CharField(max_length=128, unique=True) username = models.CharField(max_length=128, unique=True)
password = models.CharField(max_length=255) password = models.CharField(max_length=255)
@ -162,7 +162,8 @@ class MailAddress(ActivateAbleMixin, TimeStampedModel, models.Model):
""" """
localpart = models.CharField(_('local part'), max_length=128) localpart = models.CharField(_('local part'), max_length=128)
domain = models.ForeignKey(MailDomain, verbose_name=_('domain')) domain = models.ForeignKey(
MailDomain, verbose_name=_('domain'), on_delete=models.CASCADE)
class Meta: class Meta:
ordering = ['domain', 'localpart'] ordering = ['domain', 'localpart']
@ -250,8 +251,10 @@ class MailAddressMailbox(TimeStampedModel, models.Model):
""" """
mailaddress = models.OneToOneField( mailaddress = models.OneToOneField(
MailAddress, verbose_name=_('mailaddress'), primary_key=True) MailAddress, verbose_name=_('mailaddress'), primary_key=True,
mailbox = models.ForeignKey(Mailbox, verbose_name=_('mailbox')) on_delete=models.CASCADE)
mailbox = models.ForeignKey(
Mailbox, verbose_name=_('mailbox'), on_delete=models.CASCADE)
class Meta: class Meta:
unique_together = ('mailaddress', 'mailbox') unique_together = ('mailaddress', 'mailbox')
@ -265,7 +268,7 @@ class MailAddressForward(TimeStampedModel, models.Model):
This is a model class to map mail addresses to forwarding addresses. This is a model class to map mail addresses to forwarding addresses.
""" """
mailaddress = models.ForeignKey(MailAddress) mailaddress = models.ForeignKey(MailAddress, on_delete=models.CASCADE)
target = models.EmailField(max_length=254) target = models.EmailField(max_length=254)
class Meta: class Meta:

View File

@ -5,7 +5,7 @@ This module defines operating system user related forms.
from __future__ import unicode_literals from __future__ import unicode_literals
from django import forms from django import forms
from django.core.urlresolvers import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
@ -79,7 +79,7 @@ class AddSshPublicKeyForm(forms.ModelForm):
keytext = self.cleaned_data.get('publickeytext') keytext = self.cleaned_data.get('publickeytext')
try: try:
SshPublicKey.objects.parse_keytext(keytext) SshPublicKey.objects.parse_keytext(keytext)
except: except ValueError:
raise forms.ValidationError(INVALID_SSH_PUBLIC_KEY) raise forms.ValidationError(INVALID_SSH_PUBLIC_KEY)
return keytext return keytext

View File

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone import django.utils.timezone
import model_utils.fields import model_utils.fields
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
] ]
@ -15,9 +14,15 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='AdditionalGroup', name='AdditionalGroup',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), 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={ options={
'verbose_name': 'Additional group', 'verbose_name': 'Additional group',
@ -28,9 +33,14 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='DeleteTaskResult', name='DeleteTaskResult',
fields=[ fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('created', model_utils.fields.AutoCreatedField(
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), default=django.utils.timezone.now, verbose_name='created',
('task_uuid', models.CharField(max_length=64, serialize=False, primary_key=True)), editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('task_uuid', models.CharField(
max_length=64, serialize=False, primary_key=True)),
('task_name', models.CharField(max_length=255, db_index=True)), ('task_name', models.CharField(max_length=255, db_index=True)),
('is_finished', models.BooleanField(default=False)), ('is_finished', models.BooleanField(default=False)),
('is_success', models.BooleanField(default=False)), ('is_success', models.BooleanField(default=False)),
@ -47,12 +57,21 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='Group', name='Group',
fields=[ fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('created', model_utils.fields.AutoCreatedField(
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), default=django.utils.timezone.now, verbose_name='created',
('groupname', models.CharField(unique=True, max_length=16, verbose_name='Group name')), editable=False)),
('gid', models.PositiveSmallIntegerField(unique=True, serialize=False, verbose_name='Group ID', primary_key=True)), ('modified', model_utils.fields.AutoLastModifiedField(
('descr', models.TextField(verbose_name='Description', blank=True)), default=django.utils.timezone.now, verbose_name='modified',
('passwd', models.CharField(max_length=128, verbose_name='Group password', blank=True)), editable=False)),
('groupname', models.CharField(
unique=True, max_length=16, verbose_name='Group name')),
('gid', models.PositiveSmallIntegerField(
unique=True, serialize=False, verbose_name='Group ID',
primary_key=True)),
('descr', models.TextField(
verbose_name='Description', blank=True)),
('passwd', models.CharField(
max_length=128, verbose_name='Group password', blank=True)),
], ],
options={ options={
'verbose_name': 'Group', 'verbose_name': 'Group',
@ -63,15 +82,21 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='GroupTaskResult', name='GroupTaskResult',
fields=[ fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('created', model_utils.fields.AutoCreatedField(
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), default=django.utils.timezone.now, verbose_name='created',
('task_uuid', models.CharField(max_length=64, serialize=False, primary_key=True)), editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('task_uuid', models.CharField(
max_length=64, serialize=False, primary_key=True)),
('task_name', models.CharField(max_length=255, db_index=True)), ('task_name', models.CharField(max_length=255, db_index=True)),
('is_finished', models.BooleanField(default=False)), ('is_finished', models.BooleanField(default=False)),
('is_success', models.BooleanField(default=False)), ('is_success', models.BooleanField(default=False)),
('state', models.CharField(max_length=10)), ('state', models.CharField(max_length=10)),
('result_body', models.TextField(blank=True)), ('result_body', models.TextField(blank=True)),
('group', models.ForeignKey(to='osusers.Group')), ('group', models.ForeignKey(
to='osusers.Group', on_delete=models.CASCADE)),
], ],
options={ options={
'abstract': False, 'abstract': False,
@ -81,13 +106,23 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='User', name='User',
fields=[ fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('created', model_utils.fields.AutoCreatedField(
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), default=django.utils.timezone.now, verbose_name='created',
('username', models.CharField(unique=True, max_length=64, verbose_name='User name')), editable=False)),
('uid', models.PositiveSmallIntegerField(unique=True, serialize=False, verbose_name='User ID', primary_key=True)), ('modified', model_utils.fields.AutoLastModifiedField(
('gecos', models.CharField(max_length=128, verbose_name='Gecos field', blank=True)), default=django.utils.timezone.now, verbose_name='modified',
('homedir', models.CharField(max_length=256, verbose_name='Home directory')), editable=False)),
('shell', models.CharField(max_length=64, verbose_name='Login shell')), ('username', models.CharField(
unique=True, max_length=64, verbose_name='User name')),
('uid', models.PositiveSmallIntegerField(
unique=True, serialize=False, verbose_name='User ID',
primary_key=True)),
('gecos', models.CharField(
max_length=128, verbose_name='Gecos field', blank=True)),
('homedir', models.CharField(
max_length=256, verbose_name='Home directory')),
('shell', models.CharField(
max_length=64, verbose_name='Login shell')),
], ],
options={ options={
'verbose_name': 'Benutzer', 'verbose_name': 'Benutzer',
@ -98,16 +133,43 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='Shadow', name='Shadow',
fields=[ fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('created', model_utils.fields.AutoCreatedField(
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), default=django.utils.timezone.now, verbose_name='created',
('user', models.OneToOneField(primary_key=True, serialize=False, to='osusers.User', verbose_name='Benutzer')), editable=False)),
('passwd', models.CharField(max_length=128, verbose_name='Encrypted password')), ('modified', model_utils.fields.AutoLastModifiedField(
('changedays', models.PositiveSmallIntegerField(help_text='This is expressed in days since Jan 1, 1970', null=True, verbose_name='Date of last change', blank=True)), default=django.utils.timezone.now, verbose_name='modified',
('minage', models.PositiveSmallIntegerField(help_text='Minimum number of days before the password can be changed', null=True, verbose_name='Minimum age', blank=True)), editable=False)),
('maxage', models.PositiveSmallIntegerField(help_text='Maximum number of days after which the password has to be changed', null=True, verbose_name='Maximum age', blank=True)), ('user', models.OneToOneField(
('gracedays', models.PositiveSmallIntegerField(help_text='The number of days before the password is going to expire', null=True, verbose_name='Grace period', blank=True)), primary_key=True, serialize=False, to='osusers.User',
('inactdays', models.PositiveSmallIntegerField(help_text='The number of days after the password has expired during which the password should still be accepted', null=True, verbose_name='Inactivity period', blank=True)), verbose_name='Benutzer', on_delete=models.CASCADE)),
('expiredays', models.PositiveSmallIntegerField(default=None, help_text='The date of expiration of the account, expressed as number of days since Jan 1, 1970', null=True, verbose_name='Account expiration date', blank=True)), ('passwd', models.CharField(
max_length=128, verbose_name='Encrypted password')),
('changedays', models.PositiveSmallIntegerField(
help_text='This is expressed in days since Jan 1, 1970',
null=True, verbose_name='Date of last change', blank=True)),
('minage', models.PositiveSmallIntegerField(
help_text='Minimum number of days before the password can '
'be changed',
null=True, verbose_name='Minimum age', blank=True)),
('maxage', models.PositiveSmallIntegerField(
help_text='Maximum number of days after which the '
'password has to be changed',
null=True, verbose_name='Maximum age', blank=True)),
('gracedays', models.PositiveSmallIntegerField(
help_text='The number of days before the password is '
'going to expire',
null=True, verbose_name='Grace period', blank=True)),
('inactdays', models.PositiveSmallIntegerField(
help_text='The number of days after the password has '
'expired during which the password should still '
'be accepted',
null=True, verbose_name='Inactivity period', blank=True)),
('expiredays', models.PositiveSmallIntegerField(
default=None,
help_text='The date of expiration of the account, '
'expressed as number of days since Jan 1, 1970',
null=True, verbose_name='Account expiration date',
blank=True)),
], ],
options={ options={
'verbose_name': 'Shadow password', 'verbose_name': 'Shadow password',
@ -118,15 +180,21 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='UserTaskResult', name='UserTaskResult',
fields=[ fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), ('created', model_utils.fields.AutoCreatedField(
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), default=django.utils.timezone.now, verbose_name='created',
('task_uuid', models.CharField(max_length=64, serialize=False, primary_key=True)), editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('task_uuid', models.CharField(
max_length=64, serialize=False, primary_key=True)),
('task_name', models.CharField(max_length=255, db_index=True)), ('task_name', models.CharField(max_length=255, db_index=True)),
('is_finished', models.BooleanField(default=False)), ('is_finished', models.BooleanField(default=False)),
('is_success', models.BooleanField(default=False)), ('is_success', models.BooleanField(default=False)),
('state', models.CharField(max_length=10)), ('state', models.CharField(max_length=10)),
('result_body', models.TextField(blank=True)), ('result_body', models.TextField(blank=True)),
('user', models.ForeignKey(to='osusers.User')), ('user', models.ForeignKey(
to='osusers.User', on_delete=models.CASCADE)),
], ],
options={ options={
'abstract': False, 'abstract': False,
@ -136,23 +204,27 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='user', model_name='user',
name='group', name='group',
field=models.ForeignKey(verbose_name='Group', to='osusers.Group'), field=models.ForeignKey(
verbose_name='Group', to='osusers.Group',
on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AddField( migrations.AddField(
model_name='additionalgroup', model_name='additionalgroup',
name='group', name='group',
field=models.ForeignKey(to='osusers.Group'), field=models.ForeignKey(
to='osusers.Group', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AddField( migrations.AddField(
model_name='additionalgroup', model_name='additionalgroup',
name='user', name='user',
field=models.ForeignKey(to='osusers.User'), field=models.ForeignKey(
to='osusers.User', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='additionalgroup', name='additionalgroup',
unique_together=set([('user', 'group')]), unique_together={('user', 'group')},
), ),
] ]

View File

@ -6,7 +6,6 @@ from django.conf import settings
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('osusers', '0002_auto_20141226_1456'), ('osusers', '0002_auto_20141226_1456'),
@ -16,7 +15,9 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='user', model_name='user',
name='customer', name='customer',
field=models.ForeignKey(default=1, to=settings.AUTH_USER_MODEL), field=models.ForeignKey(
default=1, to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE),
preserve_default=False, preserve_default=False,
), ),
] ]

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('osusers', '0003_user_customer'), ('osusers', '0003_user_customer'),
] ]
@ -18,7 +17,9 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='shadow', model_name='shadow',
name='user', name='user',
field=models.OneToOneField(primary_key=True, serialize=False, to='osusers.User', verbose_name='User'), field=models.OneToOneField(
primary_key=True, serialize=False, to='osusers.User',
verbose_name='User', on_delete=models.CASCADE),
preserve_default=True, preserve_default=True,
), ),
] ]

View File

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone import django.utils.timezone
import model_utils.fields import model_utils.fields
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('osusers', '0004_auto_20150104_1751'), ('osusers', '0004_auto_20150104_1751'),
] ]
@ -16,13 +15,25 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='SshPublicKey', name='SshPublicKey',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), primary_key=True)),
('algorithm', models.CharField(max_length=20, verbose_name='Algorithm')), ('created', model_utils.fields.AutoCreatedField(
('data', models.TextField(help_text='Base64 encoded key bytes', verbose_name='Key bytes')), default=django.utils.timezone.now, verbose_name='created',
('comment', models.TextField(verbose_name='Comment', blank=True)), editable=False)),
('user', models.ForeignKey(verbose_name='User', to='osusers.User')), ('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('algorithm', models.CharField(
max_length=20, verbose_name='Algorithm')),
('data', models.TextField(
help_text='Base64 encoded key bytes',
verbose_name='Key bytes')),
('comment', models.TextField(
verbose_name='Comment', blank=True)),
('user', models.ForeignKey(
verbose_name='User', to='osusers.User',
on_delete=models.CASCADE)),
], ],
options={ options={
'verbose_name': 'SSH public key', 'verbose_name': 'SSH public key',
@ -32,6 +43,6 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='sshpublickey', name='sshpublickey',
unique_together=set([('user', 'algorithm', 'data')]), unique_together={('user', 'algorithm', 'data')},
), ),
] ]

View File

@ -198,11 +198,13 @@ class User(TimeStampedModel, models.Model):
_('User name'), max_length=64, unique=True) _('User name'), max_length=64, unique=True)
uid = models.PositiveSmallIntegerField( uid = models.PositiveSmallIntegerField(
_('User ID'), unique=True, primary_key=True) _('User ID'), unique=True, primary_key=True)
group = models.ForeignKey(Group, verbose_name=_('Group')) group = models.ForeignKey(
Group, verbose_name=_('Group'), on_delete=models.CASCADE)
gecos = models.CharField(_('Gecos field'), max_length=128, blank=True) gecos = models.CharField(_('Gecos field'), max_length=128, blank=True)
homedir = models.CharField(_('Home directory'), max_length=256) homedir = models.CharField(_('Home directory'), max_length=256)
shell = models.CharField(_('Login shell'), max_length=64) shell = models.CharField(_('Login shell'), max_length=64)
customer = models.ForeignKey(settings.AUTH_USER_MODEL) customer = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
objects = UserManager() objects = UserManager()
@ -307,7 +309,9 @@ class Shadow(TimeStampedModel, models.Model):
entry. entry.
""" """
user = models.OneToOneField(User, primary_key=True, verbose_name=_('User')) user = models.OneToOneField(
User, primary_key=True, verbose_name=_('User'),
on_delete=models.CASCADE)
passwd = models.CharField(_('Encrypted password'), max_length=128) passwd = models.CharField(_('Encrypted password'), max_length=128)
changedays = models.PositiveSmallIntegerField( changedays = models.PositiveSmallIntegerField(
_('Date of last change'), _('Date of last change'),
@ -364,8 +368,8 @@ class AdditionalGroup(TimeStampedModel, models.Model):
:py:class:`operating system user <osusers.models.User>`. :py:class:`operating system user <osusers.models.User>`.
""" """
user = models.ForeignKey(User) user = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(Group) group = models.ForeignKey(Group, on_delete=models.CASCADE)
class Meta: class Meta:
unique_together = ('user', 'group') unique_together = ('user', 'group')
@ -498,7 +502,8 @@ class SshPublicKey(TimeStampedModel):
system user <osusers.models.User>`. system user <osusers.models.User>`.
""" """
user = models.ForeignKey(User, verbose_name=_('User')) user = models.ForeignKey(
User, verbose_name=_('User'), on_delete=models.CASCADE)
algorithm = models.CharField(_('Algorithm'), max_length=20) algorithm = models.CharField(_('Algorithm'), max_length=20)
data = models.TextField(_('Key bytes'), data = models.TextField(_('Key bytes'),
help_text=_('Base64 encoded key bytes')) help_text=_('Base64 encoded key bytes'))

View File

@ -4,8 +4,8 @@ This module defines the views for gnuviechadmin operating system user handling.
""" """
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from django.core.urlresolvers import reverse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.urls import reverse
from django.views.generic import ( from django.views.generic import (
CreateView, CreateView,
DeleteView, DeleteView,

View File

@ -5,7 +5,7 @@ This module defines form classes for user database editing.
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from django import forms from django import forms
from django.core.urlresolvers import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper

View File

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone import django.utils.timezone
import model_utils.fields import model_utils.fields
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('osusers', '0004_auto_20150104_1751'), ('osusers', '0004_auto_20150104_1751'),
] ]
@ -16,12 +15,22 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='DatabaseUser', name='DatabaseUser',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), primary_key=True)),
('name', models.CharField(max_length=63, verbose_name='username')), ('created', model_utils.fields.AutoCreatedField(
('db_type', models.PositiveSmallIntegerField(verbose_name='database type', choices=[(0, 'PostgreSQL'), (1, 'MySQL')])), default=django.utils.timezone.now, verbose_name='created',
('osuser', models.ForeignKey(to='osusers.User')), 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={ options={
'verbose_name': 'database user', 'verbose_name': 'database user',
@ -32,11 +41,20 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='UserDatabase', name='UserDatabase',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), verbose_name='ID', serialize=False, auto_created=True,
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), primary_key=True)),
('db_name', models.CharField(max_length=63, verbose_name='database name')), ('created', model_utils.fields.AutoCreatedField(
('db_user', models.ForeignKey(verbose_name='database user', to='userdbs.DatabaseUser')), 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={ options={
'verbose_name': 'user database', 'verbose_name': 'user database',
@ -46,10 +64,10 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='userdatabase', name='userdatabase',
unique_together=set([('db_name', 'db_user')]), unique_together={('db_name', 'db_user')},
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='databaseuser', name='databaseuser',
unique_together=set([('name', 'db_type')]), unique_together={('name', 'db_type')},
), ),
] ]

View File

@ -83,7 +83,7 @@ class DatabaseUserManager(models.Manager):
@python_2_unicode_compatible @python_2_unicode_compatible
class DatabaseUser(TimeStampedModel, models.Model): class DatabaseUser(TimeStampedModel, models.Model):
osuser = models.ForeignKey(OsUser) osuser = models.ForeignKey(OsUser, on_delete=models.CASCADE)
name = models.CharField( name = models.CharField(
_('username'), max_length=63) _('username'), max_length=63)
db_type = models.PositiveSmallIntegerField( db_type = models.PositiveSmallIntegerField(
@ -203,7 +203,9 @@ class UserDatabase(TimeStampedModel, models.Model):
# MySQL limits to 64, PostgreSQL to 63 characters # MySQL limits to 64, PostgreSQL to 63 characters
db_name = models.CharField( db_name = models.CharField(
_('database name'), max_length=63) _('database name'), max_length=63)
db_user = models.ForeignKey(DatabaseUser, verbose_name=_('database user')) db_user = models.ForeignKey(
DatabaseUser, verbose_name=_('database user'),
on_delete=models.CASCADE)
objects = UserDatabaseManager() objects = UserDatabaseManager()

View File

@ -5,7 +5,7 @@ This module defines form classes for website editing.
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from django import forms from django import forms
from django.core.urlresolvers import reverse from django.urls import reverse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from crispy_forms.bootstrap import AppendedText from crispy_forms.bootstrap import AppendedText

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models, migrations from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('osusers', '0004_auto_20150104_1751'), ('osusers', '0004_auto_20150104_1751'),
('domains', '0002_auto_20150124_1909'), ('domains', '0002_auto_20150124_1909'),
@ -15,11 +14,19 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='Website', name='Website',
fields=[ fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(
('subdomain', models.CharField(max_length=64, verbose_name='sub domain')), verbose_name='ID', serialize=False, auto_created=True,
('wildcard', models.BooleanField(default=False, verbose_name='wildcard')), primary_key=True)),
('domain', models.ForeignKey(verbose_name='domain', to='domains.HostingDomain')), ('subdomain', models.CharField(
('osuser', models.ForeignKey(verbose_name='operating system user', to='osusers.User')), max_length=64, verbose_name='sub domain')),
('wildcard', models.BooleanField(
default=False, verbose_name='wildcard')),
('domain', models.ForeignKey(
verbose_name='domain', to='domains.HostingDomain',
on_delete=models.CASCADE)),
('osuser', models.ForeignKey(
verbose_name='operating system user', to='osusers.User',
on_delete=models.CASCADE)),
], ],
options={ options={
'verbose_name': 'website', 'verbose_name': 'website',
@ -29,6 +36,6 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='website', name='website',
unique_together=set([('domain', 'subdomain')]), unique_together={('domain', 'subdomain')},
), ),
] ]

View File

@ -34,9 +34,10 @@ class Website(models.Model):
subdomain = models.CharField( subdomain = models.CharField(
_('sub domain'), max_length=64) _('sub domain'), max_length=64)
osuser = models.ForeignKey( osuser = models.ForeignKey(
OsUser, verbose_name=_('operating system user')) OsUser, verbose_name=_('operating system user'),
on_delete=models.CASCADE)
domain = models.ForeignKey( domain = models.ForeignKey(
HostingDomain, verbose_name=_('domain')) HostingDomain, models.CASCADE, verbose_name=_('domain'))
wildcard = models.BooleanField(_('wildcard'), default=False) wildcard = models.BooleanField(_('wildcard'), default=False)
class Meta: class Meta:

View File

@ -1,39 +0,0 @@
#!/bin/sh -
apt-get update
apt-get install -y python-cryptography
# We just download the bootstrap script by default and execute that.
if [ -x /usr/bin/fetch ]; then
/usr/bin/fetch -o - https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.sh | sh -s -- "$@"
elif [ -x /usr/bin/curl ]; then
/usr/bin/curl -L https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.sh | sh -s -- "$@"
else
python \
-c 'import urllib; print urllib.urlopen("https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.sh").read()' \
| sh -s -- "$@"
fi
cat >/etc/salt/minion <<EOF
file_client: local
file_roots:
base:
- /srv/salt/
pillar_roots:
base:
- /srv/pillar
log_file: file:///dev/log
EOF
umask 077
cat >/etc/salt/grains <<EOF
roles:
- redis-server
- rabbitmq-server
- gnuviechadmin.database
- gnuviechadmin.queues
- gnuviechadmin.webinterface
EOF