Skip to content

Commit 845a9ba

Browse files
authored
Merge pull request #72 from QualiSystems/dev
cloudshell-networking-cisco-5.1.2
2 parents 6083c75 + 1264ff0 commit 845a9ba

16 files changed

+465
-73
lines changed

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
include *.txt
2+
recursive-include *.csv
23
global-include *.ini

cloudshell/networking/cisco/autoload/cisco_generic_snmp_autoload.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from cloudshell.networking.cisco.autoload.snmp_if_table import SnmpIfTable
88

99
from cloudshell.devices.autoload.autoload_builder import AutoloadDetailsBuilder
10+
from cloudshell.devices.autoload.device_names import get_device_name
1011
from cloudshell.devices.standards.networking.autoload_structure import *
1112

1213

@@ -15,6 +16,7 @@ class CiscoGenericSNMPAutoload(object):
1516
IF_ENTITY = "ifDescr"
1617
ENTITY_PHYSICAL = "entPhysicalDescr"
1718
SNMP_ERRORS = [r'No\s+Such\s+Object\s+currently\s+exists']
19+
DEVICE_NAMES_MAP_FILE = os.path.join(os.path.dirname(__file__), os.pardir, "mibs", "device_names_map.csv")
1820

1921
def __init__(self, snmp_handler, shell_name, shell_type, resource_name, logger):
2022
"""Basic init with injected snmp handler and logger
@@ -113,18 +115,27 @@ def _is_valid_device_os(self, supported_os):
113115
return False
114116

115117
def _get_device_model(self):
116-
"""Get device model form snmp SNMPv2 mib
118+
"""Get device model from the SNMPv2 mib
117119
118120
:return: device model
119121
:rtype: str
120122
"""
121-
122123
result = ''
123124
match_name = re.search(r'::(?P<model>\S+$)', self.snmp_handler.get_property('SNMPv2-MIB', 'sysObjectID', '0'))
124125
if match_name:
125-
result = match_name.groupdict()['model'].capitalize()
126+
result = match_name.group('model')
127+
126128
return result
127129

130+
def _get_device_model_name(self, device_model):
131+
"""Get device model name from the CSV file map
132+
133+
:param str device_model: device model
134+
:return: device model model
135+
:rtype: str
136+
"""
137+
return get_device_name(file_name=self.DEVICE_NAMES_MAP_FILE, sys_obj_id=device_model)
138+
128139
def _get_device_os_version(self):
129140
"""Get device OS Version form snmp SNMPv2 mib
130141
@@ -150,6 +161,7 @@ def _get_device_details(self):
150161
self.resource.location = self.snmp_handler.get_property('SNMPv2-MIB', 'sysLocation', '0')
151162
self.resource.os_version = self._get_device_os_version()
152163
self.resource.model = self._get_device_model()
164+
self.resource.model_name = self._get_device_model_name(self.resource.model)
153165
self.resource.vendor = vendor
154166

155167
def _load_snmp_tables(self):
@@ -305,7 +317,7 @@ def _get_port_channels(self):
305317

306318
else:
307319
self.logger.error("Adding of {0} failed. Name is invalid".format(interface_model))
308-
320+
309321
self.logger.info("Building Port Channels completed")
310322

311323
def _get_ports_attributes(self, port_list):

cloudshell/networking/cisco/autoload/snmp_entity_table.py

Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ def _get_sorted_modules_with_ports(self):
7070
if len(modules) > 1 and modules[-1] not in self._module_list:
7171
self._analyze_module(modules[-1])
7272
module_relative_paths = sorted(self.relative_address, key=self.relative_address.get)
73-
self._sorted_module_list = [module for module in module_relative_paths if module in self._module_list]
73+
self._sorted_module_list = [module for module in module_relative_paths if
74+
module in self._module_list and module not in self.exclusion_list]
7475

7576
def _analyze_module(self, module):
7677
if module not in self.exclusion_list:
@@ -220,11 +221,13 @@ def get_relative_address(self, item_id):
220221
result = ''
221222
if int(item_id) not in self._filtered_chassis_list:
222223
parent_id = int(self._entity_table[item_id]['entPhysicalContainedIn'])
224+
if parent_id in self.exclusion_list:
225+
return result
223226
if parent_id not in self.relative_address.keys():
224227
if parent_id in self._sorted_module_list:
225228
result = self.get_resource_id(parent_id)
226229
if result != '':
227-
result = self.get_relative_address(parent_id) + '/' + result
230+
result = "{}/{}".format(self.get_relative_address(parent_id), result)
228231
else:
229232
result = self.get_relative_address(parent_id)
230233
else:
@@ -243,12 +246,9 @@ def _filter_entity_table(self, raw_entity_table):
243246
elements = raw_entity_table.sort_by_column('ParentRelPos').keys()
244247
for element in reversed(elements):
245248
parent_id = int(raw_entity_table[element]['entPhysicalContainedIn'])
246-
# while parent_id in self.ignore_entities_dict.keys():
247-
# parent_id = int(raw_entity_table[parent_id]['entPhysicalContainedIn'])
248-
# raw_entity_table[element]["entPhysicalContainedIn"] = parent_id
249-
if self.exclusion_list:
250-
if parent_id not in raw_entity_table or parent_id in self.exclusion_list:
251-
self.exclusion_list.append(element)
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:
251+
self.exclusion_list.append(element)
252252
return raw_entity_table
253253

254254
def _populate_relative_addresses(self):
@@ -258,50 +258,12 @@ def _populate_relative_addresses(self):
258258
"""
259259

260260
port_list = list(self._port_list)
261-
# module_list = list(self._module_list)
262-
# for module in module_list:
263-
# if module in self.exclusion_list:
264-
# self._filtered_module_list.remove(module)
265-
# continue
266-
# module_parent_address = self.get_relative_address(module)
267-
# if len(module_parent_address.split("/")) > 2:
268-
# module_parent_address = module_parent_address[:3]
269-
#
270-
# module_rel_path = module_parent_address + '/' + self.get_resource_id(module)
271-
# i = 1
272-
# while module_rel_path in self.relative_address.values():
273-
# i += 1
274-
# module_rel_path = '{0}/{1}'.format(module_parent_address, (int(self.get_resource_id(module)) + i))
275-
# self.relative_address[module] = module_rel_path
276-
# self._filtered_module_list.append(module)
277-
278261
for port in port_list:
279262
if port not in self.exclusion_list:
280-
self.relative_address[port] = self._get_port_relative_address(
281-
self.get_relative_address(port) + '/' + self.get_resource_id(port))
263+
self.relative_address[port] = self.get_relative_address(port) + '/' + self.get_resource_id(port)
282264
else:
283265
self._port_list.remove(port)
284266

285-
def _get_port_relative_address(self, relative_id):
286-
"""
287-
Workaround for an issue when port and sub-module located on the same module and have same relative ids
288-
289-
:param relative_id:
290-
:return: relative_address
291-
"""
292-
if relative_id in self.relative_address.values():
293-
if '/' in relative_id:
294-
ids = relative_id.split('/')
295-
ids[-1] = str(int(ids[-1]) + 1000)
296-
result = '/'.join(ids)
297-
else:
298-
result = str(int(relative_id.split()[-1]) + 1000)
299-
if relative_id in self.relative_address.values():
300-
result = self._get_port_relative_address(result)
301-
else:
302-
result = relative_id
303-
return result
304-
305267
def _get_module_parents(self, module_id):
306268
"""
307269
Retrieve all parent modules for a specific module

cloudshell/networking/cisco/command_actions/add_remove_vlan_actions.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,9 @@ def set_vlan_to_interface(self, vlan_range, port_mode, port_name, qnq, c_tag,
9393
action_map=action_map,
9494
error_map=error_map).execute_command(port_mode=port_mode)
9595
if qnq:
96-
CommandTemplateExecutor(self._cli_service,
97-
vlan_command_template.L2_TUNNEL,
98-
action_map=action_map,
99-
error_map=error_map).execute_command()
96+
self._get_l2_protocol_tunnel_cmd(action_map, error_map).execute_command()
10097

10198
if 'trunk' not in port_mode:
102-
10399
CommandTemplateExecutor(self._cli_service,
104100
vlan_command_template.SWITCHPORT_ALLOW_VLAN,
105101
action_map=action_map,
@@ -109,3 +105,9 @@ def set_vlan_to_interface(self, vlan_range, port_mode, port_name, qnq, c_tag,
109105
vlan_command_template.SWITCHPORT_ALLOW_VLAN,
110106
action_map=action_map,
111107
error_map=error_map).execute_command(port_mode_trunk='', vlan_range=vlan_range)
108+
109+
def _get_l2_protocol_tunnel_cmd(self, action_map=None, error_map=None):
110+
return CommandTemplateExecutor(self._cli_service,
111+
vlan_command_template.L2_TUNNEL,
112+
action_map=action_map,
113+
error_map=error_map)

cloudshell/networking/cisco/command_actions/iface_actions.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ def clean_interface_switchport_config(self, current_config, action_map=None, err
8484
configuration.NO, action_map=action_map,
8585
error_map=error_map).execute_command(command=line_to_remove)
8686
if "switchport mode dot1q-tunnel" in current_config.lower():
87-
CommandTemplateExecutor(self._cli_service,
88-
vlan_command_template.NO_L2_TUNNEL, action_map=action_map,
89-
error_map=error_map).execute_command()
87+
self._get_no_l2_protocol_tunnel_cmd(action_map, error_map).execute_command()
9088
self._logger.debug("Completed cleaning interface switchport configuration")
89+
90+
def _get_no_l2_protocol_tunnel_cmd(self, action_map=None, error_map=None):
91+
return CommandTemplateExecutor(self._cli_service,
92+
vlan_command_template.NO_L2_TUNNEL,
93+
action_map=action_map,
94+
error_map=error_map)

cloudshell/networking/cisco/flows/cisco_add_vlan_flow.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ class CiscoAddVlanFlow(AddVlanFlow):
1010
def __init__(self, cli_handler, logger):
1111
super(CiscoAddVlanFlow, self).__init__(cli_handler, logger)
1212

13+
def _get_vlan_actions(self, config_session):
14+
return AddRemoveVlanActions(config_session, self._logger)
15+
16+
def _get_iface_actions(self, config_session):
17+
return IFaceActions(config_session, self._logger)
18+
1319
def execute_flow(self, vlan_range, port_mode, port_name, qnq, c_tag):
1420
""" Configures VLANs on multiple ports or port-channels
1521
@@ -24,8 +30,8 @@ def execute_flow(self, vlan_range, port_mode, port_name, qnq, c_tag):
2430
self._logger.info("Add VLAN(s) {} configuration started".format(vlan_range))
2531

2632
with self._cli_handler.get_cli_service(self._cli_handler.config_mode) as config_session:
27-
iface_action = IFaceActions(config_session, self._logger)
28-
vlan_actions = AddRemoveVlanActions(config_session, self._logger)
33+
iface_action = self._get_iface_actions(config_session)
34+
vlan_actions = self._get_vlan_actions(config_session)
2935
port_name = iface_action.get_port_name(port_name)
3036
vlan_actions.create_vlan(vlan_range)
3137

cloudshell/networking/cisco/flows/cisco_load_firmware_flow.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ class CiscoLoadFirmwareFlow(LoadFirmwareFlow):
1515
FLASH = "flash:"
1616
KICKSTART_IMAGE = "kickstart"
1717

18-
def __init__(self, cli_handler, logger):
18+
def __init__(self, cli_handler, logger, default_file_system=None):
1919
super(CiscoLoadFirmwareFlow, self).__init__(cli_handler, logger)
20+
self._file_system = default_file_system or self.FLASH
2021

2122
def execute_flow(self, path, vrf, timeout):
2223
"""Load a firmware onto the device
@@ -34,7 +35,7 @@ def execute_flow(self, path, vrf, timeout):
3435

3536
with self._cli_handler.get_cli_service(self._cli_handler.enable_mode) as enable_session:
3637
system_action = SystemActions(enable_session, self._logger)
37-
dst_file_system = self.FLASH
38+
dst_file_system = self._file_system
3839

3940
firmware_dst_path = "{0}/{1}".format(dst_file_system, firmware_file_name)
4041

cloudshell/networking/cisco/flows/cisco_remove_vlan_flow.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ class CiscoRemoveVlanFlow(RemoveVlanFlow):
1010
def __init__(self, cli_handler, logger):
1111
super(CiscoRemoveVlanFlow, self).__init__(cli_handler, logger)
1212

13+
def _get_vlan_actions(self, config_session):
14+
return AddRemoveVlanActions(config_session, self._logger)
15+
16+
def _get_iface_actions(self, config_session):
17+
return IFaceActions(config_session, self._logger)
18+
1319
def execute_flow(self, vlan_range, port_name, port_mode, action_map=None, error_map=None):
1420
""" Remove configuration of VLANs on multiple ports or port-channels
1521
@@ -23,8 +29,8 @@ def execute_flow(self, vlan_range, port_name, port_mode, action_map=None, error_
2329

2430
self._logger.info("Remove Vlan {} configuration started".format(vlan_range))
2531
with self._cli_handler.get_cli_service(self._cli_handler.config_mode) as config_session:
26-
iface_action = IFaceActions(config_session, self._logger)
27-
vlan_actions = AddRemoveVlanActions(config_session, self._logger)
32+
iface_action = self._get_iface_actions(config_session)
33+
vlan_actions = self._get_vlan_actions(config_session)
2834
port_name = iface_action.get_port_name(port_name)
2935

3036
current_config = iface_action.get_current_interface_config(port_name)

0 commit comments

Comments
 (0)