mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Use netifaces module instead of 'ip' command
Netifaces allows to get addresses from local interfaces of the host in safer way than parsing output of the ip command. https://fedorahosted.org/freeipa/ticket/5591 Reviewed-By: David Kupka <dkupka@redhat.com>
This commit is contained in:
parent
62bb478e11
commit
70fd78928c
@ -33,6 +33,7 @@ try:
|
||||
from optparse import SUPPRESS_HELP, OptionGroup, OptionValueError
|
||||
import dns
|
||||
import gssapi
|
||||
import netifaces
|
||||
|
||||
import nss.nss as nss
|
||||
import SSSDConfig
|
||||
@ -1526,39 +1527,31 @@ def unconfigure_nisdomain():
|
||||
|
||||
|
||||
def get_iface_from_ip(ip_addr):
|
||||
result = ipautil.run([paths.IP, '-oneline', 'address', 'show'],
|
||||
capture_output=True)
|
||||
for line in result.output.split('\n'):
|
||||
fields = line.split()
|
||||
if len(fields) < 6:
|
||||
continue
|
||||
if fields[2] not in ['inet', 'inet6']:
|
||||
continue
|
||||
(ip, mask) = fields[3].rsplit('/', 1)
|
||||
if ip == ip_addr:
|
||||
return fields[1]
|
||||
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
|
||||
else:
|
||||
raise RuntimeError("IP %s not assigned to any interface." % ip_addr)
|
||||
|
||||
|
||||
def get_local_ipaddresses(iface=None):
|
||||
args = [paths.IP, '-oneline', 'address', 'show']
|
||||
if iface:
|
||||
args += ['dev', iface]
|
||||
result = ipautil.run(args, capture_output=True)
|
||||
lines = result.output.split('\n')
|
||||
interfaces = [iface]
|
||||
else:
|
||||
interfaces = netifaces.interfaces()
|
||||
|
||||
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:
|
||||
ips.append(ipautil.CheckedIPAddress(ip))
|
||||
except ValueError:
|
||||
continue
|
||||
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']))
|
||||
except ValueError:
|
||||
continue
|
||||
return ips
|
||||
|
||||
|
||||
|
@ -103,6 +103,7 @@ BuildRequires: python-jwcrypto
|
||||
BuildRequires: custodia
|
||||
BuildRequires: libini_config-devel >= 1.2.0
|
||||
BuildRequires: dbus-python
|
||||
BuildRequires: python-netifaces >= 0.10.4
|
||||
|
||||
# Build dependencies for unit tests
|
||||
BuildRequires: libcmocka-devel
|
||||
@ -478,7 +479,6 @@ Provides: python2-ipaplatform = %{version}-%{release}
|
||||
Requires: %{name}-common = %{version}-%{release}
|
||||
Requires: python-gssapi >= 1.1.2
|
||||
Requires: gnupg
|
||||
Requires: iproute
|
||||
Requires: keyutils
|
||||
Requires: pyOpenSSL
|
||||
Requires: python-nss >= 0.16
|
||||
@ -500,6 +500,7 @@ Requires: python-ldap >= 2.4.15
|
||||
Requires: python-requests
|
||||
Requires: python-custodia
|
||||
Requires: python-dns >= 1.11.1
|
||||
Requires: python-netifaces >= 0.10.4
|
||||
|
||||
Conflicts: %{alt_name}-python < %{version}
|
||||
|
||||
@ -526,7 +527,6 @@ Provides: python3-ipaplatform = %{version}-%{release}
|
||||
Requires: %{name}-common = %{version}-%{release}
|
||||
Requires: python3-gssapi >= 1.1.2
|
||||
Requires: gnupg
|
||||
Requires: iproute
|
||||
Requires: keyutils
|
||||
Requires: python3-pyOpenSSL
|
||||
Requires: python3-nss >= 0.16
|
||||
@ -548,6 +548,7 @@ Requires: python3-pyldap >= 2.4.15
|
||||
Requires: python3-custodia
|
||||
Requires: python3-requests
|
||||
Requires: python3-dns >= 1.11.1
|
||||
Requires: python3-netifaces >= 0.10.4
|
||||
|
||||
%description -n python3-ipalib
|
||||
IPA is an integrated solution to provide centrally managed Identity (users,
|
||||
|
@ -140,7 +140,6 @@ class BasePathNamespace(object):
|
||||
CACERT_P12 = "/root/cacert.p12"
|
||||
ROOT_IPA_CSR = "/root/ipa.csr"
|
||||
NAMED_PID = "/run/named/named.pid"
|
||||
IP = "/sbin/ip"
|
||||
NOLOGIN = "/sbin/nologin"
|
||||
SBIN_REBOOT = "/sbin/reboot"
|
||||
SBIN_RESTORECON = "/sbin/restorecon"
|
||||
|
@ -32,6 +32,7 @@ import socket
|
||||
import re
|
||||
import datetime
|
||||
import netaddr
|
||||
import netifaces
|
||||
import time
|
||||
import gssapi
|
||||
import pwd
|
||||
@ -151,24 +152,24 @@ class CheckedIPAddress(netaddr.IPAddress):
|
||||
|
||||
if match_local:
|
||||
if addr.version == 4:
|
||||
family = 'inet'
|
||||
family = netifaces.AF_INET
|
||||
elif addr.version == 6:
|
||||
family = 'inet6'
|
||||
family = netifaces.AF_INET6
|
||||
else:
|
||||
raise ValueError(
|
||||
"Unsupported address family ({})".format(addr.version)
|
||||
)
|
||||
|
||||
result = run(
|
||||
[paths.IP, '-family', family, '-oneline', 'address', 'show'],
|
||||
capture_output=True)
|
||||
lines = result.output.split('\n')
|
||||
for line in lines:
|
||||
fields = line.split()
|
||||
if len(fields) < 4:
|
||||
continue
|
||||
|
||||
ifnet = netaddr.IPNetwork(fields[3])
|
||||
if ifnet == net or (net is None and ifnet.ip == addr):
|
||||
net = ifnet
|
||||
iface = fields[1]
|
||||
break
|
||||
for interface in netifaces.interfaces():
|
||||
for ifdata in netifaces.ifaddresses(interface).get(family, []):
|
||||
ifnet = netaddr.IPNetwork('{addr}/{netmask}'.format(
|
||||
addr=ifdata['addr'],
|
||||
netmask=ifdata['netmask']
|
||||
))
|
||||
if ifnet == net or (net is None and ifnet.ip == addr):
|
||||
net = ifnet
|
||||
iface = interface
|
||||
break
|
||||
|
||||
if iface is None:
|
||||
raise ValueError('No network interface matches the provided IP address and netmask')
|
||||
|
Loading…
Reference in New Issue
Block a user