Skip to content

Commit

Permalink
NX-OS ping implementation using more shared common code (#642)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktbyers authored Feb 19, 2018
1 parent 6737d62 commit b6e013a
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 1 deletion.
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/
116 changes: 116 additions & 0 deletions napalm/nxos/nxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,115 @@ def commit_config(self):
else:
raise ReplaceConfigException('No config loaded.')

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._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


class NXOSDriver(NXOSDriverBase):
def __init__(self, hostname, username, password, timeout=60, optional_args=None):
Expand Down Expand Up @@ -110,6 +219,13 @@ def close(self):
self._delete_file(self.backup_file)
self.device = None

def _send_command(self, command):
"""Wrapper for CLI method in NX-API.
Allows more code sharing between NX-API and SSH.
"""
return self.cli([command]).get(command)

@staticmethod
def _compute_timestamp(stupid_cisco_output):
"""
Expand Down
4 changes: 4 additions & 0 deletions napalm/nxos_ssh/nxos_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ def close(self):
self.device.disconnect()
self.device = None

def _send_command(self, command):
"""Wrapper for Netmiko's send_command method."""
return self.device.send_command(command)

@staticmethod
def parse_uptime(uptime_str):
"""
Expand Down
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"success": {
"rtt_stddev": 0.0,
"rtt_min": 0.0,
"results": [],
"rtt_max": 0.0,
"packet_loss": 5,
"rtt_avg": 0.0,
"probes_sent": 5
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
PING 8.8.8.8 (8.8.8.8): 100 data bytes
Request 0 timed out
Request 1 timed out
Request 2 timed out
Request 3 timed out
Request 4 timed out

--- 8.8.8.8 ping statistics ---
5 packets transmitted, 0 packets received, 100.00% packet loss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"success": {
"rtt_stddev": 0.0,
"rtt_min": 0.0,
"results": [],
"rtt_max": 0.0,
"packet_loss": 5,
"rtt_avg": 0.0,
"probes_sent": 5
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
5 packets transmitted, 0 packets received, 100.00% packet loss

PING 8.8.8.8 (8.8.8.8): 100 data bytes
36 bytes from 10.150.102.3: Destination Host Unreachable
Request 0 timed out
36 bytes from 10.150.102.3: Destination Host Unreachable
Request 1 timed out
36 bytes from 10.150.102.3: Destination Host Unreachable
Request 2 timed out
36 bytes from 10.150.102.3: Destination Host Unreachable
Request 3 timed out
36 bytes from 10.150.102.3: Destination Host Unreachable
Request 4 timed out

--- 8.8.8.8 ping statistics ---
5 packets transmitted, 0 packets received, 100.00% packet loss
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

0 comments on commit b6e013a

Please sign in to comment.