X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=yardstick%2Fbenchmark%2Fcontexts%2Fheat.py;h=d5349eab580c361bae3a02456b80c56b15317c84;hb=deccb02a8adabe609c2e903ce9f60e8b39db6c29;hp=aa134d6941a31740a4e2aa2789d10f470fdb1f8c;hpb=653902770572c780777d1dc7a371794b670585b1;p=yardstick.git diff --git a/yardstick/benchmark/contexts/heat.py b/yardstick/benchmark/contexts/heat.py index aa134d694..d5349eab5 100644 --- a/yardstick/benchmark/contexts/heat.py +++ b/yardstick/benchmark/contexts/heat.py @@ -25,6 +25,7 @@ from yardstick.benchmark.contexts.model import Network from yardstick.benchmark.contexts.model import PlacementGroup, ServerGroup from yardstick.benchmark.contexts.model import Server from yardstick.benchmark.contexts.model import update_scheduler_hints +from yardstick.common.openstack_utils import get_neutron_client from yardstick.orchestrator.heat import HeatTemplate, get_short_key_uuid from yardstick.common.constants import YARDSTICK_ROOT_PATH @@ -54,9 +55,11 @@ class HeatContext(Context): self._user = None self.template_file = None self.heat_parameters = None + self.neutron_client = None # generate an uuid to identify yardstick_key # the first 8 digits of the uuid will be used self.key_uuid = uuid.uuid4() + self.heat_timeout = None self.key_filename = ''.join( [YARDSTICK_ROOT_PATH, 'yardstick/resources/files/yardstick_key-', get_short_key_uuid(self.key_uuid)]) @@ -65,15 +68,16 @@ class HeatContext(Context): def assign_external_network(self, networks): sorted_networks = sorted(networks.items()) external_network = os.environ.get("EXTERNAL_NETWORK", "net04_ext") - have_external_network = [(name, net) - for name, net in sorted_networks if - net.get("external_network")] - # no external net defined, assign it to first network usig os.environ + + have_external_network = any(net.get("external_network") for net in networks.values()) if sorted_networks and not have_external_network: + # no external net defined, assign it to first network using os.environ sorted_networks[0][1]["external_network"] = external_network - return sorted_networks - def init(self, attrs): # pragma: no cover + self.networks = OrderedDict((name, Network(name, self, attrs)) + for name, attrs in sorted_networks) + + def init(self, attrs): """initializes itself from the supplied arguments""" self.name = attrs["name"] @@ -103,11 +107,7 @@ class HeatContext(Context): # we have to do this first, because we are injecting external_network # into the dict - sorted_networks = self.assign_external_network(attrs["networks"]) - - self.networks = OrderedDict( - (name, Network(name, self, netattrs)) for name, netattrs in - sorted_networks) + self.assign_external_network(attrs["networks"]) for name, serverattrs in sorted(attrs["servers"].items()): server = Server(name, self, serverattrs) @@ -120,7 +120,6 @@ class HeatContext(Context): with open(self.key_filename + ".pub", "w") as pubkey_file: pubkey_file.write( "%s %s\n" % (rsa_key.get_name(), rsa_key.get_base64())) - del rsa_key @property def image(self): @@ -152,9 +151,13 @@ class HeatContext(Context): for network in self.networks.values(): template.add_network(network.stack_name, network.physical_network, - network.provider) + network.provider, + network.segmentation_id, + network.port_security_enabled) template.add_subnet(network.subnet_stack_name, network.stack_name, - network.subnet_cidr) + network.subnet_cidr, + network.enable_dhcp, + network.gateway_ip) if network.router: template.add_router(network.router.stack_name, @@ -193,7 +196,7 @@ class HeatContext(Context): scheduler_hints = {} for pg in server.placement_groups: update_scheduler_hints(scheduler_hints, added_servers, pg) - # workround for openstack nova bug, check JIRA: YARDSTICK-200 + # workaround for openstack nova bug, check JIRA: YARDSTICK-200 # for details if len(availability_servers) == 2: if not scheduler_hints["different_host"]: @@ -249,6 +252,20 @@ class HeatContext(Context): list(self.networks.values()), scheduler_hints) + def get_neutron_info(self): + if not self.neutron_client: + self.neutron_client = get_neutron_client() + + networks = self.neutron_client.list_networks() + for network in self.networks.values(): + for neutron_net in networks['networks']: + if neutron_net['name'] == network.stack_name: + network.segmentation_id = neutron_net.get('provider:segmentation_id') + # we already have physical_network + # network.physical_network = neutron_net.get('provider:physical_network') + network.network_type = neutron_net.get('provider:network_type') + network.neutron_info = neutron_net + def deploy(self): """deploys template into a stack using cloud""" print("Deploying context '%s'" % self.name) @@ -266,20 +283,16 @@ class HeatContext(Context): raise SystemExit("\nStack create interrupted") except: LOG.exception("stack failed") + # let the other failures happen, we want stack trace raise - # let the other failures happend, we want stack trace + + # TODO: use Neutron to get segementation-id + self.get_neutron_info() # copy some vital stack output into server objects for server in self.servers: if server.ports: - # TODO(hafe) can only handle one internal network for now - port = next(iter(server.ports.values())) - server.private_ip = self.stack.outputs[port["stack_name"]] - server.interfaces = {} - for network_name, port in server.ports.items(): - self.make_interface_dict(network_name, port['stack_name'], - server, - self.stack.outputs) + self.add_server_port(server) if server.floating_ip: server.public_ip = \ @@ -287,24 +300,36 @@ class HeatContext(Context): print("Context '%s' deployed" % self.name) - def make_interface_dict(self, network_name, stack_name, server, outputs): - server.interfaces[network_name] = { - "private_ip": outputs[stack_name], + def add_server_port(self, server): + # TODO(hafe) can only handle one internal network for now + port = next(iter(server.ports.values())) + server.private_ip = self.stack.outputs[port["stack_name"]] + server.interfaces = {} + for network_name, port in server.ports.items(): + server.interfaces[network_name] = self.make_interface_dict( + network_name, port['stack_name'], self.stack.outputs) + + def make_interface_dict(self, network_name, stack_name, outputs): + private_ip = outputs[stack_name] + mac_addr = outputs[stack_name + "-mac_address"] + subnet_cidr_key = "-".join([self.name, network_name, 'subnet', 'cidr']) + gateway_key = "-".join([self.name, network_name, 'subnet', 'gateway_ip']) + subnet_cidr = outputs[subnet_cidr_key] + subnet_ip = ipaddress.ip_network(subnet_cidr) + return { + "private_ip": private_ip, "subnet_id": outputs[stack_name + "-subnet_id"], - "subnet_cidr": outputs[ - "{}-{}-subnet-cidr".format(self.name, network_name)], - "netmask": str(ipaddress.ip_network( - outputs["{}-{}-subnet-cidr".format(self.name, - network_name)]).netmask), - "gateway_ip": outputs[ - "{}-{}-subnet-gateway_ip".format(self.name, network_name)], - "mac_address": outputs[stack_name + "-mac_address"], + "subnet_cidr": subnet_cidr, + "network": str(subnet_ip.network_address), + "netmask": str(subnet_ip.netmask), + "gateway_ip": outputs[gateway_key], + "mac_address": mac_addr, "device_id": outputs[stack_name + "-device_id"], "network_id": outputs[stack_name + "-network_id"], "network_name": network_name, # to match vnf_generic - "local_mac": outputs[stack_name + "-mac_address"], - "local_ip": outputs[stack_name], + "local_mac": mac_addr, + "local_ip": private_ip, "vld_id": self.networks[network_name].vld_id, } @@ -325,6 +350,19 @@ class HeatContext(Context): super(HeatContext, self).undeploy() + @staticmethod + def generate_routing_table(server): + routes = [ + { + "network": intf["network"], + "netmask": intf["netmask"], + "if": name, + "gateway": intf["gateway_ip"], + } + for name, intf in server.interfaces.items() + ] + return routes + def _get_server(self, attr_name): """lookup server info by name from context attr_name: either a name for a server created by yardstick or a dict @@ -334,7 +372,10 @@ class HeatContext(Context): 'yardstick.resources', 'files/yardstick_key-' + get_short_key_uuid(self.key_uuid)) - if isinstance(attr_name, collections.Mapping): + if not isinstance(attr_name, collections.Mapping): + server = self._server_map.get(attr_name, None) + + else: cname = attr_name["name"].split(".")[1] if cname != self.name: return None @@ -351,10 +392,6 @@ class HeatContext(Context): server = Server(attr_name["name"].split(".")[0], self, {}) server.public_ip = public_ip server.private_ip = private_ip - else: - if attr_name not in self._server_map: - return None - server = self._server_map[attr_name] if server is None: return None @@ -364,9 +401,37 @@ class HeatContext(Context): "key_filename": key_filename, "private_ip": server.private_ip, "interfaces": server.interfaces, + "routing_table": self.generate_routing_table(server), + # empty IPv6 routing table + "nd_route_tbl": [], } # Target server may only have private_ip if server.public_ip: result["ip"] = server.public_ip return result + + def _get_network(self, attr_name): + if not isinstance(attr_name, collections.Mapping): + network = self.networks.get(attr_name, None) + + else: + # Don't generalize too much Just support vld_id + vld_id = attr_name.get('vld_id') + if vld_id is None: + return None + + network = next((n for n in self.networks.values() if + getattr(n, "vld_id", None) == vld_id), None) + + if network is None: + return None + + result = { + "name": network.name, + "vld_id": network.vld_id, + "segmentation_id": network.segmentation_id, + "network_type": network.network_type, + "physical_network": network.physical_network, + } + return result