Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ping functionalty to nxos driver #641

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ test/unit/test_devices.py

report.json
tags
.pytest_cache/

docs/integrations/ansible/modules/napalm_*/
docs/integrations/ansible/modules/source/*.json
docs/napalm_ansible_repo/
docs/napalm_ansible_repo/
109 changes: 109 additions & 0 deletions napalm/nxos/nxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -978,3 +978,112 @@ def get_config(self, retrieve='all'):
_cmd = 'show startup-config'
config['startup'] = py23_compat.text_type(self.cli([_cmd]).get(_cmd))
return config

def ping(self,
destination,
source=c.PING_SOURCE,
ttl=c.PING_TTL,
timeout=c.PING_TIMEOUT,
size=c.PING_SIZE,
count=c.PING_COUNT,
vrf=c.PING_VRF):
"""
Execute ping on the device and returns a dictionary with the result.
Output dictionary has one of following keys:
* success
* error
In case of success, inner dictionary will have the followin keys:
* probes_sent (int)
* packet_loss (int)
* rtt_min (float)
* rtt_max (float)
* rtt_avg (float)
* rtt_stddev (float)
* results (list)
'results' is a list of dictionaries with the following keys:
* ip_address (str)
* rtt (float)
"""
ping_dict = {}

version = ''
try:
version = '6' if IPAddress(destination).version == 6 else ''
except AddrFormatError:
# Allow use of DNS names
pass

command = 'ping{version} {destination}'.format(
version=version,
destination=destination)
command += ' timeout {}'.format(timeout)
command += ' packet-size {}'.format(size)
command += ' count {}'.format(count)
if source != '':
command += ' source {}'.format(source)

if vrf != '':
command += ' vrf {}'.format(vrf)
output = self.cli([command]).get(command)

if 'connect:' in output:
ping_dict['error'] = output
elif 'PING' in output:
ping_dict['success'] = {
'probes_sent': 0,
'packet_loss': 0,
'rtt_min': 0.0,
'rtt_max': 0.0,
'rtt_avg': 0.0,
'rtt_stddev': 0.0,
'results': []
}
results_array = []
for line in output.splitlines():
fields = line.split()
if 'icmp' in line:
if 'Unreachable' in line:
if "(" in fields[2]:
results_array.append(
{
'ip_address': py23_compat.text_type(fields[2][1:-1]),
'rtt': 0.0,
}
)
else:
results_array.append({'ip_address': py23_compat.text_type(fields[1]),
'rtt': 0.0})
elif 'truncated' in line:
if "(" in fields[4]:
results_array.append(
{
'ip_address': py23_compat.text_type(fields[4][1:-2]),
'rtt': 0.0,
}
)
else:
results_array.append(
{
'ip_address': py23_compat.text_type(fields[3][:-1]),
'rtt': 0.0,
}
)
elif fields[1] == 'bytes':
if version == '6':
m = fields[5][5:]
else:
m = fields[6][5:]
results_array.append({'ip_address': py23_compat.text_type(fields[3][:-1]),
'rtt': float(m)})
elif 'packets transmitted' in line:
ping_dict['success']['probes_sent'] = int(fields[0])
ping_dict['success']['packet_loss'] = int(fields[0]) - int(fields[3])
elif 'min/avg/max' in line:
m = fields[3].split('/')
ping_dict['success'].update({
'rtt_min': float(m[0]),
'rtt_avg': float(m[1]),
'rtt_max': float(m[2]),
})
ping_dict['success'].update({'results': results_array})
return ping_dict
109 changes: 109 additions & 0 deletions napalm/nxos_ssh/nxos_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -1524,3 +1524,112 @@ def get_config(self, retrieve='all'):
command = 'show startup-config'
config['startup'] = py23_compat.text_type(self.device.send_command(command))
return config

def ping(self,
destination,
source=c.PING_SOURCE,
ttl=c.PING_TTL,
timeout=c.PING_TIMEOUT,
size=c.PING_SIZE,
count=c.PING_COUNT,
vrf=c.PING_VRF):
"""
Execute ping on the device and returns a dictionary with the result.
Output dictionary has one of following keys:
* success
* error
In case of success, inner dictionary will have the followin keys:
* probes_sent (int)
* packet_loss (int)
* rtt_min (float)
* rtt_max (float)
* rtt_avg (float)
* rtt_stddev (float)
* results (list)
'results' is a list of dictionaries with the following keys:
* ip_address (str)
* rtt (float)
"""
ping_dict = {}

version = ''
try:
version = '6' if IPAddress(destination).version == 6 else ''
except AddrFormatError:
# Allow use of DNS names
pass

command = 'ping{version} {destination}'.format(
version=version,
destination=destination)
command += ' timeout {}'.format(timeout)
command += ' packet-size {}'.format(size)
command += ' count {}'.format(count)
if source != '':
command += ' source {}'.format(source)

if vrf != '':
command += ' vrf {}'.format(vrf)
output = self.device.send_command(command)

if 'connect:' in output:
ping_dict['error'] = output
elif 'PING' in output:
ping_dict['success'] = {
'probes_sent': 0,
'packet_loss': 0,
'rtt_min': 0.0,
'rtt_max': 0.0,
'rtt_avg': 0.0,
'rtt_stddev': 0.0,
'results': []
}
results_array = []
for line in output.splitlines():
fields = line.split()
if 'icmp' in line:
if 'Unreachable' in line:
if "(" in fields[2]:
results_array.append(
{
'ip_address': py23_compat.text_type(fields[2][1:-1]),
'rtt': 0.0,
}
)
else:
results_array.append({'ip_address': py23_compat.text_type(fields[1]),
'rtt': 0.0})
elif 'truncated' in line:
if "(" in fields[4]:
results_array.append(
{
'ip_address': py23_compat.text_type(fields[4][1:-2]),
'rtt': 0.0,
}
)
else:
results_array.append(
{
'ip_address': py23_compat.text_type(fields[3][:-1]),
'rtt': 0.0,
}
)
elif fields[1] == 'bytes':
if version == '6':
m = fields[5][5:]
else:
m = fields[6][5:]
results_array.append({'ip_address': py23_compat.text_type(fields[3][:-1]),
'rtt': float(m)})
elif 'packets transmitted' in line:
ping_dict['success']['probes_sent'] = int(fields[0])
ping_dict['success']['packet_loss'] = int(fields[0]) - int(fields[3])
elif 'min/avg/max' in line:
m = fields[3].split('/')
ping_dict['success'].update({
'rtt_min': float(m[0]),
'rtt_avg': float(m[1]),
'rtt_max': float(m[2]),
})
ping_dict['success'].update({'results': results_array})
return ping_dict
32 changes: 32 additions & 0 deletions test/nxos/mocked_data/test_ping/normal/expected_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"success": {
"rtt_stddev": 0,
"rtt_min": 18.104,
"results": [
{
"ip_address": "8.8.8.8",
"rtt": 18.411
},
{
"ip_address": "8.8.8.8",
"rtt": 18.189
},
{
"ip_address": "8.8.8.8",
"rtt": 18.13
},
{
"ip_address": "8.8.8.8",
"rtt": 18.16
},
{
"ip_address": "8.8.8.8",
"rtt": 18.104
}
],
"rtt_max": 18.411,
"packet_loss": 0,
"rtt_avg": 18.198,
"probes_sent": 5
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
PING 8.8.8.8 (8.8.8.8): 100 data bytes
108 bytes from 8.8.8.8: icmp_seq=0 ttl=57 time=18.411 ms
108 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=18.189 ms
108 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=18.13 ms
108 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=18.16 ms
108 bytes from 8.8.8.8: icmp_seq=4 ttl=57 time=18.104 ms

--- 8.8.8.8 ping statistics ---
5 packets transmitted, 5 packets received, 0.00% packet loss
round-trip min/avg/max = 18.104/18.198/18.411 ms
32 changes: 32 additions & 0 deletions test/nxos_ssh/mocked_data/test_ping/normal/expected_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"success": {
"rtt_stddev": 0,
"rtt_min": 18.104,
"results": [
{
"ip_address": "8.8.8.8",
"rtt": 18.411
},
{
"ip_address": "8.8.8.8",
"rtt": 18.189
},
{
"ip_address": "8.8.8.8",
"rtt": 18.13
},
{
"ip_address": "8.8.8.8",
"rtt": 18.16
},
{
"ip_address": "8.8.8.8",
"rtt": 18.104
}
],
"rtt_max": 18.411,
"packet_loss": 0,
"rtt_avg": 18.198,
"probes_sent": 5
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
PING 8.8.8.8 (8.8.8.8): 100 data bytes
108 bytes from 8.8.8.8: icmp_seq=0 ttl=57 time=18.411 ms
108 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=18.189 ms
108 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=18.13 ms
108 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=18.16 ms
108 bytes from 8.8.8.8: icmp_seq=4 ttl=57 time=18.104 ms

--- 8.8.8.8 ping statistics ---
5 packets transmitted, 5 packets received, 0.00% packet loss
round-trip min/avg/max = 18.104/18.198/18.411 ms