netbox-agent/netbox_agent/ethtool.py

80 lines
2.2 KiB
Python
Raw Normal View History

2019-08-04 21:48:06 +02:00
import re
2019-08-04 23:42:08 +02:00
import subprocess
2020-02-02 20:08:56 +01:00
from shutil import which
2019-08-04 21:48:06 +02:00
2019-08-04 14:37:51 +02:00
# Originally from https://github.com/opencoff/useful-scripts/blob/master/linktest.py
# mapping fields from ethtool output to simple names
2019-08-04 15:14:36 +02:00
field_map = {
'Supported ports': 'ports',
2019-08-04 14:37:51 +02:00
'Supported link modes': 'sup_link_modes',
'Supports auto-negotiation': 'sup_autoneg',
2020-02-02 20:08:56 +01:00
'Advertised link modes': 'adv_link_modes',
2019-08-04 14:37:51 +02:00
'Advertised auto-negotiation': 'adv_autoneg',
'Speed': 'speed',
'Duplex': 'duplex',
'Port': 'port',
'Auto-negotiation': 'autoneg',
'Link detected': 'link',
}
2019-08-04 15:14:36 +02:00
2019-08-06 18:15:08 +02:00
def merge_two_dicts(x, y):
z = x.copy()
z.update(y)
return z
2019-08-04 21:48:06 +02:00
class Ethtool():
2019-08-04 15:14:36 +02:00
"""
2019-08-04 21:48:06 +02:00
This class aims to parse ethtool output
There is several bindings to have something proper, but it requires
compilation and other requirements.
2019-08-04 15:14:36 +02:00
"""
2020-02-02 20:08:56 +01:00
2019-08-04 21:48:06 +02:00
def __init__(self, interface, *args, **kwargs):
self.interface = interface
def _parse_ethtool_output(self):
"""
parse ethtool output
"""
output = subprocess.getoutput('ethtool {}'.format(self.interface))
fields = {}
field = ''
fields['speed'] = '-'
fields['link'] = '-'
fields['duplex'] = '-'
for line in output.split('\n')[1:]:
line = line.rstrip()
r = line.find(':')
if r > 0:
field = line[:r].strip()
if field not in field_map:
continue
field = field_map[field]
2020-02-02 20:08:56 +01:00
output = line[r + 1:].strip()
2019-08-04 21:48:06 +02:00
fields[field] = output
else:
if len(field) > 0 and \
field in field_map:
fields[field] += ' ' + line.strip()
return fields
def _parse_ethtool_module_output(self):
status, output = subprocess.getstatusoutput('ethtool -m {}'.format(self.interface))
if status == 0:
r = re.search(r'Identifier.*\((\w+)\)', output)
if r and len(r.groups()) > 0:
return {'form_factor': r.groups()[0]}
return {}
2019-08-04 14:37:51 +02:00
2019-08-04 21:48:06 +02:00
def parse(self):
if which('ethtool') is None:
return None
output = self._parse_ethtool_output()
output.update(self._parse_ethtool_module_output())
return output