|
|
@ -167,7 +167,6 @@ class Default(FactsBase):
|
|
|
|
COMMANDS = [
|
|
|
|
COMMANDS = [
|
|
|
|
'show version | display-xml',
|
|
|
|
'show version | display-xml',
|
|
|
|
'show system | display-xml',
|
|
|
|
'show system | display-xml',
|
|
|
|
'show running-configuration | grep hostname'
|
|
|
|
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def populate(self):
|
|
|
|
def populate(self):
|
|
|
@ -177,15 +176,13 @@ class Default(FactsBase):
|
|
|
|
|
|
|
|
|
|
|
|
self.facts['name'] = self.parse_name(xml_data)
|
|
|
|
self.facts['name'] = self.parse_name(xml_data)
|
|
|
|
self.facts['version'] = self.parse_version(xml_data)
|
|
|
|
self.facts['version'] = self.parse_version(xml_data)
|
|
|
|
|
|
|
|
self.facts['model'] = self.parse_model(xml_data)
|
|
|
|
|
|
|
|
self.facts['hostname'] = self.parse_hostname(xml_data)
|
|
|
|
|
|
|
|
|
|
|
|
data = self.responses[1]
|
|
|
|
data = self.responses[1]
|
|
|
|
xml_data = ET.fromstring(data)
|
|
|
|
xml_data = ET.fromstring(data)
|
|
|
|
|
|
|
|
|
|
|
|
self.facts['servicetag'] = self.parse_serialnum(xml_data)
|
|
|
|
self.facts['servicetag'] = self.parse_servicetag(xml_data)
|
|
|
|
self.facts['model'] = self.parse_model(xml_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data = self.responses[2]
|
|
|
|
|
|
|
|
self.facts['hostname'] = self.parse_hostname(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_name(self, data):
|
|
|
|
def parse_name(self, data):
|
|
|
|
sw_name = data.find('./data/system-sw-state/sw-version/sw-name')
|
|
|
|
sw_name = data.find('./data/system-sw-state/sw-version/sw-name')
|
|
|
@ -202,18 +199,20 @@ class Default(FactsBase):
|
|
|
|
return ""
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
def parse_hostname(self, data):
|
|
|
|
def parse_hostname(self, data):
|
|
|
|
match = re.search(r'hostname\s+(\S+)', data, re.M)
|
|
|
|
hostname = data.find('./data/system-state/system-status/hostname')
|
|
|
|
if match:
|
|
|
|
if hostname is not None:
|
|
|
|
return match.group(1)
|
|
|
|
return hostname.text
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
def parse_model(self, data):
|
|
|
|
def parse_model(self, data):
|
|
|
|
prod_name = data.find('./data/system/node/mfg-info/product-name')
|
|
|
|
prod_name = data.find('./data/system-sw-state/sw-version/sw-platform')
|
|
|
|
if prod_name is not None:
|
|
|
|
if prod_name is not None:
|
|
|
|
return prod_name.text
|
|
|
|
return prod_name.text
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
return ""
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
def parse_serialnum(self, data):
|
|
|
|
def parse_servicetag(self, data):
|
|
|
|
svc_tag = data.find('./data/system/node/unit/mfg-info/service-tag')
|
|
|
|
svc_tag = data.find('./data/system/node/unit/mfg-info/service-tag')
|
|
|
|
if svc_tag is not None:
|
|
|
|
if svc_tag is not None:
|
|
|
|
return svc_tag.text
|
|
|
|
return svc_tag.text
|
|
|
@ -225,7 +224,7 @@ class Hardware(FactsBase):
|
|
|
|
|
|
|
|
|
|
|
|
COMMANDS = [
|
|
|
|
COMMANDS = [
|
|
|
|
'show version | display-xml',
|
|
|
|
'show version | display-xml',
|
|
|
|
'show processes memory | grep Total'
|
|
|
|
'show processes node-id 1 | grep "Mem:"'
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def populate(self):
|
|
|
|
def populate(self):
|
|
|
@ -251,7 +250,7 @@ class Hardware(FactsBase):
|
|
|
|
return ""
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
def parse_memory(self, data):
|
|
|
|
def parse_memory(self, data):
|
|
|
|
return re.findall(r'\:\s*(\d+)', data, re.M)
|
|
|
|
return re.findall(r'(\d+)', data, re.M)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Config(FactsBase):
|
|
|
|
class Config(FactsBase):
|
|
|
@ -267,22 +266,66 @@ class Interfaces(FactsBase):
|
|
|
|
|
|
|
|
|
|
|
|
COMMANDS = [
|
|
|
|
COMMANDS = [
|
|
|
|
'show interface | display-xml',
|
|
|
|
'show interface | display-xml',
|
|
|
|
|
|
|
|
'show lldp neighbors | display-xml'
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, module):
|
|
|
|
|
|
|
|
self.intf_facts = dict()
|
|
|
|
|
|
|
|
self.lldp_facts = dict()
|
|
|
|
|
|
|
|
super(Interfaces, self).__init__(module)
|
|
|
|
|
|
|
|
|
|
|
|
def populate(self):
|
|
|
|
def populate(self):
|
|
|
|
super(Interfaces, self).populate()
|
|
|
|
super(Interfaces, self).populate()
|
|
|
|
self.facts['all_ipv4_addresses'] = list()
|
|
|
|
self.facts['all_ipv4_addresses'] = list()
|
|
|
|
self.facts['all_ipv6_addresses'] = list()
|
|
|
|
self.facts['all_ipv6_addresses'] = list()
|
|
|
|
|
|
|
|
|
|
|
|
data = self.responses[0]
|
|
|
|
int_show_data = (self.responses[0]).splitlines()
|
|
|
|
|
|
|
|
pattern = '?xml version'
|
|
|
|
|
|
|
|
data = ''
|
|
|
|
|
|
|
|
skip = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# The output returns multiple xml trees
|
|
|
|
|
|
|
|
# parse them before handling.
|
|
|
|
|
|
|
|
for line in int_show_data:
|
|
|
|
|
|
|
|
if pattern in line:
|
|
|
|
|
|
|
|
if skip is False:
|
|
|
|
|
|
|
|
xml_data = ET.fromstring(data)
|
|
|
|
|
|
|
|
self.populate_interfaces(xml_data)
|
|
|
|
|
|
|
|
data = ''
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
skip = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data += line
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if skip is False:
|
|
|
|
xml_data = ET.fromstring(data)
|
|
|
|
xml_data = ET.fromstring(data)
|
|
|
|
|
|
|
|
self.populate_interfaces(xml_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.facts['interfaces'] = self.intf_facts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lldp_data = (self.responses[1]).splitlines()
|
|
|
|
|
|
|
|
data = ''
|
|
|
|
|
|
|
|
skip = True
|
|
|
|
|
|
|
|
# The output returns multiple xml trees
|
|
|
|
|
|
|
|
# parse them before handling.
|
|
|
|
|
|
|
|
for line in lldp_data:
|
|
|
|
|
|
|
|
if pattern in line:
|
|
|
|
|
|
|
|
if skip is False:
|
|
|
|
|
|
|
|
xml_data = ET.fromstring(data)
|
|
|
|
|
|
|
|
self.populate_neighbors(xml_data)
|
|
|
|
|
|
|
|
data = ''
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
skip = False
|
|
|
|
|
|
|
|
|
|
|
|
self.facts['interfaces'] = self.populate_interfaces(xml_data)
|
|
|
|
data += line
|
|
|
|
self.facts['neighbors'] = self.populate_neighbors(xml_data)
|
|
|
|
|
|
|
|
|
|
|
|
if skip is False:
|
|
|
|
|
|
|
|
xml_data = ET.fromstring(data)
|
|
|
|
|
|
|
|
self.populate_neighbors(xml_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.facts['neighbors'] = self.lldp_facts
|
|
|
|
|
|
|
|
|
|
|
|
def populate_interfaces(self, interfaces):
|
|
|
|
def populate_interfaces(self, interfaces):
|
|
|
|
int_facts = dict()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for interface in interfaces.findall('./data/interfaces/interface'):
|
|
|
|
for interface in interfaces.findall('./data/interfaces/interface'):
|
|
|
|
intf = dict()
|
|
|
|
intf = dict()
|
|
|
@ -296,15 +339,19 @@ class Interfaces(FactsBase):
|
|
|
|
intf['mtu'] = self.parse_item(interface, 'mtu')
|
|
|
|
intf['mtu'] = self.parse_item(interface, 'mtu')
|
|
|
|
intf['type'] = self.parse_item(interface, 'type')
|
|
|
|
intf['type'] = self.parse_item(interface, 'type')
|
|
|
|
|
|
|
|
|
|
|
|
int_facts[name] = intf
|
|
|
|
self.intf_facts[name] = intf
|
|
|
|
|
|
|
|
|
|
|
|
for interface in interfaces.findall('./data/interfaces-state/interface'):
|
|
|
|
for interface in interfaces.findall('./bulk/data/interface'):
|
|
|
|
name = self.parse_item(interface, 'name')
|
|
|
|
name = self.parse_item(interface, 'name')
|
|
|
|
intf = int_facts[name]
|
|
|
|
try:
|
|
|
|
|
|
|
|
intf = self.intf_facts[name]
|
|
|
|
intf['bandwidth'] = self.parse_item(interface, 'speed')
|
|
|
|
intf['bandwidth'] = self.parse_item(interface, 'speed')
|
|
|
|
intf['adminstatus'] = self.parse_item(interface, 'admin-status')
|
|
|
|
intf['adminstatus'] = self.parse_item(interface, 'admin-status')
|
|
|
|
intf['operstatus'] = self.parse_item(interface, 'oper-status')
|
|
|
|
intf['operstatus'] = self.parse_item(interface, 'oper-status')
|
|
|
|
intf['macaddress'] = self.parse_item(interface, 'phys-address')
|
|
|
|
intf['macaddress'] = self.parse_item(interface, 'phys-address')
|
|
|
|
|
|
|
|
except KeyError:
|
|
|
|
|
|
|
|
# skip the reserved interfaces
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
for interface in interfaces.findall('./data/ports/ports-state/port'):
|
|
|
|
for interface in interfaces.findall('./data/ports/ports-state/port'):
|
|
|
|
name = self.parse_item(interface, 'name')
|
|
|
|
name = self.parse_item(interface, 'name')
|
|
|
@ -314,20 +361,19 @@ class Interfaces(FactsBase):
|
|
|
|
typ, sname = name.split('-eth')
|
|
|
|
typ, sname = name.split('-eth')
|
|
|
|
name = "ethernet" + sname
|
|
|
|
name = "ethernet" + sname
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
intf = int_facts[name]
|
|
|
|
intf = self.intf_facts[name]
|
|
|
|
intf['mediatype'] = mediatype
|
|
|
|
intf['mediatype'] = mediatype
|
|
|
|
except:
|
|
|
|
except:
|
|
|
|
# fanout
|
|
|
|
# fanout
|
|
|
|
for subport in xrange(1, 5):
|
|
|
|
for subport in xrange(1, 5):
|
|
|
|
name = "ethernet" + sname + ":" + str(subport)
|
|
|
|
name = "ethernet" + sname + ":" + str(subport)
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
intf = int_facts[name]
|
|
|
|
intf = self.intf_facts[name]
|
|
|
|
intf['mediatype'] = mediatype
|
|
|
|
intf['mediatype'] = mediatype
|
|
|
|
except:
|
|
|
|
except:
|
|
|
|
|
|
|
|
# valid case to handle 2x50G
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
return int_facts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_ip_address(self, address, family):
|
|
|
|
def add_ip_address(self, address, family):
|
|
|
|
if family == 'ipv4':
|
|
|
|
if family == 'ipv4':
|
|
|
|
self.facts['all_ipv4_addresses'].append(address)
|
|
|
|
self.facts['all_ipv4_addresses'].append(address)
|
|
|
@ -364,30 +410,31 @@ class Interfaces(FactsBase):
|
|
|
|
return ip_address
|
|
|
|
return ip_address
|
|
|
|
|
|
|
|
|
|
|
|
def parse_ipv6_address(self, interface):
|
|
|
|
def parse_ipv6_address(self, interface):
|
|
|
|
ipv6 = interface.find('ipv6')
|
|
|
|
|
|
|
|
ip_address = ""
|
|
|
|
ip_address = list()
|
|
|
|
if ipv6 is not None:
|
|
|
|
|
|
|
|
ipv6_addr = ipv6.find('./address/ipv6-address')
|
|
|
|
for addr in interface.findall('./ipv6/ipv6-addresses/address'):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ipv6_addr = addr.find('./ipv6-address')
|
|
|
|
|
|
|
|
|
|
|
|
if ipv6_addr is not None:
|
|
|
|
if ipv6_addr is not None:
|
|
|
|
ip_address = ipv6_addr.text
|
|
|
|
ip_address.append(ipv6_addr.text)
|
|
|
|
self.add_ip_address(ip_address, 'ipv6')
|
|
|
|
self.add_ip_address(ipv6_addr.text, 'ipv6')
|
|
|
|
|
|
|
|
|
|
|
|
return ip_address
|
|
|
|
return ip_address
|
|
|
|
|
|
|
|
|
|
|
|
def populate_neighbors(self, interfaces):
|
|
|
|
def populate_neighbors(self, interfaces):
|
|
|
|
lldp_facts = dict()
|
|
|
|
for interface in interfaces.findall('./bulk/data/interface'):
|
|
|
|
for interface in interfaces.findall('./data/interfaces-state/interface'):
|
|
|
|
|
|
|
|
name = interface.find('name').text
|
|
|
|
name = interface.find('name').text
|
|
|
|
rem_sys_name = interface.find('./lldp-rem-neighbor-info/info/rem-system-name')
|
|
|
|
rem_sys_name = interface.find('./lldp-rem-neighbor-info/info/rem-system-name')
|
|
|
|
if rem_sys_name is not None:
|
|
|
|
if rem_sys_name is not None:
|
|
|
|
lldp_facts[name] = list()
|
|
|
|
self.lldp_facts[name] = list()
|
|
|
|
fact = dict()
|
|
|
|
fact = dict()
|
|
|
|
fact['host'] = rem_sys_name.text
|
|
|
|
fact['host'] = rem_sys_name.text
|
|
|
|
rem_sys_port = interface.find('./lldp-rem-neighbor-info/info/rem-lldp-port-id')
|
|
|
|
rem_sys_port = interface.find('./lldp-rem-neighbor-info/info/rem-lldp-port-id')
|
|
|
|
fact['port'] = rem_sys_port.text
|
|
|
|
fact['port'] = rem_sys_port.text
|
|
|
|
lldp_facts[name].append(fact)
|
|
|
|
self.lldp_facts[name].append(fact)
|
|
|
|
|
|
|
|
|
|
|
|
return lldp_facts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FACT_SUBSETS = dict(
|
|
|
|
FACT_SUBSETS = dict(
|
|
|
|
default=Default,
|
|
|
|
default=Default,
|
|
|
|