Bump everything (python3 ftw), starts verify api
This commit is contained in:
1 parent
bc6029e289
commit
9ff22d634f
17 files changed
+336
-287
No files matched your search
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
*.swp
|
*.swp
|
||||||
temp
|
temp
|
||||||
*.log
|
*.log
|
||||||
settings.py
|
local_settings.py
|
||||||
dns_mdb.db
|
db.sqlite3
|
||||||
/.idea
|
/.idea
|
||||||
/venv
|
/venv
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
A Django app for managing computer equipment.
|
|
||||||
Generates DHCP configs and zone files.
|
|
||||||
|
|
||||||
Dependencies:
|
|
||||||
sudo apt-get install libmysqlclient-dev python-dev libldap2-dev libsasl2-dev bind9utils
|
|
||||||
|
|
||||||
Setup environment:
|
|
||||||
mdb$ virtualenv venv
|
|
||||||
mdb$ . venv/bin/activate
|
|
||||||
(venv)mdb$ pip install -r requirements.txt
|
|
||||||
|
|
||||||
Create a config file:
|
|
||||||
mdb$ cp mdb/settings-sample.py mdb/settings.py
|
|
||||||
# Edit settings.py with your favorite editor
|
|
||||||
|
|
||||||
Run the server:
|
|
||||||
(venv)mdb$ python manage.py runserver
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
A Django app for managing computer equipment.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
sudo apt-get install libmysqlclient-dev python-dev libldap2-dev libsasl2-dev bind9utils
|
||||||
|
virtualenv venv
|
||||||
|
. venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
python manage.py migrate
|
||||||
|
python manage.py runserver
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* Creates DHCPD configuration files
|
||||||
|
* Creates DNS zone files for BIND
|
||||||
|
* TODO: Creates PXE config files (with random secret for use with Puppet autosign)
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os, sys
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mdb.settings")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mdbsite.settings")
|
||||||
|
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
|
|
||||||
execute_from_command_line(sys.argv)
|
execute_from_command_line(sys.argv)
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,6 @@
|
|||||||
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
|
|
||||||
|
class ValidatePuppetHostSecret(APIView):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
@@ -6,7 +6,11 @@ from difflib import context_diff
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.core.mail import mail_admins
|
from django.core.mail import mail_admins
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
from commands import getstatusoutput
|
try:
|
||||||
|
from subprocess import getstatusoutput
|
||||||
|
except ImportError:
|
||||||
|
from commands import getstatusoutput
|
||||||
|
|
||||||
from mdb.models import DhcpConfig
|
from mdb.models import DhcpConfig
|
||||||
|
|
||||||
|
|
||||||
@@ -42,13 +46,13 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
# do we need to do anything?
|
# do we need to do anything?
|
||||||
if config.serial == config.active_serial and not force:
|
if config.serial == config.active_serial and not force:
|
||||||
print "Nothing to do, serial is the same: %s" % config.serial
|
print("Nothing to do, serial is the same: %s" % config.serial)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# write to stdout
|
# write to stdout
|
||||||
if output == sys.stdout:
|
if output == sys.stdout:
|
||||||
print config.dhcpd_configuration()
|
print(config.dhcpd_configuration())
|
||||||
print 'Not writing to file, serial not updated'
|
print('Not writing to file, serial not updated')
|
||||||
return
|
return
|
||||||
|
|
||||||
# read current file contents
|
# read current file contents
|
||||||
@@ -71,7 +75,7 @@ class Command(BaseCommand):
|
|||||||
tofile=config.serial,
|
tofile=config.serial,
|
||||||
lineterm=''))
|
lineterm=''))
|
||||||
|
|
||||||
print diff
|
print(diff)
|
||||||
|
|
||||||
# update serial
|
# update serial
|
||||||
old_serial = config.active_serial
|
old_serial = config.active_serial
|
||||||
|
|||||||
@@ -7,8 +7,12 @@ from difflib import context_diff
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.core.mail import mail_admins
|
from django.core.mail import mail_admins
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
from commands import getstatusoutput
|
try:
|
||||||
from mdb.models import *
|
from subprocess import getstatusoutput
|
||||||
|
except ImportError:
|
||||||
|
from commands import getstatusoutput
|
||||||
|
|
||||||
|
from mdb.models import Domain, Ip4Subnet, Ip6Subnet
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@@ -43,7 +47,7 @@ class Command(BaseCommand):
|
|||||||
# do the binaries exist?
|
# do the binaries exist?
|
||||||
for f in (self.checkzone_bin, self.bind_bin):
|
for f in (self.checkzone_bin, self.bind_bin):
|
||||||
if not os.path.isfile(f):
|
if not os.path.isfile(f):
|
||||||
print "ERROR: no such file %s, exiting..." % f
|
print("ERROR: no such file %s, exiting..." % f)
|
||||||
if not debug:
|
if not debug:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@@ -106,11 +110,11 @@ class Command(BaseCommand):
|
|||||||
'diff': None,
|
'diff': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
print "updating %s %s [%d -> %d]" % (
|
print("updating %s %s [%d -> %d]" % (
|
||||||
zonetype,
|
zonetype,
|
||||||
zone.domain_name,
|
zone.domain_name,
|
||||||
zone.domain_active_serial,
|
zone.domain_active_serial,
|
||||||
zone.domain_serial)
|
zone.domain_serial))
|
||||||
|
|
||||||
# generate zone file contents
|
# generate zone file contents
|
||||||
new = zone.zone_file_contents()
|
new = zone.zone_file_contents()
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
import django.core.validators
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mdb', '0005_auto_20150822_2204'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='dhcpcustomfield',
|
||||||
|
options={'verbose_name': 'DHCP custom field'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='domain',
|
||||||
|
name='domain_admin',
|
||||||
|
field=models.EmailField(max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='domain',
|
||||||
|
name='domain_ipaddr',
|
||||||
|
field=models.GenericIPAddressField(protocol='IPv4'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='host',
|
||||||
|
name='hostname',
|
||||||
|
field=models.CharField(validators=[django.core.validators.RegexValidator(code='invalid', message='Enter a valid hostname', regex=re.compile('^(?!-)[-a-z0-9]+(?<!-)$', 34))], max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='interface',
|
||||||
|
name='ip4address',
|
||||||
|
field=models.OneToOneField(to='mdb.Ip4Address', null=True, blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='interface',
|
||||||
|
name='macaddr',
|
||||||
|
field=models.CharField(validators=[django.core.validators.RegexValidator(code='invalid', message='Enter a valid MAC address', regex=re.compile('^([0-9A-F]{2}[:]){5}([0-9A-F]{2})$', 34))], max_length=17),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ip4address',
|
||||||
|
name='address',
|
||||||
|
field=models.GenericIPAddressField(protocol='IPv4'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ip4subnet',
|
||||||
|
name='dhcp_dynamic_end',
|
||||||
|
field=models.GenericIPAddressField(protocol='IPv4', null=True, blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ip4subnet',
|
||||||
|
name='dhcp_dynamic_start',
|
||||||
|
field=models.GenericIPAddressField(protocol='IPv4', null=True, blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ip4subnet',
|
||||||
|
name='domain_admin',
|
||||||
|
field=models.EmailField(max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ip4subnet',
|
||||||
|
name='netmask',
|
||||||
|
field=models.GenericIPAddressField(protocol='IPv4'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ip4subnet',
|
||||||
|
name='network',
|
||||||
|
field=models.GenericIPAddressField(protocol='IPv4'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ip6subnet',
|
||||||
|
name='domain_admin',
|
||||||
|
field=models.EmailField(max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='operatingsystem',
|
||||||
|
name='arch',
|
||||||
|
field=models.CharField(max_length=255, choices=[('mips', 'MIPS'), ('arm', 'ARM'), ('broadcom', 'Broadcom'), ('rc32300', 'RC32300'), ('powerpc', 'PowerPC'), ('powerpc403ga', 'PowerPC403GA'), ('unknown', 'Unknown'), ('x86_64', 'x86-64'), ('i386', 'x86')], null=True, blank=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
+59
-41
@@ -2,31 +2,36 @@ from django.db import models
|
|||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.db.models.signals import post_save, pre_save, pre_delete
|
from django.db.models.signals import post_save, pre_save, pre_delete
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
|
from django.utils.six import u
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
from validators import validate_hostname, validate_macaddr
|
from mdb.validators import validate_hostname, validate_macaddr
|
||||||
|
|
||||||
import ipaddr
|
import ipaddress
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Nameserver(models.Model):
|
class Nameserver(models.Model):
|
||||||
hostname = models.CharField(max_length=256)
|
hostname = models.CharField(max_length=256)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.hostname
|
return self.hostname
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class MailExchange(models.Model):
|
class MailExchange(models.Model):
|
||||||
priority = models.IntegerField()
|
priority = models.IntegerField()
|
||||||
hostname = models.CharField(max_length=256)
|
hostname = models.CharField(max_length=256)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return "(" + str(self.priority) + ") " + self.hostname
|
return "(" + str(self.priority) + ") " + self.hostname
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Domain(models.Model):
|
class Domain(models.Model):
|
||||||
domain_name = models.CharField(max_length=256)
|
domain_name = models.CharField(max_length=256)
|
||||||
domain_soa = models.CharField(max_length=256)
|
domain_soa = models.CharField(max_length=256)
|
||||||
@@ -38,14 +43,14 @@ class Domain(models.Model):
|
|||||||
domain_expire = models.IntegerField(default=604800)
|
domain_expire = models.IntegerField(default=604800)
|
||||||
domain_minimum_ttl = models.IntegerField(default=86400)
|
domain_minimum_ttl = models.IntegerField(default=86400)
|
||||||
domain_admin = models.EmailField()
|
domain_admin = models.EmailField()
|
||||||
domain_ipaddr = models.IPAddressField()
|
domain_ipaddr = models.GenericIPAddressField(protocol='IPv4')
|
||||||
domain_filename = models.CharField(max_length=256)
|
domain_filename = models.CharField(max_length=256)
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
domain_nameservers = models.ManyToManyField(Nameserver)
|
domain_nameservers = models.ManyToManyField(Nameserver)
|
||||||
domain_mailexchanges = models.ManyToManyField(MailExchange)
|
domain_mailexchanges = models.ManyToManyField(MailExchange)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.domain_name
|
return self.domain_name
|
||||||
|
|
||||||
def num_records(self):
|
def num_records(self):
|
||||||
@@ -63,6 +68,7 @@ class Domain(models.Model):
|
|||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not other or not hasattr(other, 'domain_name'):
|
if not other or not hasattr(other, 'domain_name'):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return self.domain_name == other.domain_name
|
return self.domain_name == other.domain_name
|
||||||
|
|
||||||
def zone_file_contents(self):
|
def zone_file_contents(self):
|
||||||
@@ -93,12 +99,12 @@ class Domain(models.Model):
|
|||||||
content += "; SRV records\n"
|
content += "; SRV records\n"
|
||||||
|
|
||||||
for srv in self.domainsrvrecord_set.all():
|
for srv in self.domainsrvrecord_set.all():
|
||||||
content += unicode(srv) + "\n"
|
content += u(srv) + "\n"
|
||||||
|
|
||||||
content += "; A records\n"
|
content += "; A records\n"
|
||||||
|
|
||||||
for a in self.domainarecord_set.all():
|
for a in self.domainarecord_set.all():
|
||||||
content += unicode(a) + "\n"
|
content += u(a) + "\n"
|
||||||
|
|
||||||
content += "; CNAME records \n"
|
content += "; CNAME records \n"
|
||||||
|
|
||||||
@@ -108,7 +114,7 @@ class Domain(models.Model):
|
|||||||
content += "; TXT records \n"
|
content += "; TXT records \n"
|
||||||
|
|
||||||
for txt in self.domaintxtrecord_set.all():
|
for txt in self.domaintxtrecord_set.all():
|
||||||
content += unicode(txt) + "\n"
|
content += u(txt) + "\n"
|
||||||
|
|
||||||
content += "; HOST records\n"
|
content += "; HOST records\n"
|
||||||
|
|
||||||
@@ -126,6 +132,7 @@ class Domain(models.Model):
|
|||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class DomainSrvRecord(models.Model):
|
class DomainSrvRecord(models.Model):
|
||||||
srvce = models.CharField(max_length=64)
|
srvce = models.CharField(max_length=64)
|
||||||
prot = models.CharField(max_length=64)
|
prot = models.CharField(max_length=64)
|
||||||
@@ -137,42 +144,46 @@ class DomainSrvRecord(models.Model):
|
|||||||
domain = models.ForeignKey(Domain)
|
domain = models.ForeignKey(Domain)
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.srvce + "." + self.prot + "." + self.name + ". IN SRV " \
|
return self.srvce + "." + self.prot + "." + self.name + ". IN SRV " \
|
||||||
+ str(self.priority) + " " + str(self.weight) + " " + \
|
+ str(self.priority) + " " + str(self.weight) + " " + \
|
||||||
str(self.port) + " " + self.target + "."
|
str(self.port) + " " + self.target + "."
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class DomainTxtRecord(models.Model):
|
class DomainTxtRecord(models.Model):
|
||||||
name = models.CharField(max_length=256)
|
name = models.CharField(max_length=256)
|
||||||
target = models.CharField(max_length=256)
|
target = models.CharField(max_length=256)
|
||||||
domain = models.ForeignKey(Domain)
|
domain = models.ForeignKey(Domain)
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.name + " TXT " + self.target
|
return self.name + " TXT " + self.target
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class DomainCnameRecord(models.Model):
|
class DomainCnameRecord(models.Model):
|
||||||
name = models.CharField(max_length=256)
|
name = models.CharField(max_length=256)
|
||||||
target = models.CharField(max_length=256)
|
target = models.CharField(max_length=256)
|
||||||
domain = models.ForeignKey(Domain)
|
domain = models.ForeignKey(Domain)
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.name + " IN CNAME " + self.target
|
return self.name + " IN CNAME " + self.target
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class DomainARecord(models.Model):
|
class DomainARecord(models.Model):
|
||||||
name = models.CharField(max_length=256)
|
name = models.CharField(max_length=256)
|
||||||
target = models.CharField(max_length=256)
|
target = models.CharField(max_length=256)
|
||||||
domain = models.ForeignKey(Domain)
|
domain = models.ForeignKey(Domain)
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.name + " IN A " + self.target
|
return self.name + " IN A " + self.target
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class DhcpConfig(models.Model):
|
class DhcpConfig(models.Model):
|
||||||
serial = models.IntegerField()
|
serial = models.IntegerField()
|
||||||
active_serial = models.IntegerField()
|
active_serial = models.IntegerField()
|
||||||
@@ -229,13 +240,14 @@ class DhcpConfig(models.Model):
|
|||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'DHCP config'
|
verbose_name = 'DHCP config'
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Ip6Subnet(models.Model):
|
class Ip6Subnet(models.Model):
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
network = models.CharField(max_length=255)
|
network = models.CharField(max_length=255)
|
||||||
@@ -254,7 +266,7 @@ class Ip6Subnet(models.Model):
|
|||||||
domain_admin = models.EmailField()
|
domain_admin = models.EmailField()
|
||||||
domain_filename = models.CharField(max_length=256)
|
domain_filename = models.CharField(max_length=256)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.network + " (" + self.name + ")"
|
return self.network + " (" + self.name + ")"
|
||||||
|
|
||||||
def zone_file_contents(self, generate_unassigned=False):
|
def zone_file_contents(self, generate_unassigned=False):
|
||||||
@@ -292,7 +304,7 @@ class Ip6Subnet(models.Model):
|
|||||||
addr.interface.host.hostname,
|
addr.interface.host.hostname,
|
||||||
addr.interface.domain.domain_name)
|
addr.interface.domain.domain_name)
|
||||||
|
|
||||||
ip = ipaddr.IPv6Address(self.network + addr.address)
|
ip = ipaddress.IPv6Address(self.network + addr.address)
|
||||||
ip = ".".join(ip.exploded.replace(":", "")[16:])[::-1]
|
ip = ".".join(ip.exploded.replace(":", "")[16:])[::-1]
|
||||||
content += "%s\tPTR\t%s.\n" % (ip, hostname)
|
content += "%s\tPTR\t%s.\n" % (ip, hostname)
|
||||||
|
|
||||||
@@ -305,10 +317,11 @@ class Ip6Subnet(models.Model):
|
|||||||
verbose_name = 'IPv6 subnet'
|
verbose_name = 'IPv6 subnet'
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Ip4Subnet(models.Model):
|
class Ip4Subnet(models.Model):
|
||||||
name = models.CharField(max_length=256)
|
name = models.CharField(max_length=256)
|
||||||
netmask = models.IPAddressField()
|
netmask = models.GenericIPAddressField(protocol='IPv4')
|
||||||
network = models.IPAddressField()
|
network = models.GenericIPAddressField(protocol='IPv4')
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
domain_name = models.CharField(max_length=255, editable=False)
|
domain_name = models.CharField(max_length=255, editable=False)
|
||||||
domain_nameservers = models.ManyToManyField(Nameserver)
|
domain_nameservers = models.ManyToManyField(Nameserver)
|
||||||
@@ -324,29 +337,29 @@ class Ip4Subnet(models.Model):
|
|||||||
domain_filename = models.CharField(max_length=256)
|
domain_filename = models.CharField(max_length=256)
|
||||||
|
|
||||||
dhcp_dynamic = models.BooleanField(default=False)
|
dhcp_dynamic = models.BooleanField(default=False)
|
||||||
dhcp_dynamic_start = models.IPAddressField(null=True, blank=True)
|
dhcp_dynamic_start = models.GenericIPAddressField(protocol='IPv4', null=True, blank=True)
|
||||||
dhcp_dynamic_end = models.IPAddressField(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)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.network + " (" + self.name + ")"
|
return self.network + " (" + self.name + ")"
|
||||||
|
|
||||||
def num_addresses(self):
|
def num_addresses(self):
|
||||||
subnet = ipaddr.IPv4Network(self.network + "/" + self.netmask)
|
subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask)
|
||||||
return subnet.numhosts
|
return subnet.numhosts
|
||||||
|
|
||||||
def broadcast_address(self):
|
def broadcast_address(self):
|
||||||
subnet = ipaddr.IPv4Network(self.network + "/" + self.netmask)
|
subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask)
|
||||||
return subnet.broadcast
|
return subnet.broadcast
|
||||||
|
|
||||||
def first_address(self):
|
def first_address(self):
|
||||||
subnet = ipaddr.IPv4Network(self.network + "/" + self.netmask)
|
subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask)
|
||||||
return subnet.iterhosts().next()
|
return subnet.iterhosts().next()
|
||||||
|
|
||||||
def last_address(self):
|
def last_address(self):
|
||||||
subnet = ipaddr.IPv4Network(self.network + "/" + self.netmask)
|
subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask)
|
||||||
for curr in subnet.iterhosts():
|
for curr in subnet.iterhosts():
|
||||||
pass # horribly ineficcient
|
pass # horribly inefficient
|
||||||
|
|
||||||
return curr
|
return curr
|
||||||
|
|
||||||
@@ -405,18 +418,20 @@ class Ip4Subnet(models.Model):
|
|||||||
verbose_name = 'IPv4 subnet'
|
verbose_name = 'IPv4 subnet'
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class DhcpOption(models.Model):
|
class DhcpOption(models.Model):
|
||||||
key = models.CharField(max_length=255)
|
key = models.CharField(max_length=255)
|
||||||
value = models.CharField(max_length=255)
|
value = models.CharField(max_length=255)
|
||||||
ip4subnet = models.ForeignKey(Ip4Subnet)
|
ip4subnet = models.ForeignKey(Ip4Subnet)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.key + " " + self.value
|
return self.key + " " + self.value
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'DHCP option'
|
verbose_name = 'DHCP option'
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class DhcpCustomField(models.Model):
|
class DhcpCustomField(models.Model):
|
||||||
value = models.CharField(max_length=255)
|
value = models.CharField(max_length=255)
|
||||||
ip4subnet = models.ForeignKey(Ip4Subnet)
|
ip4subnet = models.ForeignKey(Ip4Subnet)
|
||||||
@@ -425,22 +440,20 @@ class DhcpCustomField(models.Model):
|
|||||||
verbose_name = 'DHCP custom field'
|
verbose_name = 'DHCP custom field'
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Ip4Address(models.Model):
|
class Ip4Address(models.Model):
|
||||||
subnet = models.ForeignKey(Ip4Subnet)
|
subnet = models.ForeignKey(Ip4Subnet)
|
||||||
address = models.IPAddressField()
|
address = models.GenericIPAddressField(protocol='IPv4')
|
||||||
last_contact = models.DateTimeField(null=True, blank=True)
|
last_contact = models.DateTimeField(null=True, blank=True)
|
||||||
ping_avg_rtt = models.FloatField(null=True, blank=True)
|
ping_avg_rtt = models.FloatField(null=True, blank=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
# FIXME: generates 2 SQL queries
|
# FIXME: generates 2 SQL queries
|
||||||
_if = self.interface_set.all()
|
_if = self.interface_set.all()
|
||||||
if not _if:
|
if not _if:
|
||||||
return self.address
|
return self.address
|
||||||
|
|
||||||
return "{} ({})".format(
|
return "{} ({})".format(self.address, _if.get().host.hostname)
|
||||||
self.address,
|
|
||||||
_if.get().host.hostname
|
|
||||||
)
|
|
||||||
|
|
||||||
def assigned_to_host(self):
|
def assigned_to_host(self):
|
||||||
return self.interface_set.get().host
|
return self.interface_set.get().host
|
||||||
@@ -452,11 +465,12 @@ class Ip4Address(models.Model):
|
|||||||
verbose_name_plural = 'IPv4 addresses'
|
verbose_name_plural = 'IPv4 addresses'
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class HostType(models.Model):
|
class HostType(models.Model):
|
||||||
host_type = models.CharField(max_length=64)
|
host_type = models.CharField(max_length=64)
|
||||||
description = models.CharField(max_length=1024)
|
description = models.CharField(max_length=1024)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.host_type
|
return self.host_type
|
||||||
|
|
||||||
def num_members(self):
|
def num_members(self):
|
||||||
@@ -466,6 +480,7 @@ class HostType(models.Model):
|
|||||||
ordering = ("host_type",)
|
ordering = ("host_type",)
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class OperatingSystem(models.Model):
|
class OperatingSystem(models.Model):
|
||||||
OS_ARCHITECTURES = (
|
OS_ARCHITECTURES = (
|
||||||
('mips', _('MIPS')),
|
('mips', _('MIPS')),
|
||||||
@@ -482,13 +497,14 @@ class OperatingSystem(models.Model):
|
|||||||
version = models.CharField(max_length=64)
|
version = models.CharField(max_length=64)
|
||||||
arch = models.CharField(max_length=255, choices=OS_ARCHITECTURES, blank=True, null=True)
|
arch = models.CharField(max_length=255, choices=OS_ARCHITECTURES, blank=True, null=True)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.name + " " + self.version + " (" + self.arch + ")"
|
return self.name + " " + self.version + " (" + self.arch + ")"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ("name", "version")
|
ordering = ("name", "version")
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Host(models.Model):
|
class Host(models.Model):
|
||||||
location = models.CharField(max_length=1024)
|
location = models.CharField(max_length=1024)
|
||||||
brand = models.CharField(max_length=1024)
|
brand = models.CharField(max_length=1024)
|
||||||
@@ -507,7 +523,7 @@ class Host(models.Model):
|
|||||||
kerberos_principal_name = models.CharField(max_length=256, editable=False)
|
kerberos_principal_name = models.CharField(max_length=256, editable=False)
|
||||||
kerberos_principal_created_date = models.DateTimeField(null=True, blank=True, editable=False)
|
kerberos_principal_created_date = models.DateTimeField(null=True, blank=True, editable=False)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return self.hostname
|
return self.hostname
|
||||||
|
|
||||||
def in_domain(self):
|
def in_domain(self):
|
||||||
@@ -531,23 +547,25 @@ class Host(models.Model):
|
|||||||
return ",".join(addresses)
|
return ",".join(addresses)
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Interface(models.Model):
|
class Interface(models.Model):
|
||||||
name = models.CharField(max_length=128)
|
name = models.CharField(max_length=128)
|
||||||
macaddr = models.CharField(max_length=17, validators=[validate_macaddr])
|
macaddr = models.CharField(max_length=17, validators=[validate_macaddr])
|
||||||
pxe_filename = models.CharField(max_length=64, blank=True)
|
pxe_filename = models.CharField(max_length=64, blank=True)
|
||||||
dhcp_client = models.BooleanField(default=False)
|
dhcp_client = models.BooleanField(default=False)
|
||||||
host = models.ForeignKey(Host)
|
host = models.ForeignKey(Host)
|
||||||
ip4address = models.ForeignKey(Ip4Address, blank=True, null=True, unique=True)
|
ip4address = models.OneToOneField(Ip4Address, blank=True, null=True)
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
domain = models.ForeignKey(Domain)
|
domain = models.ForeignKey(Domain)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return "%s (%s on %s)" % (self.macaddr, self.name, self.host.hostname)
|
return "%s (%s on %s)" % (self.macaddr, self.name, self.host.hostname)
|
||||||
|
|
||||||
def ipv6_enabled(self):
|
def ipv6_enabled(self):
|
||||||
return self.ip6address_set.count() > 0
|
return self.ip6address_set.count() > 0
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
class Ip6Address(models.Model):
|
class Ip6Address(models.Model):
|
||||||
subnet = models.ForeignKey(Ip6Subnet)
|
subnet = models.ForeignKey(Ip6Subnet)
|
||||||
address = models.CharField(max_length=64)
|
address = models.CharField(max_length=64)
|
||||||
@@ -556,7 +574,7 @@ class Ip6Address(models.Model):
|
|||||||
def full_address(self):
|
def full_address(self):
|
||||||
return self.subnet.network + self.address
|
return self.subnet.network + self.address
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return "%s (%s on %s)" % (
|
return "%s (%s on %s)" % (
|
||||||
self.full_address(),
|
self.full_address(),
|
||||||
self.interface.name,
|
self.interface.name,
|
||||||
@@ -604,7 +622,7 @@ def create_ips_for_subnet(sender, instance, created, **kwargs):
|
|||||||
if not created:
|
if not created:
|
||||||
return
|
return
|
||||||
|
|
||||||
subnet = ipaddr.IPv4Network(instance.network + "/" + instance.netmask)
|
subnet = ipaddress.IPv4Network(instance.network + "/" + instance.netmask)
|
||||||
|
|
||||||
for addr in subnet.iterhosts():
|
for addr in subnet.iterhosts():
|
||||||
address = Ip4Address(address=str(addr), subnet=instance)
|
address = Ip4Address(address=str(addr), subnet=instance)
|
||||||
@@ -642,7 +660,7 @@ def set_domain_name_for_ipv6_subnet(sender, instance, **kwargs):
|
|||||||
if len(instance.domain_name) > 0:
|
if len(instance.domain_name) > 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
network = ipaddr.IPv6Address("%s::" % instance.network)
|
network = ipaddress.IPv6Address("%s::" % instance.network)
|
||||||
instance.domain_name = ".".join(network.exploded.replace(":", "")[:16])[::-1] + ".ip6.arpa"
|
instance.domain_name = ".".join(network.exploded.replace(":", "")[:16])[::-1] + ".ip6.arpa"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,191 +0,0 @@
|
|||||||
# Django settings for dns_mdb project.
|
|
||||||
|
|
||||||
DEBUG = True
|
|
||||||
TEMPLATE_DEBUG = DEBUG
|
|
||||||
|
|
||||||
ADMINS = (
|
|
||||||
('System Administrator', 'sysadmin@example.com'),
|
|
||||||
)
|
|
||||||
|
|
||||||
MANAGERS = ADMINS
|
|
||||||
|
|
||||||
DATABASES = {
|
|
||||||
'default': {
|
|
||||||
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
|
||||||
'NAME': 'mdb.db', # Or path to database file if using sqlite3.
|
|
||||||
'USER': 'mdb', # Not used with sqlite3.
|
|
||||||
'PASSWORD': 'mdb', # Not used with sqlite3.
|
|
||||||
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
|
|
||||||
'PORT': '3306', # Set to empty string for default. Not used with sqlite3.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Local time zone for this installation. Choices can be found here:
|
|
||||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
|
||||||
# although not all choices may be available on all operating systems.
|
|
||||||
# On Unix systems, a value of None will cause Django to use the same
|
|
||||||
# timezone as the operating system.
|
|
||||||
# If running in a Windows environment this must be set to the same as your
|
|
||||||
# system time zone.
|
|
||||||
TIME_ZONE = 'Europe/Oslo'
|
|
||||||
|
|
||||||
# Language code for this installation. All choices can be found here:
|
|
||||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
|
||||||
|
|
||||||
SITE_ID = 1
|
|
||||||
|
|
||||||
# If you set this to False, Django will make some optimizations so as not
|
|
||||||
# to load the internationalization machinery.
|
|
||||||
USE_I18N = True
|
|
||||||
|
|
||||||
# If you set this to False, Django will not format dates, numbers and
|
|
||||||
# calendars according to the current locale
|
|
||||||
USE_L10N = True
|
|
||||||
|
|
||||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
|
||||||
# Example: "/home/media/media.lawrence.com/media/"
|
|
||||||
MEDIA_ROOT = ''
|
|
||||||
|
|
||||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
|
||||||
# trailing slash.
|
|
||||||
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
|
|
||||||
MEDIA_URL = ''
|
|
||||||
|
|
||||||
# Absolute path to the directory static files should be collected to.
|
|
||||||
# Don't put anything in this directory yourself; store your static files
|
|
||||||
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
|
|
||||||
# Example: "/home/media/media.lawrence.com/static/"
|
|
||||||
STATIC_ROOT = ''
|
|
||||||
|
|
||||||
# URL prefix for static files.
|
|
||||||
# Example: "http://media.lawrence.com/static/"
|
|
||||||
STATIC_URL = '/static/'
|
|
||||||
|
|
||||||
# URL prefix for admin static files -- CSS, JavaScript and images.
|
|
||||||
# Make sure to use a trailing slash.
|
|
||||||
# Examples: "http://foo.com/static/admin/", "/static/admin/".
|
|
||||||
ADMIN_MEDIA_PREFIX = '/media/'
|
|
||||||
|
|
||||||
# Additional locations of static files
|
|
||||||
STATICFILES_DIRS = (
|
|
||||||
# Put strings here, like "/home/html/static" or "C:/www/django/static".
|
|
||||||
# Always use forward slashes, even on Windows.
|
|
||||||
# Don't forget to use absolute paths, not relative paths.
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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'
|
|
||||||
|
|
||||||
# List of callables that know how to import templates from various sources.
|
|
||||||
TEMPLATE_LOADERS = (
|
|
||||||
'django.template.loaders.filesystem.Loader',
|
|
||||||
'django.template.loaders.app_directories.Loader',
|
|
||||||
# 'django.template.loaders.eggs.Loader',
|
|
||||||
)
|
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
|
||||||
'django.middleware.common.CommonMiddleware',
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
|
||||||
)
|
|
||||||
|
|
||||||
ROOT_URLCONF = '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.
|
|
||||||
)
|
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
|
||||||
'django.contrib.auth',
|
|
||||||
'django.contrib.contenttypes',
|
|
||||||
'django.contrib.sessions',
|
|
||||||
'django.contrib.sites',
|
|
||||||
'django.contrib.messages',
|
|
||||||
'django.contrib.staticfiles',
|
|
||||||
'mdb',
|
|
||||||
'suit',
|
|
||||||
'django.contrib.admin',
|
|
||||||
)
|
|
||||||
|
|
||||||
# Defines a test runner
|
|
||||||
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
|
|
||||||
|
|
||||||
# A sample logging configuration. The only tangible logging
|
|
||||||
# performed by this configuration is to send an email to
|
|
||||||
# the site admins on every HTTP 500 error.
|
|
||||||
# See http://docs.djangoproject.com/en/dev/topics/logging for
|
|
||||||
# more details on how to customize your logging configuration.
|
|
||||||
LOGGING = {
|
|
||||||
'version': 1,
|
|
||||||
'disable_existing_loggers': False,
|
|
||||||
'handlers': {
|
|
||||||
'mail_admins': {
|
|
||||||
'level': 'ERROR',
|
|
||||||
'class': 'django.utils.log.AdminEmailHandler'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'loggers': {
|
|
||||||
'django.request': {
|
|
||||||
'handlers': ['mail_admins'],
|
|
||||||
'level': 'ERROR',
|
|
||||||
'propagate': True,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EMAIL_SUBJECT_PREFIX = '[MDB] '
|
|
||||||
EMAIL_HOST = 'smtp.example.com'
|
|
||||||
EMAIL_PORT = 25
|
|
||||||
|
|
||||||
|
|
||||||
# for django-suit
|
|
||||||
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP
|
|
||||||
|
|
||||||
TEMPLATE_CONTEXT_PROCESSORS = TCP + (
|
|
||||||
'django.core.context_processors.request',
|
|
||||||
)
|
|
||||||
|
|
||||||
# django-suit configuration
|
|
||||||
SUIT_CONFIG = {
|
|
||||||
# header
|
|
||||||
'ADMIN_NAME': 'MDB',
|
|
||||||
'HEADER_DATE_FORMAT': 'l, Y-m-d',
|
|
||||||
'HEADER_TIME_FORMAT': 'H:i',
|
|
||||||
|
|
||||||
# forms
|
|
||||||
# 'SHOW_REQUIRED_ASTERISK': True, # Default True
|
|
||||||
# 'CONFIRM_UNSAVED_CHANGES': True, # Default True
|
|
||||||
|
|
||||||
# menu
|
|
||||||
'SEARCH_URL': '/admin/mdb/host/',
|
|
||||||
# 'MENU_ICONS': {
|
|
||||||
# 'sites': 'icon-leaf',
|
|
||||||
# 'auth': 'icon-lock',
|
|
||||||
# },
|
|
||||||
# 'MENU_OPEN_FIRST_CHILD': True, # Default True
|
|
||||||
# 'MENU_EXCLUDE': ('auth.group',),
|
|
||||||
'MENU': (
|
|
||||||
{'app': 'mdb', 'label': 'MDB', 'url': 'mdb.host'},
|
|
||||||
{
|
|
||||||
'label': 'Settings',
|
|
||||||
'icon': 'icon-cog',
|
|
||||||
'models': ('auth.user', 'auth.group')
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
# misc
|
|
||||||
'LIST_PER_PAGE': 30
|
|
||||||
}
|
|
||||||
+10
-14
@@ -1,16 +1,12 @@
|
|||||||
"""
|
from django.core.urlresolvers import reverse
|
||||||
This file demonstrates writing tests using the unittest module. These will pass
|
from rest_framework.test import APITestCase
|
||||||
when you run "manage.py test".
|
|
||||||
|
|
||||||
Replace this with more appropriate tests for your application.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleTest(TestCase):
|
class APITestCases(APITestCase):
|
||||||
def test_basic_addition(self):
|
def test_validate_puppet_host_by_secret(self):
|
||||||
"""
|
data = {
|
||||||
Tests that 1 + 1 always equals 2.
|
'secret': 'something',
|
||||||
"""
|
'certname': 'arnold.neuf.no'
|
||||||
self.assertEqual(1 + 1, 2)
|
}
|
||||||
|
res = self.client.post(reverse('api-validate-host-secret'), data)
|
||||||
|
self.fail()
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
import os
|
||||||
|
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP
|
||||||
|
|
||||||
|
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
DEBUG = True
|
||||||
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
|
||||||
|
ADMINS = (
|
||||||
|
('System Administrator', 'sysadmin@example.com'),
|
||||||
|
)
|
||||||
|
|
||||||
|
MANAGERS = ADMINS
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': 'db.sqlite3',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TIME_ZONE = 'Europe/Oslo'
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
SITE_ID = 1
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
USE_L10N = True
|
||||||
|
|
||||||
|
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||||
|
MEDIA_URL = '/media/'
|
||||||
|
ADMIN_MEDIA_PREFIX = '/media/'
|
||||||
|
|
||||||
|
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 = (
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
)
|
||||||
|
|
||||||
|
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.
|
||||||
|
)
|
||||||
|
|
||||||
|
INSTALLED_APPS = (
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.sites',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
'mdb',
|
||||||
|
'suit',
|
||||||
|
'django.contrib.admin',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Defines a test runner
|
||||||
|
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
|
||||||
|
|
||||||
|
EMAIL_SUBJECT_PREFIX = '[MDB] '
|
||||||
|
|
||||||
|
TEMPLATE_CONTEXT_PROCESSORS = TCP + (
|
||||||
|
'django.core.context_processors.request', # for django-suit
|
||||||
|
)
|
||||||
|
|
||||||
|
# django-suit configuration
|
||||||
|
SUIT_CONFIG = {
|
||||||
|
# header
|
||||||
|
'ADMIN_NAME': 'MDB',
|
||||||
|
'HEADER_DATE_FORMAT': 'l, Y-m-d',
|
||||||
|
'HEADER_TIME_FORMAT': 'H:i',
|
||||||
|
|
||||||
|
# forms
|
||||||
|
# 'SHOW_REQUIRED_ASTERISK': True, # Default True
|
||||||
|
# 'CONFIRM_UNSAVED_CHANGES': True, # Default True
|
||||||
|
|
||||||
|
# menu
|
||||||
|
'SEARCH_URL': '/admin/mdb/host/',
|
||||||
|
# 'MENU_ICONS': {
|
||||||
|
# 'sites': 'icon-leaf',
|
||||||
|
# 'auth': 'icon-lock',
|
||||||
|
# },
|
||||||
|
# 'MENU_OPEN_FIRST_CHILD': True, # Default True
|
||||||
|
# 'MENU_EXCLUDE': ('auth.group',),
|
||||||
|
'MENU': (
|
||||||
|
{'app': 'mdb', 'label': 'MDB', 'url': 'mdb.host'},
|
||||||
|
{
|
||||||
|
'label': 'Settings',
|
||||||
|
'icon': 'icon-cog',
|
||||||
|
'models': ('auth.user', 'auth.group')
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
# misc
|
||||||
|
'LIST_PER_PAGE': 30
|
||||||
|
}
|
||||||
|
REST_FRAMEWORK = {
|
||||||
|
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
|
||||||
|
'PAGINATE_BY': 10
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
from local_settings import *
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
from django.conf.urls import patterns, include, url
|
from django.conf.urls import include, url
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||||
from django.views.generic.base import RedirectView
|
from django.views.generic.base import RedirectView
|
||||||
|
from mdb.api.views import ValidatePuppetHostSecret
|
||||||
|
|
||||||
admin.autodiscover()
|
admin.autodiscover()
|
||||||
|
|
||||||
urlpatterns = patterns(
|
urlpatterns = [
|
||||||
'',
|
|
||||||
url(r'^$', RedirectView.as_view(url='admin/')),
|
url(r'^$', RedirectView.as_view(url='admin/')),
|
||||||
url(r'^admin/', include(admin.site.urls)),
|
url(r'^admin/', include(admin.site.urls)),
|
||||||
)
|
url(r'^api/validate-host-secret', ValidatePuppetHostSecret.as_view(), name='api-validate-host-secret')
|
||||||
|
]
|
||||||
|
|
||||||
urlpatterns += staticfiles_urlpatterns()
|
urlpatterns += staticfiles_urlpatterns()
|
||||||
File renamed without changes.
+5
-4
@@ -1,5 +1,6 @@
|
|||||||
Django>=1.7,<1.8
|
Django>=1.8,<1.9
|
||||||
MySQL-python==1.2.5
|
|
||||||
ipaddr==2.1.11
|
|
||||||
django-auth-ldap
|
django-auth-ldap
|
||||||
django-suit
|
django-suit==0.2.15
|
||||||
|
djangorestframework==3.2.4
|
||||||
|
ipaddress==1.0.14
|
||||||
|
mysqlclient==1.3.6
|
||||||
Reference in new issue
Block a user