mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Only warn when specified server IP addresses don't match intf
In containers local addresses differ from public addresses and we need a way to provide only public address to installers. https://pagure.io/freeipa/issue/2715 https://pagure.io/freeipa/issue/4317 Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
This commit is contained in:
parent
566361e63d
commit
6637980af6
@ -41,6 +41,7 @@ from ipalib.util import (
|
|||||||
broadcast_ip_address_warning,
|
broadcast_ip_address_warning,
|
||||||
network_ip_address_warning,
|
network_ip_address_warning,
|
||||||
normalize_hostname,
|
normalize_hostname,
|
||||||
|
no_matching_interface_for_ip_address_warning,
|
||||||
verify_host_resolvable,
|
verify_host_resolvable,
|
||||||
)
|
)
|
||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
@ -1300,6 +1301,7 @@ def update_dns(server, hostname, options):
|
|||||||
|
|
||||||
network_ip_address_warning(update_ips)
|
network_ip_address_warning(update_ips)
|
||||||
broadcast_ip_address_warning(update_ips)
|
broadcast_ip_address_warning(update_ips)
|
||||||
|
no_matching_interface_for_ip_address_warning(update_ips)
|
||||||
|
|
||||||
update_txt = "debug\n"
|
update_txt = "debug\n"
|
||||||
update_txt += ipautil.template_str(DELETE_TEMPLATE_A,
|
update_txt += ipautil.template_str(DELETE_TEMPLATE_A,
|
||||||
@ -1445,7 +1447,7 @@ def check_ip_addresses(options):
|
|||||||
if options.ip_addresses:
|
if options.ip_addresses:
|
||||||
for ip in options.ip_addresses:
|
for ip in options.ip_addresses:
|
||||||
try:
|
try:
|
||||||
ipautil.CheckedIPAddress(ip, match_local=True)
|
ipautil.CheckedIPAddress(ip)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
root_logger.error(e)
|
root_logger.error(e)
|
||||||
return False
|
return False
|
||||||
|
@ -34,7 +34,7 @@ class HostNameInstallInterface(service.ServiceInstallInterface):
|
|||||||
def ip_addresses(self, values):
|
def ip_addresses(self, values):
|
||||||
for value in values:
|
for value in values:
|
||||||
try:
|
try:
|
||||||
CheckedIPAddress(value, match_local=True)
|
CheckedIPAddress(value)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError("invalid IP address {0}: {1}".format(
|
raise ValueError("invalid IP address {0}: {1}".format(
|
||||||
value, e))
|
value, e))
|
||||||
|
@ -1128,3 +1128,17 @@ def broadcast_ip_address_warning(addr_list):
|
|||||||
# print
|
# print
|
||||||
print("WARNING: IP address {} might be broadcast address".format(
|
print("WARNING: IP address {} might be broadcast address".format(
|
||||||
ip), file=sys.stderr)
|
ip), file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def no_matching_interface_for_ip_address_warning(addr_list):
|
||||||
|
for ip in addr_list:
|
||||||
|
if not ip.get_matching_interface():
|
||||||
|
root_logger.warning(
|
||||||
|
"No network interface matches the IP address %s", ip)
|
||||||
|
# fixme: once when loggers will be fixed, we can remove this
|
||||||
|
# print
|
||||||
|
print(
|
||||||
|
"WARNING: No network interface matches the IP address "
|
||||||
|
"{}".format(ip),
|
||||||
|
file=sys.stderr
|
||||||
|
)
|
||||||
|
@ -161,34 +161,7 @@ class CheckedIPAddress(UnsafeIPAddress):
|
|||||||
raise ValueError("cannot use multicast IP address {}".format(addr))
|
raise ValueError("cannot use multicast IP address {}".format(addr))
|
||||||
|
|
||||||
if match_local:
|
if match_local:
|
||||||
if self.version == 4:
|
if not self.get_matching_interface():
|
||||||
family = netifaces.AF_INET
|
|
||||||
elif self.version == 6:
|
|
||||||
family = netifaces.AF_INET6
|
|
||||||
else:
|
|
||||||
raise ValueError(
|
|
||||||
"Unsupported address family ({})".format(self.version)
|
|
||||||
)
|
|
||||||
|
|
||||||
iface = None
|
|
||||||
for interface in netifaces.interfaces():
|
|
||||||
for ifdata in netifaces.ifaddresses(interface).get(family, []):
|
|
||||||
|
|
||||||
# link-local addresses contain '%suffix' that causes parse
|
|
||||||
# errors in IPNetwork
|
|
||||||
ifaddr = ifdata['addr'].split(u'%', 1)[0]
|
|
||||||
|
|
||||||
ifnet = netaddr.IPNetwork('{addr}/{netmask}'.format(
|
|
||||||
addr=ifaddr,
|
|
||||||
netmask=ifdata['netmask']
|
|
||||||
))
|
|
||||||
if ifnet == self._net or (
|
|
||||||
self._net is None and ifnet.ip == self):
|
|
||||||
self._net = ifnet
|
|
||||||
iface = interface
|
|
||||||
break
|
|
||||||
|
|
||||||
if iface is None:
|
|
||||||
raise ValueError('no network interface matches the IP address '
|
raise ValueError('no network interface matches the IP address '
|
||||||
'and netmask {}'.format(addr))
|
'and netmask {}'.format(addr))
|
||||||
|
|
||||||
@ -218,6 +191,39 @@ class CheckedIPAddress(UnsafeIPAddress):
|
|||||||
def is_broadcast_addr(self):
|
def is_broadcast_addr(self):
|
||||||
return self.version == 4 and self == self._net.broadcast
|
return self.version == 4 and self == self._net.broadcast
|
||||||
|
|
||||||
|
def get_matching_interface(self):
|
||||||
|
"""Find matching local interface for address
|
||||||
|
:return: Interface name or None if no interface has this address
|
||||||
|
"""
|
||||||
|
if self.version == 4:
|
||||||
|
family = netifaces.AF_INET
|
||||||
|
elif self.version == 6:
|
||||||
|
family = netifaces.AF_INET6
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"Unsupported address family ({})".format(self.version)
|
||||||
|
)
|
||||||
|
|
||||||
|
iface = None
|
||||||
|
for interface in netifaces.interfaces():
|
||||||
|
for ifdata in netifaces.ifaddresses(interface).get(family, []):
|
||||||
|
|
||||||
|
# link-local addresses contain '%suffix' that causes parse
|
||||||
|
# errors in IPNetwork
|
||||||
|
ifaddr = ifdata['addr'].split(u'%', 1)[0]
|
||||||
|
|
||||||
|
ifnet = netaddr.IPNetwork('{addr}/{netmask}'.format(
|
||||||
|
addr=ifaddr,
|
||||||
|
netmask=ifdata['netmask']
|
||||||
|
))
|
||||||
|
if ifnet == self._net or (
|
||||||
|
self._net is None and ifnet.ip == self):
|
||||||
|
self._net = ifnet
|
||||||
|
iface = interface
|
||||||
|
break
|
||||||
|
|
||||||
|
return iface
|
||||||
|
|
||||||
|
|
||||||
def valid_ip(addr):
|
def valid_ip(addr):
|
||||||
return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
|
return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
|
||||||
|
@ -266,6 +266,7 @@ def install_check(standalone, api, replica, options, hostname):
|
|||||||
|
|
||||||
util.network_ip_address_warning(ip_addresses)
|
util.network_ip_address_warning(ip_addresses)
|
||||||
util.broadcast_ip_address_warning(ip_addresses)
|
util.broadcast_ip_address_warning(ip_addresses)
|
||||||
|
util.no_matching_interface_for_ip_address_warning(ip_addresses)
|
||||||
|
|
||||||
if not options.forward_policy:
|
if not options.forward_policy:
|
||||||
# user did not specify policy, derive it: default is 'first' but
|
# user did not specify policy, derive it: default is 'first' but
|
||||||
|
@ -281,7 +281,7 @@ def read_ip_addresses():
|
|||||||
if not ip:
|
if not ip:
|
||||||
break
|
break
|
||||||
try:
|
try:
|
||||||
ip_parsed = ipautil.CheckedIPAddress(ip, match_local=True)
|
ip_parsed = ipautil.CheckedIPAddress(ip)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error: Invalid IP Address %s: %s" % (ip, e))
|
print("Error: Invalid IP Address %s: %s" % (ip, e))
|
||||||
continue
|
continue
|
||||||
@ -590,7 +590,7 @@ def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses):
|
|||||||
if len(hostaddr):
|
if len(hostaddr):
|
||||||
for ha in hostaddr:
|
for ha in hostaddr:
|
||||||
try:
|
try:
|
||||||
ips.append(ipautil.CheckedIPAddress(ha, match_local=True))
|
ips.append(ipautil.CheckedIPAddress(ha, match_local=False))
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
root_logger.warning("Invalid IP address %s for %s: %s", ha, host_name, unicode(e))
|
root_logger.warning("Invalid IP address %s for %s: %s", ha, host_name, unicode(e))
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ from ipalib.util import (
|
|||||||
validate_domain_name,
|
validate_domain_name,
|
||||||
network_ip_address_warning,
|
network_ip_address_warning,
|
||||||
broadcast_ip_address_warning,
|
broadcast_ip_address_warning,
|
||||||
|
no_matching_interface_for_ip_address_warning,
|
||||||
)
|
)
|
||||||
import ipaclient.install.ntpconf
|
import ipaclient.install.ntpconf
|
||||||
from ipaserver.install import (
|
from ipaserver.install import (
|
||||||
@ -617,6 +618,7 @@ def install_check(installer):
|
|||||||
# check addresses here, dns module is doing own check
|
# check addresses here, dns module is doing own check
|
||||||
network_ip_address_warning(ip_addresses)
|
network_ip_address_warning(ip_addresses)
|
||||||
broadcast_ip_address_warning(ip_addresses)
|
broadcast_ip_address_warning(ip_addresses)
|
||||||
|
no_matching_interface_for_ip_address_warning(ip_addresses)
|
||||||
|
|
||||||
if options.setup_adtrust:
|
if options.setup_adtrust:
|
||||||
adtrust.install_check(False, options, api)
|
adtrust.install_check(False, options, api)
|
||||||
|
@ -35,6 +35,7 @@ from ipalib.config import Env
|
|||||||
from ipalib.util import (
|
from ipalib.util import (
|
||||||
network_ip_address_warning,
|
network_ip_address_warning,
|
||||||
broadcast_ip_address_warning,
|
broadcast_ip_address_warning,
|
||||||
|
no_matching_interface_for_ip_address_warning,
|
||||||
)
|
)
|
||||||
from ipaclient.install.client import configure_krb5_conf, purge_host_keytab
|
from ipaclient.install.client import configure_krb5_conf, purge_host_keytab
|
||||||
from ipaserver.install import (
|
from ipaserver.install import (
|
||||||
@ -1285,6 +1286,7 @@ def promote_check(installer):
|
|||||||
# check addresses here, dns module is doing own check
|
# check addresses here, dns module is doing own check
|
||||||
network_ip_address_warning(config.ips)
|
network_ip_address_warning(config.ips)
|
||||||
broadcast_ip_address_warning(config.ips)
|
broadcast_ip_address_warning(config.ips)
|
||||||
|
no_matching_interface_for_ip_address_warning(config.ips)
|
||||||
|
|
||||||
if options.setup_adtrust:
|
if options.setup_adtrust:
|
||||||
adtrust.install_check(False, options, remote_api)
|
adtrust.install_check(False, options, remote_api)
|
||||||
|
Loading…
Reference in New Issue
Block a user