def compute_path(self, always_same_link=True): """Compute path for added nodes. .. note:: First add at least two nodes to the topology. :param always_same_link: If True use always same link between two nodes in path. If False use different link (if available) between two nodes if one link was used before. :type always_same_link: bool :raises RuntimeError: If not enough nodes for path. """ nodes = self._nodes if len(nodes) < 2: raise RuntimeError(u"Not enough nodes to compute path") for idx in range(0, len(nodes) - 1): topo = Topology() node1 = nodes[idx] node2 = nodes[idx + 1] n1_list = self._nodes_filter[idx] n2_list = self._nodes_filter[idx + 1] links = topo.get_active_connecting_links(node1, node2, filter_list_node1=n1_list, filter_list_node2=n2_list) if not links: raise RuntimeError( f"No link between {node1[u'host']} and {node2[u'host']}") # Not using set operations, as we need deterministic order. if always_same_link: l_set = [link for link in links if link in self._links] else: l_set = [link for link in links if link not in self._links] if not l_set: raise RuntimeError( f"No free link between {node1[u'host']} and " f"{node2[u'host']}, all links already used") if not l_set: link = links[0] else: link = l_set[0] self._links.append(link) interface1 = topo.get_interface_by_link_name(node1, link) interface2 = topo.get_interface_by_link_name(node2, link) self._path.append((interface1, node1)) self._path.append((interface2, node2)) self._path_iter.extend(self._path) self._path_iter.reverse()
def compute_path(self, always_same_link=True): """Compute path for added nodes. .. note:: First add at least two nodes to the topology. :param always_same_link: If True use always same link between two nodes in path. If False use different link (if available) between two nodes if one link was used before. :type always_same_link: bool :raises RuntimeError: If not enough nodes for path. """ nodes = self._nodes if len(nodes) < 2: raise RuntimeError('Not enough nodes to compute path') for idx in range(0, len(nodes) - 1): topo = Topology() node1 = nodes[idx] node2 = nodes[idx + 1] n1_list = self._nodes_filter[idx] n2_list = self._nodes_filter[idx + 1] links = topo.get_active_connecting_links(node1, node2, filter_list_node1=n1_list, filter_list_node2=n2_list) if not links: raise RuntimeError('No link between {0} and {1}'.format( node1['host'], node2['host'])) if always_same_link: l_set = set(links).intersection(self._links) else: l_set = set(links).difference(self._links) if not l_set: raise RuntimeError( 'No free link between {0} and {1}, all links already ' 'used'.format(node1['host'], node2['host'])) if not l_set: link = links.pop() else: link = l_set.pop() self._links.append(link) interface1 = topo.get_interface_by_link_name(node1, link) interface2 = topo.get_interface_by_link_name(node2, link) self._path.append((interface1, node1)) self._path.append((interface2, node2)) self._path_iter.extend(self._path) self._path_iter.reverse()
def get_variables(nodes, networks=IPV4_NETWORKS[:]): """Special robot framework method that returns dictionary nodes_ipv4_addr, mapping of node and interface name to IPv4 address. :param nodes: Nodes of the test topology. :param networks: List of available IPv4 networks. :type nodes: dict :type networks: list .. note:: Robot framework calls it automatically. """ topo = Topology() links = topo.get_links(nodes) if len(links) > len(networks): raise Exception('Not enough available IPv4 networks for topology.') ip4_n = IPv4NetworkGenerator(networks) nets = {} for link in links: ip4_net = ip4_n.next_network() net_hosts = ip4_net.hosts() port_idx = 0 ports = {} for node in nodes.values(): if_key = topo.get_interface_by_link_name(node, link) if_name = topo.get_interface_name(node, if_key) if if_name is not None: port = { 'addr': str(next(net_hosts)), 'node': node['host'], 'if': if_name } port_idx += 1 port_id = 'port{0}'.format(port_idx) ports.update({port_id: port}) nets.update({ link: { 'net_addr': str(ip4_net.network_address), 'prefix': ip4_net.prefixlen, 'ports': ports } }) return {'DICT__nodes_ipv4_addr': nets}
def generate_duplicate_lisp_locator_set_data(node, locator_set_number): """Generate a list of lisp locator_set we want set to VPP and then check if it is set correctly. Some locator_sets are duplicated. :param node: VPP node. :param locator_set_number: Generate n locator_set. :type node: dict :type locator_set_number: str :returns: list of lisp locator_set, list of lisp locator_set expected from VAT. :rtype: tuple """ topo = Topology() locator_set_list = [] locator_set_list_vat = [] i = 0 for num in range(0, int(locator_set_number)): locator_list = [] for interface in node['interfaces'].values(): link = interface.get('link') i += 1 if link is None: continue if_name = topo.get_interface_by_link_name(node, link) sw_if_index = topo.get_interface_sw_index(node, if_name) if if_name is not None: l_name = 'ls{0}'.format(num) locator = { 'locator-index': sw_if_index, 'priority': i, 'weight': i } locator_list.append(locator) locator_set = { 'locator-set': l_name, 'locator': locator_list } locator_set_list.append(locator_set) locator_set_vat = {"ls_name": l_name, "ls_index": num} locator_set_list_vat.append(locator_set_vat) return locator_set_list, locator_set_list_vat