aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick
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
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')
-rw-r--r--yardstick/benchmark/contexts/base.py32
-rw-r--r--yardstick/benchmark/contexts/dummy.py3
-rw-r--r--yardstick/benchmark/contexts/heat.py141
-rw-r--r--yardstick/benchmark/contexts/model.py7
-rw-r--r--yardstick/benchmark/contexts/node.py30
-rw-r--r--yardstick/benchmark/contexts/standalone.py32
-rw-r--r--yardstick/benchmark/core/task.py30
-rw-r--r--yardstick/benchmark/scenarios/networking/vnf_generic.py106
-rw-r--r--yardstick/orchestrator/heat.py8
9 files changed, 294 insertions, 95 deletions
diff --git a/yardstick/benchmark/contexts/base.py b/yardstick/benchmark/contexts/base.py
index 0be2eee77..e362c6a3d 100644
--- a/yardstick/benchmark/contexts/base.py
+++ b/yardstick/benchmark/contexts/base.py
@@ -23,7 +23,7 @@ class Context(object):
@abc.abstractmethod
def init(self, attrs):
- "Initiate context."
+ """Initiate context."""
@staticmethod
def get_cls(context_type):
@@ -56,20 +56,34 @@ class Context(object):
"""get server info by name from context
"""
+ @abc.abstractmethod
+ def _get_network(self, attr_name):
+ """get network info by name from context
+ """
+
@staticmethod
def get_server(attr_name):
"""lookup server info by name from context
attr_name: either a name for a server created by yardstick or a dict
with attribute name mapping when using external heat templates
"""
- server = None
- for context in Context.list:
- server = context._get_server(attr_name)
- if server is not None:
- break
-
- if server is None:
+ servers = (context._get_server(attr_name) for context in Context.list)
+ try:
+ return next(s for s in servers if s)
+ except StopIteration:
raise ValueError("context not found for server '%r'" %
attr_name)
- return server
+ @staticmethod
+ def get_network(attr_name):
+ """lookup server info by name from context
+ attr_name: either a name for a server created by yardstick or a dict
+ with attribute name mapping when using external heat templates
+ """
+
+ networks = (context._get_network(attr_name) for context in Context.list)
+ try:
+ return next(n for n in networks if n)
+ except StopIteration:
+ raise ValueError("context not found for server '%r'" %
+ attr_name)
diff --git a/yardstick/benchmark/contexts/dummy.py b/yardstick/benchmark/contexts/dummy.py
index c658d3257..8ae4b65b8 100644
--- a/yardstick/benchmark/contexts/dummy.py
+++ b/yardstick/benchmark/contexts/dummy.py
@@ -37,3 +37,6 @@ class DummyContext(Context):
def _get_server(self, attr_name):
return None
+
+ def _get_network(self, attr_name):
+ return None
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
diff --git a/yardstick/benchmark/contexts/model.py b/yardstick/benchmark/contexts/model.py
index 5077a9786..06538d8a9 100644
--- a/yardstick/benchmark/contexts/model.py
+++ b/yardstick/benchmark/contexts/model.py
@@ -106,13 +106,14 @@ class Network(Object):
self.subnet_cidr = attrs.get('cidr', '10.0.1.0/24')
self.router = None
self.physical_network = attrs.get('physical_network', 'physnet1')
- self.provider = attrs.get('provider', None)
- self.segmentation_id = attrs.get('segmentation_id', None)
+ self.provider = attrs.get('provider')
+ self.segmentation_id = attrs.get('segmentation_id')
+ self.network_type = attrs.get('network_type')
if "external_network" in attrs:
self.router = Router("router", self.name,
context, attrs["external_network"])
- self.vld_id = attrs.get("vld_id", "")
+ self.vld_id = attrs.get("vld_id")
Network.list.append(self)
diff --git a/yardstick/benchmark/contexts/node.py b/yardstick/benchmark/contexts/node.py
index baa1cf5d6..b3f0aca0e 100644
--- a/yardstick/benchmark/contexts/node.py
+++ b/yardstick/benchmark/contexts/node.py
@@ -33,6 +33,7 @@ class NodeContext(Context):
self.name = None
self.file_path = None
self.nodes = []
+ self.networks = {}
self.controllers = []
self.computes = []
self.baremetals = []
@@ -77,6 +78,9 @@ class NodeContext(Context):
self.env = attrs.get('env', {})
LOG.debug("Env: %r", self.env)
+ # add optional static network definition
+ self.networks.update(cfg.get("networks", {}))
+
def deploy(self):
config_type = self.env.get('type', '')
if config_type == 'ansible':
@@ -141,6 +145,32 @@ class NodeContext(Context):
node["name"] = attr_name
return node
+ def _get_network(self, attr_name):
+ if not isinstance(attr_name, collections.Mapping):
+ network = self.networks.get(attr_name)
+
+ 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
+ n.get("vld_id") == vld_id), None)
+
+ if network is None:
+ return None
+
+ result = {
+ # name is required
+ "name": network["name"],
+ "vld_id": network.get("vld_id"),
+ "segmentation_id": network.get("segmentation_id"),
+ "network_type": network.get("network_type"),
+ "physical_network": network.get("physical_network"),
+ }
+ return result
+
def _execute_script(self, node_name, info):
if node_name == 'local':
self._execute_local_script(info)
diff --git a/yardstick/benchmark/contexts/standalone.py b/yardstick/benchmark/contexts/standalone.py
index 78eaac7ee..8614f0cac 100644
--- a/yardstick/benchmark/contexts/standalone.py
+++ b/yardstick/benchmark/contexts/standalone.py
@@ -36,6 +36,7 @@ class StandaloneContext(Context):
self.name = None
self.file_path = None
self.nodes = []
+ self.networks = {}
self.nfvi_node = []
super(StandaloneContext, self).__init__()
@@ -66,8 +67,11 @@ class StandaloneContext(Context):
self.nodes.extend(cfg["nodes"])
self.nfvi_node.extend([node for node in cfg["nodes"]
if node["role"] == "nfvi_node"])
+ # add optional static network definition
+ self.networks.update(cfg.get("networks", {}))
LOG.debug("Nodes: %r", self.nodes)
LOG.debug("NFVi Node: %r", self.nfvi_node)
+ LOG.debug("Networks: %r", self.networks)
def deploy(self):
"""don't need to deploy"""
@@ -114,3 +118,31 @@ class StandaloneContext(Context):
node["name"] = attr_name
return node
+
+ def _get_network(self, attr_name):
+ if not isinstance(attr_name, collections.Mapping):
+ network = self.networks.get(attr_name)
+
+ else:
+ # Don't generalize too much Just support vld_id
+ vld_id = attr_name.get('vld_id')
+ if vld_id is None:
+ return None
+ try:
+ network = next(n for n in self.networks.values() if
+ n.get("vld_id") == vld_id)
+ except StopIteration:
+ return None
+
+ if network is None:
+ return None
+
+ result = {
+ # name is required
+ "name": network["name"],
+ "vld_id": network.get("vld_id"),
+ "segmentation_id": network.get("segmentation_id"),
+ "network_type": network.get("network_type"),
+ "physical_network": network.get("physical_network"),
+ }
+ return result
diff --git a/yardstick/benchmark/core/task.py b/yardstick/benchmark/core/task.py
index 0e85e6316..b53d6446e 100644
--- a/yardstick/benchmark/core/task.py
+++ b/yardstick/benchmark/core/task.py
@@ -322,6 +322,8 @@ class Task(object): # pragma: no cover
if "nodes" in scenario_cfg:
context_cfg["nodes"] = parse_nodes_with_context(scenario_cfg)
+ context_cfg["networks"] = get_networks_from_nodes(
+ context_cfg["nodes"])
runner = base_runner.Runner.get(runner_cfg)
print("Starting runner of type '%s'" % runner_cfg["type"])
@@ -518,7 +520,7 @@ class TaskParser(object): # pragma: no cover
cfg_schema))
def _check_precondition(self, cfg):
- """Check if the envrionment meet the preconditon"""
+ """Check if the environment meet the precondition"""
if "precondition" in cfg:
precondition = cfg["precondition"]
@@ -573,14 +575,26 @@ def _is_background_scenario(scenario):
def parse_nodes_with_context(scenario_cfg):
- """paras the 'nodes' fields in scenario """
+ """parse the 'nodes' fields in scenario """
nodes = scenario_cfg["nodes"]
-
- nodes_cfg = {}
- for nodename in nodes:
- nodes_cfg[nodename] = Context.get_server(nodes[nodename])
-
- return nodes_cfg
+ return {nodename: Context.get_server(node) for nodename, node in nodes.items()}
+
+
+def get_networks_from_nodes(nodes):
+ """parse the 'nodes' fields in scenario """
+ networks = {}
+ for node in nodes.values():
+ if not node:
+ continue
+ for interface in node['interfaces'].values():
+ vld_id = interface.get('vld_id')
+ # mgmt network doesn't have vld_id
+ if not vld_id:
+ continue
+ network = Context.get_network({"vld_id": vld_id})
+ if network:
+ networks[network['name']] = network
+ return networks
def runner_join(runner):
diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py
index 594edeaa8..9607e3005 100644
--- a/yardstick/benchmark/scenarios/networking/vnf_generic.py
+++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py
@@ -164,38 +164,60 @@ class NetworkServiceTestCase(base.Scenario):
for vnfd in topology["constituent-vnfd"]
if vnf_id == vnfd["member-vnf-index"]), None)
+ @staticmethod
+ def get_vld_networks(networks):
+ return {n['vld_id']: n for n in networks.values()}
+
def _resolve_topology(self, context_cfg, topology):
for vld in topology["vld"]:
- if len(vld["vnfd-connection-point-ref"]) > 2:
+ try:
+ node_0, node_1 = vld["vnfd-connection-point-ref"]
+ except (TypeError, ValueError):
raise IncorrectConfig("Topology file corrupted, "
- "too many endpoint for connection")
-
- node_0, node_1 = vld["vnfd-connection-point-ref"]
+ "wrong number of endpoints for connection")
- node0 = self._find_vnf_name_from_id(topology,
- node_0["member-vnf-index-ref"])
- node1 = self._find_vnf_name_from_id(topology,
- node_1["member-vnf-index-ref"])
+ node_0_name = self._find_vnf_name_from_id(topology,
+ node_0["member-vnf-index-ref"])
+ node_1_name = self._find_vnf_name_from_id(topology,
+ node_1["member-vnf-index-ref"])
- if0 = node_0["vnfd-connection-point-ref"]
- if1 = node_1["vnfd-connection-point-ref"]
+ node_0_ifname = node_0["vnfd-connection-point-ref"]
+ node_1_ifname = node_1["vnfd-connection-point-ref"]
+ node_0_if = context_cfg["nodes"][node_0_name]["interfaces"][node_0_ifname]
+ node_1_if = context_cfg["nodes"][node_1_name]["interfaces"][node_1_ifname]
try:
- nodes = context_cfg["nodes"]
- nodes[node0]["interfaces"][if0]["vld_id"] = vld["id"]
- nodes[node1]["interfaces"][if1]["vld_id"] = vld["id"]
-
- nodes[node0]["interfaces"][if0]["dst_mac"] = \
- nodes[node1]["interfaces"][if1]["local_mac"]
- nodes[node0]["interfaces"][if0]["dst_ip"] = \
- nodes[node1]["interfaces"][if1]["local_ip"]
-
- nodes[node1]["interfaces"][if1]["dst_mac"] = \
- nodes[node0]["interfaces"][if0]["local_mac"]
- nodes[node1]["interfaces"][if1]["dst_ip"] = \
- nodes[node0]["interfaces"][if0]["local_ip"]
+ vld_networks = self.get_vld_networks(context_cfg["networks"])
+
+ node_0_if["vld_id"] = vld["id"]
+ node_1_if["vld_id"] = vld["id"]
+
+ # set peer name
+ node_0_if["peer_name"] = node_1_name
+ node_1_if["peer_name"] = node_0_name
+
+ # set peer interface name
+ node_0_if["peer_ifname"] = node_1_ifname
+ node_1_if["peer_ifname"] = node_0_ifname
+
+ # just load the whole network dict
+ node_0_if["network"] = vld_networks.get(vld["id"], {})
+ node_1_if["network"] = vld_networks.get(vld["id"], {})
+
+ node_0_if["dst_mac"] = node_1_if["local_mac"]
+ node_0_if["dst_ip"] = node_1_if["local_ip"]
+
+ node_1_if["dst_mac"] = node_0_if["local_mac"]
+ node_1_if["dst_ip"] = node_0_if["local_ip"]
+
+ # add peer interface dict, but remove circular link
+ # TODO: don't waste memory
+ node_0_copy = node_0_if.copy()
+ node_1_copy = node_1_if.copy()
+ node_0_if["peer_intf"] = node_1_copy
+ node_1_if["peer_intf"] = node_0_copy
except KeyError:
- raise IncorrectConfig("Required interface not found,"
+ raise IncorrectConfig("Required interface not found, "
"topology file corrupted")
@classmethod
@@ -308,21 +330,36 @@ printf "%s/driver:" $1 ; basename $(readlink -s $1/device/driver); } \
return dict(network_devices)
@classmethod
- def get_vnf_impl(cls, vnf_model):
+ def get_vnf_impl(cls, vnf_model_id):
""" Find the implementing class from vnf_model["vnf"]["name"] field
- :param vnf_model: dictionary containing a parsed vnfd
+ :param vnf_model_id: parsed vnfd model ID field
:return: subclass of GenericVNF
"""
import_modules_from_package(
"yardstick.network_services.vnf_generic.vnf")
- expected_name = vnf_model['id']
- impl = (c for c in itersubclasses(GenericVNF)
- if c.__name__ == expected_name)
+ expected_name = vnf_model_id
+ classes_found = []
+
+ def impl():
+ for name, class_ in ((c.__name__, c) for c in itersubclasses(GenericVNF)):
+ if name == expected_name:
+ yield class_
+ classes_found.append(name)
+
try:
- return next(impl)
+ return next(impl())
except StopIteration:
- raise IncorrectConfig("No implementation for %s", expected_name)
+ pass
+
+ raise IncorrectConfig("No implementation for %s found in %s" %
+ (expected_name, classes_found))
+
+ @staticmethod
+ def update_interfaces_from_node(vnfd, node):
+ for intf in vnfd["vdu"][0]["external-interface"]:
+ node_intf = node['interfaces'][intf['name']]
+ intf['virtual-interface'].update(node_intf)
def load_vnf_models(self, scenario_cfg, context_cfg):
""" Create VNF objects based on YAML descriptors
@@ -339,8 +376,11 @@ printf "%s/driver:" $1 ; basename $(readlink -s $1/device/driver); } \
scenario_cfg['task_path']) as stream:
vnf_model = stream.read()
vnfd = vnfdgen.generate_vnfd(vnf_model, node)
- vnf_impl = self.get_vnf_impl(vnfd["vnfd:vnfd-catalog"]["vnfd"][0])
- vnf_instance = vnf_impl(vnfd["vnfd:vnfd-catalog"]["vnfd"][0])
+ # TODO: here add extra context_cfg["nodes"] regardless of template
+ vnfd = vnfd["vnfd:vnfd-catalog"]["vnfd"][0]
+ self.update_interfaces_from_node(vnfd, node)
+ vnf_impl = self.get_vnf_impl(vnfd['id'])
+ vnf_instance = vnf_impl(vnfd)
vnf_instance.name = node_name
vnfs.append(vnf_instance)
diff --git a/yardstick/orchestrator/heat.py b/yardstick/orchestrator/heat.py
index 7958b1cfb..2a907d124 100644
--- a/yardstick/orchestrator/heat.py
+++ b/yardstick/orchestrator/heat.py
@@ -534,6 +534,7 @@ name (i.e. %s).\
}
HEAT_WAIT_LOOP_INTERVAL = 2
+ HEAT_CREATE_COMPLETE_STATUS = u'CREATE_COMPLETE'
def create(self, block=True, timeout=3600):
"""
@@ -558,10 +559,13 @@ name (i.e. %s).\
if not block:
self.outputs = stack.outputs = {}
+ end_time = time.time()
+ log.info("Created stack '%s' in %.3e secs",
+ self.name, end_time - start_time)
return stack
time_limit = start_time + timeout
- for status in iter(self.status, u'CREATE_COMPLETE'):
+ for status in iter(self.status, self.HEAT_CREATE_COMPLETE_STATUS):
log.debug("stack state %s", status)
if status == u'CREATE_FAILED':
stack_status_reason = heat_client.stacks.get(self.uuid).stack_status_reason
@@ -574,7 +578,7 @@ name (i.e. %s).\
end_time = time.time()
outputs = heat_client.stacks.get(self.uuid).outputs
- log.info("Created stack '%s' in %d secs",
+ log.info("Created stack '%s' in %.3e secs",
self.name, end_time - start_time)
# keep outputs as unicode