On 03/09/14 12:45, Martin Basti wrote:
On 03/09/14 12:27, Martin Kosek wrote:
On 09/02/2014 05:46 PM, Petr Spacek wrote:
On 25.8.2014 14:52, Martin Basti wrote:
Patches attached.
Ticket: https://fedorahosted.org/freeipa/ticket/4149
There is a bug in bind-dyndb-ldap (or worse in dirsrv), which cause
the named
service is stopped after deleting zone.
Bug ticket: https://fedorahosted.org/bind-dyndb-ldap/ticket/138
Functional ACK, it works for me. It can be pushed if Python gurus
are okay with
the code.
Is it safe to commit the change given that bind-dyndb-ldap still
crash when "."
is removed? Wouldn't it break our CI tests?
Maybe we should wait until fixed bind-dydnb-ldap is released.
Hopefully it
would be soon.
Martin
_______________________________________________
Freeipa-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/freeipa-devel
It will broke tests, don't push it until bind-dyndb-ldap is fixed.
Currently I'm testing bind-dyndb-ldap related patch.
Added patches 120 and 121, which are required by DNS to work correctly.
Patches 120 and 121 add all DNS replicas to zone apex as NS,
--name-server option doesn't add NS record, only changes the SOA MNAME
attribute
Original and new patches attached.
--
Martin Basti
From 9ed12420bf52a2d2dab1f8cc4f1f6b1b5f86a801 Mon Sep 17 00:00:00 2001
From: Martin Basti <[email protected]>
Date: Fri, 22 Aug 2014 17:11:22 +0200
Subject: [PATCH 1/2] Fix DNS plugin to allow to add root zone
Ticket: https://fedorahosted.org/freeipa/ticket/4149
---
ipalib/plugins/dns.py | 53 ++++++++++++++++++++++++++++++---------------------
1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index 24b303d8405aa3b4a6e0474e75d0e46e6949860d..9c8d09856a57f12b0ff1a52c8f0277f7abb29cdd 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -1783,17 +1783,21 @@ class DNSZoneBase(LDAPObject):
zone = keys[-1]
assert isinstance(zone, DNSName)
assert zone.is_absolute()
- zone = zone.ToASCII()
+ zone_a = zone.ToASCII()
+
+ # special case when zone is the root zone ('.')
+ if zone == DNSName.root:
+ return super(DNSZoneBase, self).get_dn(zone_a, **options)
# try first relative name, a new zone has to be added as absolute
# otherwise ObjectViolation is raised
- zone = zone[:-1]
- dn = super(DNSZoneBase, self).get_dn(zone, **options)
+ zone_a = zone_a[:-1]
+ dn = super(DNSZoneBase, self).get_dn(zone_a, **options)
try:
self.backend.get_entry(dn, [''])
except errors.NotFound:
- zone = u"%s." % zone
- dn = super(DNSZoneBase, self).get_dn(zone, **options)
+ zone_a = u"%s." % zone_a
+ dn = super(DNSZoneBase, self).get_dn(zone_a, **options)
return dn
@@ -1825,6 +1829,8 @@ class DNSZoneBase(LDAPObject):
try:
api.Command['permission_del'](permission_name, force=True)
except errors.NotFound, e:
+ if zone == DNSName.root: # special case root zone
+ raise
# compatibility, older IPA versions which allows to create zone
# without absolute zone name
permission_name_rel = self.permission_name(
@@ -1988,20 +1994,21 @@ class DNSZoneBase_add_permission(LDAPQuery):
permission_name = self.obj.permission_name(keys[-1])
# compatibility with older IPA versions which allows relative zonenames
- permission_name_rel = self.obj.permission_name(
- keys[-1].relativize(DNSName.root)
- )
- try:
- api.Object['permission'].get_dn_if_exists(permission_name_rel)
- except errors.NotFound:
- pass
- else:
- # permission exists without absolute domain name
- raise errors.DuplicateEntry(
- message=_('permission "%(value)s" already exists') % {
- 'value': permission_name
- }
+ if keys[-1] != DNSName.root: # special case root zone
+ permission_name_rel = self.obj.permission_name(
+ keys[-1].relativize(DNSName.root)
)
+ try:
+ api.Object['permission'].get_dn_if_exists(permission_name_rel)
+ except errors.NotFound:
+ pass
+ else:
+ # permission exists without absolute domain name
+ raise errors.DuplicateEntry(
+ message=_('permission "%(value)s" already exists') % {
+ 'value': permission_name
+ }
+ )
permission = api.Command['permission_add_noaci'](permission_name,
ipapermissiontype=u'SYSTEM'
@@ -2417,12 +2424,14 @@ class dnszone_add(DNSZoneBase_add):
nameserver_ip_address)
# Add entry to realmdomains
- # except for our own domain, forwarded zones and reverse zones
+ # except for our own domain, forward zones, reverse zones and root zone
zone = keys[0]
if (zone != DNSName(api.env.domain).make_absolute()
and not options.get('idnsforwarders')
- and not zone.is_reverse()):
+ and not zone.is_reverse()
+ and zone != DNSName.root
+ ):
try:
api.Command['realmdomains_mod'](add_domain=unicode(zone),
force=True)
@@ -2444,11 +2453,11 @@ class dnszone_del(DNSZoneBase_del):
super(dnszone_del, self).post_callback(ldap, dn, *keys, **options)
# Delete entry from realmdomains
- # except for our own domain
+ # except for our own domain, and root zone
zone = keys[0].make_absolute()
if (zone != DNSName(api.env.domain).make_absolute() and
- not zone.is_reverse()
+ not zone.is_reverse() and zone != DNSName.root
):
try:
api.Command['realmdomains_mod'](del_domain=unicode(zone),
--
1.8.3.1
From 1e9150d63da3c5c7f1d82ce722e85449a9915661 Mon Sep 17 00:00:00 2001
From: Martin Basti <[email protected]>
Date: Mon, 25 Aug 2014 12:48:32 +0200
Subject: [PATCH 2/2] DNS test: allow '.' as zone name
https://fedorahosted.org/freeipa/ticket/4149
---
ipatests/test_xmlrpc/test_dns_plugin.py | 103 ++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/ipatests/test_xmlrpc/test_dns_plugin.py b/ipatests/test_xmlrpc/test_dns_plugin.py
index 4085871ec4ebe2e03e6fee2460f159da2c3bf855..9eca2c3697e40bd42f86231c39c2e80e841d9864 100644
--- a/ipatests/test_xmlrpc/test_dns_plugin.py
+++ b/ipatests/test_xmlrpc/test_dns_plugin.py
@@ -3697,3 +3697,106 @@ class test_dns(Declarative):
),
]
+
+
+zone_root = u'.'
+zone_root_dnsname = DNSName(zone_root)
+zone_root_ip = u'172.16.29.222'
+zone_root_dn = DN(('idnsname',zone_root), api.env.container_dns, api.env.basedn)
+zone_root_ns = u'ns'
+zone_root_ns_dnsname = DNSName(zone_root_ns)
+zone_root_ns_dn = DN(('idnsname', zone_root_ns), zone_root_dn)
+zone_root_rname = u'root.example.com.'
+zone_root_rname_dnsname = DNSName(zone_root_rname)
+zone_root_permission = u'Manage DNS zone %s' % zone_root
+zone_root_permission_dn = DN(('cn',zone_root_permission),
+ api.env.container_permission,api.env.basedn)
+
+class test_root_zone(Declarative):
+
+ @classmethod
+ def setUpClass(cls):
+ super(test_root_zone, cls).setUpClass()
+
+ if not api.Backend.rpcclient.isconnected():
+ api.Backend.rpcclient.connect(fallback=False)
+ try:
+ api.Command['dnszone_add'](zone1,
+ idnssoamname = zone1_ns,
+ idnssoarname = zone1_rname,
+ force = True,
+ )
+ api.Command['dnszone_del'](zone1)
+ except errors.NotFound:
+ raise nose.SkipTest('DNS is not configured')
+ except errors.DuplicateEntry:
+ pass
+
+ cleanup_commands = [
+ ('dnszone_del', [zone_root, ],
+ {'continue': True}),
+ ('permission_del', [zone_root_permission, ], {'force': True}
+ ),
+ ]
+
+ tests = [
+
+ dict(
+ desc='Create zone %r' % zone_root,
+ command=(
+ 'dnszone_add', [zone_root], {
+ 'idnssoamname': zone_root_ns,
+ 'idnssoarname': zone_root_rname,
+ 'ip_address' : zone_root_ip,
+ }
+ ),
+ expected={
+ 'value': zone_root_dnsname,
+ 'summary': None,
+ 'result': {
+ 'dn': zone_root_dn,
+ 'idnsname': [zone_root_dnsname],
+ 'idnszoneactive': [u'TRUE'],
+ 'idnssoamname': [zone_root_ns_dnsname],
+ 'nsrecord': [zone_root_ns],
+ 'idnssoarname': [zone_root_rname_dnsname],
+ '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='Add per-zone permission for zone %r' % zone_root,
+ command=(
+ 'dnszone_add_permission', [zone_root], {}
+ ),
+ expected=dict(
+ result=True,
+ value=zone_root_permission,
+ summary=u'Added system permission "%s"' % zone_root_permission,
+ ),
+ ),
+
+ dict(
+ desc='Delete zone %r' % zone_root,
+ command=('dnszone_del', [zone_root], {}),
+ expected={
+ 'value': [zone_root_dnsname],
+ 'summary': u'Deleted DNS zone "%s"' % zone_root,
+ 'result': {'failed': []},
+ },
+ ),
+
+ ]
--
1.8.3.1
From 92548ddb5e97c216f762cf2f51885ae73bb86b0d Mon Sep 17 00:00:00 2001
From: Martin Basti <[email protected]>
Date: Fri, 5 Sep 2014 16:09:59 +0200
Subject: [PATCH 1/2] Deprecation of --name-server and --ip-address option in
DNS
Option --name-server is changing only SOA MNAME, this option has no more
effect to NS records
Option --ip-addres is just ignored
A warning message is sent after use these options
Part of ticket: https://fedorahosted.org/freeipa/ticket/4149
---
API.txt | 2 +-
VERSION | 4 +-
ipalib/messages.py | 22 ++++++++++
ipalib/plugins/dns.py | 111 +++++++++++++++++---------------------------------
4 files changed, 63 insertions(+), 76 deletions(-)
diff --git a/API.txt b/API.txt
index 4fa27559269e05088d2e8858d0e0f3b723315fc7..02848a35f12e4fb1fbd7b2f4234326e43ecce07c 100644
--- a/API.txt
+++ b/API.txt
@@ -1152,7 +1152,7 @@ option: StrEnum('idnsforwardpolicy', attribute=True, cli_name='forward_policy',
option: Bool('idnssecinlinesigning', attribute=True, cli_name='dnssec', default=False, multivalue=False, required=False)
option: Int('idnssoaexpire', attribute=True, autofill=True, cli_name='expire', default=1209600, maxvalue=2147483647, minvalue=0, multivalue=False, required=True)
option: Int('idnssoaminimum', attribute=True, autofill=True, cli_name='minimum', default=3600, maxvalue=2147483647, minvalue=0, multivalue=False, required=True)
-option: DNSNameParam('idnssoamname', attribute=True, cli_name='name_server', multivalue=False, required=True)
+option: DNSNameParam('idnssoamname', attribute=True, cli_name='name_server', multivalue=False, required=False)
option: Int('idnssoarefresh', attribute=True, autofill=True, cli_name='refresh', default=3600, maxvalue=2147483647, minvalue=0, multivalue=False, required=True)
option: Int('idnssoaretry', attribute=True, autofill=True, cli_name='retry', default=900, maxvalue=2147483647, minvalue=0, multivalue=False, required=True)
option: DNSNameParam('idnssoarname', attribute=True, cli_name='admin_email', multivalue=False, only_absolute=True, required=True)
diff --git a/VERSION b/VERSION
index 379ead7565f23218cea087ef7ee487a71102fa7f..17672ff0c3d7f8f4771901c9cb828f02f0b8a8f2 100644
--- a/VERSION
+++ b/VERSION
@@ -89,5 +89,5 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=102
-# Last change: pviktori - allow adding services to roles
+IPA_API_VERSION_MINOR=103
+# Last change: mbasti - make --name-server option optional
diff --git a/ipalib/messages.py b/ipalib/messages.py
index f637e5b17de816f3a88645c65f4a01179d97552c..1c226ea766e44d2872a339b14a591a4dfa06caee 100644
--- a/ipalib/messages.py
+++ b/ipalib/messages.py
@@ -157,6 +157,28 @@ class DNSSECWarning(PublicMessage):
type = "warning"
format = _("DNSSEC support is experimental.\n%(additional_info)s")
+
+class OptionDeprecatedWarning(PublicMessage):
+ """
+ **13004** Used when user uses a deprecated option
+ """
+
+ errno = 13004
+ type = "warning"
+ format = _(u"'%(option)s' option is deprecated. %(additional_info)s")
+
+
+class OptionNameServerWarning(PublicMessage):
+ """
+ **13005** Used when user uses a dnszone-add/mod --name-server option
+ """
+
+ errno = 13005
+ type = "warning"
+ format = _(u"'--name-server' is used only for setting up the SOA MNAME record.\n"
+ u"To edit NS record(s) in zone apex, use command 'dnsrecord-mod [zone] @ --ns-rec=nameserver'.")
+
+
def iter_messages(variables, base):
"""Return a tuple with all subclasses
"""
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index ab79a8ef3e636be10aa10c2a22e07e3d31758cbc..d35d2be761029bc3403a69a1734d082e9cbe0f25 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -42,7 +42,7 @@ from ipalib import messages
from ipalib.util import (validate_zonemgr, normalize_zonemgr,
get_dns_forward_zone_update_policy,
get_dns_reverse_zone_update_policy,
- get_reverse_zone_default, REVERSE_DNS_ZONES)
+ get_reverse_zone_default, REVERSE_DNS_ZONES, normalize_zone)
from ipapython.ipautil import valid_ip, CheckedIPAddress, is_host_resolvable
from ipapython.dnsutil import DNSName
@@ -2088,6 +2088,7 @@ class dnszone(DNSZoneBase):
cli_name='name_server',
label=_('Authoritative nameserver'),
doc=_('Authoritative nameserver domain name'),
+ required=False,
),
DNSNameParam('idnssoarname',
_rname_validator,
@@ -2317,6 +2318,10 @@ class dnszone(DNSZoneBase):
"server.")
))
+ def _warning_name_server_option(self, result, context, **options):
+ if getattr(context, 'show_warning_nameserver_option', False):
+ messages.add_message(options['version'],
+ result, messages.OptionNameServerWarning())
@register()
class dnszone_add(DNSZoneBase_add):
@@ -2327,39 +2332,23 @@ class dnszone_add(DNSZoneBase_add):
label=_('Force'),
doc=_('Force DNS zone creation even if nameserver is not resolvable.'),
),
+
+ # Deprecated
+ # ip-address option is not used anymore, we have to keep it due to compability with clients older than 4.1
Str('ip_address?', _validate_ipaddr,
- doc=_('Add forward record for nameserver located in the created zone'),
- label=_('Nameserver IP address'),
+ doc=_('Add forward record for nameserver located in the created zone (Deprecated)'),
+ label=_('Nameserver IP address (Deprecated)'),
+ flags = ['no_option', ]
),
)
- def interactive_prompt_callback(self, kw):
- """
- Interactive mode should prompt for nameserver IP address only if all
- of the following conditions are true:
- * New zone is a forward zone
- * NS is defined inside the new zone (NS can be given either in the
- form of absolute or relative name)
- """
- if kw.get('ip_address', None):
- return
-
- try:
- zone = DNSName(kw['idnsname']).make_absolute()
- except Exception, e:
- raise errors.ValidationError(name='idnsname', error=unicode(e))
-
- try:
- ns = DNSName(kw['idnssoamname'])
- except Exception, e:
- raise errors.ValidationError(name='idnssoamname', error=unicode(e))
-
- relative_ns = not ns.is_absolute()
- ns_in_zone = self.obj.get_name_in_zone(zone, ns)
-
- if not zone.is_reverse() and (relative_ns or ns_in_zone):
- ip_address = self.Backend.textui.prompt(_(u'Nameserver IP address'))
- kw['ip_address'] = ip_address
+ def _warning_deprecated_option(self, result, **options):
+ if 'ip_address' in options:
+ messages.add_message(
+ options['version'],
+ result,
+ messages.OptionDeprecatedWarning(option='ip-address', additional_info=u"Value will be ignored.")
+ )
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
assert isinstance(dn, DN)
@@ -2367,61 +2356,36 @@ class dnszone_add(DNSZoneBase_add):
dn = super(dnszone_add, self).pre_callback(ldap, dn, entry_attrs,
attrs_list, *keys, **options)
- # Check nameserver has a forward record
- nameserver = entry_attrs['idnssoamname']
+ nameservers = [normalize_zone(x) for x in api.Object.dnsrecord.get_dns_masters()]
+ server = normalize_zone(api.env.host)
- # NS record must contain domain name
- if valid_ip(nameserver):
- raise errors.ValidationError(name='name-server',
- error=_("Nameserver address is not a domain name"))
-
- nameserver_ip_address = options.get('ip_address')
- zone = keys[-1]
- if nameserver.is_absolute():
- record_in_zone = self.obj.get_name_in_zone(keys[-1], nameserver)
+ if not entry_attrs.get('idnssoamname'):
+ # user didn't specify SOA mname
+ if server in nameservers:
+ # current ipa server is authoritative nameserver in SOA record
+ entry_attrs['idnssoamname'] = [server]
+ else:
+ # a DNS capable server is authoritative nameserver in SOA record
+ entry_attrs['idnssoamname'] = [nameservers[0]]
else:
- record_in_zone = nameserver
+ # show warning about --name-server option
+ context.show_warning_nameserver_option = True
- if zone.is_reverse():
- if not nameserver.is_absolute():
- raise errors.ValidationError(name='name-server',
- error=_("Nameserver for reverse zone cannot be "
- "a relative DNS name"))
- elif nameserver_ip_address:
- raise errors.ValidationError(name='ip_address',
- error=_("Nameserver DNS record is created for "
- "for forward zones only"))
- elif (nameserver_ip_address and nameserver.is_absolute() and
- record_in_zone is None):
- raise errors.ValidationError(name='ip_address',
- error=_("Nameserver DNS record is created only for "
- "nameservers in current zone"))
+ # all ipa DNS servers should be in NS zone record (as absolute domain name)
+ entry_attrs['nsrecord'] = nameservers
- if not nameserver_ip_address and not options['force']:
- check_ns_rec_resolvable(keys[0], nameserver)
-
- entry_attrs['nsrecord'] = nameserver
- entry_attrs['idnssoamname'] = nameserver
return dn
def execute(self, *keys, **options):
result = super(dnszone_add, self).execute(*keys, **options)
+ self._warning_deprecated_option(result, **options)
self.obj._warning_forwarding(result, **options)
self.obj._warning_dnssec_experimental(result, *keys, **options)
+ self.obj._warning_name_server_option(result, context, **options)
return result
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN)
- nameserver_ip_address = options.get('ip_address')
- if nameserver_ip_address:
- nameserver = entry_attrs['idnssoamname'][0]
- if nameserver.is_absolute():
- dns_record = self.obj.get_name_in_zone(keys[-1], nameserver)
- else:
- dns_record = nameserver
- add_forward_record(keys[-1],
- dns_record,
- nameserver_ip_address)
# Add entry to realmdomains
# except for our own domain, forward zones, reverse zones and root zone
@@ -2484,8 +2448,8 @@ class dnszone_mod(DNSZoneBase_mod):
if not _check_DN_objectclass(ldap, dn, self.obj.object_class):
self.obj.handle_not_found(*keys)
nameserver = entry_attrs.get('idnssoamname')
- if nameserver and not nameserver.is_empty() and not options['force']:
- check_ns_rec_resolvable(keys[0], nameserver)
+ if nameserver:
+ context.show_warning_nameserver_option = True
return dn
@@ -2493,6 +2457,7 @@ class dnszone_mod(DNSZoneBase_mod):
result = super(dnszone_mod, self).execute(*keys, **options)
self.obj._warning_forwarding(result, **options)
self.obj._warning_dnssec_experimental(result, *keys, **options)
+ self.obj._warning_name_server_option(result, context, **options)
return result
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
--
1.8.3.1
From 5f1dd93f8ab67174d89bef90663ef06f0c6e5a57 Mon Sep 17 00:00:00 2001
From: Martin Basti <[email protected]>
Date: Fri, 12 Sep 2014 13:20:16 +0200
Subject: [PATCH 2/2] Add correct NS records during installation
All ipa-dns capable server is added to root zones as nameserver
During uninstall all NS records pointing to particular replica are
removed.
Part of ticket: https://fedorahosted.org/freeipa/ticket/4149
---
install/tools/ipa-replica-manage | 1 +
ipaserver/install/bindinstance.py | 106 +++++++++++++++++++++-----------------
2 files changed, 61 insertions(+), 46 deletions(-)
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index aa710953a7d41348b330498727dbc57818e5ce0b..e44131ebe637f10990ecc5a81f3fb896c92d5313 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -745,6 +745,7 @@ def del_master(realm, hostname, options):
bind = bindinstance.BindInstance()
bind.remove_master_dns_records(hostname, realm, realm.lower())
bind.remove_ipa_ca_dns_records(hostname, realm.lower())
+ bind.remove_server_ns_records(hostname)
except Exception, e:
print "Failed to cleanup %s DNS entries: %s" % (hostname, e)
print "You may need to manually remove them from the tree"
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index dfb086f109371ae97151622e2c44db27256896db..086e0276e8ef824c2367cc35861c616f3df7f00c 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -279,11 +279,11 @@ def read_reverse_zone(default, ip_address):
return normalize_zone(zone)
-def add_zone(name, zonemgr=None, dns_backup=None, ns_hostname=None, ns_ip_address=None,
+def add_zone(name, zonemgr=None, dns_backup=None, ns_hostname=None,
update_policy=None, force=False):
- if zone_is_reverse(name):
- # always normalize reverse zones
- name = normalize_zone(name)
+
+ # always normalize zones
+ name = normalize_zone(name)
if update_policy is None:
if zone_is_reverse(name):
@@ -294,27 +294,13 @@ def add_zone(name, zonemgr=None, dns_backup=None, ns_hostname=None, ns_ip_addres
if zonemgr is None:
zonemgr = 'hostmaster.%s' % name
- if ns_hostname is None:
- # automatically retrieve list of DNS masters
- dns_masters = api.Object.dnsrecord.get_dns_masters()
- if not dns_masters:
- raise installutils.ScriptError(
- "No IPA server with DNS support found!")
- ns_main = dns_masters.pop(0)
- ns_replicas = dns_masters
- else:
- ns_main = ns_hostname
- ns_replicas = []
- ns_main = normalize_zone(ns_main)
-
- if ns_ip_address is not None:
- ns_ip_address = unicode(ns_ip_address)
+ if ns_hostname:
+ ns_hostname = normalize_zone(ns_hostname)
try:
api.Command.dnszone_add(unicode(name),
- idnssoamname=unicode(ns_main),
+ idnssoamname=unicode(ns_hostname),
idnssoarname=unicode(zonemgr),
- ip_address=ns_ip_address,
idnsallowdynupdate=True,
idnsupdatepolicy=unicode(update_policy),
idnsallowquery=u'any',
@@ -323,11 +309,6 @@ def add_zone(name, zonemgr=None, dns_backup=None, ns_hostname=None, ns_ip_addres
except (errors.DuplicateEntry, errors.EmptyModlist):
pass
- nameservers = ns_replicas + [ns_main]
- for hostname in nameservers:
- hostname = normalize_zone(hostname)
- add_ns_rr(name, hostname, dns_backup=None, force=True)
-
def add_rr(zone, name, type, rdata, dns_backup=None, **kwargs):
addkw = { '%srecord' % str(type.lower()) : unicode(rdata) }
addkw.update(kwargs)
@@ -368,6 +349,9 @@ def del_fwd_rr(zone, host, ip_address):
elif addr.version == 6:
del_rr(zone, host, "AAAA", ip_address)
+def del_ns_rr(zone, name, rdata):
+ del_rr(zone, name, 'NS', rdata)
+
def get_rr(zone, name, type):
rectype = '%srecord' % unicode(type.lower())
ret = api.Command.dnsrecord_find(unicode(zone), unicode(name))
@@ -533,16 +517,16 @@ class BindInstance(service.Service):
if self.first_instance:
self.step("adding DNS container", self.__setup_dns_container)
- if dns_zone_exists(self.domain):
- self.step("adding NS record to the zone", self.__add_self_ns)
- else:
+ if not dns_zone_exists(self.domain):
self.step("setting up our zone", self.__setup_zone)
+
if self.reverse_zone is not None:
self.step("setting up reverse zone", self.__setup_reverse_zone)
self.step("setting up our own record", self.__add_self)
if self.first_instance:
self.step("setting up records for other masters", self.__add_others)
+ self.step("adding NS record to the zones", self.__add_self_ns) # all zones must be created before this step
self.step("setting up CA record", self.__add_ipa_ca_record)
self.step("setting up kerberos principal", self.__setup_principal)
@@ -615,19 +599,20 @@ class BindInstance(service.Service):
self._ldap_mod("dns.ldif", self.sub_dict)
def __setup_zone(self):
- nameserver_ip_address = self.ip_address
- if not self.host_in_default_domain():
- # Nameserver is in self.host_domain, no forward record added to self.domain
- nameserver_ip_address = None
# Always use force=True as named is not set up yet
add_zone(self.domain, self.zonemgr, dns_backup=self.dns_backup,
- ns_hostname=api.env.host, ns_ip_address=nameserver_ip_address,
- force=True)
+ ns_hostname=api.env.host, force=True)
add_rr(self.domain, "_kerberos", "TXT", self.realm)
def __add_self_ns(self):
- add_ns_rr(self.domain, api.env.host, self.dns_backup, force=True)
+ # add NS record to all zones
+ ns_hostname = normalize_zone(api.env.host)
+ result = api.Command.dnszone_find()
+ for zone in result['result']:
+ zone = unicode(zone['idnsname'][0]) # we need unicode due to backup
+ root_logger.debug("adding self NS to zone %s apex", zone)
+ add_ns_rr(zone, ns_hostname, self.dns_backup, force=True)
def __setup_reverse_zone(self):
# Always use force=True as named is not set up yet
@@ -666,14 +651,8 @@ class BindInstance(service.Service):
zone, self.domain))
root_logger.debug("Add DNS zone for host first.")
- if normalize_zone(zone) == normalize_zone(self.host_domain):
- ns_ip_address = self.ip_address
- else:
- ns_ip_address = None
-
add_zone(zone, self.zonemgr, dns_backup=self.dns_backup,
- ns_hostname=self.fqdn, ns_ip_address=ns_ip_address,
- force=True)
+ ns_hostname=self.fqdn, force=True)
# Add forward and reverse records to self
for addr in addrs:
@@ -921,7 +900,6 @@ class BindInstance(service.Service):
("_kpasswd._tcp", "SRV", "0 100 464 %s" % self.host_in_rr),
("_kpasswd._udp", "SRV", "0 100 464 %s" % self.host_in_rr),
("_ntp._udp", "SRV", "0 100 123 %s" % self.host_in_rr),
- ("@", "NS", normalize_zone(fqdn)),
)
for (record, type, rdata) in resource_records:
@@ -935,8 +913,6 @@ class BindInstance(service.Service):
if rzone is not None:
record = get_reverse_record_name(rzone, rdata)
del_rr(rzone, record, "PTR", normalize_zone(fqdn))
- # remove also master NS record from the reverse zone
- del_rr(rzone, "@", "NS", normalize_zone(fqdn))
def remove_ipa_ca_dns_records(self, fqdn, domain_name):
host, zone = fqdn.split(".", 1)
@@ -948,6 +924,44 @@ class BindInstance(service.Service):
for addr in addrs:
del_fwd_rr(domain_name, IPA_CA_RECORD, addr)
+ def remove_server_ns_records(self, fqdn):
+ """
+ Remove all NS records pointing to this server
+ """
+ ns_rdata = normalize_zone(fqdn)
+ if not api.Backend.ldap2.isconnected():
+ root_logger.debug("no ldap2 connection, removing NS records pointing to %s failed", ns_rdata)
+ print "no ldap2 connection" #TODO remove
+ return # we can't modify records
+ ldap = api.Backend.ldap2
+
+ # find all NS records pointing to this server
+
+ search_kw = {}
+ search_kw['nsrecord'] = ns_rdata
+ attr_filter = ldap.make_filter(search_kw, rules=ldap.MATCH_ALL)
+ attributes = ['idnsname', 'objectclass']
+ dn = DN(api.env.container_dns, api.env.basedn)
+
+ entries, truncated = ldap.find_entries(attr_filter, attributes, base_dn=dn)
+
+ # remove records
+ if entries:
+ root_logger.debug("Removing all NS records pointing to %s:", ns_rdata)
+
+ for entry in entries:
+ print "entry", repr(entry)
+ if 'idnszone' in entry['objectclass']:
+ # zone record
+ zone = entry.single_value['idnsname']
+ root_logger.debug("zone record %s", zone)
+ del_ns_rr(zone, u'@', ns_rdata)
+ else:
+ zone = entry.dn[1].value # get zone from DN
+ record = entry.single_value['idnsname']
+ root_logger.debug("record %s in zone %s", record, zone)
+ del_ns_rr(zone, record, ns_rdata)
+
def check_global_configuration(self):
"""
Check global DNS configuration in LDAP server and inform user when it
--
1.8.3.1
_______________________________________________
Freeipa-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/freeipa-devel