mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
ios_facts: Gather CDP neighbor data (#49129)
* ios_facts: Gather CDP neighbor data * ios_facts: Create tests for ansible_net_neighbors
This commit is contained in:
parent
a51eca364f
commit
a914f494a8
6 changed files with 162 additions and 3 deletions
|
@ -142,7 +142,9 @@ ansible_net_interfaces:
|
|||
returned: when interfaces is configured
|
||||
type: dict
|
||||
ansible_net_neighbors:
|
||||
description: The list of LLDP neighbors from the remote device
|
||||
description:
|
||||
- The list of CDP and LLDP neighbors from the remote device. If both,
|
||||
CDP and LLDP neighbor data is present on one port, CDP is preferred.
|
||||
returned: when interfaces is configured
|
||||
type: dict
|
||||
"""
|
||||
|
@ -150,6 +152,7 @@ import re
|
|||
|
||||
from ansible.module_utils.network.ios.ios import run_commands
|
||||
from ansible.module_utils.network.ios.ios import ios_argument_spec, check_args
|
||||
from ansible.module_utils.network.ios.ios import normalize_interface
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils.six.moves import zip
|
||||
|
@ -294,7 +297,8 @@ class Interfaces(FactsBase):
|
|||
'show interfaces',
|
||||
'show ip interface',
|
||||
'show ipv6 interface',
|
||||
'show lldp'
|
||||
'show lldp',
|
||||
'show cdp'
|
||||
]
|
||||
|
||||
def populate(self):
|
||||
|
@ -302,6 +306,7 @@ class Interfaces(FactsBase):
|
|||
|
||||
self.facts['all_ipv4_addresses'] = list()
|
||||
self.facts['all_ipv6_addresses'] = list()
|
||||
self.facts['neighbors'] = {}
|
||||
|
||||
data = self.responses[0]
|
||||
if data:
|
||||
|
@ -324,7 +329,15 @@ class Interfaces(FactsBase):
|
|||
if data and not any(err in data for err in lldp_errs):
|
||||
neighbors = self.run(['show lldp neighbors detail'])
|
||||
if neighbors:
|
||||
self.facts['neighbors'] = self.parse_neighbors(neighbors[0])
|
||||
self.facts['neighbors'].update(self.parse_neighbors(neighbors[0]))
|
||||
|
||||
data = self.responses[4]
|
||||
cdp_errs = ['CDP is not enabled']
|
||||
|
||||
if data and not any(err in data for err in cdp_errs):
|
||||
cdp_neighbors = self.run(['show cdp neighbors detail'])
|
||||
if cdp_neighbors:
|
||||
self.facts['neighbors'].update(self.parse_cdp_neighbors(cdp_neighbors[0]))
|
||||
|
||||
def populate_interfaces(self, interfaces):
|
||||
facts = dict()
|
||||
|
@ -387,6 +400,7 @@ class Interfaces(FactsBase):
|
|||
intf = self.parse_lldp_intf(entry)
|
||||
if intf is None:
|
||||
return facts
|
||||
intf = normalize_interface(intf)
|
||||
if intf not in facts:
|
||||
facts[intf] = list()
|
||||
fact = dict()
|
||||
|
@ -395,6 +409,23 @@ class Interfaces(FactsBase):
|
|||
facts[intf].append(fact)
|
||||
return facts
|
||||
|
||||
def parse_cdp_neighbors(self, neighbors):
|
||||
facts = dict()
|
||||
for entry in neighbors.split('-------------------------'):
|
||||
if entry == '':
|
||||
continue
|
||||
intf_port = self.parse_cdp_intf_port(entry)
|
||||
if intf_port is None:
|
||||
return facts
|
||||
intf, port = intf_port
|
||||
if intf not in facts:
|
||||
facts[intf] = list()
|
||||
fact = dict()
|
||||
fact['host'] = self.parse_cdp_host(entry)
|
||||
fact['port'] = port
|
||||
facts[intf].append(fact)
|
||||
return facts
|
||||
|
||||
def parse_interfaces(self, data):
|
||||
parsed = dict()
|
||||
key = ''
|
||||
|
@ -476,6 +507,16 @@ class Interfaces(FactsBase):
|
|||
if match:
|
||||
return match.group(1)
|
||||
|
||||
def parse_cdp_intf_port(self, data):
|
||||
match = re.search(r'^Interface: (.+), Port ID \(outgoing port\): (.+)$', data, re.M)
|
||||
if match:
|
||||
return match.group(1), match.group(2)
|
||||
|
||||
def parse_cdp_host(self, data):
|
||||
match = re.search(r'^Device ID: (.+)$', data, re.M)
|
||||
if match:
|
||||
return match.group(1)
|
||||
|
||||
|
||||
FACT_SUBSETS = dict(
|
||||
default=Default,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Global CDP information:
|
||||
Sending CDP packets every 60 seconds
|
||||
Sending a holdtime value of 180 seconds
|
||||
Sending CDPv2 advertisements is enabled
|
|
@ -0,0 +1,40 @@
|
|||
-------------------------
|
||||
Device ID: R2
|
||||
Entry address(es):
|
||||
IP address: 10.0.0.3
|
||||
Platform: cisco CSR1000V, Capabilities: Router IGMP
|
||||
Interface: GigabitEthernet1, Port ID (outgoing port): GigabitEthernet2
|
||||
Holdtime : 149 sec
|
||||
|
||||
Version :
|
||||
Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.4, RELEASE SOFTWARE (fc3)
|
||||
Technical Support: http://www.cisco.com/techsupport
|
||||
Copyright (c) 1986-2018 by Cisco Systems, Inc.
|
||||
Compiled Sun 08-Jul-18 04:30 by mcpre
|
||||
|
||||
advertisement version: 2
|
||||
Duplex: full
|
||||
Management address(es):
|
||||
IP address: 10.0.0.3
|
||||
|
||||
-------------------------
|
||||
Device ID: R3
|
||||
Entry address(es):
|
||||
IP address: 10.0.0.4
|
||||
Platform: cisco CSR1000V, Capabilities: Router IGMP
|
||||
Interface: GigabitEthernet1, Port ID (outgoing port): GigabitEthernet3
|
||||
Holdtime : 149 sec
|
||||
|
||||
Version :
|
||||
Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.4, RELEASE SOFTWARE (fc3)
|
||||
Technical Support: http://www.cisco.com/techsupport
|
||||
Copyright (c) 1986-2018 by Cisco Systems, Inc.
|
||||
Compiled Sun 08-Jul-18 04:30 by mcpre
|
||||
|
||||
advertisement version: 2
|
||||
Duplex: full
|
||||
Management address(es):
|
||||
IP address: 10.0.0.4
|
||||
|
||||
|
||||
Total cdp entries displayed : 2
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
Global LLDP Information:
|
||||
Status: ACTIVE
|
||||
LLDP advertisements are sent every 30 seconds
|
||||
LLDP hold time advertised is 120 seconds
|
||||
LLDP interface reinitialisation delay is 2 seconds
|
|
@ -0,0 +1,50 @@
|
|||
------------------------------------------------
|
||||
Local Intf: Gi1
|
||||
Chassis id: 001e.14d4.5300
|
||||
Port id: Gi3
|
||||
Port Description: GigabitEthernet3
|
||||
System Name: R3
|
||||
|
||||
System Description:
|
||||
Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.4, RELEASE SOFTWARE (fc3)
|
||||
Technical Support: http://www.cisco.com/techsupport
|
||||
Copyright (c) 1986-2018 by Cisco Systems, Inc.
|
||||
Compiled Sun 08-Jul-18 04:30 by
|
||||
|
||||
Time remaining: 116 seconds
|
||||
System Capabilities: B,R
|
||||
Enabled Capabilities: R
|
||||
Management Addresses:
|
||||
IP: 10.0.0.4
|
||||
Auto Negotiation - not supported
|
||||
Physical media capabilities - not advertised
|
||||
Media Attachment Unit type - not advertised
|
||||
Vlan ID: - not advertised
|
||||
|
||||
------------------------------------------------
|
||||
Local Intf: Gi3
|
||||
Chassis id: 001e.e6c9.6d00
|
||||
Port id: Gi1
|
||||
Port Description: GigabitEthernet1
|
||||
System Name: Rtest
|
||||
|
||||
System Description:
|
||||
Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.4, RELEASE SOFTWARE (fc3)
|
||||
Technical Support: http://www.cisco.com/techsupport
|
||||
Copyright (c) 1986-2018 by Cisco Systems, Inc.
|
||||
Compiled Sun 08-Jul-18 04:30 by
|
||||
|
||||
Time remaining: 116 seconds
|
||||
System Capabilities: B,R
|
||||
Enabled Capabilities: R
|
||||
Management Addresses:
|
||||
IP: 10.3.0.3
|
||||
Auto Negotiation - not supported
|
||||
Physical media capabilities - not advertised
|
||||
Media Attachment Unit type - not advertised
|
||||
Vlan ID: - not advertised
|
||||
|
||||
|
||||
Total entries displayed: 2
|
||||
|
||||
|
|
@ -19,6 +19,7 @@ __metaclass__ = type
|
|||
|
||||
from units.compat.mock import patch
|
||||
from ansible.modules.network.ios import ios_facts
|
||||
from ansible.module_utils.six import assertCountEqual
|
||||
from units.modules.utils import set_module_args
|
||||
from .ios_module import TestIosModule, load_fixture
|
||||
|
||||
|
@ -87,3 +88,20 @@ class TestIosFactsModule(TestIosModule):
|
|||
self.assertEqual(
|
||||
result['ansible_facts']['ansible_net_filesystems_info']['bootflash:']['spacefree_kb'], 6453180.0
|
||||
)
|
||||
|
||||
def test_ios_facts_neighbors(self):
|
||||
set_module_args(dict(gather_subset='interfaces'))
|
||||
result = self.execute_module()
|
||||
assertCountEqual(
|
||||
self,
|
||||
result['ansible_facts']['ansible_net_neighbors'].keys(), ['GigabitEthernet1', 'GigabitEthernet3']
|
||||
)
|
||||
assertCountEqual(
|
||||
self,
|
||||
result['ansible_facts']['ansible_net_neighbors']['GigabitEthernet1'],
|
||||
[{'host': 'R2', 'port': 'GigabitEthernet2'}, {'host': 'R3', 'port': 'GigabitEthernet3'}]
|
||||
)
|
||||
assertCountEqual(
|
||||
self,
|
||||
result['ansible_facts']['ansible_net_neighbors']['GigabitEthernet3'], [{'host': 'Rtest', 'port': 'Gi1'}]
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue