Commit 1d7860df authored by Nikolai R Kristiansen's avatar Nikolai R Kristiansen

Upgrade to django 2.2

Also bump django suit to v2 alpha
Remove python2 transitional support
parent 47b69a9e
import ipaddress
from django.conf import settings
from django.contrib import admin, messages
from django.db.models import Count
......@@ -9,6 +10,9 @@ from mdb.models import (
HostType, DhcpConfig, DomainAAAARecord)
admin.site.site_header = settings.ADMIN_SITE_NAME
class Ip6AddressInline(admin.TabularInline):
model = Ip6Address
extra = 0
......
from __future__ import unicode_literals
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
......
from django.apps import AppConfig
from suit.apps import DjangoSuitConfig
from suit.menu import ParentItem, ChildItem
class MdbAppConfig(AppConfig):
......@@ -8,3 +10,21 @@ class MdbAppConfig(AppConfig):
def ready(self):
# all models are loaded, now attach signals
import mdb.signals # noqa
class SuitConfig(DjangoSuitConfig):
# Configuration for django-suit
# See super class for configuration options
# Ref: https://github.com/darklow/django-suit/blob/v2/demo/demo/apps.py#L6
verbose_name = 'MDB'
list_per_page = 25
SEARCH_URL = '/admin/mdb/host/' # TODO
layout = 'vertical'
menu = [
ParentItem('MDB', children=[ChildItem(model='mdb.host')]),
ParentItem('Settings', children=[
ChildItem(model='auth.user'),
ChildItem(model='auth.group')
], icon='fa fa-cog')
]
from __future__ import with_statement
import os
import sys
from difflib import context_diff
from django.core.management.base import BaseCommand
from django.core.mail import mail_admins
try:
from subprocess import getstatusoutput
except ImportError:
from commands import getstatusoutput
from subprocess import getstatusoutput
from mdb.models import DhcpConfig
......
from __future__ import with_statement
import os
import sys
from itertools import chain
from difflib import context_diff
from django.core.management.base import BaseCommand
from django.core.mail import mail_admins
try:
from subprocess import getstatusoutput
except ImportError:
from commands import getstatusoutput
from subprocess import getstatusoutput
from mdb.models import Domain, Ip4Subnet, Ip6Subnet
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import re
import django.core.validators
......@@ -81,7 +79,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=256)),
('target', models.CharField(max_length=256)),
('created_date', models.DateTimeField(auto_now_add=True)),
('domain', models.ForeignKey(to='mdb.Domain')),
('domain', models.ForeignKey(to='mdb.Domain', on_delete=models.CASCADE)),
],
options={
},
......@@ -94,7 +92,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=256)),
('target', models.CharField(max_length=256)),
('created_date', models.DateTimeField(auto_now_add=True)),
('domain', models.ForeignKey(to='mdb.Domain')),
('domain', models.ForeignKey(to='mdb.Domain', on_delete=models.CASCADE)),
],
options={
},
......@@ -112,7 +110,7 @@ class Migration(migrations.Migration):
('port', models.IntegerField()),
('target', models.CharField(max_length=256)),
('created_date', models.DateTimeField(auto_now_add=True)),
('domain', models.ForeignKey(to='mdb.Domain')),
('domain', models.ForeignKey(to='mdb.Domain', on_delete=models.CASCADE)),
],
options={
},
......@@ -125,7 +123,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=256)),
('target', models.CharField(max_length=256)),
('created_date', models.DateTimeField(auto_now_add=True)),
('domain', models.ForeignKey(to='mdb.Domain')),
('domain', models.ForeignKey(to='mdb.Domain', on_delete=models.CASCADE)),
],
options={
},
......@@ -174,8 +172,8 @@ class Migration(migrations.Migration):
('pxe_filename', models.CharField(max_length=64, blank=True)),
('dhcp_client', models.BooleanField(default=False)),
('created_date', models.DateTimeField(auto_now_add=True)),
('domain', models.ForeignKey(to='mdb.Domain')),
('host', models.ForeignKey(to='mdb.Host')),
('domain', models.ForeignKey(to='mdb.Domain', on_delete=models.CASCADE)),
('host', models.ForeignKey(to='mdb.Host', on_delete=models.CASCADE)),
],
options={
},
......@@ -217,7 +215,7 @@ class Migration(migrations.Migration):
('dhcp_dynamic', models.BooleanField(default=False)),
('dhcp_dynamic_start', models.IPAddressField(null=True, blank=True)),
('dhcp_dynamic_end', models.IPAddressField(null=True, blank=True)),
('dhcp_config', models.ForeignKey(to='mdb.DhcpConfig')),
('dhcp_config', models.ForeignKey(to='mdb.DhcpConfig', on_delete=models.CASCADE)),
],
options={
'verbose_name': 'IPv4 subnet',
......@@ -229,7 +227,7 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('address', models.CharField(max_length=64)),
('interface', models.ForeignKey(to='mdb.Interface')),
('interface', models.ForeignKey(to='mdb.Interface', on_delete=models.CASCADE)),
],
options={
'verbose_name': 'IPv6 address',
......@@ -309,7 +307,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='operatingsystem',
name='architecture',
field=models.ForeignKey(to='mdb.OsArchitecture'),
field=models.ForeignKey(to='mdb.OsArchitecture', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
......@@ -321,7 +319,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='ip6address',
name='subnet',
field=models.ForeignKey(to='mdb.Ip6Subnet'),
field=models.ForeignKey(to='mdb.Ip6Subnet', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
......@@ -333,25 +331,25 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='ip4address',
name='subnet',
field=models.ForeignKey(to='mdb.Ip4Subnet'),
field=models.ForeignKey(to='mdb.Ip4Subnet', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
model_name='interface',
name='ip4address',
field=models.ForeignKey(null=True, blank=True, to='mdb.Ip4Address', unique=True),
field=models.ForeignKey(null=True, blank=True, to='mdb.Ip4Address', unique=True, on_delete=models.SET_NULL),
preserve_default=True,
),
migrations.AddField(
model_name='host',
name='host_type',
field=models.ForeignKey(to='mdb.HostType'),
field=models.ForeignKey(to='mdb.HostType', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
model_name='host',
name='operating_system',
field=models.ForeignKey(to='mdb.OperatingSystem'),
field=models.ForeignKey(to='mdb.OperatingSystem', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
......@@ -369,13 +367,13 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='dhcpoption',
name='ip4subnet',
field=models.ForeignKey(to='mdb.Ip4Subnet'),
field=models.ForeignKey(to='mdb.Ip4Subnet', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
model_name='dhcpcustomfield',
name='ip4subnet',
field=models.ForeignKey(to='mdb.Ip4Subnet'),
field=models.ForeignKey(to='mdb.Ip4Subnet', on_delete=models.CASCADE),
preserve_default=True,
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.core.validators
import re
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db.migrations import RunPython
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.core.validators
import re
......@@ -35,7 +33,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='interface',
name='ip4address',
field=models.OneToOneField(to='mdb.Ip4Address', null=True, blank=True),
field=models.OneToOneField(to='mdb.Ip4Address', null=True, blank=True, on_delete=models.SET_NULL),
),
migrations.AlterField(
model_name='interface',
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import re
import django.core.validators
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
......@@ -18,7 +16,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=256)),
('target', models.GenericIPAddressField(protocol='IPv6')),
('created_date', models.DateTimeField(auto_now_add=True)),
('domain', models.ForeignKey(to='mdb.Domain')),
('domain', models.ForeignKey(to='mdb.Domain', on_delete=models.CASCADE)),
],
),
migrations.AlterField(
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
......
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from mdb.pxe import host_as_pxe_files
......@@ -9,7 +8,6 @@ import ipaddress
import datetime
@python_2_unicode_compatible
class Nameserver(models.Model):
hostname = models.CharField(max_length=256)
......@@ -17,7 +15,6 @@ class Nameserver(models.Model):
return self.hostname
@python_2_unicode_compatible
class MailExchange(models.Model):
priority = models.IntegerField()
hostname = models.CharField(max_length=256)
......@@ -26,7 +23,6 @@ class MailExchange(models.Model):
return "(" + str(self.priority) + ") " + self.hostname
@python_2_unicode_compatible
class Domain(models.Model):
domain_name = models.CharField(max_length=256)
domain_soa = models.CharField(max_length=256)
......@@ -124,7 +120,6 @@ class Domain(models.Model):
return content
@python_2_unicode_compatible
class DomainSrvRecord(models.Model):
srvce = models.CharField(max_length=64)
prot = models.CharField(max_length=64)
......@@ -133,7 +128,7 @@ class DomainSrvRecord(models.Model):
weight = models.IntegerField()
port = models.IntegerField()
target = models.CharField(max_length=256)
domain = models.ForeignKey(Domain)
domain = models.ForeignKey(Domain, models.CASCADE)
created_date = models.DateTimeField(auto_now_add=True)
def as_record(self):
......@@ -152,11 +147,10 @@ class DomainSrvRecord(models.Model):
return self.as_record()
@python_2_unicode_compatible
class DomainTxtRecord(models.Model):
name = models.CharField(max_length=256)
target = models.CharField(max_length=256)
domain = models.ForeignKey(Domain)
domain = models.ForeignKey(Domain, models.CASCADE)
created_date = models.DateTimeField(auto_now_add=True)
def as_record(self):
......@@ -166,11 +160,10 @@ class DomainTxtRecord(models.Model):
return self.as_record()
@python_2_unicode_compatible
class DomainCnameRecord(models.Model):
name = models.CharField(max_length=256)
target = models.CharField(max_length=256)
domain = models.ForeignKey(Domain)
domain = models.ForeignKey(Domain, models.CASCADE)
created_date = models.DateTimeField(auto_now_add=True)
def as_record(self):
......@@ -180,11 +173,10 @@ class DomainCnameRecord(models.Model):
return self.as_record()
@python_2_unicode_compatible
class DomainARecord(models.Model):
name = models.CharField(max_length=256)
target = models.GenericIPAddressField(protocol='IPv4')
domain = models.ForeignKey(Domain)
domain = models.ForeignKey(Domain, models.CASCADE)
created_date = models.DateTimeField(auto_now_add=True)
def as_record(self):
......@@ -194,11 +186,10 @@ class DomainARecord(models.Model):
return self.as_record()
@python_2_unicode_compatible
class DomainAAAARecord(models.Model):
name = models.CharField(max_length=256)
target = models.GenericIPAddressField(protocol='IPv6')
domain = models.ForeignKey(Domain)
domain = models.ForeignKey(Domain, models.CASCADE)
created_date = models.DateTimeField(auto_now_add=True)
def as_record(self):
......@@ -208,7 +199,6 @@ class DomainAAAARecord(models.Model):
return self.as_record()
@python_2_unicode_compatible
class DhcpConfig(models.Model):
serial = models.IntegerField()
active_serial = models.IntegerField()
......@@ -270,7 +260,6 @@ class DhcpConfig(models.Model):
verbose_name = 'DHCP config'
@python_2_unicode_compatible
class Ip6Subnet(models.Model):
name = models.CharField(max_length=255)
network = models.CharField(max_length=255)
......@@ -340,7 +329,6 @@ class Ip6Subnet(models.Model):
verbose_name = 'IPv6 subnet'
@python_2_unicode_compatible
class Ip4Subnet(models.Model):
name = models.CharField(max_length=256)
netmask = models.GenericIPAddressField(protocol='IPv4')
......@@ -362,7 +350,7 @@ class Ip4Subnet(models.Model):
dhcp_dynamic = models.BooleanField(default=False)
dhcp_dynamic_start = models.GenericIPAddressField(protocol='IPv4', null=True, blank=True)
dhcp_dynamic_end = models.GenericIPAddressField(protocol='IPv4', null=True, blank=True)
dhcp_config = models.ForeignKey(DhcpConfig)
dhcp_config = models.ForeignKey(DhcpConfig, models.CASCADE)
def __str__(self):
return self.network + " (" + self.name + ")"
......@@ -409,11 +397,10 @@ class Ip4Subnet(models.Model):
verbose_name = 'IPv4 subnet'
@python_2_unicode_compatible
class DhcpOption(models.Model):
key = models.CharField(max_length=255)
value = models.CharField(max_length=255)
ip4subnet = models.ForeignKey(Ip4Subnet)
ip4subnet = models.ForeignKey(Ip4Subnet, models.CASCADE)
def __str__(self):
return self.key + " " + self.value
......@@ -424,15 +411,14 @@ class DhcpOption(models.Model):
class DhcpCustomField(models.Model):
value = models.CharField(max_length=255)
ip4subnet = models.ForeignKey(Ip4Subnet)
ip4subnet = models.ForeignKey(Ip4Subnet, models.CASCADE)
class Meta:
verbose_name = 'DHCP custom field'
@python_2_unicode_compatible
class Ip4Address(models.Model):
subnet = models.ForeignKey(Ip4Subnet)
subnet = models.ForeignKey(Ip4Subnet, models.CASCADE)
address = models.GenericIPAddressField(protocol='IPv4')
last_contact = models.DateTimeField(null=True, blank=True)
ping_avg_rtt = models.FloatField(null=True, blank=True)
......@@ -445,7 +431,6 @@ class Ip4Address(models.Model):
verbose_name_plural = 'IPv4 addresses'
@python_2_unicode_compatible
class HostType(models.Model):
host_type = models.CharField(max_length=64)
description = models.CharField(max_length=1024)
......@@ -460,7 +445,6 @@ class HostType(models.Model):
ordering = ("host_type",)
@python_2_unicode_compatible
class OperatingSystem(models.Model):
OS_ARCHITECTURES = (
('mips', _('MIPS')),
......@@ -488,7 +472,6 @@ class OperatingSystem(models.Model):
ordering = ("name", "version")
@python_2_unicode_compatible
class Host(models.Model):
location = models.CharField(max_length=1024)
brand = models.CharField(max_length=1024)
......@@ -498,9 +481,9 @@ class Host(models.Model):
serial_number = models.CharField(max_length=256)
description = models.CharField(max_length=1024)
created_date = models.DateTimeField(auto_now_add=True)
host_type = models.ForeignKey(HostType)
host_type = models.ForeignKey(HostType, models.CASCADE) # FIXME: SET_NULL?
virtual = models.BooleanField(default=False)
operating_system = models.ForeignKey(OperatingSystem)
operating_system = models.ForeignKey(OperatingSystem, models.CASCADE) # FIXME: SET_NULL?
request_kerberos_principal = models.BooleanField(default=False)
kerberos_principal_created = models.BooleanField(default=False, editable=False)
......@@ -517,16 +500,15 @@ class Host(models.Model):
return host_as_pxe_files(self)
@python_2_unicode_compatible
class Interface(models.Model):
name = models.CharField(max_length=128)
macaddr = models.CharField(max_length=17, validators=[validate_macaddr])
pxe_filename = models.CharField(max_length=64, blank=True)
dhcp_client = models.BooleanField(default=False)
host = models.ForeignKey(Host)
ip4address = models.OneToOneField(Ip4Address, blank=True, null=True)
host = models.ForeignKey(Host, models.CASCADE)
ip4address = models.OneToOneField(Ip4Address, blank=True, null=True, on_delete=models.SET_NULL)
created_date = models.DateTimeField(auto_now_add=True)
domain = models.ForeignKey(Domain)
domain = models.ForeignKey(Domain, models.CASCADE)
def __str__(self):
return "%s (%s on %s)" % (self.macaddr, self.name, self.host.hostname)
......@@ -535,11 +517,10 @@ class Interface(models.Model):
return self.ip6address_set.exists()
@python_2_unicode_compatible
class Ip6Address(models.Model):
subnet = models.ForeignKey(Ip6Subnet)
subnet = models.ForeignKey(Ip6Subnet, models.CASCADE)
address = models.GenericIPAddressField(protocol='IPv6')
interface = models.ForeignKey(Interface)
interface = models.ForeignKey(Interface, models.CASCADE)
def full_address(self):
return self.subnet.network + self.address
......
......@@ -3,8 +3,9 @@ import io
from django.conf import settings
from django.contrib.auth.models import User
from django.core.management import call_command
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.urls import reverse
from mdb.pxe import render_pxelinux_cfg
from rest_framework.authtoken.models import Token
from rest_framework.test import APITestCase
......
......@@ -4,7 +4,7 @@ import re
def format_domain_serial_and_add_one(serial):
today = datetime.datetime.now()
res = re.findall("^%4d%02d%02d(\d\d)$" % (
res = re.findall(r"^%4d%02d%02d(\d\d)$" % (
today.year, today.month, today.day), str(serial), re.DOTALL)
if len(res) == 0:
......
from __future__ import unicode_literals
from django.core.validators import RegexValidator
import re
......
import os
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP
import raven
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DEBUG = True
TEMPLATE_DEBUG = DEBUG
DEBUG = os.getenv('DJANGO_DEBUG', True)
ADMINS = (
('System Administrator', 'sysadmin@example.com'),
......@@ -31,26 +27,18 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
ADMIN_MEDIA_PREFIX = '/media/'
# Static
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = '@4ps=ebofcpv8sb#y7gm896=l&l*u0u-pgo7bcdj%+(k+2lqnl'
MIDDLEWARE_CLASSES = (
MIDDLEWARE = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
......@@ -60,11 +48,25 @@ MIDDLEWARE_CLASSES = (
ROOT_URLCONF = 'mdbsite.urls'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
INSTALLED_APPS = (
'django.contrib.auth',
......@@ -73,21 +75,19 @@ INSTALLED_APPS = (
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'suit',
'mdb.apps.SuitConfig',
'django.contrib.admin',
'rest_framework',
'rest_framework.authtoken',
'django_extensions',
'raven.contrib.django.raven_compat',
'mdb',
)
EMAIL_SUBJECT_PREFIX = '[MDB] '
TEMPLATE_CONTEXT_PROCESSORS = TCP + (
'django.core.context_processors.request', # for django-suit
)
# Logging
LOGGING = {
'version': 1,
......@@ -99,10 +99,6 @@ LOGGING = {
},
},
'handlers': {
'sentry': {
'level': 'WARNING', # To capture more than ERROR, change to WARNING, INFO, etc.
'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
......@@ -112,58 +108,16 @@ LOGGING = {
'loggers': {
'root': {
'level': 'WARNING',
'handlers': ['sentry'],
'handlers': ['console'],
},
'django.db.backends': {
'level': 'ERROR',
'handlers': ['console'],
'propagate': False,
},
'raven': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False,
},
'sentry.errors': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False,
},