Add fields to dns models

Add description to zone, add category and description to record
This commit is contained in:
rdujardin 2016-07-21 13:03:39 +02:00
parent 6230ae13cc
commit efe61886a0
12 changed files with 157 additions and 45 deletions

View File

@ -13,7 +13,7 @@ class ZoneSerializer(serializers.ModelSerializer):
class Meta:
model=Zone
fields = ['id', 'name', 'ttl', 'soa_name', 'soa_contact', 'soa_serial', 'soa_refresh', 'soa_retry', 'soa_expire', 'soa_minimum']
fields = ['id', 'name', 'ttl', 'soa_name', 'soa_contact', 'soa_serial', 'soa_refresh', 'soa_retry', 'soa_expire', 'soa_minimum', 'description']
def get_bind_export(self, obj):
records = Record.objects.filter(zone=obj)
@ -39,7 +39,7 @@ class RecordSerializer(serializers.ModelSerializer):
class Meta:
model=Record
fields = ['id', 'name', 'record_type', 'priority', 'zone', 'address', 'value']
fields = ['id', 'name', 'category', 'record_type', 'priority', 'zone', 'address', 'value', 'description']
def get_bind_export(self, obj):
return {

View File

@ -6,7 +6,7 @@ from .models import (
Zone,
Record,
)
from .forms import record_type_choices
from .forms import record_type_choices, record_category_choices
class ZoneFilter(django_filters.FilterSet):
name = django_filters.CharFilter(
@ -32,6 +32,11 @@ class RecordFilter(django_filters.FilterSet):
label = 'Type',
choices = record_type_choices
)
cateogry = django_filters.MultipleChoiceFilter(
name = 'category',
label = 'Category',
choices = record_category_choices
)
name = django_filters.CharFilter(
name = 'name',
lookup_type = 'icontains',
@ -43,7 +48,7 @@ class RecordFilter(django_filters.FilterSet):
class Meta:
model=Record
field = ['name','record_type','value']
field = ['name', 'record_type', 'value', 'category']
def filter_name_or_value(self, queryset, value):
if not value:

View File

@ -19,7 +19,7 @@ class ZoneForm(forms.ModelForm, BootstrapMixin):
class Meta:
model=Zone
fields = ['name', 'ttl', 'soa_name', 'soa_contact', 'soa_serial', 'soa_refresh', 'soa_retry', 'soa_expire', 'soa_minimum']
fields = ['name', 'ttl', 'soa_name', 'soa_contact', 'soa_serial', 'soa_refresh', 'soa_retry', 'soa_expire', 'soa_minimum', 'description']
labels = {
'soa_name': 'SOA Name',
'soa_contact': 'SOA Contact',
@ -28,6 +28,7 @@ class ZoneForm(forms.ModelForm, BootstrapMixin):
'soa_retry': 'SOA Retry',
'soa_expire': 'SOA Expire',
'soa_minimum': 'SOA Minimum',
'description': 'Description',
}
help_texts = {
'ttl': "Time to live, in seconds",
@ -44,7 +45,7 @@ class ZoneFromCSVForm(forms.ModelForm):
class Meta:
model=Zone
fields = ['name', 'ttl', 'soa_name', 'soa_contact', 'soa_serial', 'soa_refresh', 'soa_retry', 'soa_expire', 'soa_minimum']
fields = ['name', 'ttl', 'soa_name', 'soa_contact', 'soa_serial', 'soa_refresh', 'soa_retry', 'soa_expire', 'soa_minimum', 'description']
class ZoneImportForm(BulkImportForm, BootstrapMixin):
csv = CSVDataField(csv_form=ZoneFromCSVForm)
@ -59,6 +60,7 @@ class ZoneBulkEditForm(forms.Form, BootstrapMixin):
soa_retry = forms.IntegerField(required=False, label='SOA Retry')
soa_expire = forms.IntegerField(required=False, label='SOA Expire')
soa_minimum = forms.IntegerField(required=False, label='SOA Minimum')
description = forms.CharField(max_length=100, required=False, label='Description')
class ZoneBulkDeleteForm(ConfirmationForm):
@ -75,13 +77,14 @@ class RecordForm(forms.ModelForm, BootstrapMixin):
class Meta:
model=Record
fields = ['name', 'record_type', 'priority', 'zone', 'address', 'value']
fields = ['name', 'category', 'record_type', 'priority', 'zone', 'address', 'value', 'description']
labels = {
'record_type': 'Type',
}
help_texts = {
'name': 'Host name, @ for origin (e.g. www)',
'record_type': 'Record type (e.g. MX or AAAA)',
'category': 'Category (e.g. SLA, Server or Customer)',
'priority': 'Priority level (e.g. 10)',
'zone': 'Zone the record belongs to',
'address': 'IP address if value is an IP address, in AAAA records for instance',
@ -95,7 +98,7 @@ class RecordFromCSVForm(forms.ModelForm):
class Meta:
model=Record
fields = ['zone', 'name', 'record_type', 'priority', 'address', 'value']
fields = ['zone', 'name', 'category', 'record_type', 'priority', 'address', 'value', 'description']
class RecordImportForm(BulkImportForm, BootstrapMixin):
csv = CSVDataField(csv_form=RecordFromCSVForm)
@ -103,6 +106,7 @@ class RecordImportForm(BulkImportForm, BootstrapMixin):
class RecordBulkEditForm(forms.Form, BootstrapMixin):
pk = forms.ModelMultipleChoiceField(queryset=Record.objects.all(), widget=forms.MultipleHiddenInput)
name = forms.CharField(max_length=100, required=False, label='Name')
category = forms.CharField(max_length=100, required=False, label='Category')
record_type = forms.CharField(max_length=100, required=False, label='Type')
priority = forms.IntegerField(required=False)
zone = forms.ModelChoiceField(queryset=Zone.objects.all(), required=False)
@ -126,9 +130,22 @@ def record_type_choices():
type_choices[r.record_type]+=1
return [(t, '{} ({})'.format(t, count)) for t,count in type_choices.items()]
def record_category_choices():
category_choices = {}
records = Record.objects.all()
for r in records:
if r.category:
if not r.category in category_choices:
category_choices[r.category]=1
else:
category_choices[r.category]+=1
return [(c, '{} ({})'.format(c, count)) for c,count in category_choices.items()]
class RecordFilterForm(forms.Form, BootstrapMixin):
zone__name = forms.MultipleChoiceField(required=False, choices=record_zone_choices, label='Zone',
widget=forms.SelectMultiple(attrs={'size': 8}))
record_type = forms.MultipleChoiceField(required=False, choices=record_type_choices, label='Type',
widget=forms.SelectMultiple(attrs={'size': 8}))
category = forms.MultipleChoiceField(required=False, choices=record_category_choices, label='Category',
widget=forms.SelectMultiple(attrs={'size': 8}))

View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-21 10:59
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dns', '0002_auto_20160719_1058'),
]
operations = [
migrations.AlterModelOptions(
name='record',
options={'ordering': ['category']},
),
migrations.AddField(
model_name='record',
name='category',
field=models.CharField(blank=True, max_length=20),
),
migrations.AddField(
model_name='record',
name='description',
field=models.CharField(blank=True, max_length=20),
),
migrations.AddField(
model_name='zone',
name='description',
field=models.CharField(blank=True, max_length=100),
),
]

View File

@ -22,6 +22,7 @@ class Zone(CreatedUpdatedModel):
soa_retry = models.PositiveIntegerField()
soa_expire = models.PositiveIntegerField()
soa_minimum = models.PositiveIntegerField()
description = models.CharField(max_length=100, blank=True)
class Meta:
ordering = ['name']
@ -43,6 +44,7 @@ class Zone(CreatedUpdatedModel):
str(self.soa_retry),
str(self.soa_expire),
str(self.soa_minimum),
self.description,
])
def to_bind(self,records):
@ -50,6 +52,7 @@ class Zone(CreatedUpdatedModel):
for r in records:
bind_records += r.to_bind()+'\n'
bind_export = '\n'.join([
'; '+self.name+((' ('+self.description+')') if self.description else ''),
'; gen by netbox ( '+time.strftime('%A %B %d %Y %H:%M:%S',time.localtime())+' ) ',
'',
'$TTL '+str(self.ttl),
@ -79,9 +82,11 @@ class Record(CreatedUpdatedModel):
zone = models.ForeignKey('Zone', related_name='records', on_delete=models.CASCADE)
address = models.ForeignKey('ipam.IPAddress', related_name='records', on_delete=models.SET_NULL, blank=True, null=True)
value = models.CharField(max_length=100, blank=True)
category = models.CharField(max_length=20, blank=True)
description = models.CharField(max_length=20, blank=True)
class Meta:
ordering = ['name']
ordering = ['category']
def __unicode__(self):
return self.name
@ -98,10 +103,12 @@ class Record(CreatedUpdatedModel):
return ','.join([
self.zone.name,
self.name,
self.category,
self.record_type,
str(self.priority) if self.priority else '',
str(self.address) if self.address else '',
str(self.value) if self.value else '',
self.value,
self.description,
])
def to_bind(self):
@ -114,7 +121,7 @@ class Record(CreatedUpdatedModel):
' ',
(str(self.address).split('/')[0] if self.address else self.value).ljust(25),
' ',
' ; gen by netbox ( '+time.strftime('%A %B %d %Y %H:%M:%S',time.localtime())+' ) '
' ; '+self.description+' ; gen by netbox ( '+time.strftime('%A %B %d %Y %H:%M:%S',time.localtime())+' ) '
])

View File

@ -30,6 +30,7 @@ class ZoneTable(BaseTable):
class RecordTable(BaseTable):
pk = ToggleColumn()
name = tables.LinkColumn('dns:record', args=[Accessor('pk')], verbose_name='Name')
category = tables.Column(verbose_name='Category')
record_type = tables.Column(verbose_name='Type')
priority = tables.Column(verbose_name='Priority')
address = tables.LinkColumn('ipam:ipaddress', args=[Accessor('address.pk')], verbose_name='IP Address')
@ -38,15 +39,16 @@ class RecordTable(BaseTable):
class Meta(BaseTable.Meta):
model=Record
fields = ('pk', 'name', 'record_type', 'priority', 'address', 'value')
fields = ('pk', 'name', 'category', 'record_type', 'priority', 'address', 'value')
class RecordBriefTable(BaseTable):
name = tables.LinkColumn('dns:record', args=[Accessor('pk')], verbose_name='Name')
category = tables.Column(verbose_name='Category')
record_type = tables.Column(verbose_name='Type')
priority = tables.Column(verbose_name='Priority')
zone = tables.LinkColumn('dns:zone', args=[Accessor('zone.pk')], verbose_name='Zone')
class Meta(BaseTable.Meta):
model=Record
fields = ('name', 'record_type', 'priority', 'zone')
fields = ('name', 'category', 'record_type', 'priority', 'zone')

View File

@ -56,6 +56,15 @@
<td>Name</td>
<td>{{ record.name }}</td>
</tr>
<tr>
<td>Category</td>
<td>
{% if record.category %}
{{ record.category }}
{% else %}
-
{% endif %}
</td>
<tr>
<td>Type</td>
<td>{{ record.record_type }}</td>
@ -90,6 +99,16 @@
{% endif %}
</td>
</tr>
<tr>
<td>Description</td>
<td>
{% if record.description %}
{{ record.description }}
{% else %}
-
{% endif %}
</td>
</tr>
<tr>
<td>Created</td>
<td>{{ record.created }}</td>

View File

@ -7,11 +7,13 @@
{% for record in selected_objects %}
<tr>
<td><a href="{% url 'dns:record' pk=record.pk %}">{{ record.name }}</a></td>
<td>{{ record.category }}</td>
<td>{{ record.record_type }}</td>
<td>{{ record.priority }}</td>
<td>{{ record.address }}</td>
<td>{{ record.value }}</td>
<td>{{ record.zone }}</td>
<td>{{ record.description }}</td>
</tr>
{% endfor %}
{% endblock %}

View File

@ -38,6 +38,11 @@
<td>Host name, @ for origin</td>
<td>www</td>
</tr>
<tr>
<td>Category</td>
<td>Category (e.g. SLA, Server or Customer ; optional)</td>
<td>Server</td>
</tr>
<tr>
<td>Type</td>
<td>Record type</td>
@ -58,10 +63,15 @@
<td>Text value else, in CNAME records for instance</td>
<td>foo.net</td>
</tr>
<tr>
<td>Description</td>
<td>Description (optional)</td>
<td>Backend API server</td>
</tr>
</tbody>
</table>
<h4>Example</h4>
<pre>foo.net,www,AAAA,,192.168.1.110/16,</pre>
<pre>foo.net,www,Server,AAAA,,192.168.1.110/16,,Backend API server</pre>
</div>
</div>
{% endblock %}

View File

@ -90,6 +90,16 @@
<td>SOA Minimum</td>
<td>{{ zone.soa_minimum }}</td>
</tr>
<tr>
<td>Description</td>
<td>
{% if zone.description %}
{{ zone.description }}
{% else %}
-
{% endif %}
</td>
</tr>
<tr>
<td>Created</td>
<td>{{ zone.created }}</td>

View File

@ -14,6 +14,7 @@
<td>{{ zone.soa_retry }}</td>
<td>{{ zone.soa_expire }}</td>
<td>{{ zone.soa_minimum }}</td>
<td>{{ zone.description }}</td>
</tr>
{% endfor %}
{% endblock %}

View File

@ -73,10 +73,15 @@
<td>Negative result TTL, in seconds</td>
<td>1800</td>
</tr>
<tr>
<td>Description</td>
<td>Description (optional)</td>
<td>Mail servers zone</td>
</tr>
</tbody>
</table>
<h4>Example</h4>
<pre>foo.net,10800,@,ns.foo.net. noc.foo.net.,2016070401,3600,3600,604800,1800</pre>
<pre>foo.net,10800,@,ns.foo.net. noc.foo.net.,2016070401,3600,3600,604800,1800,Mail servers zone</pre>
</div>
</div>
{% endblock %}