mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 07:33:27 -06:00
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>
This commit is contained in:
parent
cf634a4ff8
commit
e23159596e
6
API.txt
6
API.txt
@ -1054,6 +1054,12 @@ option: Str('version?')
|
||||
output: Output('result', type=[<type 'bool'>])
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: Output('value', type=[<type 'unicode'>])
|
||||
command: dns_update_system_records
|
||||
args: 0,2,2
|
||||
option: Flag('dry_run', autofill=True, default=False)
|
||||
option: Str('version?')
|
||||
output: Output('result', type=[<type 'dict'>])
|
||||
output: Output('value', type=[<type 'bool'>])
|
||||
command: dnsconfig_mod
|
||||
args: 0,11,3
|
||||
option: Str('addattr*', cli_name='addattr')
|
||||
|
4
VERSION
4
VERSION
@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
|
||||
# #
|
||||
########################################################
|
||||
IPA_API_VERSION_MAJOR=2
|
||||
IPA_API_VERSION_MINOR=184
|
||||
# Last change: ftweedal - add issuer options to cert-show and cert-find
|
||||
IPA_API_VERSION_MINOR=185
|
||||
# Last change: mbasti - added command dns-update-system-records
|
||||
|
@ -21,8 +21,9 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import six
|
||||
import copy
|
||||
|
||||
from ipaclient.frontend import MethodOverride
|
||||
from ipaclient.frontend import MethodOverride, CommandOverride
|
||||
from ipalib import errors
|
||||
from ipalib.dns import (get_record_rrtype,
|
||||
has_cli_options,
|
||||
@ -342,3 +343,29 @@ class dnsforwardzone_mod(MethodOverride):
|
||||
_("Server will check DNS forwarder(s)."))
|
||||
self.Backend.textui.print_plain(
|
||||
_("This may take some time, please wait ..."))
|
||||
|
||||
|
||||
@register(override=True)
|
||||
class dns_update_system_records(CommandOverride):
|
||||
def output_for_cli(self, textui, output, *args, **options):
|
||||
output_super = copy.deepcopy(output)
|
||||
super_res = output_super.get('result', {})
|
||||
super_res.pop('ipa_records', None)
|
||||
super_res.pop('location_records', None)
|
||||
|
||||
super(dns_update_system_records, self).output_for_cli(
|
||||
textui, output_super, *args, **options)
|
||||
|
||||
labels = {
|
||||
p.name: unicode(p.label) for p in self.output_params()
|
||||
}
|
||||
|
||||
result = output.get('result', {})
|
||||
for key in ('ipa_records', 'location_records'):
|
||||
if result.get(key):
|
||||
textui.print_indented(u'{}:'.format(labels[key]), indent=1)
|
||||
for val in sorted(result[key]):
|
||||
textui.print_indented(val, indent=2)
|
||||
textui.print_line(u'')
|
||||
|
||||
return int(not output['value'])
|
||||
|
@ -395,6 +395,29 @@ class DNSForwardPolicyConflictWithEmptyZone(PublicMessage):
|
||||
)
|
||||
|
||||
|
||||
class DNSUpdateOfSystemRecordFailed(PublicMessage):
|
||||
"""
|
||||
** 13022 ** Update of a DNS system record failed
|
||||
"""
|
||||
errno = 13022
|
||||
type = "warning"
|
||||
format = _(
|
||||
"Update of system record '%(record)s' failed with error: %(error)s"
|
||||
)
|
||||
|
||||
|
||||
class DNSUpdateNotIPAManagedZone(PublicMessage):
|
||||
"""
|
||||
** 13023 ** Zone for system records is not managed by IPA
|
||||
"""
|
||||
errno = 13023
|
||||
type = "warning"
|
||||
format = _(
|
||||
"IPA does not manage the zone %(zone)s, please add records "
|
||||
"to your DNS server manually"
|
||||
)
|
||||
|
||||
|
||||
def iter_messages(variables, base):
|
||||
"""Return a tuple with all subclasses
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user