From 89544d521e6aa52e8b9e5e7dc4676046b5792abd Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Tue, 23 Aug 2016 12:53:39 +0200 Subject: [PATCH] dns: fix crash in interactive mode against old servers Add a client-side fallback of the dnsrecord_split_parts command for old servers to avoid CommandError in dnsrecord_add and dnsrecord_mod CLI interactive mode. https://fedorahosted.org/freeipa/ticket/6203 Reviewed-By: Martin Basti --- ipaclient/plugins/dns.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/ipaclient/plugins/dns.py b/ipaclient/plugins/dns.py index 5e29b8c6666f94f52add7f2e1de8679127886fc2..b9ab709bf0b1d72cfb9d32aeefd77a0e8bc74d7a 100644 --- a/ipaclient/plugins/dns.py +++ b/ipaclient/plugins/dns.py @@ -22,6 +22,7 @@ from __future__ import print_function import six import copy +import re from ipaclient.frontend import MethodOverride from ipalib import errors @@ -30,7 +31,8 @@ from ipalib.dns import (get_record_rrtype, iterate_rrparams_by_parts, part_name_format, record_name_format) -from ipalib.parameters import Bool +from ipalib.frontend import Command +from ipalib.parameters import Bool, Str from ipalib.plugable import Registry from ipalib import _, ngettext from ipapython.dnsutil import DNSName @@ -121,6 +123,64 @@ class dnszone_mod(DNSZoneMethodOverride): pass +# Support old servers without dnsrecord_split_parts +# Do not add anything new here! +@register(no_fail=True) +class dnsrecord_split_parts(Command): + NO_CLI = True + + takes_args = ( + Str('name'), + Str('value'), + ) + + def execute(self, name, value, *args, **options): + def split_exactly(count): + values = value.split() + if len(values) != count: + return None + return tuple(values) + + result = () + + rrtype = get_record_rrtype(name) + if rrtype in ('A', 'AAAA', 'CNAME', 'DNAME', 'NS', 'PTR'): + result = split_exactly(1) + elif rrtype in ('AFSDB', 'KX', 'MX'): + result = split_exactly(2) + elif rrtype in ('CERT', 'DLV', 'DS', 'SRV', 'TLSA'): + result = split_exactly(4) + elif rrtype in ('NAPTR'): + result = split_exactly(6) + elif rrtype in ('A6', 'TXT'): + result = (value,) + elif rrtype == 'LOC': + regex = re.compile( + r'(?P\d{1,2}\s+)' + r'(?:(?P\d{1,2}\s+)' + r'(?P\d{1,2}(?:\.\d{1,3})?\s+)?)?' + r'(?P[NS])\s+' + r'(?P\d{1,3}\s+)' + r'(?:(?P\d{1,2}\s+)' + r'(?P\d{1,2}(?:\.\d{1,3})?\s+)?)?' + r'(?P[WE])\s+' + r'(?P-?\d{1,8}(?:\.\d{1,2})?)m?' + r'(?:\s+(?P\d{1,8}(?:\.\d{1,2})?)m?' + r'(?:\s+(?P\d{1,8}(?:\.\d{1,2})?)m?' + r'(?:\s+(?P\d{1,8}(?:\.\d{1,2})?)m?\s*)?)?)?$') + + m = regex.match(value) + if m is not None: + result = tuple( + x.strip() if x is not None else x for x in m.groups()) + elif rrtype == 'SSHFP': + values = value.split(None, 2) + if len(values) == 3: + result = tuple(values) + + return dict(result=result) + + @register(override=True, no_fail=True) class dnsrecord_add(MethodOverride): no_option_msg = 'No options to add a specific record provided.\n' \ -- 2.7.4