From 5e6ee3dd31a37aa5ed0f1f0aa7fe43c08f005fb5 Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:37:32 -0700 Subject: [PATCH 01/11] Update snmp_entity_table.py At vodafone it was seen that a device was not able to respond to snmpget but snmpwalks over the same range were able to get the value. Their Huawei contact that looked at the issue insisted there was no issue and it was somehow user error of some sort. To avoid this, I instead got the tables and then referenced them in the function instead of individually snmpgetting each value. --- .../huawei/autoload/snmp_entity_table.py | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/cloudshell/networking/huawei/autoload/snmp_entity_table.py b/cloudshell/networking/huawei/autoload/snmp_entity_table.py index 924b955..41c7821 100644 --- a/cloudshell/networking/huawei/autoload/snmp_entity_table.py +++ b/cloudshell/networking/huawei/autoload/snmp_entity_table.py @@ -120,6 +120,11 @@ def _get_entity_table(self): # 'entPhysicalVendorType': 'str'} entity_table_optional_port_attr = {'entPhysicalDescr': 'str', 'entPhysicalName': 'str'} + physical_desc = self._snmp.get_table('ENTITY-MIB', 'entPhysicalDescr') + physical_name = self._snmp.get_table('ENTITY-MIB', 'entPhysicalName') + physical_vendor = self._snmp.get_table('ENTITY-MIB', 'entPhysicalVendorType') + physical_class = self._snmp.get_table('ENTITY-MIB', 'entPhysicalClass') + contained_in = self._snmp.get_table('ENTITY-MIB', 'entPhysicalContainedIn') physical_indexes = self._snmp.get_table('ENTITY-MIB', 'entPhysicalParentRelPos') vendor_type_match_pattern = r"|".join(self.ENTITY_VENDOR_TYPE_TO_CLASS_MAP.keys()) for index in physical_indexes.keys(): @@ -129,20 +134,26 @@ def _get_entity_table(self): continue temp_entity_table = physical_indexes[index].copy() - temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalClass": "str"}) - [index]) + temp_entity_table.update(physical_class[index]) + # temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalClass": "str"}) + # [index]) + if re.search(r"cpu|fan|sensor", temp_entity_table['entPhysicalClass'].lower()): self._logger.debug("Loaded {}, skipping.".format(temp_entity_table['entPhysicalClass'])) continue - temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalContainedIn": "str"}) - [index]) + temp_entity_table.update(contained_in[index]) + # temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalContainedIn": "str"}) + # [index]) + if temp_entity_table['entPhysicalContainedIn'] == '': self.exclusion_list.append(index) continue - temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalVendorType": "str"}) - [index]) + temp_entity_table.update(physical_vendor[index]) + # temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, {"entPhysicalVendorType": "str"}) + # [index]) + ent_physical_class = temp_entity_table.get("entPhysicalClass") if not ent_physical_class or ent_physical_class == "''" or "other" in ent_physical_class: vendor_type = temp_entity_table['entPhysicalVendorType'] @@ -164,8 +175,10 @@ def _get_entity_table(self): else: temp_entity_table['entPhysicalClass'] = temp_entity_table['entPhysicalClass'].replace("'", "") - temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, entity_table_optional_port_attr) - [index]) + temp_entity_table.update(physical_desc[index]) + temp_entity_table.update(physical_name[index]) + # temp_entity_table.update(self._snmp.get_properties('ENTITY-MIB', index, entity_table_optional_port_attr) + # [index]) if re.search(r'stack|chassis|module|port|powerSupply|container|backplane', temp_entity_table['entPhysicalClass']): From 8e02f80a721b961c33d0c82c12b33d603c8fe78d Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:40:00 -0700 Subject: [PATCH 02/11] Update huawei_file_system_flow.py return from execute flow contained a number of spaces in front of the actual value. caused issues in the commands being run on the device using this value. --- cloudshell/networking/huawei/flows/huawei_file_system_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudshell/networking/huawei/flows/huawei_file_system_flow.py b/cloudshell/networking/huawei/flows/huawei_file_system_flow.py index 348b46b..833480f 100644 --- a/cloudshell/networking/huawei/flows/huawei_file_system_flow.py +++ b/cloudshell/networking/huawei/flows/huawei_file_system_flow.py @@ -20,4 +20,4 @@ def execute_flow(self): src_file = save_action.get_startup_config_filename(startup_config=startup_config) - return src_file.split(":")[0] + return src_file.split(":")[0].lstrip(' ') From 1c8fd183eea68a2f05cdf05557d0f6cd73c7f1bc Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:41:20 -0700 Subject: [PATCH 03/11] Update save_restore_actions.py Missing a positive response 'complete.' --- .../networking/huawei/command_actions/save_restore_actions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudshell/networking/huawei/command_actions/save_restore_actions.py b/cloudshell/networking/huawei/command_actions/save_restore_actions.py index b999d68..1154e0a 100644 --- a/cloudshell/networking/huawei/command_actions/save_restore_actions.py +++ b/cloudshell/networking/huawei/command_actions/save_restore_actions.py @@ -44,7 +44,7 @@ def copy_file(self, src_file, dst_file): def _device_response_verification(self, output): """ """ - match = re.search(r"\d+ bytes copied|copied.*[\[\(].*[0-9]* bytes.*[\)\]]|[Cc]opy complete", + match = re.search(r"\d+ bytes copied|copied.*[\[\(].*[0-9]* bytes.*[\)\]]|[Cc]opy complete|[Cc]omplete.", output, re.IGNORECASE) From 63e2049d2e0b298e069b6da7163e8f7adb2cbca2 Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:43:45 -0700 Subject: [PATCH 04/11] Update save_restore_actions.py setup_startup_config function was running 'SAVE_RUNNING' instead of 'SAVE_STARTUP'. Was overwriting existing saved config instead of restoring. --- .../networking/huawei/command_actions/save_restore_actions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudshell/networking/huawei/command_actions/save_restore_actions.py b/cloudshell/networking/huawei/command_actions/save_restore_actions.py index 1154e0a..767a6fe 100644 --- a/cloudshell/networking/huawei/command_actions/save_restore_actions.py +++ b/cloudshell/networking/huawei/command_actions/save_restore_actions.py @@ -79,7 +79,7 @@ def setup_startup_config(self, dst_file): """ Specifies the system configuration file for next startup """ output = CommandTemplateExecutor(self._cli_service, - configuration.SAVE_RUNNING).execute_command(dst_file=dst_file) + configuration.SAVE_STARTUP).execute_command(dst_file=dst_file) match = re.search(r"Succeeded in setting the configuration for booting system", output, From fd63a825e912aa552aadd2de4a627a4a8d7fcfd5 Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:44:58 -0700 Subject: [PATCH 05/11] Update configuration.py {dst} changed to {dst_file} to match input from restore flow. --- cloudshell/networking/huawei/command_templates/configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudshell/networking/huawei/command_templates/configuration.py b/cloudshell/networking/huawei/command_templates/configuration.py index 86f7b76..964f012 100644 --- a/cloudshell/networking/huawei/command_templates/configuration.py +++ b/cloudshell/networking/huawei/command_templates/configuration.py @@ -29,7 +29,7 @@ r"[Oo]verwrit+e": lambda session, logger: session.send_line("y", logger), "\(Y/N\)": lambda session, logger: session.send_line("Y", logger)})) -SAVE_STARTUP = CommandTemplate("startup saved-configuration {dst}", +SAVE_STARTUP = CommandTemplate("startup saved-configuration {dst_file}", action_map=OrderedDict({ r"\[confirm\]": lambda session, logger: session.send_line("", logger), r"\[Y/N\]": lambda session, logger: session.send_line("y", logger), From f02623dc782faee7fae8349aecb42e27ed220ccb Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:47:40 -0700 Subject: [PATCH 06/11] Update system_actions.py Reboot was seeming to not occur on some devices, needed a positive response to some checks. I believe in this case it was asking for confirmation that a new startup configuration was intended to hae been set. --- .../networking/huawei/command_actions/system_actions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cloudshell/networking/huawei/command_actions/system_actions.py b/cloudshell/networking/huawei/command_actions/system_actions.py index 0b344ba..e5817fd 100644 --- a/cloudshell/networking/huawei/command_actions/system_actions.py +++ b/cloudshell/networking/huawei/command_actions/system_actions.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import re - +from collections import OrderedDict from cloudshell.cli.command_template.command_template_executor import CommandTemplateExecutor from cloudshell.networking.huawei.command_templates import system @@ -71,7 +71,9 @@ def reboot(self, action_map=None, error_map=None): try: CommandTemplateExecutor(cli_service=self._cli_service, command_template=system.REBOOT, - action_map=action_map, + action_map=OrderedDict({ + r"\[Y/N\]": lambda session, logger: session.send_line("Y", logger), + "\(Y/N\)": lambda session, logger: session.send_line("Y", logger)}), error_map=error_map, expected_string="System is rebooting, please wait").execute_command() except Exception as e: From 28320e273678de0f117eedf6886ea2e4badacb3b Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:52:48 -0700 Subject: [PATCH 07/11] Update huawei_save_flow.py Some devices were having issues saving the configuration file. The only method I found that worked for all devices was to remove the file_system from the path. --- cloudshell/networking/huawei/flows/huawei_save_flow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cloudshell/networking/huawei/flows/huawei_save_flow.py b/cloudshell/networking/huawei/flows/huawei_save_flow.py index e8f996f..c2a41b6 100644 --- a/cloudshell/networking/huawei/flows/huawei_save_flow.py +++ b/cloudshell/networking/huawei/flows/huawei_save_flow.py @@ -6,6 +6,7 @@ from cloudshell.devices.flows.action_flows import SaveConfigurationFlow from cloudshell.networking.huawei.command_actions.system_actions import SystemActions from cloudshell.networking.huawei.command_actions.save_restore_actions import SaveRestoreActions +import re class HuaweiSaveFlow(SaveConfigurationFlow): @@ -22,6 +23,7 @@ def execute_flow(self, folder_path, configuration_type, vrf_management_name=None :return: saved configuration file name """ + folder_path = re.sub('{}:'.format(self.file_system), '', folder_path) if not configuration_type: configuration_type = "running-config" elif "-config" not in configuration_type: From 02e4663a724d3f9a938648b60c6cd4acb40b47ac Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:54:56 -0700 Subject: [PATCH 08/11] Update huawei_save_flow.py The devices were not able to load the configurations because they did not have the correct file extension, required some configuration extension. Added .cfg here so the files would be saved with the extension. --- cloudshell/networking/huawei/flows/huawei_save_flow.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cloudshell/networking/huawei/flows/huawei_save_flow.py b/cloudshell/networking/huawei/flows/huawei_save_flow.py index c2a41b6..b8dcab6 100644 --- a/cloudshell/networking/huawei/flows/huawei_save_flow.py +++ b/cloudshell/networking/huawei/flows/huawei_save_flow.py @@ -24,6 +24,9 @@ def execute_flow(self, folder_path, configuration_type, vrf_management_name=None """ folder_path = re.sub('{}:'.format(self.file_system), '', folder_path) + if 'cfg' not in folder_path: + folder_path = folder_path + '.cfg' + if not configuration_type: configuration_type = "running-config" elif "-config" not in configuration_type: From 11610a945fd794bc62795b64ae998ac5477344b2 Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 11:59:31 -0700 Subject: [PATCH 09/11] Update huawei_save_flow.py The devices were having an issue trying to restore the configurations. The issue was caused because we were saving the configuration to "quali_run_config.cfg" then copying it over to a new file. This was causing some reference to not be created internally on the device to allow the file to be loaded as a valid configuration. --- cloudshell/networking/huawei/flows/huawei_save_flow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cloudshell/networking/huawei/flows/huawei_save_flow.py b/cloudshell/networking/huawei/flows/huawei_save_flow.py index b8dcab6..61f8361 100644 --- a/cloudshell/networking/huawei/flows/huawei_save_flow.py +++ b/cloudshell/networking/huawei/flows/huawei_save_flow.py @@ -44,7 +44,7 @@ def execute_flow(self, folder_path, configuration_type, vrf_management_name=None if configuration_type == "running-config": # src_file = "{file_system}:/qualirunconfig.cfg".format(file_system=self.file_system) - src_file = "quali_run_config.cfg" + src_file = folder_path save_action.save_runninig_config(dst_file=src_file) else: startup_config = system_action.display_startup_config() @@ -58,6 +58,8 @@ def execute_flow(self, folder_path, configuration_type, vrf_management_name=None save_action.put_file(server_address=url.get(UrlParser.HOSTNAME), src_file=src_file, dst_file=url.get(UrlParser.FILENAME)) + elif src_file == folder_path: + pass else: raise Exception("Unsupported backup protocol {scheme}. " "Supported types are ftp, tftp of local({file_system})".format(scheme=scheme, From 4f029ca9a9dcb7d03e945ff4d166184746aefb67 Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 12:00:59 -0700 Subject: [PATCH 10/11] Update huawei_restore_flow.py Same reason as for save_flow. The only way that finding the correct file on the device worked on all devices was to remove the file_system from the file path. --- cloudshell/networking/huawei/flows/huawei_restore_flow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cloudshell/networking/huawei/flows/huawei_restore_flow.py b/cloudshell/networking/huawei/flows/huawei_restore_flow.py index 837a65f..f88869d 100644 --- a/cloudshell/networking/huawei/flows/huawei_restore_flow.py +++ b/cloudshell/networking/huawei/flows/huawei_restore_flow.py @@ -5,6 +5,7 @@ from cloudshell.devices.networking_utils import UrlParser from cloudshell.networking.huawei.command_actions.system_actions import SystemActions from cloudshell.networking.huawei.command_actions.save_restore_actions import SaveRestoreActions +import re class HuaweiRestoreFlow(RestoreConfigurationFlow): @@ -23,6 +24,7 @@ def execute_flow(self, path, configuration_type, restore_method, vrf_management_ :param vrf_management_name: Virtual Routing and Forwarding Name """ + path = re.sub('{}:'.format(self.file_system), '', path) if not configuration_type: configuration_type = "running-config" elif "-config" not in configuration_type: From 8d3c2e0eff595defb698cf1b4516de115019dea0 Mon Sep 17 00:00:00 2001 From: DYeag <37943859+DYeag@users.noreply.github.com> Date: Fri, 18 Oct 2019 12:02:46 -0700 Subject: [PATCH 11/11] Update huawei_restore_flow.py .cfg or other config file extension was required in order for a configuration file to be set as the startup configuration. --- cloudshell/networking/huawei/flows/huawei_restore_flow.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cloudshell/networking/huawei/flows/huawei_restore_flow.py b/cloudshell/networking/huawei/flows/huawei_restore_flow.py index f88869d..ad7bd4b 100644 --- a/cloudshell/networking/huawei/flows/huawei_restore_flow.py +++ b/cloudshell/networking/huawei/flows/huawei_restore_flow.py @@ -25,6 +25,9 @@ def execute_flow(self, path, configuration_type, restore_method, vrf_management_ """ path = re.sub('{}:'.format(self.file_system), '', path) + if 'cfg' not in path: + path = path + '.cfg' + if not configuration_type: configuration_type = "running-config" elif "-config" not in configuration_type: