https://fedorahosted.org/freeipa/ticket/4249
--
David Kupka
From 3bd0b78b7b6f77d39478aa75d7f808a06fed562b Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
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
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to