class GlimmerglassDriverHandler(DriverHandlerBase):
    def __init__(self):
        DriverHandlerBase.__init__(self)

        self._ctag = 1
        self._switch_name = ''
        self._switch_size = 0
        self._mapping_info = dict()

        self._resource_info = None

        self._service_mode = ConfigurationParser.get("driver_variable",
                                                     "service_mode")
        self._port_logical_mode = ConfigurationParser.get(
            "driver_variable", "port_mode")
        self._custom_port_pairing = ConfigurationParser.get(
            "driver_variable", "custom_port_pairing") or dict()
        self._login_prompt = ConfigurationParser.get("common_variable",
                                                     "device_login_prompt")
        self._prompt = ConfigurationParser.get("common_variable",
                                               "device_prompt")
        self._session = GGTCPSession()

    def _incr_ctag(self):
        self._ctag += 1
        return self._ctag

    def login(self, address, username, password, command_logger=None):
        ip = address
        port = None
        if ":" in address:
            address_data = address.split(":")
            ip = address_data[0]
            port = int(address_data[1])
        if self._service_mode.lower() == u"tl1":
            command = 'ACT-USER::{0}:{1}::{2};'.format(username, self._ctag,
                                                       password)
            command_result = self._session.connect(
                host=ip,
                username=username,
                password=password,
                command=command,
                re_string=self._login_prompt,
                port=port)
            command_logger.info(command_result)

            if not re.search(r'COMPLD', command_result):
                command_logger.info(
                    'Didn\'t find success message, retrying ...')
                command_result = self._session.send_command(
                    command, re_string=self._login_prompt)
                command_logger.info(command_result)
            else:
                command_logger.info('Login status: OK')

            match_result = re.search(r"<\s+(?P<host>\S+)\s+\d+",
                                     command_result, re.DOTALL)
            if match_result is not None:
                self._switch_name = match_result.groupdict()['host']
        else:
            raise Exception(
                self.__class__.__name__,
                "Selected '{}' connection type is not supported".format(
                    self._service_mode))

    def _get_device_data(self):
        device_data = dict()

        if self._service_mode.lower() == u"scpi":
            pass
        elif self._service_mode.lower() == u"tl1":
            command = "rtrv-system-info:::{0};".format(self._incr_ctag())
            device_data["system_info"] = self._session.send_command(
                command, re_string=self._prompt)

            size_match = re.search(
                r"LicensedPortMatrix=(?P<src>\d+)x(?P<dst>\d+)",
                device_data["system_info"], re.DOTALL)

            if size_match is not None:
                size_dict = size_match.groupdict()

                self._switch_size = int(size_dict["src"]) + int(
                    size_dict["dst"])
            else:
                raise Exception(self.__class__.__name__,
                                "Can't find 'size' parameter!")

            command = "RTRV-CFG-FIBER::all:{0};".format(self._incr_ctag())
            device_data["port_list"] = self._session.send_command(
                command, re_string=self._prompt)

            command = "rtrv-crs-fiber::all:{0};".format(self._incr_ctag())
            device_data["connections_map"] = self._session.send_command(
                command, re_string=self._prompt)
        else:
            raise Exception(
                self.__class__.__name__,
                "Selected '{}' connection type is not supported".format(
                    self._service_mode))

        return device_data

    def get_resource_description(self, address, command_logger=None):
        device_data = self._get_device_data()

        self._resource_info = ResourceInfo()
        self._resource_info.set_depth(0)
        self._resource_info.set_index(1)

        self._resource_info.set_address(address)

        if self._service_mode.lower() == "tl1":
            model_info_match = re.search(
                'SerialNumber=(?P<serial>\S+)".*SystemType=(?P<type>\S+)".*"(?P<vendor>\S+):'
                +
                'ChassisType=(?P<model>\S+)".*SoftwareActiveVersion=(?P<version>\S+)"',
                device_data["system_info"], re.DOTALL)

            # add chassis info
            if model_info_match is not None:
                model_info_dict = model_info_match.groupdict()

                self._resource_info.add_attribute("Vendor",
                                                  model_info_dict["vendor"])
                self._resource_info.add_attribute("Type",
                                                  model_info_dict["type"])
                self._resource_info.add_attribute("Version",
                                                  model_info_dict["version"])
                self._resource_info.add_attribute("Model",
                                                  model_info_dict["model"])

                model_name = model_info_dict["model"]

                self._resource_info.set_model_name(model_info_dict["model"])
                self._resource_info.set_serial_number(
                    model_info_dict["serial"])
            else:
                raise Exception(self.__class__.__name__,
                                "Can't parse model info!")

            # get port mappings and port info
            address_prefix = address + "/"
            port_map_list = device_data["connections_map"].split("\n")
            port_list = device_data['port_list'].split("\n")

            if self._port_logical_mode.lower() == "logical":
                logical_port_map = dict()
                for port_data in port_list:
                    port_info_match = re.search(
                        r"PORTID=(?P<id>\d+).*PORTNAME=(?P<name>(IN|OUT)\d+)" +
                        ".*PORTHEALTH=(?P<state>good|bad)", port_data,
                        re.DOTALL)
                    if port_info_match is not None:
                        port_info_dict = port_info_match.groupdict()
                        logical_port_id = re.sub('(IN|OUT)', '',
                                                 port_info_dict["name"])
                        if logical_port_id not in logical_port_map.keys():
                            logical_port_map[logical_port_id] = {}
                        if port_info_dict["state"].lower() == "good":
                            port_state = "Enable"
                        else:
                            port_state = "Disable"

                        logical_port_map[logical_port_id]['state'] = port_state

                        if 'in' in port_info_dict["name"].lower():
                            logical_port_map[logical_port_id][
                                'in'] = logical_port_id
                        else:
                            if logical_port_id in self._custom_port_pairing.values(
                            ):
                                for key, value in self._custom_port_pairing.iteritems(
                                ):
                                    if value == logical_port_id and key in logical_port_map:
                                        logical_port_map[key][
                                            'out'] = logical_port_id
                            else:
                                logical_port_map[logical_port_id][
                                    'out'] = logical_port_id

                for port_id, port_data in logical_port_map.iteritems():
                    if 'in' in port_data and 'out' in port_data:
                        logical_port_map[port_id][
                            'port_address'] = '{0}-{1}'.format(
                                logical_port_map[port_id]['in'],
                                logical_port_map[port_id]['out'])

                for port_data in port_map_list:
                    port_map_match = re.search(
                        r"IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S+),IP.*"
                        +
                        "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S+),OP.*",
                        port_data, re.DOTALL)
                    if port_map_match is not None:
                        port_map_dict = port_map_match.groupdict()
                        src_logical_port_id = re.sub(
                            '(IN|OUT)', '', port_map_dict["src_port_name"])
                        dst_logical_port_id = re.sub(
                            '(IN|OUT)', '', port_map_dict["dst_port_name"])
                        if src_logical_port_id in logical_port_map.keys() \
                                and dst_logical_port_id in logical_port_map.keys():
                            self._mapping_info[
                                dst_logical_port_id] = src_logical_port_id

                for logical_port_index, logical_port_data in logical_port_map.iteritems(
                ):
                    port_resource_info = ResourceInfo()
                    port_resource_info.set_depth(1)
                    if 'port_address' not in logical_port_data:
                        continue
                    port_resource_info.set_index(
                        logical_port_data['port_address'])
                    port_resource_info.set_model_name(model_name)
                    if logical_port_index in self._mapping_info:
                        port_resource_info.set_mapping(
                            address_prefix + logical_port_map[
                                self._mapping_info[logical_port_index]]
                            ['port_address'])
                    port_resource_info.add_attribute(
                        "State", logical_port_data['state'])
                    port_resource_info.add_attribute("Protocol Type", 0)
                    self._resource_info.add_child(
                        logical_port_data['port_address'], port_resource_info)
            else:
                for port_data in port_map_list:
                    port_map_match = re.search(
                        r".*IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S*),IP.*"
                        +
                        "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S*),OP.*",
                        port_data, re.DOTALL)

                    if port_map_match is not None:
                        port_map_dict = port_map_match.groupdict()
                        if int(port_map_dict['src_port']) > 0 and \
                                int(port_map_dict['dst_port']) > 0:
                            src_port = port_map_dict["src_port"]
                            dst_port = port_map_dict["dst_port"]
                            # self._mapping_info[dst_port] = src_port
                            self._mapping_info[src_port] = dst_port

                for port_data in port_list:
                    port_info_match = re.search(
                        r"PORTID=(?P<id>\d+).*PORTNAME=(?P<name>(IN|OUT)\d+)" +
                        ".*PORTHEALTH=(?P<state>good|bad)", port_data,
                        re.DOTALL)

                    if port_info_match is not None:
                        port_info_dict = port_info_match.groupdict()

                        port_resource_info = ResourceInfo()
                        port_resource_info.set_depth(1)

                        port_id = port_info_dict["id"]
                        port_resource_info.set_index(port_id)
                        port_resource_info.set_model_name(model_name)
                        # port_resource_info.set_name(port_info_dict["name"])

                        if port_id in self._mapping_info:
                            port_resource_info.set_mapping(
                                address_prefix + self._mapping_info[port_id])

                        if port_info_dict["state"].lower() == "good":
                            port_resource_info.add_attribute("State", "Enable")
                        else:
                            port_resource_info.add_attribute(
                                "State", "Disable")

                        port_resource_info.add_attribute("Protocol Type", 0)

                        self._resource_info.add_child(port_info_dict["id"],
                                                      port_resource_info)
        else:
            raise Exception(
                self.__class__.__name__,
                "Selected '{}' connection type is not supported".format(
                    self._service_mode))

        return self._resource_info.convert_to_xml()

    def map_uni(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == u"tl1":
            if self._port_logical_mode.lower() == "logical":
                src_in_port = str(10000 + int(src_port[1].split('-')[0]))
                dst_out_port = str(20000 + int(dst_port[1].split('-')[1]))
            else:
                src_in_port = min(int(src_port[1]), int(dst_port[1]))

                dst_out_port = max(int(src_port[1]), int(dst_port[1]))

            command = "ent-crs-fiber::{0},{1}:{2};".format(
                src_in_port, dst_out_port, self._incr_ctag())
            command_result = self._session.send_command(command,
                                                        re_string=self._prompt)
            command_logger.info(command_result)
        else:
            raise Exception(
                self.__class__.__name__,
                "Selected '{}' connection type is not supported".format(
                    self._service_mode))

    def map_bidi(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == u"tl1":
            if self._port_logical_mode.lower() == "logical":
                source_port = str(src_port[1]).split('-')
                destination_port = str(dst_port[1]).split('-')
                src_in_port = str(10000 + int(source_port[0]))
                dst_in_port = str(10000 + int(destination_port[0]))
                src_out_port = str(20000 + int(source_port[1]))
                dst_out_port = str(20000 + int(destination_port[1]))

                command = "ent-crs-fiber::{0}&{1},{2}&{3}:{4};".format(
                    src_in_port, dst_in_port, dst_out_port, src_out_port,
                    self._incr_ctag())
                command_result = self._session.send_command(
                    command, re_string=self._prompt)
                command_logger.info(command_result)
            else:
                raise Exception(
                    self.__class__.__name__,
                    "Bidirectional mapping supported only in logical port mode"
                    .format(self._service_mode))
        else:
            raise Exception(
                self.__class__.__name__,
                "Selected '{}' connection type is not supported".format(
                    self._service_mode))

    def map_clear_to(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "tl1":
            src_in_port = src_port[1]
            if self._port_logical_mode.lower() == "logical":
                source_port = src_port[1].split('-')
                src_in_port = str(10000 + int(source_port[0]))

            command = "dlt-crs-fiber::{0}:{1};".format(src_in_port,
                                                       self._incr_ctag())

            self._session.send_command(command, re_string=self._prompt)
        else:
            raise Exception(
                self.__class__.__name__,
                "Selected '{}' connection type is not supported".format(
                    self._service_mode))

    def map_clear(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "tl1":
            if self._port_logical_mode.lower() == "logical":
                source_port = src_port[1].split('-')
                destination_port = dst_port[1].split('-')
                src_in_port = str(10000 + int(source_port[0]))
                dst_in_port = str(10000 + int(destination_port[0]))

                command = "dlt-crs-fiber::{0}&{1}:{2};".format(
                    src_in_port, dst_in_port, self._incr_ctag())

                self._session.send_command(command, re_string=self._prompt)
            else:
                self.map_clear_to(src_port, dst_port, command_logger)
        else:
            raise Exception(
                self.__class__.__name__,
                "Selected '{}' connection type is not supported".format(
                    self._service_mode))

    def set_speed_manual(self, command_logger=None):
        pass
    def get_resource_description(self, address, command_logger=None):
        device_data = self._get_device_data()

        self._resource_info = ResourceInfo()
        self._resource_info.set_depth(0)
        self._resource_info.set_index(1)

        self._resource_info.set_address(address)

        if self._service_mode.lower() == "tl1":
            model_info_match = re.search(
                'SerialNumber=(?P<serial>\S+)".*SystemType=(?P<type>\S+)".*"(?P<vendor>\S+):'
                +
                'ChassisType=(?P<model>\S+)".*SoftwareActiveVersion=(?P<version>\S+)"',
                device_data["system_info"], re.DOTALL)

            # add chassis info
            if model_info_match is not None:
                model_info_dict = model_info_match.groupdict()

                self._resource_info.add_attribute("Vendor",
                                                  model_info_dict["vendor"])
                self._resource_info.add_attribute("Type",
                                                  model_info_dict["type"])
                self._resource_info.add_attribute("Version",
                                                  model_info_dict["version"])
                self._resource_info.add_attribute("Model",
                                                  model_info_dict["model"])

                model_name = model_info_dict["model"]

                self._resource_info.set_model_name(model_info_dict["model"])
                self._resource_info.set_serial_number(
                    model_info_dict["serial"])
            else:
                raise Exception(self.__class__.__name__,
                                "Can't parse model info!")

            # get port mappings and port info
            address_prefix = address + "/"
            port_map_list = device_data["connections_map"].split("\n")
            port_list = device_data['port_list'].split("\n")

            if self._port_logical_mode.lower() == "logical":
                logical_port_map = dict()
                for port_data in port_list:
                    port_info_match = re.search(
                        r"PORTID=(?P<id>\d+).*PORTNAME=(?P<name>(IN|OUT)\d+)" +
                        ".*PORTHEALTH=(?P<state>good|bad)", port_data,
                        re.DOTALL)
                    if port_info_match is not None:
                        port_info_dict = port_info_match.groupdict()
                        logical_port_id = re.sub('(IN|OUT)', '',
                                                 port_info_dict["name"])
                        if logical_port_id not in logical_port_map.keys():
                            logical_port_map[logical_port_id] = {}
                        if port_info_dict["state"].lower() == "good":
                            port_state = "Enable"
                        else:
                            port_state = "Disable"

                        logical_port_map[logical_port_id]['state'] = port_state

                        if 'in' in port_info_dict["name"].lower():
                            logical_port_map[logical_port_id][
                                'in'] = logical_port_id
                        else:
                            if logical_port_id in self._custom_port_pairing.values(
                            ):
                                for key, value in self._custom_port_pairing.iteritems(
                                ):
                                    if value == logical_port_id and key in logical_port_map:
                                        logical_port_map[key][
                                            'out'] = logical_port_id
                            else:
                                logical_port_map[logical_port_id][
                                    'out'] = logical_port_id

                for port_id, port_data in logical_port_map.iteritems():
                    if 'in' in port_data and 'out' in port_data:
                        logical_port_map[port_id][
                            'port_address'] = '{0}-{1}'.format(
                                logical_port_map[port_id]['in'],
                                logical_port_map[port_id]['out'])

                for port_data in port_map_list:
                    port_map_match = re.search(
                        r"IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S+),IP.*"
                        +
                        "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S+),OP.*",
                        port_data, re.DOTALL)
                    if port_map_match is not None:
                        port_map_dict = port_map_match.groupdict()
                        src_logical_port_id = re.sub(
                            '(IN|OUT)', '', port_map_dict["src_port_name"])
                        dst_logical_port_id = re.sub(
                            '(IN|OUT)', '', port_map_dict["dst_port_name"])
                        if src_logical_port_id in logical_port_map.keys() \
                                and dst_logical_port_id in logical_port_map.keys():
                            self._mapping_info[
                                dst_logical_port_id] = src_logical_port_id

                for logical_port_index, logical_port_data in logical_port_map.iteritems(
                ):
                    port_resource_info = ResourceInfo()
                    port_resource_info.set_depth(1)
                    if 'port_address' not in logical_port_data:
                        continue
                    port_resource_info.set_index(
                        logical_port_data['port_address'])
                    port_resource_info.set_model_name(model_name)
                    if logical_port_index in self._mapping_info:
                        port_resource_info.set_mapping(
                            address_prefix + logical_port_map[
                                self._mapping_info[logical_port_index]]
                            ['port_address'])
                    port_resource_info.add_attribute(
                        "State", logical_port_data['state'])
                    port_resource_info.add_attribute("Protocol Type", 0)
                    self._resource_info.add_child(
                        logical_port_data['port_address'], port_resource_info)
            else:
                for port_data in port_map_list:
                    port_map_match = re.search(
                        r".*IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S*),IP.*"
                        +
                        "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S*),OP.*",
                        port_data, re.DOTALL)

                    if port_map_match is not None:
                        port_map_dict = port_map_match.groupdict()
                        if int(port_map_dict['src_port']) > 0 and \
                                int(port_map_dict['dst_port']) > 0:
                            src_port = port_map_dict["src_port"]
                            dst_port = port_map_dict["dst_port"]
                            # self._mapping_info[dst_port] = src_port
                            self._mapping_info[src_port] = dst_port

                for port_data in port_list:
                    port_info_match = re.search(
                        r"PORTID=(?P<id>\d+).*PORTNAME=(?P<name>(IN|OUT)\d+)" +
                        ".*PORTHEALTH=(?P<state>good|bad)", port_data,
                        re.DOTALL)

                    if port_info_match is not None:
                        port_info_dict = port_info_match.groupdict()

                        port_resource_info = ResourceInfo()
                        port_resource_info.set_depth(1)

                        port_id = port_info_dict["id"]
                        port_resource_info.set_index(port_id)
                        port_resource_info.set_model_name(model_name)
                        # port_resource_info.set_name(port_info_dict["name"])

                        if port_id in self._mapping_info:
                            port_resource_info.set_mapping(
                                address_prefix + self._mapping_info[port_id])

                        if port_info_dict["state"].lower() == "good":
                            port_resource_info.add_attribute("State", "Enable")
                        else:
                            port_resource_info.add_attribute(
                                "State", "Disable")

                        port_resource_info.add_attribute("Protocol Type", 0)

                        self._resource_info.add_child(port_info_dict["id"],
                                                      port_resource_info)
        else:
            raise Exception(
                self.__class__.__name__,
                "Selected '{}' connection type is not supported".format(
                    self._service_mode))

        return self._resource_info.convert_to_xml()
示例#3
0
    def get_resource_description(self, address, command_logger):
        """Auto-load function to retrieve all information from the device

        :param address: (str) address in the format <host>:<port>?TestStream=<switch_name> (port is optional)
        :param command_logger: logging.Logger instance
        :return: common.resource_info.ResourceInfo instance with all switch sub-resources (chassis, blades, ports)
        """

        depth = 0
        resource_info = ResourceInfo()
        resource_info.set_depth(depth)
        resource_info.set_address(address)

        device_info = self._disp_switch_info()

        info_match = re.search(
            r"PHYSICAL INFORMATION(?P<physical_info>.*)"
            r"SWITCH COMPONENTS(?P<switch_components>.*)", device_info,
            re.DOTALL)

        self.model_name = re.search(r"Switch Model:[ ]*(.*?)\n",
                                    info_match.group("physical_info"),
                                    re.DOTALL).group(1)
        resource_info.set_model_name(self.model_name)
        resource_info.set_index(self.model_name)
        ip_addr = re.search(r"IP Address:[ ]*(.*?)\n",
                            info_match.group("physical_info"),
                            re.DOTALL).group(1)
        resource_info.add_attribute("Switch Address", ip_addr)

        if not self._software_version:
            self._software_version = self._get_software_version()

        resource_info.add_attribute("Software Version", self._software_version)

        info_list = info_match.group("switch_components").split("\n")

        ports_info = self._show_ports_info()

        ports_list = re.search(r".*-\n(.*)\n\n", ports_info,
                               re.DOTALL).group(1).split("\n")
        all_ports = {}

        port_mappings = self._get_port_mappings(command_logger)

        for port in ports_list:
            info = re.search(
                r"(?P<phys_addr>.*?)[ ]{2,}"
                r"(?P<status>.*?)[ ]{2,}"
                r"(?P<name>.*?)[ ]{2,}"
                r".*?[ ]{2,}"  # Lock*/Rx Pwr(dBm)
                r".*?[ ]{2,}"  # Tx Pwr(dBm)
                r".*?[ ]{2,}"  # Rx Pwr(dBm)
                r"(?P<speed>.*?)[ ]{2,}"
                r"(?P<protocol>.*)",
                port)

            chassis, blade, port_no = info.group("phys_addr").split('.')
            chassis_ports = all_ports.setdefault(int(chassis), {})
            blade_ports = chassis_ports.setdefault(int(blade), [])
            blade_ports.append(info.groupdict())

        for info_str in info_list:
            if info_str.lower().startswith("chassis"):
                chassis_no = int(re.search(r"(\d+):", info_str).group(1))
                chassis_resource = ResourceInfo()
                chassis_resource.set_depth(depth + 1)
                chassis_resource.set_index(str(chassis_no))
                resource_info.add_child(info_str, chassis_resource)

            elif info_str.startswith(" " * 4):
                # add ports

                blade_info = re.search(
                    r"(?P<vendor>.*),(?P<model>.*),(?P<uboot_rev>.*),(?P<serial_number>.*)",
                    info_str, re.DOTALL)

                if not blade_info:
                    blade_info = re.search(
                        r"(?P<model>.*?)\s{2,}(?P<uboot_rev>.*?)\s{2,}(?P<serial_number>.*?)(\s{2,}|$)",
                        info_str.strip(), re.DOTALL)

                # blade_resource.add_attribute("Vendor", blade_info.group("vendor"))
                # blade_type = blade_info.group("model").replace(" ", "-").upper()
                blade_resource.set_model_name(blade_type)
                # blade_resource.add_attribute("Model", blade_info.group("model"))
                blade_resource.add_attribute("Uboot Rev.",
                                             blade_info.group("uboot_rev"))
                blade_resource.set_serial_number(
                    blade_info.group("serial_number"))

                chassis_ports = all_ports.get(chassis_no, {})
                blade_ports = chassis_ports.get(blade_no, [])

                for port_data in blade_ports:
                    phys_addr = port_data["phys_addr"]
                    port_no = int(phys_addr.split(".")[-1])

                    if self.is_logical_port_mode:
                        port_resource = ResourceInfo()
                        port_resource.set_model_name(blade_type)
                        port_resource.set_depth(depth + 3)
                        port_resource.set_index(str(port_no))
                        port_resource.add_attribute("Protocol Type", 0)

                        connected_resource = self._get_connected_resource(
                            phys_addr, port_mappings)
                        if connected_resource:
                            port_resource.set_mapping("{}/{}".format(
                                address, connected_resource))

                        # if port_data["status"].lower() == "not connected":
                        #     port_resource.add_attribute("State", "Enable")
                        # else:
                        #     port_resource.add_attribute("State", "Disable")

                        blade_resource.add_child(port_no, port_resource)
                    else:
                        for subport in (self.TX_SUBPORT_INDEX,
                                        self.RX_SUBPORT_INDEX):
                            subport_idx = "{}-{}".format(port_no, subport)
                            subport_resource = ResourceInfo()
                            subport_resource.set_model_name(blade_type)
                            subport_resource.set_depth(depth + 3)
                            subport_resource.set_index(subport_idx)
                            subport_resource.add_attribute("Protocol Type", 0)
                            blade_resource.add_child(subport_idx,
                                                     subport_resource)

                            if subport == self.RX_SUBPORT_INDEX:
                                connected_resource = self._get_connected_resource(
                                    phys_addr, port_mappings)
                                if connected_resource:
                                    subport_resource.set_mapping(
                                        "{}/{}".format(address,
                                                       connected_resource))

            elif info_str.startswith(" " * 2):
                # blade type is the last word in the sequence
                blade_base_info = re.search(
                    r"(?P<blade_id>\d+)\s+(?P<model>.*)", info_str)

                blade_type = blade_base_info.group("model").strip().replace(
                    " ", "-").title()
                blade_no = int(blade_base_info.group("blade_id"))

                blade_resource = ResourceInfo()
                blade_resource.set_model_name(blade_type)
                blade_resource.set_depth(depth + 2)
                blade_resource.set_index(str(blade_no))
                chassis_resource.add_child(info_str, blade_resource)

        return resource_info.convert_to_xml()
示例#4
0
    def get_resource_description(self, address, command_logger=None):
        """ Auto-load function to retrieve all information from the device

        :param address: (str) address attribute from the CloudShell portal
        :param command_logger: logging.Logger instance
        :return: xml.etree.ElementTree.Element instance with all switch sub-resources (blades, ports)
        """

        resource_info = ResourceInfo()
        resource_info.set_depth(0)
        resource_info.set_address(address)

        if self._service_mode.lower() == "rest":
            raise NotImplementedError
        elif self._service_mode.lower() == "tl1":

            dev_info = self._get_device_info()
            resource_info.add_attribute("Vendor", "Calient")
            resource_info.add_attribute("Version", dev_info.get("version", ""))
            model_name = dev_info.get("model", "")
            resource_info.set_model_name(model_name)
            resource_info.set_serial_number(dev_info.get("serial", ""))

            connection_info = self._get_crossconnections()

            for port_info in self._get_ports():
                port_resource_info = ResourceInfo()
                port_resource_info.set_depth(1)

                port_name = port_info.get("port_name")
                port_resource_info.set_index(port_name)
                if port_name in connection_info:
                    port_resource_info.set_mapping(
                        "{address}/{dst_port}".format(
                            address=address,
                            dst_port=connection_info[port_name]))

                port_resource_info.add_attribute("Protocol Type", 0)
                port_resource_info.set_model_name(model_name)

                resource_info.add_child(port_name, port_resource_info)

        return resource_info.convert_to_xml()
                logical_port_map[port_id]['in'],
                logical_port_map[port_id]['out'])

for port_data in port_map_list:
    port_map_match = re.search(r"IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S+),IP.*" +
                               "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S+),OP.*",
                               port_data, re.DOTALL)
    if port_map_match is not None:
        port_map_dict = port_map_match.groupdict()
        src_logical_port_id = re.sub('(IN|OUT)', '', port_map_dict["src_port_name"])
        dst_logical_port_id = re.sub('(IN|OUT)', '', port_map_dict["dst_port_name"])
        if src_logical_port_id in logical_port_map.keys() \
                and dst_logical_port_id in logical_port_map.keys():
            _mapping_info[src_logical_port_id] = dst_logical_port_id

for logical_port_index, logical_port_data in logical_port_map.iteritems():
    port_resource_info = ResourceInfo()
    port_resource_info.set_depth(1)
    if 'port_address' not in logical_port_data:
        continue
    port_resource_info.set_index(logical_port_data['port_address'])
    port_resource_info.set_model_name('adadadad')
    if logical_port_index in _mapping_info:
        port_resource_info.set_mapping(
            address_prefix + logical_port_map[_mapping_info[logical_port_index]]['port_address'])
    port_resource_info.add_attribute("State", logical_port_data['state'])
    port_resource_info.add_attribute("Protocol Type", 0)
    result_list.append((logical_port_index, port_resource_info))

print result_list
    def get_resource_description(self, address, command_logger):
        """Auto-load function to retrieve all information from the device

        :param address: (str) address in the format <host>:<port>?TestStream=<switch_name> (port is optional)
        :param command_logger: logging.Logger instance
        :return: common.resource_info.ResourceInfo instance with all switch sub-resources (chassis, blades, ports)
        """

        depth = 0
        resource_info = ResourceInfo()
        resource_info.set_depth(depth)
        resource_info.set_address(address)

        device_info = self._disp_switch_info()

        info_match = re.search(
            r"PHYSICAL INFORMATION(?P<physical_info>.*)"
            r"SWITCH COMPONENTS(?P<switch_components>.*)",
            device_info, re.DOTALL)

        self.model_name = re.search(r"Switch Model:[ ]*(.*?)\n", info_match.group("physical_info"), re.DOTALL).group(1)
        resource_info.set_model_name(self.model_name)
        resource_info.set_index(self.model_name)
        ip_addr = re.search(r"IP Address:[ ]*(.*?)\n", info_match.group("physical_info"), re.DOTALL).group(1)
        resource_info.add_attribute("Switch Address", ip_addr)

        if not self._software_version:
            self._software_version = self._get_software_version()

        resource_info.add_attribute("Software Version", self._software_version)

        info_list = info_match.group("switch_components").split("\n")

        ports_info = self._show_ports_info()

        ports_list = re.search(r".*-\n(.*)\n\n", ports_info, re.DOTALL).group(1).split("\n")
        all_ports = {}

        port_mappings = self._get_port_mappings(command_logger)

        for port in ports_list:
            info = re.search(r"(?P<phys_addr>.*?)[ ]{2,}"
                             r"(?P<status>.*?)[ ]{2,}"
                             r"(?P<name>.*?)[ ]{2,}"
                             r".*?[ ]{2,}"  # Lock*/Rx Pwr(dBm)
                             r".*?[ ]{2,}"  # Tx Pwr(dBm)
                             r".*?[ ]{2,}"  # Rx Pwr(dBm)
                             r"(?P<speed>.*?)[ ]{2,}"
                             r"(?P<protocol>.*)", port)

            chassis, blade, port_no = info.group("phys_addr").split('.')
            chassis_ports = all_ports.setdefault(int(chassis), {})
            blade_ports = chassis_ports.setdefault(int(blade), [])
            blade_ports.append(info.groupdict())

        for info_str in info_list:
            if info_str.lower().startswith("chassis"):
                chassis_no = int(re.search(r"(\d+):", info_str).group(1))
                chassis_resource = ResourceInfo()
                chassis_resource.set_depth(depth + 1)
                chassis_resource.set_index(str(chassis_no))
                resource_info.add_child(info_str, chassis_resource)

            elif info_str.startswith(" " * 4):
                # add ports

                blade_info = re.search(
                    r"(?P<vendor>.*),(?P<model>.*),(?P<uboot_rev>.*),(?P<serial_number>.*)", info_str, re.DOTALL)

                if not blade_info:
                    blade_info = re.search(
                        r"(?P<model>.*?)\s{2,}(?P<uboot_rev>.*?)\s{2,}(?P<serial_number>.*?)(\s{2,}|$)",
                        info_str.strip(),
                        re.DOTALL)

                # blade_resource.add_attribute("Vendor", blade_info.group("vendor"))
                # blade_type = blade_info.group("model").replace(" ", "-").upper()
                blade_resource.set_model_name(blade_type)
                # blade_resource.add_attribute("Model", blade_info.group("model"))
                blade_resource.add_attribute("Uboot Rev.", blade_info.group("uboot_rev"))
                blade_resource.set_serial_number(blade_info.group("serial_number"))

                chassis_ports = all_ports.get(chassis_no, {})
                blade_ports = chassis_ports.get(blade_no, [])

                for port_data in blade_ports:
                    phys_addr = port_data["phys_addr"]
                    port_no = int(phys_addr.split(".")[-1])

                    if self.is_logical_port_mode:
                        port_resource = ResourceInfo()
                        port_resource.set_model_name(blade_type)
                        port_resource.set_depth(depth + 3)
                        port_resource.set_index(str(port_no))
                        port_resource.add_attribute("Protocol Type", 0)

                        connected_resource = self._get_connected_resource(phys_addr, port_mappings)
                        if connected_resource:
                            port_resource.set_mapping("{}/{}".format(address, connected_resource))

                        # if port_data["status"].lower() == "not connected":
                        #     port_resource.add_attribute("State", "Enable")
                        # else:
                        #     port_resource.add_attribute("State", "Disable")

                        blade_resource.add_child(port_no, port_resource)
                    else:
                        for subport in (self.TX_SUBPORT_INDEX, self.RX_SUBPORT_INDEX):
                            subport_idx = "{}-{}".format(port_no, subport)
                            subport_resource = ResourceInfo()
                            subport_resource.set_model_name(blade_type)
                            subport_resource.set_depth(depth + 3)
                            subport_resource.set_index(subport_idx)
                            subport_resource.add_attribute("Protocol Type", 0)
                            blade_resource.add_child(subport_idx, subport_resource)

                            if subport == self.RX_SUBPORT_INDEX:
                                connected_resource = self._get_connected_resource(phys_addr, port_mappings)
                                if connected_resource:
                                    subport_resource.set_mapping("{}/{}".format(address, connected_resource))

            elif info_str.startswith(" " * 2):
                # blade type is the last word in the sequence
                blade_base_info = re.search(r"(?P<blade_id>\d+)\s+(?P<model>.*)", info_str)

                blade_type = blade_base_info.group("model").strip().replace(" ", "-").title()
                blade_no = int(blade_base_info.group("blade_id"))

                blade_resource = ResourceInfo()
                blade_resource.set_model_name(blade_type)
                blade_resource.set_depth(depth + 2)
                blade_resource.set_index(str(blade_no))
                chassis_resource.add_child(info_str, blade_resource)

        return resource_info.convert_to_xml()
    def get_resource_description(self, address, command_logger=None):
        """Auto-load function to retrieve all information from the device

        :param address: (str) address attribute from the CloudShell portal
        :param command_logger: logging.Logger instance
        :return: xml.etree.ElementTree.Element instance with all switch sub-resources (blades, ports)
        """

        number_of_blades = ConfigurationParser.get("driver_variable", "number_of_blades")
        ports_per_blade = ConfigurationParser.get("driver_variable", "ports_per_blade")

        # Step 1. Create root element (switch):
        depth = 0
        resource_info = ResourceInfo()
        resource_info.set_depth(depth)
        resource_info.set_address(address)
        resource_info.set_index("L1Mock")

        # Step 2. Create child resources for the root element (blades):
        for blade_no in xrange(number_of_blades):
            blade_resource = ResourceInfo()
            blade_resource.set_depth(depth + 1)
            blade_resource.set_index(str(blade_no+1))
            resource_info.add_child(blade_no+1, blade_resource)

            # Step 3. Create child resources for each root sub-resource (ports in blades)
            for port_no in xrange(ports_per_blade):
                port_resource = ResourceInfo()
                port_resource.set_depth(depth + 2)
                port_resource.set_index("%03d" % (port_no+1))
                blade_resource.add_child(port_no+1, port_resource)

        return resource_info.convert_to_xml()
    def get_resource_description(self, address, command_logger=None):

        depth = 0
        resource_info = ResourceInfo()
        resource_info.set_depth(depth)
        resource_info.set_address(address)

        error_map = OrderedDict([("% Invalid", 'Can\'t get system details')])

        command = 'show system details | nomore'
        system_details = self._session.send_command(command,
                                                    re_string=self._prompt,
                                                    error_map=error_map)
        model_name = re.search(r"Device Model[ ]*(.*?)\n", system_details,
                               re.DOTALL).group(1)
        resource_info.set_model_name(model_name)
        resource_info.set_index(model_name)
        serial_number = re.search(r"Serial Number[ ]*(.*?)\n", system_details,
                                  re.DOTALL).group(1)
        resource_info.set_serial_number(serial_number)

        command = 'show ports | nomore'
        ports_details = self._session.send_command(command,
                                                   re_string=self._prompt,
                                                   error_map=error_map)

        blade_resource = ResourceInfo()
        blade_resource.set_depth(depth + 1)
        blade_resource.set_index(str(1))
        resource_info.add_child(1, blade_resource)

        src_ports_set = self.parse_filters_source_ports(command_logger)

        ports_list = re.search(r"Port.*?\n====.*?\n(.*)\n", ports_details,
                               re.DOTALL).group(1).split("\n")

        for port in ports_list:

            port_id = re.search(r"(.*?)[ ]{1,}.*", port, re.DOTALL).group(1)

            port_resource = ResourceInfo()
            port_resource.set_depth(depth + 2)
            port_resource.set_index(str(port_id))

            if port_id in src_ports_set:
                port_resource.set_mapping("{}/1/{}".format(
                    address, src_ports_set[port_id]))

            blade_resource.add_child(port_id, port_resource)

        return resource_info.convert_to_xml()
    def get_resource_description(self, address, command_logger=None):
        self._session.send_command("", re_string=self._login_prompt)
        device_data = self._get_device_data()

        self._resource_info = ResourceInfo()
        self._resource_info.set_depth(0)
        self._resource_info.set_index(1)

        self._resource_info.set_address(address)

        if self._service_mode.lower() == "tl1":
            model_info_match = re.search('SerialNumber=(?P<serial>\S+)".*SystemType=(?P<type>\S+)".*"(?P<vendor>\S+):' +
                                         'ChassisType=(?P<model>\S+)".*SoftwareActiveVersion=(?P<version>\S+)"',
                                         device_data["system_info"], re.DOTALL)

            # add chassis info
            if model_info_match is not None:
                model_info_dict = model_info_match.groupdict()

                self._resource_info.add_attribute("Vendor", model_info_dict["vendor"])
                self._resource_info.add_attribute("Type", model_info_dict["type"])
                self._resource_info.add_attribute("Version", model_info_dict["version"])
                self._resource_info.add_attribute("Model", model_info_dict["model"])

                model_name = model_info_dict["model"]

                self._resource_info.set_model_name(model_info_dict["model"])
                self._resource_info.set_serial_number(model_info_dict["serial"])
            else:
                raise Exception(self.__class__.__name__, "Can't parse model info!")

            # get port mappings and port info
            address_prefix = address + "/"
            port_map_list = device_data["connections_map"].split("\n")
            port_list = device_data['port_list'].split("\n")

            if self._port_logical_mode.lower() == "logical":
                logical_port_map = dict()
                for port_data in port_list:
                    port_info_match = re.search(r"PORTID=(?P<id>\d+).*PORTNAME=(?P<name>(IN|OUT)\d+)" +
                                                ".*PORTHEALTH=(?P<state>good|bad)", port_data, re.DOTALL)
                    if port_info_match is not None:
                        port_info_dict = port_info_match.groupdict()
                        logical_port_id = re.sub('(IN|OUT)', '', port_info_dict["name"])
                        if logical_port_id not in logical_port_map.keys():
                            logical_port_map[logical_port_id] = {}
                        if port_info_dict["state"].lower() == "good":
                            port_state = "Enable"
                        else:
                            port_state = "Disable"

                        logical_port_map[logical_port_id]['state'] = port_state

                        if 'in' in port_info_dict["name"].lower():
                            logical_port_map[logical_port_id]['in'] = logical_port_id
                        else:
                            if logical_port_id in self._custom_port_pairing.values():
                                for key, value in self._custom_port_pairing.iteritems():
                                    if value == logical_port_id and key in logical_port_map:
                                        logical_port_map[key]['out'] = logical_port_id
                            else:
                                logical_port_map[logical_port_id]['out'] = logical_port_id

                for port_id, port_data in logical_port_map.iteritems():
                    if 'in' in port_data and 'out' in port_data:
                        logical_port_map[port_id]['port_address'] = '{0}-{1}'.format(
                            logical_port_map[port_id]['in'],
                            logical_port_map[port_id]['out'])

                for port_data in port_map_list:
                    port_map_match = re.search(r"IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S+),IP.*" +
                                               "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S+),OP.*",
                                               port_data, re.DOTALL)
                    if port_map_match is not None:
                        port_map_dict = port_map_match.groupdict()
                        src_logical_port_id = re.sub('(IN|OUT)', '', port_map_dict["src_port_name"])
                        dst_logical_port_id = re.sub('(IN|OUT)', '', port_map_dict["dst_port_name"])
                        if src_logical_port_id in logical_port_map.keys() \
                                and dst_logical_port_id in logical_port_map.keys():
                            self._mapping_info[dst_logical_port_id] = src_logical_port_id

                for logical_port_index, logical_port_data in logical_port_map.iteritems():
                    port_resource_info = ResourceInfo()
                    port_resource_info.set_depth(1)
                    if 'port_address' not in logical_port_data:
                        continue
                    port_resource_info.set_index(logical_port_data['port_address'])
                    port_resource_info.set_model_name(model_name)
                    if logical_port_index in self._mapping_info:
                        port_resource_info.set_mapping(address_prefix +
                                                       logical_port_map[self._mapping_info[logical_port_index]][
                                                           'port_address'])
                    port_resource_info.add_attribute("State", logical_port_data['state'])
                    port_resource_info.add_attribute("Protocol Type", 0)
                    self._resource_info.add_child(logical_port_data['port_address'], port_resource_info)
            else:
                for port_data in port_map_list:
                    port_map_match = re.search(r".*IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S*),IP.*" +
                                               "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S*),OP.*",
                                               port_data, re.DOTALL)

                    if port_map_match is not None:
                        port_map_dict = port_map_match.groupdict()
                        if int(port_map_dict['src_port']) > 0 and \
                                int(port_map_dict['dst_port']) > 0:
                            src_port = port_map_dict["src_port"]
                            dst_port = port_map_dict["dst_port"]
                            # self._mapping_info[dst_port] = src_port
                            self._mapping_info[src_port] = dst_port

                for port_data in port_list:
                    port_info_match = re.search(r"PORTID=(?P<id>\d+).*PORTNAME=(?P<name>(IN|OUT)\d+)" +
                                                ".*PORTHEALTH=(?P<state>good|bad)", port_data, re.DOTALL)

                    if port_info_match is not None:
                        port_info_dict = port_info_match.groupdict()

                        port_resource_info = ResourceInfo()
                        port_resource_info.set_depth(1)

                        port_id = port_info_dict["id"]
                        port_resource_info.set_index(port_id)
                        port_resource_info.set_model_name(model_name)
                        # port_resource_info.set_name(port_info_dict["name"])

                        if port_id in self._mapping_info:
                            port_resource_info.set_mapping(address_prefix + self._mapping_info[port_id])

                        if port_info_dict["state"].lower() == "good":
                            port_resource_info.add_attribute("State", "Enable")
                        else:
                            port_resource_info.add_attribute("State", "Disable")

                        port_resource_info.add_attribute("Protocol Type", 0)

                        self._resource_info.add_child(port_info_dict["id"], port_resource_info)
        else:
            raise Exception(self.__class__.__name__,
                            "Selected '{}' connection type is not supported".format(self._service_mode))

        return self._resource_info.convert_to_xml()
class GlimmerglassDriverHandler(DriverHandlerBase):
    def __init__(self):
        DriverHandlerBase.__init__(self)

        self._ctag = 1
        self._switch_name = ''
        self._switch_size = 0
        self._mapping_info = dict()

        self._resource_info = None

        self._service_mode = ConfigurationParser.get("driver_variable", "service_mode")
        self._port_logical_mode = ConfigurationParser.get("driver_variable", "port_mode")
        self._custom_port_pairing = ConfigurationParser.get("driver_variable", "custom_port_pairing") or dict()
        self._login_prompt = ConfigurationParser.get("common_variable", "device_login_prompt")

    def _incr_ctag(self):
        self._ctag += 1
        return self._ctag

    def login(self, address, username, password, command_logger=None):
        ip = address
        port = None
        if ":" in address:
            address_data = address.split(":")
            ip = address_data[0]
            port = int(address_data[1])
        if self._service_mode.lower() == "tl1":
            command = 'ACT-USER::{0}:{1}::{2};'.format(username, self._ctag, password)
            command_result = self._session.connect(host=ip, username=username, password=password, command=command,
                                                   re_string=self._login_prompt, port=port)
            command_logger.info(command_result)

            if not re.search(r'COMPLD', command_result):
                command_logger.info('Didn\'t find success message, retrying ...')
                command_result = self._session.send_command(command, re_string=self._login_prompt)
                command_logger.info(command_result)
            else:
                command_logger.info('Login status: OK')

            match_result = re.search(r"<\s+(?P<host>\S+)\s+\d+", command_result, re.DOTALL)
            if match_result is not None:
                self._switch_name = match_result.groupdict()['host']
        else:
            raise Exception(self.__class__.__name__,
                            "Selected '{}' connection type is not supported".format(self._service_mode))

    def _get_device_data(self):
        device_data = dict()

        if self._service_mode.lower() == "scpi":
            pass
        elif self._service_mode.lower() == "tl1":
            command = "rtrv-system-info:::{0};".format(self._incr_ctag())
            device_data["system_info"] = self._session.send_command(command, re_string=self._prompt)

            size_match = re.search(r"LicensedPortMatrix=(?P<src>\d+)x(?P<dst>\d+)", device_data["system_info"],
                                   re.DOTALL)

            if size_match is not None:
                size_dict = size_match.groupdict()

                self._switch_size = int(size_dict["src"]) + int(size_dict["dst"])
            else:
                raise Exception(self.__class__.__name__, "Can't find 'size' parameter!")

            command = "RTRV-CFG-FIBER::all:{0};".format(self._incr_ctag())
            device_data["port_list"] = self._session.send_command(command, re_string=self._prompt)

            command = "rtrv-crs-fiber::all:{0};".format(self._incr_ctag())
            device_data["connections_map"] = self._session.send_command(command, re_string=self._prompt)
        else:
            raise Exception(self.__class__.__name__,
                            "Selected '{}' connection type is not supported".format(self._service_mode))

        return device_data

    def get_resource_description(self, address, command_logger=None):
        self._session.send_command("", re_string=self._login_prompt)
        device_data = self._get_device_data()

        self._resource_info = ResourceInfo()
        self._resource_info.set_depth(0)
        self._resource_info.set_index(1)

        self._resource_info.set_address(address)

        if self._service_mode.lower() == "tl1":
            model_info_match = re.search('SerialNumber=(?P<serial>\S+)".*SystemType=(?P<type>\S+)".*"(?P<vendor>\S+):' +
                                         'ChassisType=(?P<model>\S+)".*SoftwareActiveVersion=(?P<version>\S+)"',
                                         device_data["system_info"], re.DOTALL)

            # add chassis info
            if model_info_match is not None:
                model_info_dict = model_info_match.groupdict()

                self._resource_info.add_attribute("Vendor", model_info_dict["vendor"])
                self._resource_info.add_attribute("Type", model_info_dict["type"])
                self._resource_info.add_attribute("Version", model_info_dict["version"])
                self._resource_info.add_attribute("Model", model_info_dict["model"])

                model_name = model_info_dict["model"]

                self._resource_info.set_model_name(model_info_dict["model"])
                self._resource_info.set_serial_number(model_info_dict["serial"])
            else:
                raise Exception(self.__class__.__name__, "Can't parse model info!")

            # get port mappings and port info
            address_prefix = address + "/"
            port_map_list = device_data["connections_map"].split("\n")
            port_list = device_data['port_list'].split("\n")

            if self._port_logical_mode.lower() == "logical":
                logical_port_map = dict()
                for port_data in port_list:
                    port_info_match = re.search(r"PORTID=(?P<id>\d+).*PORTNAME=(?P<name>(IN|OUT)\d+)" +
                                                ".*PORTHEALTH=(?P<state>good|bad)", port_data, re.DOTALL)
                    if port_info_match is not None:
                        port_info_dict = port_info_match.groupdict()
                        logical_port_id = re.sub('(IN|OUT)', '', port_info_dict["name"])
                        if logical_port_id not in logical_port_map.keys():
                            logical_port_map[logical_port_id] = {}
                        if port_info_dict["state"].lower() == "good":
                            port_state = "Enable"
                        else:
                            port_state = "Disable"

                        logical_port_map[logical_port_id]['state'] = port_state

                        if 'in' in port_info_dict["name"].lower():
                            logical_port_map[logical_port_id]['in'] = logical_port_id
                        else:
                            if logical_port_id in self._custom_port_pairing.values():
                                for key, value in self._custom_port_pairing.iteritems():
                                    if value == logical_port_id and key in logical_port_map:
                                        logical_port_map[key]['out'] = logical_port_id
                            else:
                                logical_port_map[logical_port_id]['out'] = logical_port_id

                for port_id, port_data in logical_port_map.iteritems():
                    if 'in' in port_data and 'out' in port_data:
                        logical_port_map[port_id]['port_address'] = '{0}-{1}'.format(
                            logical_port_map[port_id]['in'],
                            logical_port_map[port_id]['out'])

                for port_data in port_map_list:
                    port_map_match = re.search(r"IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S+),IP.*" +
                                               "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S+),OP.*",
                                               port_data, re.DOTALL)
                    if port_map_match is not None:
                        port_map_dict = port_map_match.groupdict()
                        src_logical_port_id = re.sub('(IN|OUT)', '', port_map_dict["src_port_name"])
                        dst_logical_port_id = re.sub('(IN|OUT)', '', port_map_dict["dst_port_name"])
                        if src_logical_port_id in logical_port_map.keys() \
                                and dst_logical_port_id in logical_port_map.keys():
                            self._mapping_info[dst_logical_port_id] = src_logical_port_id

                for logical_port_index, logical_port_data in logical_port_map.iteritems():
                    port_resource_info = ResourceInfo()
                    port_resource_info.set_depth(1)
                    if 'port_address' not in logical_port_data:
                        continue
                    port_resource_info.set_index(logical_port_data['port_address'])
                    port_resource_info.set_model_name(model_name)
                    if logical_port_index in self._mapping_info:
                        port_resource_info.set_mapping(address_prefix +
                                                       logical_port_map[self._mapping_info[logical_port_index]][
                                                           'port_address'])
                    port_resource_info.add_attribute("State", logical_port_data['state'])
                    port_resource_info.add_attribute("Protocol Type", 0)
                    self._resource_info.add_child(logical_port_data['port_address'], port_resource_info)
            else:
                for port_data in port_map_list:
                    port_map_match = re.search(r".*IPORTID=(?P<src_port>\d+).*IPORTNAME=(?P<src_port_name>\S*),IP.*" +
                                               "OPORTID=(?P<dst_port>\d+).*OPORTNAME=(?P<dst_port_name>\S*),OP.*",
                                               port_data, re.DOTALL)

                    if port_map_match is not None:
                        port_map_dict = port_map_match.groupdict()
                        if int(port_map_dict['src_port']) > 0 and \
                                int(port_map_dict['dst_port']) > 0:
                            src_port = port_map_dict["src_port"]
                            dst_port = port_map_dict["dst_port"]
                            # self._mapping_info[dst_port] = src_port
                            self._mapping_info[src_port] = dst_port

                for port_data in port_list:
                    port_info_match = re.search(r"PORTID=(?P<id>\d+).*PORTNAME=(?P<name>(IN|OUT)\d+)" +
                                                ".*PORTHEALTH=(?P<state>good|bad)", port_data, re.DOTALL)

                    if port_info_match is not None:
                        port_info_dict = port_info_match.groupdict()

                        port_resource_info = ResourceInfo()
                        port_resource_info.set_depth(1)

                        port_id = port_info_dict["id"]
                        port_resource_info.set_index(port_id)
                        port_resource_info.set_model_name(model_name)
                        # port_resource_info.set_name(port_info_dict["name"])

                        if port_id in self._mapping_info:
                            port_resource_info.set_mapping(address_prefix + self._mapping_info[port_id])

                        if port_info_dict["state"].lower() == "good":
                            port_resource_info.add_attribute("State", "Enable")
                        else:
                            port_resource_info.add_attribute("State", "Disable")

                        port_resource_info.add_attribute("Protocol Type", 0)

                        self._resource_info.add_child(port_info_dict["id"], port_resource_info)
        else:
            raise Exception(self.__class__.__name__,
                            "Selected '{}' connection type is not supported".format(self._service_mode))

        return self._resource_info.convert_to_xml()

    def map_uni(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "tl1":
            self._session.send_command("", re_string=self._login_prompt)
            src_in_port = min(int(src_port[1]), int(dst_port[1]))

            dst_out_port = max(int(src_port[1]), int(dst_port[1]))

            if self._port_logical_mode.lower() == "logical":
                src_in_port = str(10000 + int(src_in_port.split('-')[0]))
                dst_out_port = str(20000 + int(dst_out_port.split('-')[1]))

            command = "ent-crs-fiber::{0},{1}:{2};".format(src_in_port, dst_out_port, self._incr_ctag())
            command_result = self._session.send_command(command, re_string=self._prompt)
            command_logger.info(command_result)
        else:
            raise Exception(self.__class__.__name__,
                            "Selected '{}' connection type is not supported".format(self._service_mode))

    def map_bidi(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "tl1":
            self._session.send_command("", re_string=self._login_prompt)
            if self._port_logical_mode.lower() == "logical":
                source_port = str(src_port[1]).split('-')
                destination_port = str(dst_port[1]).split('-')
                src_in_port = str(10000 + int(source_port[0]))
                dst_in_port = str(10000 + int(destination_port[0]))
                src_out_port = str(20000 + int(source_port[1]))
                dst_out_port = str(20000 + int(destination_port[1]))

                command = "ent-crs-fiber::{0}&{1},{2}&{3}:{4};".format(src_in_port, dst_in_port, dst_out_port,
                                                                       src_out_port, self._incr_ctag())
                command_result = self._session.send_command(command, re_string=self._prompt)
                command_logger.info(command_result)
            else:
                raise Exception(self.__class__.__name__,
                                "Selected '{}' connection type is not supported".format(self._service_mode))

    def map_clear_to(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "tl1":
            self._session.send_command("", re_string=self._login_prompt)
            src_in_port = src_port[1]
            if self._port_logical_mode.lower() == "logical":
                source_port = src_port[1].split('-')
                src_in_port = str(10000 + int(source_port[0]))

            command = "dlt-crs-fiber::{0}:{1};".format(src_in_port, self._incr_ctag())

            self._session.send_command(command, re_string=self._prompt)
        else:
            raise Exception(self.__class__.__name__,
                            "Selected '{}' connection type is not supported".format(self._service_mode))

    def map_clear(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "tl1":
            self._session.send_command("", re_string=self._login_prompt)
            if self._port_logical_mode.lower() == "logical":
                source_port = src_port[1].split('-')
                destination_port = dst_port[1].split('-')
                src_in_port = str(10000 + int(source_port[0]))
                dst_in_port = str(10000 + int(destination_port[0]))

                command = "dlt-crs-fiber::{0}&{1}:{2};".format(src_in_port, dst_in_port, self._incr_ctag())

                self._session.send_command(command, re_string=self._prompt)
            else:
                self.map_clear_to(src_port, dst_port, command_logger)
        else:
            raise Exception(self.__class__.__name__,
                            "Selected '{}' connection type is not supported".format(self._service_mode))

    def set_speed_manual(self, command_logger=None):
        pass
class IxiaXstreamDriverHandler(DriverHandlerBase):
    def __init__(self):
        DriverHandlerBase.__init__(self)

        self._snmp_handler = None
        self._ctag = 1
        self._switch_name = ''
        self._switch_size = 0
        self._mapping_info = dict()

        self._resource_info = None

        self._service_mode = ConfigurationParser.get("driver_variable",
                                                     "service_mode")
        self._port_logical_mode = ConfigurationParser.get(
            "driver_variable", "port_mode")
        self._custom_port_pairing = ConfigurationParser.get(
            "driver_variable", "custom_port_pairing")
        self._snmp_write_community = ConfigurationParser.get(
            "driver_variable", "snmp_write_community")
        self._snmp_version = ConfigurationParser.get("driver_variable",
                                                     "snmp_version")
        self._snmp_v3_user = ConfigurationParser.get("driver_variable",
                                                     "snmp_write_community")
        self._snmp_v3_password = ConfigurationParser.get(
            "driver_variable", "snmp_write_community")
        self._snmp_v3_private_key = ConfigurationParser.get(
            "driver_variable", "snmp_write_community")

    def _incr_ctag(self):
        self._ctag += 1
        return self._ctag

    def login(self, address, username="", password="", command_logger=None):
        if self._service_mode.lower() == "snmp":
            self._snmp_handler = self.__get_snmp_handler(
                address, command_logger)
            command_result = self._snmp_handler.get_property(
                "SNMPv2-MIB", "sysName", 0)
        elif self._service_mode.lower() == "ssh":
            command_result = ""
            try:
                self._session.connect(address, username, password, port=None)
                command_result = self._session.send_command(
                    "", re_string=self._prompt)
                command_logger.info('Login status: OK')
            except Exception as e:
                command_logger.info(e.args)
        else:
            raise Exception(
                self.__class__.__name__,
                "From service mode type (current mode: '" +
                self._service_mode + "'!")

        match_result = re.search(r"(?<=(@)).*(?=(]))", command_result,
                                 re.DOTALL)
        if match_result:
            self._switch_name = match_result.group()

    def __get_snmp_handler(self, host, logger):
        path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), ".", "mibs"))
        logger.info(host)
        logger.info(self._snmp_write_community)
        if "3" in self._snmp_version:
            if not self._snmp_v3_user or not self._snmp_v3_password or not self._snmp_v3_private_key:
                raise Exception(
                    self.__class__.__name__,
                    "Cannot create SNMP Version 3, Check configuration")
            snmp_params = SNMPV3Parameters(
                ip=host,
                snmp_user=self._snmp_v3_user,
                snmp_password=self._snmp_v3_password,
                snmp_private_key=self._snmp_v3_private_key)
            logger.info("SNMP V3 Created")
        else:
            if not self._snmp_write_community:
                raise Exception(
                    self.__class__.__name__,
                    "Cannot create SNMP Version 2, Check configuration")
            snmp_params = SNMPV2Parameters(
                ip=host, snmp_community=self._snmp_write_community)
            logger.info("SNMP V2 Created")
        snmp_handler = QualiSnmp(snmp_params, logger)
        snmp_handler.update_mib_sources(path)
        return snmp_handler

    def get_resource_description(self, address, command_logger=None):
        autoload_helper = IxiaXstreamAutoloadHelper(command_logger)
        if self._service_mode.lower() == "ssh":
            device_data = autoload_helper.get_ssh_device_structure(
                self._session)
        elif self._service_mode.lower() == "snmp":
            snmp_handler = self.__get_snmp_handler(address, command_logger)
            device_data = autoload_helper.get_snmp_device_structure(
                snmp_handler)
        else:
            if not self._service_mode.lower():
                raise Exception(self.__class__.__name__,
                                "Service mode is empty")
            raise Exception(
                self.__class__.__name__,
                "Service mode {0} is not supported".format(
                    self._service_mode.lower()))

        address_prefix = address + "/"
        self._resource_info = ResourceInfo()
        self._resource_info.set_depth(0)
        self._resource_info.set_index(1)

        self._resource_info.set_address(address)
        self._resource_info.add_attribute("Vendor", device_data["vendor"])
        self._resource_info.add_attribute("Type", device_data["type"])
        self._resource_info.add_attribute("Version", device_data["version"])
        self._resource_info.add_attribute("Model", device_data["model"])
        model_name = device_data["model"]
        self._resource_info.set_model_name(model_name)
        self._resource_info.set_serial_number(device_data["serial"])

        # if self._port_logical_mode.lower() == "logical":
        for port_id, port_data in device_data["ports"].iteritems():
            port_resource_info = ResourceInfo()
            port_resource_info.set_depth(1)
            port_resource_info.set_index(port_id)
            port_resource_info.set_model_name(model_name)
            mapped_to = port_data.get("mapped_to")
            if mapped_to:
                port_resource_info.set_mapping(address_prefix + mapped_to)
            port_resource_info.add_attribute("State", port_data['state'])
            port_resource_info.add_attribute("Protocol Type", 0)
            self._resource_info.add_child(port_id, port_resource_info)
        return self._resource_info.convert_to_xml()

    def map_uni(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "ssh":
            pass
        elif self._service_mode.lower() == "snmp":
            self._add_snmp_filter(src_port, dst_port, command_logger)

    def map_tap(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "ssh":
            pass
        elif self._service_mode.lower() == "snmp":
            self._add_snmp_filter(src_port, dst_port, command_logger)

    def map_bidi(self, src_port, dst_port, command_logger=None):
        if self._service_mode.lower() == "ssh":
            pass
        elif self._service_mode.lower() == "snmp":
            self._add_snmp_filter(src_port, dst_port, command_logger)
            self._add_snmp_filter(dst_port, src_port, command_logger)

    def _add_snmp_filter(self, src_port, dst_port, logger):
        src_in_port = src_port[-1]
        dst_out_port = dst_port[-1]
        existing_rules = self._get_filter(src_in_port)
        if existing_rules:
            logger.info(existing_rules)
            self._append_snmp_filter(existing_rules, dst_out_port, logger)
        else:
            rule_name_table = self._snmp_handler.get_table(
                "NETOPTICS-XFAM-FILTER-MIB", "filterRuleName")
            index = self._incr_ctag()
            while index in rule_name_table.keys():
                index = self._incr_ctag()

            self._set_snmp_filter(src_in_port, dst_out_port, index)

    def _append_snmp_filter(self, existing_rules, dst_out_port, logger):
        for index in existing_rules:
            dst_port = self._snmp_handler.get_property(
                "NETOPTICS-XFAM-FILTER-MIB", "filterRuleRedirPorts", index)
            if dst_port:
                dst_out_port = "{0},{1}".format(dst_port, dst_out_port)
                logger.info(dst_out_port)
            try:
                self._snmp_handler.set([(("NETOPTICS-XFAM-FILTER-MIB",
                                          "filterRuleRedirPorts", index),
                                         dst_out_port)])
            except PySnmpError as e:
                logger.error(e.args)
            if dst_out_port not in self._snmp_handler.get_property(
                    "NETOPTICS-XFAM-FILTER-MIB", "filterRuleRedirPorts",
                    index):
                raise Exception(self.__class__.__name__,
                                "Failed to append filter rule")

    def _set_snmp_filter(self, src_in_port, dst_out_port, index):
        try:
            self._snmp_handler.set([
                (("NETOPTICS-XFAM-FILTER-MIB", "filterRuleAction", index), 1),
                (("NETOPTICS-XFAM-FILTER-MIB", "filterRuleName", index),
                 "{0} to {1}".format(src_in_port, dst_out_port)),
                (("NETOPTICS-XFAM-FILTER-MIB", "filterRuleInPorts", index),
                 src_in_port),
                (("NETOPTICS-XFAM-FILTER-MIB", "filterRuleRedirPorts", index),
                 dst_out_port),
                (("NETOPTICS-XFAM-FILTER-MIB", "filterRuleEnabled", index), 1),
                (("NETOPTICS-XFAM-FILTER-MIB", "filterRuleRowstatus", index),
                 4)
            ])
        except PySnmpError:
            if not self._snmp_handler.get_property("NETOPTICS-XFAM-FILTER-MIB",
                                                   "filterRuleName", index):
                raise

    def map_clear_to(self, src_port_path, src_port_paths, command_logger=None):
        self.map_clear(src_port_path, src_port_paths, command_logger, uni=True)

    def map_clear(self, src_port, dst_port, command_logger=None, uni=False):
        if self._service_mode.lower() == "ssh":
            pass
        elif self._service_mode.lower() == "snmp":
            src_in_port = src_port[-1]
            for index in self._get_filter(src_in_port):
                self._remove_filter(index)

    def _get_filter(self, src_port):
        result = []
        rule_name_table = self._snmp_handler.get_table(
            "NETOPTICS-XFAM-FILTER-MIB", "filterRuleInPorts")
        for index, value in rule_name_table.iteritems():
            filter_port = value.get("filterRuleInPorts")
            if filter_port and int(src_port) == int(filter_port):
                result.append(index)
        return result

    def _remove_filter(self, index):
        self._snmp_handler.set([(("NETOPTICS-XFAM-FILTER-MIB",
                                  "filterRuleRowstatus", index), 6)])

    def set_speed_manual(self, command_logger=None):
        pass
    def get_resource_description(self, address, command_logger=None):
        autoload_helper = IxiaXstreamAutoloadHelper(command_logger)
        if self._service_mode.lower() == "ssh":
            device_data = autoload_helper.get_ssh_device_structure(
                self._session)
        elif self._service_mode.lower() == "snmp":
            snmp_handler = self.__get_snmp_handler(address, command_logger)
            device_data = autoload_helper.get_snmp_device_structure(
                snmp_handler)
        else:
            if not self._service_mode.lower():
                raise Exception(self.__class__.__name__,
                                "Service mode is empty")
            raise Exception(
                self.__class__.__name__,
                "Service mode {0} is not supported".format(
                    self._service_mode.lower()))

        address_prefix = address + "/"
        self._resource_info = ResourceInfo()
        self._resource_info.set_depth(0)
        self._resource_info.set_index(1)

        self._resource_info.set_address(address)
        self._resource_info.add_attribute("Vendor", device_data["vendor"])
        self._resource_info.add_attribute("Type", device_data["type"])
        self._resource_info.add_attribute("Version", device_data["version"])
        self._resource_info.add_attribute("Model", device_data["model"])
        model_name = device_data["model"]
        self._resource_info.set_model_name(model_name)
        self._resource_info.set_serial_number(device_data["serial"])

        # if self._port_logical_mode.lower() == "logical":
        for port_id, port_data in device_data["ports"].iteritems():
            port_resource_info = ResourceInfo()
            port_resource_info.set_depth(1)
            port_resource_info.set_index(port_id)
            port_resource_info.set_model_name(model_name)
            mapped_to = port_data.get("mapped_to")
            if mapped_to:
                port_resource_info.set_mapping(address_prefix + mapped_to)
            port_resource_info.add_attribute("State", port_data['state'])
            port_resource_info.add_attribute("Protocol Type", 0)
            self._resource_info.add_child(port_id, port_resource_info)
        return self._resource_info.convert_to_xml()
示例#13
0
    def get_resource_description(self, address, command_logger=None):
        """Auto-load function to retrieve all information from the device
        :param address: (str) address attribute from the CloudShell portal
        :param command_logger: logging.Logger instance
        :return: xml.etree.ElementTree.Element instance with all switch sub-resources (blades, ports)
        """
        #Validate properIP address
        if ":" not in address:
            self._logger.error('Invalid address entry found. Address found: ' +
                               address)
            raise Exception(
                'Invalid address found. Please check IP and matrix letter. Format: [IP]:[Matrix Letter]'
            )

        self._logger = command_logger
        self._create_connection()

        # Step 1. Create root element (switch):
        depth = 0
        # switch_Family = ConfigurationParser.get("driver_variable", "switch_family")
        switch_Model = ConfigurationParser.get("driver_variable",
                                               "switch_model")

        # blade_Family = ConfigurationParser.get("driver_variable", "blade_family")
        blade_Model = "Unit"

        # port_Family = ConfigurationParser.get("driver_variable", "port_family")
        port_Model = ConfigurationParser.get("driver_variable", "port_model")

        self._logger.info('switch: %s' % (str(switch_Model)))
        self._logger.info('Patch Panel: %s' % (str(blade_Model)))
        self._logger.info('port: %s' % (str(port_Model)))

        resource_info = ResourceInfo()
        resource_info.set_depth(depth)
        resource_info.set_address(address)
        resource_info.set_index("Rome")
        resource_info.add_attribute("Software Version", "1.0.0")
        resource_info.set_model_name(switch_Model)

        letter = ""

        self._connection.write('cc' + "\n!@#$")
        self._connection.read_until('cc')
        message = self._connection.expect(['!@#$'], 1)
        self._connection.write('\b\b\b\b\b\b\b')
        self._logger.info('cc output:\r\n' + message[2])
        lines = message[2].split('\r\n')
        mappings = {}
        if len(lines) > 4:
            for line in lines[4:-2]:
                values = re.match('^E(\d+)?.*?W(\d+)?.*', line).groups()
                mappings[values[1]] = values[0]

        #parse the string and only take the right side of the address
        parsed_string = address.split(":")
        try:
            #If true place remove white space and look for a single letter notation.
            matrix_letter = parsed_string[1].lower()
            string = matrix_letter
            matrix_letter = matrix_letter.replace(" ", "")
        except IndexError:
            self._logger.error(
                'Resource address should specify MatrixA or MatrixB. Current address: '
                + address)
            raise Exception(
                'Resource address should specify MatrixA or MatrixB. Format [IP]:[Matrix Letter].'
            )
        self._logger.info("Matrix Letter is: " + matrix_letter)

        # Validating the matrix address a/b
        pattern = re.compile(r"(?i)(matrix)?(.+)?(A|B)")
        mat = pattern.match(string)
        f = ['a', 'a ', 'b', 'b ', 'm']
        valid = False

        #Check for validity of format
        if mat:
            self.g3 = mat.group(3)
            self.g2 = mat.group(2)
            self.g1 = mat.group(1)
            if self.g3 == 'a' or self.g3 == 'b':
                if self.g2 not in f:
                    valid = True
        if not valid:
            if self.g3 != 'a' or self.g3 != 'b':
                self._logger.error(
                    'Resource address should specify MatrixA or MatrixB. Current address: '
                    + address)
                raise Exception(
                    'Resource address should specify MatrixA or MatrixB')

            if self.g2 in f:
                self._logger.error('Multiple matrix letters found')
                raise Exception(
                    'Resource address should only contain one matrix letter. Either A or B'
                )

        if self.g3 == 'a':
            letter = "A"
        elif self.g3 == 'b':
            letter = "B"
        else:
            self._logger.error(
                'Resource address should specify MatrixA or MatrixB. Current address: '
                + address)
            raise Exception(
                'Resource address should specify MatrixA or MatrixB')

        #Step 2. Create child resources for the root element (blades):
        for blade_no in range(1, 2):
            blade_resource = ResourceInfo()
            blade_resource.set_depth(depth + 1)
            blade_resource.set_index(str(blade_no))
            blade_resource.set_model_name(blade_Model)
            blade_resource.set_address(address + ":" + ("Matrix%s" % letter))
            resource_info.add_child(blade_no, blade_resource)

            # Step 3. Create child resources for each root sub-resource (ports in blades)
            if letter is "A":
                for port_no in range(1, 129):
                    port_resource = ResourceInfo()
                    port_resource.set_depth(depth + 2)
                    port_resource.set_index(str(port_no).zfill(3))
                    port_resource.set_model_name(port_Model)
                    if str(port_no) in mappings:
                        mapped_to = mappings[str(port_no)]
                        self._logger.info('found mapping for port ' +
                                          str(port_no) + ', mapped to: ' +
                                          mapped_to)
                        port_resource.set_mapping(address + '/1/' +
                                                  mapped_to.zfill(3))
                    blade_resource.add_child(port_no, port_resource)
            elif letter is "B":
                for port_no in range(129, 257):
                    port_resource = ResourceInfo()
                    port_resource.set_depth(depth + 2)
                    port_resource.set_index(str(port_no).zfill(3))
                    port_resource.set_model_name(port_Model)
                    if str(port_no) in mappings:
                        mapped_to = mappings[str(port_no)]
                        self._logger.info('found mapping for port ' +
                                          str(port_no) + ', mapped to: ' +
                                          mapped_to)
                        port_resource.set_mapping(address + '/1/' +
                                                  mapped_to.zfill(3))
                    blade_resource.add_child(port_no, port_resource)

        self._close_connection()
        return resource_info.convert_to_xml()