def discover(self):
        """
        Call methods in specific order to build resources and attributes
        :return:
        """
        try:
            enable_snmp = get_attribute_by_name('Enable SNMP').lower() == 'true'
            disable_snmp = get_attribute_by_name('Disable SNMP').lower() == 'true'
        except Exception:
            enable_snmp = True
            disable_snmp = False

        if enable_snmp:
            self.enable_snmp()

        if not self._is_valid_device_os():
            raise Exception(self.__class__.__name__, 'Unsupported device OS')

        try:
            self._build_root()
            self._build_chassis()
            self._build_power_modules()
            self._build_modules()
            self._build_sub_modules()
            self._build_ports()
            autoload_details = self._root.get_autoload_details()
            self._log_autoload_details(autoload_details)
        finally:
            if disable_snmp:
                self.disable_snmp()

        return autoload_details
    def get_path(self, path=''):
        if not path:
            host = get_attribute_by_name('Backup Location')
            if ':' not in host:
                scheme = get_attribute_by_name('Backup Type')
                scheme = re.sub('(:|/+).*$', '', scheme, re.DOTALL)
                host = re.sub('^/+', '', host)
                host = '{}://{}'.format(scheme, host)
            path = host

        url = UrlParser.parse_url(path)
        if UrlParser.SCHEME not in url or not url[UrlParser.SCHEME]:
            raise Exception('ConfigurationOperations', "Backup Type is wrong or empty")

        if url[UrlParser.SCHEME].lower() in self.AUTHORIZATION_REQUIRED_STORAGES:
            if UrlParser.USERNAME not in url or not url[UrlParser.USERNAME]:
                url[UrlParser.USERNAME] = get_attribute_by_name('Backup User')
            if UrlParser.PASSWORD not in url or not url[UrlParser.PASSWORD]:
                url[UrlParser.PASSWORD] = decrypt_password(get_attribute_by_name('Backup Password'))
        try:
            result = UrlParser.build_url(url)
        except Exception as e:
            self.logger.error('Failed to build url: {}'.format(e))
            raise Exception('ConfigurationOperations', 'Failed to build path url to remote host')
        return result
    def save(self, context, folder_path, configuration_type, vrf_management_name):
        """Save selected file to the provided destination

        :param ResourceCommandContext context: ResourceCommandContext object with all Resource Attributes inside
        :param configuration_type: source file, which will be saved
        :param folder_path: destination path where file will be saved
        :param vrf_management_name: VRF management Name
        :return str saved configuration file name:
        """

        if not configuration_type:
            configuration_type = 'running'

        if not vrf_management_name:
            vrf_management_name = get_attribute_by_name(context=context, attribute_name='VRF Management Name')

        logger = get_logger_with_thread_id(context)
        api = get_api(context)

        configuration_operations = ConfigurationRunner(logger=logger, cli=self._cli, context=context, api=api)
        logger.info('Save started')
        response = configuration_operations.save(folder_path=folder_path, configuration_type=configuration_type,
                                                 vrf_management_name=vrf_management_name)
        logger.info('Save completed')
        return response
 def initialize(self, context):
     """Initialize method
     :type context: cloudshell.shell.core.context.driver_context.InitCommandContext
     """
     session_pool_size = int(get_attribute_by_name(context=context, attribute_name='Sessions Concurrency Limit'))
     self._cli = get_cli(session_pool_size)
     return 'Finished initializing'
    def restore(self, context, path, configuration_type, restore_method, vrf_management_name):
        """Restore selected file to the provided destination

        :param ResourceCommandContext context: ResourceCommandContext object with all Resource Attributes inside
        :param path: source config file
        :param configuration_type: running or startup configs
        :param restore_method: append or override methods
        :param vrf_management_name: VRF management Name
        """

        if not configuration_type:
            configuration_type = 'running'

        if not restore_method:
            restore_method = 'override'

        if not vrf_management_name:
            vrf_management_name = get_attribute_by_name(context=context, attribute_name='VRF Management Name')

        logger = get_logger_with_thread_id(context)
        api = get_api(context)

        configuration_operations = ConfigurationRunner(logger=logger, api=api, cli=self._cli, context=context)
        logger.info('Restore started')
        configuration_operations.restore(path=path, restore_method=restore_method,
                                         configuration_type=configuration_type,
                                         vrf_management_name=vrf_management_name)
        logger.info('Restore completed')
    def discover(self):
        try:
            self._enable_snmp = (get_attribute_by_name('Enable SNMP') or 'true').lower() == 'true'
            self._disable_snmp = (get_attribute_by_name('Disable SNMP') or 'false').lower() == 'true'
        except:
            pass

        if self._enable_snmp:
            self.enable_snmp()
        try:
            result = self.get_autoload_details()
        except Exception as e:
            self.logger.error('Autoload failed: {0}'.format(e.message))
            raise Exception('EricssonGenericSNMPAutoload', e.message)
        finally:
            if self._disable_snmp:
                self.disable_snmp()
        return result
    def save_configuration(self, destination_host, source_filename, vrf=None):
        system_name = self.context.resource.fullname
        system_name = re.sub(r'[\.\s]', '_', system_name)

        if source_filename and source_filename.lower() == 'running':
            config_type = 'config'
        else:
            raise Exception(self.__class__.__name__,
                            'Device does not support saving \"{}\" configuration type, \"running\" '
                            'is only supported'.format(source_filename or 'None'))

        file_name = "{0}-{1}-{2}".format(system_name, source_filename, time.strftime("%d%m%y-%H%M%S", time.localtime()))
        if not destination_host:
            backup_location = get_attribute_by_name('Backup Location')
            if not backup_location:
                raise Exception('AireOSOperations', "Backup location or path is empty")
        else:
            backup_location = destination_host

        if not backup_location.endswith('/'):
            backup_location += '/'
        destination_dict = UrlParser.parse_url(backup_location)
        if not destination_dict:
            raise Exception('AireOSOperations', 'Incorrect Backup location')
        self.logger.debug('Connection dict: ' + str(destination_dict))

        save_flow = OrderedDict()
        save_flow[save_restore.SAVE_CONFIGURATION_DATATYPE] = config_type
        save_flow[save_restore.SAVE_CONFIGURATION_FILENAME] = file_name

        template_flow = OrderedDict()
        template_flow[save_restore.SAVE_CONFIGURATION_MODE] = UrlParser.SCHEME
        template_flow[save_restore.SAVE_CONFIGURATION_SERVERIP] = UrlParser.HOSTNAME
        template_flow[save_restore.SAVE_CONFIGURATION_PATH] = UrlParser.PATH
        template_flow[save_restore.SAVE_CONFIGURATION_USER] = UrlParser.USERNAME
        template_flow[save_restore.SAVE_CONFIGURATION_PASSWORD] = UrlParser.PASSWORD
        template_flow[save_restore.SAVE_CONFIGURATION_PORT] = UrlParser.PORT
        generated_flow = self._generate_flow(template_flow, destination_dict)
        if save_restore.SAVE_CONFIGURATION_PATH not in generated_flow:
            generated_flow[save_restore.SAVE_CONFIGURATION_PATH] = '/'

        save_flow.update(generated_flow)
        execute_command_map(save_flow, self.cli_service.send_command)

        expected_map = OrderedDict({r'[yY]/[nN]': lambda session: session.send_line('y')})
        error_map = OrderedDict({r'[Ee]rror:': 'Save configuration error, see logs for details'})

        self.cli_service.send_command(save_restore.SAVE_CONFIGURATION_START.get_command(), expected_map=expected_map,
                                      error_map=error_map)

        return file_name
    def copy(self, source_file='', destination_file='', vrf=None, timeout=600, retries=5):
        """Copy file from device to tftp or vice versa, as well as copying inside devices filesystem

        :param source_file: source file.
        :param destination_file: destination file.
        :return tuple(True or False, 'Success or Error message')
        """

        if not vrf:
            vrf = get_attribute_by_name('VRF Management Name')

        host = None
        expected_map = OrderedDict()

        if '://' in source_file:
            source_file_data_list = re.sub('/+', '/', source_file).split('/')
            host = source_file_data_list[1]
            expected_map[r'[^/]{}'.format(source_file_data_list[-1])] = lambda session: session.send_line('')
            expected_map[r'[^/]{}'.format(destination_file)] = lambda session: session.send_line('')
        elif '://' in destination_file:
            destination_file_data_list = re.sub('/+', '/', destination_file).split('/')
            host = destination_file_data_list[1]
            expected_map[r'[^/]{}'.format(destination_file_data_list[-1])] = lambda session: session.send_line('')
            expected_map[r'[^/]{}'.format(source_file)] = lambda session: session.send_line('')
        else:
            expected_map[r'[^/]{}'.format(destination_file)] = lambda session: session.send_line('')
            expected_map[r'[^/]{}'.format(source_file)] = lambda session: session.send_line('')

        if host and not validateIP(host):
            raise Exception('Cisco OS', 'Copy method: \'{}\' is not valid remote ip.'.format(host))

        copy_command_str = 'copy {0} {1}'.format(source_file, destination_file)
        if vrf:
            copy_command_str += ' vrf {}'.format(vrf)

        if host:
            expected_map[r"[^/]{}".format(host)] = lambda session: session.send_line('')
        expected_map[r'\s+[Vv][Rr][Ff]\s+'] = lambda session: session.send_line('')
        expected_map[r'\[confirm\]'] = lambda session: session.send_line('')
        expected_map[r'\(y/n\)'] = lambda session: session.send_line('y')
        expected_map[r'\([Yy]es/[Nn]o\)'] = lambda session: session.send_line('yes')
        expected_map[r'\?'] = lambda session: session.send_line('')
        expected_map[r'bytes'] = lambda session: session.send_line('')

        output = self.cli.send_command(command=copy_command_str, expected_map=expected_map, timeout=60)
        output += self.cli.send_command('')

        return self._check_download_from_tftp(output)
    def save_configuration(self, destination_host, source_filename, vrf=None):
        """Backup 'startup-config' or 'running-config' from device to provided file_system [ftp|tftp]
        Also possible to backup config to localhost
        :param destination_host:  tftp/ftp server where file be saved
        :param source_filename: what file to backup
        :return: status message / exception
        """

        if source_filename == '':
            source_filename = 'running-config'
        if '-config' not in source_filename:
            source_filename = source_filename.lower() + '-config'
        if ('startup' not in source_filename) and ('running' not in source_filename):
            raise Exception('Cisco OS', "Source filename must be 'startup' or 'running'!")

        if not destination_host:
            destination_host = get_attribute_by_name('Backup Location')
            if not destination_host:
                raise Exception('Cisco OS', "Backup location or path is empty")

        system_name = re.sub('\s+', '_', self.resource_name)
        if len(system_name) > 23:
            system_name = system_name[:23]

        destination_filename = '{0}-{1}-{2}'.format(system_name, source_filename.replace('-config', ''),
                                                    _get_time_stamp())
        self.logger.info('destination filename is {0}'.format(destination_filename))

        if len(destination_host) <= 0:
            destination_host = self._get_resource_attribute(self.resource_name, 'Backup Location')
            if len(destination_host) <= 0:
                raise Exception('Folder path and Backup Location are empty.')

        if destination_host.endswith('/'):
            destination_file = destination_host + destination_filename
        else:
            destination_file = destination_host + '/' + destination_filename

        is_uploaded = self.copy(destination_file=destination_file, source_file=source_filename, vrf=vrf)
        if is_uploaded[0] is True:
            self.logger.info('Save configuration completed.')
            return '{0},'.format(destination_filename)
        else:
            # self.logger.info('is_uploaded = {}'.format(is_uploaded))
            self.logger.info('Save configuration failed with errors: {0}'.format(is_uploaded[1]))
            raise Exception(is_uploaded[1])
    def update_firmware(self, context, remote_host, file_path):
        """Upload and updates firmware on the resource

        :param remote_host: path to firmware file location on ftp or tftp server
        :param file_path: firmware file name
        :return: result
        :rtype: str
        """

        logger = get_logger_with_thread_id(context)
        api = get_api(context)
        vrf_management_name = get_attribute_by_name(context=context, attribute_name='VRF Management Name')

        logger.info('Start Update Firmware')
        firmware_operations = FirmwareRunner(cli=self._cli, logger=logger, context=context, api=api)
        response = firmware_operations.load_firmware(path=remote_host, vrf_management_name=vrf_management_name)
        logger.info('Finish Update Firmware: {}'.format(response))
    def load_firmware(self, context, path, vrf_management_name):
        """Upload and updates firmware on the resource

        :param ResourceCommandContext context: ResourceCommandContext object with all Resource Attributes inside
        :param path: full path to firmware file, i.e. tftp://10.10.10.1/firmware.tar
        :param vrf_management_name: VRF management Name
        """

        logger = get_logger_with_thread_id(context)
        api = get_api(context)
        if not vrf_management_name:
            vrf_management_name = get_attribute_by_name(context=context, attribute_name='VRF Management Name')

        logger.info('Start Load Firmware')
        firmware_operations = FirmwareRunner(cli=self._cli, logger=logger, context=context, api=api)
        response = firmware_operations.load_firmware(path=path, vrf_management_name=vrf_management_name)
        logger.info('Finish Load Firmware: {}'.format(response))
    def __init__(self, snmp_handler=None, logger=None, supported_os=None, cli=None, snmp_community=None):
        """Basic init with injected snmp handler and logger

        :param snmp_handler:
        :param logger:
        :return:
        """

        EricssonGenericSNMPAutoload.__init__(self, snmp_handler, logger, supported_os)
        self.port_ethernet_vendor_type_pattern = r'port.*\d+ge|\S+.1.193.218.6.10.251|\S+Port.251'
        self._cli = cli
        self.snmp_view = 'qualiview'
        self.snmp_community = snmp_community
        self._enable_snmp = True
        self._disable_snmp = False
        self.vendor_type_exclusion_pattern = ['port.*mgmt']
        self.interface_mapping_key = 'eriRouterIpBindIfIndex'
        self.interface_mapping_mib = 'ERICSSON-ROUTER-IP-BIND-MIB'
        self.load_mib_list = ['ERICSSON-ROUTER-PRODUCT-MIB']
        if not self.snmp_community:
            self.snmp_community = get_attribute_by_name('SNMP Read Community') or 'qualicommunity'
    def save_configuration(self, destination_host, source_filename='running', vrf=None):
        system_name = self.context.resource.fullname
        system_name = re.sub(r'[\.\s]', '_', system_name)

        if source_filename.lower() != 'running':
            raise Exception(self.__class__.__name__, 'Device does not support saving \"{}\" '
                                                     'configuration type, \"running\" is only supported'.format(
                source_filename or 'None'))

        file_name = "{0}-{1}-{2}".format(system_name, source_filename, time.strftime("%d%m%y-%H%M%S", time.localtime()))
        if not destination_host:
            backup_location = get_attribute_by_name('Backup Location', context=self.context)
            if backup_location:
                destination_host = backup_location
            else:
                raise Exception(self.__class__.__name__, "Backup location or path is empty")

        if destination_host.endswith('/'):
            destination_host = destination_host[:-1]
        full_path = "{0}/{1}".format(destination_host, file_name)
        self.logger.info("Save configuration to file {0}".format(full_path))
        self.execute_command_map({save_restore.SAVE: full_path})
        return full_path
Exemplo n.º 14
0
from cloudshell.configuration.cloudshell_cli_configuration import CONNECTION_TYPE_SSH
from cloudshell.networking.cisco.aireos.cli.aireos_ssh_session import AireOSSSHSession
from cloudshell.shell.core.context_utils import get_attribute_by_name_wrapper, \
    get_resource_address, get_attribute_by_name, get_decrypted_password_by_attribute_name_wrapper
from cloudshell.shell.core.dependency_injection.context_based_logger import get_logger_with_thread_id
from cloudshell.configuration.cloudshell_cli_configuration import CONNECTION_MAP

"""Definition for SSH session"""
ssh_session = SessionCreator(AireOSSSHSession)
ssh_session.proxy = ReturnToPoolProxy
ssh_session.kwargs = {'username': get_attribute_by_name_wrapper('User'),
                      'password': get_decrypted_password_by_attribute_name_wrapper('Password'),
                      'host': get_resource_address}
CONNECTION_MAP[CONNECTION_TYPE_SSH] = ssh_session

CONNECTION_EXPECTED_MAP = OrderedDict({r'[Uu]ser:': lambda session: session.send_line(get_attribute_by_name('User')),
                                       r'[Pp]assword:': lambda session: session.send_line(
                                           get_decrypted_password_by_attribute_name_wrapper('Password')())})

GET_LOGGER_FUNCTION = get_logger_with_thread_id

DEFAULT_PROMPT = r'[>$#]\s*$'
CONFIG_MODE_PROMPT = DEFAULT_PROMPT

ENTER_CONFIG_MODE_PROMPT_COMMAND = ''
EXIT_CONFIG_MODE_PROMPT_COMMAND = ''

COMMIT_COMMAND = ''
ROLLBACK_COMMAND = ''

HE_MAX_READ_RETRIES = 10
Exemplo n.º 15
0
def decrypt_password_from_attribute(api,
                                    password_attribute_name,
                                    context=None):
    """Uses api to decrypt password."""
    password = get_attribute_by_name(password_attribute_name, context)
    return api.DecryptPassword(password).Value
Exemplo n.º 16
0
 def __init__(self, context):
     api = inject.instance('api')
     password = get_attribute_by_name('Password', context)
     self._password = api.DecryptPassword(password).Value
     self._user = get_attribute_by_name('User', context)
     self._host = context.resource.address
Exemplo n.º 17
0
from cloudshell.shell.core.context_utils import get_attribute_by_name_wrapper, get_resource_address, \
    get_attribute_by_name
from cloudshell.configuration.cloudshell_cli_configuration import CONNECTION_MAP

ssh_session = SessionCreator(AireOSSSHSession)
ssh_session.proxy = ReturnToPoolProxy
ssh_session.kwargs = {
    'username': get_attribute_by_name_wrapper('User'),
    'password': get_attribute_by_name_wrapper('Password'),
    'host': get_resource_address
}
CONNECTION_MAP[CONNECTION_TYPE_SSH] = ssh_session

CONNECTION_EXPECTED_MAP = OrderedDict({
    r'[Uu]ser:':
    lambda session: session.send_line(get_attribute_by_name('User')),
    r'[Pp]assword:':
    lambda session: session.send_line(get_attribute_by_name('Password'))
})
"""Definition for Telnet session"""
telnet_session = SessionCreator(TelnetSession)
telnet_session.proxy = ReturnToPoolProxy
telnet_session.kwargs = {
    'username': get_attribute_by_name_wrapper('User'),
    # 'password': get_decrypted_password_by_attribute_name_wrapper('Password'),
    'password': get_attribute_by_name_wrapper('Password'),
    'host': get_resource_address
}
CONNECTION_MAP[CONNECTION_TYPE_TELNET] = telnet_session

HE_MAX_LOOP_RETRIES = 5
Exemplo n.º 18
0
 def username(self):
     return get_attribute_by_name('User', self._context)
 def snmp_community(self):
     if self._snmp_community is None:
         self._snmp_community = get_attribute_by_name("SNMP Read Community") or "quali"
     return self._snmp_community