Split from patch 3. https://fedorahosted.org/freeipa/ticket/1212
Honza -- Jan Cholasta
>From 68dacbd0b4ada4c2f02570c167c34c299ceec57e Mon Sep 17 00:00:00 2001 From: Jan Cholasta <jchol...@redhat.com> Date: Tue, 10 May 2011 19:23:31 +0200 Subject: [PATCH] Parse netmasks in IP addresses passed to server install. ticket 1212 --- install/tools/ipa-dns-install | 6 ++- install/tools/ipa-replica-install | 2 + install/tools/ipa-replica-prepare | 11 ++++-- install/tools/ipa-server-install | 30 +++++++---------- ipaserver/install/installutils.py | 65 ++++++++++++++++++++++++++++-------- tests/test_install/test_utils.py | 55 +++++++++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 38 deletions(-) create mode 100644 tests/test_install/test_utils.py diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install index aac85bf..256c670 100755 --- a/install/tools/ipa-dns-install +++ b/install/tools/ipa-dns-install @@ -131,11 +131,13 @@ def main(): ip_address = options.ip_address else: ip_address = resolve_host(api.env.host) - if not ip_address or not verify_ip_address(ip_address): + ip = parse_ip_address(ip_address) + if not verify_ip_address(ip): if options.unattended: sys.exit("Unable to resolve IP address for host name") else: - ip_address = read_ip_address(api.env.host, fstore) + ip = read_ip_address(api.env.host, fstore) + ip_address = str(ip) logging.debug("will use ip_address: %s\n", ip_address) if options.no_forwarders: diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install index 64f1577..722da37 100755 --- a/install/tools/ipa-replica-install +++ b/install/tools/ipa-replica-install @@ -285,6 +285,8 @@ def install_bind(config, options): ip_address = resolve_host(config.host_name) if not ip_address: sys.exit("Unable to resolve IP address for host name") + ip = installutils.parse_ip_address(ip_address) + ip_address = str(ip) create_reverse = True if options.unattended: diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare index e912235..6a4e413 100755 --- a/install/tools/ipa-replica-prepare +++ b/install/tools/ipa-replica-prepare @@ -425,10 +425,13 @@ def main(): name = domain.pop(0) domain = ".".join(domain) - zone = add_zone(domain, nsaddr=options.ip_address) - add_rr(zone, name, "A", options.ip_address) - add_reverse_zone(options.ip_address) - add_ptr_rr(options.ip_address, replica_fqdn) + ip = installutils.parse_ip_address(options.ip_address) + ip_address = str(ip) + + zone = add_zone(domain, nsaddr=ip_address) + add_rr(zone, name, "A", ip_address) + add_reverse_zone(ip_address) + add_ptr_rr(ip_address, replica_fqdn) try: if not os.geteuid()==0: diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install index d50dc61..c256d0e 100755 --- a/install/tools/ipa-server-install +++ b/install/tools/ipa-server-install @@ -615,37 +615,33 @@ def main(): domain_name = domain_name.lower() # Check we have a public IP that is associated with the hostname - ip = resolve_host(host_name) - if ip is None: - if options.ip_address: - ip = options.ip_address - if ip is None and options.unattended: + ip = parse_ip_address(resolve_host(host_name)) + ip_opt = parse_ip_address(options.ip_address) + if not ip and ip_opt: + ip = ip_opt + if not ip and options.unattended: sys.exit("Unable to resolve IP address for host name") if not verify_ip_address(ip): - ip = "" + ip = None if options.unattended: sys.exit(1) - if options.ip_address and options.ip_address != ip: - if options.setup_dns: - if not verify_ip_address(options.ip_address): - return 1 - ip = options.ip_address - else: + if ip_opt: + if ip_opt != ip and not options.setup_dns: print >>sys.stderr, "Error: the hostname resolves to an IP address that is different" print >>sys.stderr, "from the one provided on the command line. Please fix your DNS" print >>sys.stderr, "or /etc/hosts file and restart the installation." return 1 - if options.unattended: - if not ip: - sys.exit("Unable to resolve IP address") + ip = ip_opt + if not verify_ip_address(ip): + return 1 if not ip: ip = read_ip_address(host_name, fstore) - logging.debug("read ip_address: %s\n" % ip) - ip_address = ip + logging.debug("read ip_address: %s\n" % str(ip)) + ip_address = str(ip) print "The IPA Master Server will be configured with" print "Hostname: " + host_name diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index 3868c4d..8ac24c9 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -148,17 +148,49 @@ def verify_fqdn(host_name,no_host_dns=False): else: print "Warning: Hostname (%s) not found in DNS" % host_name -def verify_ip_address(ip): - is_ok = True - try: - socket.inet_pton(socket.AF_INET, ip) - except: +class _ParsedIPAddress(netaddr.IPAddress): + def __init__(self, net): + super(_ParsedIPAddress, self).__init__(net.ip) + + self.prefixlen = net.prefixlen + +def parse_ip_address(addr): + if addr is None: + return None + if isinstance(addr, _ParsedIPAddress): + return addr + + if isinstance(addr, netaddr.IPNetwork): + net = addr + else: try: - socket.inet_pton(socket.AF_INET6, ip) + ip = netaddr.IPAddress(addr) + if ip.version == 4: + net = netaddr.IPNetwork(netaddr.cidr_abbrev_to_verbose(str(ip))) + elif ip.version == 6: + net = netaddr.IPNetwork(ip) + net.prefixlen = 64 + except ValueError: + try: + net = netaddr.IPNetwork(addr) + except: + return None except: - print "Unable to verify IP address" - is_ok = False - return is_ok + return None + + if net is None or net.version not in (4, 6): + return None + + return _ParsedIPAddress(net) + +def verify_ip_address(addr): + ip = parse_ip_address(addr) + + if ip is None: + print "Unable to verify IP address" + return False + + return True def record_in_hosts(ip, host_name, file="/etc/hosts"): hosts = open(file, 'r').readlines() @@ -192,18 +224,20 @@ def read_ip_address(host_name, fstore): while True: ip = ipautil.user_input("Please provide the IP address to be used for this host name", allow_empty = False) - if ip == "127.0.0.1" or ip == "::1": + ip_parsed = parse_ip_address(ip) + if ip_parsed.is_loopback(): print "The IPA Server can't use localhost as a valid IP" continue - if verify_ip_address(ip): + if verify_ip_address(ip_parsed): break + ip = str(ip_parsed) print "Adding ["+ip+" "+host_name+"] to your /etc/hosts file" fstore.backup_file("/etc/hosts") add_record_to_hosts(ip, host_name) - return ip + return ip_parsed def read_dns_forwarders(): addrs = [] @@ -215,15 +249,16 @@ def read_dns_forwarders(): allow_empty=True) if not ip: break - if ip == "127.0.0.1" or ip == "::1": + ip_parsed = parse_ip_address(ip) + if ip_parsed.is_loopback(): print "You cannot use localhost as a DNS forwarder" continue - if not verify_ip_address(ip): + if not verify_ip_address(ip_parsed): print "DNS forwarder %s not added" % ip continue print "DNS forwarder %s added" % ip - addrs.append(ip) + addrs.append(str(ip_parsed)) if not addrs: print "No DNS forwarders configured" diff --git a/tests/test_install/test_utils.py b/tests/test_install/test_utils.py new file mode 100644 index 0000000..70949a5 --- /dev/null +++ b/tests/test_install/test_utils.py @@ -0,0 +1,55 @@ +# Authors: +# Jan Cholasta <jchol...@redhat.com> +# +# Copyright (C) 2011 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +""" +Test the `ipaserver/install/installutils.py` module. +""" + +import nose + +from ipaserver.install import installutils + +class CheckIPAddress: + def __init__(self, addr): + self.description = "Test IP address parsing and verification (%s)" % addr + + def __call__(self, addr, words=None, prefixlen=None, verified=None): + ip = installutils.parse_ip_address(addr) + if ip: + assert ip.words == words and ip.prefixlen == prefixlen + assert not verified or installutils.verify_ip_address(ip) + else: + assert words is None and prefixlen is None and verified is None + +def test_ip_address(): + addrs = [ + ('10.11.12.13', (10, 11, 12, 13), 8, True), + ('10.11.12.13/14', (10, 11, 12, 13), 14, True), + ('10.11.12.1337',), + ('10.11.12.13/33',), + + ('2001::1', (0x2001, 0, 0, 0, 0, 0, 0, 1), 64, True), + ('2001::1/72', (0x2001, 0, 0, 0, 0, 0, 0, 1), 72, True), + ('2001::1beef',), + ('2001::1/129',), + + ('junk',) + ] + + for addr in addrs: + yield (CheckIPAddress(addr[0]),) + addr -- 1.7.4.4
_______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel