summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorMartin Basti <mbasti@redhat.com>2016-06-10 17:03:25 +0200
committerMartin Basti <mbasti@redhat.com>2016-06-17 15:22:24 +0200
commite23159596e1851f156461d00b9f9f99dc698e12b (patch)
tree5c3f2436a80b7326ad39eaa798f2fa538dfda68d /ipaserver
parentcf634a4ff8a100589f99e57c51b2c4591853e88a (diff)
downloadfreeipa-e23159596e1851f156461d00b9f9f99dc698e12b.tar.gz
freeipa-e23159596e1851f156461d00b9f9f99dc698e12b.tar.xz
freeipa-e23159596e1851f156461d00b9f9f99dc698e12b.zip
DNS Locations: command dns-update-system-records
command dns-update-system-records updates/fixes DNS records for IPA services: * updating A, AAAA records for CA * updating SRV records for LDAP, kerberos and AD trust * updating TXT record in _kerberos with proper realm * updating dns locations if used https://fedorahosted.org/freeipa/ticket/2008 Reviewed-By: Petr Spacek <pspacek@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/dns_data_management.py24
-rw-r--r--ipaserver/plugins/dns.py105
2 files changed, 128 insertions, 1 deletions
diff --git a/ipaserver/dns_data_management.py b/ipaserver/dns_data_management.py
index 7e5ad18e8..b5b9c1c18 100644
--- a/ipaserver/dns_data_management.py
+++ b/ipaserver/dns_data_management.py
@@ -4,6 +4,8 @@
from __future__ import absolute_import
+import six
+
from collections import defaultdict
from dns import (
rdataclass,
@@ -17,6 +19,10 @@ from ipalib import errors
from ipalib.dns import record_name_format
from ipapython.dnsutil import DNSName, resolve_rrsets
+if six.PY3:
+ unicode=str
+
+
IPA_DEFAULT_MASTER_SRV_REC = (
# srv record name, port
(DNSName(u'_ldap._tcp'), 389),
@@ -214,7 +220,7 @@ class IPASystemRecords(object):
for rdata in rdataset:
option_name = (record_name_format % rdatatype.to_text(
rdata.rdtype).lower())
- update_dict[option_name].append(rdata.to_text())
+ update_dict[option_name].append(unicode(rdata.to_text()))
return update_dict
def __update_dns_records(
@@ -378,3 +384,19 @@ class IPASystemRecords(object):
self.update_base_records(),
self.update_locations_records()
)
+
+ @classmethod
+ def records_list_from_node(cls, name, node):
+ records = []
+ for rdataset in node:
+ for rd in rdataset:
+ records.append(
+ u'{name} {ttl} {rdclass} {rdtype} {rdata}'.format(
+ name=name.ToASCII(),
+ ttl=rdataset.ttl,
+ rdclass=rdataclass.to_text(rd.rdclass),
+ rdtype=rdatatype.to_text(rd.rdtype),
+ rdata=rd.to_text()
+ )
+ )
+ return records
diff --git a/ipaserver/plugins/dns.py b/ipaserver/plugins/dns.py
index 8e2d402d5..e9eb1f98f 100644
--- a/ipaserver/plugins/dns.py
+++ b/ipaserver/plugins/dns.py
@@ -72,6 +72,10 @@ from ipapython.ipautil import CheckedIPAddress
from ipapython.dnsutil import check_zone_overlap
from ipapython.dnsutil import DNSName
from ipapython.dnsutil import related_to_auto_empty_zone
+from ipaserver.dns_data_management import (
+ IPASystemRecords,
+ IPADomainIsNotManagedByIPAError,
+)
if six.PY3:
unicode = str
@@ -4430,3 +4434,104 @@ class dnsforwardzone_add_permission(DNSZoneBase_add_permission):
@register()
class dnsforwardzone_remove_permission(DNSZoneBase_remove_permission):
__doc__ = _('Remove a permission for per-forward zone access delegation.')
+
+
+@register()
+class dns_update_system_records(Command):
+ __doc__ = _('Update location and IPA server DNS records')
+
+
+ has_output_params = (
+ Str(
+ 'ipa_records*',
+ label=_('IPA DNS records')
+ ),
+ Str(
+ 'location_records*',
+ label=_('IPA location records')
+ )
+ )
+
+ has_output = (
+ output.Output(
+ 'result',
+ type=dict,
+ doc=_('Dictionary mapping variable name to value'),
+ ),
+ output.Output(
+ 'value', bool,
+ _('Result of the command'), ['no_display']
+ )
+ )
+
+ takes_options = (
+ Flag(
+ 'dry_run',
+ label=_('Dry run'),
+ doc=_('Do not update recors only return expected records')
+ )
+ )
+
+ def execute(self, *args, **options):
+
+ def output_to_list(iterable):
+ rec_list = []
+ for name, node in iterable:
+ rec_list.extend(IPASystemRecords.records_list_from_node(
+ name, node))
+ return rec_list
+
+ def output_to_list_with_failed(iterable):
+ err_rec_list = []
+ for name, node, error in iterable:
+ err_rec_list.extend([
+ (v, unicode(error)) for v in
+ IPASystemRecords.records_list_from_node(name, node)
+ ])
+ return err_rec_list
+
+ result = {
+ 'result': {},
+ 'value': True,
+ }
+
+ system_records = IPASystemRecords(self.api)
+
+ if options.get('dry_run'):
+ result['result']['ipa_records'] = output_to_list(
+ system_records.get_base_records().items())
+ result['result']['location_records'] = output_to_list(
+ system_records.get_locations_records().items())
+ else:
+ try:
+ (
+ (success_base, failed_base),
+ (success_loc, failed_loc),
+ ) = system_records.update_dns_records()
+ except IPADomainIsNotManagedByIPAError:
+ result['value'] = False
+ self.add_message(
+ messages.DNSUpdateNotIPAManagedZone(
+ zone=self.api.env.domain)
+ )
+ result['result']['ipa_records'] = output_to_list(
+ system_records.get_base_records().items())
+ else:
+ if success_base:
+ result['result']['ipa_records'] = output_to_list(
+ success_base)
+ if success_loc:
+ result['result']['location_records'] = output_to_list(
+ success_loc)
+ for failed in (failed_base, failed_loc):
+ for record, error in output_to_list_with_failed(failed):
+ self.add_message(
+ messages.DNSUpdateOfSystemRecordFailed(
+ record=record,
+ error=error
+ )
+ )
+ if failed_base or failed_loc:
+ result['value'] = False
+
+ return result