Skip to content

Commit

Permalink
add support for classless delegated PTR zones
Browse files Browse the repository at this point in the history
  • Loading branch information
YanChii committed Oct 28, 2020
1 parent 9d779c3 commit 2c149dc
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 11 deletions.
2 changes: 1 addition & 1 deletion api/network/base/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class NetworkSerializer(s.ConditionalDCBoundSerializer):
mtu = s.IntegerField(min_value=576, max_value=9000, required=False) # values from man vmadm
resolvers = s.IPAddressArrayField(source='resolvers_api', required=False, max_items=8)
dns_domain = s.RegexField(r'^[A-Za-z0-9][A-Za-z0-9\._-]*$', max_length=250, required=False) # can be blank
ptr_domain = s.RegexField(r'^[A-Za-z0-9][A-Za-z0-9\._-]*$', max_length=250, required=False) # can be blank
ptr_domain = s.RegexField(r'^[A-Za-z0-9][/A-Za-z0-9\._-]*$', max_length=250, required=False) # can be blank
dhcp_passthrough = s.BooleanField(default=False)
created = s.DateTimeField(read_only=True, required=False)

Expand Down
2 changes: 1 addition & 1 deletion api/vm/define/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1559,7 +1559,7 @@ def save_ptr(request, task_id, vm, ip, net, delete=False, content=None):

record_cls = RecordView.Record
ipaddr = str(ip.ip)
ptr = record_cls.get_record_PTR(ipaddr)
ptr = record_cls.get_record_PTR(ipaddr, net.ptr_domain)
logger.info('%s DNS PTR record for vm %s, domain %s, name %s.',
'Deleting' if delete else 'Adding', vm, net.ptr_domain, ipaddr)

Expand Down
2 changes: 1 addition & 1 deletion gui/templates/gui/vm/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@
</thead>

<tbody id="vm_nic_{{ vm.hostname }}">
{% for nic in vm_nics %}{% with ip=nic.ip ptr=vm|record_PTR:nic.ip %}
{% for nic in vm_nics %}{% with ip=nic.ip ptr=vm|record_PTR:nic %}
<tr class="row1">
<td>
{{ nic.nic_id }}
Expand Down
11 changes: 8 additions & 3 deletions gui/templatetags/gui_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,20 @@
from api.mon.backends.zabbix.containers import ZabbixMediaContainer
from api.utils.encoders import JSONEncoder
from pdns.models import Record
from vms.models import Subnet

register = template.Library()


# noinspection PyPep8Naming
@register.filter
def record_PTR(vm, ip):
if ip and vm.dc.settings.DNS_ENABLED:
return Record.get_record_PTR(ip)
def record_PTR(vm, nic):
if nic.ip and vm.dc.settings.DNS_ENABLED:
try:
ptr_domain = Subnet.objects.get(name=nic.net).ptr_name
except Exception:
ptr_domain = ''
return Record.get_record_PTR(nic.ip, ptr_domain)
else:
return None

Expand Down
22 changes: 17 additions & 5 deletions pdns/models/record.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import time
from datetime import datetime
from logging import getLogger
from re import match

from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.six import text_type
Expand Down Expand Up @@ -214,14 +216,24 @@ def add_or_update_record(cls, type, domain, name, content, ttl=None, prio=None):
return rec.save()

@staticmethod
def get_reverse(ipaddr):
return reversename.from_address(ipaddr).to_text(omit_final_dot=True)
def get_reverse(ipaddr, domain=''):
rev = reversename.from_address(ipaddr).to_text(omit_final_dot=True)
if match('^[0-9]+/', domain):
# it's a classless delegated domain (e.g. 0/26.0.0.10-in-addr.arpa),
# we need to transform the reverse (e.g. 111.0.0.10-in-addr.arpa -> 111.0/26.0.0.10-in-addr.arpa)
ptr_cidr = domain.split('.', 1)[0]
rev_split = rev.split('.', 1)
return '%s.%s.%s' % (rev_split[0], ptr_cidr, rev_split[1])

else:
# normal PTR domain
return rev

# noinspection PyPep8Naming
@classmethod
def get_record_PTR(cls, ipaddr):
def get_record_PTR(cls, ipaddr, domain=''):
try:
return cls.objects.select_related('domain').get(type=cls.PTR, name=cls.get_reverse(ipaddr))
return cls.objects.select_related('domain').get(type=cls.PTR, name=cls.get_reverse(ipaddr, domain))
except cls.DoesNotExist:
return None
except exception.SyntaxError: # ipaddr in wrong format
Expand All @@ -230,7 +242,7 @@ def get_record_PTR(cls, ipaddr):
# noinspection PyPep8Naming
@classmethod
def add_record_PTR(cls, domain, ipaddr, content):
return cls.add_record(cls.PTR, domain, cls.get_reverse(ipaddr), content)
return cls.add_record(cls.PTR, domain, cls.get_reverse(ipaddr, domain), content)

# noinspection PyPep8Naming
@classmethod
Expand Down

0 comments on commit 2c149dc

Please sign in to comment.