X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=nfvbench%2Fchaining.py;h=ee8a8e0a4ab658a062410ff8ea24b461ee53c852;hb=e7fdfb5c5e386bb8851b6c583c44ae61bd188627;hp=22f000bfb6b07eb74895cbf3e5a9d1dc6d3a0231;hpb=e3d806ce064bade2ad168c9df03e3cc2ee396cff;p=nfvbench.git diff --git a/nfvbench/chaining.py b/nfvbench/chaining.py index 22f000b..ee8a8e0 100644 --- a/nfvbench/chaining.py +++ b/nfvbench/chaining.py @@ -197,17 +197,24 @@ class ChainNetwork(object): """Create a network for given chain. network_config: a dict containing the network properties - (segmentation_id and physical_network) + (name, segmentation_id and physical_network) chain_id: to which chain the networks belong. a None value will mean that these networks are shared by all chains """ self.manager = manager - self.name = network_config.name + if chain_id is None: + self.name = network_config.name + else: + # the name itself can be either a string or a list of names indexed by chain ID + if isinstance(network_config.name, tuple): + self.name = network_config.name[chain_id] + else: + # network_config.name is a prefix string + self.name = network_config.name + str(chain_id) self.segmentation_id = self._get_item(network_config.segmentation_id, chain_id, auto_index=True) self.physical_network = self._get_item(network_config.physical_network, chain_id) - if chain_id is not None: - self.name += str(chain_id) + self.reuse = False self.network = None self.vlan = None @@ -876,6 +883,12 @@ class ChainManager(object): self.flavor = ChainFlavor(config.flavor_type, config.flavor, self.comp) # Get list of all existing instances to check if some instances can be reused self.existing_instances = self.comp.get_server_list() + else: + # For EXT chains, the external_networks left and right fields in the config + # must be either a prefix string or a list of at least chain-count strings + self._check_extnet('left', config.external_networks.left) + self._check_extnet('right', config.external_networks.right) + # If networks are shared across chains, get the list of networks if config.service_chain_shared_net: self.networks = self.get_networks() @@ -883,8 +896,8 @@ class ChainManager(object): for chain_id in range(self.chain_count): self.chains.append(Chain(chain_id, self)) if config.service_chain == ChainType.EXT: - # if EXT and no ARP we need to read dest MACs from config - if config.no_arp: + # if EXT and no ARP or VxLAN we need to read dest MACs from config + if config.no_arp or config.vxlan: self._get_dest_macs_from_config() else: # Make sure all instances are active before proceeding @@ -908,6 +921,14 @@ class ChainManager(object): if config.vxlan: raise ChainException('VxLAN is only supported with OpenStack') + def _check_extnet(self, side, name): + if not name: + raise ChainException('external_networks.%s must contain a valid network' + ' name prefix or a list of network names' % side) + if isinstance(name, tuple) and len(name) < self.chain_count: + raise ChainException('external_networks.%s %s' + ' must have at least %d names' % (side, name, self.chain_count)) + def _get_config_vlans(self): re_vlan = "[0-9]*$" try: @@ -1111,11 +1132,11 @@ class ChainManager(object): """ return self.get_existing_ports().get(chain_network.get_uuid(), None) - def get_host_ip_from_mac(self, mac): - """Get the host IP address matching a MAC. + def get_hypervisor_from_mac(self, mac): + """Get the hypervisor that hosts a VM MAC. mac: MAC address to look for - return: the IP address of the host where the matching port runs or None if not found + return: the hypervisor where the matching port runs or None if not found """ # _existing_ports is a dict of list of ports indexed by network id for port_list in self.get_existing_ports().values(): @@ -1123,11 +1144,22 @@ class ChainManager(object): try: if port['mac_address'] == mac: host_id = port['binding:host_id'] - return self.comp.get_hypervisor(host_id).host_ip + return self.comp.get_hypervisor(host_id) except KeyError: pass return None + def get_host_ip_from_mac(self, mac): + """Get the host IP address matching a MAC. + + mac: MAC address to look for + return: the IP address of the host where the matching port runs or None if not found + """ + hypervisor = self.get_hypervisor_from_mac(mac) + if hypervisor: + return hypervisor.host_ip + return None + def get_chain_vlans(self, port_index): """Get the list of per chain VLAN id on a given port. @@ -1146,11 +1178,11 @@ class ChainManager(object): port_index: left port is 0, right port is 1 return: a VNIs ID list indexed by the chain index or None if no vlan tagging """ - if self.chains: + if self.chains and self.is_admin: return [self.chains[chain_index].get_vxlan(port_index) for chain_index in range(self.chain_count)] # no openstack - raise ChainException('VxLAN is only supported with OpenStack') + raise ChainException('VxLAN is only supported with OpenStack and with admin user') def get_dest_macs(self, port_index): """Get the list of per chain dest MACs on a given port. @@ -1198,7 +1230,18 @@ class ChainManager(object): if self.chains: # in the case of EXT, the compute node must be retrieved from the port # associated to any of the dest MACs - return self.chains[0].get_compute_nodes() + if self.config.service_chain != ChainType.EXT: + return self.chains[0].get_compute_nodes() + # in the case of EXT, the compute node must be retrieved from the port + # associated to any of the dest MACs + dst_macs = self.generator_config.get_dest_macs() + # dest MAC on port 0, chain 0 + dst_mac = dst_macs[0][0] + hypervisor = self.get_hypervisor_from_mac(dst_mac) + if hypervisor: + LOG.info('Found hypervisor for EXT chain: %s', hypervisor.hypervisor_hostname) + return[':' + hypervisor.hypervisor_hostname] + # no openstack = no chains return []