|
|
ac7d03 |
From a04defc43419906675107e483f0f2f3153685c8d Mon Sep 17 00:00:00 2001
|
|
|
ac7d03 |
From: Martin Basti <mbasti@redhat.com>
|
|
|
ac7d03 |
Date: Wed, 31 May 2017 15:50:05 +0200
|
|
|
ac7d03 |
Subject: [PATCH] Only warn when specified server IP addresses don't match intf
|
|
|
ac7d03 |
|
|
|
ac7d03 |
In containers local addresses differ from public addresses and we need
|
|
|
ac7d03 |
a way to provide only public address to installers.
|
|
|
ac7d03 |
|
|
|
ac7d03 |
https://pagure.io/freeipa/issue/2715
|
|
|
ac7d03 |
https://pagure.io/freeipa/issue/4317
|
|
|
ac7d03 |
|
|
|
ac7d03 |
Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
|
|
|
ac7d03 |
---
|
|
|
ac7d03 |
ipaclient/install/client.py | 4 +-
|
|
|
ac7d03 |
ipalib/install/hostname.py | 2 +-
|
|
|
ac7d03 |
ipalib/util.py | 14 +++++++
|
|
|
ac7d03 |
ipapython/ipautil.py | 62 ++++++++++++++++--------------
|
|
|
ac7d03 |
ipaserver/install/dns.py | 1 +
|
|
|
ac7d03 |
ipaserver/install/installutils.py | 4 +-
|
|
|
ac7d03 |
ipaserver/install/server/install.py | 2 +
|
|
|
ac7d03 |
ipaserver/install/server/replicainstall.py | 2 +
|
|
|
ac7d03 |
8 files changed, 59 insertions(+), 32 deletions(-)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
|
|
|
ac7d03 |
index 6f10f5258747881b9af8c6b70b499f9ff7d577ff..41dae3004d1f4836e79c2048ae0a12f722595ca0 100644
|
|
|
ac7d03 |
--- a/ipaclient/install/client.py
|
|
|
ac7d03 |
+++ b/ipaclient/install/client.py
|
|
|
ac7d03 |
@@ -41,6 +41,7 @@ from ipalib.util import (
|
|
|
ac7d03 |
broadcast_ip_address_warning,
|
|
|
ac7d03 |
network_ip_address_warning,
|
|
|
ac7d03 |
normalize_hostname,
|
|
|
ac7d03 |
+ no_matching_interface_for_ip_address_warning,
|
|
|
ac7d03 |
verify_host_resolvable,
|
|
|
ac7d03 |
)
|
|
|
ac7d03 |
from ipaplatform import services
|
|
|
ac7d03 |
@@ -1300,6 +1301,7 @@ def update_dns(server, hostname, options):
|
|
|
ac7d03 |
|
|
|
ac7d03 |
network_ip_address_warning(update_ips)
|
|
|
ac7d03 |
broadcast_ip_address_warning(update_ips)
|
|
|
ac7d03 |
+ no_matching_interface_for_ip_address_warning(update_ips)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
update_txt = "debug\n"
|
|
|
ac7d03 |
update_txt += ipautil.template_str(DELETE_TEMPLATE_A,
|
|
|
ac7d03 |
@@ -1445,7 +1447,7 @@ def check_ip_addresses(options):
|
|
|
ac7d03 |
if options.ip_addresses:
|
|
|
ac7d03 |
for ip in options.ip_addresses:
|
|
|
ac7d03 |
try:
|
|
|
ac7d03 |
- ipautil.CheckedIPAddress(ip, match_local=True)
|
|
|
ac7d03 |
+ ipautil.CheckedIPAddress(ip)
|
|
|
ac7d03 |
except ValueError as e:
|
|
|
ac7d03 |
root_logger.error(e)
|
|
|
ac7d03 |
return False
|
|
|
ac7d03 |
diff --git a/ipalib/install/hostname.py b/ipalib/install/hostname.py
|
|
|
ac7d03 |
index 74c569d972df9975d677762b5769b2bf84dfddf0..5422ba6390ce13aa40f34938ed777d8821e8231b 100644
|
|
|
ac7d03 |
--- a/ipalib/install/hostname.py
|
|
|
ac7d03 |
+++ b/ipalib/install/hostname.py
|
|
|
ac7d03 |
@@ -34,7 +34,7 @@ class HostNameInstallInterface(service.ServiceInstallInterface):
|
|
|
ac7d03 |
def ip_addresses(self, values):
|
|
|
ac7d03 |
for value in values:
|
|
|
ac7d03 |
try:
|
|
|
ac7d03 |
- CheckedIPAddress(value, match_local=True)
|
|
|
ac7d03 |
+ CheckedIPAddress(value)
|
|
|
ac7d03 |
except Exception as e:
|
|
|
ac7d03 |
raise ValueError("invalid IP address {0}: {1}".format(
|
|
|
ac7d03 |
value, e))
|
|
|
ac7d03 |
diff --git a/ipalib/util.py b/ipalib/util.py
|
|
|
ac7d03 |
index 713fc107e9374eefe7805bc4e1abc40b6d150c32..1bd8495a49b010e7a3ac926dad516ab5f8219b39 100644
|
|
|
ac7d03 |
--- a/ipalib/util.py
|
|
|
ac7d03 |
+++ b/ipalib/util.py
|
|
|
ac7d03 |
@@ -1128,3 +1128,17 @@ def broadcast_ip_address_warning(addr_list):
|
|
|
ac7d03 |
# print
|
|
|
ac7d03 |
print("WARNING: IP address {} might be broadcast address".format(
|
|
|
ac7d03 |
ip), file=sys.stderr)
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+def no_matching_interface_for_ip_address_warning(addr_list):
|
|
|
ac7d03 |
+ for ip in addr_list:
|
|
|
ac7d03 |
+ if not ip.get_matching_interface():
|
|
|
ac7d03 |
+ root_logger.warning(
|
|
|
ac7d03 |
+ "No network interface matches the IP address %s", ip)
|
|
|
ac7d03 |
+ # fixme: once when loggers will be fixed, we can remove this
|
|
|
ac7d03 |
+ # print
|
|
|
ac7d03 |
+ print(
|
|
|
ac7d03 |
+ "WARNING: No network interface matches the IP address "
|
|
|
ac7d03 |
+ "{}".format(ip),
|
|
|
ac7d03 |
+ file=sys.stderr
|
|
|
ac7d03 |
+ )
|
|
|
ac7d03 |
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
|
|
|
ac7d03 |
index 317fc225b722ad3ce2f4b9d92822b4f19d49adb9..a277ed87473f3c591f34fcc00e1159f3bbfe3e9b 100644
|
|
|
ac7d03 |
--- a/ipapython/ipautil.py
|
|
|
ac7d03 |
+++ b/ipapython/ipautil.py
|
|
|
ac7d03 |
@@ -161,34 +161,7 @@ class CheckedIPAddress(UnsafeIPAddress):
|
|
|
ac7d03 |
raise ValueError("cannot use multicast IP address {}".format(addr))
|
|
|
ac7d03 |
|
|
|
ac7d03 |
if match_local:
|
|
|
ac7d03 |
- if self.version == 4:
|
|
|
ac7d03 |
- family = netifaces.AF_INET
|
|
|
ac7d03 |
- elif self.version == 6:
|
|
|
ac7d03 |
- family = netifaces.AF_INET6
|
|
|
ac7d03 |
- else:
|
|
|
ac7d03 |
- raise ValueError(
|
|
|
ac7d03 |
- "Unsupported address family ({})".format(self.version)
|
|
|
ac7d03 |
- )
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- iface = None
|
|
|
ac7d03 |
- for interface in netifaces.interfaces():
|
|
|
ac7d03 |
- for ifdata in netifaces.ifaddresses(interface).get(family, []):
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- # link-local addresses contain '%suffix' that causes parse
|
|
|
ac7d03 |
- # errors in IPNetwork
|
|
|
ac7d03 |
- ifaddr = ifdata['addr'].split(u'%', 1)[0]
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- ifnet = netaddr.IPNetwork('{addr}/{netmask}'.format(
|
|
|
ac7d03 |
- addr=ifaddr,
|
|
|
ac7d03 |
- netmask=ifdata['netmask']
|
|
|
ac7d03 |
- ))
|
|
|
ac7d03 |
- if ifnet == self._net or (
|
|
|
ac7d03 |
- self._net is None and ifnet.ip == self):
|
|
|
ac7d03 |
- self._net = ifnet
|
|
|
ac7d03 |
- iface = interface
|
|
|
ac7d03 |
- break
|
|
|
ac7d03 |
-
|
|
|
ac7d03 |
- if iface is None:
|
|
|
ac7d03 |
+ if not self.get_matching_interface():
|
|
|
ac7d03 |
raise ValueError('no network interface matches the IP address '
|
|
|
ac7d03 |
'and netmask {}'.format(addr))
|
|
|
ac7d03 |
|
|
|
ac7d03 |
@@ -218,6 +191,39 @@ class CheckedIPAddress(UnsafeIPAddress):
|
|
|
ac7d03 |
def is_broadcast_addr(self):
|
|
|
ac7d03 |
return self.version == 4 and self == self._net.broadcast
|
|
|
ac7d03 |
|
|
|
ac7d03 |
+ def get_matching_interface(self):
|
|
|
ac7d03 |
+ """Find matching local interface for address
|
|
|
ac7d03 |
+ :return: Interface name or None if no interface has this address
|
|
|
ac7d03 |
+ """
|
|
|
ac7d03 |
+ if self.version == 4:
|
|
|
ac7d03 |
+ family = netifaces.AF_INET
|
|
|
ac7d03 |
+ elif self.version == 6:
|
|
|
ac7d03 |
+ family = netifaces.AF_INET6
|
|
|
ac7d03 |
+ else:
|
|
|
ac7d03 |
+ raise ValueError(
|
|
|
ac7d03 |
+ "Unsupported address family ({})".format(self.version)
|
|
|
ac7d03 |
+ )
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ iface = None
|
|
|
ac7d03 |
+ for interface in netifaces.interfaces():
|
|
|
ac7d03 |
+ for ifdata in netifaces.ifaddresses(interface).get(family, []):
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ # link-local addresses contain '%suffix' that causes parse
|
|
|
ac7d03 |
+ # errors in IPNetwork
|
|
|
ac7d03 |
+ ifaddr = ifdata['addr'].split(u'%', 1)[0]
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ifnet = netaddr.IPNetwork('{addr}/{netmask}'.format(
|
|
|
ac7d03 |
+ addr=ifaddr,
|
|
|
ac7d03 |
+ netmask=ifdata['netmask']
|
|
|
ac7d03 |
+ ))
|
|
|
ac7d03 |
+ if ifnet == self._net or (
|
|
|
ac7d03 |
+ self._net is None and ifnet.ip == self):
|
|
|
ac7d03 |
+ self._net = ifnet
|
|
|
ac7d03 |
+ iface = interface
|
|
|
ac7d03 |
+ break
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ return iface
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
|
|
|
ac7d03 |
def valid_ip(addr):
|
|
|
ac7d03 |
return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
|
|
|
ac7d03 |
diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
|
|
|
ac7d03 |
index 0dddf2a6427f3f939171d755bfe2b1f05cfafa67..090b79493652566a433da248fa7fd9e33dd2cb72 100644
|
|
|
ac7d03 |
--- a/ipaserver/install/dns.py
|
|
|
ac7d03 |
+++ b/ipaserver/install/dns.py
|
|
|
ac7d03 |
@@ -266,6 +266,7 @@ def install_check(standalone, api, replica, options, hostname):
|
|
|
ac7d03 |
|
|
|
ac7d03 |
util.network_ip_address_warning(ip_addresses)
|
|
|
ac7d03 |
util.broadcast_ip_address_warning(ip_addresses)
|
|
|
ac7d03 |
+ util.no_matching_interface_for_ip_address_warning(ip_addresses)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
if not options.forward_policy:
|
|
|
ac7d03 |
# user did not specify policy, derive it: default is 'first' but
|
|
|
ac7d03 |
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
|
|
|
ac7d03 |
index d2283af20485fd5d66bfd3cc49059d08d1802575..3521d555914714351160213df60ed9167ac6e370 100644
|
|
|
ac7d03 |
--- a/ipaserver/install/installutils.py
|
|
|
ac7d03 |
+++ b/ipaserver/install/installutils.py
|
|
|
ac7d03 |
@@ -276,7 +276,7 @@ def read_ip_addresses():
|
|
|
ac7d03 |
if not ip:
|
|
|
ac7d03 |
break
|
|
|
ac7d03 |
try:
|
|
|
ac7d03 |
- ip_parsed = ipautil.CheckedIPAddress(ip, match_local=True)
|
|
|
ac7d03 |
+ ip_parsed = ipautil.CheckedIPAddress(ip)
|
|
|
ac7d03 |
except Exception as e:
|
|
|
ac7d03 |
print("Error: Invalid IP Address %s: %s" % (ip, e))
|
|
|
ac7d03 |
continue
|
|
|
ac7d03 |
@@ -585,7 +585,7 @@ def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
|
|
|
ac7d03 |
if len(hostaddr):
|
|
|
ac7d03 |
for ha in hostaddr:
|
|
|
ac7d03 |
try:
|
|
|
ac7d03 |
- ips.append(ipautil.CheckedIPAddress(ha, match_local=True))
|
|
|
ac7d03 |
+ ips.append(ipautil.CheckedIPAddress(ha, match_local=False))
|
|
|
ac7d03 |
except ValueError as e:
|
|
|
ac7d03 |
root_logger.warning("Invalid IP address %s for %s: %s", ha, host_name, unicode(e))
|
|
|
ac7d03 |
|
|
|
ac7d03 |
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
|
|
|
ac7d03 |
index 9dcf903f4582740f007c049fae3ec247ddf52aef..7eb291e07c00e0407ce534c3d4088e6f6378260f 100644
|
|
|
ac7d03 |
--- a/ipaserver/install/server/install.py
|
|
|
ac7d03 |
+++ b/ipaserver/install/server/install.py
|
|
|
ac7d03 |
@@ -29,6 +29,7 @@ from ipalib.util import (
|
|
|
ac7d03 |
validate_domain_name,
|
|
|
ac7d03 |
network_ip_address_warning,
|
|
|
ac7d03 |
broadcast_ip_address_warning,
|
|
|
ac7d03 |
+ no_matching_interface_for_ip_address_warning,
|
|
|
ac7d03 |
)
|
|
|
ac7d03 |
import ipaclient.install.ntpconf
|
|
|
ac7d03 |
from ipaserver.install import (
|
|
|
ac7d03 |
@@ -617,6 +618,7 @@ def install_check(installer):
|
|
|
ac7d03 |
# check addresses here, dns module is doing own check
|
|
|
ac7d03 |
network_ip_address_warning(ip_addresses)
|
|
|
ac7d03 |
broadcast_ip_address_warning(ip_addresses)
|
|
|
ac7d03 |
+ no_matching_interface_for_ip_address_warning(ip_addresses)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
if options.setup_adtrust:
|
|
|
ac7d03 |
adtrust.install_check(False, options, api)
|
|
|
ac7d03 |
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
|
|
|
ac7d03 |
index 20eaf98397101b49c751c325afc0591e0babcc18..6620f0222f9d38112ce0d0fd72381e5673921cba 100644
|
|
|
ac7d03 |
--- a/ipaserver/install/server/replicainstall.py
|
|
|
ac7d03 |
+++ b/ipaserver/install/server/replicainstall.py
|
|
|
ac7d03 |
@@ -35,6 +35,7 @@ from ipalib.config import Env
|
|
|
ac7d03 |
from ipalib.util import (
|
|
|
ac7d03 |
network_ip_address_warning,
|
|
|
ac7d03 |
broadcast_ip_address_warning,
|
|
|
ac7d03 |
+ no_matching_interface_for_ip_address_warning,
|
|
|
ac7d03 |
)
|
|
|
ac7d03 |
from ipaclient.install.client import configure_krb5_conf, purge_host_keytab
|
|
|
ac7d03 |
from ipaserver.install import (
|
|
|
ac7d03 |
@@ -1285,6 +1286,7 @@ def promote_check(installer):
|
|
|
ac7d03 |
# check addresses here, dns module is doing own check
|
|
|
ac7d03 |
network_ip_address_warning(config.ips)
|
|
|
ac7d03 |
broadcast_ip_address_warning(config.ips)
|
|
|
ac7d03 |
+ no_matching_interface_for_ip_address_warning(config.ips)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
if options.setup_adtrust:
|
|
|
ac7d03 |
adtrust.install_check(False, options, remote_api)
|
|
|
ac7d03 |
--
|
|
|
ac7d03 |
2.9.4
|
|
|
ac7d03 |
|