def _split_addresses_and_letter(self, address): """Extract resources addresses and matrix letter. :param address: <host>:<MatrixA> or <host>:<host>:<Q> :type address: str :return: list of hosts and matrix letter (upper) :rtype: tuple[tuple[str], str] """ letter = None if not self.support_multiple_blades: try: match = self.ADDRESS_PATTERN.search(address) first_host = match.group('host') second_host = match.group('second_host') letter = match.group('letter').upper() except AttributeError: msg = ('Incorrect address. Resource address should specify ' 'MatrixA, MatrixB or Q. ' 'Format <host>:[<second_host>:]<matrix_letter>') self._logger.error(msg) raise BaseRomeException(msg) if second_host and letter != 'Q': raise BaseRomeException('') hosts = tuple(filter(None, (first_host, second_host))) else: hosts = (address, ) return hosts, letter
def _split_addresses_and_letter(self, address): """Extract resources addresses and matrix letter. :param address: <host>:<MatrixA> or <host>:<host>:<Q> :type address: str :return: list of hosts and matrix letter (upper) :rtype: tuple[tuple[str], str] """ letter = None err_msg = ( "Incorrect address. Resource address should specify MatrixA, MatrixB, " "MatrixQ or MatrixXY. Format <host>:[<second_host>:]<matrix_letter>. " "Second host is used in Q128 devices.") if not self.support_multiple_blades: try: match = self.ADDRESS_PATTERN.search(address) first_host = match.group("host") second_host = match.group("second_host") letter = match.group("letter").upper() except AttributeError: self._logger.error(err_msg) raise BaseRomeException(err_msg) if second_host and letter != "Q": raise BaseRomeException(err_msg) hosts = tuple(filter(None, (first_host, second_host))) else: hosts = (address, ) return hosts, letter
def verify_sub_port_is_not_locked_or_disabled(self): """Check that Sub Ports are not locked or disabled.""" if self.locked: raise BaseRomeException("Sub Port {} is Locked".format( self.sub_port_name)) if not self.enabled: raise BaseRomeException("Sub Port {} is Disabled".format( self.sub_port_name))
def validate(self, output): blade_name = self.logical_ports[0].blade_letter msg = "The Port Table isn't loaded correctly. Loaded {} ports".format( len(self.logical_ports)) if blade_name in tuple("ABXY") and len(self.logical_ports) != 256: raise BaseRomeException(msg) elif blade_name == "Q" and len(self.logical_ports) not in (64, 128): raise BaseRomeException(msg) msg = "Not all sub ports are loaded. Output is:\n{}".format(output) for lp in self.logical_ports: for rp in lp.rome_ports: if rp.e_port is None or rp.w_port is None: raise BaseRomeException(msg)
def map_clear_to(self, src_port, dst_ports): """Remove simplex/multi-cast/duplex connection ending on the destination port. :param src_port: src port address, '192.168.42.240:A/A/21' :type src_port: str :param dst_ports: list of dst ports addresses, ['192.168.42.240:A/A/21', '192.168.42.240:A/A/22'] :type dst_ports: list :return: None :raises Exception: if command failed """ if len(dst_ports) != 1: raise BaseRomeException( 'MapClearTo operation is not allowed for multiple Dst ports') self._logger.info('MapClearTo, SrcPort: {0}, DstPort: {1}'.format( src_port, dst_ports[0])) src_port_name = self._convert_cs_port_to_port_name(src_port) dst_port_name = self._convert_cs_port_to_port_name(dst_ports[0]) with self._get_cli_services_lst() as cli_services_lst: mapping_actions = MappingActions( cli_services_lst, self._logger, self._mapping_timeout, self._mapping_check_delay, ) system_actions = SystemActions(cli_services_lst, self._logger) port_table = system_actions.get_port_table() connected_ports = port_table.get_connected_port_pairs( [src_port_name]) if not connected_ports: self._logger.debug("Ports already disconnected.") return src_logic_port, dst_logic_port = next(iter(connected_ports)) if dst_logic_port.name != dst_port_name: raise BaseRomeException( "Source port connected to another port - {}".format( dst_logic_port.name)) mapping_actions.disconnect(connected_ports) port_table = system_actions.get_port_table() connected_ports = port_table.get_connected_port_pairs( [src_port_name]) if connected_ports: raise BaseRomeException("Cannot disconnect ports: {}".format( ' - '.join((src_logic_port.name, dst_logic_port.name))))
def map_clear(self, ports): """Remove simplex/multi-cast/duplex connection ending on the destination port. :param ports: ports, ['192.168.42.240:A/A/21', '192.168.42.240:A/A/22'] :type ports: list :return: None :raises Exception: if command failed """ self._logger.info('MapClear, Ports: {}'.format(', '.join(ports))) port_names = map(self._convert_cs_port_to_port_name, ports) with self._get_cli_services_lst() as cli_services_lst: mapping_actions = MappingActions( cli_services_lst, self._logger, self._mapping_timeout, self._mapping_check_delay, ) system_actions = SystemActions(cli_services_lst, self._logger) port_table = system_actions.get_port_table() connected_ports = port_table.get_connected_port_pairs(port_names, bidi=True) mapping_actions.disconnect(connected_ports) port_table = system_actions.get_port_table() connected_ports = port_table.get_connected_port_pairs(port_names, bidi=True) if connected_ports: connected_port_names = [(src.name, dst.name) for src, dst in connected_ports] raise BaseRomeException( "Cannot disconnect all ports. Ports: {} left connected". format(', '.join(map(' - '.join, connected_port_names))))
def __getitem__(self, logical_name): """Return Rome Logical Port. :type logical_name: str :rtype: LogicalPort """ try: val = self._map_ports[logical_name] except KeyError: raise BaseRomeException( 'We don\'t have port "{}" in Ports table'.format(logical_name)) return val
def add_sub_port(self, sub_port): if sub_port.port_resource != self.port_resource: raise ValueError( "Sub port ({}) located on a different resource from a " "Rome port ({})".format(sub_port, self)) attr_name = "{}_port".format(sub_port.direction.lower()) if getattr(self, attr_name) is not None: raise BaseRomeException("{} port already set".format( sub_port.direction)) setattr(self, attr_name, sub_port)
def map_uni(self, src_port, dst_ports): """Unidirectional mapping of two ports. :param src_port: src port address, '192.168.42.240:B/B/21' :type src_port: str :param dst_ports: list of dst ports addresses, ['192.168.42.240:B/B/22', '192.168.42.240:B/B/23'] :type dst_ports: list :return: None :raises Exception: if command failed """ if len(dst_ports) != 1: raise BaseRomeException( 'MapUni operation is not allowed for multiple Dst ports') _, letter = self._split_addresses_and_letter(src_port) if letter.startswith('Q'): raise NotSupportedError("MapUni for matrix Q doesn't supported") self._logger.info('MapUni, SrcPort: {0}, DstPort: {1}'.format( src_port, dst_ports[0])) src_port_name = self._convert_cs_port_to_port_name(src_port) dst_port_name = self._convert_cs_port_to_port_name(dst_ports[0]) with self._get_cli_services_lst() as cli_services_lst: system_actions = SystemActions(cli_services_lst, self._logger) mapping_actions = MappingActions( cli_services_lst, self._logger, self._mapping_timeout, self._mapping_check_delay, ) port_table = system_actions.get_port_table() src_logic_port = port_table[src_port_name] dst_logic_port = port_table[dst_port_name] if port_table.is_connected(src_logic_port, dst_logic_port): self._logger.debug('Ports {} and {} already connected'.format( src_port_name, dst_port_name)) return port_table.verify_ports_for_connection(src_logic_port, dst_logic_port) mapping_actions.connect(src_logic_port, dst_logic_port, bidi=False) port_table = system_actions.get_port_table() src_logic_port = port_table[src_port_name] dst_logic_port = port_table[dst_port_name] if not port_table.is_connected(src_logic_port, dst_logic_port): raise ConnectionPortsError( 'Cannot connect port {} to port {} during {}sec'.format( src_port_name, dst_port_name, self._mapping_timeout))
def reset_connection_pending(session, logger): """Reset connection pending. :type session: cloudshell.cli.session.expect_session.ExpectSession :type logger: logging.Logger """ session.hardware_expect("homing run", r"(?i)RECOVERY FINISHED SUCCESSFULLY", logger) session.hardware_expect( "connection set command-execution enable", r"connection execution is enabled", logger, ) raise BaseRomeException( "Multiple Cross Connect Severe Failure. Problem with a connection. " "Reset connection pending.")
def set_attribute_value(self, cs_address, attribute_name, attribute_value): """Set attribute value to the device. :param cs_address: address, '192.168.42.240:A/A/21' :type cs_address: str :param attribute_name: attribute name, "Port Speed" :type attribute_name: str :param attribute_value: value, "10000" :type attribute_value: str :return: attribute value :rtype: cloudshell.layer_one.core.response.response_info.AttributeValueResponseInfo :raises Exception: if command failed """ if attribute_name == 'Serial Number': return else: raise BaseRomeException( 'SetAttribute {} is not supported'.format(attribute_name))
def wait_ports_not_in_pending_connections(self, cli_service, ports, num_ports_to_connect): """Wait for ports go away from pending connections. :type cli_service: cloudshell.cli.cli_service_impl.CliServiceImpl :param ports: src and dst ports that connects :type ports: list[tuple[str, str]] :param num_ports_to_connect: timeout depends on it :type num_ports_to_connect: int """ end_time = time.time() + (self._mapping_timeout * num_ports_to_connect) while time.time() < end_time: time.sleep(self._mapping_check_delay) if not self.ports_in_pending_connections(cli_service, ports): break else: msg = "There are some pending connections after {}sec".format( self._mapping_timeout) raise BaseRomeException(msg)
def get_attribute_value(self, cs_address, attribute_name): """Retrieve attribute value from the device. :param cs_address: address, '192.168.42.240:A/A/21' :type cs_address: str :param attribute_name: attribute name, "Port Speed" :type attribute_name: str :return: attribute value :rtype: cloudshell.layer_one.core.response.response_info.AttributeValueResponseInfo :raises Exception: if command failed """ serial_number = 'Serial Number' if len(cs_address.split('/')) == 1 and attribute_name == serial_number: with self._get_cli_services_lst() as cli_services_lst: system_actions = SystemActions(cli_services_lst, self._logger) board_tables_map = system_actions.get_board_tables_map() return AttributeValueResponseInfo( board_tables_map.values()[0].get('serial_number')) else: msg = 'Attribute {} for {} is not available'.format( attribute_name, cs_address) raise BaseRomeException(msg)
def _verify_matrix_letter(self): if self.port_table.is_matrix_q and self.matrix_letter.upper() != "Q": raise BaseRomeException( "This device has MPO ports. " "You should specify MatrixQ in device address.")