mirror of
https://github.com/ansible-collections/community.routeros.git
synced 2025-07-04 23:34:39 +02:00
facts: Allow multiple entries per iface (#6)
* facts: Allow multiple entries per iface There can be multiple addresses per interface, as well as multiple neighbors. This changes the format of "ansible_net_neighbors" to list instead of dict, because the old format could not store multiple neighbors per interface. Also, this fixes a crash when the ipv6 module is not loaded, because the error "bad command name" was being parsed with interface=None * facts: Fix tests * facts: Add changelog fragment
This commit is contained in:
parent
3634150468
commit
d26dfa16c7
2 changed files with 27 additions and 59 deletions
|
@ -248,7 +248,7 @@ class Interfaces(FactsBase):
|
||||||
self.facts['interfaces'] = dict()
|
self.facts['interfaces'] = dict()
|
||||||
self.facts['all_ipv4_addresses'] = list()
|
self.facts['all_ipv4_addresses'] = list()
|
||||||
self.facts['all_ipv6_addresses'] = list()
|
self.facts['all_ipv6_addresses'] = list()
|
||||||
self.facts['neighbors'] = dict()
|
self.facts['neighbors'] = list()
|
||||||
|
|
||||||
data = self.responses[0]
|
data = self.responses[0]
|
||||||
if data:
|
if data:
|
||||||
|
@ -257,41 +257,31 @@ class Interfaces(FactsBase):
|
||||||
|
|
||||||
data = self.responses[1]
|
data = self.responses[1]
|
||||||
if data:
|
if data:
|
||||||
data = self.parse_addresses(data)
|
data = self.parse_detail(data)
|
||||||
self.populate_ipv4_interfaces(data)
|
self.populate_addresses(data, 'ipv4')
|
||||||
|
|
||||||
data = self.responses[2]
|
data = self.responses[2]
|
||||||
if data:
|
if data:
|
||||||
data = self.parse_addresses(data)
|
data = self.parse_detail(data)
|
||||||
self.populate_ipv6_interfaces(data)
|
self.populate_addresses(data, 'ipv6')
|
||||||
|
|
||||||
data = self.responses[3]
|
data = self.responses[3]
|
||||||
if data:
|
if data:
|
||||||
self.facts['neighbors'] = self.parse_neighbors(data)
|
self.facts['neighbors'] = list(self.parse_detail(data))
|
||||||
|
|
||||||
def populate_interfaces(self, data):
|
def populate_interfaces(self, data):
|
||||||
for key, value in iteritems(data):
|
for key, value in iteritems(data):
|
||||||
self.facts['interfaces'][key] = value
|
self.facts['interfaces'][key] = value
|
||||||
|
|
||||||
def populate_ipv4_interfaces(self, data):
|
def populate_addresses(self, data, family):
|
||||||
for key, value in iteritems(data):
|
for value in data:
|
||||||
if 'ipv4' not in self.facts['interfaces'][key]:
|
key = value['interface']
|
||||||
self.facts['interfaces'][key]['ipv4'] = list()
|
if family not in self.facts['interfaces'][key]:
|
||||||
|
self.facts['interfaces'][key][family] = list()
|
||||||
addr, subnet = value['address'].split("/")
|
addr, subnet = value['address'].split("/")
|
||||||
ipv4 = dict(address=addr.strip(), subnet=subnet.strip())
|
ip = dict(address=addr.strip(), subnet=subnet.strip())
|
||||||
self.add_ip_address(addr.strip(), 'ipv4')
|
self.add_ip_address(addr.strip(), family)
|
||||||
self.facts['interfaces'][key]['ipv4'].append(ipv4)
|
self.facts['interfaces'][key][family].append(ip)
|
||||||
|
|
||||||
def populate_ipv6_interfaces(self, data):
|
|
||||||
for key, value in iteritems(data):
|
|
||||||
if key is None:
|
|
||||||
break
|
|
||||||
if 'ipv6' not in self.facts['interfaces'][key]:
|
|
||||||
self.facts['interfaces'][key]['ipv6'] = list()
|
|
||||||
addr, subnet = value['address'].split("/")
|
|
||||||
ipv6 = dict(address=addr.strip(), subnet=subnet.strip())
|
|
||||||
self.add_ip_address(addr.strip(), 'ipv6')
|
|
||||||
self.facts['interfaces'][key]['ipv6'].append(ipv6)
|
|
||||||
|
|
||||||
def add_ip_address(self, address, family):
|
def add_ip_address(self, address, family):
|
||||||
if family == 'ipv4':
|
if family == 'ipv4':
|
||||||
|
@ -314,41 +304,19 @@ class Interfaces(FactsBase):
|
||||||
facts = dict()
|
facts = dict()
|
||||||
data = self.preprocess(data)
|
data = self.preprocess(data)
|
||||||
for line in data:
|
for line in data:
|
||||||
name = self.parse_name(line)
|
parsed = dict(re.findall(self.DETAIL_RE, line))
|
||||||
facts[name] = dict()
|
if "name" not in parsed:
|
||||||
for (key, value) in re.findall(self.DETAIL_RE, line):
|
continue
|
||||||
facts[name][key] = value
|
facts[parsed["name"]] = dict(re.findall(self.DETAIL_RE, line))
|
||||||
return facts
|
return facts
|
||||||
|
|
||||||
def parse_addresses(self, data):
|
def parse_detail(self, data):
|
||||||
facts = dict()
|
|
||||||
data = self.preprocess(data)
|
data = self.preprocess(data)
|
||||||
for line in data:
|
for line in data:
|
||||||
name = self.parse_interface(line)
|
parsed = dict(re.findall(self.DETAIL_RE, line))
|
||||||
facts[name] = dict()
|
if "interface" not in parsed:
|
||||||
for (key, value) in re.findall(self.DETAIL_RE, line):
|
continue
|
||||||
facts[name][key] = value
|
yield parsed
|
||||||
return facts
|
|
||||||
|
|
||||||
def parse_neighbors(self, data):
|
|
||||||
facts = dict()
|
|
||||||
data = self.preprocess(data)
|
|
||||||
for line in data:
|
|
||||||
name = self.parse_interface(line)
|
|
||||||
facts[name] = dict()
|
|
||||||
for (key, value) in re.findall(self.DETAIL_RE, line):
|
|
||||||
facts[name][key] = value
|
|
||||||
return facts
|
|
||||||
|
|
||||||
def parse_name(self, data):
|
|
||||||
match = re.search(r'name=\"([\w\d\-]+)\"', data, re.M)
|
|
||||||
if match:
|
|
||||||
return match.group(1)
|
|
||||||
|
|
||||||
def parse_interface(self, data):
|
|
||||||
match = re.search(r'interface=([\w\d\-]+)', data, re.M)
|
|
||||||
if match:
|
|
||||||
return match.group(1)
|
|
||||||
|
|
||||||
|
|
||||||
FACT_SUBSETS = dict(
|
FACT_SUBSETS = dict(
|
||||||
|
|
|
@ -92,7 +92,7 @@ class TestRouterosFactsModule(TestRouterosModule):
|
||||||
set_module_args(dict(gather_subset='interfaces'))
|
set_module_args(dict(gather_subset='interfaces'))
|
||||||
result = self.execute_module()
|
result = self.execute_module()
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
result['ansible_facts']['ansible_net_all_ipv4_addresses'][0], ['10.37.129.3', '10.37.0.0']
|
result['ansible_facts']['ansible_net_all_ipv4_addresses'][0], ['10.37.129.3', '10.37.0.0', '192.168.88.1']
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
result['ansible_facts']['ansible_net_all_ipv6_addresses'], ['fe80::21c:42ff:fe36:5290']
|
result['ansible_facts']['ansible_net_all_ipv6_addresses'], ['fe80::21c:42ff:fe36:5290']
|
||||||
|
@ -105,7 +105,7 @@ class TestRouterosFactsModule(TestRouterosModule):
|
||||||
len(result['ansible_facts']['ansible_net_interfaces'].keys()), 11
|
len(result['ansible_facts']['ansible_net_interfaces'].keys()), 11
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
len(result['ansible_facts']['ansible_net_neighbors'].keys()), 4
|
len(result['ansible_facts']['ansible_net_neighbors']), 4
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_facts_interfaces_no_ipv6(self):
|
def test_facts_interfaces_no_ipv6(self):
|
||||||
|
@ -113,7 +113,7 @@ class TestRouterosFactsModule(TestRouterosModule):
|
||||||
'facts/ipv6_address_print_detail_without-paging_no-ipv6'
|
'facts/ipv6_address_print_detail_without-paging_no-ipv6'
|
||||||
)
|
)
|
||||||
interfaces = self.module.Interfaces(module=self.module)
|
interfaces = self.module.Interfaces(module=self.module)
|
||||||
addresses = interfaces.parse_addresses(data=fixture)
|
addresses = interfaces.parse_detail(data=fixture)
|
||||||
result = interfaces.populate_ipv6_interfaces(data=addresses)
|
result = interfaces.populate_addresses(data=addresses, family='ipv6')
|
||||||
|
|
||||||
self.assertEqual(result, None)
|
self.assertEqual(result, None)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue