aboutsummaryrefslogtreecommitdiffstats
path: root/app/discover/fetchers/cli/cli_fetch_host_pnics.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/discover/fetchers/cli/cli_fetch_host_pnics.py')
-rw-r--r--app/discover/fetchers/cli/cli_fetch_host_pnics.py122
1 files changed, 122 insertions, 0 deletions
diff --git a/app/discover/fetchers/cli/cli_fetch_host_pnics.py b/app/discover/fetchers/cli/cli_fetch_host_pnics.py
new file mode 100644
index 0000000..3516e25
--- /dev/null
+++ b/app/discover/fetchers/cli/cli_fetch_host_pnics.py
@@ -0,0 +1,122 @@
+###############################################################################
+# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) #
+# and others #
+# #
+# All rights reserved. This program and the accompanying materials #
+# are made available under the terms of the Apache License, Version 2.0 #
+# which accompanies this distribution, and is available at #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+###############################################################################
+import re
+
+from discover.fetchers.cli.cli_access import CliAccess
+from utils.inventory_mgr import InventoryMgr
+
+
+class CliFetchHostPnics(CliAccess):
+ def __init__(self):
+ super().__init__()
+ self.inv = InventoryMgr()
+ self.ethtool_attr = re.compile('^\s+([^:]+):\s(.*)$')
+ self.regexps = [
+ {'name': 'mac_address', 're': '^.*\sHWaddr\s(\S+)(\s.*)?$'},
+ {'name': 'mac_address', 're': '^.*\sether\s(\S+)(\s.*)?$'},
+ {'name': 'IP Address', 're': '^\s*inet addr:?(\S+)\s.*$'},
+ {'name': 'IP Address', 're': '^\s*inet ([0-9.]+)\s.*$'},
+ {'name': 'IPv6 Address', 're': '^\s*inet6 addr:\s*(\S+)(\s.*)?$'},
+ {'name': 'IPv6 Address', 're': '^\s*inet6 \s*(\S+)(\s.*)?$'}
+ ]
+
+ def get(self, id):
+ host_id = id[:id.rindex("-")]
+ cmd = 'ls -l /sys/class/net | grep ^l | grep -v "/virtual/"'
+ host = self.inv.get_by_id(self.get_env(), host_id)
+ if not host:
+ self.log.error("CliFetchHostPnics: host not found: " + host_id)
+ return []
+ if "host_type" not in host:
+ self.log.error("host does not have host_type: " + host_id +
+ ", host: " + str(host))
+ return []
+ host_types = host["host_type"]
+ if "Network" not in host_types and "Compute" not in host_types:
+ return []
+ interface_lines = self.run_fetch_lines(cmd, host_id)
+ interfaces = []
+ for line in interface_lines:
+ interface_name = line[line.rindex('/')+1:]
+ interface_name = interface_name.strip()
+ # run ifconfig with specific interface name,
+ # since running it with no name yields a list without inactive pNICs
+ interface = self.find_interface_details(host_id, interface_name)
+ if interface:
+ interfaces.append(interface)
+ return interfaces
+
+ def find_interface_details(self, host_id, interface_name):
+ lines = self.run_fetch_lines("ifconfig " + interface_name, host_id)
+ interface = None
+ status_up = None
+ for line in [l for l in lines if l != '']:
+ tokens = None
+ if interface is None:
+ tokens = line.split()
+ name = tokens[0].strip('- :')
+ name = name.strip()
+ if name == interface_name:
+ line_remainder = line.strip('-')[len(interface_name)+2:]
+ line_remainder = line_remainder.strip(' :')
+ id = interface_name
+ interface = {
+ "host": host_id,
+ "name": id,
+ "local_name": interface_name,
+ "lines": []
+ }
+ self.handle_line(interface, line_remainder)
+ if '<UP,' in line:
+ status_up = True
+ if status_up is None:
+ if tokens is None:
+ tokens = line.split()
+ if 'BROADCAST' in tokens:
+ status_up = 'UP' in tokens
+ if interface:
+ self.handle_line(interface, line)
+ self.set_interface_data(interface)
+ interface['state'] = 'UP' if status_up else 'DOWN'
+ if 'id' not in interface:
+ interface['id'] = interface_name + '-unknown_mac'
+ return interface
+
+ def handle_line(self, interface, line):
+ self.find_matching_regexps(interface, line, self.regexps)
+ if 'mac_address' in interface:
+ interface["id"] = interface["name"] + "-" + interface["mac_address"]
+ interface["lines"].append(line.strip())
+
+ def set_interface_data(self, interface):
+ if not interface:
+ return
+ interface["data"] = "\n".join(interface["lines"])
+ interface.pop("lines", None)
+ ethtool_ifname = interface["local_name"]
+ if "@" in interface["local_name"]:
+ pos = interface["local_name"].index("@")
+ ethtool_ifname = ethtool_ifname[pos + 1:]
+ cmd = "ethtool " + ethtool_ifname
+ lines = self.run_fetch_lines(cmd, interface["host"])
+ attr = None
+ for line in lines[1:]:
+ matches = self.ethtool_attr.match(line)
+ if matches:
+ # add this attribute to the interface
+ attr = matches.group(1)
+ value = matches.group(2)
+ interface[attr] = value.strip()
+ else:
+ # add more values to the current attribute as an array
+ if isinstance(interface[attr], str):
+ interface[attr] = [interface[attr], line.strip()]
+ else:
+ interface[attr].append(line.strip())