Skip to content

Commit

Permalink
Merge branch 'bugfix/3349-network-routes-mod' into q/2.8
Browse files Browse the repository at this point in the history
  • Loading branch information
bert-e committed May 5, 2021
2 parents eca7881 + aefb577 commit 481a21e
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 2 deletions.
2 changes: 1 addition & 1 deletion salt/_modules/metalk8s_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ def route_exists(destination, raises=True):
error = None
route_exists = False

all_routes = __salt__["network.routes"](family="inet")
all_routes = __salt__["metalk8s_network.routes"]()

for route in all_routes:
# Check if our destination network is fully included in this route.
Expand Down
59 changes: 59 additions & 0 deletions salt/_modules/metalk8s_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,62 @@ def get_listening_processes():
)

return all_listen_connections


def routes():
"""
Return currently configured IPv4 routes from routing table
CLI Example:
.. code-block:: bash
salt '*' metalk8s_network.routes
"""
ret = []
cmd = "ip -4 route show table main"
out = __salt__["cmd.run"](cmd)
for line in out.splitlines():
comps = line.split()

if comps[0] in ("unreachable", "blackhole"):
continue

if comps[0] == "default":
ip_interface = ""
if comps[3] == "dev":
ip_interface = comps[4]

ret.append(
{
"addr_family": "inet",
"destination": "0.0.0.0",
"gateway": comps[2],
"netmask": "0.0.0.0",
"flags": "UG",
"interface": ip_interface,
}
)
else:
try:
address_mask = __salt__["network.convert_cidr"](comps[0])
except ValueError:
log.warning("Unsupported route type or format: %s", line)
continue

ip_interface = ""
if comps[1] == "dev":
ip_interface = comps[2]

ret.append(
{
"addr_family": "inet",
"destination": address_mask["network"],
"gateway": "0.0.0.0",
"netmask": address_mask["netmask"],
"flags": "U",
"interface": ip_interface,
}
)

return ret
46 changes: 46 additions & 0 deletions salt/tests/unit/modules/files/test_metalk8s_network.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,49 @@ get_listening_processes:
127.0.0.1:
pid: 123
name: likely-something

routes:
# 0. Default route
- ip_route_output: |-
default via 10.200.0.1 dev eth0
result:
- &default_route
addr_family: inet
destination: 0.0.0.0
flags: UG
gateway: 10.200.0.1
interface: eth0
netmask: 0.0.0.0
# 1. A simple route
- ip_route_output: |-
10.200.0.0/16 dev eth0 proto kernel scope link src 10.200.2.41
result:
- &simple_route
addr_family: inet
destination: 10.200.0.0
flags: U
gateway: 0.0.0.0
interface: eth0
netmask: 255.255.0.0
# 2. A blackhole route
- ip_route_output: |-
blackhole 10.233.162.0/26 proto bird
result: []
# 3. Multiple routes
- ip_route_output: |-
default via 10.200.0.1 dev eth0
10.200.0.0/16 dev eth0 proto kernel scope link src 10.200.2.41
blackhole 10.233.162.0/26 proto bird
result:
- *default_route
- *simple_route
# 4. No routes
- ip_route_output: ''
result: []
# 5. Unsupported type or format
- ip_route_output: |-
banana route via foo
this is not a valid input
10.200.0.0/16 dev eth0 proto kernel scope link src 10.200.2.41
result:
- *simple_route
2 changes: 1 addition & 1 deletion salt/tests/unit/modules/test_metalk8s_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def test_route_exists(
network_routes_mock = MagicMock(return_value=routes_ret)

patch_dict = {
"network.routes": network_routes_mock,
"metalk8s_network.routes": network_routes_mock,
}

with patch.dict(metalk8s_checks.__salt__, patch_dict):
Expand Down
24 changes: 24 additions & 0 deletions salt/tests/unit/modules/test_metalk8s_network.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ipaddress
import os.path
from unittest import TestCase
from unittest.mock import MagicMock, patch
Expand Down Expand Up @@ -266,3 +267,26 @@ def test_get_listening_processes(
"psutil.Process", process_mock
):
self.assertEqual(metalk8s_network.get_listening_processes(), result)

@utils.parameterized_from_cases(YAML_TESTS_CASES["routes"])
def test_routes(self, ip_route_output, result):
"""
Tests the return of `routes` function
"""

def _mock_convert_cidr(cidr):
ret = {"network": None, "netmask": None, "broadcast": None}
network_info = ipaddress.ip_network(cidr, strict=False)
ret["network"] = str(network_info.network_address)
ret["netmask"] = str(network_info.netmask)
ret["broadcast"] = str(network_info.broadcast_address)
return ret

mock_convert_cidr = MagicMock(side_effect=_mock_convert_cidr)
mock_ip_cmd = MagicMock(return_value=ip_route_output)
with patch.dict(
metalk8s_network.__salt__,
{"cmd.run": mock_ip_cmd, "network.convert_cidr": mock_convert_cidr},
):
self.assertEqual(metalk8s_network.routes(), result)
mock_ip_cmd.assert_called_once_with("ip -4 route show table main")

0 comments on commit 481a21e

Please sign in to comment.