mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-05-03 15:51:30 -07:00
This completes the refactor of the nxos modules to use the persistent connection. It also updates all of the nxos modules to use the new connection module and preserves use of nxapi as well.
260 lines
7.5 KiB
Python
260 lines
7.5 KiB
Python
#!/usr/bin/python
|
|
#
|
|
# This file is part of Ansible
|
|
#
|
|
# Ansible is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Ansible is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
ANSIBLE_METADATA = {'status': ['preview'],
|
|
'supported_by': 'community',
|
|
'version': '1.0'}
|
|
|
|
DOCUMENTATION = '''
|
|
---
|
|
module: nxos_ping
|
|
version_added: "2.1"
|
|
short_description: Tests reachability using ping from Nexus switch.
|
|
description:
|
|
- Tests reachability using ping from switch to a remote destination.
|
|
author:
|
|
- Jason Edelman (@jedelman8)
|
|
- Gabriele Gerbino (@GGabriele)
|
|
options:
|
|
dest:
|
|
description:
|
|
- IP address or hostname (resolvable by switch) of remote node.
|
|
required: true
|
|
count:
|
|
description:
|
|
- Number of packets to send.
|
|
required: false
|
|
default: 2
|
|
source:
|
|
description:
|
|
- Source IP Address.
|
|
required: false
|
|
default: null
|
|
vrf:
|
|
description:
|
|
- Outgoing VRF.
|
|
required: false
|
|
default: null
|
|
'''
|
|
|
|
EXAMPLES = '''
|
|
- name: Test reachability to 8.8.8.8 using mgmt vrf
|
|
nxos_ping:
|
|
dest: 8.8.8.8
|
|
vrf: management
|
|
host: 68.170.147.165
|
|
|
|
- name: Test reachability to a few different public IPs using mgmt vrf
|
|
nxos_ping:
|
|
dest: nxos_ping
|
|
vrf: management
|
|
host: 68.170.147.165
|
|
with_items:
|
|
- 8.8.8.8
|
|
- 4.4.4.4
|
|
- 198.6.1.4
|
|
'''
|
|
|
|
RETURN = '''
|
|
action:
|
|
description:
|
|
- Show what action has been performed
|
|
returned: always
|
|
type: string
|
|
sample: "PING 8.8.8.8 (8.8.8.8): 56 data bytes"
|
|
updates:
|
|
description: Show the command sent
|
|
returned: always
|
|
type: list
|
|
sample: ["ping 8.8.8.8 count 2 vrf management"]
|
|
count:
|
|
description: Show amount of packets sent
|
|
returned: always
|
|
type: string
|
|
sample: "2"
|
|
dest:
|
|
description: Show the ping destination
|
|
returned: always
|
|
type: string
|
|
sample: "8.8.8.8"
|
|
rtt:
|
|
description: Show RTT stats
|
|
returned: always
|
|
type: dict
|
|
sample: {"avg": "6.264","max":"6.564",
|
|
"min": "5.978"}
|
|
packets_rx:
|
|
description: Packets successfully received
|
|
returned: always
|
|
type: string
|
|
sample: "2"
|
|
packets_tx:
|
|
description: Packets successfully transmitted
|
|
returned: always
|
|
type: string
|
|
sample: "2"
|
|
packet_loss:
|
|
description: Percentage of packets lost
|
|
returned: always
|
|
type: string
|
|
sample: "0.00%"
|
|
'''
|
|
from ansible.module_utils.nxos import get_config, load_config, run_commands
|
|
from ansible.module_utils.nxos import nxos_argument_spec, check_args
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
def get_summary(results_list, reference_point):
|
|
summary_string = results_list[reference_point+1]
|
|
summary_list = summary_string.split(',')
|
|
pkts_tx = summary_list[0].split('packets')[0].strip()
|
|
pkts_rx = summary_list[1].split('packets')[0].strip()
|
|
pkt_loss = summary_list[2].split('packet')[0].strip()
|
|
summary = dict(packets_tx=pkts_tx,
|
|
packets_rx=pkts_rx,
|
|
packet_loss=pkt_loss)
|
|
|
|
if 'bytes from' not in results_list[reference_point-2]:
|
|
ping_pass = False
|
|
else:
|
|
ping_pass = True
|
|
|
|
return summary, ping_pass
|
|
|
|
|
|
def get_rtt(results_list, packet_loss, location):
|
|
if packet_loss != '100.00%':
|
|
rtt_string = results_list[location]
|
|
base = rtt_string.split('=')[1]
|
|
rtt_list = base.split('/')
|
|
min_rtt = rtt_list[0].lstrip()
|
|
avg_rtt = rtt_list[1]
|
|
max_rtt = rtt_list[2][:-3]
|
|
rtt = dict(min=min_rtt, avg=avg_rtt, max=max_rtt)
|
|
else:
|
|
rtt = dict(min=None, avg=None, max=None)
|
|
|
|
return rtt
|
|
|
|
|
|
def get_statistics_summary_line(response_as_list):
|
|
for each in response_as_list:
|
|
if '---' in each:
|
|
index = response_as_list.index(each)
|
|
return index
|
|
|
|
|
|
def get_ping_results(command, module, transport):
|
|
cmd = {'command': command, 'output': 'text'}
|
|
ping = run_commands(module, [cmd])[0]
|
|
|
|
if not ping:
|
|
module.fail_json(msg="An unexpected error occurred. Check all params.",
|
|
command=command, destination=module.params['dest'],
|
|
vrf=module.params['vrf'],
|
|
source=module.params['source'])
|
|
|
|
elif "can't bind to address" in ping:
|
|
module.fail_json(msg="Can't bind to source address.", command=command)
|
|
elif "bad context" in ping:
|
|
module.fail_json(msg="Wrong VRF name inserted.", command=command,
|
|
vrf=module.params['vrf'])
|
|
else:
|
|
splitted_ping = ping.split('\n')
|
|
reference_point = get_statistics_summary_line(splitted_ping)
|
|
summary, ping_pass = get_summary(splitted_ping, reference_point)
|
|
rtt = get_rtt(splitted_ping, summary['packet_loss'], reference_point+2)
|
|
|
|
return (splitted_ping, summary, rtt, ping_pass)
|
|
|
|
|
|
def main():
|
|
argument_spec = dict(
|
|
dest=dict(required=True),
|
|
count=dict(required=False, default=2),
|
|
vrf=dict(required=False),
|
|
source=dict(required=False),
|
|
state=dict(required=False, choices=['present', 'absent'],
|
|
default='present'),
|
|
include_defaults=dict(default=False),
|
|
config=dict(),
|
|
save=dict(type='bool', default=False)
|
|
)
|
|
|
|
argument_spec.update(nxos_argument_spec)
|
|
|
|
module = AnsibleModule(argument_spec=argument_spec,
|
|
supports_check_mode=True)
|
|
|
|
warnings = list()
|
|
check_args(module, warnings)
|
|
|
|
|
|
destination = module.params['dest']
|
|
count = module.params['count']
|
|
vrf = module.params['vrf']
|
|
source = module.params['source']
|
|
state = module.params['state']
|
|
|
|
if count:
|
|
try:
|
|
if int(count) < 1 or int(count) > 655350:
|
|
raise ValueError
|
|
except ValueError:
|
|
module.fail_json(msg="'count' must be an integer between 1 "
|
|
"and 655350.", count=count)
|
|
|
|
OPTIONS = {
|
|
'vrf': vrf,
|
|
'count': count,
|
|
'source': source
|
|
}
|
|
|
|
ping_command = 'ping {0}'.format(destination)
|
|
for command, arg in OPTIONS.items():
|
|
if arg:
|
|
ping_command += ' {0} {1}'.format(command, arg)
|
|
|
|
ping_results, summary, rtt, ping_pass = get_ping_results(
|
|
ping_command, module, module.params['transport'])
|
|
|
|
packet_loss = summary['packet_loss']
|
|
packets_rx = summary['packets_rx']
|
|
packets_tx = summary['packets_tx']
|
|
|
|
results = {}
|
|
results['updates'] = [ping_command]
|
|
results['action'] = ping_results[1]
|
|
results['dest'] = destination
|
|
results['count'] = count
|
|
results['packets_tx'] = packets_tx
|
|
results['packets_rx'] = packets_rx
|
|
results['packet_loss'] = packet_loss
|
|
results['rtt'] = rtt
|
|
results['state'] = module.params['state']
|
|
|
|
if ping_pass and state == 'absent':
|
|
module.fail_json(msg="Ping succeeded unexpectedly", results=results)
|
|
elif not ping_pass and state == 'present':
|
|
module.fail_json(msg="Ping failed unexpectedly", results=results)
|
|
else:
|
|
module.exit_json(**results)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|