mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add ability to specify DNS reverse zone name by IP network address.
In order for this to work, chaining of parameters through default_from is made possible. ticket 1474
This commit is contained in:
committed by
Rob Crittenden
parent
d802aa57f1
commit
b203756a88
23
API.txt
23
API.txt
@@ -737,8 +737,9 @@ output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), 'User-friendly
|
||||
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
|
||||
output: Output('value', <type 'unicode'>, "The primary_key value of the entry, e.g. 'jdoe' for a user")
|
||||
command: dnszone_add
|
||||
args: 1,18,3
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, required=True)
|
||||
args: 1,19,3
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', default_from=DefaultFrom(<lambda>, 'name_from_ip'), label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, required=True)
|
||||
option: Str('name_from_ip', _validate_ipnet, attribute=True, cli_name='name_from_ip', label=Gettext('Reverse zone IP network', domain='ipa', localedir=None), multivalue=False, required=False)
|
||||
option: Str('idnssoamname', attribute=True, cli_name='name_server', label=Gettext('Authoritative nameserver', domain='ipa', localedir=None), multivalue=False, required=True)
|
||||
option: Str('idnssoarname', attribute=True, cli_name='admin_email', default_from=DefaultFrom(<lambda>, 'idnsname'), label=Gettext('Administrator e-mail address', domain='ipa', localedir=None), multivalue=False, normalizer=_rname_normalizer, required=True)
|
||||
option: Int('idnssoaserial', attribute=True, autofill=True, cli_name='serial', create_default=_create_zone_serial, label=Gettext('SOA serial', domain='ipa', localedir=None), minvalue=1, multivalue=False, required=False)
|
||||
@@ -762,27 +763,28 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
|
||||
output: Output('value', <type 'unicode'>, "The primary_key value of the entry, e.g. 'jdoe' for a user")
|
||||
command: dnszone_del
|
||||
args: 1,1,3
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=True, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', default_from=DefaultFrom(<lambda>, 'name_from_ip'), label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=True, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
option: Flag('continue', autofill=True, cli_name='continue', default=False)
|
||||
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), 'User-friendly description of action performed')
|
||||
output: Output('result', <type 'dict'>, 'list of deletions that failed')
|
||||
output: Output('value', <type 'unicode'>, "The primary_key value of the entry, e.g. 'jdoe' for a user")
|
||||
command: dnszone_disable
|
||||
args: 1,0,3
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', default_from=DefaultFrom(<lambda>, 'name_from_ip'), label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), 'User-friendly description of action performed')
|
||||
output: Output('result', <type 'bool'>, 'True means the operation was successful')
|
||||
output: Output('value', <type 'unicode'>, "The primary_key value of the entry, e.g. 'jdoe' for a user")
|
||||
command: dnszone_enable
|
||||
args: 1,0,3
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', default_from=DefaultFrom(<lambda>, 'name_from_ip'), label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), 'User-friendly description of action performed')
|
||||
output: Output('result', <type 'bool'>, 'True means the operation was successful')
|
||||
output: Output('value', <type 'unicode'>, "The primary_key value of the entry, e.g. 'jdoe' for a user")
|
||||
command: dnszone_find
|
||||
args: 1,19,4
|
||||
args: 1,20,4
|
||||
arg: Str('criteria?', noextrawhitespace=False)
|
||||
option: Str('idnsname', attribute=True, autofill=False, cli_name='name', label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=False)
|
||||
option: Str('idnsname', attribute=True, autofill=False, cli_name='name', default_from=DefaultFrom(<lambda>, 'name_from_ip'), label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=False)
|
||||
option: Str('name_from_ip', _validate_ipnet, attribute=True, autofill=False, cli_name='name_from_ip', label=Gettext('Reverse zone IP network', domain='ipa', localedir=None), multivalue=False, query=True, required=False)
|
||||
option: Str('idnssoamname', attribute=True, autofill=False, cli_name='name_server', label=Gettext('Authoritative nameserver', domain='ipa', localedir=None), multivalue=False, query=True, required=False)
|
||||
option: Str('idnssoarname', attribute=True, autofill=False, cli_name='admin_email', default_from=DefaultFrom(<lambda>, 'idnsname'), label=Gettext('Administrator e-mail address', domain='ipa', localedir=None), multivalue=False, normalizer=_rname_normalizer, query=True, required=False)
|
||||
option: Int('idnssoaserial', attribute=True, autofill=False, cli_name='serial', create_default=_create_zone_serial, label=Gettext('SOA serial', domain='ipa', localedir=None), minvalue=1, multivalue=False, query=True, required=False)
|
||||
@@ -806,8 +808,9 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
|
||||
output: Output('count', <type 'int'>, 'Number of entries returned')
|
||||
output: Output('truncated', <type 'bool'>, 'True if not all results were returned')
|
||||
command: dnszone_mod
|
||||
args: 1,17,3
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
args: 1,18,3
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', default_from=DefaultFrom(<lambda>, 'name_from_ip'), label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
option: Str('name_from_ip', _validate_ipnet, attribute=True, autofill=False, cli_name='name_from_ip', label=Gettext('Reverse zone IP network', domain='ipa', localedir=None), multivalue=False, required=False)
|
||||
option: Str('idnssoamname', attribute=True, autofill=False, cli_name='name_server', label=Gettext('Authoritative nameserver', domain='ipa', localedir=None), multivalue=False, required=False)
|
||||
option: Str('idnssoarname', attribute=True, autofill=False, cli_name='admin_email', default_from=DefaultFrom(<lambda>, 'idnsname'), label=Gettext('Administrator e-mail address', domain='ipa', localedir=None), multivalue=False, normalizer=_rname_normalizer, required=False)
|
||||
option: Int('idnssoaserial', attribute=True, autofill=False, cli_name='serial', create_default=_create_zone_serial, label=Gettext('SOA serial', domain='ipa', localedir=None), minvalue=1, multivalue=False, required=False)
|
||||
@@ -830,7 +833,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
|
||||
output: Output('value', <type 'unicode'>, "The primary_key value of the entry, e.g. 'jdoe' for a user")
|
||||
command: dnszone_show
|
||||
args: 1,4,3
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
arg: Str('idnsname', attribute=True, cli_name='name', default_from=DefaultFrom(<lambda>, 'name_from_ip'), label=Gettext('Zone name', domain='ipa', localedir=None), multivalue=False, normalizer=<lambda>, primary_key=True, query=True, required=True)
|
||||
option: Flag('rights', autofill=True, default=False, label=Gettext('Rights', domain='ipa', localedir=None))
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui', flags=['no_output'])
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui', flags=['no_output'])
|
||||
|
||||
2
VERSION
2
VERSION
@@ -79,4 +79,4 @@ IPA_DATA_VERSION=20100614120000
|
||||
# #
|
||||
########################################################
|
||||
IPA_API_VERSION_MAJOR=2
|
||||
IPA_API_VERSION_MINOR=9
|
||||
IPA_API_VERSION_MINOR=10
|
||||
|
||||
@@ -408,7 +408,11 @@ class Command(HasParam):
|
||||
self.debug(
|
||||
'raw: %s(%s)', self.name, ', '.join(self._repr_iter(**params))
|
||||
)
|
||||
params.update(self.get_default(**params))
|
||||
while True:
|
||||
default = self.get_default(**params)
|
||||
if len(default) == 0:
|
||||
break
|
||||
params.update(default)
|
||||
params = self.normalize(**params)
|
||||
params = self.convert(**params)
|
||||
self.debug(
|
||||
|
||||
@@ -28,6 +28,10 @@ EXAMPLES:
|
||||
ipa dnszone-add example.com --name-server nameserver.example.com
|
||||
--admin-email admin@example.com
|
||||
|
||||
Add new reverse zone specified by network IP address:
|
||||
ipa dnszone-add --name-from-ip 80.142.15.0/24
|
||||
--name-server nameserver.example.com
|
||||
|
||||
Add second nameserver for example.com:
|
||||
ipa dnsrecord-add example.com @ --ns-rec nameserver2.example.com
|
||||
|
||||
@@ -141,6 +145,16 @@ def _create_zone_serial(**kwargs):
|
||||
"""Generate serial number for zones."""
|
||||
return int('%s01' % time.strftime('%Y%d%m'))
|
||||
|
||||
def _reverse_zone_name(netstr):
|
||||
net = netaddr.IPNetwork(netstr)
|
||||
items = net.ip.reverse_dns.split('.')
|
||||
if net.version == 4:
|
||||
return u'.'.join(items[4 - net.prefixlen / 8:])
|
||||
elif net.version == 6:
|
||||
return u'.'.join(items[32 - net.prefixlen / 4:])
|
||||
else:
|
||||
return None
|
||||
|
||||
def _validate_ipaddr(ugettext, ipaddr):
|
||||
try:
|
||||
ip = netaddr.IPAddress(ipaddr)
|
||||
@@ -293,9 +307,14 @@ class dnszone(LDAPObject):
|
||||
cli_name='name',
|
||||
label=_('Zone name'),
|
||||
doc=_('Zone name (FQDN)'),
|
||||
default_from=lambda name_from_ip: _reverse_zone_name(name_from_ip),
|
||||
normalizer=lambda value: value.lower(),
|
||||
primary_key=True,
|
||||
),
|
||||
Str('name_from_ip?', _validate_ipnet,
|
||||
label=_('Reverse zone IP network'),
|
||||
doc=_('IP network to create reverse zone name from'),
|
||||
),
|
||||
Str('idnssoamname',
|
||||
cli_name='name_server',
|
||||
label=_('Authoritative nameserver'),
|
||||
@@ -401,6 +420,9 @@ class dnszone_add(LDAPCreate):
|
||||
if not dns_container_exists(self.api.Backend.ldap2):
|
||||
raise errors.NotFound(reason=_('DNS is not configured'))
|
||||
|
||||
if 'name_from_ip' in entry_attrs:
|
||||
del entry_attrs['name_from_ip']
|
||||
|
||||
entry_attrs['idnszoneactive'] = 'TRUE'
|
||||
entry_attrs['idnsallowdynupdate'] = str(
|
||||
entry_attrs.get('idnsallowdynupdate', False)
|
||||
@@ -445,6 +467,8 @@ class dnszone_mod(LDAPUpdate):
|
||||
Modify DNS zone (SOA record).
|
||||
"""
|
||||
def pre_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
if 'name_from_ip' in entry_attrs:
|
||||
del entry_attrs['name_from_ip']
|
||||
entry_attrs['idnsallowdynupdate'] = str(
|
||||
entry_attrs.get('idnsallowdynupdate', False)
|
||||
).upper()
|
||||
@@ -457,6 +481,12 @@ class dnszone_find(LDAPSearch):
|
||||
"""
|
||||
Search for DNS zones (SOA records).
|
||||
"""
|
||||
def args_options_2_entry(self, *args, **options):
|
||||
if 'name_from_ip' in options:
|
||||
if 'idnsname' not in options:
|
||||
options['idnsname'] = self.obj.params['idnsname'].get_default(**options)
|
||||
del options['name_from_ip']
|
||||
return super(dnszone_find, self).args_options_2_entry(self, *args, **options)
|
||||
|
||||
takes_options = LDAPSearch.takes_options + (
|
||||
Flag('forward_only',
|
||||
|
||||
@@ -418,6 +418,33 @@ class test_Command(ClassChecker):
|
||||
"""
|
||||
# FIXME: Add an updated unit tests for get_default()
|
||||
|
||||
def test_default_from_chaining(self):
|
||||
"""
|
||||
Test chaining of parameters through default_from.
|
||||
"""
|
||||
class my_cmd(self.cls):
|
||||
takes_options = (
|
||||
Str('option0'),
|
||||
Str('option1', default_from=lambda option0: option0),
|
||||
Str('option2', default_from=lambda option1: option1),
|
||||
)
|
||||
|
||||
def run(self, *args, **options):
|
||||
return dict(result=options)
|
||||
|
||||
kw = dict(option0=u'some value')
|
||||
|
||||
(api, home) = create_test_api()
|
||||
api.finalize()
|
||||
o = my_cmd()
|
||||
o.set_api(api)
|
||||
o.finalize()
|
||||
e = o(**kw)
|
||||
assert type(e) is dict
|
||||
assert 'result' in e
|
||||
assert 'option2' in e['result']
|
||||
assert e['result']['option2'] == u'some value'
|
||||
|
||||
def test_validate(self):
|
||||
"""
|
||||
Test the `ipalib.frontend.Command.validate` method.
|
||||
|
||||
Reference in New Issue
Block a user