Skip to content

Commit

Permalink
fix(dhcpcd): Make lease parsing more robust (#5129)
Browse files Browse the repository at this point in the history
  • Loading branch information
holmanb authored and blackboxsw committed Apr 3, 2024
1 parent 3d4213f commit b0c7936
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 7 deletions.
12 changes: 10 additions & 2 deletions cloudinit/net/dhcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -791,12 +791,20 @@ def parse_dhcpcd_lease(lease_dump: str, interface: str) -> Dict:
try:
lease = dict(
[
a.split("=")
a.split("=", maxsplit=1)
for a in lease_dump.strip().replace("'", "").split("\n")
if "=" in a
]
)
if not lease:
msg = (
"No valid DHCP lease configuration "
"found in dhcpcd lease: %r"
)
LOG.error(msg, lease_dump)
raise InvalidDHCPLeaseFileError(msg % lease_dump)
except ValueError as error:
LOG.error("Error parsing dhcpcd lease: %r", error)
LOG.error("Error parsing dhcpcd lease: %r", lease_dump)
raise InvalidDHCPLeaseFileError from error

# this is expected by cloud-init's code
Expand Down
63 changes: 58 additions & 5 deletions tests/unittests/net/test_dhcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1199,17 +1199,70 @@ def test_parse_lease_dump(self):
assert "255.255.240.0" == parsed_lease["subnet-mask"]
assert "192.168.0.1" == parsed_lease["routers"]

@pytest.mark.parametrize(
"lease, parsed",
(
pytest.param(
"""
domain_name='us-east-2.compute.internal'
domain_name_servers='192.168.0.2'
""",
{
"domain_name": "us-east-2.compute.internal",
"domain_name_servers": "192.168.0.2",
},
id="lease_has_empty_lines",
),
pytest.param(
"""
domain_name='us-east-2.compute.internal'
not-a-kv-pair
domain_name_servers='192.168.0.2'
""",
{
"domain_name": "us-east-2.compute.internal",
"domain_name_servers": "192.168.0.2",
},
id="lease_has_values_that_arent_key_value_pairs",
),
pytest.param(
"""
domain_name='us-east=2.compute.internal'
""",
{
"domain_name": "us-east=2.compute.internal",
},
id="lease_has_kv_pair_including_equals_sign_in_value",
),
),
)
def test_parse_lease_dump_resilience(self, lease, parsed):
with mock.patch("cloudinit.net.dhcp.util.load_binary_file"):
Dhcpcd.parse_dhcpcd_lease(dedent(lease), "eth0")

def test_parse_lease_dump_fails(self):
lease = dedent(
"""
fail
"""
)
def _raise():
raise ValueError()

lease = mock.Mock()
lease.strip = _raise

with pytest.raises(InvalidDHCPLeaseFileError):
with mock.patch("cloudinit.net.dhcp.util.load_binary_file"):
Dhcpcd.parse_dhcpcd_lease(lease, "eth0")

with pytest.raises(InvalidDHCPLeaseFileError):
with mock.patch("cloudinit.net.dhcp.util.load_binary_file"):
lease = dedent(
"""
fail
"""
)
Dhcpcd.parse_dhcpcd_lease(lease, "eth0")

@pytest.mark.parametrize(
"lease_file, option_245",
(
Expand Down

0 comments on commit b0c7936

Please sign in to comment.