Пример #1
0
def find_graph(hostnames):
    filename = os.path.join(LAB_GRAPHFILE_PATH, LAB_CONNECTION_GRAPH_FILE)
    with open(filename) as fd:
        file_list = yaml.safe_load(fd)

    # Finding the graph file contains all duts from hostnames,
    for fn in file_list:
        print_debug_msg(
            debug_fname,
            "Looking at conn graph file: %s for hosts %s" % (fn, hostnames))
        filename = os.path.join(LAB_GRAPHFILE_PATH, fn)
        lab_graph = Parse_Lab_Graph(filename)
        lab_graph.parse_graph()
        if lab_graph.contains_hosts(hostnames):
            print_debug_msg(
                debug_fname,
                ("Returning lab graph from conn graph file: %s for hosts %s" %
                 (fn, hostnames)))
            return lab_graph

    # Fallback to return an empty connection graph, this is
    # needed to bridge the kvm test needs. The KVM test needs
    # A graph file, which used to be whatever hardcoded file.
    # Here we provide one empty file for the purpose.
    lab_graph = Parse_Lab_Graph(
        os.path.join(LAB_GRAPHFILE_PATH, EMPTY_GRAPH_FILE))
    lab_graph.parse_graph()
    return lab_graph
Пример #2
0
def find_graph(hostnames, part=False):
    """
    Find a graph file contains all devices in testbed.
    duts are spcified by hostnames

    Parameters:
        hostnames: list of duts in the target testbed.
        part: select the graph file if over 80% of hosts are found in conn_graph when part is True
    """
    global debug_fname
    filename = os.path.join(LAB_GRAPHFILE_PATH, LAB_CONNECTION_GRAPH_FILE)
    with open(filename) as fd:
        file_list = yaml.safe_load(fd)

    # Finding the graph file contains all duts from hostnames,
    for fn in file_list:
        print_debug_msg(
            debug_fname,
            "Looking at conn graph file: %s for hosts %s" % (fn, hostnames))
        filename = os.path.join(LAB_GRAPHFILE_PATH, fn)
        lab_graph = Parse_Lab_Graph(filename)
        lab_graph.parse_graph()
        print_debug_msg(
            debug_fname,
            "For file %s, got hostnames %s" % (fn, lab_graph.devices))
        if lab_graph.contains_hosts(hostnames, part):
            print_debug_msg(
                debug_fname,
                ("Returning lab graph from conn graph file: %s for hosts %s" %
                 (fn, hostnames)))
            return lab_graph
    # Fallback to return an empty connection graph, this is
    # needed to bridge the kvm test needs. The KVM test needs
    # A graph file, which used to be whatever hardcoded file.
    # Here we provide one empty file for the purpose.
    lab_graph = Parse_Lab_Graph(
        os.path.join(LAB_GRAPHFILE_PATH, EMPTY_GRAPH_FILE))
    lab_graph.parse_graph()
    return lab_graph
Пример #3
0
def main():
    module = AnsibleModule(argument_spec=dict(
        host=dict(required=False),
        hosts=dict(required=False, type='list'),
        filename=dict(required=False),
        filepath=dict(required=False),
        anchor=dict(required=False, type='list'),
    ),
                           mutually_exclusive=[['host', 'hosts', 'anchor']],
                           supports_check_mode=True)
    m_args = module.params
    global debug_fname
    debug_fname = create_debug_file("/tmp/conn_graph_debug.txt")

    anchor = m_args['anchor']
    if m_args['hosts']:
        hostnames = m_args['hosts']
    elif m_args['host']:
        hostnames = [m_args['host']]
    else:
        # return the whole graph
        hostnames = []
    try:
        # When called by pytest, the file path is obscured to /tmp/.../.
        # we need the caller to tell us where the graph files are with
        # filepath argument.
        if m_args['filepath']:
            global LAB_GRAPHFILE_PATH
            LAB_GRAPHFILE_PATH = m_args['filepath']

        if m_args['filename']:
            filename = os.path.join(LAB_GRAPHFILE_PATH, m_args['filename'])
            lab_graph = Parse_Lab_Graph(filename)
            lab_graph.parse_graph()
        else:
            # When calling passed in anchor instead of hostnames,
            # the caller is asking to return the whole graph. This
            # is needed when configuring the root fanout switch.
            target = anchor if anchor else hostnames
            lab_graph = find_graph(target)

        # early return for the whole graph or empty graph file(vtestbed)
        if (not hostnames or not lab_graph.devices and not lab_graph.links
                and not lab_graph.vlanport):
            results = {
                'device_info': lab_graph.devices,
                'device_conn': lab_graph.links,
                'device_port_vlans': lab_graph.vlanport,
            }
            module.exit_json(ansible_facts=results)

        device_info = {}
        device_conn = {}
        device_port_vlans = {}
        device_vlan_range = {}
        device_vlan_list = {}
        device_vlan_map_list = {}
        device_console_info = {}
        device_console_link = {}
        device_pdu_info = {}
        device_pdu_links = {}
        for hostname in hostnames:
            dev = lab_graph.get_host_device_info(hostname)
            if dev is None:
                module.fail_json(msg="cannot find info for %s" % hostname)
            device_info[hostname] = dev
            device_conn[hostname] = lab_graph.get_host_connections(hostname)
            host_vlan = lab_graph.get_host_vlan(hostname)
            port_vlans = lab_graph.get_host_port_vlans(hostname)
            # for multi-DUTs, must ensure all have vlan configured.
            if host_vlan:
                device_vlan_range[hostname] = host_vlan["VlanRange"]
                device_vlan_list[hostname] = host_vlan["VlanList"]
                if dev["Type"].lower() != "devsonic":
                    device_vlan_map_list[hostname] = host_vlan["VlanList"]
                else:
                    device_vlan_map_list[hostname] = {}

                    port_name_list_sorted = get_port_name_list(dev['HwSku'])
                    print_debug_msg(
                        debug_fname,
                        "For %s with hwsku %s, port_name_list is %s" %
                        (hostname, dev['HwSku'], port_name_list_sorted))
                    for a_host_vlan in host_vlan["VlanList"]:
                        # Get the corresponding port for this vlan from the port vlan list for this hostname
                        found_port_for_vlan = False
                        for a_port in port_vlans:
                            if a_host_vlan in port_vlans[a_port]['vlanlist']:
                                if a_port in port_name_list_sorted:
                                    port_index = port_name_list_sorted.index(
                                        a_port)
                                    device_vlan_map_list[hostname][
                                        port_index] = a_host_vlan
                                    found_port_for_vlan = True
                                    break
                                else:
                                    module.fail_json(
                                        msg=
                                        "Did not find port for %s in the ports based on hwsku '%s' for host %s"
                                        % (a_port, dev['HwSku'], hostname))
                        if not found_port_for_vlan:
                            module.fail_json(
                                msg=
                                "Did not find corresponding link for vlan %d in %s for host %s"
                                % (a_host_vlan, port_vlans, hostname))
            device_port_vlans[hostname] = port_vlans
            device_console_info[hostname] = lab_graph.get_host_console_info(
                hostname)
            device_console_link[hostname] = lab_graph.get_host_console_link(
                hostname)
            device_pdu_info[hostname] = lab_graph.get_host_pdu_info(hostname)
            device_pdu_links[hostname] = lab_graph.get_host_pdu_links(hostname)
        results = {
            k: v
            for k, v in locals().items() if (k.startswith("device_") and v)
        }

        module.exit_json(ansible_facts=results)
    except (IOError, OSError):
        module.fail_json(msg="Can not find lab graph file under {}".format(
            LAB_GRAPHFILE_PATH))
    except Exception as e:
        module.fail_json(msg=traceback.format_exc())
Пример #4
0
    def parse_graph(self):
        """
        Parse  the xml graph file
        """
        deviceinfo = {}
        deviceroot = self.root.find(self.pngtag).find('Devices')
        devices = deviceroot.findall('Device')
        if devices is not None:
            for dev in devices:
                hostname = dev.attrib['Hostname']
                if hostname is not None:
                    deviceinfo[hostname] = {}
                    hwsku = dev.attrib['HwSku']
                    devtype = dev.attrib['Type']
                    deviceinfo[hostname]['HwSku'] = hwsku
                    deviceinfo[hostname]['Type'] = devtype
                    self.links[hostname] = {}
        devicel2info = {}
        devicel3s = self.root.find(self.dpgtag).findall('DevicesL3Info')
        devicel2s = self.root.find(self.dpgtag).findall('DevicesL2Info')
        if devicel2s is not None:
            for l2info in devicel2s:
                hostname = l2info.attrib['Hostname']
                if hostname is not None:
                    devicel2info[hostname] = {}
                    vlans = l2info.findall('InterfaceVlan')
                    for vlan in vlans:
                        portname = vlan.attrib['portname']
                        portmode = vlan.attrib['mode']
                        portvlanid = vlan.attrib['vlanids']
                        portvlanlist = self.port_vlanlist(portvlanid)
                        devicel2info[hostname][portname] = {
                            'mode': portmode,
                            'vlanids': portvlanid,
                            'vlanlist': portvlanlist
                        }
        if devicel3s is not None:
            for l3info in devicel3s:
                hostname = l3info.attrib['Hostname']
                if hostname is not None:
                    management_ip = l3info.find(
                        'ManagementIPInterface').attrib['Prefix']
                    deviceinfo[hostname]['ManagementIp'] = management_ip
                    mgmtip = ipaddress.IPNetwork(management_ip)
                    deviceinfo[hostname]['mgmtip'] = str(mgmtip.ip)
                    management_gw = str(mgmtip.network + 1)
                    deviceinfo[hostname]['ManagementGw'] = management_gw
        allinks = self.root.find(self.pngtag).find(
            'DeviceInterfaceLinks').findall('DeviceInterfaceLink')
        if allinks is not None:
            for link in allinks:
                start_dev = link.attrib['StartDevice']
                end_dev = link.attrib['EndDevice']
                if start_dev:
                    self.links[start_dev][link.attrib['StartPort']] = {
                        'peerdevice': link.attrib['EndDevice'],
                        'peerport': link.attrib['EndPort'],
                        'speed': link.attrib['BandWidth']
                    }
                if end_dev:
                    self.links[end_dev][link.attrib['EndPort']] = {
                        'peerdevice': link.attrib['StartDevice'],
                        'peerport': link.attrib['StartPort'],
                        'speed': link.attrib['BandWidth']
                    }
        console_root = self.root.find(self.csgtag)
        if console_root:
            devicecsgroot = console_root.find('DevicesConsoleInfo')
            devicescsg = devicecsgroot.findall('DeviceConsoleInfo')
            if devicescsg is not None:
                for dev in devicescsg:
                    hostname = dev.attrib['Hostname']
                    if hostname is not None:
                        deviceinfo[hostname] = {}
                        hwsku = dev.attrib['HwSku']
                        devtype = dev.attrib['Type']
                        protocol = dev.attrib['Protocol']
                        mgmt_ip = dev.attrib['ManagementIp']
                        deviceinfo[hostname]['HwSku'] = hwsku
                        deviceinfo[hostname]['Type'] = devtype
                        deviceinfo[hostname]['Protocol'] = protocol
                        deviceinfo[hostname]['ManagementIp'] = mgmt_ip
                        self.consolelinks[hostname] = {}
            console_link_root = console_root.find('ConsoleLinksInfo')
            if console_link_root:
                allconsolelinks = console_link_root.findall('ConsoleLinkInfo')
                if allconsolelinks is not None:
                    for consolelink in allconsolelinks:
                        start_dev = consolelink.attrib['StartDevice']
                        end_dev = consolelink.attrib['EndDevice']
                        if start_dev:
                            if start_dev not in self.consolelinks:
                                self.consolelinks.update({start_dev: {}})
                            self.consolelinks[start_dev][
                                consolelink.attrib['StartPort']] = {
                                    'peerdevice':
                                    consolelink.attrib['EndDevice'],
                                    'peerport': 'ConsolePort'
                                }
                        if end_dev:
                            if end_dev not in self.consolelinks:
                                self.consolelinks.update({end_dev: {}})
                            self.consolelinks[end_dev]['ConsolePort'] = {
                                'peerdevice':
                                consolelink.attrib['StartDevice'],
                                'peerport': consolelink.attrib['StartPort']
                            }

        pdu_root = self.root.find(self.pcgtag)
        if pdu_root:
            devicepcgroot = pdu_root.find('DevicesPowerControlInfo')
            devicespcsg = devicepcgroot.findall('DevicePowerControlInfo')
            if devicespcsg is not None:
                for dev in devicespcsg:
                    hostname = dev.attrib['Hostname']
                    if hostname is not None:
                        deviceinfo[hostname] = {}
                        hwsku = dev.attrib['HwSku']
                        devtype = dev.attrib['Type']
                        protocol = dev.attrib['Protocol']
                        mgmt_ip = dev.attrib['ManagementIp']
                        deviceinfo[hostname]['HwSku'] = hwsku
                        deviceinfo[hostname]['Type'] = devtype
                        deviceinfo[hostname]['Protocol'] = protocol
                        deviceinfo[hostname]['ManagementIp'] = mgmt_ip
                        self.pdulinks[hostname] = {}
            pdu_link_root = pdu_root.find('PowerControlLinksInfo')
            if pdu_link_root:
                allpdulinks = pdu_link_root.findall('PowerControlLinkInfo')
                if allpdulinks is not None:
                    for pdulink in allpdulinks:
                        start_dev = pdulink.attrib['StartDevice']
                        end_dev = pdulink.attrib['EndDevice']
                        print_debug_msg(debug_fname,
                                        "pdulink {}".format(pdulink.attrib))
                        print_debug_msg(
                            debug_fname,
                            "self.pdulinks {}".format(self.pdulinks))
                        if start_dev:
                            if start_dev not in self.pdulinks:
                                self.pdulinks.update({start_dev: {}})
                            self.pdulinks[start_dev][
                                pdulink.attrib['StartPort']] = {
                                    'peerdevice': pdulink.attrib['EndDevice'],
                                    'peerport': pdulink.attrib['EndPort']
                                }
                        if end_dev:
                            if end_dev not in self.pdulinks:
                                self.pdulinks.update({end_dev: {}})
                            self.pdulinks[end_dev][
                                pdulink.attrib['EndPort']] = {
                                    'peerdevice':
                                    pdulink.attrib['StartDevice'],
                                    'peerport': pdulink.attrib['StartPort']
                                }
        self.devices = deviceinfo
        self.vlanport = devicel2info
Пример #5
0
def build_results(lab_graph, hostnames, ignore_error=False):
    """
    Refactor code for building json results.
    Code is refactored because same logic is needed in devutil
    """
    device_info = {}
    device_conn = {}
    device_port_vlans = {}
    device_vlan_range = {}
    device_vlan_list = {}
    device_vlan_map_list = {}
    device_console_info = {}
    device_console_link = {}
    device_pdu_info = {}
    device_pdu_links = {}
    msg = {}
    for hostname in hostnames:
        dev = lab_graph.get_host_device_info(hostname)
        if dev is None and not ignore_error:
            msg = "cannot find info for %s" % hostname
            return (False, msg)
        device_info[hostname] = dev
        device_conn[hostname] = lab_graph.get_host_connections(hostname)
        host_vlan = lab_graph.get_host_vlan(hostname)
        port_vlans = lab_graph.get_host_port_vlans(hostname)
        # for multi-DUTs, must ensure all have vlan configured.
        if host_vlan:
            device_vlan_range[hostname] = host_vlan["VlanRange"]
            device_vlan_list[hostname] = host_vlan["VlanList"]
            if dev["Type"].lower() != "devsonic":
                device_vlan_map_list[hostname] = host_vlan["VlanList"]
            else:
                device_vlan_map_list[hostname] = {}

                port_name_list_sorted = get_port_name_list(dev['HwSku'])
                print_debug_msg(
                    debug_fname, "For %s with hwsku %s, port_name_list is %s" %
                    (hostname, dev['HwSku'], port_name_list_sorted))
                for a_host_vlan in host_vlan["VlanList"]:
                    # Get the corresponding port for this vlan from the port vlan list for this hostname
                    found_port_for_vlan = False
                    for a_port in port_vlans:
                        if a_host_vlan in port_vlans[a_port]['vlanlist']:
                            if a_port in port_name_list_sorted:
                                port_index = port_name_list_sorted.index(
                                    a_port)
                                device_vlan_map_list[hostname][
                                    port_index] = a_host_vlan
                                found_port_for_vlan = True
                                break
                            elif not ignore_error:
                                msg = "Did not find port for %s in the ports based on hwsku '%s' for host %s" % (
                                    a_port, dev['HwSku'], hostname)
                                return (False, msg)
                    if not found_port_for_vlan and not ignore_error:
                        msg = "Did not find corresponding link for vlan %d in %s for host %s" % (
                            a_host_vlan, port_vlans, hostname)
                        return (False, msg)
        device_port_vlans[hostname] = port_vlans
        device_console_info[hostname] = lab_graph.get_host_console_info(
            hostname)
        device_console_link[hostname] = lab_graph.get_host_console_link(
            hostname)
        device_pdu_info[hostname] = lab_graph.get_host_pdu_info(hostname)
        device_pdu_links[hostname] = lab_graph.get_host_pdu_links(hostname)
    results = {
        k: v
        for k, v in locals().items() if (k.startswith("device_") and v)
    }
    return (True, results)