mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-03 12:11:25 -06:00
Replace netifaces with ifaddr
Python netifaces has been unmaintained and its main repository has been archived since June, 2021. Python ifaddr is an alternative to netifaces, is currently maintained, and provides an API which requires little change for FreeIPA current usage. This patch modifies FreeIPA to rely on ifaddr instead of neitfaces, due to its current maintainance status. Fixes: https://pagure.io/freeipa/issue/9555 Signed-off-by: Rafael Guterres Jeffman <rjeffman@redhat.com> Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
parent
cce8dc4da8
commit
6c6b9354b5
@ -120,7 +120,7 @@ extraction:
|
||||
- lxml
|
||||
- gssapi
|
||||
- netaddr
|
||||
- netifaces
|
||||
- ifaddr
|
||||
- polib
|
||||
- requests
|
||||
- python-augeas
|
||||
|
@ -11,6 +11,7 @@ m2r2
|
||||
## ipa dependencies
|
||||
dnspython
|
||||
jwcrypto
|
||||
ifaddr
|
||||
netaddr
|
||||
qrcode
|
||||
six
|
||||
|
@ -403,7 +403,7 @@ BuildRequires: python3-libipa_hbac
|
||||
BuildRequires: python3-libsss_nss_idmap
|
||||
BuildRequires: python3-lxml
|
||||
BuildRequires: python3-netaddr >= %{python_netaddr_version}
|
||||
BuildRequires: python3-netifaces
|
||||
BuildRequires: python3-ifaddr
|
||||
BuildRequires: python3-pki >= %{pki_version}
|
||||
BuildRequires: python3-polib
|
||||
BuildRequires: python3-pyasn1
|
||||
@ -885,7 +885,7 @@ Requires: python3-gssapi >= 1.2.0
|
||||
Requires: python3-jwcrypto >= 0.4.2
|
||||
Requires: python3-libipa_hbac
|
||||
Requires: python3-netaddr >= %{python_netaddr_version}
|
||||
Requires: python3-netifaces >= 0.10.4
|
||||
Requires: python3-ifaddr
|
||||
Requires: python3-pyasn1 >= 0.3.2-2
|
||||
Requires: python3-pyasn1-modules >= 0.3.2-2
|
||||
Requires: python3-pyusb
|
||||
|
@ -18,7 +18,7 @@ import logging
|
||||
import dns
|
||||
import getpass
|
||||
import gssapi
|
||||
import netifaces
|
||||
import ifaddr
|
||||
import os
|
||||
import re
|
||||
import SSSDConfig
|
||||
@ -1351,31 +1351,36 @@ def unconfigure_nisdomain(statestore):
|
||||
|
||||
|
||||
def get_iface_from_ip(ip_addr):
|
||||
for interface in netifaces.interfaces():
|
||||
if_addrs = netifaces.ifaddresses(interface)
|
||||
for family in [netifaces.AF_INET, netifaces.AF_INET6]:
|
||||
for ip in if_addrs.get(family, []):
|
||||
if ip['addr'] == ip_addr:
|
||||
return interface
|
||||
for adapter in ifaddr.get_adapters():
|
||||
for ips in adapter.ips:
|
||||
# IPv6 is reported as a tuple, IPv4 is reported as str
|
||||
if ip_addr in (ips.ip[0], ips.ip):
|
||||
return adapter.name
|
||||
raise RuntimeError("IP %s not assigned to any interface." % ip_addr)
|
||||
|
||||
|
||||
def get_local_ipaddresses(iface=None):
|
||||
def __get_ifaddr_adapters(iface=None):
|
||||
if iface:
|
||||
interfaces = [iface]
|
||||
interfaces = set(iface if isinstance(iface, (list, tuple)) else [iface])
|
||||
else:
|
||||
interfaces = netifaces.interfaces()
|
||||
interfaces = set(adapter.name for adapter in ifaddr.get_adapters())
|
||||
return [
|
||||
adapter
|
||||
for adapter in ifaddr.get_adapters()
|
||||
if adapter.name in interfaces or adapter.nice_name in interfaces
|
||||
]
|
||||
|
||||
|
||||
def get_local_ipaddresses(iface=None):
|
||||
ips = []
|
||||
for interface in interfaces:
|
||||
if_addrs = netifaces.ifaddresses(interface)
|
||||
for family in [netifaces.AF_INET, netifaces.AF_INET6]:
|
||||
for ip in if_addrs.get(family, []):
|
||||
try:
|
||||
ips.append(ipautil.CheckedIPAddress(ip['addr']))
|
||||
logger.debug('IP check successful: %s', ip['addr'])
|
||||
except ValueError as e:
|
||||
logger.debug('IP check failed: %s', e)
|
||||
for adapter in __get_ifaddr_adapters(iface):
|
||||
for ifip in adapter.ips:
|
||||
try:
|
||||
ip_addr = ifip.ip[0] if isinstance(ifip.ip, tuple) else ifip.ip
|
||||
ips.append(ipautil.CheckedIPAddress(ip_addr))
|
||||
logger.debug('IP check successful: %s', ip_addr)
|
||||
except ValueError as e:
|
||||
logger.debug('IP check failed: %s', e)
|
||||
return ips
|
||||
|
||||
|
||||
|
@ -48,9 +48,9 @@ import six
|
||||
from six.moves import input
|
||||
|
||||
try:
|
||||
import netifaces
|
||||
import ifaddr
|
||||
except ImportError:
|
||||
netifaces = None
|
||||
ifaddr = None
|
||||
|
||||
from ipapython.dn import DN
|
||||
from ipaplatform.paths import paths
|
||||
@ -203,42 +203,37 @@ class CheckedIPAddress(UnsafeIPAddress):
|
||||
:return: InterfaceDetails named tuple or None if no interface has
|
||||
this address
|
||||
"""
|
||||
if netifaces is None:
|
||||
raise ImportError("netifaces")
|
||||
if ifaddr is None:
|
||||
raise ImportError("ifaddr")
|
||||
logger.debug("Searching for an interface of IP address: %s", self)
|
||||
|
||||
if self.version == 4:
|
||||
family = netifaces.AF_INET
|
||||
family_ips = (
|
||||
(ip.ip, ip.network_prefix, ip.nice_name)
|
||||
for ips in [a.ips for a in ifaddr.get_adapters()]
|
||||
for ip in ips if not isinstance(ip.ip, tuple)
|
||||
)
|
||||
elif self.version == 6:
|
||||
family = netifaces.AF_INET6
|
||||
family_ips = (
|
||||
(ip.ip[0], ip.network_prefix, ip.nice_name)
|
||||
for ips in [a.ips for a in ifaddr.get_adapters()]
|
||||
for ip in ips if isinstance(ip.ip, tuple)
|
||||
)
|
||||
else:
|
||||
raise ValueError(
|
||||
"Unsupported address family ({})".format(self.version)
|
||||
)
|
||||
|
||||
for interface in netifaces.interfaces():
|
||||
for ifdata in netifaces.ifaddresses(interface).get(family, []):
|
||||
for ip, prefix, ifname in family_ips:
|
||||
ifaddrmask = "{ip}/{prefix}".format(ip=ip, prefix=prefix)
|
||||
logger.debug(
|
||||
"Testing local IP address: %s (interface: %s)",
|
||||
ifaddrmask, ifname)
|
||||
ifnet = netaddr.IPNetwork(ifaddrmask)
|
||||
|
||||
# link-local addresses contain '%suffix' that causes parse
|
||||
# errors in IPNetwork
|
||||
ifaddr = ifdata['addr'].split(u'%', 1)[0]
|
||||
if ifnet.ip == self:
|
||||
return InterfaceDetails(ifname, ifnet)
|
||||
|
||||
# newer versions of netifaces provide IPv6 netmask in format
|
||||
# 'ffff:ffff:ffff:ffff::/64'. We have to split and use prefix
|
||||
# or the netmask with older versions
|
||||
ifmask = ifdata['netmask'].split(u'/')[-1]
|
||||
|
||||
ifaddrmask = '{addr}/{netmask}'.format(
|
||||
addr=ifaddr,
|
||||
netmask=ifmask
|
||||
)
|
||||
logger.debug(
|
||||
"Testing local IP address: %s (interface: %s)",
|
||||
ifaddrmask, interface)
|
||||
|
||||
ifnet = netaddr.IPNetwork(ifaddrmask)
|
||||
|
||||
if ifnet.ip == self:
|
||||
return InterfaceDetails(interface, ifnet)
|
||||
return None
|
||||
|
||||
def set_ip_net(self, ifnet):
|
||||
|
@ -48,6 +48,6 @@ if __name__ == '__main__':
|
||||
extras_require={
|
||||
"ldap": ["python-ldap"], # ipapython.ipaldap
|
||||
# CheckedIPAddress.get_matching_interface
|
||||
"netifaces": ["netifaces"],
|
||||
"ifaddr": ["ifaddr"],
|
||||
},
|
||||
)
|
||||
|
@ -75,7 +75,7 @@ PACKAGE_VERSION = {
|
||||
'ipaserver': 'ipaserver == {}'.format(VERSION),
|
||||
'jwcrypto': 'jwcrypto >= 0.4.2',
|
||||
'kdcproxy': 'kdcproxy >= 0.3',
|
||||
'netifaces': 'netifaces >= 0.10.4',
|
||||
'ifaddr': 'ifaddr >= 0.1.7',
|
||||
'python-ldap': 'python-ldap >= 3.0.0',
|
||||
'python-yubico': 'python-yubico >= 1.2.3',
|
||||
'qrcode': 'qrcode >= 5.0',
|
||||
|
Loading…
Reference in New Issue
Block a user