mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Integrate realmdomains with IPA DNS
Add an entry to realmdomains when a DNS zone is added to IPA. Delete the related entry from realmdomains when the DNS zone is deleted from IPA. Add _kerberos TXT record to DNS zone when a new realmdomain is added. Delete _kerberos TXT record from DNS zone when realmdomain is deleted. Add unit tests to cover new functionality. https://fedorahosted.org/freeipa/ticket/3544
This commit is contained in:
parent
e736e75ce9
commit
a730b6e7b5
@ -1841,6 +1841,18 @@ class dnszone_add(LDAPCreate):
|
|||||||
dns_record,
|
dns_record,
|
||||||
nameserver_ip_address)
|
nameserver_ip_address)
|
||||||
|
|
||||||
|
# Add entry to realmdomains
|
||||||
|
# except for our own domain, forwarded zones and reverse zones
|
||||||
|
zone = keys[0]
|
||||||
|
|
||||||
|
if (zone != api.env.domain
|
||||||
|
and not options.get('idnsforwarders')
|
||||||
|
and not zone_is_reverse(zone)):
|
||||||
|
try:
|
||||||
|
api.Command['realmdomains_mod'](add_domain=zone, force=True)
|
||||||
|
except errors.EmptyModlist:
|
||||||
|
pass
|
||||||
|
|
||||||
return dn
|
return dn
|
||||||
|
|
||||||
api.register(dnszone_add)
|
api.register(dnszone_add)
|
||||||
@ -1857,6 +1869,17 @@ class dnszone_del(LDAPDelete):
|
|||||||
force=True)
|
force=True)
|
||||||
except errors.NotFound:
|
except errors.NotFound:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Delete entry from realmdomains
|
||||||
|
# except for our own domain
|
||||||
|
zone = keys[0]
|
||||||
|
|
||||||
|
if zone != api.env.domain:
|
||||||
|
try:
|
||||||
|
api.Command['realmdomains_mod'](del_domain=zone, force=True)
|
||||||
|
except errors.AttrValueNotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
api.register(dnszone_del)
|
api.register(dnszone_del)
|
||||||
|
@ -49,6 +49,10 @@ EXAMPLES:
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
def _domain_name_normalizer(d):
|
||||||
|
return d.lower().rstrip('.')
|
||||||
|
|
||||||
|
|
||||||
class realmdomains(LDAPObject):
|
class realmdomains(LDAPObject):
|
||||||
"""
|
"""
|
||||||
List of domains associated with IPA realm.
|
List of domains associated with IPA realm.
|
||||||
@ -64,16 +68,19 @@ class realmdomains(LDAPObject):
|
|||||||
takes_params = (
|
takes_params = (
|
||||||
Str('associateddomain+',
|
Str('associateddomain+',
|
||||||
_domain_name_validator,
|
_domain_name_validator,
|
||||||
|
normalizer=_domain_name_normalizer,
|
||||||
cli_name='domain',
|
cli_name='domain',
|
||||||
label=_('Domain'),
|
label=_('Domain'),
|
||||||
),
|
),
|
||||||
Str('add_domain?',
|
Str('add_domain?',
|
||||||
_domain_name_validator,
|
_domain_name_validator,
|
||||||
|
normalizer=_domain_name_normalizer,
|
||||||
cli_name='add_domain',
|
cli_name='add_domain',
|
||||||
label=_('Add domain'),
|
label=_('Add domain'),
|
||||||
),
|
),
|
||||||
Str('del_domain?',
|
Str('del_domain?',
|
||||||
_domain_name_validator,
|
_domain_name_validator,
|
||||||
|
normalizer=_domain_name_normalizer,
|
||||||
cli_name='del_domain',
|
cli_name='del_domain',
|
||||||
label=_('Delete domain'),
|
label=_('Delete domain'),
|
||||||
),
|
),
|
||||||
@ -133,6 +140,49 @@ class realmdomains_mod(LDAPUpdate):
|
|||||||
entry_attrs['associateddomain'] = domains
|
entry_attrs['associateddomain'] = domains
|
||||||
return dn
|
return dn
|
||||||
|
|
||||||
|
def execute(self, *keys, **options):
|
||||||
|
dn = self.obj.get_dn(*keys, **options)
|
||||||
|
ldap = self.obj.backend
|
||||||
|
|
||||||
|
domains_old = set(ldap.get_entry(dn)[1]['associateddomain'])
|
||||||
|
result = super(realmdomains_mod, self).execute(*keys, **options)
|
||||||
|
domains_new = set(ldap.get_entry(dn)[1]['associateddomain'])
|
||||||
|
|
||||||
|
domains_added = domains_new - domains_old
|
||||||
|
domains_deleted = domains_old - domains_new
|
||||||
|
|
||||||
|
# Add a _kerberos TXT record for zones that correspond with
|
||||||
|
# domains which were added
|
||||||
|
for d in domains_added:
|
||||||
|
# Skip our own domain
|
||||||
|
if d == api.env.domain:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
api.Command['dnsrecord_add'](
|
||||||
|
unicode(d),
|
||||||
|
u'_kerberos',
|
||||||
|
txtrecord=api.env.realm
|
||||||
|
)
|
||||||
|
except (errors.EmptyModlist, errors.NotFound):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Delete _kerberos TXT record from zones that correspond with
|
||||||
|
# domains which were deleted
|
||||||
|
for d in domains_deleted:
|
||||||
|
# Skip our own domain
|
||||||
|
if d == api.env.domain:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
api.Command['dnsrecord_del'](
|
||||||
|
unicode(d),
|
||||||
|
u'_kerberos',
|
||||||
|
txtrecord=api.env.realm
|
||||||
|
)
|
||||||
|
except (errors.AttrValueNotFound, errors.NotFound):
|
||||||
|
pass
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
api.register(realmdomains_mod)
|
api.register(realmdomains_mod)
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ dnszone1_rname = u'root.%s.' % dnszone1
|
|||||||
dnszone1_permission = u'Manage DNS zone %s' % dnszone1
|
dnszone1_permission = u'Manage DNS zone %s' % dnszone1
|
||||||
dnszone1_permission_dn = DN(('cn',dnszone1_permission),
|
dnszone1_permission_dn = DN(('cn',dnszone1_permission),
|
||||||
api.env.container_permission,api.env.basedn)
|
api.env.container_permission,api.env.basedn)
|
||||||
|
dnszone1_txtrec_dn = DN(('idnsname', '_kerberos'), dnszone1_dn)
|
||||||
dnszone2 = u'dnszone2.test'
|
dnszone2 = u'dnszone2.test'
|
||||||
dnszone2_dn = DN(('idnsname', dnszone2), api.env.container_dns, api.env.basedn)
|
dnszone2_dn = DN(('idnsname', dnszone2), api.env.container_dns, api.env.basedn)
|
||||||
dnszone2_mname = u'ns1.%s.' % dnszone2
|
dnszone2_mname = u'ns1.%s.' % dnszone2
|
||||||
@ -526,7 +527,7 @@ class test_dns(Declarative):
|
|||||||
command=('dnsrecord_find', [dnszone1], {}),
|
command=('dnsrecord_find', [dnszone1], {}),
|
||||||
expected={
|
expected={
|
||||||
'summary': None,
|
'summary': None,
|
||||||
'count': 3,
|
'count': 4,
|
||||||
'truncated': False,
|
'truncated': False,
|
||||||
'result': [
|
'result': [
|
||||||
{
|
{
|
||||||
@ -534,6 +535,11 @@ class test_dns(Declarative):
|
|||||||
'nsrecord': (dnszone1_mname,),
|
'nsrecord': (dnszone1_mname,),
|
||||||
'idnsname': [u'@'],
|
'idnsname': [u'@'],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'dn': dnszone1_txtrec_dn,
|
||||||
|
'txtrecord': [api.env.realm],
|
||||||
|
'idnsname': [u'_kerberos'],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'dn': dnszone1_mname_dn,
|
'dn': dnszone1_mname_dn,
|
||||||
'idnsname': [u'ns1'],
|
'idnsname': [u'ns1'],
|
||||||
|
168
tests/test_xmlrpc/test_dns_realmdomains_integration.py
Normal file
168
tests/test_xmlrpc/test_dns_realmdomains_integration.py
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# Authors:
|
||||||
|
# Ana Krivokapic <akrivoka@redhat.com>
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Red Hat
|
||||||
|
# see file 'COPYING' for use and warranty information
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"""
|
||||||
|
Test integration of DNS and realmdomains.
|
||||||
|
1. dnszone_{add,del} should create/delete appropriate entry in realmdomains.
|
||||||
|
2. realmdomains_mod should add a _kerberos TXT record in the DNS zone.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ipalib import api, errors
|
||||||
|
from ipapython.dn import DN
|
||||||
|
from tests.test_xmlrpc import objectclasses
|
||||||
|
from xmlrpc_test import Declarative, fuzzy_digits
|
||||||
|
|
||||||
|
|
||||||
|
cn = u'Realm Domains'
|
||||||
|
dn = DN(('cn', cn), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||||
|
our_domain = api.env.domain
|
||||||
|
dnszone_1 = u'dnszone.test'
|
||||||
|
dnszone_1_dn = DN(('idnsname', dnszone_1), api.env.container_dns,
|
||||||
|
api.env.basedn)
|
||||||
|
idnssoamname = u'ns1.%s.' % dnszone_1
|
||||||
|
idnssoarname = u'root.%s.' % dnszone_1
|
||||||
|
dnszone_2 = u'dnszone2.test'
|
||||||
|
dnszone_2_dn = DN(('idnsname', dnszone_2), api.env.container_dns,
|
||||||
|
api.env.basedn)
|
||||||
|
|
||||||
|
|
||||||
|
def assert_realmdomain_and_txt_record_present(response):
|
||||||
|
zone = response['value']
|
||||||
|
|
||||||
|
r = api.Command['realmdomains_show']()
|
||||||
|
assert zone in r['result']['associateddomain']
|
||||||
|
|
||||||
|
r = api.Command['dnsrecord_show'](zone, u'_kerberos')
|
||||||
|
assert api.env.realm in r['result']['txtrecord']
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def assert_realmdomain_and_txt_record_not_present(response):
|
||||||
|
zone = response['value']
|
||||||
|
|
||||||
|
r = api.Command['realmdomains_show']()
|
||||||
|
assert zone not in r['result']['associateddomain']
|
||||||
|
|
||||||
|
try:
|
||||||
|
api.Command['dnsrecord_show'](zone, u'_kerberos')
|
||||||
|
except errors.NotFound:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class test_dns_realmdomains_integration(Declarative):
|
||||||
|
cleanup_commands = [
|
||||||
|
('realmdomains_mod', [], {'associateddomain': [our_domain]}),
|
||||||
|
('dnszone_del', [dnszone_1, dnszone_2], {'continue': True}),
|
||||||
|
]
|
||||||
|
|
||||||
|
tests = [
|
||||||
|
dict(
|
||||||
|
desc='Check realmdomain and TXT record get created '
|
||||||
|
'during dnszone_add',
|
||||||
|
command=(
|
||||||
|
'dnszone_add', [dnszone_1], {
|
||||||
|
'idnssoamname': idnssoamname,
|
||||||
|
'idnssoarname': idnssoarname,
|
||||||
|
'ip_address': u'1.2.3.4',
|
||||||
|
}
|
||||||
|
),
|
||||||
|
expected={
|
||||||
|
'value': dnszone_1,
|
||||||
|
'summary': None,
|
||||||
|
'result': {
|
||||||
|
'dn': dnszone_1_dn,
|
||||||
|
'idnsname': [dnszone_1],
|
||||||
|
'idnszoneactive': [u'TRUE'],
|
||||||
|
'idnssoamname': [idnssoamname],
|
||||||
|
'nsrecord': [idnssoamname],
|
||||||
|
'idnssoarname': [idnssoarname],
|
||||||
|
'idnssoaserial': [fuzzy_digits],
|
||||||
|
'idnssoarefresh': [fuzzy_digits],
|
||||||
|
'idnssoaretry': [fuzzy_digits],
|
||||||
|
'idnssoaexpire': [fuzzy_digits],
|
||||||
|
'idnssoaminimum': [fuzzy_digits],
|
||||||
|
'idnsallowdynupdate': [u'FALSE'],
|
||||||
|
'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; '
|
||||||
|
u'grant %(realm)s krb5-self * AAAA; '
|
||||||
|
u'grant %(realm)s krb5-self * SSHFP;'
|
||||||
|
% dict(realm=api.env.realm)],
|
||||||
|
'idnsallowtransfer': [u'none;'],
|
||||||
|
'idnsallowquery': [u'any;'],
|
||||||
|
'objectclass': objectclasses.dnszone,
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extra_check=assert_realmdomain_and_txt_record_present,
|
||||||
|
),
|
||||||
|
|
||||||
|
dict(
|
||||||
|
desc='Check realmdomain and TXT record do not get created '
|
||||||
|
'during dnszone_add for forwarded zone',
|
||||||
|
command=(
|
||||||
|
'dnszone_add', [dnszone_2], {
|
||||||
|
'idnssoamname': idnssoamname,
|
||||||
|
'idnssoarname': idnssoarname,
|
||||||
|
'idnsforwarders': u'1.2.3.4',
|
||||||
|
'idnsforwardpolicy': u'only',
|
||||||
|
'force': True,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
expected={
|
||||||
|
'value': dnszone_2,
|
||||||
|
'summary': None,
|
||||||
|
'result': {
|
||||||
|
'dn': dnszone_2_dn,
|
||||||
|
'idnsname': [dnszone_2],
|
||||||
|
'idnszoneactive': [u'TRUE'],
|
||||||
|
'idnssoamname': [idnssoamname],
|
||||||
|
'idnsforwarders': [u'1.2.3.4'],
|
||||||
|
'idnsforwardpolicy': [u'only'],
|
||||||
|
'nsrecord': [idnssoamname],
|
||||||
|
'idnssoarname': [idnssoarname],
|
||||||
|
'idnssoaserial': [fuzzy_digits],
|
||||||
|
'idnssoarefresh': [fuzzy_digits],
|
||||||
|
'idnssoaretry': [fuzzy_digits],
|
||||||
|
'idnssoaexpire': [fuzzy_digits],
|
||||||
|
'idnssoaminimum': [fuzzy_digits],
|
||||||
|
'idnsallowdynupdate': [u'FALSE'],
|
||||||
|
'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; '
|
||||||
|
u'grant %(realm)s krb5-self * AAAA; '
|
||||||
|
u'grant %(realm)s krb5-self * SSHFP;'
|
||||||
|
% dict(realm=api.env.realm)],
|
||||||
|
'idnsallowtransfer': [u'none;'],
|
||||||
|
'idnsallowquery': [u'any;'],
|
||||||
|
'objectclass': objectclasses.dnszone,
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extra_check=assert_realmdomain_and_txt_record_not_present,
|
||||||
|
),
|
||||||
|
|
||||||
|
dict(
|
||||||
|
desc='Check realmdomain and TXT record get deleted '
|
||||||
|
'during dnszone_del',
|
||||||
|
command=('dnszone_del', [dnszone_1], {}),
|
||||||
|
expected={
|
||||||
|
'value': dnszone_1,
|
||||||
|
'summary': u'Deleted DNS zone "%s"' % dnszone_1,
|
||||||
|
'result': {'failed': u''},
|
||||||
|
},
|
||||||
|
extra_check=assert_realmdomain_and_txt_record_not_present,
|
||||||
|
),
|
||||||
|
]
|
Loading…
Reference in New Issue
Block a user