if data is None:
data = {}
- logging.info("data: {}".format(data))
vnf_src_name = data.get("vnf_src_name")
vnf_dst_name = data.get("vnf_dst_name")
vnf_src_interface = data.get("vnf_src_interface")
partner consortium (www.sonata-nfv.eu).
"""
from requests import get,put, delete
-import pprint
import argparse
-pp = pprint.PrettyPrinter(indent=4)
class RestApiClient():
response = put("{0}/restapi/network".format(args.get("endpoint")),
params=params)
- pp.pprint(response.text)
+ print(self._nice_print(response.text))
def remove(self, args):
params = self._create_dict(
response = delete("{0}/restapi/network".format(args.get("endpoint")),
params=params)
- pp.pprint(response.text)
+ print(self._nice_print(response.text))
def _parse_vnf_name(self, vnf_name_str):
vnf_name = vnf_name_str.split(':')[0]
def _create_dict(self, **kwargs):
return kwargs
+ def _nice_print(self, text):
+ # some modules seem to return unicode strings where newlines, other special characters are escaped
+ text = str(text).replace('\\n', '\n')
+ text = str(text).replace('\\"', '"')
+ return text
+
parser = argparse.ArgumentParser(description='son-emu-cli network')
parser.add_argument(
"command",
"--weight", "-w", dest="weight",
help="weight edge attribute to calculate the path")
parser.add_argument(
- "--priority", "-p", dest="priority", default="0",
+ "--priority", "-p", dest="priority", default="1000",
help="priority of flow rule")
parser.add_argument(
"--match", "-m", dest="match",
"--bidirectional", "-b", dest="bidirectional", action='store_true',
help="add/remove the flow entries from src to dst and back")
parser.add_argument(
- "--cookie", "-c", dest="cookie",
+ "--cookie", "-c", dest="cookie", default="10",
help="cookie for this flow, as easy to use identifier (eg. per tenant/service)")
parser.add_argument(
"--endpoint", "-e", dest="endpoint",
import re
import requests
import os
+import json
from mininet.net import Containernet
from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController
# default CPU period used for cpu percentage-based cfs values (microseconds)
CPU_PERIOD = 1000000
+# default priority setting for added flow-rules
+DEFAULT_PRIORITY = 1000
+# default cookie number for new flow-rules
+DEFAULT_COOKIE = 10
+
class DCNetwork(Containernet):
"""
Wraps the original Mininet/Containernet class and provides
switch_inport_nr = self.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
current_hop = next_hop
- return "path {2} between {0} and {1}".format(vnf_src_name, vnf_dst_name, cmd)
+ flow_options = {
+ 'priority':kwargs.get('priority', DEFAULT_PRIORITY),
+ 'cookie':kwargs.get('cookie', DEFAULT_COOKIE),
+ 'vlan':kwargs['vlan'],
+ 'path':kwargs['path'],
+ 'match_input':kwargs.get('match')
+ }
+ flow_options_str = json.dumps(flow_options, indent=1)
+ return "success: {2} between {0} and {1} with options: {3}".format(vnf_src_name, vnf_dst_name, cmd, flow_options_str)
def _set_flow_entry_ryu_rest(self, node, switch_inport_nr, switch_outport_nr, **kwargs):
match = 'in_port=%s' % switch_inport_nr
index = kwargs.get('pathindex')
vlan = kwargs.get('vlan')
- priority = kwargs.get('priority')
+ priority = kwargs.get('priority', DEFAULT_PRIORITY)
# flag to not set the ovs port vlan tag
skip_vlan_tag = kwargs.get('skip_vlan_tag')
# table id to put this flowentry
Initialize multi PoP emulator network.
"""
super(DemoTopology, self).__init__(
- monitor=False,
+ monitor=True,
enable_learning=True
)
# define members for later use
def create_topology1():
# create topology
- net = DCNetwork(controller=RemoteController, monitor=False, enable_learning=True)
+ net = DCNetwork(controller=RemoteController, monitor=True, enable_learning=True)
dc1 = net.addDatacenter("dc1")
dc2 = net.addDatacenter("dc2")
dc3 = net.addDatacenter("dc3")
specific controller functionality.
"""
self.net = DCNetwork(controller=controller, **kwargs)
- self.api = RestApiEndpoint("127.0.0.1", 5001)
+ self.api = RestApiEndpoint("127.0.0.1", 5001, self.net)
# add some switches
# start from s1 because ovs does not like to have dpid = 0
# and switch name-number is being used by mininet to set the dpid
class testEmulatorNetworking( SimpleTestTopology ):
+ def testSDNChainingSingleService_withLearning(self):
+ """
+ Create a two data centers and interconnect them with additional
+ switches between them.
+ Uses Ryu SDN controller.
+ Connect the Docker hosts to different datacenters and setup the links between.
+ """
+ # create network
+ self.createNet(
+ nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
+ autolinkswitches=True,
+ controller=RemoteController,
+ enable_learning=True)
+ # setup links
+ self.net.addLink(self.dc[0], self.s[0])
+ self.net.addLink(self.s[2], self.dc[1])
+ # start Mininet network
+ self.startNet()
+
+ # add compute resources
+ vnf1 = self.dc[0].startCompute("vnf1", network=[{'id':'intf1', 'ip':'10.0.10.1/24'}])
+ vnf2 = self.dc[1].startCompute("vnf2", network=[{'id':'intf2', 'ip':'10.0.10.2/24'}])
+ # check number of running nodes
+ self.assertTrue(len(self.getContainernetContainers()) == 2)
+ self.assertTrue(len(self.net.hosts) == 2)
+ self.assertTrue(len(self.net.switches) == 5)
+ # check status
+ # check get status
+ s1 = self.dc[0].containers.get("vnf1").getStatus()
+ print s1
+ self.assertTrue(s1["name"] == "vnf1")
+ self.assertTrue(s1["state"]["Running"])
+ self.assertTrue(s1["network"][0]['intf_name'] == 'intf1')
+ self.assertTrue(s1["network"][0]['ip'] == '10.0.10.1/24')
+
+ s2 = self.dc[1].containers.get("vnf2").getStatus()
+ print s2
+ self.assertTrue(s2["name"] == "vnf2")
+ self.assertTrue(s2["state"]["Running"])
+ self.assertTrue(s2["network"][0]['intf_name'] == 'intf2')
+ self.assertTrue(s2["network"][0]['ip'] == '10.0.10.2/24')
+
+ # should be connected because learning = True
+ self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
+ # setup links
+ self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='add-flow')
+ # should still be connected
+ self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
+ # stop Mininet network
+ self.stopNet()
+
def testSDNChainingSingleService(self):
"""
Create a two data centers and interconnect them with additional
print('network add vnf1 vnf2->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli network add -src vnf1 -dst vnf2 -b -c 10", shell=True)
+ output = subprocess.check_output("son-emu-cli network add -src vnf1 -dst vnf2 -b -c 10", shell=True)
+ self.assertTrue("add-flow" in output)
+ self.assertTrue("success" in output)
+
print('network remove vnf1 vnf2->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli network remove -src vnf1 -dst vnf2 -b", shell=True)
+ output = subprocess.check_output("son-emu-cli network remove -src vnf1 -dst vnf2 -b", shell=True)
+ self.assertTrue("del-flows" in output)
+ self.assertTrue("success" in output)
print('>>>>> checking --> son-emu-cli compute stop -d datacenter0 -n vnf2 ->>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli compute stop -d datacenter0 -n vnf2", shell=True)
+ output = subprocess.check_output("son-emu-cli compute stop -d datacenter0 -n vnf2", shell=True)
# check number of running nodes
self.assertTrue(len(self.getContainernetContainers()) == 2)
print('>>>>> checking --> son-emu-cli compute list ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli compute list", shell=True)
output = subprocess.check_output("son-emu-cli compute list", shell=True)
# check datacenter list result
print('>>>>> checking --> son-emu-cli compute status -d datacenter0 -n vnf1 ->>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli compute status -d datacenter0 -n vnf1", shell=True)
output = subprocess.check_output("son-emu-cli compute status -d datacenter0 -n vnf1", shell=True)
output = ast.literal_eval(output)
print('>>>>> checking --> son-emu-cli datacenter list ->>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli datacenter list", shell=True)
output = subprocess.check_output("son-emu-cli datacenter list", shell=True)
-
# check datacenter list result
-
self.assertTrue("datacenter0" in output)
print('->>>>> checking --> son-emu-cli datacenter status -d datacenter0 ->>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli datacenter status -d datacenter0", shell=True)
output = subprocess.check_output("son-emu-cli datacenter status -d datacenter0", shell=True)
-
# check datacenter status result
self.assertTrue("datacenter0" in output)