diff --git a/changelogs/fragments/fix_facts_gather.yaml b/changelogs/fragments/fix_facts_gather.yaml new file mode 100644 index 000000000..be0bbe562 --- /dev/null +++ b/changelogs/fragments/fix_facts_gather.yaml @@ -0,0 +1,3 @@ +--- +bugfixes: + - Fixes an issue with facts gathering failing when an sub interface is in a deleted state. diff --git a/plugins/module_utils/network/ios/facts/legacy/base.py b/plugins/module_utils/network/ios/facts/legacy/base.py index 5344ca627..6788821a1 100644 --- a/plugins/module_utils/network/ios/facts/legacy/base.py +++ b/plugins/module_utils/network/ios/facts/legacy/base.py @@ -285,7 +285,12 @@ def populate_interfaces(self, interfaces): def populate_ipv4_interfaces(self, data): for key, value in data.items(): - self.facts["interfaces"][key]["ipv4"] = list() + try: + self.facts["interfaces"][key]["ipv4"] = list() + except KeyError: + self.facts["interfaces"][key] = dict() + self.facts["interfaces"][key]["ipv4"] = list() + self.parse_deleted_status(key, value) primary_address = addresses = [] primary_address = re.findall(r"Internet address is (.+)$", value, re.M) addresses = re.findall(r"Secondary address (.+)$", value, re.M) @@ -305,6 +310,7 @@ def populate_ipv6_interfaces(self, data): except KeyError: self.facts["interfaces"][key] = dict() self.facts["interfaces"][key]["ipv6"] = list() + self.parse_deleted_status(key, value) addresses = re.findall(r"\s+(.+), subnet", value, re.M) subnets = re.findall(r", subnet is (.+)$", value, re.M) for addr, subnet in zip(addresses, subnets): @@ -370,6 +376,11 @@ def parse_interfaces(self, data): parsed[key] = line return parsed + def parse_deleted_status(self, interface, value): + status = self.parse_operstatus(value) + if status == "deleted": + self.facts["interfaces"][interface]["operstatus"] = status + def parse_description(self, data): match = re.search(r"Description: (.+)$", data, re.M) if match: diff --git a/tests/unit/modules/network/ios/fixtures/ios_facts_show_ip_interface b/tests/unit/modules/network/ios/fixtures/ios_facts_show_ip_interface index e69de29bb..1cffb658e 100644 --- a/tests/unit/modules/network/ios/fixtures/ios_facts_show_ip_interface +++ b/tests/unit/modules/network/ios/fixtures/ios_facts_show_ip_interface @@ -0,0 +1,6 @@ +Tunnel1110 is up, line protocol is up + Internet address is 10.10.10.2/30 +GigabitEthernet2/5/5 is up, line protocol is up + Internet protocol processing disabled +GigabitEthernet2/5/5.1874 is deleted, line protocol is down + Internet protocol processing disabled diff --git a/tests/unit/modules/network/ios/test_ios_facts.py b/tests/unit/modules/network/ios/test_ios_facts.py index 4878d4ad7..35b396b87 100644 --- a/tests/unit/modules/network/ios/test_ios_facts.py +++ b/tests/unit/modules/network/ios/test_ios_facts.py @@ -199,3 +199,28 @@ def test_ios_facts_neighbors(self): result["ansible_facts"]["ansible_net_neighbors"]["GigabitEthernet3"], [{"host": "Rtest", "port": "Gi1", "ip": "10.3.0.3"}], ) + + def test_ios_facts_interfaces(self): + set_module_args(dict(gather_subset="interfaces")) + result = self.execute_module() + self.assertEqual( + result["ansible_facts"]["ansible_net_interfaces"]["GigabitEthernet2/5/5.1874"], + {"ipv4": [], "operstatus": "deleted"}, + ) + self.assertEqual( + result["ansible_facts"]["ansible_net_interfaces"]["Tunnel1110"], + { + "bandwidth": None, + "description": None, + "duplex": None, + "ipv4": [ + {"address": "10.10.10.2", "subnet": "30"}, + ], + "lineprotocol": "up", + "macaddress": None, + "mediatype": None, + "mtu": None, + "operstatus": "up", + "type": None, + }, + )