From: stevenvanrossem Date: Mon, 2 May 2016 11:10:40 +0000 (+0200) Subject: add weight metric for adding network links X-Git-Tag: v3.1~135^2~1 X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2Fvim-emu.git;a=commitdiff_plain;h=6b1d9b990bb02fc14ecaace75ef2492b21d7e819 add weight metric for adding network links --- diff --git a/src/emuvim/api/zerorpc/compute.py b/src/emuvim/api/zerorpc/compute.py index 6e4a083..f5d0799 100644 --- a/src/emuvim/api/zerorpc/compute.py +++ b/src/emuvim/api/zerorpc/compute.py @@ -56,7 +56,7 @@ class MultiDatacenterApi(object): def __init__(self, dcs): self.dcs = dcs - def compute_action_start(self, dc_label, compute_name, image, command, network): + def compute_action_start(self, dc_label, compute_name, image, network=None, command=None): """ Start a new compute instance: A docker container :param dc_label: name of the DC diff --git a/src/emuvim/api/zerorpc/network.py b/src/emuvim/api/zerorpc/network.py index 8278422..5a353fe 100644 --- a/src/emuvim/api/zerorpc/network.py +++ b/src/emuvim/api/zerorpc/network.py @@ -64,27 +64,27 @@ class DCNetworkApi(object): def __init__(self, net): self.net = net - def network_action_start(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None): + def network_action_start(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None, weight=None): # call DCNetwork method, not really datacenter specific API for now... # provided dc name needs to be part of API endpoint # no check if vnfs are really connected to this datacenter... logging.debug("RPC CALL: network chain start") try: c = self.net.setChain( - vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface) + vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface, weight=weight) return str(c) except Exception as ex: logging.exception("RPC error.") return ex.message - def network_action_stop(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None): + def network_action_stop(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None, weight=None): # call DCNetwork method, not really datacenter specific API for now... # provided dc name needs to be part of API endpoint # no check if vnfs are really connected to this datacenter... logging.debug("RPC CALL: network chain stop") try: c = self.net.setChain( - vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface, cmd='del-flows') + vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface, cmd='del-flows', weight=weight) return c except Exception as ex: logging.exception("RPC error.") diff --git a/src/emuvim/cli/compute.py b/src/emuvim/cli/compute.py index 179ae1e..f2fdc62 100755 --- a/src/emuvim/cli/compute.py +++ b/src/emuvim/cli/compute.py @@ -35,8 +35,9 @@ class ZeroRpcClient(object): args.get("datacenter"), args.get("name"), args.get("image"), - args.get("docker_command"), - nw_list) + network=nw_list, + command=args.get("docker_command") + ) pp.pprint(r) def stop(self, args): diff --git a/src/emuvim/cli/network.py b/src/emuvim/cli/network.py index c27da59..5b0aa51 100755 --- a/src/emuvim/cli/network.py +++ b/src/emuvim/cli/network.py @@ -32,12 +32,14 @@ class ZeroRpcClient(object): vnf_src_interface = self._parse_vnf_interface(args.get("source")) vnf_dst_name = self._parse_vnf_name(args.get("destination")) vnf_dst_interface = self._parse_vnf_interface(args.get("destination")) + weight = args.get("weight") r = self.c.network_action_start( #args.get("datacenter"), vnf_src_name, vnf_dst_name, vnf_src_interface, - vnf_dst_interface) + vnf_dst_interface, + weight=weight) pp.pprint(r) def remove(self, args): @@ -45,12 +47,14 @@ class ZeroRpcClient(object): vnf_src_interface = self._parse_vnf_interface(args.get("source")) vnf_dst_name = self._parse_vnf_name(args.get("destination")) vnf_dst_interface = self._parse_vnf_interface(args.get("destination")) + weight = args.get("weight") r = self.c.network_action_stop( #args.get("datacenter"), vnf_src_name, vnf_dst_name, vnf_src_interface, - vnf_dst_interface) + vnf_dst_interface, + weight=weight) pp.pprint(r) def _parse_vnf_name(self, vnf_name_str): @@ -79,6 +83,9 @@ parser.add_argument( parser.add_argument( "--destination", "-dst", dest="destination", help="vnf name of the destination of the chain") +parser.add_argument( + "--weight", "-w", dest="weight", + help="weight metric to calculate the path") def main(argv): args = vars(parser.parse_args(argv)) diff --git a/src/emuvim/dcemulator/net.py b/src/emuvim/dcemulator/net.py index dbfde5c..54d578d 100755 --- a/src/emuvim/dcemulator/net.py +++ b/src/emuvim/dcemulator/net.py @@ -8,6 +8,9 @@ import site import time from subprocess import Popen import os +import re + + from mininet.net import Dockernet from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController @@ -127,16 +130,35 @@ class DCNetwork(Dockernet): if "id" in params["params2"]: node2_port_id = params["params2"]["id"] + + # add edge and assigned port number to graph in both directions between node1 and node2 # port_id: id given in descriptor (if available, otherwise same as port) # port: portnumber assigned by Dockernet - self.DCNetwork_graph.add_edge(node1.name, node2.name, - attr_dict={'src_port_id': node1_port_id, 'src_port': node1.ports[link.intf1], - 'dst_port_id': node2_port_id, 'dst_port': node2.ports[link.intf2]}) - self.DCNetwork_graph.add_edge(node2.name, node1.name, - attr_dict={'src_port_id': node2_port_id, 'src_port': node2.ports[link.intf2], - 'dst_port_id': node1_port_id, 'dst_port': node1.ports[link.intf1]}) + attr_dict = {} + # possible weight metrics allowed by TClink class: + weight_metrics = ['bw', 'delay', 'jitter', 'loss'] + edge_attributes = [p for p in params if p in weight_metrics] + for attr in edge_attributes: + # if delay: strip ms (need number as weight in graph) + match = re.search('([0-9]*\.?[0-9]+)', params[attr]) + if match: + attr_number = match.group(1) + else: + attr_number = None + attr_dict[attr] = attr_number + + + attr_dict2 = {'src_port_id': node1_port_id, 'src_port': node1.ports[link.intf1], + 'dst_port_id': node2_port_id, 'dst_port': node2.ports[link.intf2]} + attr_dict2.update(attr_dict) + self.DCNetwork_graph.add_edge(node1.name, node2.name, attr_dict=attr_dict2) + + attr_dict2 = {'src_port_id': node2_port_id, 'src_port': node2.ports[link.intf2], + 'dst_port_id': node1_port_id, 'dst_port': node1.ports[link.intf1]} + attr_dict2.update(attr_dict) + self.DCNetwork_graph.add_edge(node2.name, node1.name, attr_dict=attr_dict2) return link @@ -194,7 +216,7 @@ class DCNetwork(Dockernet): CLI(self) # to remove chain do setChain( src, dst, cmd='del-flows') - def setChain(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None, cmd='add-flow'): + def setChain(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None, cmd='add-flow', weight=None): #check if port is specified (vnf:port) if vnf_src_interface is None: @@ -237,7 +259,7 @@ class DCNetwork(Dockernet): # get shortest path #path = nx.shortest_path(self.DCNetwork_graph, vnf_src_name, vnf_dst_name) try: - path = nx.shortest_path(self.DCNetwork_graph, src_sw, dst_sw) + path = nx.shortest_path(self.DCNetwork_graph, src_sw, dst_sw, weight=weight) except: logging.info("No path could be found between {0} and {1}".format(vnf_src_name, vnf_dst_name)) return "No path could be found between {0} and {1}".format(vnf_src_name, vnf_dst_name) diff --git a/src/emuvim/dcemulator/prometheus.yml b/src/emuvim/dcemulator/prometheus.yml old mode 100644 new mode 100755 diff --git a/src/emuvim/examples/monitoring_demo_topology.py b/src/emuvim/examples/monitoring_demo_topology.py index 16c2b50..20f3ba0 100755 --- a/src/emuvim/examples/monitoring_demo_topology.py +++ b/src/emuvim/examples/monitoring_demo_topology.py @@ -60,8 +60,8 @@ def create_topology1(): to define you topology. These links can use Mininet's features to limit bw, add delay or jitter. """ - net.addLink(dc1, dc2) - net.addLink("datacenter1", s1) + net.addLink(dc1, dc2, delay="10ms") + net.addLink("datacenter1", s1, delay="20ms") net.addLink(s1, dc3) net.addLink(s1, "datacenter4")