Bump everything (python3 ftw), starts verify api

This commit is contained in:
nikolark committed 2015-10-01 22:54:50 +02:00
1 parent bc6029e289
commit 9ff22d634f
17 files changed
+336 -287

No files matched your search

+2 -2
View File
@@ -2,7 +2,7 @@
*.swp
temp
*.log
settings.py
dns_mdb.db
local_settings.py
db.sqlite3
/.idea
/venv
-17
View File
@@ -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
+15
View File
@@ -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)
+3 -4
View File
@@ -1,9 +1,8 @@
#!/usr/bin/env python
import os, sys
import os
import sys
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
execute_from_command_line(sys.argv)
View File
File renamed without changes.
File renamed without changes.
+6
View File
@@ -0,0 +1,6 @@
from rest_framework.views import APIView
class ValidatePuppetHostSecret(APIView):
# TODO
pass
+9 -5
View File
@@ -6,7 +6,11 @@ from difflib import context_diff
from django.core.management.base import BaseCommand
from django.core.mail import mail_admins
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
@@ -42,13 +46,13 @@ class Command(BaseCommand):
# do we need to do anything?
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)
# write to stdout
if output == sys.stdout:
print config.dhcpd_configuration()
print 'Not writing to file, serial not updated'
print(config.dhcpd_configuration())
print('Not writing to file, serial not updated')
return
# read current file contents
@@ -71,7 +75,7 @@ class Command(BaseCommand):
tofile=config.serial,
lineterm=''))
print diff
print(diff)
# update serial
old_serial = config.active_serial
+9 -5
View File
@@ -7,8 +7,12 @@ from difflib import context_diff
from django.core.management.base import BaseCommand
from django.core.mail import mail_admins
from optparse import make_option
from commands import getstatusoutput
from mdb.models import *
try:
from subprocess import getstatusoutput
except ImportError:
from commands import getstatusoutput
from mdb.models import Domain, Ip4Subnet, Ip6Subnet
class Command(BaseCommand):
@@ -43,7 +47,7 @@ class Command(BaseCommand):
# do the binaries exist?
for f in (self.checkzone_bin, self.bind_bin):
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:
sys.exit(1)
@@ -106,11 +110,11 @@ class Command(BaseCommand):
'diff': None,
}
print "updating %s %s [%d -> %d]" % (
print("updating %s %s [%d -> %d]" % (
zonetype,
zone.domain_name,
zone.domain_active_serial,
zone.domain_serial)
zone.domain_serial))
# generate zone file contents
new = zone.zone_file_contents()
+85
View File
@@ -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
View File
@@ -2,31 +2,36 @@ from django.db import models
from django.db.models import Count
from django.db.models.signals import post_save, pre_save, pre_delete
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 validators import validate_hostname, validate_macaddr
from mdb.validators import validate_hostname, validate_macaddr
import ipaddr
import ipaddress
import datetime
import re
@python_2_unicode_compatible
class Nameserver(models.Model):
hostname = models.CharField(max_length=256)
def __unicode__(self):
def __str__(self):
return self.hostname
@python_2_unicode_compatible
class MailExchange(models.Model):
priority = models.IntegerField()
hostname = models.CharField(max_length=256)
def __unicode__(self):
def __str__(self):
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)
@@ -38,14 +43,14 @@ class Domain(models.Model):
domain_expire = models.IntegerField(default=604800)
domain_minimum_ttl = models.IntegerField(default=86400)
domain_admin = models.EmailField()
domain_ipaddr = models.IPAddressField()
domain_ipaddr = models.GenericIPAddressField(protocol='IPv4')
domain_filename = models.CharField(max_length=256)
created_date = models.DateTimeField(auto_now_add=True)
domain_nameservers = models.ManyToManyField(Nameserver)
domain_mailexchanges = models.ManyToManyField(MailExchange)
def __unicode__(self):
def __str__(self):
return self.domain_name
def num_records(self):
@@ -63,6 +68,7 @@ class Domain(models.Model):
def __eq__(self, other):
if not other or not hasattr(other, 'domain_name'):
return False
return self.domain_name == other.domain_name
def zone_file_contents(self):
@@ -93,12 +99,12 @@ class Domain(models.Model):
content += "; SRV records\n"
for srv in self.domainsrvrecord_set.all():
content += unicode(srv) + "\n"
content += u(srv) + "\n"
content += "; A records\n"
for a in self.domainarecord_set.all():
content += unicode(a) + "\n"
content += u(a) + "\n"
content += "; CNAME records \n"
@@ -108,7 +114,7 @@ class Domain(models.Model):
content += "; TXT records \n"
for txt in self.domaintxtrecord_set.all():
content += unicode(txt) + "\n"
content += u(txt) + "\n"
content += "; HOST records\n"
@@ -126,6 +132,7 @@ 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)
@@ -137,42 +144,46 @@ class DomainSrvRecord(models.Model):
domain = models.ForeignKey(Domain)
created_date = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
def __str__(self):
return self.srvce + "." + self.prot + "." + self.name + ". IN SRV " \
+ str(self.priority) + " " + str(self.weight) + " " + \
str(self.port) + " " + self.target + "."
@python_2_unicode_compatible
class DomainTxtRecord(models.Model):
name = models.CharField(max_length=256)
target = models.CharField(max_length=256)
domain = models.ForeignKey(Domain)
created_date = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
def __str__(self):
return self.name + " TXT " + self.target
@python_2_unicode_compatible
class DomainCnameRecord(models.Model):
name = models.CharField(max_length=256)
target = models.CharField(max_length=256)
domain = models.ForeignKey(Domain)
created_date = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
def __str__(self):
return self.name + " IN CNAME " + self.target
@python_2_unicode_compatible
class DomainARecord(models.Model):
name = models.CharField(max_length=256)
target = models.CharField(max_length=256)
domain = models.ForeignKey(Domain)
created_date = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
def __str__(self):
return self.name + " IN A " + self.target
@python_2_unicode_compatible
class DhcpConfig(models.Model):
serial = models.IntegerField()
active_serial = models.IntegerField()
@@ -229,13 +240,14 @@ class DhcpConfig(models.Model):
return content
def __unicode__(self):
def __str__(self):
return self.name
class Meta:
verbose_name = 'DHCP config'
@python_2_unicode_compatible
class Ip6Subnet(models.Model):
name = models.CharField(max_length=255)
network = models.CharField(max_length=255)
@@ -254,7 +266,7 @@ class Ip6Subnet(models.Model):
domain_admin = models.EmailField()
domain_filename = models.CharField(max_length=256)
def __unicode__(self):
def __str__(self):
return self.network + " (" + self.name + ")"
def zone_file_contents(self, generate_unassigned=False):
@@ -292,7 +304,7 @@ class Ip6Subnet(models.Model):
addr.interface.host.hostname,
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]
content += "%s\tPTR\t%s.\n" % (ip, hostname)
@@ -305,10 +317,11 @@ class Ip6Subnet(models.Model):
verbose_name = 'IPv6 subnet'
@python_2_unicode_compatible
class Ip4Subnet(models.Model):
name = models.CharField(max_length=256)
netmask = models.IPAddressField()
network = models.IPAddressField()
netmask = models.GenericIPAddressField(protocol='IPv4')
network = models.GenericIPAddressField(protocol='IPv4')
created_date = models.DateTimeField(auto_now_add=True)
domain_name = models.CharField(max_length=255, editable=False)
domain_nameservers = models.ManyToManyField(Nameserver)
@@ -324,29 +337,29 @@ class Ip4Subnet(models.Model):
domain_filename = models.CharField(max_length=256)
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_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)
def __unicode__(self):
def __str__(self):
return self.network + " (" + self.name + ")"
def num_addresses(self):
subnet = ipaddr.IPv4Network(self.network + "/" + self.netmask)
subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask)
return subnet.numhosts
def broadcast_address(self):
subnet = ipaddr.IPv4Network(self.network + "/" + self.netmask)
subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask)
return subnet.broadcast
def first_address(self):
subnet = ipaddr.IPv4Network(self.network + "/" + self.netmask)
subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask)
return subnet.iterhosts().next()
def last_address(self):
subnet = ipaddr.IPv4Network(self.network + "/" + self.netmask)
subnet = ipaddress.IPv4Network(self.network + "/" + self.netmask)
for curr in subnet.iterhosts():
pass # horribly ineficcient
pass # horribly inefficient
return curr
@@ -405,18 +418,20 @@ 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)
def __unicode__(self):
def __str__(self):
return self.key + " " + self.value
class Meta:
verbose_name = 'DHCP option'
@python_2_unicode_compatible
class DhcpCustomField(models.Model):
value = models.CharField(max_length=255)
ip4subnet = models.ForeignKey(Ip4Subnet)
@@ -425,22 +440,20 @@ class DhcpCustomField(models.Model):
verbose_name = 'DHCP custom field'
@python_2_unicode_compatible
class Ip4Address(models.Model):
subnet = models.ForeignKey(Ip4Subnet)
address = models.IPAddressField()
address = models.GenericIPAddressField(protocol='IPv4')
last_contact = models.DateTimeField(null=True, blank=True)
ping_avg_rtt = models.FloatField(null=True, blank=True)
def __unicode__(self):
def __str__(self):
# FIXME: generates 2 SQL queries
_if = self.interface_set.all()
if not _if:
return self.address
return "{} ({})".format(
self.address,
_if.get().host.hostname
)
return "{} ({})".format(self.address, _if.get().host.hostname)
def assigned_to_host(self):
return self.interface_set.get().host
@@ -452,11 +465,12 @@ 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)
def __unicode__(self):
def __str__(self):
return self.host_type
def num_members(self):
@@ -466,6 +480,7 @@ class HostType(models.Model):
ordering = ("host_type",)
@python_2_unicode_compatible
class OperatingSystem(models.Model):
OS_ARCHITECTURES = (
('mips', _('MIPS')),
@@ -482,13 +497,14 @@ class OperatingSystem(models.Model):
version = models.CharField(max_length=64)
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 + ")"
class Meta:
ordering = ("name", "version")
@python_2_unicode_compatible
class Host(models.Model):
location = 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_created_date = models.DateTimeField(null=True, blank=True, editable=False)
def __unicode__(self):
def __str__(self):
return self.hostname
def in_domain(self):
@@ -531,23 +547,25 @@ class Host(models.Model):
return ",".join(addresses)
@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.ForeignKey(Ip4Address, blank=True, null=True, unique=True)
ip4address = models.OneToOneField(Ip4Address, blank=True, null=True)
created_date = models.DateTimeField(auto_now_add=True)
domain = models.ForeignKey(Domain)
def __unicode__(self):
def __str__(self):
return "%s (%s on %s)" % (self.macaddr, self.name, self.host.hostname)
def ipv6_enabled(self):
return self.ip6address_set.count() > 0
@python_2_unicode_compatible
class Ip6Address(models.Model):
subnet = models.ForeignKey(Ip6Subnet)
address = models.CharField(max_length=64)
@@ -556,7 +574,7 @@ class Ip6Address(models.Model):
def full_address(self):
return self.subnet.network + self.address
def __unicode__(self):
def __str__(self):
return "%s (%s on %s)" % (
self.full_address(),
self.interface.name,
@@ -604,7 +622,7 @@ def create_ips_for_subnet(sender, instance, created, **kwargs):
if not created:
return
subnet = ipaddr.IPv4Network(instance.network + "/" + instance.netmask)
subnet = ipaddress.IPv4Network(instance.network + "/" + instance.netmask)
for addr in subnet.iterhosts():
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:
return
network = ipaddr.IPv6Address("%s::" % instance.network)
network = ipaddress.IPv6Address("%s::" % instance.network)
instance.domain_name = ".".join(network.exploded.replace(":", "")[:16])[::-1] + ".ip6.arpa"
-191
View File
@@ -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
View File
@@ -1,16 +1,12 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
from django.core.urlresolvers import reverse
from rest_framework.test import APITestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)
class APITestCases(APITestCase):
def test_validate_puppet_host_by_secret(self):
data = {
'secret': 'something',
'certname': 'arnold.neuf.no'
}
res = self.client.post(reverse('api-validate-host-secret'), data)
self.fail()
+128
View File
@@ -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
+5 -4
View File
@@ -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.staticfiles.urls import staticfiles_urlpatterns
from django.views.generic.base import RedirectView
from mdb.api.views import ValidatePuppetHostSecret
admin.autodiscover()
urlpatterns = patterns(
'',
urlpatterns = [
url(r'^$', RedirectView.as_view(url='admin/')),
url(r'^admin/', include(admin.site.urls)),
)
url(r'^api/validate-host-secret', ValidatePuppetHostSecret.as_view(), name='api-validate-host-secret')
]
urlpatterns += staticfiles_urlpatterns()
View File
File renamed without changes.
+5 -4
View File
@@ -1,5 +1,6 @@
Django>=1.7,<1.8
MySQL-python==1.2.5
ipaddr==2.1.11
Django>=1.8,<1.9
django-auth-ldap
django-suit
django-suit==0.2.15
djangorestframework==3.2.4
ipaddress==1.0.14
mysqlclient==1.3.6