diff --git a/salt/modules/network.py b/salt/modules/network.py index edd8bc4d9b..86ab4d5415 100644 --- a/salt/modules/network.py +++ b/salt/modules/network.py @@ -90,13 +90,38 @@ def traceroute(host): salt '*' network.traceroute archlinux.org ''' ret = [] + if not salt.utils.which('traceroute'): + log.info("This minion does not have traceroute installed") + return ret + cmd = 'traceroute {0}'.format(salt.utils.network.sanitize_host(host)) + out = __salt__['cmd.run'](cmd) # Parse version of traceroute cmd2 = 'traceroute --version' out2 = __salt__['cmd.run'](cmd2) - traceroute_version = re.findall(r'version (\d+)\.(\d+)\.(\d+)', out2)[0] + try: + # Linux traceroute version looks like: + # Modern traceroute for Linux, version 2.0.19, Dec 10 2012 + # Darwin and FreeBSD traceroute version looks like: Version 1.4a12+[FreeBSD|Darwin] + + traceroute_version_raw = re.findall(r'.*[Vv]ersion (\d+)\.([\w\+]+)\.*(\w*)', out2)[0] + log.debug("traceroute_version_raw: {}".format(traceroute_version_raw)) + traceroute_version = [] + for t in traceroute_version_raw: + try: + traceroute_version.append(int(t)) + except ValueError: + traceroute_version.append(t) + + if len(traceroute_version) < 3: + traceroute_version.append(0) + + log.debug("traceroute_version: {}".format(str(traceroute_version))) + + except IndexError: + traceroute_version = [0, 0, 0] for line in out.splitlines(): if ' ' not in line: @@ -104,7 +129,33 @@ def traceroute(host): if line.startswith('traceroute'): continue - if (traceroute_version[0] >= 2 and traceroute_version[2] >= 14 + if ('Darwin' in str(traceroute_version[1]) or 'FreeBSD' in str(traceroute_version[1])): + try: + traceline = re.findall(r'\s*(\d*)\s+(.*)\s+\((.*)\)\s+(.*)$', line)[0] + except IndexError: + traceline = re.findall(r'\s*(\d*)\s+(\*\s+\*\s+\*)', line)[0] + + log.debug("traceline: {}".format(traceline)) + delays = re.findall(r'(\d+\.\d+)\s*ms', str(traceline)) + + try: + if traceline[1] == '* * *': + result = { + 'count': traceline[0], + 'hostname': '*' + } + else: + result = { + 'count': traceline[0], + 'hostname': traceline[1], + 'ip': traceline[2], + } + for x in range(0, len(delays)): + result['ms{}'.format(x+1)] = delays[x] + except IndexError: + result = {} + + elif (traceroute_version[0] >= 2 and traceroute_version[2] >= 14 or traceroute_version[0] >= 2 and traceroute_version[1] > 0): comps = line.split(' ') if comps[1] == '* * *':