Make win_system.master locale agnostic

This commit is contained in:
Shane Lee 2024-04-15 13:34:22 -06:00 committed by Daniel Wozniak
parent 6fc0fa2e02
commit cb57145514
3 changed files with 45 additions and 40 deletions

2
changelog/60508.fixed.md Normal file
View file

@ -0,0 +1,2 @@
Fix an issue with the win_system module detecting established connections on
non-Windows systems. Uses psutils instead of parsing the return of netstat

View file

@ -11,7 +11,6 @@ or for problem solving if your minion is having problems.
import ctypes
import datetime
import logging
import subprocess
import salt.utils.event
import salt.utils.platform
@ -486,6 +485,24 @@ def _byte_calc(val):
return tstr
def _get_connected_ips(port):
"""
List all connections on the system that have an established connection on
the passed port. This uses psutil.net_connections instead of netstat to be
locale agnostic.
"""
connected_ips = set()
# Let's use psutil to be non-locale specific
conns = psutil.net_connections()
for conn in conns:
if conn.status == psutil.CONN_ESTABLISHED:
if conn.laddr.port == port:
connected_ips.add(conn.laddr.ip)
return connected_ips
def master(master=None, connected=True):
"""
.. versionadded:: 2015.5.0
@ -501,44 +518,6 @@ def master(master=None, connected=True):
salt '*' status.master
"""
def _win_remotes_on(port):
"""
Windows specific helper function.
Returns set of ipv4 host addresses of remote established connections
on local or remote tcp port.
Parses output of shell 'netstat' to get connections
PS C:> netstat -n -p TCP
Active Connections
Proto Local Address Foreign Address State
TCP 10.1.1.26:3389 10.1.1.1:4505 ESTABLISHED
TCP 10.1.1.26:56862 10.1.1.10:49155 TIME_WAIT
TCP 10.1.1.26:56868 169.254.169.254:80 CLOSE_WAIT
TCP 127.0.0.1:49197 127.0.0.1:49198 ESTABLISHED
TCP 127.0.0.1:49198 127.0.0.1:49197 ESTABLISHED
"""
remotes = set()
try:
data = subprocess.check_output(["netstat", "-n", "-p", "TCP"])
except subprocess.CalledProcessError:
log.error("Failed netstat")
raise
lines = salt.utils.stringutils.to_unicode(data).split("\n")
for line in lines:
if "ESTABLISHED" not in line:
continue
chunks = line.split()
remote_host, remote_port = chunks[2].rsplit(":", 1)
if int(remote_port) != port:
continue
remotes.add(remote_host)
return remotes
# the default publishing port
port = 4505
master_ips = None
@ -553,7 +532,7 @@ def master(master=None, connected=True):
port = int(__salt__["config.get"]("publish_port"))
master_connection_status = False
connected_ips = _win_remotes_on(port)
connected_ips = _get_connected_ips(port)
# Get connection status for master
for master_ip in master_ips:

View file

@ -0,0 +1,24 @@
import psutil
import pytest
import salt.modules.win_status as win_status
pytestmark = [
pytest.mark.windows_whitelisted,
pytest.mark.skip_unless_on_windows,
]
def test__get_connected_ips():
# Let's find an active connection to test with
port = None
ip = None
conns = psutil.net_connections()
for conn in conns:
if conn.status == psutil.CONN_ESTABLISHED:
ip = conn.laddr.ip
port = conn.laddr.port
break
assert port is not None
assert ip is not None
assert win_status._get_connected_ips(port) == {ip}