aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick/benchmark/contexts/heat.py
diff options
context:
space:
mode:
authorRoss Brattain <ross.b.brattain@intel.com>2017-05-21 21:07:50 -0700
committerEdward MacGillivray <edward.s.macgillivray@intel.com>2017-07-13 16:34:24 -0700
commit7a32c18b2fb3f220f099218871ba29115ef31ee9 (patch)
tree3e87b12bdbd030a43bbd849aee4f231b699768a5 /yardstick/benchmark/contexts/heat.py
parent49d358550209ab39bf618d8b226f655a0b54d13f (diff)
add network info to topology
we need to know which network each port is connected to so we can find VLAN or VXLAN ID. To do this we implement a new method for Contexts, Context.get_network(). This method is similar to Context.get_server(), it searches for a given network name in all the contexts. From this we generate a context_cfg["networks"] dict that stores all the network info for the nodes in the scenario. Then when we generate the topology for VNFD, we can lookup a given network by the vld_id and get the network_type, segmentation_id, etc. Then if we need to for example generated traffic on a given VLAN or VXLAN, we have this info available. Define default nd_route_tbl for ACL VNF we need default empty nd_route_tbl for IPv6 route. Change-Id: I9f9cfbd6acabeb4ae4675ca7354390efa57b29e7 Signed-off-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Edward MacGillivray <edward.s.macgillivray@intel.com>
Diffstat (limited to 'yardstick/benchmark/contexts/heat.py')
-rw-r--r--yardstick/benchmark/contexts/heat.py141
1 files changed, 101 insertions, 40 deletions
diff --git a/yardstick/benchmark/contexts/heat.py b/yardstick/benchmark/contexts/heat.py
index fed8fc342..0a94dd976 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):
@@ -194,7 +193,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"]:
@@ -250,6 +249,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)
@@ -267,20 +280,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 = \
@@ -288,24 +297,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,
}
@@ -326,6 +347,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
@@ -335,7 +369,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
@@ -352,10 +389,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
@@ -365,9 +398,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