From c60142efda817f030a7495cd6fe4a19953e55afa Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 21 May 2013 13:40:27 +0200 Subject: Make an ipa-tests package Rename the 'tests' directory to 'ipa-tests', and create an ipa-tests RPM containing the test suite Part of the work for: https://fedorahosted.org/freeipa/ticket/3654 --- ipatests/test_xmlrpc/test_dns_plugin.py | 1511 +++++++++++++++++++++++++++++++ 1 file changed, 1511 insertions(+) create mode 100644 ipatests/test_xmlrpc/test_dns_plugin.py (limited to 'ipatests/test_xmlrpc/test_dns_plugin.py') diff --git a/ipatests/test_xmlrpc/test_dns_plugin.py b/ipatests/test_xmlrpc/test_dns_plugin.py new file mode 100644 index 000000000..ea9b70e36 --- /dev/null +++ b/ipatests/test_xmlrpc/test_dns_plugin.py @@ -0,0 +1,1511 @@ +# Authors: +# Pavel Zuna +# +# Copyright (C) 2010 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 . +""" +Test the `ipalib/plugins/dns.py` module. +""" + +import nose +from ipalib import api, errors +from ipapython.dn import DN +from ipatests.test_xmlrpc import objectclasses +from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid + +dnszone1 = u'dnszone.test' +dnszone1_dn = DN(('idnsname',dnszone1), api.env.container_dns, api.env.basedn) +dnszone1_mname = u'ns1.%s.' % dnszone1 +dnszone1_mname_dn = DN(('idnsname','ns1'), dnszone1_dn) +dnszone1_rname = u'root.%s.' % dnszone1 +dnszone1_permission = u'Manage DNS zone %s' % dnszone1 +dnszone1_permission_dn = DN(('cn',dnszone1_permission), + api.env.container_permission,api.env.basedn) +dnszone1_txtrec_dn = DN(('idnsname', '_kerberos'), dnszone1_dn) +dnszone2 = u'dnszone2.test' +dnszone2_dn = DN(('idnsname', dnszone2), api.env.container_dns, api.env.basedn) +dnszone2_mname = u'ns1.%s.' % dnszone2 +dnszone2_rname = u'root.%s.' % dnszone2 +revdnszone1 = u'15.142.80.in-addr.arpa.' +revdnszone1_ip = u'80.142.15.0/24' +revdnszone1_dn = DN(('idnsname', revdnszone1), api.env.container_dns, api.env.basedn) +revdnszone2 = u'16.142.80.in-addr.arpa.' +revdnszone2_ip = u'80.142.16.0' +revdnszone2_dn = DN(('idnsname',revdnszone2), api.env.container_dns, api.env.basedn) +dnsres1 = u'testdnsres' +dnsres1_dn = DN(('idnsname',dnsres1), dnszone1_dn) +dnsres1_renamed = u'testdnsres-renamed' +dnsrev1 = u'80' +dnsrev1_dn = DN(('idnsname',dnsrev1), revdnszone1_dn) +dnsrev2 = u'81' +dnsrev2_dn = DN(('idnsname',dnsrev2), revdnszone1_dn) +dnsrescname = u'testcnamerec' +dnsrescname_dn = DN(('idnsname',dnsrescname), dnszone1_dn) +dnsresdname = u'testdns-dname' +dnsresdname_dn = DN(('idnsname',dnsresdname), dnszone1_dn) + +class test_dns(Declarative): + + @classmethod + def setUpClass(cls): + super(test_dns, cls).setUpClass() + + if not api.Backend.xmlclient.isconnected(): + api.Backend.xmlclient.connect(fallback=False) + try: + api.Command['dnszone_add'](dnszone1, + idnssoamname = dnszone1_mname, + idnssoarname = dnszone1_rname, + force = True, + ) + api.Command['dnszone_del'](dnszone1) + except errors.NotFound: + raise nose.SkipTest('DNS is not configured') + except errors.DuplicateEntry: + pass + + cleanup_commands = [ + ('dnszone_del', [dnszone1, dnszone2, revdnszone1, revdnszone2], + {'continue': True}), + ('dnsconfig_mod', [], {'idnsforwarders' : None, + 'idnsforwardpolicy' : None, + 'idnsallowsyncptr' : None, + 'idnszonerefresh' : None, + }), + ('permission_del', [dnszone1_permission], {'force': True}), + ] + + tests = [ + + dict( + desc='Try to retrieve non-existent zone %r' % dnszone1, + command=('dnszone_show', [dnszone1], {}), + expected=errors.NotFound( + reason=u'%s: DNS zone not found' % dnszone1), + ), + + + dict( + desc='Try to update non-existent zone %r' % dnszone1, + command=('dnszone_mod', [dnszone1], {'idnssoaminimum': 3500}), + expected=errors.NotFound( + reason=u'%s: DNS zone not found' % dnszone1), + ), + + + dict( + desc='Try to delete non-existent zone %r' % dnszone1, + command=('dnszone_del', [dnszone1], {}), + expected=errors.NotFound( + reason=u'%s: DNS zone not found' % dnszone1), + ), + + + dict( + desc='Try to create zone with invalid name', + command=( + 'dnszone_add', [u'invalid zone'], { + 'idnssoamname': dnszone1_mname, + 'idnssoarname': dnszone1_rname, + 'ip_address' : u'1.2.3.4', + } + ), + expected=errors.ValidationError(name='name', + error=u'only letters, numbers, and - are allowed. ' + + u'DNS label may not start or end with -'), + ), + + + dict( + desc='Create zone %r' % dnszone1, + command=( + 'dnszone_add', [dnszone1], { + 'idnssoamname': dnszone1_mname, + 'idnssoarname': dnszone1_rname, + 'ip_address' : u'1.2.3.4', + } + ), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'dn': dnszone1_dn, + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'idnssoamname': [dnszone1_mname], + 'nsrecord': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + '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, + }, + }, + ), + + + dict( + desc='Try to create duplicate zone %r' % dnszone1, + command=( + 'dnszone_add', [dnszone1], { + 'idnssoamname': dnszone1_mname, + 'idnssoarname': dnszone1_rname, + 'ip_address' : u'1.2.3.4', + } + ), + expected=errors.DuplicateEntry( + message=u'DNS zone with name "%s" already exists' % dnszone1), + ), + + dict( + desc='Try to create a zone with nonexistent NS entry', + command=( + 'dnszone_add', [dnszone2], { + 'idnssoamname': dnszone2_mname, + 'idnssoarname': dnszone2_rname, + } + ), + expected=errors.NotFound(reason='Nameserver \'%s\' does not have a corresponding A/AAAA record' % (dnszone2_mname)), + ), + + dict( + desc='Create a zone with nonexistent NS entry with --force', + command=( + 'dnszone_add', [dnszone2], { + 'idnssoamname': dnszone2_mname, + 'idnssoarname': dnszone2_rname, + 'force' : True, + } + ), + expected={ + 'value': dnszone2, + 'summary': None, + 'result': { + 'dn': dnszone2_dn, + 'idnsname': [dnszone2], + 'idnszoneactive': [u'TRUE'], + 'idnssoamname': [dnszone2_mname], + 'nsrecord': [dnszone2_mname], + 'idnssoarname': [dnszone2_rname], + '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, + }, + }, + ), + + + dict( + desc='Retrieve zone %r' % dnszone1, + command=('dnszone_show', [dnszone1], {}), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'dn': dnszone1_dn, + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [fuzzy_digits], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + }, + }, + ), + + + dict( + desc='Update zone %r' % dnszone1, + command=('dnszone_mod', [dnszone1], {'idnssoarefresh': 5478}), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [u'5478'], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + }, + }, + ), + + + dict( + desc='Try to create reverse zone %r with NS record in it' % revdnszone1, + command=( + 'dnszone_add', [revdnszone1], { + 'idnssoamname': u'ns', + 'idnssoarname': dnszone1_rname, + } + ), + expected=errors.ValidationError(name='name-server', + error=u"Nameserver for reverse zone cannot be a relative DNS name"), + ), + + + dict( + desc='Create reverse zone %r' % revdnszone1, + command=( + 'dnszone_add', [revdnszone1], { + 'idnssoamname': dnszone1_mname, + 'idnssoarname': dnszone1_rname, + } + ), + expected={ + 'value': revdnszone1, + 'summary': None, + 'result': { + 'dn': revdnszone1_dn, + 'idnsname': [revdnszone1], + 'idnszoneactive': [u'TRUE'], + 'idnssoamname': [dnszone1_mname], + 'nsrecord': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [fuzzy_digits], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowdynupdate': [u'FALSE'], + 'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;' + % dict(realm=api.env.realm, zone=revdnszone1)], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + 'objectclass': objectclasses.dnszone, + }, + }, + ), + + + dict( + desc='Search for zones with name server %r' % (dnszone1_mname), + command=('dnszone_find', [], {'idnssoamname': dnszone1_mname}), + expected={ + 'summary': None, + 'count': 2, + 'truncated': False, + 'result': [{ + 'dn': revdnszone1_dn, + 'idnsname': [revdnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [fuzzy_digits], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + }, + { + 'dn': dnszone1_dn, + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [u'5478'], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + }], + }, + ), + + + dict( + desc='Search for zones with name server %r with --forward-only' % dnszone1_mname, + command=('dnszone_find', [], {'idnssoamname': dnszone1_mname, 'forward_only' : True}), + expected={ + 'summary': None, + 'count': 1, + 'truncated': False, + 'result': [{ + 'dn': dnszone1_dn, + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [u'5478'], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + }], + }, + ), + + + dict( + desc='Delete reverse zone %r' % revdnszone1, + command=('dnszone_del', [revdnszone1], {}), + expected={ + 'value': revdnszone1, + 'summary': u'Deleted DNS zone "%s"' % revdnszone1, + 'result': {'failed': u''}, + }, + ), + + + dict( + desc='Disable zone %r' % dnszone1, + command=('dnszone_disable', [dnszone1], {}), + expected={ + 'value': dnszone1, + 'summary': u'Disabled DNS zone "%s"' % dnszone1, + 'result': True, + }, + ), + + + dict( + desc='Check if zone %r is really disabled' % dnszone1, + command=('dnszone_show', [dnszone1], {}), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'dn': dnszone1_dn, + 'idnsname': [dnszone1], + 'idnszoneactive': [u'FALSE'], + 'nsrecord': [dnszone1_mname], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [fuzzy_digits], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + }, + }, + ), + + + dict( + desc='Enable zone %r' % dnszone1, + command=('dnszone_enable', [dnszone1], {}), + expected={ + 'value': dnszone1, + 'summary': u'Enabled DNS zone "%s"' % dnszone1, + 'result': True, + }, + ), + + + dict( + desc='Check if zone %r is really enabled' % dnszone1, + command=('dnszone_show', [dnszone1], {}), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'dn': dnszone1_dn, + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [fuzzy_digits], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + }, + }, + ), + + + dict( + desc='Try to retrieve non-existent record %r in zone %r' % (dnsres1, dnszone1), + command=('dnsrecord_show', [dnszone1, dnsres1], {}), + expected=errors.NotFound( + reason=u'%s: DNS resource record not found' % dnsres1), + ), + + + dict( + desc='Try to delete non-existent record %r in zone %r' % (dnsres1, dnszone1), + command=('dnsrecord_del', [dnszone1, dnsres1], {'del_all' : True}), + expected=errors.NotFound( + reason=u'%s: DNS resource record not found' % dnsres1), + ), + + + dict( + desc='Try to delete root zone record \'@\' in %r' % (dnszone1), + command=('dnsrecord_del', [dnszone1, u'@'], {'del_all' : True}), + expected=errors.ValidationError(name='del_all', + error=u"Zone record '@' cannot be deleted"), + ), + + + dict( + desc='Try to create record with invalid name in zone %r' % dnszone1, + command=('dnsrecord_add', [dnszone1, u'invalid record'], {'arecord': u'127.0.0.1'}), + expected=errors.ValidationError(name='name', + error=u'only letters, numbers, _, and - are allowed. ' + + u'DNS label may not start or end with -'), + ), + + + dict( + desc='Create record %r in zone %r' % (dnszone1, dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'arecord': u'127.0.0.1'}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'dn': dnsres1_dn, + 'idnsname': [dnsres1], + 'objectclass': objectclasses.dnsrecord, + 'arecord': [u'127.0.0.1'], + }, + }, + ), + + + dict( + desc='Search for all records in zone %r' % dnszone1, + command=('dnsrecord_find', [dnszone1], {}), + expected={ + 'summary': None, + 'count': 4, + 'truncated': False, + 'result': [ + { + 'dn': dnszone1_dn, + 'nsrecord': (dnszone1_mname,), + 'idnsname': [u'@'], + }, + { + 'dn': dnszone1_txtrec_dn, + 'txtrecord': [api.env.realm], + 'idnsname': [u'_kerberos'], + }, + { + 'dn': dnszone1_mname_dn, + 'idnsname': [u'ns1'], + 'arecord': [u'1.2.3.4'], + }, + { + 'dn': dnsres1_dn, + 'idnsname': [dnsres1], + 'arecord': [u'127.0.0.1'], + }, + ], + }, + ), + + + dict( + desc='Add A record to %r in zone %r' % (dnsres1, dnszone1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'arecord': u'10.10.0.1'}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'dn': dnsres1_dn, + 'idnsname': [dnsres1], + 'arecord': [u'127.0.0.1', u'10.10.0.1'], + 'objectclass': objectclasses.dnsrecord, + }, + }, + ), + + + dict( + desc='Remove A record from %r in zone %r' % (dnsres1, dnszone1), + command=('dnsrecord_del', [dnszone1, dnsres1], {'arecord': u'127.0.0.1'}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'idnsname': [dnsres1], + 'arecord': [u'10.10.0.1'], + }, + }, + ), + + + dict( + desc='Add AAAA record to %r in zone %r using dnsrecord_mod' % (dnsres1, dnszone1), + command=('dnsrecord_mod', [dnszone1, dnsres1], {'aaaarecord': u'::1'}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'idnsname': [dnsres1], + 'arecord': [u'10.10.0.1'], + 'aaaarecord': [u'::1'], + }, + }, + ), + + + dict( + desc='Try to modify nonexistent record in zone %r' % dnszone1, + command=('dnsrecord_mod', + [dnszone1, u'ghostname'], + {'aaaarecord': u'f001:baad::1'}), + expected=errors.NotFound( + reason=u'ghostname: DNS resource record not found'), + ), + + + dict( + desc='Modify AAAA record in %r in zone %r' % (dnsres1, dnszone1), + command=('dnsrecord_mod', [dnszone1, dnsres1], {'aaaarecord': u'ff02::1'}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'idnsname': [dnsres1], + 'arecord': [u'10.10.0.1'], + 'aaaarecord': [u'ff02::1'], + }, + }, + ), + + + dict( + desc='Remove AAAA record from %r in zone %r using dnsrecord_mod' % (dnsres1, dnszone1), + command=('dnsrecord_mod', [dnszone1, dnsres1], {'aaaarecord': u''}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'idnsname': [dnsres1], + 'arecord': [u'10.10.0.1'], + }, + }, + ), + + dict( + desc='Try to add invalid MX record to zone %r using dnsrecord_add' % (dnszone1), + command=('dnsrecord_add', [dnszone1, u'@'], {'mxrecord': dnszone1_mname }), + expected=errors.ValidationError(name='mx_rec', + error=u'format must be specified as "PREFERENCE EXCHANGER" ' + + u' (see RFC 1035 for details)'), + ), + + dict( + desc='Add MX record to zone %r using dnsrecord_add' % (dnszone1), + command=('dnsrecord_add', [dnszone1, u'@'], {'mxrecord': u"0 %s" % dnszone1_mname }), + expected={ + 'value': u'@', + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnszone, + 'dn': dnszone1_dn, + 'idnsname': [u'@'], + 'mxrecord': [u"0 %s" % dnszone1_mname], + 'nsrecord': [dnszone1_mname], + }, + }, + ), + + dict( + desc='Try to add invalid SRV record to zone %r using dnsrecord_add' % (dnszone1), + command=('dnsrecord_add', [dnszone1, u'_foo._tcp'], {'srvrecord': dnszone1_mname}), + expected=errors.ValidationError(name='srv_rec', + error=u'format must be specified as "PRIORITY WEIGHT PORT TARGET" ' + + u' (see RFC 2782 for details)'), + ), + + dict( + desc='Try to add invalid SRV record via parts to zone %r using dnsrecord_add' % (dnszone1), + command=('dnsrecord_add', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 0, + 'srv_part_weight' : 0, + 'srv_part_port' : 123, + 'srv_part_target' : u'foo bar'}), + expected=errors.ValidationError(name='srv_target', + error=u'invalid domain-name: only letters, numbers, _, and - ' + + u'are allowed. DNS label may not start or end with -'), + ), + + dict( + desc='Try to add SRV record to zone %r both via parts and a raw value' % (dnszone1), + command=('dnsrecord_add', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 0, + 'srv_part_weight' : 0, + 'srv_part_port' : 123, + 'srv_part_target' : u'foo.bar.', + 'srvrecord': [u"1 100 1234 %s" \ + % dnszone1_mname]}), + expected=errors.ValidationError(name='srv_target', + error=u'Raw value of a DNS record was already set by ' + + u'"srv_rec" option'), + ), + + dict( + desc='Add SRV record to zone %r using dnsrecord_add' % (dnszone1), + command=('dnsrecord_add', [dnszone1, u'_foo._tcp'], {'srvrecord': u"0 100 1234 %s" % dnszone1_mname}), + expected={ + 'value': u'_foo._tcp', + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnsrecord, + 'dn': DN(('idnsname', u'_foo._tcp'), dnszone1_dn), + 'idnsname': [u'_foo._tcp'], + 'srvrecord': [u"0 100 1234 %s" % dnszone1_mname], + }, + }, + ), + + dict( + desc='Try to modify SRV record in zone %r without specifying modified value' % (dnszone1), + command=('dnsrecord_mod', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 1,}), + expected=errors.RequirementError(name='srvrecord'), + ), + + dict( + desc='Try to modify SRV record in zone %r with non-existent modified value' % (dnszone1), + command=('dnsrecord_mod', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 1, + 'srvrecord' : [u"0 100 1234 does.not.exist."] }), + expected=errors.AttrValueNotFound(attr='SRV record', + value=u'0 100 1234 does.not.exist.'), + ), + + dict( + desc='Try to modify SRV record in zone %r with invalid part value' % (dnszone1), + command=('dnsrecord_mod', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 100000, + 'srvrecord' : [u"0 100 1234 %s" % dnszone1_mname] }), + expected=errors.ValidationError(name='srv_priority', error=u'can be at most 65535'), + ), + + dict( + desc='Modify SRV record in zone %r using parts' % (dnszone1), + command=('dnsrecord_mod', [dnszone1, u'_foo._tcp'], {'srv_part_priority': 1, + 'srvrecord' : [u"0 100 1234 %s" % dnszone1_mname] }), + expected={ + 'value': u'_foo._tcp', + 'summary': None, + 'result': { + 'idnsname': [u'_foo._tcp'], + 'srvrecord': [u"1 100 1234 %s" % dnszone1_mname], + }, + }, + ), + + dict( + desc='Try to add invalid LOC record to zone %r using dnsrecord_add' % (dnszone1), + command=('dnsrecord_add', [dnszone1, u'@'], {'locrecord': u"91 11 42.4 N 16 36 29.6 E 227.64" }), + expected=errors.ValidationError(name='lat_deg', + error=u'can be at most 90'), + ), + + dict( + desc='Add LOC record to zone %r using dnsrecord_add' % (dnszone1), + command=('dnsrecord_add', [dnszone1, u'@'], {'locrecord': u"49 11 42.4 N 16 36 29.6 E 227.64" }), + expected={ + 'value': u'@', + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnszone, + 'dn': dnszone1_dn, + 'idnsname': [u'@'], + 'mxrecord': [u"0 %s" % dnszone1_mname], + 'nsrecord': [dnszone1_mname], + 'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"], + }, + }, + ), + + dict( + desc='Try to add CNAME record to %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'cnamerecord': u'foo-1.example.com.'}), + expected=errors.ValidationError(name='cnamerecord', + error=u'CNAME record is not allowed to coexist with any other ' + u'record (RFC 1034, section 3.6.2)'), + ), + + dict( + desc='Try to add invalid CNAME record %r using dnsrecord_add' % (dnsrescname), + command=('dnsrecord_add', [dnszone1, dnsrescname], {'cnamerecord': u'-.example.com'}), + expected=errors.ValidationError(name='hostname', + error=u'invalid domain-name: only letters, numbers, _, and - ' + + u'are allowed. DNS label may not start or end with -'), + ), + + dict( + desc='Try to add multiple CNAME record %r using dnsrecord_add' % (dnsrescname), + command=('dnsrecord_add', [dnszone1, dnsrescname], {'cnamerecord': + [u'1.example.com.', u'2.example.com.']}), + expected=errors.ValidationError(name='cnamerecord', + error=u'only one CNAME record is allowed per name (RFC 2136, section 1.1.5)'), + ), + + dict( + desc='Add CNAME record to %r using dnsrecord_add' % (dnsrescname), + command=('dnsrecord_add', [dnszone1, dnsrescname], {'cnamerecord': u'foo-1.example.com.'}), + expected={ + 'value': dnsrescname, + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnsrecord, + 'dn': dnsrescname_dn, + 'idnsname': [dnsrescname], + 'cnamerecord': [u'foo-1.example.com.'], + }, + }, + ), + + dict( + desc='Try to add other record to CNAME record %r using dnsrecord_add' % (dnsrescname), + command=('dnsrecord_add', [dnszone1, dnsrescname], {'arecord': u'10.0.0.1'}), + expected=errors.ValidationError(name='cnamerecord', + error=u'CNAME record is not allowed to coexist with any other ' + u'record (RFC 1034, section 3.6.2)'), + ), + + dict( + desc='Try to add other record to CNAME record %r using dnsrecord_mod' % (dnsrescname), + command=('dnsrecord_mod', [dnszone1, dnsrescname], {'arecord': u'10.0.0.1'}), + expected=errors.ValidationError(name='cnamerecord', + error=u'CNAME record is not allowed to coexist with any other ' + u'record (RFC 1034, section 3.6.2)'), + ), + + dict( + desc='Add A record and delete CNAME record in %r with dnsrecord_mod' % (dnsrescname), + command=('dnsrecord_mod', [dnszone1, dnsrescname], {'arecord': u'10.0.0.1', + 'cnamerecord': None}), + expected={ + 'value': dnsrescname, + 'summary': None, + 'result': { + 'idnsname': [dnsrescname], + 'arecord': [u'10.0.0.1'], + }, + }, + ), + + dict( + desc='Try to add multiple DNAME records to %r using dnsrecord_add' % (dnsresdname), + command=('dnsrecord_add', [dnszone1, dnsres1], {'dnamerecord': + [u'foo-1.example.com.', u'foo-2.example.com.']}), + expected=errors.ValidationError(name='dnamerecord', + error=u'only one DNAME record is allowed per name (RFC 6672, section 2.4)'), + ), + + dict( + desc='Try to add invalid DNAME record %r using dnsrecord_add' % (dnsresdname), + command=('dnsrecord_add', [dnszone1, dnsresdname], {'dnamerecord': u'-.example.com.'}), + expected=errors.ValidationError(name='target', + error=u'invalid domain-name: only letters, numbers, _, and - ' + + u'are allowed. DNS label may not start or end with -'), + ), + + dict( + desc='Add DNAME record to %r using dnsrecord_add' % (dnsresdname), + command=('dnsrecord_add', [dnszone1, dnsresdname], + {'dnamerecord': u'd.example.com.', 'arecord': u'10.0.0.1'}), + expected={ + 'value': dnsresdname, + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnsrecord, + 'dn': dnsresdname_dn, + 'idnsname': [dnsresdname], + 'dnamerecord': [u'd.example.com.'], + 'arecord': [u'10.0.0.1'], + }, + }, + ), + + dict( + desc='Try to add CNAME record to %r using dnsrecord_add' % (dnsresdname), + command=('dnsrecord_add', [dnszone1, dnsresdname], {'cnamerecord': u'foo-1.example.com.'}), + expected=errors.ValidationError(name='cnamerecord', + error=u'CNAME record is not allowed to coexist with any other ' + u'record (RFC 1034, section 3.6.2)'), + ), + + dict( + desc='Try to add NS record to %r using dnsrecord_add' % (dnsresdname), + command=('dnsrecord_add', [dnszone1, dnsresdname], + {'nsrecord': u'%s.%s.' % (dnsres1, dnszone1)}), + expected=errors.ValidationError(name='dnamerecord', + error=u'DNAME record is not allowed to coexist with an NS ' + u'record except when located in a zone root record (RFC 6672, section 2.3)'), + ), + + dict( + desc='Add NS+DNAME record to %r zone record using dnsrecord_add' % (dnszone2), + command=('dnsrecord_add', [dnszone2, u'@'], + {'dnamerecord': u'd.example.com.', + 'nsrecord': dnszone1_mname}), + expected = { + 'value': u'@', + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnszone, + 'dnamerecord': [u'd.example.com.'], + 'dn': dnszone2_dn, + 'nsrecord': [dnszone2_mname, dnszone1_mname], + 'idnsname': [u'@'] + } + }, + ), + + + dict( + desc='Delete zone %r' % dnszone2, + command=('dnszone_del', [dnszone2], {}), + expected={ + 'value': dnszone2, + 'summary': u'Deleted DNS zone "%s"' % dnszone2, + 'result': {'failed': u''}, + }, + ), + + dict( + desc='Try to add invalid KX record %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'kxrecord': u'foo-1.example.com' }), + expected=errors.ValidationError(name='kx_rec', + error=u'format must be specified as "PREFERENCE EXCHANGER" ' + + u' (see RFC 2230 for details)'), + ), + + dict( + desc='Add KX record to %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'kxrecord': u'1 foo-1' }), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnsrecord, + 'dn': dnsres1_dn, + 'idnsname': [dnsres1], + 'arecord': [u'10.10.0.1'], + 'kxrecord': [u'1 foo-1'], + }, + }, + ), + + dict( + desc='Add TXT record to %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'txtrecord': u'foo bar' }), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnsrecord, + 'dn': dnsres1_dn, + 'idnsname': [dnsres1], + 'arecord': [u'10.10.0.1'], + 'kxrecord': [u'1 foo-1'], + 'txtrecord': [u'foo bar'], + }, + }, + ), + + dict( + desc='Add NSEC record to %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], { + 'nsec_part_next': dnszone1, + 'nsec_part_types' : [u'TXT', u'A']}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnsrecord, + 'dn': dnsres1_dn, + 'idnsname': [dnsres1], + 'arecord': [u'10.10.0.1'], + 'kxrecord': [u'1 foo-1'], + 'txtrecord': [u'foo bar'], + 'nsecrecord': [dnszone1 + u' TXT A'], + }, + }, + ), + + dict( + desc='Try to add unresolvable absolute NS record to %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist.'}), + expected=errors.NotFound(reason=u"Nameserver 'does.not.exist.' does not have a corresponding A/AAAA record"), + ), + + dict( + desc='Try to add unresolvable relative NS record to %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist'}), + expected=errors.NotFound(reason=u"Nameserver 'does.not.exist.%s.' does not have a corresponding A/AAAA record" % dnszone1), + ), + + dict( + desc='Add unresolvable NS record with --force to %r using dnsrecord_add' % (dnsres1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'nsrecord': u'does.not.exist.', + 'force' : True}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnsrecord, + 'dn': dnsres1_dn, + 'idnsname': [dnsres1], + 'arecord': [u'10.10.0.1'], + 'kxrecord': [u'1 foo-1'], + 'txtrecord': [u'foo bar'], + 'nsecrecord': [dnszone1 + u' TXT A'], + 'nsrecord': [u'does.not.exist.'], + }, + }, + ), + + dict( + desc='Try to to rename DNS zone %r root record' % (dnszone1), + command=('dnsrecord_mod', [dnszone1, u'@'], {'rename': dnsres1_renamed,}), + expected=errors.ValidationError(name='rename', + error=u'DNS zone root record cannot be renamed') + ), + + dict( + desc='Rename DNS record %r to %r' % (dnsres1, dnsres1_renamed), + command=('dnsrecord_mod', [dnszone1, dnsres1], {'rename': dnsres1_renamed,}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'idnsname': [dnsres1_renamed], + 'arecord': [u'10.10.0.1'], + 'kxrecord': [u'1 foo-1'], + 'txtrecord': [u'foo bar'], + 'nsecrecord': [dnszone1 + u' TXT A'], + 'nsrecord': [u'does.not.exist.'], + }, + }, + ), + + + dict( + desc='Delete record %r in zone %r' % (dnsres1_renamed, dnszone1), + command=('dnsrecord_del', [dnszone1, dnsres1_renamed], {'del_all': True }), + expected={ + 'value': dnsres1_renamed, + 'summary': u'Deleted record "%s"' % dnsres1_renamed, + 'result': {'failed': u''}, + }, + ), + + + dict( + desc='Try to create a reverse zone from invalid IP', + command=( + 'dnszone_add', [], { + 'name_from_ip': u'foo', + 'idnssoamname': dnszone1_mname, + 'idnssoarname': dnszone1_rname, + } + ), + expected=errors.ValidationError(name='name_from_ip', + error=u'invalid IP network format'), + ), + + dict( + desc='Create reverse zone from IP/netmask %r using name_from_ip option' % revdnszone1_ip, + command=( + 'dnszone_add', [], { + 'name_from_ip': revdnszone1_ip, + 'idnssoamname': dnszone1_mname, + 'idnssoarname': dnszone1_rname, + } + ), + expected={ + 'value': revdnszone1, + 'summary': None, + 'result': { + 'dn': revdnszone1_dn, + 'idnsname': [revdnszone1], + 'idnszoneactive': [u'TRUE'], + 'idnssoamname': [dnszone1_mname], + 'nsrecord': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [fuzzy_digits], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowdynupdate': [u'FALSE'], + 'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;' + % dict(realm=api.env.realm, zone=revdnszone1)], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + 'objectclass': objectclasses.dnszone, + }, + }, + ), + + + dict( + desc='Create reverse zone from IP %r using name_from_ip option' % revdnszone2_ip, + command=( + 'dnszone_add', [], { + 'name_from_ip': revdnszone2_ip, + 'idnssoamname': dnszone1_mname, + 'idnssoarname': dnszone1_rname, + } + ), + expected={ + 'value': revdnszone2, + 'summary': None, + 'result': { + 'dn': revdnszone2_dn, + 'idnsname': [revdnszone2], + 'idnszoneactive': [u'TRUE'], + 'idnssoamname': [dnszone1_mname], + 'nsrecord': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [fuzzy_digits], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowdynupdate': [u'FALSE'], + 'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;' + % dict(realm=api.env.realm, zone=revdnszone2)], + 'idnsallowtransfer': [u'none;'], + 'idnsallowquery': [u'any;'], + 'objectclass': objectclasses.dnszone, + }, + }, + ), + + + dict( + desc='Try to add invalid PTR %r to %r using dnsrecord_add' % (dnsrev1, revdnszone1), + command=('dnsrecord_add', [revdnszone1, dnsrev1], {'ptrrecord': u'-.example.com' }), + expected=errors.ValidationError(name='hostname', + error=u'invalid domain-name: only letters, numbers, and - ' + + u'are allowed. DNS label may not start or end with -'), + ), + + dict( + desc='Add PTR record %r to %r using dnsrecord_add' % (dnsrev1, revdnszone1), + command=('dnsrecord_add', [revdnszone1, dnsrev1], {'ptrrecord': u'foo-1.example.com' }), + expected={ + 'value': dnsrev1, + 'summary': None, + 'result': { + 'objectclass': objectclasses.dnsrecord, + 'dn': dnsrev1_dn, + 'idnsname': [dnsrev1], + 'ptrrecord': [u'foo-1.example.com.'], + }, + }, + ), + + dict( + desc='Show record %r in zone %r with --structured and --all options'\ + % (dnsrev1, revdnszone1), + command=('dnsrecord_show', [revdnszone1, dnsrev1], + {'structured': True, 'all': True}), + expected={ + 'value': dnsrev1, + 'summary': None, + 'result': { + 'dn': dnsrev1_dn, + 'idnsname': [dnsrev1], + 'objectclass': objectclasses.dnsrecord, + 'dnsrecords': [ + { + 'dnstype': u'PTR', + 'dnsdata': u'foo-1.example.com.', + 'ptr_part_hostname': u'foo-1.example.com.' + }, + ], + }, + }, + ), + + dict( + desc='Update global DNS settings', + command=('dnsconfig_mod', [], {'idnsforwarders' : [u'80.142.15.80'],}), + expected={ + 'value': u'', + 'summary': None, + 'result': { + 'idnsforwarders': [u'80.142.15.80'], + }, + }, + ), + + + dict( + desc='Try to add invalid allow-query to zone %r' % dnszone1, + command=('dnszone_mod', [dnszone1], {'idnsallowquery': u'foo'}), + expected=errors.ValidationError(name='allow_query', + error=u"failed to detect a valid IP address from 'foo'"), + ), + + dict( + desc='Add allow-query ACL to zone %r' % dnszone1, + command=('dnszone_mod', [dnszone1], {'idnsallowquery': u'!10/8;any'}), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'mxrecord': [u'0 ns1.dnszone.test.'], + 'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [u'5478'], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowquery': [u'!10.0.0.0/8;any;'], + 'idnsallowtransfer': [u'none;'], + }, + }, + ), + + + dict( + desc='Try to add invalid allow-transfer to zone %r' % dnszone1, + command=('dnszone_mod', [dnszone1], {'idnsallowtransfer': u'10.'}), + expected=errors.ValidationError(name='allow_transfer', + error=u"failed to detect a valid IP address from '10.'"), + ), + + dict( + desc='Add allow-transer ACL to zone %r' % dnszone1, + command=('dnszone_mod', [dnszone1], {'idnsallowtransfer': u'80.142.15.80'}), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'mxrecord': [u'0 ns1.dnszone.test.'], + 'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [fuzzy_digits], + 'idnssoarefresh': [u'5478'], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowquery': [u'!10.0.0.0/8;any;'], + 'idnsallowtransfer': [u'80.142.15.80;'], + }, + }, + ), + + + dict( + desc='Set SOA serial of zone %r to high number' % dnszone1, + command=('dnszone_mod', [dnszone1], {'idnssoaserial': 4294967295}), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'nsrecord': [dnszone1_mname], + 'mxrecord': [u'0 ns1.dnszone.test.'], + 'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"], + 'idnssoamname': [dnszone1_mname], + 'idnssoarname': [dnszone1_rname], + 'idnssoaserial': [u'4294967295'], + 'idnssoarefresh': [u'5478'], + 'idnssoaretry': [fuzzy_digits], + 'idnssoaexpire': [fuzzy_digits], + 'idnssoaminimum': [fuzzy_digits], + 'idnsallowquery': [u'!10.0.0.0/8;any;'], + 'idnsallowtransfer': [u'80.142.15.80;'], + }, + }, + ), + + + dict( + desc='Try to create duplicate PTR record for %r with --a-create-reverse' % dnsres1, + command=('dnsrecord_add', [dnszone1, dnsres1], {'arecord': u'80.142.15.80', + 'a_extra_create_reverse' : True}), + expected=errors.DuplicateEntry(message=u'Reverse record for IP ' + + u'address 80.142.15.80 already exists in reverse zone ' + + u'15.142.80.in-addr.arpa..'), + ), + + + dict( + desc='Create A record %r in zone %r with --a-create-reverse' % (dnsres1, dnszone1), + command=('dnsrecord_add', [dnszone1, dnsres1], {'arecord': u'80.142.15.81', + 'a_extra_create_reverse' : True}), + expected={ + 'value': dnsres1, + 'summary': None, + 'result': { + 'dn': dnsres1_dn, + 'idnsname': [dnsres1], + 'objectclass': objectclasses.dnsrecord, + 'arecord': [u'80.142.15.81'], + }, + }, + ), + + + dict( + desc='Check reverse record for %r created via --a-create-reverse' % dnsres1, + command=('dnsrecord_show', [revdnszone1, dnsrev2], {}), + expected={ + 'value': dnsrev2, + 'summary': None, + 'result': { + 'dn': dnsrev2_dn, + 'idnsname': [dnsrev2], + 'ptrrecord': [dnsres1 + '.' + dnszone1 + '.'], + }, + }, + ), + + + dict( + desc='Try to add per-zone permission for unknown zone', + command=('dnszone_add_permission', [u'does.not.exist'], {}), + expected=errors.NotFound(reason=u'does.not.exist: DNS zone not found') + ), + + + dict( + desc='Add per-zone permission for zone %r' % dnszone1, + command=( + 'dnszone_add_permission', [dnszone1], {} + ), + expected=dict( + result=True, + value=dnszone1_permission, + summary=u'Added system permission "%s"' % dnszone1_permission, + ), + ), + + + dict( + desc='Try to add duplicate per-zone permission for zone %r' % dnszone1, + command=( + 'dnszone_add_permission', [dnszone1], {} + ), + expected=errors.DuplicateEntry(message=u'permission with name ' + '"%s" already exists' % dnszone1_permission) + ), + + + dict( + desc='Make sure the permission was created %r' % dnszone1, + command=( + 'permission_show', [dnszone1_permission], {} + ), + expected=dict( + value=dnszone1_permission, + summary=None, + result={ + 'dn': dnszone1_permission_dn, + 'cn': [dnszone1_permission], + 'ipapermissiontype': [u'SYSTEM'], + }, + ), + ), + + + dict( + desc='Try to remove per-zone permission for unknown zone', + command=('dnszone_remove_permission', [u'does.not.exist'], {}), + expected=errors.NotFound(reason=u'does.not.exist: DNS zone not found') + ), + + + dict( + desc='Remove per-zone permission for zone %r' % dnszone1, + command=( + 'dnszone_remove_permission', [dnszone1], {} + ), + expected=dict( + result=True, + value=dnszone1_permission, + summary=u'Removed system permission "%s"' % dnszone1_permission, + ), + ), + + + dict( + desc='Make sure the permission for zone %r was deleted' % dnszone1, + command=( + 'permission_show', [dnszone1_permission], {} + ), + expected=errors.NotFound(reason=u'%s: permission not found' + % dnszone1_permission) + ), + + + dict( + desc='Delete zone %r' % dnszone1, + command=('dnszone_del', [dnszone1], {}), + expected={ + 'value': dnszone1, + 'summary': u'Deleted DNS zone "%s"' % dnszone1, + 'result': {'failed': u''}, + }, + ), + + + dict( + desc='Try to create zone %r nameserver not in it' % dnszone1, + command=( + 'dnszone_add', [dnszone1], { + 'idnssoamname': u'not.in.this.zone.', + 'idnssoarname': dnszone1_rname, + 'ip_address' : u'1.2.3.4', + } + ), + expected=errors.ValidationError(name='ip_address', + error=u"Nameserver DNS record is created only for nameservers" + u" in current zone"), + ), + + + dict( + desc='Create zone %r with relative nameserver' % dnszone1, + command=( + 'dnszone_add', [dnszone1], { + 'idnssoamname': u'ns', + 'idnssoarname': dnszone1_rname, + 'ip_address' : u'1.2.3.4', + } + ), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'dn': dnszone1_dn, + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'idnssoamname': [u'ns'], + 'nsrecord': [u'ns'], + 'idnssoarname': [dnszone1_rname], + '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, + }, + }, + ), + + + dict( + desc='Delete zone %r' % dnszone1, + command=('dnszone_del', [dnszone1], {}), + expected={ + 'value': dnszone1, + 'summary': u'Deleted DNS zone "%s"' % dnszone1, + 'result': {'failed': u''}, + }, + ), + + + dict( + desc='Create zone %r with nameserver in the zone itself' % dnszone1, + command=( + 'dnszone_add', [dnszone1], { + 'idnssoamname': dnszone1 + u'.', + 'idnssoarname': dnszone1_rname, + 'ip_address' : u'1.2.3.4', + } + ), + expected={ + 'value': dnszone1, + 'summary': None, + 'result': { + 'dn': dnszone1_dn, + 'idnsname': [dnszone1], + 'idnszoneactive': [u'TRUE'], + 'idnssoamname': [dnszone1 + u'.'], + 'nsrecord': [dnszone1 + u'.'], + 'idnssoarname': [dnszone1_rname], + '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, + }, + }, + ), + + ] -- cgit