https://fedorahosted.org/freeipa/ticket/4249 -- David Kupka
From 3bd0b78b7b6f77d39478aa75d7f808a06fed562b Mon Sep 17 00:00:00 2001 From: David Kupka <[email protected]> Date: Sun, 4 Jan 2015 15:04:18 -0500 Subject: [PATCH] client: Update DNS with all available local IP addresses.
Detect all usable IP addresses assigned to any interface and create coresponding DNS records on server. https://fedorahosted.org/freeipa/ticket/4249 --- ipa-client/ipa-install/ipa-client-install | 103 +++++++++++++----------------- 1 file changed, 45 insertions(+), 58 deletions(-) diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install index dfe0e3b7597c2ea63c299969b3a9d76cf8ecc273..027dda2e04212fe90ab291adf23edb63b194475d 100755 --- a/ipa-client/ipa-install/ipa-client-install +++ b/ipa-client/ipa-install/ipa-client-install @@ -1494,40 +1494,22 @@ def unconfigure_nisdomain(): if not enabled: services.knownservices.domainname.disable() - -def resolve_ipaddress(server): - """ Connect to the server's LDAP port in order to determine what ip - address this machine uses as "public" ip (relative to the server). - - Returns a tuple with the IP address and address family when - connection was successful. Socket error is raised otherwise. - """ - last_socket_error = None - - for res in socket.getaddrinfo(server, 389, socket.AF_UNSPEC, - socket.SOCK_STREAM): - af, socktype, proto, canonname, sa = res - try: - s = socket.socket(af, socktype, proto) - except socket.error, e: - last_socket_error = e - s = None +def get_local_ipaddresses(): + ipresult = ipautil.run([paths.IP, '-oneline', 'address', 'show']) + lines = ipresult[0].replace('\\', '').split('\n') + ips = [] + for line in lines: + fields = line.split() + if len(fields) < 6: + continue + if fields[2] not in ['inet', 'inet6']: continue - + (ip, mask) = fields[3].rsplit('/', 1) try: - s.connect(sa) - sockname = s.getsockname() - - # For both IPv4 and IPv6 own IP address is always the first item - return (sockname[0], af) - except socket.error, e: - last_socket_error = e - finally: - if s: - s.close() - - if last_socket_error is not None: - raise last_socket_error # pylint: disable=E0702 + ips.append(ipautil.CheckedIPAddress(ip)) + except ValueError: + continue + return ips def do_nsupdate(update_txt): root_logger.debug("Writing nsupdate commands to %s:", UPDATE_FILE) @@ -1552,21 +1534,24 @@ def do_nsupdate(update_txt): return result -UPDATE_TEMPLATE_A = """ -debug +DELETE_TEMPLATE_A = """ update delete $HOSTNAME. IN A show send -update add $HOSTNAME. $TTL IN A $IPADDRESS -show -send """ -UPDATE_TEMPLATE_AAAA = """ -debug +DELETE_TEMPLATE_AAAA = """ update delete $HOSTNAME. IN AAAA show send +""" +ADD_TEMPLATE_A = """ +update add $HOSTNAME. $TTL IN A $IPADDRESS +show +send +""" + +ADD_TEMPLATE_AAAA = """ update add $HOSTNAME. $TTL IN AAAA $IPADDRESS show send @@ -1578,31 +1563,33 @@ CCACHE_FILE = paths.IPA_DNS_CCACHE def update_dns(server, hostname): try: - (ip, af) = resolve_ipaddress(server) - except socket.gaierror, e: - root_logger.debug("update_dns: could not connect to server: %s", e) - root_logger.error("Cannot update DNS records! " - "Failed to connect to server '%s'.", server) + ips = get_local_ipaddresses() + except CalledProcessError as e: + root_logger.error("Cannot update DNS records. %s" % e) return - sub_dict = dict(HOSTNAME=hostname, - IPADDRESS=ip, - TTL=1200 - ) - - if af == socket.AF_INET: - template = UPDATE_TEMPLATE_A - elif af == socket.AF_INET6: - template = UPDATE_TEMPLATE_AAAA - else: - root_logger.info("Failed to determine this machine's ip address.") - root_logger.warning("Failed to update DNS A record.") + if len(ips) == 0: + root_logger.info("Failed to determine this machine's ip address(es).") return - update_txt = ipautil.template_str(template, sub_dict) + update_txt = "debug\n" + update_txt += ipautil.template_str(DELETE_TEMPLATE_A, dict(HOSTNAME=hostname)) + update_txt += ipautil.template_str(DELETE_TEMPLATE_AAAA, dict(HOSTNAME=hostname)) + + for ip in ips: + sub_dict = dict(HOSTNAME=hostname, + IPADDRESS=ip, + TTL=1200 + ) + if ip.version == 4: + template = ADD_TEMPLATE_A + elif ip.version == 6: + template = ADD_TEMPLATE_AAAA + update_txt += ipautil.template_str(template, sub_dict) if do_nsupdate(update_txt): - root_logger.info("DNS server record set to: %s -> %s", hostname, ip) + str_ips = ', '.join([str(ip) for ip in ips]) + root_logger.info("DNS server record set to: %s -> %s", hostname, str_ips) else: root_logger.error("Failed to update DNS records.") -- 2.1.0
_______________________________________________ Freeipa-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/freeipa-devel
