Don't assume column index for netmask and broadcast (#79121)
* Don't assume column index for netmask and broadcast. Fixes #79117 * fix typo
This commit is contained in:
4
changelogs/fragments/79117-bsd-ifconfig-inet-fix.yml
Normal file
4
changelogs/fragments/79117-bsd-ifconfig-inet-fix.yml
Normal file
@ -0,0 +1,4 @@
|
||||
bugfixes:
|
||||
- BSD network facts - Do not assume column indexes, look for ``netmask`` and
|
||||
``broadcast`` for determining the correct columns when parsing ``inet`` line
|
||||
(https://github.com/ansible/ansible/issues/79117)
|
||||
@ -221,24 +221,35 @@ class GenericBsdIfconfigNetwork(Network):
|
||||
address['broadcast'] = words[3]
|
||||
|
||||
else:
|
||||
# Don't just assume columns, use "netmask" as the index for the prior column
|
||||
try:
|
||||
netmask_idx = words.index('netmask') + 1
|
||||
except ValueError:
|
||||
netmask_idx = 3
|
||||
|
||||
# deal with hex netmask
|
||||
if re.match('([0-9a-f]){8}', words[3]) and len(words[3]) == 8:
|
||||
words[3] = '0x' + words[3]
|
||||
if words[3].startswith('0x'):
|
||||
address['netmask'] = socket.inet_ntoa(struct.pack('!L', int(words[3], base=16)))
|
||||
if re.match('([0-9a-f]){8}$', words[netmask_idx]):
|
||||
netmask = '0x' + words[netmask_idx]
|
||||
else:
|
||||
netmask = words[netmask_idx]
|
||||
|
||||
if netmask.startswith('0x'):
|
||||
address['netmask'] = socket.inet_ntoa(struct.pack('!L', int(netmask, base=16)))
|
||||
else:
|
||||
# otherwise assume this is a dotted quad
|
||||
address['netmask'] = words[3]
|
||||
address['netmask'] = netmask
|
||||
# calculate the network
|
||||
address_bin = struct.unpack('!L', socket.inet_aton(address['address']))[0]
|
||||
netmask_bin = struct.unpack('!L', socket.inet_aton(address['netmask']))[0]
|
||||
address['network'] = socket.inet_ntoa(struct.pack('!L', address_bin & netmask_bin))
|
||||
if 'broadcast' not in address:
|
||||
# broadcast may be given or we need to calculate
|
||||
if len(words) > 5:
|
||||
address['broadcast'] = words[5]
|
||||
else:
|
||||
try:
|
||||
broadcast_idx = words.index('broadcast') + 1
|
||||
except ValueError:
|
||||
address['broadcast'] = socket.inet_ntoa(struct.pack('!L', address_bin | (~netmask_bin & 0xffffffff)))
|
||||
else:
|
||||
address['broadcast'] = words[broadcast_idx]
|
||||
|
||||
# add to our list of addresses
|
||||
if not words[1].startswith('127.'):
|
||||
|
||||
@ -173,3 +173,45 @@ class TestGenericBsdNetworkNetBSD(unittest.TestCase):
|
||||
'filter': '*'}
|
||||
mock_module.get_bin_path = Mock(return_value=None)
|
||||
return mock_module
|
||||
|
||||
def test_ensure_correct_netmask_parsing(self):
|
||||
n = generic_bsd.GenericBsdIfconfigNetwork(None)
|
||||
lines = [
|
||||
'inet 192.168.7.113 netmask 0xffffff00 broadcast 192.168.7.255',
|
||||
'inet 10.109.188.206 --> 10.109.188.206 netmask 0xffffe000',
|
||||
]
|
||||
expected = [
|
||||
(
|
||||
{
|
||||
'ipv4': [
|
||||
{
|
||||
'address': '192.168.7.113',
|
||||
'netmask': '255.255.255.0',
|
||||
'network': '192.168.7.0',
|
||||
'broadcast': '192.168.7.255'
|
||||
}
|
||||
]
|
||||
},
|
||||
{'all_ipv4_addresses': ['192.168.7.113']},
|
||||
),
|
||||
(
|
||||
{
|
||||
'ipv4': [
|
||||
{
|
||||
'address': '10.109.188.206',
|
||||
'netmask': '255.255.224.0',
|
||||
'network': '10.109.160.0',
|
||||
'broadcast': '10.109.191.255'
|
||||
}
|
||||
]
|
||||
},
|
||||
{'all_ipv4_addresses': ['10.109.188.206']},
|
||||
),
|
||||
]
|
||||
for i, line in enumerate(lines):
|
||||
words = line.split()
|
||||
current_if = {'ipv4': []}
|
||||
ips = {'all_ipv4_addresses': []}
|
||||
n.parse_inet_line(words, current_if, ips)
|
||||
self.assertDictEqual(current_if, expected[i][0])
|
||||
self.assertDictEqual(ips, expected[i][1])
|
||||
|
||||
Reference in New Issue
Block a user