2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-01-11 18:42:29 +00:00

Support and prefer psutil

The netifaces library seems dead, we can use psutil instead
which seems more popular.
This commit is contained in:
Jarrod Johnson
2025-06-09 14:12:31 -04:00
parent 5f9250c492
commit c7d41f8a4b
4 changed files with 109 additions and 39 deletions

View File

@@ -36,7 +36,11 @@ import ctypes.util
import eventlet
import eventlet.green.socket as socket
import eventlet.green.select as select
import netifaces
try:
import psutil
except ImportError:
psutil = None
import netifaces
import os
import struct
import time
@@ -136,7 +140,12 @@ def idxtoname(idx):
_idxtobcast = {}
def get_bcastaddr(idx):
if idx not in _idxtobcast:
bc = netifaces.ifaddresses(idxtoname(idx))[17][0]['broadcast']
if psutil:
for addr in psutil.net_if_addrs()[idxtoname(idx)]:
if addr.family == socket.AF_PACKET:
bc = addr.broadcast
else:
bc = netifaces.ifaddresses(idxtoname(idx))[17][0]['broadcast']
bc = bytearray([int(x, 16) for x in bc.split(':')])
_idxtobcast[idx] = bc
return _idxtobcast[idx]

View File

@@ -18,7 +18,10 @@
import confluent.exceptions as exc
import codecs
import netifaces
try:
import psutil
except ImportError:
import netifaces
import struct
import eventlet.green.socket as socket
import eventlet.support.greendns
@@ -32,9 +35,18 @@ def msg_align(len):
return (len + 3) & ~3
def mask_to_cidr(mask):
maskn = socket.inet_pton(socket.AF_INET, mask)
maskn = struct.unpack('!I', maskn)[0]
cidr = 32
fam = socket.AF_INET
fmt =
if ':' in mask: # ipv6
fam = socket.AF_INET6
cidr = 128
maskn = socket.inet_pton(fam, mask)
if len(maskn) == 4
maskn = struct.unpack('!I', maskn)[0]
else:
first, second = struct.unpack('!QQ', maskn)
maskn = first << 64 | second
while maskn & 0b1 == 0 and cidr > 0:
cidr -= 1
maskn >>= 1
@@ -101,16 +113,25 @@ def ipn_is_local(ipn):
def address_is_local(address):
for iface in netifaces.interfaces():
for i4 in netifaces.ifaddresses(iface).get(2, []):
cidr = mask_to_cidr(i4['netmask'])
if ip_on_same_subnet(i4['addr'], address, cidr):
return True
for i6 in netifaces.ifaddresses(iface).get(10, []):
cidr = int(i6['netmask'].split('/')[1])
laddr = i6['addr'].split('%')[0]
if ip_on_same_subnet(laddr, address, cidr):
return True
if psutil:
ifas = psutil.net_if_addrs()
for iface in ifas:
for addr in ifas[iface]:
if addr.family in (socket.AF_INET, socket.AF_INET6):
cidr = mask_to_cidr(addr.netmask)
if ip_on_same_subnet(addr.address, address, cidr):
return True
else:
for iface in netifaces.interfaces():
for i4 in netifaces.ifaddresses(iface).get(2, []):
cidr = mask_to_cidr(i4['netmask'])
if ip_on_same_subnet(i4['addr'], address, cidr):
return True
for i6 in netifaces.ifaddresses(iface).get(10, []):
cidr = int(i6['netmask'].split('/')[1])
laddr = i6['addr'].split('%')[0]
if ip_on_same_subnet(laddr, address, cidr):
return True
return False
@@ -126,20 +147,35 @@ def _rebuildidxmap():
def myiptonets(svrip):
fam = netifaces.AF_INET
fam = socket.AF_INET
if ':' in svrip:
fam = netifaces.AF_INET6
fam = socket.AF_INET6
relevantnic = None
for iface in netifaces.interfaces():
for addr in netifaces.ifaddresses(iface).get(fam, []):
addr = addr.get('addr', '')
addr = addr.split('%')[0]
if addresses_match(addr, svrip):
relevantnic = iface
break
else:
continue
break
if psutil:
ifas = psutil.net_if_addrs()
for iface in ifas:
for addr in ifas[iface]:
if addr.fam != fam:
continue
addr = addr.address
addr = addr.split('%')[0]
if addresses_match(addr, svrip):
relevantnic = iface
break
else:
continue
break
else:
for iface in netifaces.interfaces():
for addr in netifaces.ifaddresses(iface).get(fam, []):
addr = addr.get('addr', '')
addr = addr.split('%')[0]
if addresses_match(addr, svrip):
relevantnic = iface
break
else:
continue
break
return inametonets(relevantnic)
@@ -150,11 +186,22 @@ def _iftonets(ifidx):
return inametonets(ifidx)
def inametonets(iname):
addrs = netifaces.ifaddresses(iname)
try:
addrs = addrs[netifaces.AF_INET]
except KeyError:
return
addrs = []
if psutil:
ifaces = psutil.net_if_addrs()
if iname not in ifaces:
return
for iface in ifaces:
for addrent in ifaces[iface]:
if addrent.family != socket.AF_INET:
continue
addrs.append({'addr': addrent.address, 'netmask': addrent.netmask})
else:
addrs = netifaces.ifaddresses(iname)
try:
addrs = addrs[netifaces.AF_INET]
except KeyError:
return
for addr in addrs:
ip = struct.unpack('!I', socket.inet_aton(addr['addr']))[0]
mask = struct.unpack('!I', socket.inet_aton(addr['netmask']))[0]

View File

@@ -20,7 +20,10 @@ import base64
import confluent.exceptions as cexc
import confluent.log as log
import hashlib
import netifaces
try:
import psutil
except ImportError:
import netifaces
import os
import re
import socket
@@ -85,11 +88,18 @@ def list_interface_indexes():
def list_ips():
# Used for getting addresses to indicate the multicast address
# as well as getting all the broadcast addresses
for iface in netifaces.interfaces():
addrs = netifaces.ifaddresses(iface)
if netifaces.AF_INET in addrs:
for addr in addrs[netifaces.AF_INET]:
yield addr
if psutil:
ifas = psutil.net_if_addrs()
for intf in ifas:
for addr in ifas[intf]:
if addr.family == socket.AF_INET and addr.broadcast:
yield {'broadcast': addr.broadcast, 'addr': addr.address}
else:
for iface in netifaces.interfaces():
addrs = netifaces.ifaddresses(iface)
if netifaces.AF_INET in addrs:
for addr in addrs[netifaces.AF_INET]:
yield addr
def randomstring(length=20):
"""Generate a random string of requested length

View File

@@ -24,14 +24,18 @@ Requires: python-pyghmi >= 1.5.71, python-eventlet, python-greenlet, python-pycr
%if "%{dist}" == ".el8"
Requires: python3-pyghmi >= 1.5.71, python3-eventlet, python3-greenlet, python3-pycryptodomex >= 3.4.7, confluent_client == %{version}, python3-pyparsing, python3-paramiko, python3-dns, python3-netifaces, python3-pyasn1 >= 0.2.3, python3-pysnmp >= 4.3.4, python3-lxml, python3-eficompressor, python3-setuptools, python3-dateutil, python3-enum34, python3-asn1crypto, python3-cffi, python3-pyOpenSSL, python3-websocket-client python3-msgpack python3-libarchive-c python3-yaml openssl iproute
%else
%if "%{dist}" == ".el9" || "%{dist}" == ".el10"
%if "%{dist}" == ".el9"
Requires: python3-pyghmi >= 1.5.71, python3-eventlet, python3-greenlet, python3-pycryptodomex >= 3.4.7, confluent_client == %{version}, python3-pyparsing, python3-paramiko, python3-dns, python3-webauthn, python3-netifaces, python3-pyasn1 >= 0.2.3, python3-pysnmp >= 4.3.4, python3-lxml, python3-eficompressor, python3-setuptools, python3-dateutil, python3-cffi, python3-pyOpenSSL, python3-websocket-client python3-msgpack python3-libarchive-c python3-yaml openssl iproute
%else
%if "%{dist}" == ".el10"
Requires: python3-pyghmi >= 1.5.71, python3-eventlet, python3-greenlet, python3-pycryptodomex >= 3.4.7, confluent_client == %{version}, python3-pyparsing, python3-paramiko, python3-dns, python3-webauthn, python3-psutil, python3-pyasn1 >= 0.2.3, python3-pysnmp >= 4.3.4, python3-lxml, python3-eficompressor, python3-setuptools, python3-dateutil, python3-cffi, python3-pyOpenSSL, python3-websocket-client python3-msgpack python3-libarchive-c python3-yaml openssl iproute
%else
Requires: python3-dbm,python3-pyghmi >= 1.5.71, python3-eventlet, python3-greenlet, python3-pycryptodome >= 3.4.7, confluent_client == %{version}, python3-pyparsing, python3-paramiko, python3-dnspython, python3-netifaces, python3-pyasn1 >= 0.2.3, python3-pysnmp >= 4.3.4, python3-lxml, python3-eficompressor, python3-setuptools, python3-dateutil, python3-cffi, python3-pyOpenSSL, python3-websocket-client python3-msgpack python3-libarchive-c python3-PyYAML openssl iproute
%endif
%endif
%endif
%endif
Vendor: Lenovo
Url: https://github.com/lenovo/confluent