Skip to content

Commit 7d65533

Browse files
authored
Merge pull request #74 from QualiSystems/dev
cloudshell-networking-cisco-5.2.6
2 parents c8c3048 + 742d390 commit 7d65533

File tree

14 files changed

+469
-166
lines changed

14 files changed

+469
-166
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,7 @@ target/
6161
#Ipython Notebook
6262
.ipynb_checkpoints
6363
.pypirc
64+
tests/networking/cisco/autoload/test_cisco_autoload.py
65+
tests/networking/cisco/autoload/autoload_structure.py
66+
/*.pyproj
67+
/.pytest_cache

cloudshell/networking/cisco/autoload/cisco_generic_snmp_autoload.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,10 @@ def _get_port_channels(self):
290290
:return:
291291
"""
292292

293-
if not self.if_table:
293+
if not self.if_table.if_port_channels:
294294
return
295-
port_channel_list = [if_entity for if_entity in self.if_table.if_entities if
296-
"port-channel" in if_entity.if_name.lower()]
297295
self.logger.info("Building Port Channels")
298-
for if_port_channel in port_channel_list:
296+
for if_port_channel in self.if_table.if_port_channels:
299297
interface_model = if_port_channel.if_name
300298
match_object = re.search(r"\d+$", interface_model)
301299
if match_object:

cloudshell/networking/cisco/autoload/snmp_entity_table.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ def __init__(self, snmp_handler, logger, if_table):
2525
self._sorted_module_list = []
2626
self._power_supply_list = []
2727
self._filtered_power_supply_list = []
28-
self.port_exclude_pattern = r'stack|engine|management|mgmt|voice|foreign|cpu|control\s*ethernet\s*port'
28+
self.port_exclude_pattern = r'stack|engine|management|mgmt|voice|foreign|' \
29+
r'cpu|control\s*ethernet\s*port|console\s*port'
2930
# self.module_exclude_pattern = r''
3031
self.entity_to_container_pattern = "powershelf|cevsfp|cevxfr|cevxfp|cevContainer10GigBasePort|cevModulePseAsicPlim"
3132
# self.ignore_entity_pattern = "cevModule$|cevModuleDaughterCard$"
@@ -76,7 +77,12 @@ def _get_sorted_modules_with_ports(self):
7677
def _analyze_module(self, module):
7778
if module not in self.exclusion_list:
7879
module_parent_address = self.get_relative_address(module)
79-
module_parent_address = module_parent_address[:3]
80+
if not module_parent_address:
81+
self._excluded_models.append(module)
82+
return
83+
module_parent_address_list = module_parent_address.split("/")
84+
if len(module_parent_address_list) > 2:
85+
module_parent_address = '{0}/{1}'.format(module_parent_address[0], module_parent_address[1])
8086

8187
module_rel_path = module_parent_address + '/' + self.get_resource_id(module)
8288
i = 1
@@ -107,8 +113,8 @@ def _get_entity_table(self):
107113

108114
result_dict = QualiMibTable('entPhysicalTable')
109115

110-
entity_table_critical_port_attr = {'entPhysicalContainedIn': 'str', 'entPhysicalClass': 'str',
111-
'entPhysicalVendorType': 'str'}
116+
# entity_table_critical_port_attr = {'entPhysicalContainedIn': 'str', 'entPhysicalClass': 'str',
117+
# 'entPhysicalVendorType': 'str'}
112118
entity_table_optional_port_attr = {'entPhysicalDescr': 'str', 'entPhysicalName': 'str'}
113119

114120
physical_indexes = self._snmp.get_table('ENTITY-MIB', 'entPhysicalParentRelPos')
@@ -119,27 +125,38 @@ def _get_entity_table(self):
119125
self.exclusion_list.append(index)
120126
continue
121127
temp_entity_table = physical_indexes[index].copy()
122-
temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, entity_table_critical_port_attr)
128+
129+
temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalClass": "str"})
123130
[index])
124-
if re.search(r"cevsensor|cevfan", temp_entity_table['entPhysicalVendorType'].lower()):
131+
if re.search(r"cpu|fan|sensor", temp_entity_table['entPhysicalClass'].lower()):
132+
self._logger.debug("Loaded {}, skipping.".format(temp_entity_table['entPhysicalClass']))
125133
continue
134+
135+
temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalContainedIn": "str"})
136+
[index])
126137
if temp_entity_table['entPhysicalContainedIn'] == '':
127138
self.exclusion_list.append(index)
128139
continue
129140

130-
if temp_entity_table['entPhysicalClass'] == '' or "other" in temp_entity_table['entPhysicalClass']:
141+
temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalVendorType": "str"})
142+
[index])
143+
ent_physical_class = temp_entity_table.get("entPhysicalClass")
144+
if not ent_physical_class or ent_physical_class == "''" or "other" in ent_physical_class:
131145
vendor_type = temp_entity_table['entPhysicalVendorType']
132146
if not vendor_type:
133147
continue
134148
vendor_type_match = re.search(vendor_type_match_pattern, vendor_type.lower())
149+
index_entity_class = None
135150
if vendor_type_match:
136151
index_entity_class = self.ENTITY_VENDOR_TYPE_TO_CLASS_MAP[vendor_type_match.group()]
137-
else:
138-
continue
139152
if index_entity_class:
140153
temp_entity_table['entPhysicalClass'] = index_entity_class
141-
if re.search(self.entity_to_container_pattern, temp_entity_table['entPhysicalVendorType'].lower(),
142-
re.IGNORECASE):
154+
elif not ent_physical_class or ent_physical_class == "''":
155+
self.exclusion_list.append(index)
156+
continue
157+
if "module" in temp_entity_table['entPhysicalClass'].lower() \
158+
and re.search(self.entity_to_container_pattern, temp_entity_table['entPhysicalVendorType'].lower(),
159+
re.IGNORECASE):
143160
temp_entity_table['entPhysicalClass'] = 'container'
144161
else:
145162
temp_entity_table['entPhysicalClass'] = temp_entity_table['entPhysicalClass'].replace("'", "")
@@ -165,6 +182,8 @@ def _get_entity_table(self):
165182
and not re.search(self.port_exclude_pattern, temp_entity_table['entPhysicalDescr'],
166183
re.IGNORECASE):
167184
port_entity = self._get_mapping(index, temp_entity_table[self.ENTITY_PHYSICAL])
185+
if not port_entity:
186+
port_entity = self._get_mapping(index, temp_entity_table["entPhysicalName"])
168187
if port_entity and port_entity not in self.port_mapping.values():
169188
self.port_mapping[index] = port_entity
170189
self._port_list.append(index)
@@ -246,8 +265,9 @@ def _filter_entity_table(self, raw_entity_table):
246265
elements = raw_entity_table.sort_by_column('ParentRelPos').keys()
247266
for element in reversed(elements):
248267
parent_id = int(raw_entity_table[element]['entPhysicalContainedIn'])
249-
if (parent_id not in raw_entity_table and "chassis" not in raw_entity_table[element][
250-
"entPhysicalClass"]) or parent_id in self.exclusion_list:
268+
element_class = raw_entity_table.get(element, dict()).get("entPhysicalClass")
269+
if (parent_id not in raw_entity_table and element_class not in ["chassis",
270+
"stack"]) or parent_id in self.exclusion_list:
251271
self.exclusion_list.append(element)
252272
return raw_entity_table
253273

cloudshell/networking/cisco/autoload/snmp_if_entity.py

Lines changed: 1 addition & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,30 @@
11
class SnmpIfEntity(object):
22
IF_MIB = "IF-MIB"
3-
IF_TYPE = "ifType"
4-
IF_MTU = "ifMtu"
5-
IF_SPEED = "ifHighSpeed"
63
IF_NAME = "ifDescr"
7-
IF_MAC = "ifPhysAddress"
84
IF_ALIAS = "ifAlias"
95

106
def __init__(self, snmp_handler, logger, index, port_attributes_snmp_tables):
117
self.if_index = int(index)
128
self._snmp = snmp_handler
139
self._port_attributes_snmp_tables = port_attributes_snmp_tables
1410
self._logger = logger
15-
self._if_type = "other"
16-
self._if_speed = 0
17-
self._if_mtu = 0
18-
self._if_mac = ""
1911
self._ipv4 = ""
2012
self._ipv6 = ""
2113
self._if_alias = ""
22-
self._if_name = None
23-
self._adjacent = ""
24-
self._duplex = ""
25-
self._auto_neg = ""
26-
self._port_channel_associated_port = ""
14+
self._if_name = ""
2715

2816
@property
2917
def if_name(self):
3018
if not self._if_name:
3119
self._if_name = self._snmp.get_property(self.IF_MIB, self.IF_NAME, self.if_index)
3220
return self._if_name
3321

34-
@property
35-
def if_type(self):
36-
if not self._if_type:
37-
self._if_type = self._snmp.get_property(self.IF_MIB, self.IF_TYPE, self.if_index).replace('/', '').replace(
38-
"'", '')
39-
return self._if_type
40-
4122
@property
4223
def if_port_description(self):
4324
if not self._if_alias:
4425
self._if_alias = self._snmp.get_property(self.IF_MIB, self.IF_ALIAS, self.if_index)
4526
return self._if_alias
4627

47-
@property
48-
def if_speed(self):
49-
if not self._if_speed:
50-
self._if_speed = self._snmp.get_property(self.IF_MIB, self.IF_SPEED, self.if_index)
51-
return self._if_speed
52-
53-
@property
54-
def if_mtu(self):
55-
if not self._if_mtu:
56-
self._if_mtu = self._snmp.get_property(self.IF_MIB, self.IF_MTU, self.if_index)
57-
return self._if_mtu
58-
59-
@property
60-
def if_mac(self):
61-
if not self._if_mac:
62-
self._if_mac = self._snmp.get_property(self.IF_MIB, self.IF_MAC, self.if_index)
63-
return self._if_mac
64-
6528
@property
6629
def ipv4_address(self):
6730
if not self._ipv4:
@@ -74,96 +37,6 @@ def ipv6_address(self):
7437
self._ipv6 = self._get_ipv6()
7538
return self._ipv6
7639

77-
@property
78-
def adjacent(self):
79-
if not self._adjacent:
80-
self._adjacent = self._get_adjacent()
81-
return self._adjacent
82-
83-
@property
84-
def duplex(self):
85-
if not self._duplex:
86-
self._duplex = self._get_duplex() or "Half"
87-
return self._duplex
88-
89-
@property
90-
def auto_negotiation(self):
91-
if not self._auto_neg:
92-
self._auto_neg = self._get_auto_neg() or "False"
93-
return self._auto_neg
94-
95-
@property
96-
def associated_port_list(self):
97-
if not self._port_channel_associated_port:
98-
self._port_channel_associated_port = self._get_associated_ports()
99-
return self._port_channel_associated_port
100-
101-
def _get_associated_ports(self):
102-
"""Get all ports associated with provided port channel
103-
:return:
104-
"""
105-
106-
result = []
107-
for key, value in self._port_attributes_snmp_tables.port_channel_ports.iteritems():
108-
if str(self.if_index) in value['dot3adAggPortAttachedAggID']:
109-
result.append(key)
110-
return result
111-
112-
def _get_adjacent(self):
113-
"""Get connected device interface and device name to the specified port id, using cdp or lldp protocols
114-
115-
:param interface_id: port id
116-
:return: device's name and port connected to port id
117-
:rtype string
118-
"""
119-
120-
result_template = '{remote_host} through {remote_port}'
121-
result = ''
122-
for key, value in self._port_attributes_snmp_tables.cdp_table.iteritems():
123-
if str(key).startswith(str(self.if_index)):
124-
port = self._snmp.get_property('CISCO-CDP-MIB', 'cdpCacheDevicePort', key)
125-
result = result_template.format(remote_host=value.get('cdpCacheDeviceId', ''), remote_port=port)
126-
break
127-
if result == '' and self._port_attributes_snmp_tables.lldp_local_table:
128-
interface_name = self.if_name.lower()
129-
if interface_name:
130-
key = self._port_attributes_snmp_tables.lldp_local_table.get(interface_name, None)
131-
if key:
132-
for port_id, rem_table in self._port_attributes_snmp_tables.lldp_remote_table.iteritems():
133-
if ".{0}.".format(key) in port_id:
134-
remoute_sys_name = rem_table.get('lldpRemSysName', "")
135-
remoute_port_name = self._snmp.get_property('LLDP-MIB', 'lldpRemPortDesc', port_id)
136-
if remoute_port_name and remoute_sys_name:
137-
result = result_template.format(remote_host=remoute_sys_name,
138-
remote_port=remoute_port_name)
139-
break
140-
return result
141-
142-
def _get_auto_neg(self):
143-
"""Get port auto negotiation status
144-
145-
:return return "True"
146-
"""
147-
148-
try:
149-
auto_negotiation = self._snmp.get(('MAU-MIB', 'ifMauAutoNegAdminStatus', self.if_index, 1)).values()[0]
150-
if 'enabled' in auto_negotiation.lower():
151-
return 'True'
152-
except Exception as e:
153-
self._logger.error('Failed to load auto negotiation property for interface {0}'.format(e.message))
154-
155-
def _get_duplex(self):
156-
"""Get current duplex state
157-
158-
:return str "Full"
159-
"""
160-
161-
for key, value in self._port_attributes_snmp_tables.duplex_table.iteritems():
162-
if 'dot3StatsIndex' in value.keys() and value['dot3StatsIndex'] == str(self.if_index):
163-
interface_duplex = self._snmp.get_property('EtherLike-MIB', 'dot3StatsDuplexStatus', key)
164-
if 'fullDuplex' in interface_duplex:
165-
return 'Full'
166-
16740
def _get_ipv4(self):
16841
"""Get IPv4 address details for provided port
16942
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from cloudshell.networking.cisco.autoload.snmp_if_entity import SnmpIfEntity
2+
3+
4+
class SnmpIfPortChannelEntity(SnmpIfEntity):
5+
def __init__(self, snmp_handler, logger, index, port_attributes_snmp_tables, name=None):
6+
super(SnmpIfPortChannelEntity, self).__init__(snmp_handler, logger, index, port_attributes_snmp_tables)
7+
self._port_channel_associated_port = ""
8+
self._if_name = name
9+
10+
@property
11+
def associated_port_list(self):
12+
if not self._port_channel_associated_port:
13+
self._port_channel_associated_port = self._get_associated_ports()
14+
return self._port_channel_associated_port
15+
16+
def _get_associated_ports(self):
17+
"""Get all ports associated with provided port channel
18+
:return:
19+
"""
20+
21+
result = []
22+
for key, value in self._port_attributes_snmp_tables.port_channel_ports.iteritems():
23+
if str(self.if_index) in value['dot3adAggPortAttachedAggID']:
24+
result.append(key)
25+
return result

0 commit comments

Comments
 (0)