Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions cloudinit/netinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,16 +598,19 @@ def route_pformat():
tbl_v4 = SimpleTable(fields_v4)
for (n, r) in enumerate(routes.get("ipv4")):
route_id = str(n)
tbl_v4.add_row(
[
route_id,
r["destination"],
r["gateway"],
r["genmask"],
r["iface"],
r["flags"],
]
)
try:
tbl_v4.add_row(
[
route_id,
r["destination"],
r.get("gateway", "0.0.0.0"),
r["genmask"],
r["iface"],
r["flags"],
]
)
except KeyError as e:
util.logexc(LOG, "Route info formatting error: %s" % e)
route_s = tbl_v4.get_string()
max_len = len(max(route_s.splitlines(), key=len))
header = util.center("Route IPv4 info", "+", max_len)
Expand All @@ -625,15 +628,18 @@ def route_pformat():
route_id = str(n)
if r["iface"] == "lo":
continue
tbl_v6.add_row(
[
route_id,
r["destination"],
r["gateway"],
r["iface"],
r["flags"],
]
)
try:
tbl_v6.add_row(
[
route_id,
r["destination"],
r.get("gateway", "::"),
r["iface"],
r["flags"],
]
)
except KeyError as e:
util.logexc(LOG, "Route info formatting error: %s" % e)
route_s = tbl_v6.get_string()
max_len = len(max(route_s.splitlines(), key=len))
header = util.center("Route IPv6 info", "+", max_len)
Expand Down
19 changes: 19 additions & 0 deletions tests/data/netinfo/route-formatted-output-missing-gateway
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
+++++++++++++++++++++++++++Route IPv4 info+++++++++++++++++++++++++++
+-------+-------------+---------+---------------+-----------+-------+
| Route | Destination | Gateway | Genmask | Interface | Flags |
+-------+-------------+---------+---------------+-----------+-------+
| 0 | 192.168.2.0 | 0.0.0.0 | 255.255.255.0 | enp0s25 | U |
+-------+-------------+---------+---------------+-----------+-------+
++++++++++++++++++++++++++Route IPv6 info++++++++++++++++++++++++++
+-------+---------------------------+---------+-----------+-------+
| Route | Destination | Gateway | Interface | Flags |
+-------+---------------------------+---------+-----------+-------+
| 0 | 2a00:abcd:82ae:cd33::657 | :: | enp0s25 | Ue |
| 1 | 2a00:abcd:82ae:cd33::/64 | :: | enp0s25 | U |
| 2 | 2a00:abcd:82ae:cd33::/56 | :: | enp0s25 | U |
| 3 | fd81:123f:654::657 | :: | enp0s25 | U |
| 4 | fd81:123f:654::/64 | :: | enp0s25 | U |
| 5 | fd81:123f:654::/48 | :: | enp0s25 | U |
| 6 | fe80::abcd:ef12:bc34:da21 | :: | enp0s25 | U |
| 7 | fe80::/64 | :: | enp0s25 | U |
+-------+---------------------------+---------+-----------+-------+
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
192.168.2.0/24 dev enp0s25 proto kernel scope link src 192.168.2.18 metric 100
10 changes: 10 additions & 0 deletions tests/data/netinfo/sample-iproute-output-v6-missing-gateway
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
2a00:abcd:82ae:cd33::657 dev enp0s25 proto kernel metric 256 expires 2334sec pref medium
2a00:abcd:82ae:cd33::/64 dev enp0s25 proto ra metric 100 pref medium
2a00:abcd:82ae:cd33::/56 dev enp0s25 proto ra metric 100 pref medium
fd81:123f:654::657 dev enp0s25 proto kernel metric 256 pref medium
fd81:123f:654::/64 dev enp0s25 proto ra metric 100 pref medium
fd81:123f:654::/48 dev enp0s25 proto ra metric 100 pref medium
fe80::abcd:ef12:bc34:da21 dev enp0s25 proto static metric 100 pref medium
fe80::/64 dev enp0s25 proto kernel metric 256 pref medium
local ::1 dev lo table local proto none metric 0 pref medium
local 2600:1f16:b80:ad00:90a:c915:bca6:5ff2 dev lo table local proto none metric 0 pref medium
27 changes: 27 additions & 0 deletions tests/unittests/test_netinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,17 @@
SAMPLE_ROUTE_OUT_V6 = readResource("netinfo/sample-route-output-v6")
SAMPLE_IPROUTE_OUT_V4 = readResource("netinfo/sample-iproute-output-v4")
SAMPLE_IPROUTE_OUT_V6 = readResource("netinfo/sample-iproute-output-v6")
SAMPLE_IPROUTE_OUT_V6_MISSING_GATEWAY = readResource(
"netinfo/sample-iproute-output-v6-missing-gateway"
)
SAMPLE_IPROUTE_OUT_V4_MISSING_GATEWAY = readResource(
"netinfo/sample-iproute-output-v4-missing-gateway"
)
NETDEV_FORMATTED_OUT = readResource("netinfo/netdev-formatted-output")
ROUTE_FORMATTED_OUT = readResource("netinfo/route-formatted-output")
ROUTE_FORMATTED_OUT_MISSING_GATEWAY = readResource(
"netinfo/route-formatted-output-missing-gateway"
)
FREEBSD_NETDEV_OUT = readResource("netinfo/freebsd-netdev-formatted-output")


Expand Down Expand Up @@ -223,6 +232,24 @@ def subp_iproute_selector(*args, **kwargs):
content = route_pformat()
assert ROUTE_FORMATTED_OUT == content

@mock.patch("cloudinit.netinfo.subp.which")
@mock.patch("cloudinit.netinfo.subp.subp")
def test_route_iproute_pformat_missing_gateway(self, m_subp, m_which):
"""route_pformat properly rendering info with missing gateway."""

def subp_iproute_selector(*args, **kwargs):
if ["ip", "-o", "route", "list"] == args[0]:
return (SAMPLE_IPROUTE_OUT_V4_MISSING_GATEWAY, "")
v6cmd = ["ip", "--oneline", "-6", "route", "list", "table", "all"]
if v6cmd == args[0]:
return (SAMPLE_IPROUTE_OUT_V6_MISSING_GATEWAY, "")
raise RuntimeError("Unexpected subp call %s" % args[0])

m_subp.side_effect = subp_iproute_selector
m_which.side_effect = lambda x: x if x == "ip" else None
content = route_pformat()
assert ROUTE_FORMATTED_OUT_MISSING_GATEWAY == content

@mock.patch("cloudinit.netinfo.subp.which")
@mock.patch("cloudinit.netinfo.subp.subp")
def test_route_warn_on_missing_commands(self, m_subp, m_which, caplog):
Expand Down
1 change: 1 addition & 0 deletions tools/.github-cla-signers
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,4 @@ yangzz-97
yawkat
zhan9san
zhuzaifangxuele
zykovd