Refactoring: Made complete codebase PEP8 compatible.
Only PEP8 rule E501 (line too long) is not yet reflected
by this change.
The patch also adds automated code style checks to the
CI test stage using flake8.
It will let the tests fail if there is a code style
violation.
Change-Id: I90956dd424a46691546ef720351757d3c43451a7
Signed-off-by: peusterm <manuel.peuster@uni-paderborn.de>
diff --git a/src/emuvim/__init__.py b/src/emuvim/__init__.py
index 7e60065..d888119 100755
--- a/src/emuvim/__init__.py
+++ b/src/emuvim/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/api/__init__.py b/src/emuvim/api/__init__.py
index 395c0ce..d888119 100755
--- a/src/emuvim/api/__init__.py
+++ b/src/emuvim/api/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/api/openstack/__init__.py b/src/emuvim/api/openstack/__init__.py
index 9979159..d888119 100755
--- a/src/emuvim/api/openstack/__init__.py
+++ b/src/emuvim/api/openstack/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/api/openstack/chain_api.py b/src/emuvim/api/openstack/chain_api.py
index 20258bb..47af63c 100755
--- a/src/emuvim/api/openstack/chain_api.py
+++ b/src/emuvim/api/openstack/chain_api.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import json
import logging
import copy
@@ -34,8 +32,6 @@
from flask import Flask
from flask import Response, request
from flask_restful import Api, Resource
-from mininet.link import Link
-import uuid
class ChainApi(Resource):
@@ -77,7 +73,8 @@
return response
def _start_flask(self):
- logging.info("Starting %s endpoint @ http://%s:%d" % ("ChainDummyApi", self.ip, self.port))
+ logging.info("Starting %s endpoint @ http://%s:%d" %
+ ("ChainDummyApi", self.ip, self.port))
if self.app is not None:
self.app.before_request(self.dump_playbook)
self.app.run(self.ip, self.port, debug=True, use_reloader=False)
@@ -88,8 +85,8 @@
if len(request.data) > 0:
data = "# CHAIN API\n"
data += "curl -X {type} -H \"Content-type: application/json\" -d '{data}' {url}".format(type=request.method,
- data=request.data,
- url=request.url)
+ data=request.data,
+ url=request.url)
logfile.write(data + "\n")
@@ -139,7 +136,8 @@
return Response(resp, status=200, mimetype="application/json")
except Exception as ex:
- logging.exception(u"%s: Could not show list of versions." % __name__)
+ logging.exception(
+ u"%s: Could not show list of versions." % __name__)
return ex.message, 500
@@ -162,10 +160,12 @@
for chain in self.api.manage.full_chain_data.values():
resp["chains"].append(chain)
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
except Exception as ex:
- logging.exception(u"%s: Could not list all network chains." % __name__)
+ logging.exception(
+ u"%s: Could not list all network chains." % __name__)
return ex.message, 500
@@ -188,10 +188,12 @@
for lb in self.api.manage.full_lb_data.values():
resp["loadbalancers"].append(lb)
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
except Exception as ex:
- logging.exception(u"%s: Could not list all live loadbalancers." % __name__)
+ logging.exception(
+ u"%s: Could not list all live loadbalancers." % __name__)
return ex.message, 500
@@ -271,11 +273,14 @@
vnf_dst_interface=dst_intfs, bidirectional=True,
path=path, layer2=layer2)
resp = {'cookie': cookie}
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
except Exception as e:
- logging.exception(u"%s: Error setting up the chain.\n %s" % (__name__, e))
- return Response(u"Error setting up the chain", status=500, mimetype="application/json")
+ logging.exception(
+ u"%s: Error setting up the chain.\n %s" % (__name__, e))
+ return Response(u"Error setting up the chain",
+ status=500, mimetype="application/json")
def delete(self, src_vnf, src_intfs, dst_vnf, dst_intfs):
"""
@@ -307,10 +312,13 @@
try:
cookie = self.api.manage.network_action_stop(src_vnf, dst_vnf, vnf_src_interface=src_intfs,
vnf_dst_interface=dst_intfs, bidirectional=True)
- return Response(json.dumps(cookie), status=200, mimetype="application/json")
+ return Response(json.dumps(cookie), status=200,
+ mimetype="application/json")
except Exception as e:
- logging.exception(u"%s: Error deleting the chain.\n %s" % (__name__, e))
- return Response(u"Error deleting the chain", status=500, mimetype="application/json")
+ logging.exception(
+ u"%s: Error deleting the chain.\n %s" % (__name__, e))
+ return Response(u"Error deleting the chain",
+ status=500, mimetype="application/json")
class ChainVnfDcStackInterfaces(Resource):
@@ -322,7 +330,8 @@
def __init__(self, api):
self.api = api
- def put(self, src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs):
+ def put(self, src_dc, src_stack, src_vnf, src_intfs,
+ dst_dc, dst_stack, dst_vnf, dst_intfs):
"""
A PUT request to "/v1/chain/<src_dc>/<src_stack>/<src_vnf>/<src_intfs>/<dst_dc>/<dst_stack>/<dst_vnf>/<dst_intfs>"
will set up chain.
@@ -352,18 +361,21 @@
"""
# search for real names
- real_names = self._findNames(src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs)
- if type(real_names) is not tuple:
+ real_names = self._findNames(
+ src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs)
+ if not isinstance(real_names, tuple):
# something went wrong
return real_names
container_src, container_dst, interface_src, interface_dst = real_names
# check if both VNFs exist
- if not self.api.manage.check_vnf_intf_pair(container_src, interface_src):
+ if not self.api.manage.check_vnf_intf_pair(
+ container_src, interface_src):
return Response(u"VNF %s or intfs %s does not exist" % (container_src, interface_src), status=501,
mimetype="application/json")
- if not self.api.manage.check_vnf_intf_pair(container_dst, interface_dst):
+ if not self.api.manage.check_vnf_intf_pair(
+ container_dst, interface_dst):
return Response(u"VNF %s or intfs %s does not exist" % (container_dst, interface_dst), status=501,
mimetype="application/json")
@@ -372,13 +384,17 @@
vnf_dst_interface=interface_dst, bidirectional=True,
layer2=True)
resp = {'cookie': cookie}
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
except Exception as e:
- logging.exception(u"%s: Error setting up the chain.\n %s" % (__name__, e))
- return Response(u"Error setting up the chain", status=500, mimetype="application/json")
+ logging.exception(
+ u"%s: Error setting up the chain.\n %s" % (__name__, e))
+ return Response(u"Error setting up the chain",
+ status=500, mimetype="application/json")
- def post(self, src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs):
+ def post(self, src_dc, src_stack, src_vnf, src_intfs,
+ dst_dc, dst_stack, dst_vnf, dst_intfs):
"""
A post request to "/v1/chain/<src_dc>/<src_stack>/<src_vnf>/<src_intfs>/<dst_dc>/<dst_stack>/<dst_vnf>/<dst_intfs>"
will create a chain between two interfaces at the specified vnfs.
@@ -410,8 +426,9 @@
layer2 = True
# search for real names
- real_names = self._findNames(src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs)
- if type(real_names) is not tuple:
+ real_names = self._findNames(
+ src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs)
+ if not isinstance(real_names, tuple):
# something went wrong
return real_names
@@ -422,13 +439,17 @@
vnf_dst_interface=interface_dst, bidirectional=True,
path=path, layer2=layer2)
resp = {'cookie': cookie}
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
except Exception as e:
- logging.exception(u"%s: Error setting up the chain.\n %s" % (__name__, e))
- return Response(u"Error setting up the chain", status=500, mimetype="application/json")
+ logging.exception(
+ u"%s: Error setting up the chain.\n %s" % (__name__, e))
+ return Response(u"Error setting up the chain",
+ status=500, mimetype="application/json")
- def delete(self, src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs):
+ def delete(self, src_dc, src_stack, src_vnf, src_intfs,
+ dst_dc, dst_stack, dst_vnf, dst_intfs):
"""
A DELETE request to "/v1/chain/<src_dc>/<src_stack>/<src_vnf>/<src_intfs>/<dst_dc>/<dst_stack>/<dst_vnf>/<dst_intfs>"
will delete a previously created chain.
@@ -456,8 +477,9 @@
"""
# search for real names
- real_names = self._findNames(src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs)
- if type(real_names) is not tuple:
+ real_names = self._findNames(
+ src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs)
+ if not isinstance(real_names, tuple):
# something went wrong, real_names is a Response object
return real_names
@@ -466,17 +488,22 @@
try:
cookie = self.api.manage.network_action_stop(container_src, container_dst, vnf_src_interface=interface_src,
vnf_dst_interface=interface_dst, bidirectional=True)
- return Response(json.dumps(cookie), status=200, mimetype="application/json")
+ return Response(json.dumps(cookie), status=200,
+ mimetype="application/json")
except Exception as e:
- logging.exception(u"%s: Error deleting the chain.\n %s" % (__name__, e))
- return Response(u"Error deleting the chain", status=500, mimetype="application/json")
+ logging.exception(
+ u"%s: Error deleting the chain.\n %s" % (__name__, e))
+ return Response(u"Error deleting the chain",
+ status=500, mimetype="application/json")
# Tries to find real container and interface names according to heat template names
# Returns a tuple of 4 or a Response object
- def _findNames(self, src_dc, src_stack, src_vnf, src_intfs, dst_dc, dst_stack, dst_vnf, dst_intfs):
+ def _findNames(self, src_dc, src_stack, src_vnf, src_intfs,
+ dst_dc, dst_stack, dst_vnf, dst_intfs):
# search for datacenters
if src_dc not in self.api.manage.net.dcs or dst_dc not in self.api.manage.net.dcs:
- return Response(u"At least one DC does not exist", status=500, mimetype="application/json")
+ return Response(u"At least one DC does not exist",
+ status=500, mimetype="application/json")
dc_src = self.api.manage.net.dcs[src_dc]
dc_dst = self.api.manage.net.dcs[dst_dc]
# search for related OpenStackAPIs
@@ -489,7 +516,8 @@
if api.compute.dc == dc_dst:
api_dst = api
if api_src is None or api_dst is None:
- return Response(u"At least one OpenStackAPI does not exist", status=500, mimetype="application/json")
+ return Response(u"At least one OpenStackAPI does not exist",
+ status=500, mimetype="application/json")
# search for stacks
stack_src = None
stack_dst = None
@@ -500,7 +528,8 @@
if stack.stack_name == dst_stack:
stack_dst = stack
if stack_src is None or stack_dst is None:
- return Response(u"At least one Stack does not exist", status=500, mimetype="application/json")
+ return Response(u"At least one Stack does not exist",
+ status=500, mimetype="application/json")
# search for servers
server_src = None
server_dst = None
@@ -513,7 +542,8 @@
server_dst = server
break
if server_src is None or server_dst is None:
- return Response(u"At least one VNF does not exist", status=500, mimetype="application/json")
+ return Response(u"At least one VNF does not exist",
+ status=500, mimetype="application/json")
container_src = server_src.name
container_dst = server_dst.name
@@ -526,7 +556,8 @@
if dst_intfs in server_dst.port_names:
port_dst = stack_dst.ports[dst_intfs]
if port_src is None or port_dst is None:
- return Response(u"At least one Port does not exist", status=500, mimetype="application/json")
+ return Response(u"At least one Port does not exist",
+ status=500, mimetype="application/json")
interface_src = port_src.intf_name
interface_dst = port_dst.intf_name
@@ -576,8 +607,9 @@
# check src vnf/port
if src_stack != "floating":
- real_src = self._findName(src_dc, src_stack, vnf_src_name, vnf_src_interface)
- if type(real_src) is not tuple:
+ real_src = self._findName(
+ src_dc, src_stack, vnf_src_name, vnf_src_interface)
+ if not isinstance(real_src, tuple):
# something went wrong, real_src is a Response object
return real_src
@@ -590,20 +622,24 @@
dst_server = dst_vnf.get('server', None)
dst_port = dst_vnf.get('port', None)
if dst_dc is not None and dst_stack is not None and dst_server is not None and dst_port is not None:
- real_dst = self._findName(dst_dc, dst_stack, dst_server, dst_port)
- if type(real_dst) is not tuple:
+ real_dst = self._findName(
+ dst_dc, dst_stack, dst_server, dst_port)
+ if not isinstance(real_dst, tuple):
# something went wrong, real_dst is a Response object
return real_dst
real_dst_dict[real_dst[0]] = real_dst[1]
- input_object = {"dst_vnf_interfaces": real_dst_dict, "path": req.get("path", None)}
+ input_object = {"dst_vnf_interfaces": real_dst_dict,
+ "path": req.get("path", None)}
if src_stack != "floating":
- self.api.manage.add_loadbalancer(container_src, interface_src, lb_data=input_object)
+ self.api.manage.add_loadbalancer(
+ container_src, interface_src, lb_data=input_object)
return Response(u"Loadbalancer set up at %s:%s" % (container_src, interface_src),
status=200, mimetype="application/json")
else:
- cookie, floating_ip = self.api.manage.add_floating_lb(src_dc, lb_data=input_object)
+ cookie, floating_ip = self.api.manage.add_floating_lb(
+ src_dc, lb_data=input_object)
return Response(json.dumps({"cookie": "%d" % cookie, "floating_ip": "%s" % floating_ip}),
status=200, mimetype="application/json")
@@ -612,7 +648,8 @@
logging.exception(u"%s: Error setting up the loadbalancer at %s %s %s:%s.\n %s" %
(__name__, src_dc, src_stack, vnf_src_name, vnf_src_interface, e))
return Response(u"%s: Error setting up the loadbalancer at %s %s %s:%s.\n %s" %
- (__name__, src_dc, src_stack, vnf_src_name, vnf_src_interface, e), status=500,
+ (__name__, src_dc, src_stack, vnf_src_name,
+ vnf_src_interface, e), status=500,
mimetype="application/json")
def delete(self, src_dc, src_stack, vnf_src_name, vnf_src_interface):
@@ -634,14 +671,16 @@
try:
# check src vnf/port
if src_stack != "floating":
- real_src = self._findName(src_dc, src_stack, vnf_src_name, vnf_src_interface)
- if type(real_src) is not tuple:
+ real_src = self._findName(
+ src_dc, src_stack, vnf_src_name, vnf_src_interface)
+ if not isinstance(real_src, tuple):
# something went wrong, real_src is a Response object
return real_src
container_src, interface_src = real_src
- self.api.manage.delete_loadbalancer(container_src, interface_src)
+ self.api.manage.delete_loadbalancer(
+ container_src, interface_src)
return Response(u"Loadbalancer deleted at %s:%s" % (vnf_src_name, vnf_src_interface),
status=200, mimetype="application/json")
else:
@@ -654,7 +693,8 @@
logging.exception(u"%s: Error deleting the loadbalancer at %s %s %s%s.\n %s" %
(__name__, src_dc, src_stack, vnf_src_name, vnf_src_interface, e))
return Response(u"%s: Error deleting the loadbalancer at %s %s %s%s." %
- (__name__, src_dc, src_stack, vnf_src_name, vnf_src_interface), status=500,
+ (__name__, src_dc, src_stack, vnf_src_name,
+ vnf_src_interface), status=500,
mimetype="application/json")
# Tries to find real container and port name according to heat template names
@@ -662,7 +702,8 @@
def _findName(self, dc, stack, vnf, port):
# search for datacenters
if dc not in self.api.manage.net.dcs:
- return Response(u"DC does not exist", status=500, mimetype="application/json")
+ return Response(u"DC does not exist", status=500,
+ mimetype="application/json")
dc_real = self.api.manage.net.dcs[dc]
# search for related OpenStackAPIs
api_real = None
@@ -671,14 +712,16 @@
if api.compute.dc == dc_real:
api_real = api
if api_real is None:
- return Response(u"OpenStackAPI does not exist", status=500, mimetype="application/json")
+ return Response(u"OpenStackAPI does not exist",
+ status=500, mimetype="application/json")
# search for stacks
stack_real = None
for stackObj in api_real.compute.stacks.values():
if stackObj.stack_name == stack:
stack_real = stackObj
if stack_real is None:
- return Response(u"Stack does not exist", status=500, mimetype="application/json")
+ return Response(u"Stack does not exist", status=500,
+ mimetype="application/json")
# search for servers
server_real = None
for server in stack_real.servers.values():
@@ -686,7 +729,8 @@
server_real = server
break
if server_real is None:
- return Response(u"VNF does not exist", status=500, mimetype="application/json")
+ return Response(u"VNF does not exist", status=500,
+ mimetype="application/json")
container_real = server_real.name
@@ -695,7 +739,8 @@
if port in server_real.port_names:
port_real = stack_real.ports[port]
if port_real is None:
- return Response(u"At least one Port does not exist", status=500, mimetype="application/json")
+ return Response(u"At least one Port does not exist",
+ status=500, mimetype="application/json")
interface_real = port_real.intf_name
@@ -733,16 +778,19 @@
if vnf_src_name != "floating":
# check if VNF exist
- if not self.api.manage.check_vnf_intf_pair(vnf_src_name, vnf_src_interface):
+ if not self.api.manage.check_vnf_intf_pair(
+ vnf_src_name, vnf_src_interface):
return Response(u"VNF %s or intfs %s does not exist" % (vnf_src_name, vnf_src_interface),
status=501,
mimetype="application/json")
- self.api.manage.add_loadbalancer(vnf_src_name, vnf_src_interface, lb_data=req)
+ self.api.manage.add_loadbalancer(
+ vnf_src_name, vnf_src_interface, lb_data=req)
return Response(u"Loadbalancer set up at %s:%s" % (vnf_src_name, vnf_src_interface),
status=200, mimetype="application/json")
else:
- cookie, floating_ip = self.api.manage.add_floating_lb(vnf_src_interface, lb_data=req)
+ cookie, floating_ip = self.api.manage.add_floating_lb(
+ vnf_src_interface, lb_data=req)
return Response(json.dumps({"cookie": "%d" % cookie, "floating_ip": "%s" % floating_ip}),
status=200, mimetype="application/json")
@@ -766,11 +814,13 @@
"""
# check if VNF exist
- if not self.api.manage.check_vnf_intf_pair(vnf_src_name, vnf_src_interface):
+ if not self.api.manage.check_vnf_intf_pair(
+ vnf_src_name, vnf_src_interface):
return Response(u"VNF %s or intfs %s does not exist" % (vnf_src_name, vnf_src_interface), status=501,
mimetype="application/json")
try:
- logging.debug("Deleting loadbalancer at %s: interface: %s" % (vnf_src_name, vnf_src_interface))
+ logging.debug("Deleting loadbalancer at %s: interface: %s" %
+ (vnf_src_name, vnf_src_interface))
net = self.api.manage.net
if vnf_src_name != "floating":
@@ -779,7 +829,8 @@
return Response(u"Source VNF or interface can not be found." % vnf_src_name,
status=404, mimetype="application/json")
- self.api.manage.delete_loadbalancer(vnf_src_name, vnf_src_interface)
+ self.api.manage.delete_loadbalancer(
+ vnf_src_name, vnf_src_interface)
return Response(u"Loadbalancer deleted at %s:%s" % (vnf_src_name, vnf_src_interface),
status=200, mimetype="application/json")
@@ -848,7 +899,8 @@
# with their unique keys
link = copy.copy(data)
for edge in link:
- # do not add any links to the floating switch to the topology!
+ # do not add any links to the floating switch
+ # to the topology!
if graph_node == "fs1":
continue
# the translator wants everything as a string!
diff --git a/src/emuvim/api/openstack/compute.py b/src/emuvim/api/openstack/compute.py
index b812953..6fc4c1b 100755
--- a/src/emuvim/api/openstack/compute.py
+++ b/src/emuvim/api/openstack/compute.py
@@ -1,33 +1,40 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from mininet.link import Link
-from resources import *
+from resources.instance_flavor import InstanceFlavor
+from resources.net import Net
+from resources.port import Port
+from resources.port_pair import PortPair
+from resources.port_pair_group import PortPairGroup
+from resources.flow_classifier import FlowClassifier
+from resources.port_chain import PortChain
+from resources.server import Server
+from resources.image import Image
+
from docker import DockerClient
import logging
import threading
@@ -89,7 +96,8 @@
for image in self.dcli.images.list():
if len(image.tags) > 0:
for t in image.tags:
- t = t.replace(":latest", "") # only use short tag names for OSM compatibility
+ # only use short tag names for OSM compatibility
+ t = t.replace(":latest", "")
if t not in self._images:
self._images[t] = Image(t)
return self._images
@@ -103,7 +111,8 @@
"""
if not self.check_stack(stack):
self.clean_broken_stack(stack)
- raise HeatApiStackInvalidException("Stack did not pass validity checks")
+ raise HeatApiStackInvalidException(
+ "Stack did not pass validity checks")
self.stacks[stack.id] = stack
def clean_broken_stack(self, stack):
@@ -132,7 +141,7 @@
for port_name in server.port_names:
if port_name not in stack.ports:
LOG.warning("Server %s of stack %s has a port named %s that is not known." %
- (server.name, stack.stack_name, port_name))
+ (server.name, stack.stack_name, port_name))
everything_ok = False
if server.image is None:
LOG.warning("Server %s holds no image." % (server.name))
@@ -143,7 +152,7 @@
for port in stack.ports.values():
if port.net_name not in stack.nets:
LOG.warning("Port %s of stack %s has a network named %s that is not known." %
- (port.name, stack.stack_name, port.net_name))
+ (port.name, stack.stack_name, port.net_name))
everything_ok = False
if port.intf_name is None:
LOG.warning("Port %s has no interface name." % (port.name))
@@ -160,11 +169,12 @@
break
if not found:
LOG.warning("Router %s of stack %s has a network named %s that is not known." %
- (router.name, stack.stack_name, subnet_name))
+ (router.name, stack.stack_name, subnet_name))
everything_ok = False
return everything_ok
- def add_flavor(self, name, cpu, memory, memory_unit, storage, storage_unit):
+ def add_flavor(self, name, cpu, memory,
+ memory_unit, storage, storage_unit):
"""
Adds a flavor to the stack.
@@ -181,7 +191,8 @@
:param storage_unit:
:type storage_unit: ``str``
"""
- flavor = InstanceFlavor(name, cpu, memory, memory_unit, storage, storage_unit)
+ flavor = InstanceFlavor(
+ name, cpu, memory, memory_unit, storage, storage_unit)
self.flavors[flavor.name] = flavor
return flavor
@@ -244,7 +255,8 @@
* *False*: else
:rtype: ``bool``
"""
- LOG.debug("updating stack {} with new_stack {}".format(old_stack_id, new_stack))
+ LOG.debug("updating stack {} with new_stack {}".format(
+ old_stack_id, new_stack))
if old_stack_id not in self.stacks:
return False
old_stack = self.stacks[old_stack_id]
@@ -281,24 +293,26 @@
# Remove unnecessary networks
for net in old_stack.nets.values():
- if not net.name in new_stack.nets:
+ if net.name not in new_stack.nets:
self.delete_network(net.id)
# Remove all unnecessary servers
for server in old_stack.servers.values():
if server.name in new_stack.servers:
- if not server.compare_attributes(new_stack.servers[server.name]):
+ if not server.compare_attributes(
+ new_stack.servers[server.name]):
self.stop_compute(server)
else:
# Delete unused and changed links
for port_name in server.port_names:
if port_name in old_stack.ports and port_name in new_stack.ports:
- if not old_stack.ports.get(port_name) == new_stack.ports.get(port_name):
+ if not old_stack.ports.get(
+ port_name) == new_stack.ports.get(port_name):
my_links = self.dc.net.links
for link in my_links:
if str(link.intf1) == old_stack.ports[port_name].intf_name and \
- str(link.intf1.ip) == \
- old_stack.ports[port_name].ip_address.split('/')[0]:
+ str(link.intf1.ip) == \
+ old_stack.ports[port_name].ip_address.split('/')[0]:
self._remove_link(server.name, link)
# Add changed link
@@ -367,15 +381,18 @@
if port.compare_attributes(old_port):
for net in new_stack.nets.values():
if net.name == port.net_name:
- if net.assign_ip_address(old_port.ip_address, port.name):
+ if net.assign_ip_address(
+ old_port.ip_address, port.name):
port.ip_address = old_port.ip_address
port.mac_address = old_port.mac_address
else:
- port.ip_address = net.get_new_ip_address(port.name)
+ port.ip_address = net.get_new_ip_address(
+ port.name)
for port in new_stack.ports.values():
for net in new_stack.nets.values():
- if port.net_name == net.name and not net.is_my_ip(port.ip_address, port.name):
+ if port.net_name == net.name and not net.is_my_ip(
+ port.ip_address, port.name):
port.ip_address = net.get_new_ip_address(port.name)
def update_subnet_cidr(self, old_stack, new_stack):
@@ -446,7 +463,8 @@
if port is not None:
network_dict['id'] = port.intf_name
network_dict['ip'] = port.ip_address
- network_dict[network_dict['id']] = self.find_network_by_name_or_id(port.net_name).name
+ network_dict[network_dict['id']] = self.find_network_by_name_or_id(
+ port.net_name).name
network.append(network_dict)
# default network dict
if len(network) < 1:
@@ -481,7 +499,8 @@
if "SON_EMU_CMD=" in env_var:
cmd = str(env_var.split("=")[1])
server.son_emu_command = cmd
- # execute command in new thread to ensure that GK is not blocked by VNF
+ # execute command in new thread to ensure that GK is not
+ # blocked by VNF
t = threading.Thread(target=c.cmdPrint, args=(cmd,))
t.daemon = True
t.start()
@@ -493,7 +512,8 @@
:param server: The server that should be removed
:type server: ``heat.resources.server``
"""
- LOG.debug("Stopping container %s with full name %s" % (server.name, server.full_name))
+ LOG.debug("Stopping container %s with full name %s" %
+ (server.name, server.full_name))
link_names = list()
for port_name in server.port_names:
prt = self.find_port_by_name_or_id(port_name)
@@ -502,7 +522,8 @@
my_links = self.dc.net.links
for link in my_links:
if str(link.intf1) in link_names:
- # Remove all self created links that connect the server to the main switch
+ # Remove all self created links that connect the server to the
+ # main switch
self._remove_link(server.name, link)
# Stop the server and the remaining connection to the datacenter switch
@@ -528,11 +549,13 @@
return self.computeUnits[name_or_id]
for server in self.computeUnits.values():
- if server.name == name_or_id or server.template_name == name_or_id or server.full_name == name_or_id:
+ if (server.name == name_or_id or
+ server.template_name == name_or_id or
+ server.full_name == name_or_id):
return server
- if (server.name == self._shorten_server_name(name_or_id)
- or server.template_name == self._shorten_server_name(name_or_id)
- or server.full_name == self._shorten_server_name(name_or_id)):
+ if (server.name == self._shorten_server_name(name_or_id) or
+ server.template_name == self._shorten_server_name(name_or_id) or
+ server.full_name == self._shorten_server_name(name_or_id)):
return server
return None
@@ -548,7 +571,8 @@
:return: Returns the created server.
:rtype: :class:`heat.resources.server`
"""
- if self.find_server_by_name_or_id(name) is not None and not stack_operation:
+ if self.find_server_by_name_or_id(
+ name) is not None and not stack_operation:
raise Exception("Server with name %s already exists." % name)
safe_name = self._shorten_server_name(name)
server = Server(safe_name)
@@ -570,7 +594,6 @@
LOG.info("Short server name: {}".format(h))
return name
-
def delete_server(self, server):
"""
Deletes the given server from the stack dictionary and the computeUnits dictionary.
@@ -625,8 +648,10 @@
:return: :class:`heat.resources.net`
"""
LOG.debug("Creating network with name %s" % name)
- if self.find_network_by_name_or_id(name) is not None and not stack_operation:
- LOG.warning("Creating network with name %s failed, as it already exists" % name)
+ if self.find_network_by_name_or_id(
+ name) is not None and not stack_operation:
+ LOG.warning(
+ "Creating network with name %s failed, as it already exists" % name)
raise Exception("Network with name %s already exists." % name)
network = Net(name)
network.id = str(uuid.uuid4())
@@ -643,7 +668,8 @@
"""
net = self.find_network_by_name_or_id(name_or_id)
if net is None:
- raise Exception("Network with name or id %s does not exists." % name_or_id)
+ raise Exception(
+ "Network with name or id %s does not exists." % name_or_id)
for stack in self.stacks.values():
stack.nets.pop(net.name, None)
@@ -664,7 +690,8 @@
"""
port = self.find_port_by_name_or_id(name)
if port is not None and not stack_operation:
- LOG.warning("Creating port with name %s failed, as it already exists" % name)
+ LOG.warning(
+ "Creating port with name %s failed, as it already exists" % name)
raise Exception("Port with name %s already exists." % name)
LOG.debug("Creating port with name %s" % name)
port = Port(name)
@@ -699,13 +726,14 @@
"""
port = self.find_port_by_name_or_id(name_or_id)
if port is None:
- LOG.warning("Port with name or id %s does not exist. Can't delete it." % name_or_id)
+ LOG.warning(
+ "Port with name or id %s does not exist. Can't delete it." % name_or_id)
return
my_links = self.dc.net.links
for link in my_links:
if str(link.intf1) == port.intf_name and \
- str(link.intf1.ip) == port.ip_address.split('/')[0]:
+ str(link.intf1.ip) == port.ip_address.split('/')[0]:
self._remove_link(link.intf1.node.name, link)
break
@@ -727,7 +755,8 @@
"""
port_pair = self.find_port_pair_by_name_or_id(name)
if port_pair is not None and not stack_operation:
- logging.warning("Creating port pair with name %s failed, as it already exists" % name)
+ logging.warning(
+ "Creating port pair with name %s failed, as it already exists" % name)
raise Exception("Port pair with name %s already exists." % name)
logging.debug("Creating port pair with name %s" % name)
port_pair = PortPair(name)
@@ -761,7 +790,8 @@
"""
port_pair = self.find_port_pair_by_name_or_id(name_or_id)
if port_pair is None:
- raise Exception("Port pair with name or id %s does not exists." % name_or_id)
+ raise Exception(
+ "Port pair with name or id %s does not exists." % name_or_id)
self.port_pairs.pop(port_pair.id, None)
@@ -779,8 +809,10 @@
"""
port_pair_group = self.find_port_pair_group_by_name_or_id(name)
if port_pair_group is not None and not stack_operation:
- logging.warning("Creating port pair group with name %s failed, as it already exists" % name)
- raise Exception("Port pair group with name %s already exists." % name)
+ logging.warning(
+ "Creating port pair group with name %s failed, as it already exists" % name)
+ raise Exception(
+ "Port pair group with name %s already exists." % name)
logging.debug("Creating port pair group with name %s" % name)
port_pair_group = PortPairGroup(name)
if not stack_operation:
@@ -813,7 +845,8 @@
"""
port_pair_group = self.find_port_pair_group_by_name_or_id(name_or_id)
if port_pair_group is None:
- raise Exception("Port pair with name or id %s does not exists." % name_or_id)
+ raise Exception(
+ "Port pair with name or id %s does not exists." % name_or_id)
self.port_pair_groups.pop(port_pair_group.id, None)
@@ -831,7 +864,8 @@
"""
port_chain = self.find_port_chain_by_name_or_id(name)
if port_chain is not None and not stack_operation:
- logging.warning("Creating port chain with name %s failed, as it already exists" % name)
+ logging.warning(
+ "Creating port chain with name %s failed, as it already exists" % name)
raise Exception("Port chain with name %s already exists." % name)
logging.debug("Creating port chain with name %s" % name)
port_chain = PortChain(name)
@@ -865,7 +899,8 @@
port_chain = self.find_port_chain_by_name_or_id(name_or_id)
port_chain.uninstall(self)
if port_chain is None:
- raise Exception("Port chain with name or id %s does not exists." % name_or_id)
+ raise Exception(
+ "Port chain with name or id %s does not exists." % name_or_id)
self.port_chains.pop(port_chain.id, None)
@@ -883,8 +918,10 @@
"""
flow_classifier = self.find_flow_classifier_by_name_or_id(name)
if flow_classifier is not None and not stack_operation:
- logging.warning("Creating flow classifier with name %s failed, as it already exists" % name)
- raise Exception("Flow classifier with name %s already exists." % name)
+ logging.warning(
+ "Creating flow classifier with name %s failed, as it already exists" % name)
+ raise Exception(
+ "Flow classifier with name %s already exists." % name)
logging.debug("Creating flow classifier with name %s" % name)
flow_classifier = FlowClassifier(name)
if not stack_operation:
@@ -917,7 +954,8 @@
"""
flow_classifier = self.find_flow_classifier_by_name_or_id(name_or_id)
if flow_classifier is None:
- raise Exception("Flow classifier with name or id %s does not exists." % name_or_id)
+ raise Exception(
+ "Flow classifier with name or id %s does not exists." % name_or_id)
self.flow_classifiers.pop(flow_classifier.id, None)
diff --git a/src/emuvim/api/openstack/docker_util.py b/src/emuvim/api/openstack/docker_util.py
index a93e75e..f32d971 100755
--- a/src/emuvim/api/openstack/docker_util.py
+++ b/src/emuvim/api/openstack/docker_util.py
@@ -1,31 +1,29 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-from docker import DockerClient, APIClient
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
+from docker import APIClient
import time
import re
@@ -64,7 +62,8 @@
cpu_usage = 0
for number in numbers:
cpu_usage += number
- return {'CPU_used': cpu_usage, 'CPU_used_systime': sys_time, 'CPU_cores': len(numbers)}
+ return {'CPU_used': cpu_usage,
+ 'CPU_used_systime': sys_time, 'CPU_cores': len(numbers)}
def docker_mem_used(container_id):
@@ -123,7 +122,8 @@
out_dict = dict()
out_dict['MEM_used'] = docker_mem_used(container_id)
out_dict['MEM_limit'] = docker_max_mem(container_id)
- out_dict['MEM_%'] = float(out_dict['MEM_used']) / float(out_dict['MEM_limit'])
+ out_dict['MEM_%'] = float(out_dict['MEM_used']) / \
+ float(out_dict['MEM_limit'])
return out_dict
@@ -218,9 +218,12 @@
second_disk_io = docker_block_rw(container_id)
# Disk access
- time_div = (int(second_disk_io['BLOCK_systime']) - int(first_disk_io['BLOCK_systime']))
- read_div = int(second_disk_io['BLOCK_read']) - int(first_disk_io['BLOCK_read'])
- write_div = int(second_disk_io['BLOCK_write']) - int(first_disk_io['BLOCK_write'])
+ time_div = (int(second_disk_io['BLOCK_systime']
+ ) - int(first_disk_io['BLOCK_systime']))
+ read_div = int(second_disk_io['BLOCK_read']) - \
+ int(first_disk_io['BLOCK_read'])
+ write_div = int(second_disk_io['BLOCK_write']) - \
+ int(first_disk_io['BLOCK_write'])
out_dict = {'BLOCK_read/s': int(read_div * 1000000000 / float(time_div) + 0.5),
'BLOCK_write/s': int(write_div * 1000000000 / float(time_div) + 0.5)}
@@ -232,7 +235,10 @@
'NET_out/s': int(out_div * 1000000000 / float(time_div) + 0.5)})
# CPU utilization
- time_div = (int(second_cpu_usage['CPU_used_systime']) - int(first_cpu_usage['CPU_used_systime']))
- usage_div = int(second_cpu_usage['CPU_used']) - int(first_cpu_usage['CPU_used'])
- out_dict.update({'CPU_%': usage_div / float(time_div), 'CPU_cores': first_cpu_usage['CPU_cores']})
+ time_div = (int(second_cpu_usage['CPU_used_systime']
+ ) - int(first_cpu_usage['CPU_used_systime']))
+ usage_div = int(second_cpu_usage['CPU_used']) - \
+ int(first_cpu_usage['CPU_used'])
+ out_dict.update({'CPU_%': usage_div / float(time_div),
+ 'CPU_cores': first_cpu_usage['CPU_cores']})
return out_dict
diff --git a/src/emuvim/api/openstack/heat_parser.py b/src/emuvim/api/openstack/heat_parser.py
index 9bf80ee..ffcaa0a 100755
--- a/src/emuvim/api/openstack/heat_parser.py
+++ b/src/emuvim/api/openstack/heat_parser.py
@@ -1,32 +1,30 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from __future__ import print_function # TODO remove when print is no longer needed for debugging
-from resources import *
+from resources.router import Router
from datetime import datetime
import re
import sys
@@ -68,7 +66,8 @@
* *False*: Else
:rtype: ``bool``
"""
- if not self.check_template_version(str(input_dict['heat_template_version'])):
+ if not self.check_template_version(
+ str(input_dict['heat_template_version'])):
print('Unsupported template version: ' + input_dict['heat_template_version'], file=sys.stderr)
return False
@@ -81,15 +80,19 @@
self.bufferResource = list()
for resource in self.resources.values():
- self.handle_resource(resource, stack, dc_label, stack_update=stack_update)
+ self.handle_resource(resource, stack, dc_label,
+ stack_update=stack_update)
- # This loop tries to create all classes which had unresolved dependencies.
+ # This loop tries to create all classes which had unresolved
+ # dependencies.
unresolved_resources_last_round = len(self.bufferResource) + 1
- while len(self.bufferResource) > 0 and unresolved_resources_last_round > len(self.bufferResource):
+ while len(self.bufferResource) > 0 and unresolved_resources_last_round > len(
+ self.bufferResource):
unresolved_resources_last_round = len(self.bufferResource)
number_of_items = len(self.bufferResource)
while number_of_items > 0:
- self.handle_resource(self.bufferResource.pop(0), stack, dc_label, stack_update=stack_update)
+ self.handle_resource(self.bufferResource.pop(
+ 0), stack, dc_label, stack_update=stack_update)
number_of_items -= 1
if len(self.bufferResource) > 0:
@@ -123,7 +126,8 @@
try:
net_name = resource['properties']['name']
if net_name not in stack.nets:
- stack.nets[net_name] = self.compute.create_network(net_name, True)
+ stack.nets[net_name] = self.compute.create_network(
+ net_name, True)
except Exception as e:
LOG.warning('Could not create Net: ' + e.message)
@@ -141,7 +145,8 @@
net.subnet_name = resource['properties']['name']
if 'gateway_ip' in resource['properties']:
net.gateway_ip = resource['properties']['gateway_ip']
- net.subnet_id = resource['properties'].get('id', str(uuid.uuid4()))
+ net.subnet_id = resource['properties'].get(
+ 'id', str(uuid.uuid4()))
net.subnet_creation_time = str(datetime.now())
if not stack_update:
net.set_cidr(IP.get_new_cidr(net.subnet_id))
@@ -158,8 +163,10 @@
else:
port = stack.ports[port_name]
- if str(resource['properties']['network']['get_resource']) in stack.nets:
- net = stack.nets[resource['properties']['network']['get_resource']]
+ if str(resource['properties']['network']
+ ['get_resource']) in stack.nets:
+ net = stack.nets[resource['properties']
+ ['network']['get_resource']]
if net.subnet_id is not None:
port.net_name = net.name
port.ip_address = net.get_new_ip_address(port.name)
@@ -171,20 +178,24 @@
if 'OS::Nova::Server' in resource['type']:
try:
- compute_name = str(dc_label) + '_' + str(stack.stack_name) + '_' + str(resource['properties']['name'])
+ compute_name = str(dc_label) + '_' + str(stack.stack_name) + \
+ '_' + str(resource['properties']['name'])
shortened_name = str(dc_label) + '_' + str(stack.stack_name) + '_' + \
- self.shorten_server_name(str(resource['properties']['name']), stack)
+ self.shorten_server_name(
+ str(resource['properties']['name']), stack)
nw_list = resource['properties']['networks']
if shortened_name not in stack.servers:
- server = self.compute.create_server(shortened_name, stack_update)
+ server = self.compute.create_server(
+ shortened_name, stack_update)
stack.servers[shortened_name] = server
else:
server = stack.servers[shortened_name]
server.full_name = compute_name
server.template_name = str(resource['properties']['name'])
- server.command = resource['properties'].get('command', '/bin/sh')
+ server.command = resource['properties'].get(
+ 'command', '/bin/sh')
server.image = resource['properties']['image']
server.flavor = resource['properties']['flavor']
@@ -194,7 +205,8 @@
# we don't know which network it belongs to yet, but the resource will appear later in a valid
# template
if port_name not in stack.ports:
- stack.ports[port_name] = self.compute.create_port(port_name, stack_update)
+ stack.ports[port_name] = self.compute.create_port(
+ port_name, stack_update)
server.port_names.append(port_name)
return
except Exception as e:
@@ -219,7 +231,8 @@
stack.routers[router_name].add_subnet(subnet_name)
return
except Exception as e:
- LOG.warning('Could not create RouterInterface: ' + e.__repr__())
+ LOG.warning(
+ 'Could not create RouterInterface: ' + e.__repr__())
self.bufferResource.append(resource)
return
@@ -228,7 +241,8 @@
port_name = resource['properties']['port_id']['get_resource']
floating_network_id = resource['properties']['floating_network_id']
if port_name not in stack.ports:
- stack.ports[port_name] = self.compute.create_port(port_name, stack_update)
+ stack.ports[port_name] = self.compute.create_port(
+ port_name, stack_update)
stack.ports[port_name].floating_ip = floating_network_id
except Exception as e:
@@ -247,14 +261,17 @@
if 'OS::Heat::ResourceGroup' in resource['type']:
try:
embedded_resource = resource['properties']['resource_def']
- LOG.debug("Found resource in resource group: {}".format(embedded_resource))
+ LOG.debug("Found resource in resource group: {}".format(
+ embedded_resource))
# recursively parse embedded resource
- self.handle_resource(embedded_resource, stack, dc_label, stack_update)
+ self.handle_resource(
+ embedded_resource, stack, dc_label, stack_update)
except Exception as e:
print('Could not create Router: ' + e.message)
return
- LOG.warning('Could not determine resource type: {}'.format(resource['type']))
+ LOG.warning(
+ 'Could not determine resource type: {}'.format(resource['type']))
return
def shorten_server_name(self, server_name, stack):
@@ -310,8 +327,8 @@
if year < 2015:
return False
if year == 2015:
- if month < 04:
+ if month < 0o4:
return False
- if month == 04 and day < 30:
+ if month == 0o4 and day < 30:
return False
return True
diff --git a/src/emuvim/api/openstack/helper.py b/src/emuvim/api/openstack/helper.py
index 09a51f6..c7ef69b 100644
--- a/src/emuvim/api/openstack/helper.py
+++ b/src/emuvim/api/openstack/helper.py
@@ -1,38 +1,37 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from urlparse import urlparse
import logging
LOG = logging.getLogger("api.openstack.helper")
+
def get_host(r):
try:
return urlparse(r.base_url).hostname
- except:
+ except BaseException:
LOG.error("Could not get host part of request URL.")
return "0.0.0.0"
diff --git a/src/emuvim/api/openstack/ip_handler.py b/src/emuvim/api/openstack/ip_handler.py
index 208a910..9138342 100755
--- a/src/emuvim/api/openstack/ip_handler.py
+++ b/src/emuvim/api/openstack/ip_handler.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from resources.net import Net
import threading
@@ -128,7 +126,7 @@
int_ip = Net.cidr_2_int(cidr)
- if not int_ip in __issued_ips:
+ if int_ip not in __issued_ips:
return False
if __issued_ips[int_ip] == uuid:
diff --git a/src/emuvim/api/openstack/manage.py b/src/emuvim/api/openstack/manage.py
index 5405e78..083550e 100755
--- a/src/emuvim/api/openstack/manage.py
+++ b/src/emuvim/api/openstack/manage.py
@@ -1,38 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-"""Openstack manage component of PG Sandman.
-
-.. module:: manage
- :synopsis: Module containing the OpenstackManage class.
-.. moduleauthor: PG Sandman
-
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
import threading
import uuid
@@ -40,7 +30,8 @@
import chain_api
import json
import random
-from emuvim.api.openstack.resources import Net, Port
+from emuvim.api.openstack.resources.net import Net
+from emuvim.api.openstack.resources.port import Port
from mininet.node import OVSSwitch, RemoteController, Node
@@ -71,7 +62,8 @@
self.ip = ip
self.port = port
self._net = None
- # to keep track which src_vnf(input port on the switch) handles a load balancer
+ # to keep track which src_vnf(input port on the switch) handles a load
+ # balancer
self.lb_flow_cookies = dict()
self.chain_flow_cookies = dict()
@@ -83,7 +75,8 @@
# debug and to maintain
self.flow_groups = dict()
- # we want one global chain api. this should not be datacenter dependent!
+ # we want one global chain api. this should not be datacenter
+ # dependent!
self.chain = chain_api.ChainApi(ip, port, self)
self.thread = threading.Thread(target=self.chain._start_flask, args=())
self.thread.daemon = True
@@ -128,7 +121,7 @@
# create a port for the host
port = Port("root-port")
- #port.id = str(uuid.uuid4())
+ # port.id = str(uuid.uuid4())
port.net_name = fn.name
# get next free ip
@@ -137,16 +130,19 @@
# floating ip network setup
# wierd way of getting a datacenter object
first_dc = self.net.dcs.values()[0]
- # set a dpid for the switch. for this we have to get the id of the next possible dc
- self.floating_switch = self.net.addSwitch("fs1", dpid=hex(first_dc._get_next_dc_dpid())[2:])
+ # set a dpid for the switch. for this we have to get the id of the
+ # next possible dc
+ self.floating_switch = self.net.addSwitch(
+ "fs1", dpid=hex(first_dc._get_next_dc_dpid())[2:])
# this is the interface appearing on the physical host
self.floating_root = Node('root', inNamespace=False)
self.net.hosts.append(self.floating_root)
self.net.nameToNode['root'] = self.floating_root
- self.floating_intf = self.net.addLink(self.floating_root, self.floating_switch).intf1
+ self.floating_intf = self.net.addLink(
+ self.floating_root, self.floating_switch).intf1
self.floating_root.setIP(root_ip, intf=self.floating_intf)
- self.floating_nodes[(self.floating_root.name, root_ip)] = self.floating_root
-
+ self.floating_nodes[(self.floating_root.name,
+ root_ip)] = self.floating_root
def stop_floating_network(self):
self._net = None
@@ -235,16 +231,21 @@
vnf_dst_interface = kwargs.get('vnf_dst_interface')
layer2 = kwargs.get('layer2', True)
match = kwargs.get('match')
- flow = (vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface)
+ flow = (vnf_src_name, vnf_src_interface,
+ vnf_dst_name, vnf_dst_interface)
if flow in self.chain_flow_cookies:
- raise Exception("There is already a chain at the specified src/dst pair!")
- # set up a layer 2 chain, this allows multiple chains for the same interface
+ raise Exception(
+ "There is already a chain at the specified src/dst pair!")
+ # set up a layer 2 chain, this allows multiple chains for the same
+ # interface
src_node = self.net.getNodeByName(vnf_src_name)
dst_node = self.net.getNodeByName(vnf_dst_name)
dst_intf = dst_node.intf(vnf_dst_interface)
if layer2:
- switch, inport = self._get_connected_switch_data(vnf_src_name, vnf_src_interface)
- self.setup_arp_reply_at(switch, inport, dst_intf.IP(), dst_intf.MAC())
+ switch, inport = self._get_connected_switch_data(
+ vnf_src_name, vnf_src_interface)
+ self.setup_arp_reply_at(
+ switch, inport, dst_intf.IP(), dst_intf.MAC())
if isinstance(match, str):
match += ",dl_dst=%s" % dst_intf.MAC()
else:
@@ -252,7 +253,7 @@
cookie = kwargs.get('cookie', self.get_cookie())
self.cookies.add(cookie)
- c = self.net.setChain(
+ self.net.setChain(
vnf_src_name, vnf_dst_name,
vnf_src_interface=vnf_src_interface,
vnf_dst_interface=vnf_dst_interface,
@@ -263,7 +264,8 @@
cookie=cookie,
path=kwargs.get('path'))
- # to keep this logic seperate of the core son-emu do the housekeeping here
+ # to keep this logic seperate of the core son-emu do the
+ # housekeeping here
data = dict()
data["src_vnf"] = vnf_src_name
data["src_intf"] = vnf_src_interface
@@ -278,15 +280,18 @@
vnf_dst_interface)[0]
# add route to dst ip to this interface
- # this might block on containers that are still setting up, so start a new thread
+ # this might block on containers that are still setting up, so
+ # start a new thread
if not kwargs.get('no_route'):
# son_emu does not like concurrent commands for a container so we need to lock this if multiple chains
# on the same interface are created
- src_node.setHostRoute(dst_node.intf(vnf_dst_interface).IP(), vnf_src_interface)
+ src_node.setHostRoute(dst_node.intf(
+ vnf_dst_interface).IP(), vnf_src_interface)
try:
- son_emu_data = json.loads(self.get_son_emu_chain_data(vnf_src_name))
- except:
+ son_emu_data = json.loads(
+ self.get_son_emu_chain_data(vnf_src_name))
+ except BaseException:
son_emu_data = dict()
if "son_emu_data" not in son_emu_data:
son_emu_data["son_emu_data"] = dict()
@@ -294,7 +299,8 @@
son_emu_data["son_emu_data"]["interfaces"] = dict()
if vnf_src_interface not in son_emu_data["son_emu_data"]["interfaces"]:
son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface] = list()
- son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface].append(dst_intf.IP())
+ son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface].append(
+ dst_intf.IP())
self.set_son_emu_chain_data(vnf_src_name, son_emu_data)
@@ -356,12 +362,14 @@
:param data: Raw data to store on the node.
:type data: ``str``
"""
- self.net.getNodeByName(vnf_name).cmd("echo \'%s\' > /tmp/son_emu_data.json" % json.dumps(data))
+ self.net.getNodeByName(vnf_name).cmd(
+ "echo \'%s\' > /tmp/son_emu_data.json" % json.dumps(data))
ip_list = []
for intf in data['son_emu_data']['interfaces'].values():
ip_list.extend(intf)
- self.net.getNodeByName(vnf_name).cmd("echo \'%s\' > /tmp/son_emu_data" % "\n".join(ip_list))
+ self.net.getNodeByName(vnf_name).cmd(
+ "echo \'%s\' > /tmp/son_emu_data" % "\n".join(ip_list))
def get_son_emu_chain_data(self, vnf_name):
"""
@@ -372,7 +380,8 @@
:return: raw data stored on the node
:rtype: ``str``
"""
- return self.net.getNodeByName(vnf_name).cmd("cat /tmp/son_emu_data.json")
+ return self.net.getNodeByName(vnf_name).cmd(
+ "cat /tmp/son_emu_data.json")
def _get_connected_switch_data(self, vnf_name, vnf_interface):
"""
@@ -390,8 +399,8 @@
link_dict = self.net.DCNetwork_graph[vnf_name][connected_sw]
for link in link_dict:
if (link_dict[link]['src_port_id'] == vnf_interface or
- link_dict[link][
- 'src_port_name'] == vnf_interface):
+ link_dict[link][
+ 'src_port_name'] == vnf_interface):
# found the right link and connected switch
src_sw = connected_sw
src_sw_inport_nr = link_dict[link]['dst_port_nr']
@@ -415,7 +424,8 @@
:return: path, src_sw, dst_sw
:rtype: ``list``, ``str``, ``str``
"""
- # modified version of the _chainAddFlow from emuvim.dcemulator.net._chainAddFlow
+ # modified version of the _chainAddFlow from
+ # emuvim.dcemulator.net._chainAddFlow
src_sw = None
dst_sw = None
logging.debug("Find shortest path from vnf %s to %s",
@@ -425,8 +435,8 @@
link_dict = self.net.DCNetwork_graph[src_vnf][connected_sw]
for link in link_dict:
if (link_dict[link]['src_port_id'] == src_vnf_intf or
- link_dict[link][
- 'src_port_name'] == src_vnf_intf):
+ link_dict[link][
+ 'src_port_name'] == src_vnf_intf):
# found the right link and connected switch
src_sw = connected_sw
break
@@ -435,8 +445,8 @@
link_dict = self.net.DCNetwork_graph[connected_sw][dst_vnf]
for link in link_dict:
if link_dict[link]['dst_port_id'] == dst_vnf_intf or \
- link_dict[link][
- 'dst_port_name'] == dst_vnf_intf:
+ link_dict[link][
+ 'dst_port_name'] == dst_vnf_intf:
# found the right link and connected
dst_sw = connected_sw
break
@@ -447,16 +457,18 @@
# returns the first found shortest path
# if all shortest paths are wanted, use: all_shortest_paths
path = nx.shortest_path(self.net.DCNetwork_graph, src_sw, dst_sw)
- except:
+ except BaseException:
logging.exception("No path could be found between {0} and {1} using src_sw={2} and dst_sw={3}".format(
src_vnf, dst_vnf, src_sw, dst_sw))
logging.debug("Graph nodes: %r" % self.net.DCNetwork_graph.nodes())
logging.debug("Graph edges: %r" % self.net.DCNetwork_graph.edges())
for e, v in self.net.DCNetwork_graph.edges():
logging.debug("%r" % self.net.DCNetwork_graph[e][v])
- return "No path could be found between {0} and {1}".format(src_vnf, dst_vnf)
+ return "No path could be found between {0} and {1}".format(
+ src_vnf, dst_vnf)
- logging.info("Shortest path between {0} and {1}: {2}".format(src_vnf, dst_vnf, path))
+ logging.info("Shortest path between {0} and {1}: {2}".format(
+ src_vnf, dst_vnf, path))
return path, src_sw, dst_sw
def add_loadbalancer(self, src_vnf_name, src_vnf_interface, lb_data):
@@ -483,12 +495,15 @@
custom_paths = lb_data.get('path', dict())
dest_vnf_outport_nrs = list()
- logging.debug("Call to add_loadbalancer at %s intfs:%s" % (src_vnf_name, src_vnf_interface))
+ logging.debug("Call to add_loadbalancer at %s intfs:%s" %
+ (src_vnf_name, src_vnf_interface))
if not self.check_vnf_intf_pair(src_vnf_name, src_vnf_interface):
- raise Exception(u"Source VNF %s or intfs %s does not exist" % (src_vnf_name, src_vnf_interface))
+ raise Exception(u"Source VNF %s or intfs %s does not exist" % (
+ src_vnf_name, src_vnf_interface))
- # find the switch belonging to the source interface, as well as the inport nr
+ # find the switch belonging to the source interface, as well as the
+ # inport nr
for connected_sw in net.DCNetwork_graph.neighbors(src_vnf_name):
link_dict = net.DCNetwork_graph[src_vnf_name][connected_sw]
for link in link_dict:
@@ -508,19 +523,18 @@
link_dict = net.DCNetwork_graph[vnf_name][connected_sw]
for link in link_dict:
if link_dict[link]['src_port_name'] == dest_intfs_mapping[vnf_name]:
- dest_vnf_outport_nrs.append(int(link_dict[link]['dst_port_nr']))
+ dest_vnf_outport_nrs.append(
+ int(link_dict[link]['dst_port_nr']))
# get first switch
if (src_vnf_name, src_vnf_interface) not in self.lb_flow_cookies:
self.lb_flow_cookies[(src_vnf_name, src_vnf_interface)] = list()
- src_intf = None
src_ip = None
src_mac = None
for intf in net[src_vnf_name].intfs.values():
if intf.name == src_vnf_interface:
src_mac = intf.mac
src_ip = intf.ip
- src_intf = intf
# set up paths for each destination vnf individually
index = 0
@@ -536,7 +550,8 @@
data["cookie"] = cookie
# lb mac for src -> target connections
- lb_mac = "31:33:70:%02x:%02x:%02x" % (random.randint(0, 255),random.randint(0, 255),random.randint(0, 255))
+ lb_mac = "31:33:70:%02x:%02x:%02x" % (random.randint(
+ 0, 255), random.randint(0, 255), random.randint(0, 255))
# calculate lb ip as src_intf.ip +1
octets = src_ip.split('.')
@@ -544,8 +559,10 @@
plus_one = '.'.join(octets)
# set up arp reply as well as add the route to the interface
- self.setup_arp_reply_at(src_sw, src_sw_inport_nr, plus_one, lb_mac, cookie=cookie)
- net.getNodeByName(src_vnf_name).setHostRoute(plus_one, src_vnf_interface)
+ self.setup_arp_reply_at(src_sw, src_sw_inport_nr,
+ plus_one, lb_mac, cookie=cookie)
+ net.getNodeByName(src_vnf_name).setHostRoute(
+ plus_one, src_vnf_interface)
for dst_vnf_name, dst_vnf_interface in dest_intfs_mapping.items():
path, src_sw, dst_sw = self._get_path(src_vnf_name, dst_vnf_name,
@@ -556,14 +573,17 @@
if custom_paths is not None and dst_vnf_name in custom_paths:
if dst_vnf_interface in custom_paths[dst_vnf_name]:
path = custom_paths[dst_vnf_name][dst_vnf_interface]
- logging.debug("Taking custom path from %s to %s: %s" % (src_vnf_name, dst_vnf_name, path))
+ logging.debug("Taking custom path from %s to %s: %s" % (
+ src_vnf_name, dst_vnf_name, path))
if not self.check_vnf_intf_pair(dst_vnf_name, dst_vnf_interface):
self.delete_loadbalancer(src_vnf_name, src_vnf_interface)
- raise Exception(u"VNF %s or intfs %s does not exist" % (dst_vnf_name, dst_vnf_interface))
+ raise Exception(u"VNF %s or intfs %s does not exist" %
+ (dst_vnf_name, dst_vnf_interface))
if isinstance(path, dict):
self.delete_loadbalancer(src_vnf_name, src_vnf_interface)
- raise Exception(u"Can not find a valid path. Are you specifying the right interfaces?.")
+ raise Exception(
+ u"Can not find a valid path. Are you specifying the right interfaces?.")
target_mac = "fa:17:00:03:13:37"
target_ip = "0.0.0.0"
@@ -575,8 +595,9 @@
current_hop = src_sw
switch_inport_nr = src_sw_inport_nr
- #self.setup_arp_reply_at(src_sw, src_sw_inport_nr, target_ip, target_mac, cookie=cookie)
- net.getNodeByName(dst_vnf_name).setHostRoute(src_ip, dst_vnf_interface)
+ # self.setup_arp_reply_at(src_sw, src_sw_inport_nr, target_ip, target_mac, cookie=cookie)
+ net.getNodeByName(dst_vnf_name).setHostRoute(
+ src_ip, dst_vnf_interface)
# choose free vlan if path contains more than 1 switch
if len(path) > 1:
@@ -607,16 +628,20 @@
switch_outport_nr = dst_sw_outport_nr
logging.info("end node reached: {0}".format(dst_vnf_name))
elif not isinstance(next_node, OVSSwitch):
- logging.info("Next node: {0} is not a switch".format(next_hop))
+ logging.info(
+ "Next node: {0} is not a switch".format(next_hop))
return "Next node: {0} is not a switch".format(next_hop)
else:
# take first link between switches by default
index_edge_out = 0
switch_outport_nr = net.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']
- cmd = 'priority=1,in_port=%s,cookie=%s' % (switch_inport_nr, cookie)
- cmd_back = 'priority=1,in_port=%s,cookie=%s' % (switch_outport_nr, cookie)
- # if a vlan is picked, the connection is routed through multiple switches
+ cmd = 'priority=1,in_port=%s,cookie=%s' % (
+ switch_inport_nr, cookie)
+ cmd_back = 'priority=1,in_port=%s,cookie=%s' % (
+ switch_outport_nr, cookie)
+ # if a vlan is picked, the connection is routed through
+ # multiple switches
if vlan is not None:
if path.index(current_hop) == 0: # first node
# flow #index set up
@@ -642,8 +667,10 @@
# remove any vlan tags
cmd += ',dl_vlan=%s' % vlan
cmd += ',actions=pop_vlan,output:%s' % switch_outport_nr
- # set up arp replys at the port so the dst nodes know the src
- self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
+ # set up arp replys at the port so the dst nodes know
+ # the src
+ self.setup_arp_reply_at(
+ current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
# reverse route
cmd_back = 'in_port=%s' % switch_outport_nr
@@ -663,8 +690,10 @@
cmd += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
cmd_back += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
else:
- cmd += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_outport_nr)
- cmd_back += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_inport_nr)
+ cmd += ',dl_vlan=%s,actions=output:%s' % (
+ vlan, switch_outport_nr)
+ cmd_back += ',dl_vlan=%s,actions=output:%s' % (
+ vlan, switch_inport_nr)
# output the packet at the correct outport
else:
cmd = 'in_port=%s' % src_sw_inport_nr
@@ -686,7 +715,8 @@
cmd_back += ',set_field:%s->ip_src' % plus_one
cmd_back += ',output:%s' % src_sw_inport_nr
- self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
+ self.setup_arp_reply_at(
+ current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
# excecute the command on the target switch
logging.debug(cmd)
@@ -703,7 +733,8 @@
# advance to next destination
index += 1
- # set up the actual load balancing rule as a multipath on the very first switch
+ # set up the actual load balancing rule as a multipath on the very
+ # first switch
cmd = '"in_port=%s' % src_sw_inport_nr
cmd += ',cookie=%s' % (cookie)
cmd += ',ip'
@@ -713,7 +744,8 @@
# load balance modulo n over all dest interfaces
# TODO: in newer openvswitch implementations this should be changed to symmetric_l3l4+udp
# to balance any kind of traffic
- cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(dest_intfs_mapping)
+ cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(
+ dest_intfs_mapping)
# reuse the cookie as table entry as it will be unique
cmd += ',resubmit(, %s)"' % cookie
@@ -758,10 +790,12 @@
link_dict = net.DCNetwork_graph[vnf_name][connected_sw]
for link in link_dict:
if link_dict[link]['src_port_name'] == dest_intfs_mapping[vnf_name]:
- dest_vnf_outport_nrs.append(int(link_dict[link]['dst_port_nr']))
+ dest_vnf_outport_nrs.append(
+ int(link_dict[link]['dst_port_nr']))
if len(dest_vnf_outport_nrs) == 0:
- raise Exception("There are no paths specified for the loadbalancer")
+ raise Exception(
+ "There are no paths specified for the loadbalancer")
src_ip = self.floating_intf.IP()
src_mac = self.floating_intf.MAC()
@@ -769,7 +803,8 @@
index = 0
cookie = self.get_cookie()
main_cmd = "add-flow -OOpenFlow13"
- floating_ip = self.floating_network.get_new_ip_address("floating-ip").split("/")[0]
+ floating_ip = self.floating_network.get_new_ip_address(
+ "floating-ip").split("/")[0]
for dst_vnf_name, dst_vnf_interface in dest_intfs_mapping.items():
path = None
@@ -778,17 +813,20 @@
if custom_paths is not None and dst_vnf_name in custom_paths:
if dst_vnf_interface in custom_paths[dst_vnf_name]:
path = custom_paths[dst_vnf_name][dst_vnf_interface]
- logging.debug("Taking custom path to %s: %s" % (dst_vnf_name, path))
+ logging.debug("Taking custom path to %s: %s" %
+ (dst_vnf_name, path))
else:
if datacenter not in self.floating_links:
self.floating_links[datacenter] = \
net.addLink(self.floating_switch, datacenter)
path = \
- self._get_path(self.floating_root.name, dst_vnf_name, self.floating_intf.name, dst_vnf_interface)[0]
+ self._get_path(self.floating_root.name, dst_vnf_name,
+ self.floating_intf.name, dst_vnf_interface)[0]
if isinstance(path, dict):
self.delete_flow_by_cookie(cookie)
- raise Exception(u"Can not find a valid path. Are you specifying the right interfaces?.")
+ raise Exception(
+ u"Can not find a valid path. Are you specifying the right interfaces?.")
intf = net[dst_vnf_name].nameToIntf[dst_vnf_interface]
target_mac = str(intf.MAC())
@@ -812,16 +850,20 @@
switch_outport_nr = dst_sw_outport_nr
logging.info("end node reached: {0}".format(dst_vnf_name))
elif not isinstance(next_node, OVSSwitch):
- logging.info("Next node: {0} is not a switch".format(next_hop))
+ logging.info(
+ "Next node: {0} is not a switch".format(next_hop))
return "Next node: {0} is not a switch".format(next_hop)
else:
# take first link between switches by default
index_edge_out = 0
switch_outport_nr = net.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']
- # default filters, just overwritten on the first node and last node
- cmd = 'priority=1,in_port=%s,cookie=%s' % (switch_inport_nr, cookie)
- cmd_back = 'priority=1,in_port=%s,cookie=%s' % (switch_outport_nr, cookie)
+ # default filters, just overwritten on the first node and last
+ # node
+ cmd = 'priority=1,in_port=%s,cookie=%s' % (
+ switch_inport_nr, cookie)
+ cmd_back = 'priority=1,in_port=%s,cookie=%s' % (
+ switch_outport_nr, cookie)
if i == 0: # first node
cmd = 'in_port=%s' % src_sw_inport_nr
cmd += ',cookie=%s' % cookie
@@ -842,13 +884,16 @@
# remove any vlan tags
cmd_back += ',dl_vlan=%s' % vlan
cmd_back += ',actions=pop_vlan,output:%s' % switch_inport_nr
- self.setup_arp_reply_at(current_hop, src_sw_inport_nr, floating_ip, target_mac, cookie=cookie)
+ self.setup_arp_reply_at(
+ current_hop, src_sw_inport_nr, floating_ip, target_mac, cookie=cookie)
elif next_hop == dst_vnf_name: # last switch
# remove any vlan tags
cmd += ',dl_vlan=%s' % vlan
cmd += ',actions=pop_vlan,output:%s' % switch_outport_nr
- # set up arp replys at the port so the dst nodes know the src
- self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
+ # set up arp replys at the port so the dst nodes know the
+ # src
+ self.setup_arp_reply_at(
+ current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)
# reverse route
cmd_back = 'in_port=%s' % switch_outport_nr
@@ -861,7 +906,8 @@
cmd_back += ',set_field:%s->eth_src' % src_mac
cmd_back += ',set_field:%s->ip_src' % floating_ip
cmd_back += ',output:%s' % switch_inport_nr
- net.getNodeByName(dst_vnf_name).setHostRoute(src_ip, dst_vnf_interface)
+ net.getNodeByName(dst_vnf_name).setHostRoute(
+ src_ip, dst_vnf_interface)
else: # middle node
# if we have a circle in the path we need to specify this, as openflow will ignore the packet
# if we just output it on the same port as it came in
@@ -869,8 +915,10 @@
cmd += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
cmd_back += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
else:
- cmd += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_outport_nr)
- cmd_back += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_inport_nr)
+ cmd += ',dl_vlan=%s,actions=output:%s' % (
+ vlan, switch_outport_nr)
+ cmd_back += ',dl_vlan=%s,actions=output:%s' % (
+ vlan, switch_inport_nr)
# excecute the command on the target switch
logging.debug(cmd)
@@ -887,7 +935,8 @@
# advance to next destination
index += 1
- # set up the actual load balancing rule as a multipath on the very first switch
+ # set up the actual load balancing rule as a multipath on the very
+ # first switch
cmd = '"in_port=%s' % src_sw_inport_nr
cmd += ',cookie=%s' % (cookie)
cmd += ',ip'
@@ -897,7 +946,8 @@
# load balance modulo n over all dest interfaces
# TODO: in newer openvswitch implementations this should be changed to symmetric_l3l4+udp
# to balance any kind of traffic
- cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(dest_intfs_mapping)
+ cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(
+ dest_intfs_mapping)
# reuse the cookie as table entry as it will be unique
cmd += ',resubmit(, %s)"' % cookie
@@ -909,7 +959,8 @@
return cookie, floating_ip
- def setup_arp_reply_at(self, switch, port_nr, target_ip, target_mac, cookie=None):
+ def setup_arp_reply_at(self, switch, port_nr,
+ target_ip, target_mac, cookie=None):
"""
Sets up a custom ARP reply at a switch.
An ARP request coming in on the `port_nr` for `target_ip` will be answered with target IP/MAC.
@@ -931,7 +982,8 @@
cookie = self.get_cookie()
main_cmd = "add-flow -OOpenFlow13"
- # first set up ARP requests for the source node, so it will always 'find' a partner
+ # first set up ARP requests for the source node, so it will always
+ # 'find' a partner
cmd = '"in_port=%s' % port_nr
cmd += ',cookie=%s' % cookie
cmd += ',arp'
@@ -988,7 +1040,8 @@
self.cookies.remove(cookie)
return True
- def delete_chain_by_intf(self, src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf):
+ def delete_chain_by_intf(
+ self, src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf):
"""
Removes a flow identified by the vnf_name/vnf_intf pairs
@@ -1003,16 +1056,18 @@
:return: True if successful, else false
:rtype: ``bool``
"""
- logging.debug("Deleting flow for vnf/intf pair %s %s" % (src_vnf_name, src_vnf_intf))
+ logging.debug("Deleting flow for vnf/intf pair %s %s" %
+ (src_vnf_name, src_vnf_intf))
if not self.check_vnf_intf_pair(src_vnf_name, src_vnf_intf):
return False
if not self.check_vnf_intf_pair(dst_vnf_name, dst_vnf_intf):
return False
target_flow = (src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf)
- if not target_flow in self.chain_flow_cookies:
+ if target_flow not in self.chain_flow_cookies:
return False
- success = self.delete_flow_by_cookie(self.chain_flow_cookies[target_flow])
+ success = self.delete_flow_by_cookie(
+ self.chain_flow_cookies[target_flow])
if success:
del self.chain_flow_cookies[target_flow]
@@ -1032,7 +1087,8 @@
delete_group = list()
group_id = self.get_flow_group(vnf_src_name, vnf_src_interface)
for node in self.net.switches:
- for cookie in self.lb_flow_cookies[(vnf_src_name, vnf_src_interface)]:
+ for cookie in self.lb_flow_cookies[(
+ vnf_src_name, vnf_src_interface)]:
flow = dict()
flow["dpid"] = int(node.dpid, 16)
flow["cookie"] = cookie
@@ -1053,7 +1109,8 @@
logging.debug("Deleting group with id %s" % group_id)
for switch_del_group in delete_group:
if self.net.controller == RemoteController:
- self.net.ryu_REST("stats/groupentry/delete", data=switch_del_group)
+ self.net.ryu_REST("stats/groupentry/delete",
+ data=switch_del_group)
# unmap groupid from the interface
target_pair = (vnf_src_name, vnf_src_interface)
@@ -1071,7 +1128,8 @@
"""
cookie = int(cookie)
if cookie not in self.floating_cookies:
- raise Exception("Can not delete floating loadbalancer as the flowcookie is not known")
+ raise Exception(
+ "Can not delete floating loadbalancer as the flowcookie is not known")
self.delete_flow_by_cookie(cookie)
floating_ip = self.floating_cookies[cookie]
diff --git a/src/emuvim/api/openstack/openstack_api_endpoint.py b/src/emuvim/api/openstack/openstack_api_endpoint.py
index e340a3a..b6347eb 100755
--- a/src/emuvim/api/openstack/openstack_api_endpoint.py
+++ b/src/emuvim/api/openstack/openstack_api_endpoint.py
@@ -1,36 +1,39 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from manage import OpenstackManage
-from openstack_dummies import *
+
+from openstack_dummies.glance_dummy_api import GlanceDummyApi
+from openstack_dummies.heat_dummy_api import HeatDummyApi
+from openstack_dummies.keystone_dummy_api import KeystoneDummyApi
+from openstack_dummies.neutron_dummy_api import NeutronDummyApi
+from openstack_dummies.nova_dummy_api import NovaDummyApi
+
import logging
import threading
import compute
-import requests
import socket
import time
@@ -47,11 +50,16 @@
self.port = port
self.compute = compute.OpenstackCompute()
self.openstack_endpoints = dict()
- self.openstack_endpoints['keystone'] = KeystoneDummyApi(self.ip, self.port)
- self.openstack_endpoints['neutron'] = NeutronDummyApi(self.ip, self.port + 4696, self.compute)
- self.openstack_endpoints['nova'] = NovaDummyApi(self.ip, self.port + 3774, self.compute)
- self.openstack_endpoints['heat'] = HeatDummyApi(self.ip, self.port + 3004, self.compute)
- self.openstack_endpoints['glance'] = GlanceDummyApi(self.ip, self.port + 4242, self.compute)
+ self.openstack_endpoints['keystone'] = KeystoneDummyApi(
+ self.ip, self.port)
+ self.openstack_endpoints['neutron'] = NeutronDummyApi(
+ self.ip, self.port + 4696, self.compute)
+ self.openstack_endpoints['nova'] = NovaDummyApi(
+ self.ip, self.port + 3774, self.compute)
+ self.openstack_endpoints['heat'] = HeatDummyApi(
+ self.ip, self.port + 3004, self.compute)
+ self.openstack_endpoints['glance'] = GlanceDummyApi(
+ self.ip, self.port + 4242, self.compute)
self.rest_threads = list()
self.manage = OpenstackManage()
@@ -69,8 +77,8 @@
self.compute.dc = dc
for ep in self.openstack_endpoints.values():
ep.manage = self.manage
- logging.info \
- ("Connected DC(%s) to API endpoint %s(%s:%d)" % (dc.label, self.__class__.__name__, self.ip, self.port))
+ logging.info("Connected DC(%s) to API endpoint %s(%s:%d)" %
+ (dc.label, self.__class__.__name__, self.ip, self.port))
def connect_dc_network(self, dc_network):
"""
@@ -97,14 +105,14 @@
c.server_thread.start()
if wait_for_port:
self._wait_for_port(c.ip, c.port)
-
+
def stop(self):
"""
Stop all connected OpenStack endpoints that are connected to this API endpoint.
"""
for c in self.openstack_endpoints.values():
c.stop()
- #for c in self.openstack_endpoints.values():
+ # for c in self.openstack_endpoints.values():
# if c.server_thread:
# print("Waiting for WSGIServers to be stopped ...")
# c.server_thread.join()
@@ -117,5 +125,6 @@
if r == 0:
break # port is open proceed
else:
- logging.warning("Waiting for {}:{} ... ({}/10)".format(ip, port, i + 1))
+ logging.warning(
+ "Waiting for {}:{} ... ({}/10)".format(ip, port, i + 1))
time.sleep(1)
diff --git a/src/emuvim/api/openstack/openstack_dummies/__init__.py b/src/emuvim/api/openstack/openstack_dummies/__init__.py
index ef97752..d888119 100755
--- a/src/emuvim/api/openstack/openstack_dummies/__init__.py
+++ b/src/emuvim/api/openstack/openstack_dummies/__init__.py
@@ -1,32 +1,25 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-from glance_dummy_api import GlanceDummyApi
-from heat_dummy_api import HeatDummyApi
-from keystone_dummy_api import KeystoneDummyApi
-from neutron_dummy_api import NeutronDummyApi
-from nova_dummy_api import NovaDummyApi
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/api/openstack/openstack_dummies/base_openstack_dummy.py b/src/emuvim/api/openstack/openstack_dummies/base_openstack_dummy.py
index 93ad2bd..d8eeb79 100755
--- a/src/emuvim/api/openstack/openstack_dummies/base_openstack_dummy.py
+++ b/src/emuvim/api/openstack/openstack_dummies/base_openstack_dummy.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from flask import Flask, request
from flask_restful import Api, Resource
from gevent.pywsgi import WSGIServer
@@ -71,8 +69,9 @@
with self.manage.lock:
with open(self.playbook_file, 'a') as logfile:
if len(request.data) > 0:
- data = "# %s API\n" % str(self.__class__).split('.')[-1].rstrip('\'>')
+ data = "# %s API\n" % str(
+ self.__class__).split('.')[-1].rstrip('\'>')
data += "curl -X {type} -H \"Content-type: application/json\" -d '{data}' {url}".format(type=request.method,
- data=request.data,
- url=request.url)
+ data=request.data,
+ url=request.url)
logfile.write(data + "\n")
diff --git a/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py
index 4ce9e77..6edaa72 100755
--- a/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py
+++ b/src/emuvim/api/openstack/openstack_dummies/glance_dummy_api.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from flask_restful import Resource
from flask import Response, request
from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
@@ -78,7 +76,8 @@
]
}]
resp['versions'] = versions
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
class GlanceSchema(Resource):
@@ -88,7 +87,8 @@
resp['name'] = 'someImageName'
resp['properties'] = dict()
# just an ugly hack to allow the openstack client to work
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
class GlanceListImagesApi(Resource):
@@ -97,7 +97,7 @@
def get(self):
LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
- try:
+ try:
resp = dict()
resp['next'] = None
resp['first'] = "/v2/images"
@@ -132,10 +132,12 @@
break
if "marker" in request.args: # ugly hack to fix pageination of openstack client
resp['images'] = None
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of images." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of images." % __name__)
return ex.message, 500
def post(self):
@@ -147,20 +149,22 @@
LOG.debug("API CALL: %s POST" % str(self.__class__.__name__))
try:
body_data = json.loads(request.data)
- except:
+ except BaseException:
body_data = dict()
# lets see what we should create
img_name = request.headers.get("X-Image-Meta-Name")
img_size = request.headers.get("X-Image-Meta-Size")
img_disk_format = request.headers.get("X-Image-Meta-Disk-Format")
img_is_public = request.headers.get("X-Image-Meta-Is-Public")
- img_container_format = request.headers.get("X-Image-Meta-Container-Format")
+ img_container_format = request.headers.get(
+ "X-Image-Meta-Container-Format")
# try to use body payload if header fields are empty
if img_name is None:
img_name = body_data.get("name")
img_size = 1234
img_disk_format = body_data.get("disk_format")
- img_is_public = True if "public" in body_data.get("visibility") else False
+ img_is_public = True if "public" in body_data.get(
+ "visibility") else False
img_container_format = body_data.get("container_format")
# try to find ID of already existing image (matched by name)
img_id = None
@@ -212,15 +216,19 @@
resp['id'] = image.id
resp['name'] = image.name
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
- response = Response("Image with id or name %s does not exists." % id, status=404)
+ response = Response(
+ "Image with id or name %s does not exists." % id, status=404)
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve image with id %s." % (__name__, id))
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception(
+ u"%s: Could not retrieve image with id %s." % (__name__, id))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
def put(self, id):
LOG.debug("API CALL: %s " % str(self.__class__.__name__))
@@ -241,12 +249,16 @@
resp = dict()
resp['id'] = image.id
resp['name'] = image.name
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
- response = Response("Image with id or name %s does not exists." % id, status=404)
+ response = Response(
+ "Image with id or name %s does not exists." % id, status=404)
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- logging.exception(u"%s: Could not retrieve image with id %s." % (__name__, id))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception(
+ u"%s: Could not retrieve image with id %s." % (__name__, id))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
diff --git a/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py
index 9822f22..86fb6c1 100755
--- a/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py
+++ b/src/emuvim/api/openstack/openstack_dummies/heat_dummy_api.py
@@ -1,33 +1,31 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from flask import request, Response
from flask_restful import Resource
-from emuvim.api.openstack.resources import Stack
+from emuvim.api.openstack.resources.stack import Stack
from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
from emuvim.api.openstack.helper import get_host
from datetime import datetime
@@ -88,7 +86,8 @@
]
}]
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
class HeatCreateStack(Resource):
@@ -116,9 +115,11 @@
stack.stack_name = stack_dict['stack_name']
reader = HeatParser(self.api.compute)
- if isinstance(stack_dict['template'], str) or isinstance(stack_dict['template'], unicode):
+ if isinstance(stack_dict['template'], str) or isinstance(
+ stack_dict['template'], unicode):
stack_dict['template'] = json.loads(stack_dict['template'])
- if not reader.parse_input(stack_dict['template'], stack, self.api.compute.dc.label):
+ if not reader.parse_input(
+ stack_dict['template'], stack, self.api.compute.dc.label):
self.api.compute.clean_broken_stack(stack)
return 'Could not create stack.', 400
@@ -136,7 +137,8 @@
self.api.compute.add_stack(stack)
self.api.compute.deploy_stack(stack.id)
- return Response(json.dumps(return_dict), status=201, mimetype="application/json")
+ return Response(json.dumps(return_dict), status=201,
+ mimetype="application/json")
except Exception as ex:
LOG.exception("Heat: Create Stack exception.")
@@ -168,7 +170,8 @@
"tags": ""
})
- return Response(json.dumps(return_stacks), status=200, mimetype="application/json")
+ return Response(json.dumps(return_stacks),
+ status=200, mimetype="application/json")
except Exception as ex:
LOG.exception("Heat: List Stack exception.")
return ex.message, 500
@@ -225,7 +228,8 @@
"stack_name": stack.stack_name,
"stack_owner": "The owner of the stack.", # add stack owner
"stack_status": stack.status,
- "stack_status_reason": "The reason for the current status of the stack.", # add status reason
+ # add status reason
+ "stack_status_reason": "The reason for the current status of the stack.",
"template_description": "The description of the stack template.",
"stack_user_project_id": "The project UUID of the stack user.",
"timeout_mins": "",
@@ -235,13 +239,14 @@
}
}
- return Response(json.dumps(return_stack), status=200, mimetype="application/json")
+ return Response(json.dumps(return_stack),
+ status=200, mimetype="application/json")
except Exception as ex:
LOG.exception("Heat: Show stack exception.")
return ex.message, 500
-
+
class HeatShowStackTemplate(Resource):
def __init__(self, api):
self.api = api
@@ -253,7 +258,7 @@
:param tenant_id:
:param stack_name_or_id:
:param stack_id:
- :return: Returns a json response which contains the stack's template.
+ :return: Returns a json response which contains the stack's template.
"""
LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
try:
@@ -266,9 +271,10 @@
stack = tmp_stack
if stack is None:
return 'Could not resolve Stack - ID', 404
- #LOG.debug("STACK: {}".format(stack))
- #LOG.debug("TEMPLATE: {}".format(stack.template))
- return Response(json.dumps(stack.template), status=200, mimetype="application/json")
+ # LOG.debug("STACK: {}".format(stack))
+ # LOG.debug("TEMPLATE: {}".format(stack.template))
+ return Response(json.dumps(stack.template),
+ status=200, mimetype="application/json")
except Exception as ex:
LOG.exception("Heat: Show stack template exception.")
@@ -286,7 +292,7 @@
:param tenant_id:
:param stack_name_or_id:
:param stack_id:
- :return: Returns a json response which contains the stack's template.
+ :return: Returns a json response which contains the stack's template.
"""
LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
try:
@@ -302,7 +308,8 @@
response = {"resources": []}
- return Response(json.dumps(response), status=200, mimetype="application/json")
+ return Response(json.dumps(response), status=200,
+ mimetype="application/json")
except Exception as ex:
LOG.exception("Heat: Show stack template exception.")
@@ -320,7 +327,7 @@
def patch(self, tenant_id, stack_name_or_id, stack_id=None):
LOG.debug("API CALL: %s PATCH" % str(self.__class__.__name__))
return self.update_stack(tenant_id, stack_name_or_id, stack_id)
-
+
def update_stack(self, tenant_id, stack_name_or_id, stack_id=None):
"""
Updates an existing stack with a new heat template.
@@ -354,9 +361,11 @@
stack.status = "UPDATE_COMPLETE"
reader = HeatParser(self.api.compute)
- if isinstance(stack_dict['template'], str) or isinstance(stack_dict['template'], unicode):
+ if isinstance(stack_dict['template'], str) or isinstance(
+ stack_dict['template'], unicode):
stack_dict['template'] = json.loads(stack_dict['template'])
- if not reader.parse_input(stack_dict['template'], stack, self.api.compute.dc.label, stack_update=True):
+ if not reader.parse_input(
+ stack_dict['template'], stack, self.api.compute.dc.label, stack_update=True):
return 'Could not create stack.', 400
stack.template = stack_dict['template']
diff --git a/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py
index 1a258df..0741553 100755
--- a/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py
+++ b/src/emuvim/api/openstack/openstack_dummies/keystone_dummy_api.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from flask_restful import Resource
from flask import request, Response
from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
@@ -39,11 +37,16 @@
def __init__(self, in_ip, in_port):
super(KeystoneDummyApi, self).__init__(in_ip, in_port)
- self.api.add_resource(KeystoneListVersions, "/", resource_class_kwargs={'api': self})
- self.api.add_resource(KeystoneShowAPIv2, "/v2.0", resource_class_kwargs={'api': self})
- self.api.add_resource(KeystoneGetToken, "/v2.0/tokens", resource_class_kwargs={'api': self})
- self.api.add_resource(KeystoneShowAPIv3, "/v3.0", resource_class_kwargs={'api': self})
- self.api.add_resource(KeystoneGetTokenv3, "/v3.0/auth/tokens", resource_class_kwargs={'api': self})
+ self.api.add_resource(KeystoneListVersions, "/",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(KeystoneShowAPIv2, "/v2.0",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(KeystoneGetToken, "/v2.0/tokens",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(KeystoneShowAPIv3, "/v3.0",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(
+ KeystoneGetTokenv3, "/v3.0/auth/tokens", resource_class_kwargs={'api': self})
class KeystoneListVersions(Resource):
@@ -85,7 +88,8 @@
}]
resp['versions']['values'] = version
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
class KeystoneShowAPIv2(Resource):
@@ -106,8 +110,8 @@
"""
LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
- neutron_port = self.api.port + 4696
- heat_port = self.api.port + 3004
+ # neutron_port = self.api.port + 4696
+ # heat_port = self.api.port + 3004
resp = dict()
resp['version'] = {
@@ -127,7 +131,8 @@
]
}
LOG.debug(json.dumps(resp))
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
class KeystoneShowAPIv3(Resource):
@@ -148,8 +153,8 @@
"""
LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
- neutron_port = self.api.port + 4696
- heat_port = self.api.port + 3004
+ # neutron_port = self.api.port + 4696
+ # heat_port = self.api.port + 3004
resp = dict()
resp['version'] = {
@@ -169,7 +174,8 @@
]
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
class KeystoneGetToken(Resource):
@@ -208,11 +214,13 @@
token['issued_at'] = "2014-01-30T15:30:58.819Z"
token['expires'] = "2999-01-30T15:30:58.819Z"
- token['id'] = req['auth'].get('token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id')
+ token['id'] = req['auth'].get(
+ 'token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id')
token['tenant'] = dict()
token['tenant']['description'] = None
token['tenant']['enabled'] = True
- token['tenant']['id'] = req['auth'].get('tenantId', 'fc394f2ab2df4114bde39905f800dc57')
+ token['tenant']['id'] = req['auth'].get(
+ 'tenantId', 'fc394f2ab2df4114bde39905f800dc57')
token['tenant']['name'] = "tenantName"
ret['access']['user'] = dict()
@@ -220,7 +228,8 @@
user['username'] = req.get('username', "username")
user['name'] = "tenantName"
user['roles_links'] = list()
- user['id'] = token['tenant'].get('id', "fc394f2ab2df4114bde39905f800dc57")
+ user['id'] = token['tenant'].get(
+ 'id', "fc394f2ab2df4114bde39905f800dc57")
user['roles'] = [{'name': 'Member'}]
ret['access']['region_name'] = "RegionOne"
@@ -252,7 +261,7 @@
"endpoints_links": [],
"type": "identity",
"name": "keystone"
- },
+ },
{
"endpoints": [
{
@@ -266,7 +275,7 @@
"endpoints_links": [],
"type": "network",
"name": "neutron"
- },
+ },
{
"endpoints": [
{
@@ -280,7 +289,7 @@
"endpoints_links": [],
"type": "image",
"name": "glance"
- },
+ },
{
"endpoints": [
{
@@ -294,27 +303,29 @@
"endpoints_links": [],
"type": "orchestration",
"name": "heat"
- }
+ }
]
ret['access']["metadata"] = {
- "is_admin": 0,
- "roles": [
- "7598ac3c634d4c3da4b9126a5f67ca2b"
- ]
- },
+ "is_admin": 0,
+ "roles": [
+ "7598ac3c634d4c3da4b9126a5f67ca2b"
+ ]
+ },
ret['access']['trust'] = {
"id": "394998fa61f14736b1f0c1f322882949",
"trustee_user_id": "269348fdd9374b8885da1418e0730af1",
"trustor_user_id": "3ec3164f750146be97f21559ee4d9c51",
"impersonation": False
}
- return Response(json.dumps(ret), status=200, mimetype='application/json')
+ return Response(json.dumps(ret), status=200,
+ mimetype='application/json')
except Exception as ex:
logging.exception("Keystone: Get token failed.")
return ex.message, 500
+
class KeystoneGetTokenv3(Resource):
"""
Returns a static keystone token.
@@ -354,7 +365,8 @@
token['extras'] = dict()
token['user'] = dict()
user = token['user']
- user['id'] = req['auth'].get('token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id')
+ user['id'] = req['auth'].get(
+ 'token', {'id': 'fc394f2ab2df4114bde39905f800dc57'}).get('id')
user['name'] = "tenantName"
user['password_expires_at'] = None
user['domain'] = {"id": "default", "name": "Default"}
@@ -363,7 +375,7 @@
# project
token['project'] = {
"domain": {
- "id" : "default",
+ "id": "default",
"name": "Default"
},
"id": "8538a3f13f9541b28c2620eb19065e45",
@@ -396,7 +408,7 @@
"id": "2dad48f09e2a447a9bf852bcd93543fc",
"type": "identity",
"name": "keystone"
- },
+ },
{
"endpoints": [
{
@@ -409,7 +421,7 @@
"id": "2dad48f09e2a447a9bf852bcd93548cf",
"type": "network",
"name": "neutron"
- },
+ },
{
"endpoints": [
{
@@ -422,7 +434,7 @@
"id": "2dad48f09e2a447a9bf852bcd93548cf",
"type": "image",
"name": "glance"
- },
+ },
{
"endpoints": [
{
@@ -435,9 +447,10 @@
"id": "2dad48f09e2a447a9bf852bcd93548bf",
"type": "orchestration",
"name": "heat"
- }
+ }
]
- return Response(json.dumps(ret), status=201, mimetype='application/json')
+ return Response(json.dumps(ret), status=201,
+ mimetype='application/json')
except Exception as ex:
logging.exception("Keystone: Get token failed.")
diff --git a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py
index 6f6d3dc..154f1ca 100755
--- a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py
+++ b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py
@@ -1,34 +1,31 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from flask_restful import Resource
from flask import request, Response
from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
-from emuvim.api.openstack.helper import get_host
from datetime import datetime
import neutron_sfc_dummy_api as SFC
import logging
@@ -44,7 +41,8 @@
super(NeutronDummyApi, self).__init__(ip, port)
self.compute = compute
- # create default networks (OSM usually assumes to have these pre-configured)
+ # create default networks (OSM usually assumes to have these
+ # pre-configured)
self.compute.create_network("mgmt")
self.compute.create_network("mgmtnet")
@@ -165,7 +163,8 @@
}]
resp['versions'] = versions
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
class NeutronShowAPIv2Details(Resource):
@@ -199,7 +198,7 @@
],
"name": "network",
"collection": "networks"
- },
+ },
{
"links": [
{
@@ -209,10 +208,11 @@
],
"name": "ports",
"collection": "ports"
- }
+ }
]
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
class NeutronListNetworks(Resource):
@@ -232,14 +232,18 @@
try:
if request.args.get('name'):
tmp_network = NeutronShowNetwork(self.api)
- response = tmp_network.get_network(request.args.get('name'), True)
- LOG.debug("{} RESPONSE (1): {}".format(self.__class__.__name__, response))
+ response = tmp_network.get_network(
+ request.args.get('name'), True)
+ LOG.debug("{} RESPONSE (1): {}".format(
+ self.__class__.__name__, response))
return response
id_list = request.args.getlist('id')
if len(id_list) == 1:
tmp_network = NeutronShowNetwork(self.api)
- response = tmp_network.get_network(request.args.get('id'), True)
- LOG.debug("{} RESPONSE (2): {}".format(self.__class__.__name__, response))
+ response = tmp_network.get_network(
+ request.args.get('id'), True)
+ LOG.debug("{} RESPONSE (2): {}".format(
+ self.__class__.__name__, response))
return response
network_list = list()
@@ -258,12 +262,15 @@
network_list.append(tmp_network_dict)
network_dict["networks"] = network_list
- LOG.debug("{} RESPONSE (3): {}".format(self.__class__.__name__, network_dict))
- return Response(json.dumps(network_dict), status=200, mimetype='application/json')
+ LOG.debug("{} RESPONSE (3): {}".format(
+ self.__class__.__name__, network_dict))
+ return Response(json.dumps(network_dict),
+ status=200, mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: List networks exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronShowNetwork(Resource):
@@ -294,9 +301,11 @@
:rtype: :class:`flask.response`
"""
try:
- net = self.api.compute.find_network_by_name_or_id(network_name_or_id)
+ net = self.api.compute.find_network_by_name_or_id(
+ network_name_or_id)
if net is None:
- return Response(u'Network not found.\n', status=404, mimetype='application/json')
+ return Response(u'Network not found.\n',
+ status=404, mimetype='application/json')
tmp_network_dict = net.create_network_dict()
tmp_dict = dict()
@@ -305,12 +314,13 @@
else:
tmp_dict["network"] = tmp_network_dict
- return Response(json.dumps(tmp_dict), status=200, mimetype='application/json')
-
+ return Response(json.dumps(tmp_dict), status=200,
+ mimetype='application/json')
except Exception as ex:
logging.exception("Neutron: Show network exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronCreateNetwork(Resource):
@@ -332,13 +342,16 @@
name = network_dict['network']['name']
net = self.api.compute.find_network_by_name_or_id(name)
if net is not None:
- return Response('Network already exists.\n', status=400, mimetype='application/json')
+ return Response('Network already exists.\n',
+ status=400, mimetype='application/json')
net = self.api.compute.create_network(name)
- return Response(json.dumps({"network": net.create_network_dict()}), status=201, mimetype='application/json')
+ return Response(json.dumps(
+ {"network": net.create_network_dict()}), status=201, mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Create network excepiton.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronUpdateNetwork(Resource):
@@ -361,7 +374,6 @@
if network_id in self.api.compute.nets:
net = self.api.compute.nets[network_id]
network_dict = json.loads(request.data)
- old_net = copy.copy(net)
if "status" in network_dict["network"]:
net.status = network_dict["network"]["status"]
@@ -372,17 +384,21 @@
if "admin_state_up" in network_dict["network"]:
pass # tmp_network_dict["admin_state_up"] = True
if "tenant_id" in network_dict["network"]:
- pass # tmp_network_dict["tenant_id"] = "c1210485b2424d48804aad5d39c61b8f"
+ # tmp_network_dict["tenant_id"] = "c1210485b2424d48804aad5d39c61b8f"
+ pass
if "shared" in network_dict["network"]:
pass # tmp_network_dict["shared"] = False
- return Response(json.dumps(network_dict), status=200, mimetype='application/json')
+ return Response(json.dumps(network_dict),
+ status=200, mimetype='application/json')
- return Response('Network not found.\n', status=404, mimetype='application/json')
+ return Response('Network not found.\n', status=404,
+ mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Show networks exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronDeleteNetwork(Resource):
@@ -410,7 +426,7 @@
delete_subnet = NeutronDeleteSubnet(self.api)
resp = delete_subnet.delete(net.subnet_id)
- if not '204' in resp.status and not '404' in resp.status:
+ if '204' not in resp.status and '404' not in resp.status:
return resp
self.api.compute.delete_network(network_id)
@@ -418,7 +434,8 @@
return Response('', status=204, mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Delete network exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronListSubnets(Resource):
@@ -459,11 +476,13 @@
subnet_dict["subnets"] = subnet_list
- return Response(json.dumps(subnet_dict), status=200, mimetype='application/json')
+ return Response(json.dumps(subnet_dict), status=200,
+ mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: List subnets exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronShowSubnet(Resource):
@@ -502,13 +521,16 @@
tmp_dict["subnets"] = [tmp_subnet_dict]
else:
tmp_dict["subnet"] = tmp_subnet_dict
- return Response(json.dumps(tmp_dict), status=200, mimetype='application/json')
+ return Response(json.dumps(tmp_dict),
+ status=200, mimetype='application/json')
- return Response('Subnet not found. (' + subnet_name_or_id + ')\n', status=404, mimetype='application/json')
+ return Response('Subnet not found. (' + subnet_name_or_id +
+ ')\n', status=404, mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Show subnet exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronCreateSubnet(Resource):
@@ -529,15 +551,20 @@
LOG.debug("API CALL: %s POST" % str(self.__class__.__name__))
try:
subnet_dict = json.loads(request.data)
- net = self.api.compute.find_network_by_name_or_id(subnet_dict['subnet']['network_id'])
+ net = self.api.compute.find_network_by_name_or_id(
+ subnet_dict['subnet']['network_id'])
if net is None:
- return Response('Could not find network.\n', status=404, mimetype='application/json')
+ return Response('Could not find network.\n',
+ status=404, mimetype='application/json')
- net.subnet_name = subnet_dict["subnet"].get('name', str(net.name) + '-sub')
+ net.subnet_name = subnet_dict["subnet"].get(
+ 'name', str(net.name) + '-sub')
if net.subnet_id is not None:
- LOG.error("Only one subnet per network is supported: {}".format(net.subnet_id))
- return Response('Only one subnet per network is supported\n', status=409, mimetype='application/json')
+ LOG.error(
+ "Only one subnet per network is supported: {}".format(net.subnet_id))
+ return Response('Only one subnet per network is supported\n',
+ status=409, mimetype='application/json')
if "id" in subnet_dict["subnet"]:
net.subnet_id = subnet_dict["subnet"]["id"]
@@ -557,11 +584,13 @@
if "enable_dhcp" in subnet_dict["subnet"]:
pass
- return Response(json.dumps({'subnet': net.create_subnet_dict()}), status=201, mimetype='application/json')
+ return Response(json.dumps(
+ {'subnet': net.create_subnet_dict()}), status=201, mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Create network excepiton.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronUpdateSubnet(Resource):
@@ -606,13 +635,16 @@
net.subnet_update_time = str(datetime.now())
tmp_dict = {'subnet': net.create_subnet_dict()}
- return Response(json.dumps(tmp_dict), status=200, mimetype='application/json')
+ return Response(json.dumps(tmp_dict),
+ status=200, mimetype='application/json')
- return Response('Network not found.\n', status=404, mimetype='application/json')
+ return Response('Network not found.\n', status=404,
+ mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Show networks exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronDeleteSubnet(Resource):
@@ -636,9 +668,11 @@
if net.subnet_id == subnet_id:
for server in self.api.compute.computeUnits.values():
for port_name in server.port_names:
- port = self.api.compute.find_port_by_name_or_id(port_name)
+ port = self.api.compute.find_port_by_name_or_id(
+ port_name)
if port is None:
- LOG.warning("Port search for {} returned None.".format(port_name))
+ LOG.warning(
+ "Port search for {} returned None.".format(port_name))
continue
if port.net_name == net.name:
port.ip_address = None
@@ -650,12 +684,15 @@
net.delete_subnet()
- return Response('', status=204, mimetype='application/json')
+ return Response(
+ '', status=204, mimetype='application/json')
- return Response('Could not find subnet.', status=404, mimetype='application/json')
+ return Response('Could not find subnet.',
+ status=404, mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Delete subnet exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronListPorts(Resource):
@@ -695,11 +732,13 @@
port_dict["ports"] = port_list
- return Response(json.dumps(port_dict), status=200, mimetype='application/json')
+ return Response(json.dumps(port_dict), status=200,
+ mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: List ports exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronShowPort(Resource):
@@ -732,17 +771,20 @@
try:
port = self.api.compute.find_port_by_name_or_id(port_name_or_id)
if port is None:
- return Response('Port not found. (' + port_name_or_id + ')\n', status=404, mimetype='application/json')
+ return Response('Port not found. (' + port_name_or_id + ')\n',
+ status=404, mimetype='application/json')
tmp_port_dict = port.create_port_dict(self.api.compute)
tmp_dict = dict()
if as_list:
tmp_dict["ports"] = [tmp_port_dict]
else:
tmp_dict["port"] = tmp_port_dict
- return Response(json.dumps(tmp_dict), status=200, mimetype='application/json')
+ return Response(json.dumps(tmp_dict), status=200,
+ mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Show port exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronCreatePort(Resource):
@@ -764,7 +806,8 @@
net_id = port_dict['port']['network_id']
if net_id not in self.api.compute.nets:
- return Response('Could not find network.\n', status=404, mimetype='application/json')
+ return Response('Could not find network.\n',
+ status=404, mimetype='application/json')
net = self.api.compute.nets[net_id]
if 'name' in port_dict['port']:
@@ -774,7 +817,8 @@
name = "port:cp%s:man:%s" % (num_ports, str(uuid.uuid4()))
if self.api.compute.find_port_by_name_or_id(name):
- return Response("Port with name %s already exists.\n" % name, status=500, mimetype='application/json')
+ return Response("Port with name %s already exists.\n" %
+ name, status=500, mimetype='application/json')
port = self.api.compute.create_port(name)
@@ -796,7 +840,8 @@
if "tenant_id" in port_dict["port"]:
pass
- # add the port to a stack if the specified network is a stack network
+ # add the port to a stack if the specified network is a stack
+ # network
for stack in self.api.compute.stacks.values():
for net in stack.nets.values():
if net.id == net_id:
@@ -806,7 +851,8 @@
mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Show port exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronUpdatePort(Resource):
@@ -829,7 +875,8 @@
port_dict = json.loads(request.data)
port = self.api.compute.find_port_by_name_or_id(port_id)
if port is None:
- return Response("Port with id %s does not exists.\n" % port_id, status=404, mimetype='application/json')
+ return Response("Port with id %s does not exists.\n" %
+ port_id, status=404, mimetype='application/json')
old_port = copy.copy(port)
stack = None
@@ -853,7 +900,8 @@
port.set_name(port_dict["port"]["name"])
if stack is not None:
if port.net_name in stack.nets:
- stack.nets[port.net_name].update_port_name_for_ip_address(port.ip_address, port.name)
+ stack.nets[port.net_name].update_port_name_for_ip_address(
+ port.ip_address, port.name)
stack.ports[port.name] = stack.ports[old_port.name]
del stack.ports[old_port.name]
if "network_id" in port_dict["port"]:
@@ -867,7 +915,8 @@
mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Update port exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronDeletePort(Resource):
@@ -889,7 +938,8 @@
try:
port = self.api.compute.find_port_by_name_or_id(port_id)
if port is None:
- return Response("Port with id %s does not exists.\n" % port_id, status=404)
+ return Response("Port with id %s does not exists.\n" %
+ port_id, status=404)
stack = None
for s in self.api.compute.stacks.values():
for p in s.ports.values():
@@ -897,7 +947,8 @@
stack = s
if stack is not None:
if port.net_name in stack.nets:
- stack.nets[port.net_name].withdraw_ip_address(port.ip_address)
+ stack.nets[port.net_name].withdraw_ip_address(
+ port.ip_address)
for server in stack.servers.values():
try:
server.port_names.remove(port.name)
@@ -911,7 +962,8 @@
except Exception as ex:
LOG.exception("Neutron: Delete port exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class NeutronAddFloatingIp(Resource):
@@ -944,7 +996,8 @@
ip["floating_ip_address"] = "172.0.0.%d" % i
ip["fixed_ip_address"] = "10.0.0.%d" % i
resp["floatingips"].append(ip)
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
def post(self):
"""
@@ -972,7 +1025,8 @@
status=400, mimetype='application/json')
if port.floating_ip is not None:
- return Response("We allow only one floating ip per port\n", status=400, mimetype='application/json')
+ return Response("We allow only one floating ip per port\n",
+ status=400, mimetype='application/json')
else:
num_ports = len(self.api.compute.ports)
name = "port:cp%s:fl:%s" % (num_ports, str(uuid.uuid4()))
@@ -992,7 +1046,9 @@
resp["floating_ip_address"] = port.floating_ip
resp["fixed_ip_address"] = port.floating_ip
- return Response(json.dumps(response), status=200, mimetype='application/json')
+ return Response(json.dumps(response), status=200,
+ mimetype='application/json')
except Exception as ex:
LOG.exception("Neutron: Create FloatingIP exception %s.", ex)
- return Response(ex.message, status=500, mimetype='application/json')
+ return Response(ex.message, status=500,
+ mimetype='application/json')
diff --git a/src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py
index 1494bce..f2ea6bb 100644
--- a/src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py
+++ b/src/emuvim/api/openstack/openstack_dummies/neutron_sfc_dummy_api.py
@@ -1,38 +1,32 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from flask_restful import Resource
from flask import request, Response
import logging
import json
-import uuid
-
-from emuvim.api.openstack.resources.port_chain import PortChain
-from emuvim.api.openstack.helper import get_host
class SFC(Resource):
@@ -52,8 +46,10 @@
request_dict = json.loads(request.data).get("port_pair")
name = request_dict["name"]
- ingress_port = self.api.compute.find_port_by_name_or_id(request_dict["ingress"])
- egress_port = self.api.compute.find_port_by_name_or_id(request_dict["egress"])
+ ingress_port = self.api.compute.find_port_by_name_or_id(
+ request_dict["ingress"])
+ egress_port = self.api.compute.find_port_by_name_or_id(
+ request_dict["egress"])
port_pair = self.api.compute.create_port_pair(name)
port_pair.ingress = ingress_port
@@ -66,10 +62,13 @@
resp = {
"port_pair": port_pair.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=201, mimetype='application/json')
+ return Response(json.dumps(resp), status=201,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortPairsUpdate(SFC):
@@ -87,10 +86,13 @@
resp = {
"port_pair": port_pair.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortPairsDelete(SFC):
@@ -102,8 +104,10 @@
return Response("", status=204,
mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortPairsList(SFC):
@@ -115,10 +119,13 @@
port_pair_list.append(port_pair.create_dict(self.api.compute))
resp = {"port_pairs": port_pair_list}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortPairsShow(SFC):
@@ -130,10 +137,13 @@
resp = {
"port_pair": port_pair.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
###############################################################################
@@ -147,20 +157,25 @@
try:
request_dict = json.loads(request.data).get("port_pair_group")
- port_pair_group = self.api.compute.create_port_pair_group(request_dict["name"])
+ port_pair_group = self.api.compute.create_port_pair_group(
+ request_dict["name"])
port_pair_group.port_pairs = request_dict["port_pairs"]
if "description" in request_dict:
port_pair_group.description = request_dict["description"]
if "port_pair_group_parameters" in request_dict:
- port_pair_group.port_pair_group_parameters = request_dict["port_pair_group_parameters"]
+ port_pair_group.port_pair_group_parameters = request_dict[
+ "port_pair_group_parameters"]
resp = {
"port_pair_group": port_pair_group.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=201, mimetype='application/json')
+ return Response(json.dumps(resp), status=201,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortPairGroupUpdate(SFC):
@@ -169,7 +184,8 @@
try:
request_dict = json.loads(request.data).get("port_pair_group")
- port_pair_group = self.api.compute.find_port_pair_group_by_name_or_id(group_id)
+ port_pair_group = self.api.compute.find_port_pair_group_by_name_or_id(
+ group_id)
if "name" in request_dict:
port_pair_group.name = request_dict["name"]
if "description" in request_dict:
@@ -180,10 +196,13 @@
resp = {
"port_pair_group": port_pair_group.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortPairGroupDelete(SFC):
@@ -195,8 +214,10 @@
return Response("", status=204,
mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortPairGroupList(SFC):
@@ -205,13 +226,17 @@
try:
port_pair_group_list = []
for port_pair_group in self.api.compute.port_pair_groups.values():
- port_pair_group_list.append(port_pair_group.create_dict(self.api.compute))
+ port_pair_group_list.append(
+ port_pair_group.create_dict(self.api.compute))
resp = {"port_pair_groups": port_pair_group_list}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortPairGroupShow(SFC):
@@ -219,14 +244,18 @@
logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
try:
- port_pair_group = self.api.compute.find_port_pair_group_by_name_or_id(group_id)
+ port_pair_group = self.api.compute.find_port_pair_group_by_name_or_id(
+ group_id)
resp = {
"port_pair_group": port_pair_group.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
###############################################################################
@@ -240,7 +269,8 @@
try:
request_dict = json.loads(request.data).get("flow_classifier")
- flow_classifier = self.api.compute.create_flow_classifier(request_dict["name"])
+ flow_classifier = self.api.compute.create_flow_classifier(
+ request_dict["name"])
if "description" in request_dict:
flow_classifier.description = request_dict["description"]
if "ethertype" in request_dict:
@@ -252,9 +282,11 @@
if "source_port_range_max" in request_dict:
flow_classifier.source_port_range_max = request_dict["source_port_range_max"]
if "destination_port_range_min" in request_dict:
- flow_classifier.destination_port_range_min = request_dict["destination_port_range_min"]
+ flow_classifier.destination_port_range_min = request_dict[
+ "destination_port_range_min"]
if "destination_port_range_max" in request_dict:
- flow_classifier.destination_port_range_max = request_dict["destination_port_range_max"]
+ flow_classifier.destination_port_range_max = request_dict[
+ "destination_port_range_max"]
if "source_ip_prefix" in request_dict:
flow_classifier.source_ip_prefix = request_dict["source_ip_prefix"]
if "destination_ip_prefix" in request_dict:
@@ -269,10 +301,13 @@
resp = {
"flow_classifier": flow_classifier.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=201, mimetype='application/json')
+ return Response(json.dumps(resp), status=201,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class FlowClassifierUpdate(SFC):
@@ -281,7 +316,8 @@
try:
request_dict = json.loads(request.data).get("flow_classifier")
- flow_classifier = self.api.compute.find_flow_classifier_by_name_or_id(flow_classifier_id)
+ flow_classifier = self.api.compute.find_flow_classifier_by_name_or_id(
+ flow_classifier_id)
if "name" in request_dict:
flow_classifier.name = request_dict["name"]
if "description" in request_dict:
@@ -290,10 +326,13 @@
resp = {
"flow_classifier": flow_classifier.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class FlowClassifierDelete(SFC):
@@ -305,8 +344,10 @@
return Response("", status=204,
mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class FlowClassifierList(SFC):
@@ -315,13 +356,17 @@
try:
flow_classifier_list = []
for flow_classifier in self.api.compute.flow_classifiers.values():
- flow_classifier_list.append(flow_classifier.create_dict(self.api.compute))
+ flow_classifier_list.append(
+ flow_classifier.create_dict(self.api.compute))
resp = {"flow_classifiers": flow_classifier_list}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class FlowClassifierShow(SFC):
@@ -329,14 +374,18 @@
logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
try:
- flow_classifier = self.api.compute.find_flow_classifier_by_name_or_id(flow_classifier_id)
+ flow_classifier = self.api.compute.find_flow_classifier_by_name_or_id(
+ flow_classifier_id)
resp = {
"flow_classifier": flow_classifier.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
###############################################################################
@@ -350,7 +399,8 @@
try:
request_dict = json.loads(request.data).get("port_chain")
- port_chain = self.api.compute.create_port_chain(request_dict["name"])
+ port_chain = self.api.compute.create_port_chain(
+ request_dict["name"])
port_chain.port_pair_groups = request_dict["port_pair_groups"]
if "description" in request_dict:
port_chain.description = request_dict["description"]
@@ -364,10 +414,13 @@
resp = {
"port_chain": port_chain.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=201, mimetype='application/json')
+ return Response(json.dumps(resp), status=201,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortChainUpdate(SFC):
@@ -394,10 +447,13 @@
resp = {
"port_chain": port_chain.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortChainDelete(SFC):
@@ -409,8 +465,10 @@
return Response("", status=204,
mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortChainList(SFC):
@@ -419,13 +477,17 @@
try:
port_chain_list = []
for port_chain in self.api.compute.port_chains.values():
- port_chain_list.append(port_chain.create_dict(self.api.compute))
+ port_chain_list.append(
+ port_chain.create_dict(self.api.compute))
resp = {"port_chains": port_chain_list}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
class PortChainShow(SFC):
@@ -433,11 +495,15 @@
logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
try:
- port_chain = self.api.compute.find_port_chain_by_name_or_id(chain_id)
+ port_chain = self.api.compute.find_port_chain_by_name_or_id(
+ chain_id)
resp = {
"port_chain": port_chain.create_dict(self.api.compute)
}
- return Response(json.dumps(resp), status=200, mimetype='application/json')
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron SFC: %s Exception." % str(self.__class__.__name__))
- return Response(ex.message, status=500, mimetype='application/json')
+ logging.exception("Neutron SFC: %s Exception." %
+ str(self.__class__.__name__))
+ return Response(ex.message, status=500,
+ mimetype='application/json')
diff --git a/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py b/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py
index 9dcfa48..e12fb05 100755
--- a/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py
+++ b/src/emuvim/api/openstack/openstack_dummies/nova_dummy_api.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from flask_restful import Resource
from flask import Response, request
from emuvim.api.openstack.openstack_dummies.base_openstack_dummy import BaseOpenstackDummy
@@ -202,12 +200,14 @@
resp['servers'].append(s)
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of servers." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of servers." % __name__)
return ex.message, 500
def post(self, id):
@@ -227,12 +227,12 @@
if self.api.compute.find_server_by_name_or_id(name) is not None:
LOG.error("Server with name %s already exists. 409" % name)
- return Response("Server with name %s already exists." % name, status=409)
+ return Response(
+ "Server with name %s already exists." % name, status=409)
# TODO: not finished!
- resp = dict()
-
server = self.api.compute.create_server(name)
- server.full_name = str(self.api.compute.dc.label) + "_" + server_dict["name"]
+ server.full_name = str(
+ self.api.compute.dc.label) + "_" + server_dict["name"]
server.template_name = server_dict["name"]
if "metadata" in server_dict:
server.properties = server_dict["metadata"]
@@ -246,11 +246,13 @@
if networks is not None:
for net in networks:
- port = self.api.compute.find_port_by_name_or_id(net.get('port', ""))
+ port = self.api.compute.find_port_by_name_or_id(
+ net.get('port', ""))
if port is not None:
server.port_names.append(port.name)
else:
- return Response("Currently only networking by port is supported.", status=400)
+ return Response(
+ "Currently only networking by port is supported.", status=400)
self.api.compute._start_compute(server)
@@ -301,12 +303,14 @@
resp['servers'].append(s)
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of servers." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of servers." % __name__)
return ex.message, 500
@@ -363,12 +367,14 @@
resp['servers'].append(s)
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of servers." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of servers." % __name__)
return ex.message, 500
@@ -399,12 +405,14 @@
flavor.id)}]
resp['flavors'].append(f)
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of servers." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of servers." % __name__)
return ex.message, 500
def post(self, id):
@@ -424,7 +432,8 @@
id,
f.id)}]
resp = {"flavor": data}
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
class NovaListFlavorsDetails(Resource):
@@ -463,12 +472,14 @@
f['rxtx_factor'] = 1.0
resp['flavors'].append(f)
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of servers." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of servers." % __name__)
return ex.message, 500
def post(self, id):
@@ -488,7 +499,8 @@
id,
f.id)}]
resp = {"flavor": data}
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
class NovaListFlavorById(Resource):
@@ -522,12 +534,14 @@
self.api.port,
id,
flavor.id)}]
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve flavor with id %s" % (__name__, flavorid))
+ LOG.exception(u"%s: Could not retrieve flavor with id %s" %
+ (__name__, flavorid))
return ex.message, 500
def delete(self, id, flavorid):
@@ -565,12 +579,14 @@
id,
image.id)}]
resp['images'].append(f)
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of images." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of images." % __name__)
return ex.message, 500
@@ -609,12 +625,14 @@
}
resp['images'].append(f)
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of images." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of images." % __name__)
return ex.message, 500
@@ -642,14 +660,17 @@
i['id'] = image.id
i['name'] = image.name
- return Response(json.dumps(resp), status=200, mimetype="application/json")
+ return Response(json.dumps(resp), status=200,
+ mimetype="application/json")
- response = Response("Image with id or name %s does not exists." % imageid, status=404)
+ response = Response(
+ "Image with id or name %s does not exists." % imageid, status=404)
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve image with id %s." % (__name__, imageid))
+ LOG.exception(u"%s: Could not retrieve image with id %s." %
+ (__name__, imageid))
return ex.message, 500
def delete(self, id, imageid):
@@ -680,7 +701,8 @@
try:
server = self.api.compute.find_server_by_name_or_id(serverid)
if server is None:
- return Response("Server with id or name %s does not exists." % serverid, status=404)
+ return Response(
+ "Server with id or name %s does not exists." % serverid, status=404)
s = server.create_server_dict()
s['links'] = [{'href': "http://%s:%d/v2.1/%s/servers/%s" % (get_host(request),
self.api.port,
@@ -714,12 +736,14 @@
]
}
- response = Response(json.dumps({'server': s}), status=200, mimetype="application/json")
+ response = Response(json.dumps(
+ {'server': s}), status=200, mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the server details." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the server details." % __name__)
return ex.message, 500
def delete(self, id, serverid):
@@ -737,7 +761,8 @@
try:
server = self.api.compute.find_server_by_name_or_id(serverid)
if server is None:
- return Response('Could not find server.', status=404, mimetype="application/json")
+ return Response('Could not find server.',
+ status=404, mimetype="application/json")
self.api.compute.stop_compute(server)
@@ -769,11 +794,13 @@
try:
server = self.api.compute.find_server_by_name_or_id(serverid)
if server is None:
- return Response("Server with id or name %s does not exists." % serverid, status=404)
+ return Response(
+ "Server with id or name %s does not exists." % serverid, status=404)
if server.emulator_compute is None:
LOG.error("The targeted container does not exist.")
- return Response("The targeted container of %s does not exist." % serverid, status=404)
+ return Response(
+ "The targeted container of %s does not exist." % serverid, status=404)
data = json.loads(request.data).get("interfaceAttachment")
resp = dict()
port = data.get("port_id", None)
@@ -791,7 +818,8 @@
elif net is not None:
network = self.api.compute.find_network_by_name_or_id(net)
if network is None:
- return Response("Network with id or name %s does not exists." % net, status=404)
+ return Response(
+ "Network with id or name %s does not exists." % net, status=404)
port = self.api.compute.create_port("port:cp%s:fl:%s" %
(len(self.api.compute.ports), str(uuid.uuid4())))
@@ -804,10 +832,12 @@
port = self.api.compute.find_port_by_name_or_id(port)
network_dict['id'] = port.intf_name
network_dict['ip'] = port.ip_address
- network = self.api.compute.find_network_by_name_or_id(port.net_name)
+ network = self.api.compute.find_network_by_name_or_id(
+ port.net_name)
network_dict[network_dict['id']] = network.name
else:
- raise Exception("You can only attach interfaces by port or network at the moment")
+ raise Exception(
+ "You can only attach interfaces by port or network at the moment")
if network == self.api.manage.floating_network:
dc.net.addLink(server.emulator_compute, self.api.manage.floating_switch,
@@ -817,19 +847,22 @@
params1=network_dict, cls=Link, intfName1=port.intf_name)
resp["port_state"] = "ACTIVE"
resp["port_id"] = port.id
- resp["net_id"] = self.api.compute.find_network_by_name_or_id(port.net_name).id
+ resp["net_id"] = self.api.compute.find_network_by_name_or_id(
+ port.net_name).id
resp["mac_addr"] = port.mac_address
resp["fixed_ips"] = list()
fixed_ips = dict()
fixed_ips["ip_address"] = port.ip_address
fixed_ips["subnet_id"] = network.subnet_name
resp["fixed_ips"].append(fixed_ips)
- response = Response(json.dumps({"interfaceAttachment": resp}), status=202, mimetype="application/json")
+ response = Response(json.dumps(
+ {"interfaceAttachment": resp}), status=202, mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not add interface to the server." % __name__)
+ LOG.exception(
+ u"%s: Could not add interface to the server." % __name__)
return ex.message, 500
@@ -855,14 +888,16 @@
try:
server = self.api.compute.find_server_by_name_or_id(serverid)
if server is None:
- return Response("Server with id or name %s does not exists." % serverid, status=404)
+ return Response(
+ "Server with id or name %s does not exists." % serverid, status=404)
port = self.api.compute.find_port_by_name_or_id(port_id)
if port is None:
- return Response("Port with id or name %s does not exists." % port_id, status=404)
+ return Response(
+ "Port with id or name %s does not exists." % port_id, status=404)
for link in self.api.compute.dc.net.links:
if str(link.intf1) == port.intf_name and \
- str(link.intf1.ip) == port.ip_address.split('/')[0]:
+ str(link.intf1.ip) == port.ip_address.split('/')[0]:
self.api.compute.dc.net.removeLink(link)
break
@@ -871,7 +906,8 @@
return response
except Exception as ex:
- LOG.exception(u"%s: Could not detach interface from the server." % __name__)
+ LOG.exception(
+ u"%s: Could not detach interface from the server." % __name__)
return ex.message, 500
@@ -919,10 +955,12 @@
"rate": []
}
}
- response = Response(json.dumps(resp), status=200, mimetype="application/json")
+ response = Response(json.dumps(resp), status=200,
+ mimetype="application/json")
response.headers['Access-Control-Allow-Origin'] = '*'
return response
except Exception as ex:
- LOG.exception(u"%s: Could not retrieve the list of images." % __name__)
+ LOG.exception(
+ u"%s: Could not retrieve the list of images." % __name__)
return ex.message, 500
diff --git a/src/emuvim/api/openstack/resources/__init__.py b/src/emuvim/api/openstack/resources/__init__.py
index e252c1e..d888119 100755
--- a/src/emuvim/api/openstack/resources/__init__.py
+++ b/src/emuvim/api/openstack/resources/__init__.py
@@ -1,41 +1,25 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-from instance_flavor import InstanceFlavor
-from model import Model
-from net import Net
-from port import Port
-from port_pair import PortPair
-from port_pair_group import PortPairGroup
-from flow_classifier import FlowClassifier
-from port_chain import PortChain
-from resource import Resource
-from router import Router
-from server import Server
-from stack import Stack
-from template import Template
-from image import Image
\ No newline at end of file
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/api/openstack/resources/flow_classifier.py b/src/emuvim/api/openstack/resources/flow_classifier.py
index 5b50c92..284fee8 100644
--- a/src/emuvim/api/openstack/resources/flow_classifier.py
+++ b/src/emuvim/api/openstack/resources/flow_classifier.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import uuid
diff --git a/src/emuvim/api/openstack/resources/image.py b/src/emuvim/api/openstack/resources/image.py
index 715d0f9..3d9c66b 100755
--- a/src/emuvim/api/openstack/resources/image.py
+++ b/src/emuvim/api/openstack/resources/image.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import uuid
from datetime import datetime
diff --git a/src/emuvim/api/openstack/resources/instance_flavor.py b/src/emuvim/api/openstack/resources/instance_flavor.py
index 90f7fe5..1e7b6f6 100755
--- a/src/emuvim/api/openstack/resources/instance_flavor.py
+++ b/src/emuvim/api/openstack/resources/instance_flavor.py
@@ -1,35 +1,34 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import uuid
class InstanceFlavor:
- def __init__(self, name, cpu=None, memory=None, memory_unit=None, storage=None, storage_unit=None):
+ def __init__(self, name, cpu=None, memory=None,
+ memory_unit=None, storage=None, storage_unit=None):
self.id = str(uuid.uuid4())
self.name = name
self.cpu = cpu
diff --git a/src/emuvim/api/openstack/resources/load_balancer.py b/src/emuvim/api/openstack/resources/load_balancer.py
index 39be655..0938203 100755
--- a/src/emuvim/api/openstack/resources/load_balancer.py
+++ b/src/emuvim/api/openstack/resources/load_balancer.py
@@ -1,32 +1,33 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
class LoadBalancer(object):
- def __init__(self, name, id=None, flavor=None, image=None, command=None, nw_list=None):
+ def __init__(self, name, id=None, flavor=None,
+ image=None, command=None, nw_list=None):
self.name = name
self.id = id # not set
self.out_ports = dict()
diff --git a/src/emuvim/api/openstack/resources/model.py b/src/emuvim/api/openstack/resources/model.py
index ea5c054..ae7ceff 100755
--- a/src/emuvim/api/openstack/resources/model.py
+++ b/src/emuvim/api/openstack/resources/model.py
@@ -1,30 +1,30 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
class Model:
def __init__(self, resources=None):
if not resources:
diff --git a/src/emuvim/api/openstack/resources/net.py b/src/emuvim/api/openstack/resources/net.py
index db38348..112cca6 100755
--- a/src/emuvim/api/openstack/resources/net.py
+++ b/src/emuvim/api/openstack/resources/net.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import re
@@ -63,9 +61,11 @@
if self.start_end_dict is None:
return None
- int_start_ip = Net.ip_2_int(self.start_end_dict['start']) + 2 # First address as network address not usable
+ # First address as network address not usable
+ int_start_ip = Net.ip_2_int(self.start_end_dict['start']) + 2
# Second one is for gateways only
- int_end_ip = Net.ip_2_int(self.start_end_dict['end']) - 1 # Last address for broadcasts
+ # Last address for broadcasts
+ int_end_ip = Net.ip_2_int(self.start_end_dict['end']) - 1
while int_start_ip in self._issued_ip_addresses and int_start_ip <= int_end_ip:
int_start_ip += 1
@@ -90,8 +90,10 @@
if int_ip in self._issued_ip_addresses:
return False
- int_start_ip = Net.ip_2_int(self.start_end_dict['start']) + 1 # First address as network address not usable
- int_end_ip = Net.ip_2_int(self.start_end_dict['end']) - 1 # Last address for broadcasts
+ # First address as network address not usable
+ int_start_ip = Net.ip_2_int(self.start_end_dict['start']) + 1
+ # Last address for broadcasts
+ int_end_ip = Net.ip_2_int(self.start_end_dict['end']) - 1
if int_ip < int_start_ip or int_ip > int_end_ip:
return False
@@ -110,7 +112,7 @@
"""
int_ip = Net.cidr_2_int(cidr)
- if not int_ip in self._issued_ip_addresses:
+ if int_ip not in self._issued_ip_addresses:
return False
if self._issued_ip_addresses[int_ip] == port_name:
@@ -285,14 +287,16 @@
:rtype: ``dict``
"""
network_dict = dict()
- network_dict["status"] = "ACTIVE" # TODO do we support inactive networks?
- if self.subnet_id == None:
+ # TODO do we support inactive networks?
+ network_dict["status"] = "ACTIVE"
+ if self.subnet_id is None:
network_dict["subnets"] = []
else:
network_dict["subnets"] = [self.subnet_id]
network_dict["name"] = self.name
network_dict["admin_state_up"] = True # TODO is it always true?
- network_dict["tenant_id"] = "abcdefghijklmnopqrstuvwxyz123456" # TODO what should go in here
+ # TODO what should go in here
+ network_dict["tenant_id"] = "abcdefghijklmnopqrstuvwxyz123456"
network_dict["id"] = self.id
network_dict["shared"] = False # TODO is it always false?
return network_dict
@@ -307,7 +311,8 @@
subnet_dict = dict()
subnet_dict["name"] = self.subnet_name
subnet_dict["network_id"] = self.id
- subnet_dict["tenant_id"] = "abcdefghijklmnopqrstuvwxyz123456" # TODO what should go in here?
+ # TODO what should go in here?
+ subnet_dict["tenant_id"] = "abcdefghijklmnopqrstuvwxyz123456"
subnet_dict["created_at"] = self.subnet_creation_time
subnet_dict["dns_nameservers"] = []
subnet_dict["allocation_pools"] = [self.start_end_dict]
@@ -322,10 +327,10 @@
def __eq__(self, other):
if self.name == other.name and self.subnet_name == other.subnet_name and \
- self.gateway_ip == other.gateway_ip and \
- self.segmentation_id == other.segmentation_id and \
- self._cidr == other._cidr and \
- self.start_end_dict == other.start_end_dict:
+ self.gateway_ip == other.gateway_ip and \
+ self.segmentation_id == other.segmentation_id and \
+ self._cidr == other._cidr and \
+ self.start_end_dict == other.start_end_dict:
return True
return False
diff --git a/src/emuvim/api/openstack/resources/port.py b/src/emuvim/api/openstack/resources/port.py
index 2e4d693..1d82e92 100755
--- a/src/emuvim/api/openstack/resources/port.py
+++ b/src/emuvim/api/openstack/resources/port.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
import threading
import uuid
@@ -34,7 +32,8 @@
class Port:
- def __init__(self, name, ip_address=None, mac_address=None, floating_ip=None):
+ def __init__(self, name, ip_address=None,
+ mac_address=None, floating_ip=None):
self.name = name
self.intf_name = None
self.id = str(uuid.uuid4())
@@ -80,13 +79,13 @@
if len(split_name) >= 3:
if split_name[2] == 'input' or split_name[2] == 'in':
self.intf_name = split_name[0][:4] + '-' + \
- 'in'
+ 'in'
elif split_name[2] == 'output' or split_name[2] == 'out':
self.intf_name = split_name[0][:4] + '-' + \
- 'out'
+ 'out'
else:
self.intf_name = split_name[0][:4] + '-' + \
- split_name[2][:4]
+ split_name[2][:4]
else:
self.intf_name = self.name[:9]
@@ -96,12 +95,14 @@
global intf_names
intf_len = len(self.intf_name)
self.intf_name = self.intf_name + '-' + str(counter)[:4]
- while self.intf_name in intf_names and counter < 999 and not intf_names[self.intf_name][0] == self.id:
+ while self.intf_name in intf_names and counter < 999 and not intf_names[
+ self.intf_name][0] == self.id:
counter += 1
self.intf_name = self.intf_name[:intf_len] + '-' + str(counter)[:4]
if counter >= 1000:
- logging.ERROR("Port %s could not create unique interface name (%s)", self.name, self.intf_name)
+ logging.ERROR(
+ "Port %s could not create unique interface name (%s)", self.name, self.intf_name)
lock.release()
return
@@ -132,7 +133,8 @@
"""
port_dict = dict()
port_dict["admin_state_up"] = True # TODO is it always true?
- port_dict["device_id"] = "257614cc-e178-4c92-9c61-3b28d40eca44" # TODO find real values
+ # TODO find real values
+ port_dict["device_id"] = "257614cc-e178-4c92-9c61-3b28d40eca44"
port_dict["device_owner"] = "" # TODO do we have such things?
net = compute.find_network_by_name_or_id(self.net_name)
port_dict["fixed_ips"] = [
@@ -146,7 +148,8 @@
port_dict["name"] = self.name
port_dict["network_id"] = net.id if net is not None else ""
port_dict["status"] = "ACTIVE" # TODO do we support inactive port?
- port_dict["tenant_id"] = "abcdefghijklmnopqrstuvwxyz123456" # TODO find real tenant_id
+ # TODO find real tenant_id
+ port_dict["tenant_id"] = "abcdefghijklmnopqrstuvwxyz123456"
return port_dict
def compare_attributes(self, other):
@@ -163,7 +166,7 @@
return False
if self.name == other.name and self.floating_ip == other.floating_ip and \
- self.net_name == other.net_name:
+ self.net_name == other.net_name:
return True
return False
@@ -172,9 +175,9 @@
return False
if self.name == other.name and self.ip_address == other.ip_address and \
- self.mac_address == other.mac_address and \
- self.floating_ip == other.floating_ip and \
- self.net_name == other.net_name:
+ self.mac_address == other.mac_address and \
+ self.floating_ip == other.floating_ip and \
+ self.net_name == other.net_name:
return True
return False
diff --git a/src/emuvim/api/openstack/resources/port_chain.py b/src/emuvim/api/openstack/resources/port_chain.py
index d82c9b1..dfdd2d3 100644
--- a/src/emuvim/api/openstack/resources/port_chain.py
+++ b/src/emuvim/api/openstack/resources/port_chain.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import random
import uuid
import logging
@@ -40,7 +38,8 @@
self.flow_classifiers = list()
self.chain_parameters = dict()
- # Cookie for internal identification of installed flows (e.g. to delete them)
+ # Cookie for internal identification of installed flows (e.g. to delete
+ # them)
self.cookie = random.randint(1, 0xffffffff)
def create_dict(self, compute):
@@ -56,13 +55,16 @@
def install(self, compute):
for flow_classifier_id in self.flow_classifiers:
- flow_classifier = compute.find_flow_classifier_by_name_or_id(flow_classifier_id)
+ flow_classifier = compute.find_flow_classifier_by_name_or_id(
+ flow_classifier_id)
if flow_classifier:
pass
- # TODO: for every flow classifier create match and pass it to setChain
+ # TODO: for every flow classifier create match and pass it to
+ # setChain
for group_id in self.port_pair_groups:
- port_pair_group = compute.find_port_pair_group_by_name_or_id(group_id)
+ port_pair_group = compute.find_port_pair_group_by_name_or_id(
+ group_id)
for port_pair_id in port_pair_group.port_pairs:
port_pair = compute.find_port_pair_by_name_or_id(port_pair_id)
@@ -76,10 +78,12 @@
# TODO: Not sure, if this should throw an error
if not server_ingress:
- logging.warn("Neutron SFC: ingress port %s not connected." % str(port_pair.ingress.name))
+ logging.warn("Neutron SFC: ingress port %s not connected." % str(
+ port_pair.ingress.name))
continue
if not server_egress:
- logging.warn("Neutron SFC: egress port %s not connected." % str(port_pair.egress.name))
+ logging.warn("Neutron SFC: egress port %s not connected." % str(
+ port_pair.egress.name))
continue
compute.dc.net.setChain(
diff --git a/src/emuvim/api/openstack/resources/port_pair.py b/src/emuvim/api/openstack/resources/port_pair.py
index 52a4ba0..a2e31bc 100644
--- a/src/emuvim/api/openstack/resources/port_pair.py
+++ b/src/emuvim/api/openstack/resources/port_pair.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import uuid
diff --git a/src/emuvim/api/openstack/resources/port_pair_group.py b/src/emuvim/api/openstack/resources/port_pair_group.py
index 75a5d0e..fd97917 100644
--- a/src/emuvim/api/openstack/resources/port_pair_group.py
+++ b/src/emuvim/api/openstack/resources/port_pair_group.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import uuid
diff --git a/src/emuvim/api/openstack/resources/resource.py b/src/emuvim/api/openstack/resources/resource.py
index efa33b1..9a33ebf 100755
--- a/src/emuvim/api/openstack/resources/resource.py
+++ b/src/emuvim/api/openstack/resources/resource.py
@@ -1,30 +1,30 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
class Resource:
def __init__(self, name, type=None, properties=None):
self.name = name
diff --git a/src/emuvim/api/openstack/resources/router.py b/src/emuvim/api/openstack/resources/router.py
index 27abf53..3d30e1b 100755
--- a/src/emuvim/api/openstack/resources/router.py
+++ b/src/emuvim/api/openstack/resources/router.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import uuid
@@ -39,6 +37,6 @@
def __eq__(self, other):
if self.name == other.name and len(self.subnet_names) == len(other.subnet_names) and \
- set(self.subnet_names) == set(other.subnet_names):
+ set(self.subnet_names) == set(other.subnet_names):
return True
return False
diff --git a/src/emuvim/api/openstack/resources/server.py b/src/emuvim/api/openstack/resources/server.py
index 2224de9..48f1898 100755
--- a/src/emuvim/api/openstack/resources/server.py
+++ b/src/emuvim/api/openstack/resources/server.py
@@ -1,32 +1,33 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
class Server(object):
- def __init__(self, name, id=None, flavor=None, image=None, command=None, nw_list=None):
+ def __init__(self, name, id=None, flavor=None,
+ image=None, command=None, nw_list=None):
self.name = name
self.full_name = None
self.template_name = None
@@ -50,19 +51,19 @@
:rtype: ``bool``
"""
if self.name == other.name and self.full_name == other.full_name and \
- self.flavor == other.flavor and \
- self.image == other.image and \
- self.command == other.command:
+ self.flavor == other.flavor and \
+ self.image == other.image and \
+ self.command == other.command:
return True
return False
def __eq__(self, other):
if self.name == other.name and self.full_name == other.full_name and \
- self.flavor == other.flavor and \
- self.image == other.image and \
- self.command == other.command and \
- len(self.port_names) == len(other.port_names) and \
- set(self.port_names) == set(other.port_names):
+ self.flavor == other.flavor and \
+ self.image == other.image and \
+ self.command == other.command and \
+ len(self.port_names) == len(other.port_names) and \
+ set(self.port_names) == set(other.port_names):
return True
return False
diff --git a/src/emuvim/api/openstack/resources/stack.py b/src/emuvim/api/openstack/resources/stack.py
index 453e20c..cabaffa 100755
--- a/src/emuvim/api/openstack/resources/stack.py
+++ b/src/emuvim/api/openstack/resources/stack.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import uuid
diff --git a/src/emuvim/api/openstack/resources/template.py b/src/emuvim/api/openstack/resources/template.py
index 5b1ebe9..bbb7713 100755
--- a/src/emuvim/api/openstack/resources/template.py
+++ b/src/emuvim/api/openstack/resources/template.py
@@ -1,30 +1,30 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
class Template:
def __init__(self, resources=None):
self.version = '2015-04-30'
diff --git a/src/emuvim/api/rest/__init__.py b/src/emuvim/api/rest/__init__.py
index 395c0ce..d888119 100755
--- a/src/emuvim/api/rest/__init__.py
+++ b/src/emuvim/api/rest/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/api/rest/compute.py b/src/emuvim/api/rest/compute.py
index 78d96da..5120b9e 100755
--- a/src/emuvim/api/rest/compute.py
+++ b/src/emuvim/api/rest/compute.py
@@ -1,36 +1,33 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
from flask_restful import Resource
from flask import request
import json
import threading
-from copy import deepcopy
logging.basicConfig()
@@ -61,7 +58,7 @@
data = request.json
if data is None:
data = {}
- elif type(data) is not dict:
+ elif not isinstance(data, dict):
data = json.loads(request.json)
network = data.get("network")
@@ -84,10 +81,12 @@
env = config.get("Env", list())
for env_var in env:
var, cmd = map(str.strip, map(str, env_var.split('=', 1)))
- logging.debug("%r = %r" % (var , cmd))
- if var=="SON_EMU_CMD" or var=="VIM_EMU_CMD":
- logging.info("Executing entry point script in %r: %r" % (c.name, cmd))
- # execute command in new thread to ensure that API is not blocked by VNF
+ logging.debug("%r = %r" % (var, cmd))
+ if var == "SON_EMU_CMD" or var == "VIM_EMU_CMD":
+ logging.info(
+ "Executing entry point script in %r: %r" % (c.name, cmd))
+ # execute command in new thread to ensure that API is
+ # not blocked by VNF
t = threading.Thread(target=c.cmdPrint, args=(cmd,))
t.daemon = True
t.start()
@@ -105,7 +104,8 @@
logging.debug("API CALL: compute status")
try:
- return dcs.get(dc_label).containers.get(compute_name).getStatus(), 200, CORS_HEADER
+ return dcs.get(dc_label).containers.get(
+ compute_name).getStatus(), 200, CORS_HEADER
except Exception as ex:
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
@@ -113,7 +113,8 @@
def delete(self, dc_label, compute_name):
logging.debug("API CALL: compute stop")
try:
- return dcs.get(dc_label).stopCompute(compute_name), 200, CORS_HEADER
+ return dcs.get(dc_label).stopCompute(
+ compute_name), 200, CORS_HEADER
except Exception as ex:
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
@@ -152,20 +153,25 @@
all_containers += dc.listCompute()
all_extSAPs += dc.listExtSAPs()
- extSAP_list = [(sap.name, sap.getStatus()) for sap in all_extSAPs]
- container_list = [(c.name, c.getStatus()) for c in all_containers]
+ extSAP_list = [(sap.name, sap.getStatus())
+ for sap in all_extSAPs]
+ container_list = [(c.name, c.getStatus())
+ for c in all_containers]
total_list = container_list + extSAP_list
return total_list, 200, CORS_HEADER
else:
# return list of compute nodes for specified DC
- container_list = [(c.name, c.getStatus()) for c in dcs.get(dc_label).listCompute()]
- extSAP_list = [(sap.name, sap.getStatus()) for sap in dcs.get(dc_label).listExtSAPs()]
+ container_list = [(c.name, c.getStatus())
+ for c in dcs.get(dc_label).listCompute()]
+ extSAP_list = [(sap.name, sap.getStatus())
+ for sap in dcs.get(dc_label).listExtSAPs()]
total_list = container_list + extSAP_list
return total_list, 200, CORS_HEADER
except Exception as ex:
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
+
class ComputeResources(Resource):
"""
Update the container's resources using the docker.update function
@@ -206,8 +212,9 @@
# then no data
if params is None:
params = {}
- logging.debug("REST CALL: update container resources {0}".format(params))
- #check if container exists
+ logging.debug(
+ "REST CALL: update container resources {0}".format(params))
+ # check if container exists
d = dcs.get(dc_label).net.getNodeByName(compute_name)
# general request of cpu percentage
@@ -217,24 +224,26 @@
cpu_period = int(dcs.get(dc_label).net.cpu_period)
value = params.get('cpu_bw')
cpu_quota = int(cpu_period * float(value))
- #put default values back
+ # put default values back
if float(value) <= 0:
cpu_period = 100000
cpu_quota = -1
params['cpu_period'] = cpu_period
params['cpu_quota'] = cpu_quota
- #d.updateCpuLimit(cpu_period=cpu_period, cpu_quota=cpu_quota)
+ # d.updateCpuLimit(cpu_period=cpu_period, cpu_quota=cpu_quota)
# only pass allowed keys to docker
allowed_keys = ['blkio_weight', 'cpu_period', 'cpu_quota', 'cpu_shares', 'cpuset_cpus',
'cpuset_mems', 'mem_limit', 'mem_reservation', 'memswap_limit',
'kernel_memory', 'restart_policy']
- filtered_params = {key:params[key] for key in allowed_keys if key in params}
+ filtered_params = {key: params[key]
+ for key in allowed_keys if key in params}
d.update_resources(**filtered_params)
return d
+
class DatacenterList(Resource):
global dcs
diff --git a/src/emuvim/api/rest/monitor.py b/src/emuvim/api/rest/monitor.py
index bf0f26b..094f122 100755
--- a/src/emuvim/api/rest/monitor.py
+++ b/src/emuvim/api/rest/monitor.py
@@ -1,41 +1,35 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-"""
-Distributed Cloud Emulator (dcemulator)
-Networking and monitoring functions
-(c) 2015 by Steven Van Rossem <steven.vanrossem@intec.ugent.be>
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
+#
+# Distributed Cloud Emulator (dcemulator)
+# Networking and monitoring functions
+# (c) 2015 by Steven Van Rossem <steven.vanrossem@intec.ugent.be>
import logging
-from flask_restful import Resource, reqparse
+from flask_restful import Resource
from flask import request
-import json
logging.basicConfig()
@@ -44,7 +38,6 @@
net = None
-
class MonitorInterfaceAction(Resource):
"""
Monitor the counters of a VNF interface
@@ -68,11 +61,13 @@
try:
if cookie:
- c = net.monitor_agent.setup_flow(vnf_name, vnf_interface, metric, cookie)
+ c = net.monitor_agent.setup_flow(
+ vnf_name, vnf_interface, metric, cookie)
else:
- c = net.monitor_agent.setup_metric(vnf_name, vnf_interface, metric)
+ c = net.monitor_agent.setup_metric(
+ vnf_name, vnf_interface, metric)
# return monitor message response
- return str(c), 200, CORS_HEADER
+ return str(c), 200, CORS_HEADER
except Exception as ex:
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
@@ -90,9 +85,11 @@
try:
if cookie:
- c = net.monitor_agent.stop_flow(vnf_name, vnf_interface, metric, cookie)
+ c = net.monitor_agent.stop_flow(
+ vnf_name, vnf_interface, metric, cookie)
else:
- c = net.monitor_agent.stop_metric(vnf_name, vnf_interface, metric)
+ c = net.monitor_agent.stop_metric(
+ vnf_name, vnf_interface, metric)
# return monitor message response
return str(c), 200, CORS_HEADER
except Exception as ex:
@@ -123,7 +120,8 @@
cookie = data.get("cookie", 0)
try:
- c = net.monitor_agent.setup_flow(vnf_name, vnf_interface, metric, cookie)
+ c = net.monitor_agent.setup_flow(
+ vnf_name, vnf_interface, metric, cookie)
# return monitor message response
return str(c), 200, CORS_HEADER
except Exception as ex:
@@ -142,13 +140,15 @@
cookie = data.get("cookie", 0)
try:
- c = net.monitor_agent.stop_flow(vnf_name, vnf_interface, metric, cookie)
+ c = net.monitor_agent.stop_flow(
+ vnf_name, vnf_interface, metric, cookie)
# return monitor message response
return str(c), 200, CORS_HEADER
except Exception as ex:
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
+
class MonitorLinkAction(Resource):
"""
Add or remove flow monitoring on chains between VNFs.
@@ -171,7 +171,8 @@
:return: message string indicating if the chain action is succesful or not
"""
- # the global net is set from the topology file, and connected via connectDCNetwork function in rest_api_endpoint.py
+ # the global net is set from the topology file, and connected via
+ # connectDCNetwork function in rest_api_endpoint.py
global net
def put(self):
@@ -222,7 +223,7 @@
monitor = data.get("monitor")
monitor_placement = data.get("monitor_placement")
- #first install monitor flow
+ # first install monitor flow
c1 = net.setChain(
vnf_src_name, vnf_dst_name,
vnf_src_interface=vnf_src_interface,
@@ -237,7 +238,7 @@
monitor=monitor,
monitor_placement=monitor_placement)
- #then export monitor flow
+ # then export monitor flow
metric = data.get("metric")
if 'rx' in monitor_placement:
vnf_name = vnf_dst_name
@@ -248,9 +249,11 @@
c2 = 'command unknown'
if command == 'add-flow':
- c2 = net.monitor_agent.setup_flow(vnf_name, vnf_interface, metric, cookie)
+ c2 = net.monitor_agent.setup_flow(
+ vnf_name, vnf_interface, metric, cookie)
elif command == 'del-flows':
- c2 = net.monitor_agent.stop_flow(vnf_name, vnf_interface, metric, cookie)
+ c2 = net.monitor_agent.stop_flow(
+ vnf_name, vnf_interface, metric, cookie)
# return setChain response
return (str(c1) + " " + str(c2)), 200, CORS_HEADER
@@ -258,6 +261,7 @@
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
+
class MonitorSkewAction(Resource):
"""
Monitor the counters of a VNF interface
@@ -277,10 +281,11 @@
resource_name = data.get("resource_name", 'cpu')
try:
# configure skewmon
- c = net.monitor_agent.update_skewmon(vnf_name, resource_name, action='start')
+ c = net.monitor_agent.update_skewmon(
+ vnf_name, resource_name, action='start')
# return monitor message response
- return str(c), 200, CORS_HEADER
+ return str(c), 200, CORS_HEADER
except Exception as ex:
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
@@ -295,7 +300,8 @@
resource_name = data.get("resource_name", 'cpu')
try:
# configure skewmon
- c = net.monitor_agent.update_skewmon(vnf_name, resource_name, action='stop')
+ c = net.monitor_agent.update_skewmon(
+ vnf_name, resource_name, action='stop')
# return monitor message response
return str(c), 200, CORS_HEADER
@@ -303,6 +309,7 @@
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
+
class MonitorTerminal(Resource):
"""
start a terminal for the selected VNFs
@@ -323,7 +330,7 @@
c = net.monitor_agent.term(vnf_list)
# return monitor message response
- return str(c), 200, CORS_HEADER
+ return str(c), 200, CORS_HEADER
except Exception as ex:
logging.exception("API error.")
return ex.message, 500, CORS_HEADER
diff --git a/src/emuvim/api/rest/network.py b/src/emuvim/api/rest/network.py
index 9aab1e6..e8c6b9a 100755
--- a/src/emuvim/api/rest/network.py
+++ b/src/emuvim/api/rest/network.py
@@ -1,48 +1,43 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-"""
-Distributed Cloud Emulator (dcemulator)
-Networking and monitoring functions
-(c) 2015 by Steven Van Rossem <steven.vanrossem@intec.ugent.be>
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
+#
+# Distributed Cloud Emulator (dcemulator)
+# Networking and monitoring functions
+# (c) 2015 by Steven Van Rossem <steven.vanrossem@intec.ugent.be>
import logging
from flask_restful import Resource
from flask import request
-import json
import networkx
logging.basicConfig()
CORS_HEADER = {'Access-Control-Allow-Origin': '*'}
-# the global net is set from the topology file, and connected via connectDCNetwork function in rest_api_endpoint.py
+# the global net is set from the topology file, and connected via
+# connectDCNetwork function in rest_api_endpoint.py
net = None
@@ -135,9 +130,8 @@
node_attr = networkx.get_node_attributes(net.DCNetwork_graph, 'type')
for node_name in net.DCNetwork_graph.nodes():
nodes2.append(node_name)
- node_index = nodes2.index(node_name)
type = node_attr[node_name]
- node_dict = {"name":node_name,"group":type}
+ node_dict = {"name": node_name, "group": type}
nodes.append(node_dict)
# add links between other DCs
@@ -145,8 +139,9 @@
node1_index = nodes2.index(node1_name)
for node2_name in net.DCNetwork_graph.neighbors(node1_name):
node2_index = nodes2.index(node2_name)
- edge_dict = {"source": node1_index, "target": node2_index, "value": 10}
+ edge_dict = {"source": node1_index,
+ "target": node2_index, "value": 10}
links.append(edge_dict)
- json = {"nodes":nodes, "links":links}
+ json = {"nodes": nodes, "links": links}
return json, 200, CORS_HEADER
diff --git a/src/emuvim/api/rest/rest_api_endpoint.py b/src/emuvim/api/rest/rest_api_endpoint.py
index a980dc9..4f9d6d8 100755
--- a/src/emuvim/api/rest/rest_api_endpoint.py
+++ b/src/emuvim/api/rest/rest_api_endpoint.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
import threading
@@ -34,7 +32,7 @@
# need to import total module to set its global variable dcs
import compute
-from compute import dcs, ComputeList, Compute, ComputeResources, DatacenterList, DatacenterStatus
+from compute import ComputeList, Compute, ComputeResources, DatacenterList, DatacenterStatus
# need to import total module to set its global variable net
import network
@@ -60,31 +58,36 @@
self.ip = listenip
self.port = port
- # connect this DC network to the rest api endpoint (needed for the networking and monitoring api)
+ # connect this DC network to the rest api endpoint (needed for the
+ # networking and monitoring api)
self.connectDCNetwork(DCnetwork)
# setup Flask
# find directory of dashboard files
- dashboard_file = pkg_resources.resource_filename('emuvim.dashboard', "index.html")
+ dashboard_file = pkg_resources.resource_filename(
+ 'emuvim.dashboard', "index.html")
dashboard_dir = path.dirname(dashboard_file)
logging.info("Started emu dashboard: {0}".format(dashboard_dir))
- self.app = Flask(__name__, static_folder=dashboard_dir, static_url_path='/dashboard')
+ self.app = Flask(__name__, static_folder=dashboard_dir,
+ static_url_path='/dashboard')
self.api = Api(self.app)
# setup endpoints
# compute related actions (start/stop VNFs, get info)
- self.api.add_resource(Compute, "/restapi/compute/<dc_label>/<compute_name>")
+ self.api.add_resource(
+ Compute, "/restapi/compute/<dc_label>/<compute_name>")
self.api.add_resource(ComputeList,
- "/restapi/compute",
- "/restapi/compute/<dc_label>")
- self.api.add_resource(ComputeResources, "/restapi/compute/resources/<dc_label>/<compute_name>")
+ "/restapi/compute",
+ "/restapi/compute/<dc_label>")
+ self.api.add_resource(
+ ComputeResources, "/restapi/compute/resources/<dc_label>/<compute_name>")
- self.api.add_resource(DatacenterStatus, "/restapi/datacenter/<dc_label>")
+ self.api.add_resource(
+ DatacenterStatus, "/restapi/datacenter/<dc_label>")
self.api.add_resource(DatacenterList, "/restapi/datacenter")
-
# network related actions (setup chaining between VNFs)
self.api.add_resource(NetworkAction,
"/restapi/network")
@@ -95,7 +98,8 @@
# export a network interface traffic rate counter
self.api.add_resource(MonitorInterfaceAction,
"/restapi/monitor/interface")
- # export flow traffic counter, of a manually pre-installed flow entry, specified by its cookie
+ # export flow traffic counter, of a manually pre-installed flow entry,
+ # specified by its cookie
self.api.add_resource(MonitorFlowAction,
"/restapi/monitor/flow")
# install monitoring of a specific flow on a pre-existing link in the service.
@@ -110,9 +114,8 @@
self.api.add_resource(MonitorTerminal,
"/restapi/monitor/term")
-
- logging.debug("Created API endpoint %s(%s:%d)" % (self.__class__.__name__, self.ip, self.port))
-
+ logging.debug("Created API endpoint %s(%s:%d)" %
+ (self.__class__.__name__, self.ip, self.port))
def connectDatacenter(self, dc):
compute.dcs[dc.label] = dc
@@ -130,18 +133,22 @@
self.thread = threading.Thread(target=self._start_flask, args=())
self.thread.daemon = True
self.thread.start()
- logging.info("Started API endpoint @ http://%s:%d" % (self.ip, self.port))
+ logging.info("Started API endpoint @ http://%s:%d" %
+ (self.ip, self.port))
def stop(self):
if self.http_server:
self.http_server.close()
def _start_flask(self):
- #self.app.run(self.ip, self.port, debug=False, use_reloader=False)
- #this should be a more production-fit http-server
- #self.app.logger.setLevel(logging.ERROR)
+ # self.app.run(self.ip, self.port, debug=False, use_reloader=False)
+ # this should be a more production-fit http-server
+ # self.app.logger.setLevel(logging.ERROR)
self.http_server = WSGIServer((self.ip, self.port),
- self.app,
- log=open("/dev/null", "w") # This disables HTTP request logs to not mess up the CLI when e.g. the auto-updated dashboard is used
- )
+ self.app,
+ # This disables HTTP request logs to not
+ # mess up the CLI when e.g. the
+ # auto-updated dashboard is used
+ log=open("/dev/null", "w")
+ )
self.http_server.serve_forever()
diff --git a/src/emuvim/api/sonata/__init__.py b/src/emuvim/api/sonata/__init__.py
index 879320c..44988d6 100755
--- a/src/emuvim/api/sonata/__init__.py
+++ b/src/emuvim/api/sonata/__init__.py
@@ -1,37 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-"""
-This module implements a simple REST API that behaves like SONATA's gatekeeper.
-
-It is only used to support the development of SONATA's SDK tools and to demonstrate
-the year 1 version of the emulator until the integration with WP4's orchestrator is done.
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
import threading
import dummygatekeeper as dgk
@@ -47,7 +38,7 @@
"""
def __init__(self, listenip, port, deploy_sap=False, docker_management=False,
- auto_deploy=False, auto_delete=False, sap_vnfd_path=None):
+ auto_deploy=False, auto_delete=False, sap_vnfd_path=None):
self.dcs = {}
self.ip = listenip
self.port = port
diff --git a/src/emuvim/api/sonata/dummygatekeeper.py b/src/emuvim/api/sonata/dummygatekeeper.py
index f20483b..59b1900 100755
--- a/src/emuvim/api/sonata/dummygatekeeper.py
+++ b/src/emuvim/api/sonata/dummygatekeeper.py
@@ -1,37 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-"""
-This module implements a simple REST API that behaves like SONATA's gatekeeper.
-
-It is only used to support the development of SONATA's SDK tools and to demonstrate
-the year 1 version of the emulator until the integration with WP4's orchestrator is done.
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
import os
import uuid
@@ -39,7 +30,7 @@
import zipfile
import yaml
import threading
-from docker import DockerClient, APIClient
+from docker import DockerClient
from flask import Flask, request
import flask_restful as fr
from collections import defaultdict
@@ -49,6 +40,7 @@
import ipaddress
import copy
import time
+from functools import reduce
logging.basicConfig()
LOG = logging.getLogger("sonata-dummy-gatekeeper")
@@ -62,28 +54,34 @@
# Enable Dockerfile build functionality
BUILD_DOCKERFILE = False
-# flag to indicate that we run without the emulator (only the bare API for integration testing)
+# flag to indicate that we run without the emulator (only the bare API for
+# integration testing)
GK_STANDALONE_MODE = False
# should a new version of an image be pulled even if its available
FORCE_PULL = False
# Automatically deploy SAPs (endpoints) of the service as new containers
-# Attention: This is not a configuration switch but a global variable! Don't change its default value.
+# Attention: This is not a configuration switch but a global variable!
+# Don't change its default value.
DEPLOY_SAP = False
-# flag to indicate if we use bidirectional forwarding rules in the automatic chaining process
+# flag to indicate if we use bidirectional forwarding rules in the
+# automatic chaining process
BIDIRECTIONAL_CHAIN = False
-# override the management interfaces in the descriptors with default docker0 interfaces in the containers
+# override the management interfaces in the descriptors with default
+# docker0 interfaces in the containers
USE_DOCKER_MGMT = False
-# automatically deploy uploaded packages (no need to execute son-access deploy --latest separately)
+# automatically deploy uploaded packages (no need to execute son-access
+# deploy --latest separately)
AUTO_DEPLOY = False
# and also automatically terminate any other running services
AUTO_DELETE = False
+
def generate_subnets(prefix, base, subnet_size=50, mask=24):
# Generate a list of ipaddress in subnets
r = list()
@@ -91,6 +89,8 @@
subnet = "{0}.{1}.0/{2}".format(prefix, net, mask)
r.append(ipaddress.ip_network(unicode(subnet)))
return r
+
+
# private subnet definitions for the generated interfaces
# 10.10.xxx.0/24
SAP_SUBNETS = generate_subnets('10.10', 0, subnet_size=50, mask=30)
@@ -100,18 +100,20 @@
ELINE_SUBNETS = generate_subnets('10.30', 0, subnet_size=50, mask=30)
# path to the VNFD for the SAP VNF that is deployed as internal SAP point
-SAP_VNFD=None
+SAP_VNFD = None
# Time in seconds to wait for vnf stop scripts to execute fully
VNF_STOP_WAIT_TIME = 5
+
class Gatekeeper(object):
def __init__(self):
self.services = dict()
self.dcs = dict()
self.net = None
- self.vnf_counter = 0 # used to generate short names for VNFs (Mininet limitation)
+ # used to generate short names for VNFs (Mininet limitation)
+ self.vnf_counter = 0
LOG.info("Create SONATA dummy gatekeeper.")
def register_service_package(self, service_uuid, service):
@@ -143,7 +145,8 @@
self.uuid = service_uuid
self.package_file_hash = package_file_hash
self.package_file_path = package_file_path
- self.package_content_path = os.path.join(CATALOG_FOLDER, "services/%s" % self.uuid)
+ self.package_content_path = os.path.join(
+ CATALOG_FOLDER, "services/%s" % self.uuid)
self.manifest = None
self.nsd = None
self.vnfds = dict()
@@ -194,9 +197,10 @@
self.instances[instance_uuid] = dict()
self.instances[instance_uuid]["vnf_instances"] = list()
- # 2. compute placement of this service instance (adds DC names to VNFDs)
+ # 2. compute placement of this service instance (adds DC names to
+ # VNFDs)
if not GK_STANDALONE_MODE:
- #self._calculate_placement(FirstDcPlacement)
+ # self._calculate_placement(FirstDcPlacement)
self._calculate_placement(RoundRobinDcPlacementWithSAPs)
# 3. start all vnfds that we have in the service (except SAPs)
for vnf_id in self.vnfds:
@@ -216,9 +220,11 @@
if "virtual_links" in self.nsd and "forwarding_graphs" in self.nsd:
vlinks = self.nsd["virtual_links"]
# constituent virtual links are not checked
- #fwd_links = self.nsd["forwarding_graphs"][0]["constituent_virtual_links"]
- eline_fwd_links = [l for l in vlinks if (l["connectivity_type"] == "E-Line")]
- elan_fwd_links = [l for l in vlinks if (l["connectivity_type"] == "E-LAN")]
+ # fwd_links = self.nsd["forwarding_graphs"][0]["constituent_virtual_links"]
+ eline_fwd_links = [l for l in vlinks if (
+ l["connectivity_type"] == "E-Line")]
+ elan_fwd_links = [l for l in vlinks if (
+ l["connectivity_type"] == "E-LAN")]
GK.net.deployed_elines.extend(eline_fwd_links)
GK.net.deployed_elans.extend(elan_fwd_links)
@@ -229,8 +235,10 @@
# 5b. deploy E-LAN links
self._connect_elans(elan_fwd_links, instance_uuid)
- # 6. run the emulator specific entrypoint scripts in the VNFIs of this service instance
- self._trigger_emulator_start_scripts_in_vnfis(self.instances[instance_uuid]["vnf_instances"])
+ # 6. run the emulator specific entrypoint scripts in the VNFIs of this
+ # service instance
+ self._trigger_emulator_start_scripts_in_vnfis(
+ self.instances[instance_uuid]["vnf_instances"])
LOG.info("Service started. Instance id: %r" % instance_uuid)
return instance_uuid
@@ -248,7 +256,8 @@
# instance_uuid = str(self.uuid.uuid4())
vnf_instances = self.instances[instance_uuid]["vnf_instances"]
- # trigger stop skripts in vnf instances and wait a few seconds for completion
+ # trigger stop skripts in vnf instances and wait a few seconds for
+ # completion
self._trigger_emulator_stop_scripts_in_vnfis(vnf_instances)
time.sleep(VNF_STOP_WAIT_TIME)
@@ -259,7 +268,8 @@
ext_sap = self.saps[sap_name]
target_dc = ext_sap.get("dc")
target_dc.removeExternalSAP(sap_name)
- LOG.info("Stopping the SAP instance: %r in DC %r" % (sap_name, target_dc))
+ LOG.info("Stopping the SAP instance: %r in DC %r" %
+ (sap_name, target_dc))
if not GK_STANDALONE_MODE:
# remove placement?
@@ -290,7 +300,8 @@
assert(docker_name is not None)
assert(target_dc is not None)
if not self._check_docker_image_exists(docker_name):
- raise Exception("Docker image %r not found. Abort." % docker_name)
+ raise Exception(
+ "Docker image %r not found. Abort." % docker_name)
# 3. get the resource limits
res_req = u.get("resource_requirements")
@@ -298,77 +309,88 @@
if cpu_list is None:
cpu_list = res_req.get("cpu").get("vcpus")
if cpu_list is None:
- cpu_list="1"
+ cpu_list = "1"
cpu_bw = res_req.get("cpu").get("cpu_bw")
if not cpu_bw:
- cpu_bw=1
+ cpu_bw = 1
mem_num = str(res_req.get("memory").get("size"))
- if len(mem_num)==0:
- mem_num="2"
+ if len(mem_num) == 0:
+ mem_num = "2"
mem_unit = str(res_req.get("memory").get("size_unit"))
- if str(mem_unit)==0:
- mem_unit="GB"
+ if str(mem_unit) == 0:
+ mem_unit = "GB"
mem_limit = float(mem_num)
- if mem_unit=="GB":
- mem_limit=mem_limit*1024*1024*1024
- elif mem_unit=="MB":
- mem_limit=mem_limit*1024*1024
- elif mem_unit=="KB":
- mem_limit=mem_limit*1024
+ if mem_unit == "GB":
+ mem_limit = mem_limit * 1024 * 1024 * 1024
+ elif mem_unit == "MB":
+ mem_limit = mem_limit * 1024 * 1024
+ elif mem_unit == "KB":
+ mem_limit = mem_limit * 1024
mem_lim = int(mem_limit)
- cpu_period, cpu_quota = self._calculate_cpu_cfs_values(float(cpu_bw))
+ cpu_period, cpu_quota = self._calculate_cpu_cfs_values(
+ float(cpu_bw))
- # check if we need to deploy the management ports (defined as type:management both on in the vnfd and nsd)
+ # check if we need to deploy the management ports (defined as
+ # type:management both on in the vnfd and nsd)
intfs = vnfd.get("connection_points", [])
mgmt_intf_names = []
if USE_DOCKER_MGMT:
- mgmt_intfs = [vnf_id + ':' + intf['id'] for intf in intfs if intf.get('type') == 'management']
- # check if any of these management interfaces are used in a management-type network in the nsd
+ mgmt_intfs = [vnf_id + ':' + intf['id']
+ for intf in intfs if intf.get('type') == 'management']
+ # check if any of these management interfaces are used in a
+ # management-type network in the nsd
for nsd_intf_name in mgmt_intfs:
- vlinks = [ l["connection_points_reference"] for l in self.nsd.get("virtual_links", [])]
+ vlinks = [l["connection_points_reference"]
+ for l in self.nsd.get("virtual_links", [])]
for link in vlinks:
- if nsd_intf_name in link and self.check_mgmt_interface(link):
- # this is indeed a management interface and can be skipped
- vnf_id, vnf_interface, vnf_sap_docker_name = parse_interface(nsd_intf_name)
- found_interfaces = [intf for intf in intfs if intf.get('id') == vnf_interface]
+ if nsd_intf_name in link and self.check_mgmt_interface(
+ link):
+ # this is indeed a management interface and can be
+ # skipped
+ vnf_id, vnf_interface, vnf_sap_docker_name = parse_interface(
+ nsd_intf_name)
+ found_interfaces = [
+ intf for intf in intfs if intf.get('id') == vnf_interface]
intfs.remove(found_interfaces[0])
mgmt_intf_names.append(vnf_interface)
# 4. generate the volume paths for the docker container
- volumes=list()
+ volumes = list()
# a volume to extract log files
- docker_log_path = "/tmp/results/%s/%s"%(self.uuid,vnf_id)
- LOG.debug("LOG path for vnf %s is %s."%(vnf_id,docker_log_path))
+ docker_log_path = "/tmp/results/%s/%s" % (self.uuid, vnf_id)
+ LOG.debug("LOG path for vnf %s is %s." % (vnf_id, docker_log_path))
if not os.path.exists(docker_log_path):
- LOG.debug("Creating folder %s"%docker_log_path)
+ LOG.debug("Creating folder %s" % docker_log_path)
os.makedirs(docker_log_path)
- volumes.append(docker_log_path+":/mnt/share/")
-
+ volumes.append(docker_log_path + ":/mnt/share/")
# 5. do the dc.startCompute(name="foobar") call to run the container
# TODO consider flavors, and other annotations
# TODO: get all vnf id's from the nsd for this vnfd and use those as dockername
# use the vnf_id in the nsd as docker name
# so deployed containers can be easily mapped back to the nsd
- LOG.info("Starting %r as %r in DC %r" % (vnf_name, vnf_id, vnfd.get("dc")))
+ LOG.info("Starting %r as %r in DC %r" %
+ (vnf_name, vnf_id, vnfd.get("dc")))
LOG.debug("Interfaces for %r: %r" % (vnf_id, intfs))
vnfi = target_dc.startCompute(
- vnf_id,
- network=intfs,
- image=docker_name,
- flavor_name="small",
- cpu_quota=cpu_quota,
- cpu_period=cpu_period,
- cpuset=cpu_list,
- mem_limit=mem_lim,
- volumes=volumes,
- type=kwargs.get('type','docker'))
+ vnf_id,
+ network=intfs,
+ image=docker_name,
+ flavor_name="small",
+ cpu_quota=cpu_quota,
+ cpu_period=cpu_period,
+ cpuset=cpu_list,
+ mem_limit=mem_lim,
+ volumes=volumes,
+ type=kwargs.get('type', 'docker'))
- # rename the docker0 interfaces (eth0) to the management port name defined in the VNFD
+ # rename the docker0 interfaces (eth0) to the management port name
+ # defined in the VNFD
if USE_DOCKER_MGMT:
for intf_name in mgmt_intf_names:
- self._vnf_reconfigure_network(vnfi, 'eth0', new_name=intf_name)
+ self._vnf_reconfigure_network(
+ vnfi, 'eth0', new_name=intf_name)
return vnfi
@@ -383,7 +405,8 @@
dc = vnfi.datacenter
# stop the vnfi
- LOG.info("Stopping the vnf instance contained in %r in DC %r" % (status["name"], dc))
+ LOG.info("Stopping the vnf instance contained in %r in DC %r" %
+ (status["name"], dc))
dc.stopCompute(status["name"])
def _get_vnf_instance(self, instance_uuid, vnf_id):
@@ -416,17 +439,18 @@
intf = vnfi.intf(intf=if_name)
if intf is not None:
intf.setIP(net_str)
- LOG.debug("Reconfigured network of %s:%s to %r" % (vnfi.name, if_name, net_str))
+ LOG.debug("Reconfigured network of %s:%s to %r" %
+ (vnfi.name, if_name, net_str))
else:
- LOG.warning("Interface not found: %s:%s. Network reconfiguration skipped." % (vnfi.name, if_name))
+ LOG.warning("Interface not found: %s:%s. Network reconfiguration skipped." % (
+ vnfi.name, if_name))
if new_name is not None:
vnfi.cmd('ip link set', if_name, 'down')
vnfi.cmd('ip link set', if_name, 'name', new_name)
vnfi.cmd('ip link set', new_name, 'up')
- LOG.debug("Reconfigured interface name of %s:%s to %s" % (vnfi.name, if_name, new_name))
-
-
+ LOG.debug("Reconfigured interface name of %s:%s to %s" %
+ (vnfi.name, if_name, new_name))
def _trigger_emulator_start_scripts_in_vnfis(self, vnfi_list):
for vnfi in vnfi_list:
@@ -434,10 +458,12 @@
env = config.get("Env", list())
for env_var in env:
var, cmd = map(str.strip, map(str, env_var.split('=', 1)))
- LOG.debug("%r = %r" % (var , cmd))
- if var=="SON_EMU_CMD":
- LOG.info("Executing entry point script in %r: %r" % (vnfi.name, cmd))
- # execute command in new thread to ensure that GK is not blocked by VNF
+ LOG.debug("%r = %r" % (var, cmd))
+ if var == "SON_EMU_CMD":
+ LOG.info("Executing entry point script in %r: %r" %
+ (vnfi.name, cmd))
+ # execute command in new thread to ensure that GK is not
+ # blocked by VNF
t = threading.Thread(target=vnfi.cmdPrint, args=(cmd,))
t.daemon = True
t.start()
@@ -448,15 +474,15 @@
env = config.get("Env", list())
for env_var in env:
var, cmd = map(str.strip, map(str, env_var.split('=', 1)))
- if var=="SON_EMU_CMD_STOP":
- LOG.info("Executing stop script in %r: %r" % (vnfi.name, cmd))
- # execute command in new thread to ensure that GK is not blocked by VNF
+ if var == "SON_EMU_CMD_STOP":
+ LOG.info("Executing stop script in %r: %r" %
+ (vnfi.name, cmd))
+ # execute command in new thread to ensure that GK is not
+ # blocked by VNF
t = threading.Thread(target=vnfi.cmdPrint, args=(cmd,))
t.daemon = True
t.start()
-
-
def _unpack_service_package(self):
"""
unzip *.son file and store contents in CATALOG_FOLDER/services/<service_uuid>/
@@ -465,7 +491,6 @@
with zipfile.ZipFile(self.package_file_path, "r") as z:
z.extractall(self.package_content_path)
-
def _load_package_descriptor(self):
"""
Load the main package descriptor YAML and keep it as dict.
@@ -488,7 +513,7 @@
GK.net.deployed_nsds.append(self.nsd)
# create dict to find the vnf_name for any vnf id
self.vnf_id2vnf_name = defaultdict(lambda: "NotExistingNode",
- reduce(lambda x, y: dict(x, **y),
+ reduce(lambda x, y: dict(x, **y),
map(lambda d: {d["vnf_id"]: d["vnf_name"]},
self.nsd["network_functions"])))
@@ -504,14 +529,15 @@
vnfd_set = dict()
if "package_content" in self.manifest:
for pc in self.manifest.get("package_content"):
- if pc.get("content-type") == "application/sonata.function_descriptor":
+ if pc.get(
+ "content-type") == "application/sonata.function_descriptor":
vnfd_path = os.path.join(
self.package_content_path,
make_relative_path(pc.get("name")))
vnfd = load_yaml(vnfd_path)
vnfd_set[vnfd.get("name")] = vnfd
# then link each vnf_id in the nsd to its vnfd
- for vnf_id in self.vnf_id2vnf_name:
+ for vnf_id in self.vnf_id2vnf_name:
vnf_name = self.vnf_id2vnf_name[vnf_id]
self.vnfds[vnf_id] = vnfd_set[vnf_name]
LOG.debug("Loaded VNFD: {0} id: {1}".format(vnf_name, vnf_id))
@@ -520,7 +546,8 @@
# create list of all SAPs
# check if we need to deploy management ports
if USE_DOCKER_MGMT:
- SAPs = [p for p in self.nsd["connection_points"] if 'management' not in p.get('type')]
+ SAPs = [p for p in self.nsd["connection_points"]
+ if 'management' not in p.get('type')]
else:
SAPs = [p for p in self.nsd["connection_points"]]
@@ -530,21 +557,26 @@
# make sure SAP has type set (default internal)
sap["type"] = sap.get("type", 'internal')
- # Each Service Access Point (connection_point) in the nsd is an IP address on the host
+ # Each Service Access Point (connection_point) in the nsd is an IP
+ # address on the host
if sap["type"] == "external":
# add to vnfds to calculate placement later on
sap_net = SAP_SUBNETS.pop(0)
- self.saps[sap_docker_name] = {"name": sap_docker_name , "type": "external", "net": sap_net}
+ self.saps[sap_docker_name] = {
+ "name": sap_docker_name, "type": "external", "net": sap_net}
# add SAP vnf to list in the NSD so it is deployed later on
- # each SAP gets a unique VNFD and vnf_id in the NSD and custom type (only defined in the dummygatekeeper)
+ # each SAP gets a unique VNFD and vnf_id in the NSD and custom
+ # type (only defined in the dummygatekeeper)
self.nsd["network_functions"].append(
{"vnf_id": sap_docker_name, "vnf_name": sap_docker_name, "vnf_type": "sap_ext"})
- # Each Service Access Point (connection_point) in the nsd is getting its own container (default)
+ # Each Service Access Point (connection_point) in the nsd is
+ # getting its own container (default)
elif sap["type"] == "internal" or sap["type"] == "management":
# add SAP to self.vnfds
if SAP_VNFD is None:
- sapfile = pkg_resources.resource_filename(__name__, "sap_vnfd.yml")
+ sapfile = pkg_resources.resource_filename(
+ __name__, "sap_vnfd.yml")
else:
sapfile = SAP_VNFD
sap_vnfd = load_yaml(sapfile)
@@ -558,17 +590,20 @@
self.nsd["network_functions"].append(
{"vnf_id": sap_docker_name, "vnf_name": sap_docker_name, "vnf_type": "sap_int"})
- LOG.debug("Loaded SAP: name: {0}, type: {1}".format(sap_docker_name, sap['type']))
+ LOG.debug("Loaded SAP: name: {0}, type: {1}".format(
+ sap_docker_name, sap['type']))
# create sap lists
- self.saps_ext = [self.saps[sap]['name'] for sap in self.saps if self.saps[sap]["type"] == "external"]
- self.saps_int = [self.saps[sap]['name'] for sap in self.saps if self.saps[sap]["type"] == "internal"]
+ self.saps_ext = [self.saps[sap]['name']
+ for sap in self.saps if self.saps[sap]["type"] == "external"]
+ self.saps_int = [self.saps[sap]['name']
+ for sap in self.saps if self.saps[sap]["type"] == "internal"]
def _start_sap(self, sap, instance_uuid):
if not DEPLOY_SAP:
return
- LOG.info('start SAP: {0} ,type: {1}'.format(sap['name'],sap['type']))
+ LOG.info('start SAP: {0} ,type: {1}'.format(sap['name'], sap['type']))
if sap["type"] == "internal":
vnfi = None
if not GK_STANDALONE_MODE:
@@ -593,39 +628,49 @@
for link in eline_fwd_links:
# check if we need to deploy this link when its a management link:
if USE_DOCKER_MGMT:
- if self.check_mgmt_interface(link["connection_points_reference"]):
+ if self.check_mgmt_interface(
+ link["connection_points_reference"]):
continue
- src_id, src_if_name, src_sap_id = parse_interface(link["connection_points_reference"][0])
- dst_id, dst_if_name, dst_sap_id = parse_interface(link["connection_points_reference"][1])
+ src_id, src_if_name, src_sap_id = parse_interface(
+ link["connection_points_reference"][0])
+ dst_id, dst_if_name, dst_sap_id = parse_interface(
+ link["connection_points_reference"][1])
setChaining = False
# check if there is a SAP in the link and chain everything together
if src_sap_id in self.saps and dst_sap_id in self.saps:
- LOG.info('2 SAPs cannot be chained together : {0} - {1}'.format(src_sap_id, dst_sap_id))
+ LOG.info(
+ '2 SAPs cannot be chained together : {0} - {1}'.format(src_sap_id, dst_sap_id))
continue
elif src_sap_id in self.saps_ext:
src_id = src_sap_id
- # set intf name to None so the chaining function will choose the first one
+ # set intf name to None so the chaining function will choose
+ # the first one
src_if_name = None
dst_vnfi = self._get_vnf_instance(instance_uuid, dst_id)
if dst_vnfi is not None:
# choose first ip address in sap subnet
sap_net = self.saps[src_sap_id]['net']
- sap_ip = "{0}/{1}".format(str(sap_net[2]), sap_net.prefixlen)
- self._vnf_reconfigure_network(dst_vnfi, dst_if_name, sap_ip)
+ sap_ip = "{0}/{1}".format(str(sap_net[2]),
+ sap_net.prefixlen)
+ self._vnf_reconfigure_network(
+ dst_vnfi, dst_if_name, sap_ip)
setChaining = True
elif dst_sap_id in self.saps_ext:
dst_id = dst_sap_id
- # set intf name to None so the chaining function will choose the first one
+ # set intf name to None so the chaining function will choose
+ # the first one
dst_if_name = None
src_vnfi = self._get_vnf_instance(instance_uuid, src_id)
if src_vnfi is not None:
sap_net = self.saps[dst_sap_id]['net']
- sap_ip = "{0}/{1}".format(str(sap_net[2]), sap_net.prefixlen)
- self._vnf_reconfigure_network(src_vnfi, src_if_name, sap_ip)
+ sap_ip = "{0}/{1}".format(str(sap_net[2]),
+ sap_net.prefixlen)
+ self._vnf_reconfigure_network(
+ src_vnfi, src_if_name, sap_ip)
setChaining = True
# Link between 2 VNFs
@@ -635,20 +680,23 @@
src_id = src_sap_id
if dst_sap_id in self.saps_int:
dst_id = dst_sap_id
- # re-configure the VNFs IP assignment and ensure that a new subnet is used for each E-Link
+ # re-configure the VNFs IP assignment and ensure that a new
+ # subnet is used for each E-Link
src_vnfi = self._get_vnf_instance(instance_uuid, src_id)
dst_vnfi = self._get_vnf_instance(instance_uuid, dst_id)
if src_vnfi is not None and dst_vnfi is not None:
eline_net = ELINE_SUBNETS.pop(0)
- ip1 = "{0}/{1}".format(str(eline_net[1]), eline_net.prefixlen)
- ip2 = "{0}/{1}".format(str(eline_net[2]), eline_net.prefixlen)
+ ip1 = "{0}/{1}".format(str(eline_net[1]),
+ eline_net.prefixlen)
+ ip2 = "{0}/{1}".format(str(eline_net[2]),
+ eline_net.prefixlen)
self._vnf_reconfigure_network(src_vnfi, src_if_name, ip1)
self._vnf_reconfigure_network(dst_vnfi, dst_if_name, ip2)
setChaining = True
# Set the chaining
if setChaining:
- ret = GK.net.setChain(
+ GK.net.setChain(
src_id, dst_id,
vnf_src_interface=src_if_name, vnf_dst_interface=dst_if_name,
bidirectional=BIDIRECTIONAL_CHAIN, cmd="add-flow", cookie=cookie, priority=10)
@@ -656,7 +704,6 @@
"Setting up E-Line link. (%s:%s) -> (%s:%s)" % (
src_id, src_if_name, dst_id, dst_if_name))
-
def _connect_elans(self, elan_fwd_links, instance_uuid):
"""
Connect all E-LAN links in the NSD
@@ -667,17 +714,18 @@
for link in elan_fwd_links:
# check if we need to deploy this link when its a management link:
if USE_DOCKER_MGMT:
- if self.check_mgmt_interface(link["connection_points_reference"]):
+ if self.check_mgmt_interface(
+ link["connection_points_reference"]):
continue
elan_vnf_list = []
- # check if an external SAP is in the E-LAN (then a subnet is already defined)
+ # check if an external SAP is in the E-LAN (then a subnet is
+ # already defined)
intfs_elan = [intf for intf in link["connection_points_reference"]]
lan_sap = self.check_ext_saps(intfs_elan)
if lan_sap:
lan_net = self.saps[lan_sap]['net']
lan_hosts = list(lan_net.hosts())
- sap_ip = str(lan_hosts.pop(0))
else:
lan_net = ELAN_SUBNETS.pop(0)
lan_hosts = list(lan_net.hosts())
@@ -686,12 +734,15 @@
for intf in link["connection_points_reference"]:
# skip external SAPs, they already have an ip
- vnf_id, vnf_interface, vnf_sap_docker_name = parse_interface(intf)
+ vnf_id, vnf_interface, vnf_sap_docker_name = parse_interface(
+ intf)
if vnf_sap_docker_name in self.saps_ext:
- elan_vnf_list.append({'name': vnf_sap_docker_name, 'interface': vnf_interface})
+ elan_vnf_list.append(
+ {'name': vnf_sap_docker_name, 'interface': vnf_interface})
continue
- ip_address = "{0}/{1}".format(str(lan_hosts.pop(0)), lan_net.prefixlen)
+ ip_address = "{0}/{1}".format(str(lan_hosts.pop(0)),
+ lan_net.prefixlen)
vnf_id, intf_name, vnf_sap_id = parse_interface(intf)
# make sure we use the correct sap vnf name
@@ -711,12 +762,12 @@
if vnfi is not None:
self._vnf_reconfigure_network(vnfi, intf_name, ip_address)
# add this vnf and interface to the E-LAN for tagging
- elan_vnf_list.append({'name': src_docker_name, 'interface': intf_name})
+ elan_vnf_list.append(
+ {'name': src_docker_name, 'interface': intf_name})
# install the VLAN tags for this E-LAN
GK.net.setLAN(elan_vnf_list)
-
def _load_docker_files(self):
"""
Get all paths to Dockerfiles from VNFDs and store them in dict.
@@ -737,7 +788,8 @@
Get all URLs to pre-build docker images in some repo.
:return:
"""
- # also merge sap dicts, because internal saps also need a docker container
+ # also merge sap dicts, because internal saps also need a docker
+ # container
all_vnfs = self.vnfds.copy()
all_vnfs.update(self.saps)
@@ -748,7 +800,8 @@
if url is not None:
url = url.replace("http://", "")
self.remote_docker_image_urls[k] = url
- LOG.debug("Found Docker image URL (%r): %r" % (k, self.remote_docker_image_urls[k]))
+ LOG.debug("Found Docker image URL (%r): %r" %
+ (k, self.remote_docker_image_urls[k]))
def _build_images_from_dockerfiles(self):
"""
@@ -757,9 +810,11 @@
if GK_STANDALONE_MODE:
return # do not build anything in standalone mode
dc = DockerClient()
- LOG.info("Building %d Docker images (this may take several minutes) ..." % len(self.local_docker_files))
+ LOG.info("Building %d Docker images (this may take several minutes) ..." % len(
+ self.local_docker_files))
for k, v in self.local_docker_files.iteritems():
- for line in dc.build(path=v.replace("Dockerfile", ""), tag=k, rm=False, nocache=False):
+ for line in dc.build(path=v.replace(
+ "Dockerfile", ""), tag=k, rm=False, nocache=False):
LOG.debug("DOCKER BUILD: %s" % line)
LOG.info("Docker image created: %s" % k)
@@ -769,7 +824,8 @@
"""
dc = DockerClient()
for url in self.remote_docker_image_urls.itervalues():
- if not FORCE_PULL: # only pull if not present (speedup for development)
+ # only pull if not present (speedup for development)
+ if not FORCE_PULL:
if len(dc.images.list(name=url)) > 0:
LOG.debug("Image %r present. Skipping pull." % url)
continue
@@ -777,16 +833,13 @@
# this seems to fail with latest docker api version 2.0.2
# dc.images.pull(url,
# insecure_registry=True)
- #using docker cli instead
+ # using docker cli instead
cmd = ["docker",
"pull",
url,
]
Popen(cmd).wait()
-
-
-
def _check_docker_image_exists(self, image_name):
"""
Query the docker service and check if the given image exists
@@ -814,7 +867,6 @@
sap_dict = self.saps[sap]
LOG.info("Placed SAP %r on DC %r" % (sap, str(sap_dict.get("dc"))))
-
def _calculate_cpu_cfs_values(self, cpu_time_percentage):
"""
Calculate cpu period and quota for CFS
@@ -828,30 +880,38 @@
# (see: https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt)
# Attention minimum cpu_quota is 1ms (micro)
cpu_period = 1000000 # lets consider a fixed period of 1000000 microseconds for now
- LOG.debug("cpu_period is %r, cpu_percentage is %r" % (cpu_period, cpu_time_percentage))
- cpu_quota = cpu_period * cpu_time_percentage # calculate the fraction of cpu time for this container
- # ATTENTION >= 1000 to avoid a invalid argument system error ... no idea why
+ LOG.debug("cpu_period is %r, cpu_percentage is %r" %
+ (cpu_period, cpu_time_percentage))
+ # calculate the fraction of cpu time for this container
+ cpu_quota = cpu_period * cpu_time_percentage
+ # ATTENTION >= 1000 to avoid a invalid argument system error ... no
+ # idea why
if cpu_quota < 1000:
LOG.debug("cpu_quota before correcting: %r" % cpu_quota)
cpu_quota = 1000
LOG.warning("Increased CPU quota to avoid system error.")
- LOG.debug("Calculated: cpu_period=%f / cpu_quota=%f" % (cpu_period, cpu_quota))
+ LOG.debug("Calculated: cpu_period=%f / cpu_quota=%f" %
+ (cpu_period, cpu_quota))
return int(cpu_period), int(cpu_quota)
def check_ext_saps(self, intf_list):
# check if the list of interfacs contains an external SAP
- saps_ext = [self.saps[sap]['name'] for sap in self.saps if self.saps[sap]["type"] == "external"]
+ saps_ext = [self.saps[sap]['name']
+ for sap in self.saps if self.saps[sap]["type"] == "external"]
for intf_name in intf_list:
- vnf_id, vnf_interface, vnf_sap_docker_name = parse_interface(intf_name)
+ vnf_id, vnf_interface, vnf_sap_docker_name = parse_interface(
+ intf_name)
if vnf_sap_docker_name in saps_ext:
return vnf_sap_docker_name
def check_mgmt_interface(self, intf_list):
- SAPs_mgmt = [p.get('id') for p in self.nsd["connection_points"] if 'management' in p.get('type')]
+ SAPs_mgmt = [p.get('id') for p in self.nsd["connection_points"]
+ if 'management' in p.get('type')]
for intf_name in intf_list:
if intf_name in SAPs_mgmt:
return True
+
"""
Some (simple) placement algorithms
"""
@@ -861,6 +921,7 @@
"""
Placement: Always use one and the same data center from the GK.dcs dict.
"""
+
def place(self, nsd, vnfds, saps, dcs):
for id, vnfd in vnfds.iteritems():
vnfd["dc"] = list(dcs.itervalues())[0]
@@ -870,6 +931,7 @@
"""
Placement: Distribute VNFs across all available DCs in a round robin fashion.
"""
+
def place(self, nsd, vnfds, saps, dcs):
c = 0
dcs_list = list(dcs.itervalues())
@@ -877,11 +939,13 @@
vnfd["dc"] = dcs_list[c % len(dcs_list)]
c += 1 # inc. c to use next DC
+
class RoundRobinDcPlacementWithSAPs(object):
"""
Placement: Distribute VNFs across all available DCs in a round robin fashion,
every SAP is instantiated on the same DC as the connected VNF.
"""
+
def place(self, nsd, vnfds, saps, dcs):
# place vnfs
@@ -893,13 +957,18 @@
# place SAPs
vlinks = nsd.get("virtual_links", [])
- eline_fwd_links = [l for l in vlinks if (l["connectivity_type"] == "E-Line")]
- elan_fwd_links = [l for l in vlinks if (l["connectivity_type"] == "E-LAN")]
+ eline_fwd_links = [l for l in vlinks if (
+ l["connectivity_type"] == "E-Line")]
+ elan_fwd_links = [l for l in vlinks if (
+ l["connectivity_type"] == "E-LAN")]
- # SAPs on E-Line links are placed on the same DC as the VNF on the E-Line
+ # SAPs on E-Line links are placed on the same DC as the VNF on the
+ # E-Line
for link in eline_fwd_links:
- src_id, src_if_name, src_sap_id = parse_interface(link["connection_points_reference"][0])
- dst_id, dst_if_name, dst_sap_id = parse_interface(link["connection_points_reference"][1])
+ src_id, src_if_name, src_sap_id = parse_interface(
+ link["connection_points_reference"][0])
+ dst_id, dst_if_name, dst_sap_id = parse_interface(
+ link["connection_points_reference"][1])
# check if there is a SAP in the link
if src_sap_id in saps:
@@ -920,11 +989,10 @@
# find SAP interfaces
intf_id, intf_name, intf_sap_id = parse_interface(intf)
if intf_sap_id in saps:
- dc = dcs_list[randint(0, dc_len-1)]
+ dc = dcs_list[randint(0, dc_len - 1)]
saps[intf_sap_id]['dc'] = dc
-
"""
Resource definitions and API endpoints
"""
@@ -950,7 +1018,8 @@
elif len(request.data) > 0:
son_file = request.data
else:
- return {"service_uuid": None, "size": 0, "sha1": None, "error": "upload failed. file not found."}, 500
+ return {"service_uuid": None, "size": 0, "sha1": None,
+ "error": "upload failed. file not found."}, 500
# generate a uuid to reference this package
service_uuid = str(uuid.uuid4())
file_hash = hashlib.sha1(str(son_file)).hexdigest()
@@ -969,11 +1038,14 @@
if AUTO_DELETE:
service_list = copy.copy(GK.services)
for service_uuid in service_list:
- instances_list = copy.copy(GK.services[service_uuid].instances)
+ instances_list = copy.copy(
+ GK.services[service_uuid].instances)
for instance_uuid in instances_list:
# valid service and instance UUID, stop service
- GK.services.get(service_uuid).stop_service(instance_uuid)
- LOG.info("service instance with uuid %r stopped." % instance_uuid)
+ GK.services.get(service_uuid).stop_service(
+ instance_uuid)
+ LOG.info("service instance with uuid %r stopped." %
+ instance_uuid)
# create a service object and register it
s = Service(service_uuid, file_hash, upload_path)
@@ -983,13 +1055,15 @@
if AUTO_DEPLOY:
# ok, we have a service uuid, lets start the service
reset_subnets()
- service_instance_uuid = GK.services.get(service_uuid).start_service()
+ GK.services.get(service_uuid).start_service()
# generate the JSON result
- return {"service_uuid": service_uuid, "size": size, "sha1": file_hash, "error": None}, 201
- except Exception as ex:
+ return {"service_uuid": service_uuid, "size": size,
+ "sha1": file_hash, "error": None}, 201
+ except BaseException:
LOG.exception("Service package upload failed:")
- return {"service_uuid": None, "size": 0, "sha1": None, "error": "upload failed"}, 500
+ return {"service_uuid": None, "size": 0,
+ "sha1": None, "error": "upload failed"}, 500
def get(self):
"""
@@ -1014,12 +1088,15 @@
service_uuid = json_data.get("service_uuid")
# lets be a bit fuzzy here to make testing easier
- if (service_uuid is None or service_uuid=="latest") and len(GK.services) > 0:
- # if we don't get a service uuid, we simple start the first service in the list
+ if (service_uuid is None or service_uuid ==
+ "latest") and len(GK.services) > 0:
+ # if we don't get a service uuid, we simple start the first service
+ # in the list
service_uuid = list(GK.services.iterkeys())[0]
if service_uuid in GK.services:
# ok, we have a service uuid, lets start the service
- service_instance_uuid = GK.services.get(service_uuid).start_service()
+ service_instance_uuid = GK.services.get(
+ service_uuid).start_service()
return {"service_instance_uuid": service_instance_uuid}, 201
return "Service not found", 404
@@ -1043,17 +1120,21 @@
# try to be fuzzy
if service_uuid is None and len(GK.services) > 0:
- #if we don't get a service uuid, we simply stop the last service in the list
+ # if we don't get a service uuid, we simply stop the last service
+ # in the list
service_uuid = list(GK.services.iterkeys())[0]
- if instance_uuid is None and len(GK.services[service_uuid].instances) > 0:
- instance_uuid = list(GK.services[service_uuid].instances.iterkeys())[0]
+ if instance_uuid is None and len(
+ GK.services[service_uuid].instances) > 0:
+ instance_uuid = list(
+ GK.services[service_uuid].instances.iterkeys())[0]
if service_uuid in GK.services and instance_uuid in GK.services[service_uuid].instances:
# valid service and instance UUID, stop service
GK.services.get(service_uuid).stop_service(instance_uuid)
- return "service instance with uuid %r stopped." % instance_uuid,200
+ return "service instance with uuid %r stopped." % instance_uuid, 200
return "Service not found", 404
+
class Exit(fr.Resource):
def put(self):
@@ -1068,7 +1149,6 @@
GK = Gatekeeper()
-
# create a single, global GK object
GK = None
initialize_GK()
@@ -1078,11 +1158,11 @@
api = fr.Api(app)
# define endpoints
api.add_resource(Packages, '/packages', '/api/v2/packages')
-api.add_resource(Instantiations, '/instantiations', '/api/v2/instantiations', '/api/v2/requests')
+api.add_resource(Instantiations, '/instantiations',
+ '/api/v2/instantiations', '/api/v2/requests')
api.add_resource(Exit, '/emulator/exit')
-
def start_rest_api(host, port, datacenters=dict()):
GK.dcs = datacenters
GK.net = get_dc_network()
@@ -1104,7 +1184,7 @@
try:
r = yaml.load(f)
except yaml.YAMLError as exc:
- LOG.exception("YAML parse error")
+ LOG.exception("YAML parse error: %r" % str(exc))
r = dict()
return r
@@ -1144,6 +1224,7 @@
return vnf_id, vnf_interface, vnf_sap_docker_name
+
def reset_subnets():
# private subnet definitions for the generated interfaces
# 10.10.xxx.0/24
@@ -1156,6 +1237,7 @@
global ELINE_SUBNETS
ELINE_SUBNETS = generate_subnets('10.30', 0, subnet_size=50, mask=30)
+
if __name__ == '__main__':
"""
Lets allow to run the API in standalone mode.
@@ -1163,4 +1245,3 @@
GK_STANDALONE_MODE = True
logging.getLogger("werkzeug").setLevel(logging.INFO)
start_rest_api("0.0.0.0", 8000)
-
diff --git a/src/emuvim/cli/__init__.py b/src/emuvim/cli/__init__.py
index dba0b3c..d888119 100755
--- a/src/emuvim/cli/__init__.py
+++ b/src/emuvim/cli/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/cli/prometheus.py b/src/emuvim/cli/prometheus.py
index 58969d1..82fa5bd 100755
--- a/src/emuvim/cli/prometheus.py
+++ b/src/emuvim/cli/prometheus.py
@@ -1,38 +1,35 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import requests
# set this to localhost for now
# this is correct for son-emu started outside of a container or as a container with net=host
-#TODO if prometheus sdk DB is started outside of emulator, place these globals in an external SDK config file?
+# TODO if prometheus sdk DB is started outside of emulator, place these
+# globals in an external SDK config file?
prometheus_ip = 'localhost'
# when sdk is started with docker-compose, we could use
# prometheus_ip = 'prometheus'
@@ -49,8 +46,8 @@
# logging.info('return:{0}'.format(ret))
try:
ret = ret['data']['result'][0]['value']
- except:
+ except BaseException:
ret = None
else:
ret = None
- return ret
\ No newline at end of file
+ return ret
diff --git a/src/emuvim/cli/rest/__init__.py b/src/emuvim/cli/rest/__init__.py
index dba0b3c..d888119 100755
--- a/src/emuvim/cli/rest/__init__.py
+++ b/src/emuvim/cli/rest/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/cli/rest/compute.py b/src/emuvim/cli/rest/compute.py
index fdfc11b..5abaa28 100755
--- a/src/emuvim/cli/rest/compute.py
+++ b/src/emuvim/cli/rest/compute.py
@@ -1,35 +1,32 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from requests import get, put, delete
from tabulate import tabulate
import pprint
import argparse
-import json
from subprocess import Popen
pp = pprint.PrettyPrinter(indent=4)
@@ -70,7 +67,8 @@
def list(self, args):
- list = get('%s/restapi/compute/%s' % (args.get("endpoint"), args.get('datacenter'))).json()
+ list = get('%s/restapi/compute/%s' %
+ (args.get("endpoint"), args.get('datacenter'))).json()
table = []
for c in list:
@@ -78,15 +76,17 @@
if len(c) > 1:
name = c[0]
status = c[1]
- #eth0ip = status.get("docker_network", "-")
- netw_list = [netw_dict['intf_name'] for netw_dict in status.get("network")]
- dc_if_list = [netw_dict['dc_portname'] for netw_dict in status.get("network")]
+ # eth0ip = status.get("docker_network", "-")
+ netw_list = [netw_dict['intf_name']
+ for netw_dict in status.get("network")]
+ dc_if_list = [netw_dict['dc_portname']
+ for netw_dict in status.get("network")]
table.append([status.get("datacenter"),
name,
status.get("image"),
','.join(netw_list),
','.join(dc_if_list)])
- #status.get("state").get("Status")]
+ # status.get("state").get("Status")]
headers = ["Datacenter",
"Container",
@@ -110,8 +110,9 @@
Popen(['xterm', '-xrm', 'XTerm.vt100.allowTitleOps: false', '-T', vnf_name,
'-e', "docker exec -it mn.{0} /bin/bash".format(vnf_name)])
+
parser = argparse.ArgumentParser(description="""son-emu-cli compute
-
+
Examples:
- son-emu-cli compute start -d dc2 -n client -i sonatanfv/sonata-iperf3-vnf
- son-emu-cli list
diff --git a/src/emuvim/cli/rest/datacenter.py b/src/emuvim/cli/rest/datacenter.py
index 651c55c..f4f92c3 100755
--- a/src/emuvim/cli/rest/datacenter.py
+++ b/src/emuvim/cli/rest/datacenter.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
from requests import get
from tabulate import tabulate
import pprint
@@ -32,6 +30,7 @@
pp = pprint.PrettyPrinter(indent=4)
+
class RestApiClient():
def __init__(self):
@@ -44,40 +43,41 @@
else:
print("Command not implemented.")
- def list(self,args):
+ def list(self, args):
list = get('%s/restapi/datacenter' % args.get('endpoint')).json()
table = []
for d in list:
# for each dc add a line to the output table
if len(d) > 0:
table.append([d.get("label"),
- d.get("internalname"),
- d.get("switch"),
- d.get("n_running_containers"),
- len(d.get("metadata"))])
+ d.get("internalname"),
+ d.get("switch"),
+ d.get("n_running_containers"),
+ len(d.get("metadata"))])
headers = ["Label",
- "Internal Name",
- "Switch",
- "# Containers",
- "# Metadata Items"]
- print (tabulate(table, headers=headers, tablefmt="grid"))
+ "Internal Name",
+ "Switch",
+ "# Containers",
+ "# Metadata Items"]
+ print(tabulate(table, headers=headers, tablefmt="grid"))
- def status(self,args):
- list = get('%s/restapi/datacenter/%s' % ( args.get("endpoint"), args.get("datacenter"))).json()
+ def status(self, args):
+ list = get('%s/restapi/datacenter/%s' %
+ (args.get("endpoint"), args.get("datacenter"))).json()
table = []
table.append([list.get('label'),
- list.get('internalname'),
- list.get('switch'),
- list.get('n_running_containers'),
- len(list.get('metadata'))])
+ list.get('internalname'),
+ list.get('switch'),
+ list.get('n_running_containers'),
+ len(list.get('metadata'))])
headers = ["Label",
- "Internal Name",
- "Switch",
- "# Containers",
- "# Metadata Items"]
+ "Internal Name",
+ "Switch",
+ "# Containers",
+ "# Metadata Items"]
- print (tabulate(table, headers=headers, tablefmt="grid"))
+ print(tabulate(table, headers=headers, tablefmt="grid"))
parser = argparse.ArgumentParser(description='son-emu-cli datacenter')
@@ -98,4 +98,3 @@
args = vars(parser.parse_args(argv))
c = RestApiClient()
c.execute_command(args)
-
diff --git a/src/emuvim/cli/rest/monitor.py b/src/emuvim/cli/rest/monitor.py
index 8be1e7f..3787887 100755
--- a/src/emuvim/cli/rest/monitor.py
+++ b/src/emuvim/cli/rest/monitor.py
@@ -1,38 +1,36 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-from requests import get, put, delete
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
+from requests import get, put
import pprint
import argparse
from emuvim.cli import prometheus
pp = pprint.PrettyPrinter(indent=4)
+
class RestApiClient():
def __init__(self):
@@ -49,8 +47,8 @@
params = self._create_dict(
vnf_name=self._parse_vnf_name(args.get("vnf_name")),
- vnf_interface = self._parse_vnf_interface(args.get("vnf_name")),
- metric = args.get("metric"))
+ vnf_interface=self._parse_vnf_interface(args.get("vnf_name")),
+ metric=args.get("metric"))
url = "{0}/restapi/monitor/interface".format(args.get("endpoint"))
response = put(url, params=params)
@@ -92,14 +90,12 @@
# This functions makes it more user-friendly to create the correct prometheus query
# <uuid> is replaced by the correct uuid of the deployed vnf container
vnf_name = self._parse_vnf_name(args.get("vnf_name"))
- vnf_interface = self._parse_vnf_interface(args.get("vnf_name"))
- dc_label = args.get("datacenter")
query = args.get("query")
vnf_status = get("%s/restapi/compute/%s/%s" %
- (args.get("endpoint"),
- args.get("datacenter"),
- vnf_name)).json()
+ (args.get("endpoint"),
+ args.get("datacenter"),
+ vnf_name)).json()
uuid = vnf_status['id']
query = query.replace('<uuid>', uuid)
@@ -113,7 +109,7 @@
def _parse_vnf_interface(self, vnf_name_str):
try:
vnf_interface = vnf_name_str.split(':')[1]
- except:
+ except BaseException:
vnf_interface = None
return vnf_interface
@@ -121,10 +117,12 @@
def _create_dict(self, **kwargs):
return kwargs
+
parser = argparse.ArgumentParser(description='son-emu-cli monitor')
parser.add_argument(
"command",
- choices=['setup_metric', 'stop_metric', 'setup_flow', 'stop_flow','prometheus'],
+ choices=['setup_metric', 'stop_metric',
+ 'setup_flow', 'stop_flow', 'prometheus'],
help="setup/stop a metric/flow to be monitored or query Prometheus")
parser.add_argument(
"--vnf_name", "-vnf", dest="vnf_name",
@@ -146,7 +144,8 @@
default="http://127.0.0.1:5001",
help="REST API endpoint of son-emu (default:http://127.0.0.1:5001)")
+
def main(argv):
args = vars(parser.parse_args(argv))
c = RestApiClient()
- c.execute_command(args)
\ No newline at end of file
+ c.execute_command(args)
diff --git a/src/emuvim/cli/rest/network.py b/src/emuvim/cli/rest/network.py
index 82fe99f..7566f44 100755
--- a/src/emuvim/cli/rest/network.py
+++ b/src/emuvim/cli/rest/network.py
@@ -1,31 +1,29 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-from requests import get,put, delete
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
+from requests import put, delete
import argparse
@@ -44,9 +42,10 @@
def add(self, args):
params = self._create_dict(
vnf_src_name=self._parse_vnf_name(args.get("source")),
- vnf_dst_name = self._parse_vnf_name(args.get("destination")),
+ vnf_dst_name=self._parse_vnf_name(args.get("destination")),
vnf_src_interface=self._parse_vnf_interface(args.get("source")),
- vnf_dst_interface=self._parse_vnf_interface(args.get("destination")),
+ vnf_dst_interface=self._parse_vnf_interface(
+ args.get("destination")),
weight=args.get("weight"),
match=args.get("match"),
bidirectional=args.get("bidirectional"),
@@ -59,10 +58,11 @@
def remove(self, args):
params = self._create_dict(
- vnf_src_name = self._parse_vnf_name(args.get("source")),
- vnf_dst_name = self._parse_vnf_name(args.get("destination")),
+ vnf_src_name=self._parse_vnf_name(args.get("source")),
+ vnf_dst_name=self._parse_vnf_name(args.get("destination")),
vnf_src_interface=self._parse_vnf_interface(args.get("source")),
- vnf_dst_interface=self._parse_vnf_interface(args.get("destination")),
+ vnf_dst_interface=self._parse_vnf_interface(
+ args.get("destination")),
weight=args.get("weight"),
match=args.get("match"),
bidirectional=args.get("bidirectional"),
@@ -80,7 +80,7 @@
def _parse_vnf_interface(self, vnf_name_str):
try:
vnf_interface = vnf_name_str.split(':')[1]
- except:
+ except BaseException:
vnf_interface = None
return vnf_interface
@@ -89,11 +89,13 @@
return kwargs
def _nice_print(self, text):
- # some modules seem to return unicode strings where newlines, other special characters are escaped
+ # 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",
@@ -128,6 +130,7 @@
default="http://127.0.0.1:5001",
help="REST API endpoint of son-emu (default:http://127.0.0.1:5001)")
+
def main(argv):
args = vars(parser.parse_args(argv))
c = RestApiClient()
diff --git a/src/emuvim/cli/son_emu_cli.py b/src/emuvim/cli/son_emu_cli.py
index 0223818..801c60b 100755
--- a/src/emuvim/cli/son_emu_cli.py
+++ b/src/emuvim/cli/son_emu_cli.py
@@ -1,48 +1,36 @@
#!/usr/bin/python
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-"""
- Simple CLI client to interact with a running emulator.
-
- The CLI offers different tools, e.g., compute, network, ...
- Each of these tools is implemented as an independent Python
- module.
-
- cli compute start dc1 my_name flavor_a
- cli network create dc1 11.0.0.0/24
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import sys
from emuvim.cli.rest import compute as restcom
from emuvim.cli.rest import datacenter as restdc
from emuvim.cli.rest import monitor as restmon
from emuvim.cli.rest import network as restnetw
+
def help():
print("Missing arguments.\n")
print("Usage: son-emu-cli compute|datacenter|network|monitor <arguments>\n")
@@ -53,6 +41,7 @@
print("\tson-emu-cli monitor --help")
exit(0)
+
def main():
if len(sys.argv) < 2:
help()
diff --git a/src/emuvim/dashboard/__init__.py b/src/emuvim/dashboard/__init__.py
index 45ad698..d888119 100755
--- a/src/emuvim/dashboard/__init__.py
+++ b/src/emuvim/dashboard/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2017 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
\ No newline at end of file
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/dcemulator/__init__.py b/src/emuvim/dcemulator/__init__.py
index 395c0ce..d888119 100755
--- a/src/emuvim/dcemulator/__init__.py
+++ b/src/emuvim/dcemulator/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/dcemulator/link.py b/src/emuvim/dcemulator/link.py
index 395c0ce..d888119 100755
--- a/src/emuvim/dcemulator/link.py
+++ b/src/emuvim/dcemulator/link.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/dcemulator/monitoring.py b/src/emuvim/dcemulator/monitoring.py
index 21985cb..6ed87cb 100755
--- a/src/emuvim/dcemulator/monitoring.py
+++ b/src/emuvim/dcemulator/monitoring.py
@@ -1,38 +1,34 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
-import sys
-from mininet.node import OVSSwitch
+from mininet.node import OVSSwitch
import ast
import time
-from prometheus_client import start_http_server, Summary, Histogram, Gauge, Counter, REGISTRY, CollectorRegistry, \
- pushadd_to_gateway, push_to_gateway, delete_from_gateway
+from prometheus_client import Gauge, CollectorRegistry, \
+ pushadd_to_gateway, delete_from_gateway
import threading
from subprocess import Popen
import os
@@ -52,6 +48,7 @@
COOKIE_MASK = 0xffffffff
+
class DCNetworkMonitor():
def __init__(self, net):
self.net = net
@@ -71,8 +68,8 @@
self.prom_rx_byte_count = Gauge('sonemu_rx_count_bytes', 'Total number of bytes received',
['vnf_name', 'vnf_interface', 'flow_id'], registry=self.registry)
- self.prom_metrics={'tx_packets':self.prom_tx_packet_count, 'rx_packets':self.prom_rx_packet_count,
- 'tx_bytes':self.prom_tx_byte_count,'rx_bytes':self.prom_rx_byte_count}
+ self.prom_metrics = {'tx_packets': self.prom_tx_packet_count, 'rx_packets': self.prom_rx_packet_count,
+ 'tx_bytes': self.prom_tx_byte_count, 'rx_bytes': self.prom_rx_byte_count}
# list of installed metrics to monitor
# each entry can contain this data
@@ -98,17 +95,20 @@
self.monitor_thread = threading.Thread(target=self.get_network_metrics)
self.monitor_thread.start()
- self.monitor_flow_thread = threading.Thread(target=self.get_flow_metrics)
+ self.monitor_flow_thread = threading.Thread(
+ target=self.get_flow_metrics)
self.monitor_flow_thread.start()
# helper tools
- # cAdvisor, Prometheus pushgateway are started as external container, to gather monitoring metric in son-emu
+ # cAdvisor, Prometheus pushgateway are started as external container,
+ # to gather monitoring metric in son-emu
self.pushgateway_process = self.start_PushGateway()
self.cadvisor_process = self.start_cAdvisor()
-
# first set some parameters, before measurement can start
- def setup_flow(self, vnf_name, vnf_interface=None, metric='tx_packets', cookie=0):
+
+ def setup_flow(self, vnf_name, vnf_interface=None,
+ metric='tx_packets', cookie=0):
flow_metric = {}
@@ -133,8 +133,10 @@
break
if not vnf_switch:
- logging.exception("vnf switch of {0}:{1} not found!".format(vnf_name, vnf_interface))
- return "vnf switch of {0}:{1} not found!".format(vnf_name, vnf_interface)
+ logging.exception("vnf switch of {0}:{1} not found!".format(
+ vnf_name, vnf_interface))
+ return "vnf switch of {0}:{1} not found!".format(
+ vnf_name, vnf_interface)
try:
# default port direction to monitor
@@ -144,7 +146,8 @@
next_node = self.net.getNodeByName(vnf_switch)
if not isinstance(next_node, OVSSwitch):
- logging.info("vnf: {0} is not connected to switch".format(vnf_name))
+ logging.info(
+ "vnf: {0} is not connected to switch".format(vnf_name))
return
flow_metric['previous_measurement'] = 0
@@ -158,8 +161,10 @@
self.flow_metrics.append(flow_metric)
self.monitor_flow_lock.release()
- logging.info('Started monitoring flow:{3} {2} on {0}:{1}'.format(vnf_name, vnf_interface, metric, cookie))
- return 'Started monitoring flow:{3} {2} on {0}:{1}'.format(vnf_name, vnf_interface, metric, cookie)
+ logging.info('Started monitoring flow:{3} {2} on {0}:{1}'.format(
+ vnf_name, vnf_interface, metric, cookie))
+ return 'Started monitoring flow:{3} {2} on {0}:{1}'.format(
+ vnf_name, vnf_interface, metric, cookie)
except Exception as ex:
logging.exception("setup_metric error.")
@@ -187,17 +192,21 @@
labels(vnf_name=vnf_name, vnf_interface=vnf_interface, flow_id=cookie). \
set(float('nan'))
- delete_from_gateway(self.pushgateway, job='sonemu-SDNcontroller')
+ delete_from_gateway(
+ self.pushgateway, job='sonemu-SDNcontroller')
self.monitor_flow_lock.release()
- logging.info('Stopped monitoring flow {3}: {2} on {0}:{1}'.format(vnf_name, vnf_interface, metric, cookie))
- return 'Stopped monitoring flow {3}: {2} on {0}:{1}'.format(vnf_name, vnf_interface, metric, cookie)
+ logging.info('Stopped monitoring flow {3}: {2} on {0}:{1}'.format(
+ vnf_name, vnf_interface, metric, cookie))
+ return 'Stopped monitoring flow {3}: {2} on {0}:{1}'.format(
+ vnf_name, vnf_interface, metric, cookie)
- return 'Error stopping monitoring flow: {0} on {1}:{2}'.format(metric, vnf_name, vnf_interface)
-
+ return 'Error stopping monitoring flow: {0} on {1}:{2}'.format(
+ metric, vnf_name, vnf_interface)
# first set some parameters, before measurement can start
+
def setup_metric(self, vnf_name, vnf_interface=None, metric='tx_packets'):
network_metric = {}
@@ -221,8 +230,10 @@
break
if 'mon_port' not in network_metric:
- logging.exception("vnf interface {0}:{1} not found!".format(vnf_name,vnf_interface))
- return "vnf interface {0}:{1} not found!".format(vnf_name,vnf_interface)
+ logging.exception("vnf interface {0}:{1} not found!".format(
+ vnf_name, vnf_interface))
+ return "vnf interface {0}:{1} not found!".format(
+ vnf_name, vnf_interface)
try:
# default port direction to monitor
@@ -242,13 +253,13 @@
next_node = self.net.getNodeByName(vnf_switch)
if not isinstance(next_node, OVSSwitch):
- logging.info("vnf: {0} is not connected to switch".format(vnf_name))
+ logging.info(
+ "vnf: {0} is not connected to switch".format(vnf_name))
return
network_metric['previous_measurement'] = 0
network_metric['previous_monitor_time'] = 0
-
network_metric['switch_dpid'] = int(str(next_node.dpid), 16)
network_metric['metric_key'] = metric
@@ -256,9 +267,10 @@
self.network_metrics.append(network_metric)
self.monitor_lock.release()
-
- logging.info('Started monitoring: {2} on {0}:{1}'.format(vnf_name, vnf_interface, metric))
- return 'Started monitoring: {2} on {0}:{1}'.format(vnf_name, vnf_interface, metric)
+ logging.info('Started monitoring: {2} on {0}:{1}'.format(
+ vnf_name, vnf_interface, metric))
+ return 'Started monitoring: {2} on {0}:{1}'.format(
+ vnf_name, vnf_interface, metric)
except Exception as ex:
logging.exception("setup_metric error.")
@@ -282,7 +294,7 @@
self.network_metrics.remove(metric_dict)
# set values to NaN, prometheus api currently does not support removal of metrics
- #self.prom_metrics[metric_dict['metric_key']].labels(vnf_name, vnf_interface).set(float('nan'))
+ # self.prom_metrics[metric_dict['metric_key']].labels(vnf_name, vnf_interface).set(float('nan'))
self.prom_metrics[metric_dict['metric_key']]. \
labels(vnf_name=vnf_name, vnf_interface=vnf_interface, flow_id=None). \
set(float('nan'))
@@ -291,21 +303,28 @@
# 1 single monitor job for all metrics of the SDN controller
# we can only remove from the pushgateway grouping keys(labels) which we have defined for the add_to_pushgateway
# we can not specify labels from the metrics to be removed
- # if we need to remove the metrics seperatelty, we need to give them a separate grouping key, and probably a diffferent registry also
- delete_from_gateway(self.pushgateway, job='sonemu-SDNcontroller')
+ # if we need to remove the metrics seperatelty, we need to give
+ # them a separate grouping key, and probably a diffferent
+ # registry also
+ delete_from_gateway(
+ self.pushgateway, job='sonemu-SDNcontroller')
self.monitor_lock.release()
- logging.info('Stopped monitoring: {2} on {0}:{1}'.format(vnf_name, vnf_interface, metric))
- return 'Stopped monitoring: {2} on {0}:{1}'.format(vnf_name, vnf_interface, metric)
+ logging.info('Stopped monitoring: {2} on {0}:{1}'.format(
+ vnf_name, vnf_interface, metric))
+ return 'Stopped monitoring: {2} on {0}:{1}'.format(
+ vnf_name, vnf_interface, metric)
# delete everything from this vnf
elif metric_dict['vnf_name'] == vnf_name and vnf_interface is None and metric is None:
self.monitor_lock.acquire()
self.network_metrics.remove(metric_dict)
- logging.info('remove metric from monitor: vnf_name:{0} vnf_interface:{1} mon_port:{2}'.format(metric_dict['vnf_name'], metric_dict['vnf_interface'], metric_dict['mon_port']))
+ logging.info('remove metric from monitor: vnf_name:{0} vnf_interface:{1} mon_port:{2}'.format(
+ metric_dict['vnf_name'], metric_dict['vnf_interface'], metric_dict['mon_port']))
- delete_from_gateway(self.pushgateway, job='sonemu-SDNcontroller')
+ delete_from_gateway(
+ self.pushgateway, job='sonemu-SDNcontroller')
self.monitor_lock.release()
continue
@@ -313,10 +332,12 @@
logging.info('Stopped monitoring vnf: {0}'.format(vnf_name))
return 'Stopped monitoring: {0}'.format(vnf_name)
else:
- return 'Error stopping monitoring metric: {0} on {1}:{2}'.format(metric, vnf_name, vnf_interface)
+ return 'Error stopping monitoring metric: {0} on {1}:{2}'.format(
+ metric, vnf_name, vnf_interface)
# get all metrics defined in the list and export it to Prometheus
+
def get_flow_metrics(self):
while self.start_monitoring:
@@ -329,13 +350,13 @@
data['cookie_mask'] = COOKIE_MASK
if 'tx' in flow_dict['metric_key']:
- data['match'] = {'in_port':flow_dict['mon_port']}
+ data['match'] = {'in_port': flow_dict['mon_port']}
elif 'rx' in flow_dict['metric_key']:
data['out_port'] = flow_dict['mon_port']
-
# query Ryu
- ret = self.net.ryu_REST('stats/flow', dpid=flow_dict['switch_dpid'], data=data)
+ ret = self.net.ryu_REST(
+ 'stats/flow', dpid=flow_dict['switch_dpid'], data=data)
if isinstance(ret, dict):
flow_stat_dict = ret
elif isinstance(ret, basestring):
@@ -347,12 +368,13 @@
self.set_flow_metric(flow_dict, flow_stat_dict)
-
try:
if len(self.flow_metrics) > 0:
- pushadd_to_gateway(self.pushgateway, job='sonemu-SDNcontroller', registry=self.registry)
- except Exception, e:
- logging.warning("Pushgateway not reachable: {0} {1}".format(Exception, e))
+ pushadd_to_gateway(
+ self.pushgateway, job='sonemu-SDNcontroller', registry=self.registry)
+ except Exception as e:
+ logging.warning(
+ "Pushgateway not reachable: {0} {1}".format(Exception, e))
self.monitor_flow_lock.release()
time.sleep(1)
@@ -363,7 +385,8 @@
self.monitor_lock.acquire()
# group metrics by dpid to optimize the rest api calls
- dpid_list = [metric_dict['switch_dpid'] for metric_dict in self.network_metrics]
+ dpid_list = [metric_dict['switch_dpid']
+ for metric_dict in self.network_metrics]
dpid_set = set(dpid_list)
for dpid in dpid_set:
@@ -378,28 +401,30 @@
port_stat_dict = None
metric_list = [metric_dict for metric_dict in self.network_metrics
- if int(metric_dict['switch_dpid'])==int(dpid)]
+ if int(metric_dict['switch_dpid']) == int(dpid)]
for metric_dict in metric_list:
self.set_network_metric(metric_dict, port_stat_dict)
try:
if len(self.network_metrics) > 0:
- pushadd_to_gateway(self.pushgateway, job='sonemu-SDNcontroller', registry=self.registry)
- except Exception, e:
- logging.warning("Pushgateway not reachable: {0} {1}".format(Exception, e))
+ pushadd_to_gateway(
+ self.pushgateway, job='sonemu-SDNcontroller', registry=self.registry)
+ except Exception as e:
+ logging.warning(
+ "Pushgateway not reachable: {0} {1}".format(Exception, e))
self.monitor_lock.release()
time.sleep(1)
- # add metric to the list to export to Prometheus, parse the Ryu port-stats reply
+ # add metric to the list to export to Prometheus, parse the Ryu port-stats
+ # reply
def set_network_metric(self, metric_dict, port_stat_dict):
# vnf tx is the datacenter switch rx and vice-versa
metric_key = self.switch_tx_rx(metric_dict['metric_key'])
switch_dpid = metric_dict['switch_dpid']
vnf_name = metric_dict['vnf_name']
vnf_interface = metric_dict['vnf_interface']
- previous_measurement = metric_dict['previous_measurement']
previous_monitor_time = metric_dict['previous_monitor_time']
mon_port = metric_dict['mon_port']
for port_stat in port_stat_dict[str(switch_dpid)]:
@@ -407,7 +432,8 @@
if port_stat['port_no'] == 'LOCAL':
continue
if int(port_stat['port_no']) == int(mon_port):
- port_uptime = port_stat['duration_sec'] + port_stat['duration_nsec'] * 10 ** (-9)
+ port_uptime = port_stat['duration_sec'] + \
+ port_stat['duration_nsec'] * 10 ** (-9)
this_measurement = int(port_stat[metric_key])
# set prometheus metric
@@ -418,27 +444,26 @@
# also the rate is calculated here, but not used for now
# (rate can be easily queried from prometheus also)
if previous_monitor_time <= 0 or previous_monitor_time >= port_uptime:
- metric_dict['previous_measurement'] = int(port_stat[metric_key])
+ metric_dict['previous_measurement'] = int(
+ port_stat[metric_key])
metric_dict['previous_monitor_time'] = port_uptime
# do first measurement
- #time.sleep(1)
- #self.monitor_lock.release()
+ # time.sleep(1)
+ # self.monitor_lock.release()
# rate cannot be calculated yet (need a first measurement)
- metric_rate = None
-
- else:
- time_delta = (port_uptime - metric_dict['previous_monitor_time'])
- #metric_rate = (this_measurement - metric_dict['previous_measurement']) / float(time_delta)
-
metric_dict['previous_measurement'] = this_measurement
metric_dict['previous_monitor_time'] = port_uptime
return
- logging.exception('metric {0} not found on {1}:{2}'.format(metric_key, vnf_name, vnf_interface))
- logging.exception('monport:{0}, dpid:{1}'.format(mon_port, switch_dpid))
- logging.exception('monitored network_metrics:{0}'.format(self.network_metrics))
+ logging.exception('metric {0} not found on {1}:{2}'.format(
+ metric_key, vnf_name, vnf_interface))
+ logging.exception(
+ 'monport:{0}, dpid:{1}'.format(mon_port, switch_dpid))
+ logging.exception(
+ 'monitored network_metrics:{0}'.format(self.network_metrics))
logging.exception('port dict:{0}'.format(port_stat_dict))
- return 'metric {0} not found on {1}:{2}'.format(metric_key, vnf_name, vnf_interface)
+ return 'metric {0} not found on {1}:{2}'.format(
+ metric_key, vnf_name, vnf_interface)
def set_flow_metric(self, metric_dict, flow_stat_dict):
# vnf tx is the datacenter switch rx and vice-versa
@@ -446,8 +471,6 @@
switch_dpid = metric_dict['switch_dpid']
vnf_name = metric_dict['vnf_name']
vnf_interface = metric_dict['vnf_interface']
- previous_measurement = metric_dict['previous_measurement']
- previous_monitor_time = metric_dict['previous_monitor_time']
cookie = metric_dict['cookie']
counter = 0
@@ -458,21 +481,24 @@
counter += flow_stat['packet_count']
# flow_uptime disabled for now (can give error)
- #flow_stat = flow_stat_dict[str(switch_dpid)][0]
- #flow_uptime = flow_stat['duration_sec'] + flow_stat['duration_nsec'] * 10 ** (-9)
+ # flow_stat = flow_stat_dict[str(switch_dpid)][0]
+ # flow_uptime = flow_stat['duration_sec'] + flow_stat['duration_nsec'] * 10 ** (-9)
self.prom_metrics[metric_dict['metric_key']]. \
labels(vnf_name=vnf_name, vnf_interface=vnf_interface, flow_id=cookie). \
set(counter)
def start_Prometheus(self, port=9090):
- # prometheus.yml configuration file is located in the same directory as this file
+ # prometheus.yml configuration file is located in the same directory as
+ # this file
cmd = ["docker",
"run",
"--rm",
"-p", "{0}:9090".format(port),
- "-v", "{0}/prometheus.yml:/etc/prometheus/prometheus.yml".format(os.path.dirname(os.path.abspath(__file__))),
- "-v", "{0}/profile.rules:/etc/prometheus/profile.rules".format(os.path.dirname(os.path.abspath(__file__))),
+ "-v", "{0}/prometheus.yml:/etc/prometheus/prometheus.yml".format(
+ os.path.dirname(os.path.abspath(__file__))),
+ "-v", "{0}/profile.rules:/etc/prometheus/profile.rules".format(
+ os.path.dirname(os.path.abspath(__file__))),
"--name", "prometheus",
"prom/prometheus"
]
@@ -502,12 +528,12 @@
"--volume=/var/lib/docker/:/var/lib/docker:ro",
"--publish={0}:8080".format(port),
"--name=cadvisor",
- "--label",'com.containernet=""',
+ "--label", 'com.containernet=""',
"--detach=true",
"google/cadvisor:latest",
- #"--storage_duration=1m0s",
- #"--allow_dynamic_housekeeping=true",
- #"--housekeeping_interval=1s",
+ # "--storage_duration=1m0s",
+ # "--allow_dynamic_housekeeping=true",
+ # "--housekeeping_interval=1s",
]
logging.info('Start cAdvisor container {0}'.format(cmd))
return Popen(cmd)
@@ -518,7 +544,8 @@
self.monitor_thread.join()
self.monitor_flow_thread.join()
- # these containers are used for monitoring but are started now outside of son-emu
+ # these containers are used for monitoring but are started now outside
+ # of son-emu
if self.pushgateway_process is not None:
logging.info('stopping pushgateway container')
@@ -528,28 +555,28 @@
logging.info('stopping cadvisor container')
self._stop_container('cadvisor')
- def switch_tx_rx(self,metric=''):
+ def switch_tx_rx(self, metric=''):
# when monitoring vnfs, the tx of the datacenter switch is actually the rx of the vnf
- # so we need to change the metric name to be consistent with the vnf rx or tx
+ # so we need to change the metric name to be consistent with the vnf rx
+ # or tx
if 'tx' in metric:
- metric = metric.replace('tx','rx')
+ metric = metric.replace('tx', 'rx')
elif 'rx' in metric:
- metric = metric.replace('rx','tx')
+ metric = metric.replace('rx', 'tx')
return metric
def _stop_container(self, name):
- #container = self.dockercli.containers.get(name)
- #container.stop()
- #container.remove(force=True)
+ # container = self.dockercli.containers.get(name)
+ # container.stop()
+ # container.remove(force=True)
# the only robust way to stop these containers is via Popen, it seems
time.sleep(1)
cmd = ['docker', 'rm', '-f', name]
Popen(cmd)
-
def update_skewmon(self, vnf_name, resource_name, action):
ret = ''
@@ -558,11 +585,11 @@
configfile = open(config_file_path, 'a+')
try:
config = json.load(configfile)
- except:
- #not a valid json file or empty
+ except BaseException:
+ # not a valid json file or empty
config = {}
- #initialize config file
+ # initialize config file
if len(self.skewmon_metrics) == 0:
config = {}
json.dump(config, configfile)
@@ -576,14 +603,16 @@
if action == 'start':
# add a new vnf to monitor
config[key] = dict(VNF_NAME=vnf_name,
- VNF_ID=vnf_id,
- VNF_METRIC=resource_name)
- ret = 'adding to skewness monitor: {0} {1} '.format(vnf_name, resource_name)
+ VNF_ID=vnf_id,
+ VNF_METRIC=resource_name)
+ ret = 'adding to skewness monitor: {0} {1} '.format(
+ vnf_name, resource_name)
logging.info(ret)
elif action == 'stop':
# remove vnf to monitor
config.pop(key)
- ret = 'removing from skewness monitor: {0} {1} '.format(vnf_name, resource_name)
+ ret = 'removing from skewness monitor: {0} {1} '.format(
+ vnf_name, resource_name)
logging.info(ret)
self.skewmon_metrics = config
@@ -604,8 +633,8 @@
# start container if not running
ret += 'starting skewness monitor'
logging.info('starting skewness monitor')
- volumes = {'/sys/fs/cgroup':{'bind':'/sys/fs/cgroup', 'mode':'ro'},
- '/tmp/skewmon.cfg':{'bind':'/config.txt', 'mode':'ro'}}
+ volumes = {'/sys/fs/cgroup': {'bind': '/sys/fs/cgroup', 'mode': 'ro'},
+ '/tmp/skewmon.cfg': {'bind': '/config.txt', 'mode': 'ro'}}
self.dockercli.containers.run('skewmon',
detach=True,
volumes=volumes,
@@ -616,7 +645,8 @@
started = False
wait_time = 0
while not started:
- list1 = self.dockercli.containers.list(filters={'status': 'running', 'name': 'prometheus'})
+ list1 = self.dockercli.containers.list(
+ filters={'status': 'running', 'name': 'prometheus'})
if len(list1) >= 1:
time.sleep(1)
started = True
@@ -634,7 +664,6 @@
:return:
"""
-
if vnf_list is None:
vnf_list = []
if not isinstance(vnf_list, list):
@@ -644,8 +673,8 @@
return self.start_xterm(vnf_list)
-
# start an xterm for the specfified vnfs
+
def start_xterm(self, vnf_names):
# start xterm for all vnfs
for vnf_name in vnf_names:
@@ -660,13 +689,3 @@
if len(vnf_names) == 0:
ret = 'vnf list is empty, no xterms started'
return ret
-
-
-
-
-
-
-
-
-
-
diff --git a/src/emuvim/dcemulator/net.py b/src/emuvim/dcemulator/net.py
index ea9fd1c..005e272 100755
--- a/src/emuvim/dcemulator/net.py
+++ b/src/emuvim/dcemulator/net.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
import site
@@ -36,13 +34,13 @@
import json
from mininet.net import Containernet
-from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController
+from mininet.node import OVSSwitch, OVSKernelSwitch, Docker, RemoteController
from mininet.cli import CLI
from mininet.link import TCLink
from mininet.clean import cleanup
import networkx as nx
from emuvim.dcemulator.monitoring import DCNetworkMonitor
-from emuvim.dcemulator.node import Datacenter, EmulatorCompute, EmulatorExtSAP
+from emuvim.dcemulator.node import Datacenter, EmulatorCompute
from emuvim.dcemulator.resourcemodel import ResourceModelRegistrar
LOG = logging.getLogger("dcemulator.net")
@@ -56,6 +54,7 @@
# default cookie number for new flow-rules
DEFAULT_COOKIE = 10
+
class DCNetwork(Containernet):
"""
Wraps the original Mininet/Containernet class and provides
@@ -65,7 +64,10 @@
"""
def __init__(self, controller=RemoteController, monitor=False,
- enable_learning=False, # learning switch behavior of the default ovs switches icw Ryu controller can be turned off/on, needed for E-LAN functionality
+ enable_learning=False,
+ # learning switch behavior of the default ovs switches icw Ryu
+ # controller can be turned off/on, needed for E-LAN
+ # functionality
dc_emulation_max_cpu=1.0, # fraction of overall CPU time for emulation
dc_emulation_max_mem=512, # emulation max mem in MB
**kwargs):
@@ -78,13 +80,13 @@
# members
self.dcs = {}
self.ryu_process = None
- #list of deployed nsds.E_Lines and E_LANs (uploaded from the dummy gatekeeper)
+ # list of deployed nsds.E_Lines and E_LANs (uploaded from the dummy
+ # gatekeeper)
self.deployed_nsds = []
self.deployed_elines = []
self.deployed_elans = []
self.installed_chains = []
-
# always cleanup environment before we start the emulator
self.killRyu()
cleanup()
@@ -95,7 +97,7 @@
# default switch configuration
enable_ryu_learning = False
- if enable_learning :
+ if enable_learning:
self.failMode = 'standalone'
enable_ryu_learning = True
else:
@@ -138,7 +140,8 @@
"""
if label in self.dcs:
raise Exception("Data center label already exists: %s" % label)
- dc = Datacenter(label, metadata=metadata, resource_log_path=resource_log_path)
+ dc = Datacenter(label, metadata=metadata,
+ resource_log_path=resource_log_path)
dc.net = self # set reference to network
self.dcs[label] = dc
dc.create() # finally create the data center in our Mininet instance
@@ -154,31 +157,32 @@
assert node2 is not None
# ensure type of node1
- if isinstance( node1, basestring ):
+ if isinstance(node1, basestring):
if node1 in self.dcs:
node1 = self.dcs[node1].switch
- if isinstance( node1, Datacenter ):
+ if isinstance(node1, Datacenter):
node1 = node1.switch
# ensure type of node2
- if isinstance( node2, basestring ):
+ if isinstance(node2, basestring):
if node2 in self.dcs:
node2 = self.dcs[node2].switch
- if isinstance( node2, Datacenter ):
+ if isinstance(node2, Datacenter):
node2 = node2.switch
# try to give containers a default IP
- if isinstance( node1, Docker ):
+ if isinstance(node1, Docker):
if "params1" not in params:
params["params1"] = {}
if "ip" not in params["params1"]:
params["params1"]["ip"] = self.getNextIp()
- if isinstance( node2, Docker ):
+ if isinstance(node2, Docker):
if "params2" not in params:
params["params2"] = {}
if "ip" not in params["params2"]:
params["params2"]["ip"] = self.getNextIp()
# ensure that we allow TCLinks between data centers
# TODO this is not optimal, we use cls=Link for containers and TCLink for data centers
- # see Containernet issue: https://github.com/mpeuster/containernet/issues/3
+ # see Containernet issue:
+ # https://github.com/mpeuster/containernet/issues/3
if "cls" not in params:
params["cls"] = TCLink
@@ -197,7 +201,6 @@
node2_port_id = params["params2"]["id"]
node2_port_name = link.intf2.name
-
# 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 Containernet
@@ -215,23 +218,24 @@
attr_number = None
attr_dict[attr] = attr_number
-
attr_dict2 = {'src_port_id': node1_port_id, 'src_port_nr': node1.ports[link.intf1],
'src_port_name': node1_port_name,
- 'dst_port_id': node2_port_id, 'dst_port_nr': node2.ports[link.intf2],
+ 'dst_port_id': node2_port_id, 'dst_port_nr': node2.ports[link.intf2],
'dst_port_name': node2_port_name}
attr_dict2.update(attr_dict)
- self.DCNetwork_graph.add_edge(node1.name, node2.name, attr_dict=attr_dict2)
+ self.DCNetwork_graph.add_edge(
+ node1.name, node2.name, attr_dict=attr_dict2)
attr_dict2 = {'src_port_id': node2_port_id, 'src_port_nr': node2.ports[link.intf2],
'src_port_name': node2_port_name,
- 'dst_port_id': node1_port_id, 'dst_port_nr': node1.ports[link.intf1],
+ 'dst_port_id': node1_port_id, 'dst_port_nr': node1.ports[link.intf1],
'dst_port_name': node1_port_name}
attr_dict2.update(attr_dict)
- self.DCNetwork_graph.add_edge(node2.name, node1.name, attr_dict=attr_dict2)
+ self.DCNetwork_graph.add_edge(
+ node2.name, node1.name, attr_dict=attr_dict2)
LOG.debug("addLink: n1={0} intf1={1} -- n2={2} intf2={3}".format(
- str(node1),node1_port_name, str(node2), node2_port_name))
+ str(node1), node1_port_name, str(node2), node2_port_name))
return link
@@ -248,21 +252,24 @@
# TODO we might decrease the loglevel to debug:
try:
self.DCNetwork_graph.remove_edge(node2.name, node1.name)
- except:
- LOG.warning("%s, %s not found in DCNetwork_graph." % ((node2.name, node1.name)))
+ except BaseException:
+ LOG.warning("%s, %s not found in DCNetwork_graph." %
+ ((node2.name, node1.name)))
try:
self.DCNetwork_graph.remove_edge(node1.name, node2.name)
- except:
- LOG.warning("%s, %s not found in DCNetwork_graph." % ((node1.name, node2.name)))
+ except BaseException:
+ LOG.warning("%s, %s not found in DCNetwork_graph." %
+ ((node1.name, node2.name)))
- def addDocker( self, label, **params ):
+ def addDocker(self, label, **params):
"""
Wrapper for addDocker method to use custom container class.
"""
self.DCNetwork_graph.add_node(label, type=params.get('type', 'docker'))
- return Containernet.addDocker(self, label, cls=EmulatorCompute, **params)
+ return Containernet.addDocker(
+ self, label, cls=EmulatorCompute, **params)
- def removeDocker( self, label, **params):
+ def removeDocker(self, label, **params):
"""
Wrapper for removeDocker method to update graph.
"""
@@ -274,7 +281,7 @@
Wrapper for addExtSAP method to store SAP also in graph.
"""
# make sure that 'type' is set
- params['type'] = params.get('type','sap_ext')
+ params['type'] = params.get('type', 'sap_ext')
self.DCNetwork_graph.add_node(sap_name, type=params['type'])
return Containernet.addExtSAP(self, sap_name, sap_ip, **params)
@@ -285,22 +292,24 @@
self.DCNetwork_graph.remove_node(sap_name)
return Containernet.removeExtSAP(self, sap_name)
- def addSwitch( self, name, add_to_graph=True, **params ):
+ def addSwitch(self, name, add_to_graph=True, **params):
"""
Wrapper for addSwitch method to store switch also in graph.
"""
# add this switch to the global topology overview
if add_to_graph:
- self.DCNetwork_graph.add_node(name, type=params.get('type','switch'))
+ self.DCNetwork_graph.add_node(
+ name, type=params.get('type', 'switch'))
# set the learning switch behavior
- if 'failMode' in params :
+ if 'failMode' in params:
failMode = params['failMode']
- else :
+ else:
failMode = self.failMode
- s = Containernet.addSwitch(self, name, protocols='OpenFlow10,OpenFlow12,OpenFlow13', failMode=failMode, **params)
+ s = Containernet.addSwitch(
+ self, name, protocols='OpenFlow10,OpenFlow12,OpenFlow13', failMode=failMode, **params)
return s
@@ -331,7 +340,6 @@
# stop Ryu controller
self.killRyu()
-
def CLI(self):
CLI(self)
@@ -343,7 +351,6 @@
:return:
"""
src_sw = None
- src_sw_inport_nr = 0
src_sw_inport_name = None
# get a vlan tag for this E-LAN
@@ -364,20 +371,20 @@
link_dict = self.DCNetwork_graph[vnf_src_name][connected_sw]
for link in link_dict:
if (link_dict[link]['src_port_id'] == vnf_src_interface or
- link_dict[link]['src_port_name'] == vnf_src_interface): # Fix: we might also get interface names, e.g, from a son-emu-cli call
+ link_dict[link]['src_port_name'] == vnf_src_interface): # Fix: we might also get interface names, e.g, from a son-emu-cli call
# found the right link and connected switch
src_sw = connected_sw
- src_sw_inport_nr = link_dict[link]['dst_port_nr']
src_sw_inport_name = link_dict[link]['dst_port_name']
break
# set the tag on the dc switch interface
- LOG.debug('set E-LAN: vnf name: {0} interface: {1} tag: {2}'.format(vnf_src_name, vnf_src_interface,vlan))
+ LOG.debug('set E-LAN: vnf name: {0} interface: {1} tag: {2}'.format(
+ vnf_src_name, vnf_src_interface, vlan))
switch_node = self.getNodeByName(src_sw)
self._set_vlan_tag(switch_node, src_sw_inport_name, vlan)
def _addMonitorFlow(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None,
- tag=None, **kwargs):
+ tag=None, **kwargs):
"""
Add a monitoring flow entry that adds a special flowentry/counter at the begin or end of a chain.
So this monitoring flowrule exists on top of a previously defined chain rule and uses the same vlan tag/routing.
@@ -400,7 +407,7 @@
LOG.debug("call AddMonitorFlow vnf_src_name=%r, vnf_src_interface=%r, vnf_dst_name=%r, vnf_dst_interface=%r",
vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface)
- #check if port is specified (vnf:port)
+ # check if port is specified (vnf:port)
if vnf_src_interface is None:
# take first interface by default
connected_sw = self.DCNetwork_graph.neighbors(vnf_src_name)[0]
@@ -443,31 +450,34 @@
try:
# returns the first found shortest path
# if all shortest paths are wanted, use: all_shortest_paths
- path = nx.shortest_path(self.DCNetwork_graph, src_sw, dst_sw, weight=kwargs.get('weight'))
- except:
+ path = nx.shortest_path(
+ self.DCNetwork_graph, src_sw, dst_sw, weight=kwargs.get('weight'))
+ except BaseException:
LOG.exception("No path could be found between {0} and {1} using src_sw={2} and dst_sw={3}".format(
vnf_src_name, vnf_dst_name, src_sw, dst_sw))
LOG.debug("Graph nodes: %r" % self.DCNetwork_graph.nodes())
LOG.debug("Graph edges: %r" % self.DCNetwork_graph.edges())
for e, v in self.DCNetwork_graph.edges():
LOG.debug("%r" % self.DCNetwork_graph[e][v])
- return "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)
- LOG.info("Path between {0} and {1}: {2}".format(vnf_src_name, vnf_dst_name, path))
+ LOG.info("Path between {0} and {1}: {2}".format(
+ vnf_src_name, vnf_dst_name, path))
current_hop = src_sw
switch_inport_nr = src_sw_inport_nr
cmd = kwargs.get('cmd')
- #iterate through the path to install the flow-entries
- for i in range(0,len(path)):
+ # iterate through the path to install the flow-entries
+ for i in range(0, len(path)):
current_node = self.getNodeByName(current_hop)
- if path.index(current_hop) < len(path)-1:
- next_hop = path[path.index(current_hop)+1]
+ if path.index(current_hop) < len(path) - 1:
+ next_hop = path[path.index(current_hop) + 1]
else:
- #last switch reached
+ # last switch reached
next_hop = vnf_dst_name
next_node = self.getNodeByName(next_hop)
@@ -475,7 +485,7 @@
if next_hop == vnf_dst_name:
switch_outport_nr = dst_sw_outport_nr
LOG.info("end node reached: {0}".format(vnf_dst_name))
- elif not isinstance( next_node, OVSSwitch ):
+ elif not isinstance(next_node, OVSSwitch):
LOG.info("Next node: {0} is not a switch".format(next_hop))
return "Next node: {0} is not a switch".format(next_hop)
else:
@@ -483,9 +493,8 @@
index_edge_out = 0
switch_outport_nr = self.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']
-
- # set of entry via ovs-ofctl
- if isinstance( current_node, OVSSwitch ):
+ # set of entry via ovs-ofctl
+ if isinstance(current_node, OVSSwitch):
kwargs['vlan'] = tag
kwargs['path'] = path
kwargs['current_hop'] = current_hop
@@ -497,33 +506,38 @@
monitor_placement = kwargs.get('monitor_placement').strip()
# put monitor flow at the dst switch
insert_flow = False
- if monitor_placement == 'tx' and path.index(current_hop) == 0: # first node:
+ # first node:
+ if monitor_placement == 'tx' and path.index(current_hop) == 0:
insert_flow = True
# put monitoring flow at the src switch
- elif monitor_placement == 'rx' and path.index(current_hop) == len(path) - 1: # last node:
+ # last node:
+ elif monitor_placement == 'rx' and path.index(current_hop) == len(path) - 1:
insert_flow = True
elif monitor_placement not in ['rx', 'tx']:
- LOG.exception('invalid monitor command: {0}'.format(monitor_placement))
-
+ LOG.exception(
+ 'invalid monitor command: {0}'.format(monitor_placement))
if self.controller == RemoteController and insert_flow:
- ## set flow entry via ryu rest api
- self._set_flow_entry_ryu_rest(current_node, switch_inport_nr, switch_outport_nr, **kwargs)
+ # set flow entry via ryu rest api
+ self._set_flow_entry_ryu_rest(
+ current_node, switch_inport_nr, switch_outport_nr, **kwargs)
break
elif insert_flow:
- ## set flow entry via ovs-ofctl
- self._set_flow_entry_dpctl(current_node, switch_inport_nr, switch_outport_nr, **kwargs)
+ # set flow entry via ovs-ofctl
+ self._set_flow_entry_dpctl(
+ current_node, switch_inport_nr, switch_outport_nr, **kwargs)
break
# take first link between switches by default
- if isinstance( next_node, OVSSwitch ):
+ if isinstance(next_node, OVSSwitch):
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)
+ return "path {2} between {0} and {1}".format(
+ vnf_src_name, vnf_dst_name, cmd)
-
- def setChain(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None, **kwargs):
+ def setChain(self, vnf_src_name, vnf_dst_name,
+ vnf_src_interface=None, vnf_dst_interface=None, **kwargs):
"""
Chain 2 vnf interfaces together by installing the flowrules in the switches along their path.
Currently the path is found using the default networkx shortest path function.
@@ -549,17 +563,19 @@
# check if chain already exists
found_chains = [chain_dict for chain_dict in self.installed_chains if
- (chain_dict['vnf_src_name'] == vnf_src_name and chain_dict['vnf_src_interface'] == vnf_src_interface
- and chain_dict['vnf_dst_name'] == vnf_dst_name and chain_dict['vnf_dst_interface'] == vnf_dst_interface)]
+ (chain_dict['vnf_src_name'] == vnf_src_name and
+ chain_dict['vnf_src_interface'] == vnf_src_interface and
+ chain_dict['vnf_dst_name'] == vnf_dst_name and
+ chain_dict['vnf_dst_interface'] == vnf_dst_interface)]
if len(found_chains) > 0:
# this chain exists, so need an extra monitoring flow
# assume only 1 chain per vnf/interface pair
LOG.debug('*** installing monitoring chain on top of pre-defined chain from {0}:{1} -> {2}:{3}'.
- format(vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface))
+ format(vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface))
tag = found_chains[0]['tag']
ret = self._addMonitorFlow(vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface,
- tag=tag, table_id=0, **kwargs)
+ tag=tag, table_id=0, **kwargs)
return ret
else:
# no chain existing (or E-LAN) -> install normal chain
@@ -567,22 +583,24 @@
format(vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface))
pass
-
cmd = kwargs.get('cmd', 'add-flow')
if cmd == 'add-flow' or cmd == 'del-flows':
- ret = self._chainAddFlow(vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface, **kwargs)
+ ret = self._chainAddFlow(
+ vnf_src_name, vnf_dst_name, vnf_src_interface, vnf_dst_interface, **kwargs)
if kwargs.get('bidirectional'):
if kwargs.get('path') is not None:
kwargs['path'] = list(reversed(kwargs.get('path')))
- ret = ret +'\n' + self._chainAddFlow(vnf_dst_name, vnf_src_name, vnf_dst_interface, vnf_src_interface, **kwargs)
+ ret = ret + '\n' + \
+ self._chainAddFlow(
+ vnf_dst_name, vnf_src_name, vnf_dst_interface, vnf_src_interface, **kwargs)
else:
ret = "Command unknown"
return ret
-
- def _chainAddFlow(self, vnf_src_name, vnf_dst_name, vnf_src_interface=None, vnf_dst_interface=None, **kwargs):
+ def _chainAddFlow(self, vnf_src_name, vnf_dst_name,
+ vnf_src_interface=None, vnf_dst_interface=None, **kwargs):
src_sw = None
src_sw_inport_nr = 0
@@ -594,7 +612,7 @@
LOG.debug("call chainAddFlow vnf_src_name=%r, vnf_src_interface=%r, vnf_dst_name=%r, vnf_dst_interface=%r",
vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface)
- #check if port is specified (vnf:port)
+ # check if port is specified (vnf:port)
if vnf_src_interface is None:
# take first interface by default
connected_sw = self.DCNetwork_graph.neighbors(vnf_src_name)[0]
@@ -636,17 +654,20 @@
try:
# returns the first found shortest path
# if all shortest paths are wanted, use: all_shortest_paths
- path = nx.shortest_path(self.DCNetwork_graph, src_sw, dst_sw, weight=kwargs.get('weight'))
- except:
+ path = nx.shortest_path(
+ self.DCNetwork_graph, src_sw, dst_sw, weight=kwargs.get('weight'))
+ except BaseException:
LOG.exception("No path could be found between {0} and {1} using src_sw={2} and dst_sw={3}".format(
vnf_src_name, vnf_dst_name, src_sw, dst_sw))
LOG.debug("Graph nodes: %r" % self.DCNetwork_graph.nodes())
LOG.debug("Graph edges: %r" % self.DCNetwork_graph.edges())
for e, v in self.DCNetwork_graph.edges():
LOG.debug("%r" % self.DCNetwork_graph[e][v])
- return "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)
- LOG.info("Path between {0} and {1}: {2}".format(vnf_src_name, vnf_dst_name, path))
+ LOG.info("Path between {0} and {1}: {2}".format(
+ vnf_src_name, vnf_dst_name, path))
current_hop = src_sw
switch_inport_nr = src_sw_inport_nr
@@ -671,8 +692,8 @@
chain_dict['tag'] = vlan
self.installed_chains.append(chain_dict)
- #iterate through the path to install the flow-entries
- for i in range(0,len(path)):
+ # iterate through the path to install the flow-entries
+ for i in range(0, len(path)):
current_node = self.getNodeByName(current_hop)
if i < len(path) - 1:
@@ -686,7 +707,7 @@
if next_hop == vnf_dst_name:
switch_outport_nr = dst_sw_outport_nr
LOG.info("end node reached: {0}".format(vnf_dst_name))
- elif not isinstance( next_node, OVSSwitch ):
+ elif not isinstance(next_node, OVSSwitch):
LOG.info("Next node: {0} is not a switch".format(next_hop))
return "Next node: {0} is not a switch".format(next_hop)
else:
@@ -694,9 +715,8 @@
index_edge_out = 0
switch_outport_nr = self.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']
-
- # set OpenFlow entry
- if isinstance( current_node, OVSSwitch ):
+ # set OpenFlow entry
+ if isinstance(current_node, OVSSwitch):
kwargs['vlan'] = vlan
kwargs['path'] = path
kwargs['current_hop'] = current_hop
@@ -705,28 +725,32 @@
kwargs['pathindex'] = i
if self.controller == RemoteController:
- ## set flow entry via ryu rest api
- self._set_flow_entry_ryu_rest(current_node, switch_inport_nr, switch_outport_nr, **kwargs)
+ # set flow entry via ryu rest api
+ self._set_flow_entry_ryu_rest(
+ current_node, switch_inport_nr, switch_outport_nr, **kwargs)
else:
- ## set flow entry via ovs-ofctl
- self._set_flow_entry_dpctl(current_node, switch_inport_nr, switch_outport_nr, **kwargs)
+ # set flow entry via ovs-ofctl
+ self._set_flow_entry_dpctl(
+ current_node, switch_inport_nr, switch_outport_nr, **kwargs)
# take first link between switches by default
- if isinstance( next_node, OVSSwitch ):
+ if isinstance(next_node, OVSSwitch):
switch_inport_nr = self.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
current_hop = next_hop
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')
+ '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)
+ 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):
+ def _set_flow_entry_ryu_rest(
+ self, node, switch_inport_nr, switch_outport_nr, **kwargs):
match = 'in_port=%s' % switch_inport_nr
cookie = kwargs.get('cookie')
@@ -764,7 +788,7 @@
# http://ryu.readthedocs.io/en/latest/app/ofctl_rest.html#add-a-flow-entry
if cmd == 'add-flow':
prefix = 'stats/flowentry/add'
- if vlan != None:
+ if vlan is not None:
if index == 0: # first node
# set vlan tag in ovs instance (to isolate E-LANs)
if not skip_vlan_tag:
@@ -773,8 +797,12 @@
# set vlan push action if more than 1 switch in the path
if len(path) > 1:
action = {}
- action['type'] = 'PUSH_VLAN' # Push a new VLAN tag if a input frame is non-VLAN-tagged
- action['ethertype'] = 33024 # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged frame
+ # Push a new VLAN tag if a input frame is
+ # non-VLAN-tagged
+ action['type'] = 'PUSH_VLAN'
+ # Ethertype 0x8100(=33024): IEEE 802.1Q VLAN-tagged
+ # frame
+ action['ethertype'] = 33024
flow['actions'].append(action)
action = {}
action['type'] = 'SET_FIELD'
@@ -809,7 +837,8 @@
if cookie:
# TODO: add cookie_mask as argument
- flow['cookie_mask'] = int('0xffffffffffffffff', 16) # need full mask to match complete cookie
+ # need full mask to match complete cookie
+ flow['cookie_mask'] = int('0xffffffffffffffff', 16)
action = {}
action['type'] = 'OUTPUT'
@@ -820,10 +849,12 @@
self.ryu_REST(prefix, data=flow)
def _set_vlan_tag(self, node, switch_port, tag):
- node.vsctl('set', 'port {0} tag={1}'.format(switch_port,tag))
- LOG.debug("set vlan in switch: {0} in_port: {1} vlan tag: {2}".format(node.name, switch_port, tag))
+ node.vsctl('set', 'port {0} tag={1}'.format(switch_port, tag))
+ LOG.debug("set vlan in switch: {0} in_port: {1} vlan tag: {2}".format(
+ node.name, switch_port, tag))
- def _set_flow_entry_dpctl(self, node, switch_inport_nr, switch_outport_nr, **kwargs):
+ def _set_flow_entry_dpctl(
+ self, node, switch_inport_nr, switch_outport_nr, **kwargs):
match = 'in_port=%s' % switch_inport_nr
@@ -842,9 +873,10 @@
match = s.join([match, match_input])
if cmd == 'add-flow':
action = 'action=%s' % switch_outport_nr
- if vlan != None:
- if index == 0: # first node
- action = ('action=mod_vlan_vid:%s' % vlan) + (',output=%s' % switch_outport_nr)
+ if vlan is not None:
+ if index == 0: # first node
+ action = ('action=mod_vlan_vid:%s' % vlan) + \
+ (',output=%s' % switch_outport_nr)
match = '-O OpenFlow13 ' + match
elif index == len(path) - 1: # last node
match += ',dl_vlan=%s' % vlan
@@ -859,15 +891,16 @@
node.dpctl(cmd, ofcmd)
LOG.info("{3} in switch: {0} in_port: {1} out_port: {2}".format(node.name, switch_inport_nr,
- switch_outport_nr, cmd))
+ switch_outport_nr, cmd))
# start Ryu Openflow controller as Remote Controller for the DCNetwork
def startRyu(self, learning_switch=True):
# start Ryu controller with rest-API
python_install_path = site.getsitepackages()[0]
# ryu default learning switch
- #ryu_path = python_install_path + '/ryu/app/simple_switch_13.py'
- #custom learning switch that installs a default NORMAL action in the ovs switches
+ # ryu_path = python_install_path + '/ryu/app/simple_switch_13.py'
+ # custom learning switch that installs a default NORMAL action in the
+ # ovs switches
dir_path = os.path.dirname(os.path.realpath(__file__))
ryu_path = dir_path + '/son_emu_simple_switch_13.py'
ryu_path2 = python_install_path + '/ryu/app/ofctl_rest.py'
@@ -878,12 +911,14 @@
ryu_cmd = 'ryu-manager'
FNULL = open("/tmp/ryu.log", 'w')
if learning_switch:
- self.ryu_process = Popen([ryu_cmd, ryu_path, ryu_path2, ryu_option, ryu_of_port], stdout=FNULL, stderr=FNULL)
+ self.ryu_process = Popen(
+ [ryu_cmd, ryu_path, ryu_path2, ryu_option, ryu_of_port], stdout=FNULL, stderr=FNULL)
LOG.debug('starting ryu-controller with {0}'.format(ryu_path))
LOG.debug('starting ryu-controller with {0}'.format(ryu_path2))
else:
# no learning switch, but with rest api
- self.ryu_process = Popen([ryu_cmd, ryu_path2, ryu_option, ryu_of_port], stdout=FNULL, stderr=FNULL)
+ self.ryu_process = Popen(
+ [ryu_cmd, ryu_path2, ryu_option, ryu_of_port], stdout=FNULL, stderr=FNULL)
LOG.debug('starting ryu-controller with {0}'.format(ryu_path2))
time.sleep(1)
@@ -910,7 +945,6 @@
else:
req = self.RyuSession.get(url)
-
# do extra logging if status code is not 200 (OK)
if req.status_code is not requests.codes.ok:
logging.info(
@@ -918,9 +952,10 @@
req.encoding, req.text,
req.headers, req.history))
LOG.info('url: {0}'.format(str(url)))
- if data: LOG.info('POST: {0}'.format(str(data)))
- LOG.info('status: {0} reason: {1}'.format(req.status_code, req.reason))
-
+ if data:
+ LOG.info('POST: {0}'.format(str(data)))
+ LOG.info('status: {0} reason: {1}'.format(
+ req.status_code, req.reason))
if 'json' in req.headers['content-type']:
ret = req.json()
@@ -929,9 +964,9 @@
ret = req.text.rstrip()
return ret
-
# need to respect that some match fields must be integers
# http://ryu.readthedocs.io/en/latest/app/ofctl_rest.html#description-of-match-and-actions
+
def _parse_match(self, match):
matches = match.split(',')
dict = {}
@@ -940,13 +975,14 @@
if len(match) == 2:
try:
m2 = int(match[1], 0)
- except:
+ except BaseException:
m2 = match[1]
- dict.update({match[0]:m2})
+ dict.update({match[0]: m2})
return dict
- def find_connected_dc_interface(self, vnf_src_name, vnf_src_interface=None):
+ def find_connected_dc_interface(
+ self, vnf_src_name, vnf_src_interface=None):
if vnf_src_interface is None:
# take first interface by default
@@ -958,9 +994,8 @@
link_dict = self.DCNetwork_graph[vnf_src_name][connected_sw]
for link in link_dict:
if (link_dict[link]['src_port_id'] == vnf_src_interface or
- link_dict[link]['src_port_name'] == vnf_src_interface): # Fix: we might also get interface names, e.g, from a son-emu-cli call
+ link_dict[link]['src_port_name'] == vnf_src_interface):
+ # Fix: we might also get interface names, e.g, from a son-emu-cli call
# found the right link and connected switch
- src_sw = connected_sw
- src_sw_inport_nr = link_dict[link]['dst_port_nr']
src_sw_inport_name = link_dict[link]['dst_port_name']
return src_sw_inport_name
diff --git a/src/emuvim/dcemulator/node.py b/src/emuvim/dcemulator/node.py
index 77a71a0..5a9c048 100755
--- a/src/emuvim/dcemulator/node.py
+++ b/src/emuvim/dcemulator/node.py
@@ -1,31 +1,29 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-from mininet.node import Docker, OVSBridge
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
+from mininet.node import Docker
from mininet.link import Link
from emuvim.dcemulator.resourcemodel import NotEnoughResourcesAvailable
import logging
@@ -38,6 +36,7 @@
DCDPID_BASE = 1000 # start of switch dpid's used for data center switches
EXTSAPDPID_BASE = 2000 # start of switch dpid's used for external SAP switches
+
class EmulatorCompute(Docker):
"""
Emulator specific compute node class.
@@ -51,7 +50,8 @@
self, name, dimage, **kwargs):
self.datacenter = kwargs.get("datacenter") # pointer to current DC
self.flavor_name = kwargs.get("flavor_name")
- LOG.debug("Starting compute instance %r in data center %r" % (name, str(self.datacenter)))
+ LOG.debug("Starting compute instance %r in data center %r" %
+ (name, str(self.datacenter)))
# call original Docker.__init__
Docker.__init__(self, name, dimage, **kwargs)
@@ -65,9 +65,11 @@
for i in self.intfList():
vnf_name = self.name
vnf_interface = str(i)
- dc_port_name = self.datacenter.net.find_connected_dc_interface(vnf_name, vnf_interface)
+ dc_port_name = self.datacenter.net.find_connected_dc_interface(
+ vnf_name, vnf_interface)
# format list of tuples (name, Ip, MAC, isUp, status, dc_portname)
- intf_dict = {'intf_name': str(i), 'ip': "{0}/{1}".format(i.IP(), i.prefixLen), 'netmask': i.prefixLen, 'mac': i.MAC(), 'up': i.isUp(), 'status': i.status(), 'dc_portname': dc_port_name}
+ intf_dict = {'intf_name': str(i), 'ip': "{0}/{1}".format(i.IP(), i.prefixLen), 'netmask': i.prefixLen,
+ 'mac': i.MAC(), 'up': i.isUp(), 'status': i.status(), 'dc_portname': dc_port_name}
networkStatusList.append(intf_dict)
return networkStatusList
@@ -91,7 +93,8 @@
status["state"] = self.dcli.inspect_container(self.dc)["State"]
status["id"] = self.dcli.inspect_container(self.dc)["Id"]
status["short_id"] = self.dcli.inspect_container(self.dc)["Id"][:12]
- status["hostname"] = self.dcli.inspect_container(self.dc)["Config"]['Hostname']
+ status["hostname"] = self.dcli.inspect_container(self.dc)[
+ "Config"]['Hostname']
status["datacenter"] = (None if self.datacenter is None
else self.datacenter.label)
@@ -113,14 +116,16 @@
self.net = self.datacenter.net
self.name = sap_name
- LOG.debug("Starting ext SAP instance %r in data center %r" % (sap_name, str(self.datacenter)))
+ LOG.debug("Starting ext SAP instance %r in data center %r" %
+ (sap_name, str(self.datacenter)))
# create SAP as separate OVS switch with an assigned ip address
self.ip = str(sap_net[1]) + '/' + str(sap_net.prefixlen)
self.subnet = sap_net
# allow connection to the external internet through the host
params = dict(NAT=True)
- self.switch = self.net.addExtSAP(sap_name, self.ip, dpid=hex(self._get_next_extSAP_dpid())[2:], **params)
+ self.switch = self.net.addExtSAP(sap_name, self.ip, dpid=hex(
+ self._get_next_extSAP_dpid())[2:], **params)
self.switch.start()
def _get_next_extSAP_dpid(self):
@@ -140,9 +145,11 @@
vnf_interface = str(i)
if vnf_interface == 'lo':
continue
- dc_port_name = self.datacenter.net.find_connected_dc_interface(vnf_name, vnf_interface)
+ dc_port_name = self.datacenter.net.find_connected_dc_interface(
+ vnf_name, vnf_interface)
# format list of tuples (name, Ip, MAC, isUp, status, dc_portname)
- intf_dict = {'intf_name': str(i), 'ip': self.ip, 'netmask': i.prefixLen, 'mac': i.MAC(), 'up': i.isUp(), 'status': i.status(), 'dc_portname': dc_port_name}
+ intf_dict = {'intf_name': str(i), 'ip': self.ip, 'netmask': i.prefixLen, 'mac': i.MAC(
+ ), 'up': i.isUp(), 'status': i.status(), 'dc_portname': dc_port_name}
networkStatusList.append(intf_dict)
return networkStatusList
@@ -154,6 +161,7 @@
"network": self.getNetworkStatus()
}
+
class Datacenter(object):
"""
Represents a logical data center to which compute resources
@@ -174,7 +182,8 @@
self.label = label
# dict to store arbitrary metadata (e.g. latitude and longitude)
self.metadata = metadata
- # path to which resource information should be logged (e.g. for experiments). None = no logging
+ # path to which resource information should be logged (e.g. for
+ # experiments). None = no logging
self.resource_log_path = resource_log_path
# first prototype assumes one "bigswitch" per DC
self.switch = None
@@ -208,7 +217,8 @@
def start(self):
pass
- def startCompute(self, name, image=None, command=None, network=None, flavor_name="tiny", properties=dict(), **params):
+ def startCompute(self, name, image=None, command=None, network=None,
+ flavor_name="tiny", properties=dict(), **params):
"""
Create a new container as compute resource and connect it to this
data center.
@@ -230,7 +240,8 @@
if network is None:
network = {} # {"ip": "10.0.0.254/8"}
if isinstance(network, dict):
- network = [network] # if we have only one network, put it in a list
+ # if we have only one network, put it in a list
+ network = [network]
if isinstance(network, list):
if len(network) < 1:
network.append({})
@@ -250,19 +261,19 @@
dcmd=command,
datacenter=self,
flavor_name=flavor_name,
- environment = env,
+ environment=env,
**params
)
-
-
# apply resource limits to container if a resource model is defined
if self._resource_model is not None:
try:
self._resource_model.allocate(d)
- self._resource_model.write_allocation_log(d, self.resource_log_path)
+ self._resource_model.write_allocation_log(
+ d, self.resource_log_path)
except NotEnoughResourcesAvailable as ex:
- LOG.warning("Allocation of container %r was blocked by resource model." % name)
+ LOG.warning(
+ "Allocation of container %r was blocked by resource model." % name)
LOG.info(ex.message)
# ensure that we remove the container
self.net.removeDocker(name)
@@ -272,11 +283,14 @@
# if no --net option is given, network = [{}], so 1 empty dict in the list
# this results in 1 default interface with a default ip address
for nw in network:
- # clean up network configuration (e.g. RTNETLINK does not allow ':' in intf names
+ # clean up network configuration (e.g. RTNETLINK does not allow ':'
+ # in intf names
if nw.get("id") is not None:
nw["id"] = self._clean_ifname(nw["id"])
- # TODO we cannot use TCLink here (see: https://github.com/mpeuster/containernet/issues/3)
- self.net.addLink(d, self.switch, params1=nw, cls=Link, intfName1=nw.get('id'))
+ # TODO we cannot use TCLink here (see:
+ # https://github.com/mpeuster/containernet/issues/3)
+ self.net.addLink(d, self.switch, params1=nw,
+ cls=Link, intfName1=nw.get('id'))
# do bookkeeping
self.containers[name] = d
@@ -289,7 +303,8 @@
assert name is not None
if name not in self.containers:
raise Exception("Container with name %s not found." % name)
- LOG.debug("Stopping compute instance %r in data center %r" % (name, str(self)))
+ LOG.debug("Stopping compute instance %r in data center %r" %
+ (name, str(self)))
# stop the monitored metrics
if self.net.monitor_agent is not None:
@@ -298,7 +313,8 @@
# call resource model and free resources
if self._resource_model is not None:
self._resource_model.free(self.containers[name])
- self._resource_model.write_free_log(self.containers[name], self.resource_log_path)
+ self._resource_model.write_free_log(
+ self.containers[name], self.resource_log_path)
# remove links
self.net.removeLink(
@@ -318,7 +334,7 @@
def removeExternalSAP(self, sap_name):
sap_switch = self.extSAPs[sap_name].switch
- #sap_switch = self.net.getNodeByName(sap_name)
+ # sap_switch = self.net.getNodeByName(sap_name)
# remove link of SAP to the DC switch
self.net.removeLink(link=None, node1=sap_switch, node2=self.switch)
self.net.removeExtSAP(sap_name)
@@ -350,8 +366,8 @@
"switch": self.switch.name,
"n_running_containers": len(self.containers),
"metadata": self.metadata,
- "vnf_list" : container_list,
- "ext SAP list" : ext_saplist
+ "vnf_list": container_list,
+ "ext SAP list": ext_saplist
}
def assignResourceModel(self, rm):
@@ -361,7 +377,8 @@
:return:
"""
if self._resource_model is not None:
- raise Exception("There is already an resource model assigned to this DC.")
+ raise Exception(
+ "There is already an resource model assigned to this DC.")
self._resource_model = rm
self.net.rm_registrar.register(self, rm)
LOG.info("Assigned RM: %r to DC: %r" % (rm, self))
@@ -381,4 +398,3 @@
name = name.replace(".", "-")
name = name.replace("_", "-")
return name
-
diff --git a/src/emuvim/dcemulator/resourcemodel/__init__.py b/src/emuvim/dcemulator/resourcemodel/__init__.py
index 869eb1d..de100f7 100755
--- a/src/emuvim/dcemulator/resourcemodel/__init__.py
+++ b/src/emuvim/dcemulator/resourcemodel/__init__.py
@@ -1,34 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-"""
-Base classes needed for resource models support.
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
LOG = logging.getLogger("resourcemodel")
LOG.setLevel(logging.DEBUG)
@@ -55,7 +49,8 @@
:return: None
"""
if dc in self._resource_models:
- raise Exception("There is already an resource model assigned to this DC.")
+ raise Exception(
+ "There is already an resource model assigned to this DC.")
self._resource_models[dc] = rm
rm.registrar = self
rm.dcs.append(dc)
@@ -75,7 +70,8 @@
Total number of data centers that are connected to a resource model
:return:
"""
- return sum([len(rm.dcs) for rm in list(self._resource_models.itervalues())])
+ return sum([len(rm.dcs)
+ for rm in list(self._resource_models.itervalues())])
class ResourceFlavor(object):
@@ -83,6 +79,7 @@
Simple class that represents resource flavors (c.f. OpenStack).
Can contain arbitrary metrics.
"""
+
def __init__(self, name, metrics):
self.name = name
self._metrics = metrics
@@ -114,15 +111,15 @@
initialize some default flavours (naming/sizes inspired by OpenStack)
"""
self.addFlavour(ResourceFlavor(
- "tiny", {"compute": 0.5, "memory": 32, "disk": 1}))
+ "tiny", {"compute": 0.5, "memory": 32, "disk": 1}))
self.addFlavour(ResourceFlavor(
- "small", {"compute": 1.0, "memory": 128, "disk": 20}))
+ "small", {"compute": 1.0, "memory": 128, "disk": 20}))
self.addFlavour(ResourceFlavor(
- "medium", {"compute": 4.0, "memory": 256, "disk": 40}))
+ "medium", {"compute": 4.0, "memory": 256, "disk": 40}))
self.addFlavour(ResourceFlavor(
- "large", {"compute": 8.0, "memory": 512, "disk": 80}))
+ "large", {"compute": 8.0, "memory": 512, "disk": 80}))
self.addFlavour(ResourceFlavor(
- "xlarge", {"compute": 16.0, "memory": 1024, "disk": 160}))
+ "xlarge", {"compute": 16.0, "memory": 1024, "disk": 160}))
def addFlavour(self, fl):
"""
@@ -139,7 +136,8 @@
This method has to be overwritten by a real resource model.
:param d: Container object
"""
- LOG.warning("Allocating in BaseResourceModel: %r with flavor: %r" % (d.name, d.flavor_name))
+ LOG.warning("Allocating in BaseResourceModel: %r with flavor: %r" % (
+ d.name, d.flavor_name))
self._allocated_compute_instances[d.name] = d.flavor_name
def free(self, d):
diff --git a/src/emuvim/dcemulator/resourcemodel/upb/__init__.py b/src/emuvim/dcemulator/resourcemodel/upb/__init__.py
index 395c0ce..d888119 100755
--- a/src/emuvim/dcemulator/resourcemodel/upb/__init__.py
+++ b/src/emuvim/dcemulator/resourcemodel/upb/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/dcemulator/resourcemodel/upb/simple.py b/src/emuvim/dcemulator/resourcemodel/upb/simple.py
index b812aad..01231fd 100755
--- a/src/emuvim/dcemulator/resourcemodel/upb/simple.py
+++ b/src/emuvim/dcemulator/resourcemodel/upb/simple.py
@@ -1,33 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-"""
-Playground for resource models created by University of Paderborn.
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import time
import json
import logging
@@ -93,7 +88,8 @@
fl_cu = self._get_flavor(d).get("compute")
# check for over provisioning
if self.dc_alloc_cu + fl_cu > self.dc_max_cu and self.raise_no_cpu_resources_left:
- raise NotEnoughResourcesAvailable("Not enough compute resources left.")
+ raise NotEnoughResourcesAvailable(
+ "Not enough compute resources left.")
self.dc_alloc_cu += fl_cu
def _allocate_mem(self, d):
@@ -105,7 +101,8 @@
fl_mu = self._get_flavor(d).get("memory")
# check for over provisioning
if self.dc_alloc_mu + fl_mu > self.dc_max_mu and self.raise_no_mem_resources_left:
- raise NotEnoughResourcesAvailable("Not enough memory resources left.")
+ raise NotEnoughResourcesAvailable(
+ "Not enough memory resources left.")
self.dc_alloc_mu += fl_mu
def free(self, d):
@@ -162,12 +159,14 @@
# calculate cpu time fraction for container with given flavor
cpu_time_percentage = self.single_cu * number_cu
# calculate input values for CFS scheduler bandwidth limitation
- cpu_period, cpu_quota = self._calculate_cpu_cfs_values(cpu_time_percentage)
+ cpu_period, cpu_quota = self._calculate_cpu_cfs_values(
+ cpu_time_percentage)
# apply limits to container if changed
if d.resources['cpu_period'] != cpu_period or d.resources['cpu_quota'] != cpu_quota:
LOG.debug("Setting CPU limit for %r: cpu_quota = cpu_period * limit = %f * %f = %f (op_factor=%f)" % (
d.name, cpu_period, cpu_time_percentage, cpu_quota, self.cpu_op_factor))
- d.updateCpuLimit(cpu_period=int(cpu_period), cpu_quota=int(cpu_quota))
+ d.updateCpuLimit(cpu_period=int(cpu_period),
+ cpu_quota=int(cpu_quota))
def _compute_single_cu(self):
"""
@@ -177,7 +176,8 @@
# get cpu time fraction for entire emulation
e_cpu = self.registrar.e_cpu
# calculate
- return float(e_cpu) / sum([rm.dc_max_cu for rm in list(self.registrar.resource_models)])
+ return float(
+ e_cpu) / sum([rm.dc_max_cu for rm in list(self.registrar.resource_models)])
def _calculate_cpu_cfs_values(self, cpu_time_percentage):
"""
@@ -188,8 +188,10 @@
# (see: https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt)
# Attention minimum cpu_quota is 1ms (micro)
cpu_period = CPU_PERIOD # lets consider a fixed period of 1000000 microseconds for now
- cpu_quota = cpu_period * cpu_time_percentage # calculate the fraction of cpu time for this container
- # ATTENTION >= 1000 to avoid a invalid argument system error ... no idea why
+ # calculate the fraction of cpu time for this container
+ cpu_quota = cpu_period * cpu_time_percentage
+ # ATTENTION >= 1000 to avoid a invalid argument system error ... no
+ # idea why
if cpu_quota < 1000:
cpu_quota = 1000
LOG.warning("Increased CPU quota to avoid system error.")
@@ -205,14 +207,15 @@
# get memory amount for entire emulation
e_mem = self.registrar.e_mem
# calculate amount of memory for a single mu
- self.single_mu = float(e_mem) / sum([rm.dc_max_mu for rm in list(self.registrar.resource_models)])
+ self.single_mu = float(
+ e_mem) / sum([rm.dc_max_mu for rm in list(self.registrar.resource_models)])
# calculate mem for given flavor
mem_limit = self.single_mu * number_mu
mem_limit = self._calculate_mem_limit_value(mem_limit)
# apply to container if changed
if d.resources['mem_limit'] != mem_limit:
LOG.debug("Setting MEM limit for %r: mem_limit = %f MB (op_factor=%f)" %
- (d.name, mem_limit/1024/1024, self.mem_op_factor))
+ (d.name, mem_limit / 1024 / 1024, self.mem_op_factor))
d.updateMemoryLimit(mem_limit=mem_limit)
def _calculate_mem_limit_value(self, mem_limit):
@@ -226,7 +229,7 @@
mem_limit = 4
LOG.warning("Increased MEM limit because it was less than 4.0 MB.")
# to byte!
- return int(mem_limit*1024*1024)
+ return int(mem_limit * 1024 * 1024)
def get_state_dict(self):
"""
@@ -281,14 +284,14 @@
if path is None:
return
# we have a path: write out RM info
- l = dict()
- l["t"] = time.time()
- l["container_state"] = d.getStatus()
- l["action"] = action
- l["rm_state"] = self.get_state_dict()
+ logd = dict()
+ logd["t"] = time.time()
+ logd["container_state"] = d.getStatus()
+ logd["action"] = action
+ logd["rm_state"] = self.get_state_dict()
# append to logfile
with open(path, "a") as f:
- f.write("%s\n" % json.dumps(l))
+ f.write("%s\n" % json.dumps(logd))
class UpbOverprovisioningCloudDcRM(UpbSimpleCloudDcRM):
@@ -299,6 +302,7 @@
containers whenever a data-center is over provisioned.
"""
# TODO add parts for memory
+
def __init__(self, *args, **kvargs):
super(UpbOverprovisioningCloudDcRM, self).__init__(*args, **kvargs)
self.raise_no_cpu_resources_left = False
@@ -312,15 +316,18 @@
# get cpu time fraction for entire emulation
e_cpu = self.registrar.e_cpu
# calculate over provisioning scale factor
- self.cpu_op_factor = float(self.dc_max_cu) / (max(self.dc_max_cu, self.dc_alloc_cu))
+ self.cpu_op_factor = float(self.dc_max_cu) / \
+ (max(self.dc_max_cu, self.dc_alloc_cu))
# calculate
- return float(e_cpu) / sum([rm.dc_max_cu for rm in list(self.registrar.resource_models)]) * self.cpu_op_factor
+ return float(e_cpu) / sum([rm.dc_max_cu for rm in list(
+ self.registrar.resource_models)]) * self.cpu_op_factor
class UpbDummyRM(UpbSimpleCloudDcRM):
"""
No limits. But log allocations.
"""
+
def __init__(self, *args, **kvargs):
super(UpbDummyRM, self).__init__(*args, **kvargs)
self.raise_no_cpu_resources_left = False
@@ -328,4 +335,3 @@
def _apply_limits(self):
# do nothing here
pass
-
diff --git a/src/emuvim/dcemulator/son_emu_simple_switch_13.py b/src/emuvim/dcemulator/son_emu_simple_switch_13.py
index 53d1a2e..2adaf80 100755
--- a/src/emuvim/dcemulator/son_emu_simple_switch_13.py
+++ b/src/emuvim/dcemulator/son_emu_simple_switch_13.py
@@ -21,7 +21,8 @@
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib.packet import ether_types
-from ryu.topology.event import EventSwitchEnter, EventSwitchLeave, EventSwitchReconnected
+from ryu.topology.event import EventSwitchEnter, EventSwitchReconnected
+
class SimpleSwitch13(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
@@ -44,12 +45,13 @@
# truncated packet data. In that case, we cannot output packets
# correctly. The bug has been fixed in OVS v2.1.0.
match = parser.OFPMatch()
- #actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
+ # actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
# ofproto.OFPCML_NO_BUFFER)]
actions = [parser.OFPActionOutput(ofproto.OFPCML_NO_BUFFER)]
self.add_flow(datapath, 0, match, actions)
- def add_flow(self, datapath, priority, match, actions, buffer_id=None, table_id=0):
+ def add_flow(self, datapath, priority, match,
+ actions, buffer_id=None, table_id=0):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
@@ -77,7 +79,6 @@
actions = [ofp_parser.OFPActionOutput(ofproto_v1_3.OFPP_NORMAL)]
self.add_flow(datapath, 0, None, actions, table_id=0)
-
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
# If you hit this you might want to increase
diff --git a/src/emuvim/examples/default_single_dc_topology.py b/src/emuvim/examples/default_single_dc_topology.py
index 9574d17..6ae0ae2 100644
--- a/src/emuvim/examples/default_single_dc_topology.py
+++ b/src/emuvim/examples/default_single_dc_topology.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
from mininet.log import setLogLevel
from emuvim.dcemulator.net import DCNetwork
diff --git a/src/emuvim/examples/openstack_single_dc.py b/src/emuvim/examples/openstack_single_dc.py
index e30ff19..7070cda 100644
--- a/src/emuvim/examples/openstack_single_dc.py
+++ b/src/emuvim/examples/openstack_single_dc.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
from mininet.log import setLogLevel
from emuvim.dcemulator.net import DCNetwork
diff --git a/src/emuvim/examples/osm_default_daemon_topology_2_pop.py b/src/emuvim/examples/osm_default_daemon_topology_2_pop.py
index 4f44ddd..164ecb4 100644
--- a/src/emuvim/examples/osm_default_daemon_topology_2_pop.py
+++ b/src/emuvim/examples/osm_default_daemon_topology_2_pop.py
@@ -1,30 +1,28 @@
-"""
-Copyright (c) 2017 SONATA-NFV and Paderborn University
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV, Paderborn University
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import logging
import time
import signal
@@ -47,11 +45,12 @@
logging.getLogger('api.openstack.glance').setLevel(logging.DEBUG)
logging.getLogger('api.openstack.helper').setLevel(logging.DEBUG)
+
class DaemonTopology(object):
"""
Topology with two datacenters:
- dc1 <-- 50ms --> dc2
+ dc1 <-- 50ms --> dc2
"""
def __init__(self):
@@ -105,7 +104,7 @@
def main():
- t = DaemonTopology()
+ DaemonTopology()
if __name__ == '__main__':
diff --git a/src/emuvim/test/__init__.py b/src/emuvim/test/__init__.py
index 7e60065..d888119 100755
--- a/src/emuvim/test/__init__.py
+++ b/src/emuvim/test/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/test/api_base.py b/src/emuvim/test/api_base.py
index 0d994ca..bf0f4c0 100755
--- a/src/emuvim/test/api_base.py
+++ b/src/emuvim/test/api_base.py
@@ -1,35 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-"""
-Helper module that implements helpers for test implementations.
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import unittest
import os
import subprocess
@@ -39,6 +32,7 @@
from mininet.clean import cleanup
from mininet.node import Controller
+
class SimpleTestTopology(unittest.TestCase):
"""
Helper class to do basic test setups.
@@ -72,7 +66,7 @@
# 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
- for i in range(1, nswitches+1):
+ for i in range(1, nswitches + 1):
self.s.append(self.net.addSwitch('s%d' % i))
# if specified, chain all switches
if autolinkswitches:
@@ -92,14 +86,15 @@
self.h.append(self.net.addHost('h%d' % i))
# add some dockers
for i in range(0, ndockers):
- self.d.append(self.net.addDocker('d%d' % i, dimage="ubuntu:trusty"))
+ self.d.append(self.net.addDocker('d%d' %
+ i, dimage="ubuntu:trusty"))
def startApi(self):
self.api.start()
def stopApi(self):
self.api.stop()
-
+
def startNet(self):
self.net.start()
@@ -119,7 +114,8 @@
"""
List the containers managed by containernet
"""
- return self.getDockerCli().containers(filters={"label": "com.containernet"})
+ return self.getDockerCli().containers(
+ filters={"label": "com.containernet"})
@staticmethod
def setUp():
diff --git a/src/emuvim/test/api_base_openstack.py b/src/emuvim/test/api_base_openstack.py
index c951665..3909e1a 100755
--- a/src/emuvim/test/api_base_openstack.py
+++ b/src/emuvim/test/api_base_openstack.py
@@ -1,35 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-"""
-Helper module that implements helpers for test implementations.
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import unittest
import os
import subprocess
@@ -40,6 +33,7 @@
from mininet.clean import cleanup
from mininet.node import Controller
+
class ApiBaseOpenStack(unittest.TestCase):
"""
Helper class to do basic test setups.
@@ -70,18 +64,19 @@
"""
self.net = DCNetwork(controller=controller, **kwargs)
for i in range(0, ndatacenter):
- self.api.append(OpenstackApiEndpoint("0.0.0.0", 15000+i))
+ self.api.append(OpenstackApiEndpoint("0.0.0.0", 15000 + i))
# 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
- for i in range(1, nswitches+1):
+ for i in range(1, nswitches + 1):
self.s.append(self.net.addSwitch('s%d' % i))
# if specified, chain all switches
if autolinkswitches:
for i in range(0, len(self.s) - 1):
self.net.addLink(self.s[i], self.s[i + 1])
- self.net.addLink(self.s[2], self.s[0]) # link switches s1, s2 and s3
+ # link switches s1, s2 and s3
+ self.net.addLink(self.s[2], self.s[0])
# add some data centers
for i in range(0, ndatacenter):
@@ -89,7 +84,8 @@
self.net.addDatacenter(
'dc%d' % i,
metadata={"unittest_dc": i}))
- self.net.addLink(self.dc[0].switch, self.s[0]) # link switches dc0.s1 with s1
+ # link switches dc0.s1 with s1
+ self.net.addLink(self.dc[0].switch, self.s[0])
# connect data centers to the endpoint
for i in range(0, ndatacenter):
self.api[i].connect_datacenter(self.dc[i])
@@ -99,7 +95,8 @@
self.h.append(self.net.addHost('h%d' % i))
# add some dockers
for i in range(0, ndockers):
- self.d.append(self.net.addDocker('d%d' % i, dimage="ubuntu:trusty"))
+ self.d.append(self.net.addDocker('d%d' %
+ i, dimage="ubuntu:trusty"))
def startApi(self):
for i in self.api:
@@ -129,25 +126,26 @@
"""
List the containers managed by containernet
"""
- return self.getDockerCli().containers(filters={"label": "com.containernet"})
+ return self.getDockerCli().containers(
+ filters={"label": "com.containernet"})
@staticmethod
def setUp():
pass
-
def tearDown(self):
time.sleep(2)
print('->>>>>>> tear everything down ->>>>>>>>>>>>>>>')
- self.stopApi() # stop all flask threads
- self.stopNet() # stop some mininet and containernet stuff
+ self.stopApi() # stop all flask threads
+ self.stopNet() # stop some mininet and containernet stuff
cleanup()
# make sure that all pending docker containers are killed
- with open(os.devnull, 'w') as devnull: # kill a possibly running docker process that blocks the open ports
+ # kill a possibly running docker process that blocks the open ports
+ with open(os.devnull, 'w') as devnull:
subprocess.call("kill $(netstat -npl | grep '15000' | grep -o -e'[0-9]\+/docker' | grep -o -e '[0-9]\+')",
- stdout=devnull,
- stderr=devnull,
- shell=True)
+ stdout=devnull,
+ stderr=devnull,
+ shell=True)
with open(os.devnull, 'w') as devnull:
subprocess.call(
@@ -156,8 +154,3 @@
stderr=devnull,
shell=True)
time.sleep(2)
-
-
-
-
-
diff --git a/src/emuvim/test/base.py b/src/emuvim/test/base.py
index 397e2a1..6221765 100755
--- a/src/emuvim/test/base.py
+++ b/src/emuvim/test/base.py
@@ -1,35 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-"""
-Helper module that implements helpers for test implementations.
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import unittest
import os
import subprocess
@@ -38,6 +31,7 @@
from mininet.clean import cleanup
from mininet.node import Controller
+
class SimpleTestTopology(unittest.TestCase):
"""
Helper class to do basic test setups.
@@ -70,7 +64,7 @@
# 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
- for i in range(1, nswitches+1):
+ for i in range(1, nswitches + 1):
self.s.append(self.net.addSwitch('s%d' % i))
# if specified, chain all switches
if autolinkswitches:
@@ -87,7 +81,8 @@
self.h.append(self.net.addHost('h%d' % i))
# add some dockers
for i in range(0, ndockers):
- self.d.append(self.net.addDocker('d%d' % i, dimage="ubuntu:trusty"))
+ self.d.append(self.net.addDocker('d%d' %
+ i, dimage="ubuntu:trusty"))
def startNet(self):
self.net.start()
@@ -108,7 +103,8 @@
"""
List the containers managed by containernet
"""
- return self.getDockerCli().containers(filters={"label": "com.containernet"})
+ return self.getDockerCli().containers(
+ filters={"label": "com.containernet"})
@staticmethod
def setUp():
@@ -123,4 +119,4 @@
"sudo docker rm -f $(sudo docker ps --filter 'label=com.containernet' -a -q)",
stdout=devnull,
stderr=devnull,
- shell=True)
\ No newline at end of file
+ shell=True)
diff --git a/src/emuvim/test/integrationtests/__init__.py b/src/emuvim/test/integrationtests/__init__.py
index 7e60065..d888119 100755
--- a/src/emuvim/test/integrationtests/__init__.py
+++ b/src/emuvim/test/integrationtests/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/test/unittests/__init__.py b/src/emuvim/test/unittests/__init__.py
index 7e60065..d888119 100755
--- a/src/emuvim/test/unittests/__init__.py
+++ b/src/emuvim/test/unittests/__init__.py
@@ -1,27 +1,25 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
diff --git a/src/emuvim/test/unittests/test_emulator.py b/src/emuvim/test/unittests/test_emulator.py
index 94db55f..fc06a69 100755
--- a/src/emuvim/test/unittests/test_emulator.py
+++ b/src/emuvim/test/unittests/test_emulator.py
@@ -1,47 +1,36 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-"""
-Test suite to automatically test emulator functionalities.
-Directly interacts with the emulator through the Mininet-like
-Python API.
-
-Does not test API endpoints. This is done in separated test suites.
-"""
-
-import time
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import unittest
from emuvim.dcemulator.node import EmulatorCompute
from emuvim.test.base import SimpleTestTopology
from mininet.node import RemoteController
-#@unittest.skip("disabled topology tests for development")
-class testEmulatorTopology( SimpleTestTopology ):
+# @unittest.skip("disabled topology tests for development")
+class testEmulatorTopology(SimpleTestTopology):
"""
Tests to check the topology API of the emulator.
"""
@@ -68,7 +57,7 @@
# stop Mininet network
self.stopNet()
- #@unittest.skip("disabled to test if CI fails because this is the first test.")
+ # @unittest.skip("disabled to test if CI fails because this is the first test.")
def testMultipleDatacenterDirect(self):
"""
Create a two data centers and interconnect them.
@@ -115,7 +104,8 @@
# stop Mininet network
self.stopNet()
-class testEmulatorNetworking( SimpleTestTopology ):
+
+class testEmulatorNetworking(SimpleTestTopology):
def testSDNChainingSingleService_withLearning(self):
"""
@@ -137,8 +127,10 @@
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'}])
+ 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)
@@ -162,7 +154,8 @@
# 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')
+ 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
@@ -188,8 +181,10 @@
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'}])
+ 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)
@@ -213,7 +208,8 @@
# should be not not yet connected
self.assertTrue(self.net.ping([vnf1, vnf2]) > 0.0)
# setup links
- self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='add-flow')
+ self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
+ bidirectional=True, cmd='add-flow')
# check connectivity by using ping
self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
# stop Mininet network
@@ -239,19 +235,24 @@
# start Mininet network
self.startNet()
- ## First Service
+ # First Service
# 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'}])
+ 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'}])
# setup links
- self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='add-flow', cookie=1)
+ self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
+ bidirectional=True, cmd='add-flow', cookie=1)
# check connectivity by using ping
self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
- ## Second Service
+ # Second Service
# add compute resources
- vnf11 = self.dc[0].startCompute("vnf11", network=[{'id': 'intf1', 'ip': '10.0.20.1/24'}])
- vnf22 = self.dc[1].startCompute("vnf22", network=[{'id': 'intf2', 'ip': '10.0.20.2/24'}])
+ vnf11 = self.dc[0].startCompute(
+ "vnf11", network=[{'id': 'intf1', 'ip': '10.0.20.1/24'}])
+ vnf22 = self.dc[1].startCompute(
+ "vnf22", network=[{'id': 'intf2', 'ip': '10.0.20.2/24'}])
# check number of running nodes
self.assertTrue(len(self.getContainernetContainers()) == 4)
@@ -259,7 +260,8 @@
self.assertTrue(len(self.net.switches) == 5)
# setup links
- self.net.setChain('vnf11', 'vnf22', 'intf1', 'intf2', bidirectional=True, cmd='add-flow', cookie=2)
+ self.net.setChain('vnf11', 'vnf22', 'intf1', 'intf2',
+ bidirectional=True, cmd='add-flow', cookie=2)
# check connectivity by using ping
self.assertTrue(self.net.ping([vnf11, vnf22]) <= 0.0)
# check first service cannot ping second service
@@ -267,18 +269,21 @@
self.assertTrue(self.net.ping([vnf2, vnf11]) > 0.0)
# delete the first service chain
- self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='del-flows', cookie=1)
+ self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
+ bidirectional=True, cmd='del-flows', cookie=1)
# check connectivity of first service is down
self.assertTrue(self.net.ping([vnf1, vnf2]) > 0.0)
- #time.sleep(100)
+ # time.sleep(100)
# check connectivity of second service is still up
self.assertTrue(self.net.ping([vnf11, vnf22]) <= 0.0)
# stop Mininet network
self.stopNet()
-#@unittest.skip("disabled compute tests for development")
-class testEmulatorCompute( SimpleTestTopology ):
+# @unittest.skip("disabled compute tests for development")
+
+
+class testEmulatorCompute(SimpleTestTopology):
"""
Tests to check the emulator's API to add and remove
compute resources at runtime.
@@ -304,7 +309,8 @@
self.assertTrue(len(self.net.switches) == 1)
# check compute list result
self.assertTrue(len(self.dc[0].listCompute()) == 1)
- self.assertTrue(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
+ self.assertTrue(isinstance(
+ self.dc[0].listCompute()[0], EmulatorCompute))
self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
# check connectivity by using ping
self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
@@ -362,7 +368,8 @@
self.assertTrue(len(self.net.switches) == 1)
# check compute list result
self.assertTrue(len(self.dc[0].listCompute()) == 1)
- self.assertTrue(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
+ self.assertTrue(isinstance(
+ self.dc[0].listCompute()[0], EmulatorCompute))
self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
# check connectivity by using ping
self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
@@ -407,7 +414,7 @@
Test multiple, interleaved add and remove operations and ensure
that always all expected compute instances are reachable.
"""
- # create network
+ # create network
self.createNet(
nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
autolinkswitches=True)
@@ -455,5 +462,6 @@
# stop Mininet network
self.stopNet()
+
if __name__ == '__main__':
unittest.main()
diff --git a/src/emuvim/test/unittests/test_openstack.py b/src/emuvim/test/unittests/test_openstack.py
index 3e9037a..a9273fb 100755
--- a/src/emuvim/test/unittests/test_openstack.py
+++ b/src/emuvim/test/unittests/test_openstack.py
@@ -1,41 +1,33 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-"""
-Test suite to automatically test emulator REST API endpoints.
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import os
import unittest
import requests
import simplejson as json
import yaml
-import time
from emuvim.test.api_base_openstack import ApiBaseOpenStack
@@ -47,7 +39,8 @@
def setUp(self):
# create network
- self.createNet(nswitches=3, ndatacenter=2, nhosts=2, ndockers=0, autolinkswitches=True)
+ self.createNet(nswitches=3, ndatacenter=2, nhosts=2,
+ ndockers=0, autolinkswitches=True)
# setup links
self.net.addLink(self.dc[0], self.h[0])
@@ -66,7 +59,8 @@
print(" ")
headers = {'Content-type': 'application/json'}
- test_heatapi_template_create_stack = open(os.path.join(os.path.dirname(__file__), "templates/test_heatapi_template_create_stack.yml")).read()
+ test_heatapi_template_create_stack = open(os.path.join(os.path.dirname(
+ __file__), "templates/test_heatapi_template_create_stack.yml")).read()
url = "http://0.0.0.0:18004/v1/tenantabc123/stacks"
requests.post(url, data=json.dumps(yaml.load(test_heatapi_template_create_stack)),
headers=headers)
@@ -76,11 +70,16 @@
url = "http://0.0.0.0:18774/"
listapiversionnovaresponse = requests.get(url, headers=headers)
self.assertEqual(listapiversionnovaresponse.status_code, 200)
- self.assertEqual(json.loads(listapiversionnovaresponse.content)["versions"][0]["id"], "v2.1")
- self.assertEqual(json.loads(listapiversionnovaresponse.content)["versions"][0]["status"], "CURRENT")
- self.assertEqual(json.loads(listapiversionnovaresponse.content)["versions"][0]["version"], "2.38")
- self.assertEqual(json.loads(listapiversionnovaresponse.content)["versions"][0]["min_version"], "2.1")
- self.assertEqual(json.loads(listapiversionnovaresponse.content)["versions"][0]["updated"], "2013-07-23T11:33:21Z")
+ self.assertEqual(json.loads(listapiversionnovaresponse.content)[
+ "versions"][0]["id"], "v2.1")
+ self.assertEqual(json.loads(listapiversionnovaresponse.content)[
+ "versions"][0]["status"], "CURRENT")
+ self.assertEqual(json.loads(listapiversionnovaresponse.content)[
+ "versions"][0]["version"], "2.38")
+ self.assertEqual(json.loads(listapiversionnovaresponse.content)[
+ "versions"][0]["min_version"], "2.1")
+ self.assertEqual(json.loads(listapiversionnovaresponse.content)[
+ "versions"][0]["updated"], "2013-07-23T11:33:21Z")
print(" ")
print('->>>>>>> test Nova Version Show ->>>>>>>>>>>>>>>')
@@ -88,11 +87,16 @@
url = "http://0.0.0.0:18774/v2.1/id_bla"
listapiversion21novaresponse = requests.get(url, headers=headers)
self.assertEqual(listapiversion21novaresponse.status_code, 200)
- self.assertEqual(json.loads(listapiversion21novaresponse.content)["version"]["id"], "v2.1")
- self.assertEqual(json.loads(listapiversion21novaresponse.content)["version"]["status"], "CURRENT")
- self.assertEqual(json.loads(listapiversion21novaresponse.content)["version"]["version"], "2.38")
- self.assertEqual(json.loads(listapiversion21novaresponse.content)["version"]["min_version"], "2.1")
- self.assertEqual(json.loads(listapiversion21novaresponse.content)["version"]["updated"], "2013-07-23T11:33:21Z")
+ self.assertEqual(json.loads(listapiversion21novaresponse.content)[
+ "version"]["id"], "v2.1")
+ self.assertEqual(json.loads(listapiversion21novaresponse.content)[
+ "version"]["status"], "CURRENT")
+ self.assertEqual(json.loads(listapiversion21novaresponse.content)[
+ "version"]["version"], "2.38")
+ self.assertEqual(json.loads(listapiversion21novaresponse.content)[
+ "version"]["min_version"], "2.1")
+ self.assertEqual(json.loads(listapiversion21novaresponse.content)[
+ "version"]["updated"], "2013-07-23T11:33:21Z")
print(" ")
print('->>>>>>> test Nova Version List Server APIs ->>>>>>>>>>>>>>>')
@@ -100,12 +104,14 @@
url = "http://0.0.0.0:18774/v2.1/id_bla/servers"
listserverapisnovaresponse = requests.get(url, headers=headers)
self.assertEqual(listserverapisnovaresponse.status_code, 200)
- self.assertNotEqual(json.loads(listserverapisnovaresponse.content)["servers"][0]["name"], "")
+ self.assertNotEqual(json.loads(listserverapisnovaresponse.content)[
+ "servers"][0]["name"], "")
print(" ")
print('->>>>>>> test Nova Delete Server APIs ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:18774/v2.1/id_bla/servers/%s" % (json.loads(listserverapisnovaresponse.content)["servers"][0]["id"])
+ url = "http://0.0.0.0:18774/v2.1/id_bla/servers/%s" % (
+ json.loads(listserverapisnovaresponse.content)["servers"][0]["id"])
deleteserverapisnovaresponse = requests.delete(url, headers=headers)
self.assertEqual(deleteserverapisnovaresponse.status_code, 204)
print(" ")
@@ -117,13 +123,13 @@
self.assertEqual(deleteserverapisnovaresponse.status_code, 404)
print(" ")
-
print('->>>>>>> testNovaVersionListServerAPIs_withPortInformation ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18774/v2.1/id_bla/servers/andPorts"
listserverapisnovaresponse = requests.get(url, headers=headers)
self.assertEqual(listserverapisnovaresponse.status_code, 200)
- self.assertNotEqual(json.loads(listserverapisnovaresponse.content)["servers"][0]["name"], "")
+ self.assertNotEqual(json.loads(listserverapisnovaresponse.content)[
+ "servers"][0]["name"], "")
print(" ")
print('->>>>>>> test Nova List Flavors ->>>>>>>>>>>>>>>')
@@ -131,9 +137,12 @@
url = "http://0.0.0.0:18774/v2.1/id_bla/flavors"
listflavorsresponse = requests.get(url, headers=headers)
self.assertEqual(listflavorsresponse.status_code, 200)
- self.assertIn(json.loads(listflavorsresponse.content)["flavors"][0]["name"], ["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
- self.assertIn(json.loads(listflavorsresponse.content)["flavors"][1]["name"], ["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
- self.assertIn(json.loads(listflavorsresponse.content)["flavors"][2]["name"], ["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
+ self.assertIn(json.loads(listflavorsresponse.content)["flavors"][0]["name"], [
+ "m1.nano", "m1.tiny", "m1.micro", "m1.small"])
+ self.assertIn(json.loads(listflavorsresponse.content)["flavors"][1]["name"], [
+ "m1.nano", "m1.tiny", "m1.micro", "m1.small"])
+ self.assertIn(json.loads(listflavorsresponse.content)["flavors"][2]["name"], [
+ "m1.nano", "m1.tiny", "m1.micro", "m1.small"])
print(" ")
print('->>>>>>> testNovaAddFlavors ->>>>>>>>>>>>>>>')
@@ -143,8 +152,10 @@
data='{"flavor":{"name": "testFlavor", "vcpus": "test_vcpus", "ram": 1024, "disk": 10}}',
headers=headers)
self.assertEqual(addflavorsresponse.status_code, 200)
- self.assertIsNotNone(json.loads(addflavorsresponse.content)["flavor"]["id"])
- self.assertIsNotNone(json.loads(addflavorsresponse.content)["flavor"]["links"][0]['href'])
+ self.assertIsNotNone(json.loads(
+ addflavorsresponse.content)["flavor"]["id"])
+ self.assertIsNotNone(json.loads(addflavorsresponse.content)[
+ "flavor"]["links"][0]['href'])
print(" ")
print('->>>>>>> test Nova List Flavors Detail ->>>>>>>>>>>>>>>')
@@ -152,9 +163,12 @@
url = "http://0.0.0.0:18774/v2.1/id_bla/flavors/detail"
listflavorsdetailresponse = requests.get(url, headers=headers)
self.assertEqual(listflavorsdetailresponse.status_code, 200)
- self.assertIn(json.loads(listflavorsdetailresponse.content)["flavors"][0]["name"],["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
- self.assertIn(json.loads(listflavorsdetailresponse.content)["flavors"][1]["name"],["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
- self.assertIn(json.loads(listflavorsdetailresponse.content)["flavors"][2]["name"],["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
+ self.assertIn(json.loads(listflavorsdetailresponse.content)[
+ "flavors"][0]["name"], ["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
+ self.assertIn(json.loads(listflavorsdetailresponse.content)[
+ "flavors"][1]["name"], ["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
+ self.assertIn(json.loads(listflavorsdetailresponse.content)[
+ "flavors"][2]["name"], ["m1.nano", "m1.tiny", "m1.micro", "m1.small"])
print(" ")
print('->>>>>>> testNovaAddFlavors ->>>>>>>>>>>>>>>')
@@ -164,17 +178,21 @@
data='{"flavor":{"name": "testFlavor", "vcpus": "test_vcpus", "ram": 1024, "disk": 10}}',
headers=headers)
self.assertEqual(addflavorsresponse.status_code, 200)
- self.assertIsNotNone(json.loads(addflavorsresponse.content)["flavor"]["id"])
- self.assertIsNotNone(json.loads(addflavorsresponse.content)["flavor"]["links"][0]['href'])
+ self.assertIsNotNone(json.loads(
+ addflavorsresponse.content)["flavor"]["id"])
+ self.assertIsNotNone(json.loads(addflavorsresponse.content)[
+ "flavor"]["links"][0]['href'])
print(" ")
print('->>>>>>> test Nova List Flavor By Id ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:18774/v2.1/id_bla/flavors/%s" % (json.loads(listflavorsdetailresponse.content)["flavors"][0]["name"])
+ url = "http://0.0.0.0:18774/v2.1/id_bla/flavors/%s" % (
+ json.loads(listflavorsdetailresponse.content)["flavors"][0]["name"])
listflavorsbyidresponse = requests.get(url, headers=headers)
self.assertEqual(listflavorsbyidresponse.status_code, 200)
- self.assertEqual(json.loads(listflavorsbyidresponse.content)["flavor"]["id"], json.loads(listflavorsdetailresponse.content)["flavors"][0]["id"])
+ self.assertEqual(json.loads(listflavorsbyidresponse.content)[
+ "flavor"]["id"], json.loads(listflavorsdetailresponse.content)["flavors"][0]["id"])
print(" ")
print('->>>>>>> test Nova List Images ->>>>>>>>>>>>>>>')
@@ -183,10 +201,6 @@
listimagesresponse = requests.get(url, headers=headers)
self.assertEqual(listimagesresponse.status_code, 200)
print(listimagesresponse.content)
- # deactivated: highly depends on the environment in which the tests are executed. one cannot make such an assumption.
- #self.assertIn(json.loads(listimagesresponse.content)["images"][0]["name"],["google/cadvisor:latest", "ubuntu:trusty", "prom/pushgateway:latest"])
- #self.assertIn(json.loads(listimagesresponse.content)["images"][1]["name"],["google/cadvisor:latest", "ubuntu:trusty", "prom/pushgateway:latest"])
- #self.assertIn(json.loads(listimagesresponse.content)["images"][2]["name"],["google/cadvisor:latest", "ubuntu:trusty", "prom/pushgateway:latest"])
print(" ")
print('->>>>>>> test Nova List Images Details ->>>>>>>>>>>>>>>')
@@ -194,19 +208,18 @@
url = "http://0.0.0.0:18774/v2.1/id_bla/images/detail"
listimagesdetailsresponse = requests.get(url, headers=headers)
self.assertEqual(listimagesdetailsresponse.status_code, 200)
- # deactivated: highly depends on the environment in which the tests are executed. one cannot make such an assumption.
- #self.assertIn(json.loads(listimagesdetailsresponse.content)["images"][0]["name"],["google/cadvisor:latest", "ubuntu:trusty", "prom/pushgateway:latest"])
- #self.assertIn(json.loads(listimagesdetailsresponse.content)["images"][1]["name"],["google/cadvisor:latest", "ubuntu:trusty", "prom/pushgateway:latest"])
- #self.assertIn(json.loads(listimagesdetailsresponse.content)["images"][2]["name"],["google/cadvisor:latest", "ubuntu:trusty", "prom/pushgateway:latest"])
- self.assertEqual(json.loads(listimagesdetailsresponse.content)["images"][0]["metadata"]["architecture"],"x86_64")
+ self.assertEqual(json.loads(listimagesdetailsresponse.content)[
+ "images"][0]["metadata"]["architecture"], "x86_64")
print(" ")
print('->>>>>>> test Nova List Image By Id ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:18774/v2.1/id_bla/images/%s" % (json.loads(listimagesdetailsresponse.content)["images"][0]["id"])
+ url = "http://0.0.0.0:18774/v2.1/id_bla/images/%s" % (
+ json.loads(listimagesdetailsresponse.content)["images"][0]["id"])
listimagebyidresponse = requests.get(url, headers=headers)
self.assertEqual(listimagebyidresponse.status_code, 200)
- self.assertEqual(json.loads(listimagebyidresponse.content)["image"]["id"],json.loads(listimagesdetailsresponse.content)["images"][0]["id"])
+ self.assertEqual(json.loads(listimagebyidresponse.content)[
+ "image"]["id"], json.loads(listimagesdetailsresponse.content)["images"][0]["id"])
print(" ")
print('->>>>>>> test Nova List Image By Non-Existend Id ->>>>>>>>>>>>>>>')
@@ -216,7 +229,7 @@
self.assertEqual(listimagebynonexistingidresponse.status_code, 404)
print(" ")
- #find ubuntu id
+ # find ubuntu id
for image in json.loads(listimagesresponse.content)["images"]:
if image["name"] == "ubuntu:trusty":
ubuntu_image_id = image["id"]
@@ -224,16 +237,19 @@
print('->>>>>>> test Nova Create Server Instance ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18774/v2.1/id_bla/servers"
- data = '{"server": {"name": "X", "flavorRef": "%s", "imageRef":"%s"}}' % (json.loads(listflavorsresponse.content)["flavors"][0]["id"], ubuntu_image_id)
+ data = '{"server": {"name": "X", "flavorRef": "%s", "imageRef":"%s"}}' % (
+ json.loads(listflavorsresponse.content)["flavors"][0]["id"], ubuntu_image_id)
createserverinstance = requests.post(url, data=data, headers=headers)
self.assertEqual(createserverinstance.status_code, 200)
- self.assertEqual(json.loads(createserverinstance.content)["server"]["image"]["id"], ubuntu_image_id)
+ self.assertEqual(json.loads(createserverinstance.content)[
+ "server"]["image"]["id"], ubuntu_image_id)
print(" ")
print('->>>>>>> test Nova Create Server Instance With Already Existing Name ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18774/v2.1/id_bla/servers"
- data = '{"server": {"name": "X", "flavorRef": "%s", "imageRef":"%s"}}' % (json.loads(listflavorsresponse.content)["flavors"][0]["id"], ubuntu_image_id)
+ data = '{"server": {"name": "X", "flavorRef": "%s", "imageRef":"%s"}}' % (
+ json.loads(listflavorsresponse.content)["flavors"][0]["id"], ubuntu_image_id)
createserverinstance = requests.post(url, data=data, headers=headers)
self.assertEqual(createserverinstance.status_code, 409)
print(" ")
@@ -243,21 +259,25 @@
url = "http://0.0.0.0:18774/v2.1/id_bla/servers/detail"
listserverapisdetailedresponse = requests.get(url, headers=headers)
self.assertEqual(listserverapisdetailedresponse.status_code, 200)
- self.assertEqual(json.loads(listserverapisdetailedresponse.content)["servers"][0]["status"], "ACTIVE")
+ self.assertEqual(json.loads(listserverapisdetailedresponse.content)[
+ "servers"][0]["status"], "ACTIVE")
print(" ")
print('->>>>>>> test Nova Show Server Details ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:18774/v2.1/id_bla/servers/%s" % (json.loads(listserverapisdetailedresponse.content)["servers"][0]["id"])
+ url = "http://0.0.0.0:18774/v2.1/id_bla/servers/%s" % (
+ json.loads(listserverapisdetailedresponse.content)["servers"][0]["id"])
listserverdetailsresponse = requests.get(url, headers=headers)
self.assertEqual(listserverdetailsresponse.status_code, 200)
- self.assertEqual(json.loads(listserverdetailsresponse.content)["server"]["flavor"]["links"][0]["rel"], "bookmark")
+ self.assertEqual(json.loads(listserverdetailsresponse.content)[
+ "server"]["flavor"]["links"][0]["rel"], "bookmark")
print(" ")
print('->>>>>>> test Nova Show Non-Existing Server Details ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18774/v2.1/id_bla/servers/non_existing_server_id"
- listnonexistingserverdetailsresponse = requests.get(url, headers=headers)
+ listnonexistingserverdetailsresponse = requests.get(
+ url, headers=headers)
self.assertEqual(listnonexistingserverdetailsresponse.status_code, 404)
print(" ")
@@ -267,9 +287,11 @@
print(" ")
headers = {'Content-type': 'application/json'}
- test_heatapi_template_create_stack = open(os.path.join(os.path.dirname(__file__), "templates/test_heatapi_template_create_stack.yml")).read()
+ test_heatapi_template_create_stack = open(os.path.join(os.path.dirname(
+ __file__), "templates/test_heatapi_template_create_stack.yml")).read()
url = "http://0.0.0.0:18004/v1/tenantabc123/stacks"
- requests.post(url, data=json.dumps(yaml.load(test_heatapi_template_create_stack)), headers=headers)
+ requests.post(url, data=json.dumps(
+ yaml.load(test_heatapi_template_create_stack)), headers=headers)
# test_heatapi_keystone_get_token = open("test_heatapi_keystone_get_token.json").read()
print('->>>>>>> test Neutron List Versions ->>>>>>>>>>>>>>>')
@@ -277,7 +299,8 @@
url = "http://0.0.0.0:19696/"
listapiversionstackresponse = requests.get(url, headers=headers)
self.assertEqual(listapiversionstackresponse.status_code, 200)
- self.assertEqual(json.loads(listapiversionstackresponse.content)["versions"][0]["id"], "v2.0")
+ self.assertEqual(json.loads(listapiversionstackresponse.content)[
+ "versions"][0]["id"], "v2.0")
print(" ")
print('->>>>>>> test Neutron Show API v2.0 ->>>>>>>>>>>>>>>')
@@ -285,9 +308,12 @@
url = "http://0.0.0.0:19696/v2.0"
listapiversionv20response = requests.get(url, headers=headers)
self.assertEqual(listapiversionv20response.status_code, 200)
- self.assertEqual(json.loads(listapiversionv20response.content)["resources"][0]["name"], "subnet")
- self.assertEqual(json.loads(listapiversionv20response.content)["resources"][1]["name"], "network")
- self.assertEqual(json.loads(listapiversionv20response.content)["resources"][2]["name"], "ports")
+ self.assertEqual(json.loads(listapiversionv20response.content)[
+ "resources"][0]["name"], "subnet")
+ self.assertEqual(json.loads(listapiversionv20response.content)[
+ "resources"][1]["name"], "network")
+ self.assertEqual(json.loads(listapiversionv20response.content)[
+ "resources"][2]["name"], "ports")
print(" ")
print('->>>>>>> test Neutron List Networks ->>>>>>>>>>>>>>>')
@@ -295,50 +321,62 @@
url = "http://0.0.0.0:19696/v2.0/networks"
listnetworksesponse1 = requests.get(url, headers=headers)
self.assertEqual(listnetworksesponse1.status_code, 200)
- self.assertEqual(json.loads(listnetworksesponse1.content)["networks"][0]["status"], "ACTIVE")
- listNetworksId = json.loads(listnetworksesponse1.content)["networks"][0]["id"]
- listNetworksName = json.loads(listnetworksesponse1.content)["networks"][0]["name"]
- listNetworksId2 = json.loads(listnetworksesponse1.content)["networks"][1]["id"]
+ self.assertEqual(json.loads(listnetworksesponse1.content)[
+ "networks"][0]["status"], "ACTIVE")
+ listNetworksId = json.loads(listnetworksesponse1.content)[
+ "networks"][0]["id"]
+ listNetworksName = json.loads(listnetworksesponse1.content)[
+ "networks"][0]["name"]
+ listNetworksId2 = json.loads(listnetworksesponse1.content)[
+ "networks"][1]["id"]
print(" ")
print('->>>>>>> test Neutron List Non-Existing Networks ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/networks?name=non_existent_network_name"
- listnetworksesponse2 = requests.get(url,headers=headers)
+ listnetworksesponse2 = requests.get(url, headers=headers)
self.assertEqual(listnetworksesponse2.status_code, 404)
print(" ")
print('->>>>>>> test Neutron List Networks By Name ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/networks?name=" + listNetworksName #tcpdump-vnf:input:net:9df6a98f-9e11-4cb7-b3c0-InAdUnitTest
+ # tcpdump-vnf:input:net:9df6a98f-9e11-4cb7-b3c0-InAdUnitTest
+ url = "http://0.0.0.0:19696/v2.0/networks?name=" + listNetworksName
listnetworksesponse3 = requests.get(url, headers=headers)
self.assertEqual(listnetworksesponse3.status_code, 200)
- self.assertEqual(json.loads(listnetworksesponse3.content)["networks"][0]["name"], listNetworksName)
+ self.assertEqual(json.loads(listnetworksesponse3.content)[
+ "networks"][0]["name"], listNetworksName)
print(" ")
print('->>>>>>> test Neutron List Networks By Id ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/networks?id=" + listNetworksId # tcpdump-vnf:input:net:9df6a98f-9e11-4cb7-b3c0-InAdUnitTest
+ # tcpdump-vnf:input:net:9df6a98f-9e11-4cb7-b3c0-InAdUnitTest
+ url = "http://0.0.0.0:19696/v2.0/networks?id=" + listNetworksId
listnetworksesponse4 = requests.get(url, headers=headers)
self.assertEqual(listnetworksesponse4.status_code, 200)
- self.assertEqual(json.loads(listnetworksesponse4.content)["networks"][0]["id"], listNetworksId)
+ self.assertEqual(json.loads(listnetworksesponse4.content)[
+ "networks"][0]["id"], listNetworksId)
print(" ")
print('->>>>>>> test Neutron List Networks By Multiple Ids ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/networks?id=" + listNetworksId + "&id="+ listNetworksId2 # tcpdump-vnf:input:net:9df6a98f-9e11-4cb7-b3c0-InAdUnitTest
+ url = "http://0.0.0.0:19696/v2.0/networks?id=" + listNetworksId + "&id=" + \
+ listNetworksId2 # tcpdump-vnf:input:net:9df6a98f-9e11-4cb7-b3c0-InAdUnitTest
listnetworksesponse5 = requests.get(url, headers=headers)
self.assertEqual(listnetworksesponse5.status_code, 200)
- self.assertEqual(json.loads(listnetworksesponse5.content)["networks"][0]["id"], listNetworksId)
- self.assertEqual(json.loads(listnetworksesponse5.content)["networks"][1]["id"], listNetworksId2)
+ self.assertEqual(json.loads(listnetworksesponse5.content)[
+ "networks"][0]["id"], listNetworksId)
+ self.assertEqual(json.loads(listnetworksesponse5.content)[
+ "networks"][1]["id"], listNetworksId2)
print(" ")
print('->>>>>>> test Neutron Show Network ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/networks/"+listNetworksId
+ url = "http://0.0.0.0:19696/v2.0/networks/" + listNetworksId
shownetworksesponse = requests.get(url, headers=headers)
self.assertEqual(shownetworksesponse.status_code, 200)
- self.assertEqual(json.loads(shownetworksesponse.content)["network"]["status"], "ACTIVE")
+ self.assertEqual(json.loads(shownetworksesponse.content)[
+ "network"]["status"], "ACTIVE")
print(" ")
print('->>>>>>> test Neutron Show Network Non-ExistendNetwork ->>>>>>>>>>>>>>>')
@@ -351,31 +389,39 @@
print('->>>>>>> test Neutron Create Network ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/networks"
- createnetworkresponse = requests.post(url, data='{"network": {"name": "sample_network","admin_state_up": true}}', headers=headers)
+ createnetworkresponse = requests.post(
+ url, data='{"network": {"name": "sample_network","admin_state_up": true}}', headers=headers)
self.assertEqual(createnetworkresponse.status_code, 201)
- self.assertEqual(json.loads(createnetworkresponse.content)["network"]["status"], "ACTIVE")
+ self.assertEqual(json.loads(createnetworkresponse.content)[
+ "network"]["status"], "ACTIVE")
print(" ")
print('->>>>>>> test Neutron Create Network With Existing Name ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/networks"
- createnetworkresponsefailure = requests.post(url,data='{"network": {"name": "sample_network","admin_state_up": true}}',headers=headers)
+ createnetworkresponsefailure = requests.post(
+ url, data='{"network": {"name": "sample_network","admin_state_up": true}}', headers=headers)
self.assertEqual(createnetworkresponsefailure.status_code, 400)
print(" ")
print('->>>>>>> test Neutron Update Network ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/networks/%s" % (json.loads(createnetworkresponse.content)["network"]["id"])
- updatenetworkresponse = requests.put(url, data='{"network": {"status": "ACTIVE", "admin_state_up":true, "tenant_id":"abcd123", "name": "sample_network_new_name", "shared":false}}' , headers=headers)
+ url = "http://0.0.0.0:19696/v2.0/networks/%s" % (
+ json.loads(createnetworkresponse.content)["network"]["id"])
+ updatenetworkresponse = requests.put(
+ url, data='{"network": {"status": "ACTIVE", "admin_state_up":true, "tenant_id":"abcd123", "name": "sample_network_new_name", "shared":false}}', headers=headers)
self.assertEqual(updatenetworkresponse.status_code, 200)
- self.assertEqual(json.loads(updatenetworkresponse.content)["network"]["name"], "sample_network_new_name")
- self.assertEqual(json.loads(updatenetworkresponse.content)["network"]["tenant_id"], "abcd123")
+ self.assertEqual(json.loads(updatenetworkresponse.content)[
+ "network"]["name"], "sample_network_new_name")
+ self.assertEqual(json.loads(updatenetworkresponse.content)[
+ "network"]["tenant_id"], "abcd123")
print(" ")
print('->>>>>>> test Neutron Update Non-Existing Network ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/networks/non-existing-name123"
- updatenetworkresponse = requests.put(url, data='{"network": {"name": "sample_network_new_name"}}', headers=headers)
+ updatenetworkresponse = requests.put(
+ url, data='{"network": {"name": "sample_network_new_name"}}', headers=headers)
self.assertEqual(updatenetworkresponse.status_code, 404)
print(" ")
@@ -383,19 +429,23 @@
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/subnets"
listsubnetsresponse = requests.get(url, headers=headers)
- listSubnetName = json.loads(listsubnetsresponse.content)["subnets"][0]["name"]
- listSubnetId = json.loads(listsubnetsresponse.content)["subnets"][0]["id"]
- listSubnetId2 = json.loads(listsubnetsresponse.content)["subnets"][1]["id"]
+ listSubnetName = json.loads(listsubnetsresponse.content)[
+ "subnets"][0]["name"]
+ listSubnetId = json.loads(listsubnetsresponse.content)[
+ "subnets"][0]["id"]
+ listSubnetId2 = json.loads(listsubnetsresponse.content)[
+ "subnets"][1]["id"]
self.assertEqual(listsubnetsresponse.status_code, 200)
self.assertNotIn('None', listSubnetName)
print(" ")
print('->>>>>>> test Neutron List Subnets By Name ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/subnets?name="+listSubnetName
+ url = "http://0.0.0.0:19696/v2.0/subnets?name=" + listSubnetName
listsubnetByNameresponse = requests.get(url, headers=headers)
self.assertEqual(listsubnetByNameresponse.status_code, 200)
- self.assertNotIn('None', json.loads(listsubnetByNameresponse.content)["subnets"][0]["name"])
+ self.assertNotIn('None', json.loads(
+ listsubnetByNameresponse.content)["subnets"][0]["name"])
print(" ")
print('->>>>>>> test Neutron List Subnets By Id ->>>>>>>>>>>>>>>')
@@ -403,25 +453,28 @@
url = "http://0.0.0.0:19696/v2.0/subnets?id=" + listSubnetId
listsubnetsbyidresponse = requests.get(url, headers=headers)
self.assertEqual(listsubnetsbyidresponse.status_code, 200)
- self.assertNotIn("None", json.loads(listsubnetsbyidresponse.content)["subnets"][0]["name"])
+ self.assertNotIn("None", json.loads(
+ listsubnetsbyidresponse.content)["subnets"][0]["name"])
print(" ")
print('->>>>>>> test Neutron List Subnets By Multiple Id ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/subnets?id=" + listSubnetId +"&id="+listSubnetId2
+ url = "http://0.0.0.0:19696/v2.0/subnets?id=" + \
+ listSubnetId + "&id=" + listSubnetId2
listsubnetsbymultipleidsresponse = requests.get(url, headers=headers)
self.assertEqual(listsubnetsbymultipleidsresponse.status_code, 200)
- self.assertNotIn("None", json.loads(listsubnetsbymultipleidsresponse.content)["subnets"][0]["name"])
+ self.assertNotIn("None", json.loads(
+ listsubnetsbymultipleidsresponse.content)["subnets"][0]["name"])
print(" ")
-
-
print('->>>>>>> test Neutron Show Subnet->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/subnets/%s" % (json.loads(listsubnetsresponse.content)["subnets"][0]["id"])
+ url = "http://0.0.0.0:19696/v2.0/subnets/%s" % (
+ json.loads(listsubnetsresponse.content)["subnets"][0]["id"])
showsubnetsresponse = requests.get(url, headers=headers)
self.assertEqual(showsubnetsresponse.status_code, 200)
- self.assertNotIn("None", json.loads(showsubnetsresponse.content)["subnet"]["name"])
+ self.assertNotIn("None", json.loads(
+ showsubnetsresponse.content)["subnet"]["name"])
print(" ")
print('->>>>>>> test Neutron Show Non-Existing Subnet->>>>>>>>>>>>>>>')
@@ -431,38 +484,46 @@
self.assertEqual(showsubnetsresponse.status_code, 404)
print(" ")
-
print('->>>>>>> test Neutron Create Subnet ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/subnets"
- createsubnetdata = '{"subnet": {"name": "new_subnet", "network_id": "%s","ip_version": 4,"cidr": "10.0.0.1/24"} }' % (json.loads(createnetworkresponse.content)["network"]["id"])
- createsubnetresponse = requests.post(url, data=createsubnetdata, headers=headers)
+ createsubnetdata = '{"subnet": {"name": "new_subnet", "network_id": "%s","ip_version": 4,"cidr": "10.0.0.1/24"} }' % (
+ json.loads(createnetworkresponse.content)["network"]["id"])
+ createsubnetresponse = requests.post(
+ url, data=createsubnetdata, headers=headers)
self.assertEqual(createsubnetresponse.status_code, 201)
- self.assertEqual(json.loads(createsubnetresponse.content)["subnet"]["name"], "new_subnet")
+ self.assertEqual(json.loads(createsubnetresponse.content)[
+ "subnet"]["name"], "new_subnet")
print(" ")
print('->>>>>>> test Neutron Create Second Subnet ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/subnets"
- createsubnetdata = '{"subnet": {"name": "new_subnet", "network_id": "%s","ip_version": 4,"cidr": "10.0.0.1/24"} }' % (json.loads(createnetworkresponse.content)["network"]["id"])
- createsubnetfailureresponse = requests.post(url, data=createsubnetdata, headers=headers)
+ createsubnetdata = '{"subnet": {"name": "new_subnet", "network_id": "%s","ip_version": 4,"cidr": "10.0.0.1/24"} }' % (
+ json.loads(createnetworkresponse.content)["network"]["id"])
+ createsubnetfailureresponse = requests.post(
+ url, data=createsubnetdata, headers=headers)
self.assertEqual(createsubnetfailureresponse.status_code, 409)
print(" ")
print('->>>>>>> test Neutron Update Subnet ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/subnets/%s" % (json.loads(createsubnetresponse.content)["subnet"]["id"])
+ url = "http://0.0.0.0:19696/v2.0/subnets/%s" % (
+ json.loads(createsubnetresponse.content)["subnet"]["id"])
updatesubnetdata = '{"subnet": {"name": "new_subnet_new_name", "network_id":"some_id", "tenant_id":"new_tenant_id", "allocation_pools":"change_me", "gateway_ip":"192.168.1.120", "ip_version":4, "cidr":"10.0.0.1/24", "id":"some_new_id", "enable_dhcp":true} }'
- updatesubnetresponse = requests.put(url, data=updatesubnetdata, headers=headers)
+ updatesubnetresponse = requests.put(
+ url, data=updatesubnetdata, headers=headers)
self.assertEqual(updatesubnetresponse.status_code, 200)
- self.assertEqual(json.loads(updatesubnetresponse.content)["subnet"]["name"], "new_subnet_new_name")
+ self.assertEqual(json.loads(updatesubnetresponse.content)[
+ "subnet"]["name"], "new_subnet_new_name")
print(" ")
print('->>>>>>> test Neutron Update Non-Existing Subnet ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/subnets/non-existing-subnet-12345"
updatenonexistingsubnetdata = '{"subnet": {"name": "new_subnet_new_name"} }'
- updatenonexistingsubnetresponse = requests.put(url, data=updatenonexistingsubnetdata, headers=headers)
+ updatenonexistingsubnetresponse = requests.put(
+ url, data=updatenonexistingsubnetdata, headers=headers)
self.assertEqual(updatenonexistingsubnetresponse.status_code, 404)
print(" ")
@@ -471,8 +532,10 @@
url = "http://0.0.0.0:19696/v2.0/ports"
listportsesponse = requests.get(url, headers=headers)
self.assertEqual(listportsesponse.status_code, 200)
- self.assertEqual(json.loads(listportsesponse.content)["ports"][0]["status"], "ACTIVE")
- listPortsName = json.loads(listportsesponse.content)["ports"][0]["name"]
+ self.assertEqual(json.loads(listportsesponse.content)
+ ["ports"][0]["status"], "ACTIVE")
+ listPortsName = json.loads(listportsesponse.content)[
+ "ports"][0]["name"]
listPortsId1 = json.loads(listportsesponse.content)["ports"][0]["id"]
listPortsId2 = json.loads(listportsesponse.content)["ports"][1]["id"]
print(" ")
@@ -482,7 +545,8 @@
url = "http://0.0.0.0:19696/v2.0/ports?name=" + listPortsName
listportsbynameesponse = requests.get(url, headers=headers)
self.assertEqual(listportsbynameesponse.status_code, 200)
- self.assertEqual(json.loads(listportsbynameesponse.content)["ports"][0]["name"], listPortsName)
+ self.assertEqual(json.loads(listportsbynameesponse.content)[
+ "ports"][0]["name"], listPortsName)
print(" ")
print('->>>>>>> test Neutron List Ports By Id ->>>>>>>>>>>>>>>')
@@ -490,15 +554,18 @@
url = "http://0.0.0.0:19696/v2.0/ports?id=" + listPortsId1
listportsbyidesponse = requests.get(url, headers=headers)
self.assertEqual(listportsbyidesponse.status_code, 200)
- self.assertEqual(json.loads(listportsbyidesponse.content)["ports"][0]["id"], listPortsId1)
+ self.assertEqual(json.loads(listportsbyidesponse.content)[
+ "ports"][0]["id"], listPortsId1)
print(" ")
print('->>>>>>> test Neutron List Ports By Multiple Ids ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/ports?id=" + listPortsId1 +"&id="+listPortsId2
+ url = "http://0.0.0.0:19696/v2.0/ports?id=" + \
+ listPortsId1 + "&id=" + listPortsId2
listportsbymultipleidsesponse = requests.get(url, headers=headers)
self.assertEqual(listportsbymultipleidsesponse.status_code, 200)
- self.assertEqual(json.loads(listportsbymultipleidsesponse.content)["ports"][0]["id"], listPortsId1)
+ self.assertEqual(json.loads(listportsbymultipleidsesponse.content)[
+ "ports"][0]["id"], listPortsId1)
print(" ")
print('->>>>>>> test Neutron List Non-Existing Ports ->>>>>>>>>>>>>>>')
@@ -510,10 +577,12 @@
print('->>>>>>> test Neutron Show Port ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:19696/v2.0/ports/%s" % (json.loads(listportsesponse.content)["ports"][0]["id"])
+ url = "http://0.0.0.0:19696/v2.0/ports/%s" % (
+ json.loads(listportsesponse.content)["ports"][0]["id"])
showportresponse = requests.get(url, headers=headers)
self.assertEqual(showportresponse.status_code, 200)
- self.assertEqual(json.loads(showportresponse.content)["port"]["status"], "ACTIVE")
+ self.assertEqual(json.loads(showportresponse.content)
+ ["port"]["status"], "ACTIVE")
print(" ")
print('->>>>>>> test Neutron Show Non-Existing Port ->>>>>>>>>>>>>>>')
@@ -527,63 +596,76 @@
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/ports"
createnonexistingportdata = '{"port": {"name": "new_port", "network_id": "non-existing-id"} }'
- createnonexistingnetworkportresponse = requests.post(url, data=createnonexistingportdata, headers=headers)
+ createnonexistingnetworkportresponse = requests.post(
+ url, data=createnonexistingportdata, headers=headers)
self.assertEqual(createnonexistingnetworkportresponse.status_code, 404)
print(" ")
print('->>>>>>> test Neutron Create Port ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/ports"
- createportdata = '{"port": {"name": "new_port", "network_id": "%s", "admin_state_up":true, "device_id":"device_id123", "device_owner":"device_owner123", "fixed_ips":"change_me","id":"new_id1234", "mac_address":"12:34:56:78:90", "status":"change_me", "tenant_id":"tenant_id123"} }' % (json.loads(createnetworkresponse.content)["network"]["id"])
- createportresponse = requests.post(url, data=createportdata, headers=headers)
+ createportdata = '{"port": {"name": "new_port", "network_id": "%s", "admin_state_up":true, "device_id":"device_id123", "device_owner":"device_owner123", "fixed_ips":"change_me","id":"new_id1234", "mac_address":"12:34:56:78:90", "status":"change_me", "tenant_id":"tenant_id123"} }' % (json.loads(createnetworkresponse.content)[
+ "network"]["id"])
+ createportresponse = requests.post(
+ url, data=createportdata, headers=headers)
self.assertEqual(createportresponse.status_code, 201)
- print (createportresponse.content)
- self.assertEqual(json.loads(createportresponse.content)["port"]["name"], "new_port")
+ print(createportresponse.content)
+ self.assertEqual(json.loads(createportresponse.content)[
+ "port"]["name"], "new_port")
print(" ")
print('->>>>>>> test Neutron Create Port With Existing Name ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/ports"
- createportwithexistingnamedata = '{"port": {"name": "new_port", "network_id": "%s"} }' % (json.loads(createnetworkresponse.content)["network"]["id"])
- createportwithexistingnameresponse = requests.post(url, data=createportwithexistingnamedata, headers=headers)
+ createportwithexistingnamedata = '{"port": {"name": "new_port", "network_id": "%s"} }' % (
+ json.loads(createnetworkresponse.content)["network"]["id"])
+ createportwithexistingnameresponse = requests.post(
+ url, data=createportwithexistingnamedata, headers=headers)
self.assertEqual(createportwithexistingnameresponse.status_code, 500)
print(" ")
print('->>>>>>> test Neutron Create Port Without Name ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/ports"
- createportdatawithoutname = '{"port": {"network_id": "%s"} }' % (json.loads(createnetworkresponse.content)["network"]["id"])
- createportwithoutnameresponse = requests.post(url, data=createportdatawithoutname, headers=headers)
+ createportdatawithoutname = '{"port": {"network_id": "%s"} }' % (
+ json.loads(createnetworkresponse.content)["network"]["id"])
+ createportwithoutnameresponse = requests.post(
+ url, data=createportdatawithoutname, headers=headers)
self.assertEqual(createportwithoutnameresponse.status_code, 201)
- self.assertIn("port:cp", json.loads(createportwithoutnameresponse.content)["port"]["name"])
+ self.assertIn("port:cp", json.loads(
+ createportwithoutnameresponse.content)["port"]["name"])
print(" ")
print('->>>>>>> test Neutron Update Port ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print(json.loads(createportresponse.content)["port"]["name"])
- url = "http://0.0.0.0:19696/v2.0/ports/%s" % (json.loads(createportresponse.content)["port"]["name"])
+ url = "http://0.0.0.0:19696/v2.0/ports/%s" % (
+ json.loads(createportresponse.content)["port"]["name"])
updateportdata = '{"port": {"name": "new_port_new_name", "admin_state_up":true, "device_id":"device_id123", "device_owner":"device_owner123", "fixed_ips":"change_me","mac_address":"12:34:56:78:90", "status":"change_me", "tenant_id":"tenant_id123", "network_id":"network_id123"} }'
- updateportresponse = requests.put(url, data=updateportdata, headers=headers)
+ updateportresponse = requests.put(
+ url, data=updateportdata, headers=headers)
self.assertEqual(updateportresponse.status_code, 200)
- self.assertEqual(json.loads(updateportresponse.content)["port"]["name"], "new_port_new_name")
+ self.assertEqual(json.loads(updateportresponse.content)[
+ "port"]["name"], "new_port_new_name")
print(" ")
print('->>>>>>> test Neutron Update Non-Existing Port ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/ports/non-existing-port-ip"
updatenonexistingportdata = '{"port": {"name": "new_port_new_name"} }'
- updatenonexistingportresponse = requests.put(url, data=updatenonexistingportdata, headers=headers)
+ updatenonexistingportresponse = requests.put(
+ url, data=updatenonexistingportdata, headers=headers)
self.assertEqual(updatenonexistingportresponse.status_code, 404)
print(" ")
print('->>>>>>> test Neutron Delete Port ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- righturl = "http://0.0.0.0:19696/v2.0/ports/%s" % (json.loads(createportresponse.content)["port"]["id"])
+ righturl = "http://0.0.0.0:19696/v2.0/ports/%s" % (
+ json.loads(createportresponse.content)["port"]["id"])
deleterightportresponse = requests.delete(righturl, headers=headers)
self.assertEqual(deleterightportresponse.status_code, 204)
print(" ")
-
print('->>>>>>> test Neutron Delete Non-Existing Port ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
wrongurl = "http://0.0.0.0:19696/v2.0/ports/unknownid"
@@ -594,7 +676,8 @@
print('->>>>>>> test Neutron Delete Subnet ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
wrongurl = "http://0.0.0.0:19696/v2.0/subnets/unknownid"
- righturl = "http://0.0.0.0:19696/v2.0/subnets/%s" % (json.loads(updatesubnetresponse.content)["subnet"]["id"])
+ righturl = "http://0.0.0.0:19696/v2.0/subnets/%s" % (
+ json.loads(updatesubnetresponse.content)["subnet"]["id"])
deletewrongsubnetresponse = requests.delete(wrongurl, headers=headers)
deleterightsubnetresponse = requests.delete(righturl, headers=headers)
self.assertEqual(deletewrongsubnetresponse.status_code, 404)
@@ -603,7 +686,8 @@
print('->>>>>>> test Neutron Delete Network ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- righturl = "http://0.0.0.0:19696/v2.0/networks/%s" % (json.loads(createnetworkresponse.content)["network"]["id"])
+ righturl = "http://0.0.0.0:19696/v2.0/networks/%s" % (
+ json.loads(createnetworkresponse.content)["network"]["id"])
deleterightnetworkresponse = requests.delete(righturl, headers=headers)
self.assertEqual(deleterightnetworkresponse.status_code, 204)
print(" ")
@@ -621,14 +705,16 @@
print(" ")
headers = {'Content-type': 'application/json'}
- test_heatapi_keystone_get_token = open(os.path.join(os.path.dirname(__file__), "templates/test_heatapi_keystone_get_token.yml")).read()
+ test_heatapi_keystone_get_token = open(os.path.join(os.path.dirname(
+ __file__), "templates/test_heatapi_keystone_get_token.yml")).read()
print('->>>>>>> test Keystone List Versions ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:15000/"
listapiversionstackresponse = requests.get(url, headers=headers)
self.assertEqual(listapiversionstackresponse.status_code, 200)
- self.assertEqual(json.loads(listapiversionstackresponse.content)["versions"]["values"][0]["id"], "v2.0")
+ self.assertEqual(json.loads(listapiversionstackresponse.content)[
+ "versions"]["values"][0]["id"], "v2.0")
print(" ")
print('->>>>>>> test Keystone Show ApiV2 ->>>>>>>>>>>>>>>')
@@ -636,15 +722,18 @@
url = "http://0.0.0.0:15000/v2.0"
showapiversionstackresponse = requests.get(url, headers=headers)
self.assertEqual(showapiversionstackresponse.status_code, 200)
- self.assertEqual(json.loads(showapiversionstackresponse.content)["version"]["id"], "v2.0")
+ self.assertEqual(json.loads(showapiversionstackresponse.content)[
+ "version"]["id"], "v2.0")
print(" ")
print('->>>>>>> test Keystone Get Token ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:15000/v2.0/tokens"
- gettokenstackresponse = requests.post(url, data=json.dumps(yaml.load(test_heatapi_keystone_get_token)), headers=headers)
+ gettokenstackresponse = requests.post(url, data=json.dumps(
+ yaml.load(test_heatapi_keystone_get_token)), headers=headers)
self.assertEqual(gettokenstackresponse.status_code, 200)
- self.assertEqual(json.loads(gettokenstackresponse.content)["access"]["user"]["name"], "tenantName")
+ self.assertEqual(json.loads(gettokenstackresponse.content)[
+ "access"]["user"]["name"], "tenantName")
print(" ")
def testHeatDummy(self):
@@ -653,78 +742,91 @@
print(" ")
headers = {'Content-type': 'application/json'}
- test_heatapi_template_create_stack = open(os.path.join(os.path.dirname(__file__), "templates/test_heatapi_template_create_stack.yml")).read()
- test_heatapi_template_update_stack = open(os.path.join(os.path.dirname(__file__), "templates/test_heatapi_template_update_stack.yml")).read()
+ test_heatapi_template_create_stack = open(os.path.join(os.path.dirname(
+ __file__), "templates/test_heatapi_template_create_stack.yml")).read()
+ test_heatapi_template_update_stack = open(os.path.join(os.path.dirname(
+ __file__), "templates/test_heatapi_template_update_stack.yml")).read()
print('->>>>>>> test Heat List API Versions Stack ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18004/"
listapiversionstackresponse = requests.get(url, headers=headers)
self.assertEqual(listapiversionstackresponse.status_code, 200)
- self.assertEqual(json.loads(listapiversionstackresponse.content)["versions"][0]["id"], "v1.0")
+ self.assertEqual(json.loads(listapiversionstackresponse.content)[
+ "versions"][0]["id"], "v1.0")
print(" ")
print('->>>>>>> test Create Stack ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18004/v1/tenantabc123/stacks"
- createstackresponse = requests.post(url, data=json.dumps(yaml.load(test_heatapi_template_create_stack)), headers=headers)
+ createstackresponse = requests.post(url, data=json.dumps(
+ yaml.load(test_heatapi_template_create_stack)), headers=headers)
self.assertEqual(createstackresponse.status_code, 201)
- self.assertNotEqual(json.loads(createstackresponse.content)["stack"]["id"], "")
+ self.assertNotEqual(json.loads(
+ createstackresponse.content)["stack"]["id"], "")
print(" ")
print('->>>>>>> test Create Stack With Existing Name ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18004/v1/tenantabc123/stacks"
- createstackwithexistingnameresponse = requests.post(url, data='{"stack_name" : "s1"}', headers=headers)
+ createstackwithexistingnameresponse = requests.post(
+ url, data='{"stack_name" : "s1"}', headers=headers)
self.assertEqual(createstackwithexistingnameresponse.status_code, 409)
print(" ")
print('->>>>>>> test Create Stack With Unsupported Version ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18004/v1/tenantabc123/stacks"
- createstackwitheunsupportedversionresponse = requests.post(url, data='{"stack_name" : "stackname123", "template" : {"heat_template_version": "2015-04-29"}}', headers=headers)
- self.assertEqual(createstackwitheunsupportedversionresponse.status_code, 400)
+ createstackwitheunsupportedversionresponse = requests.post(
+ url, data='{"stack_name" : "stackname123", "template" : {"heat_template_version": "2015-04-29"}}', headers=headers)
+ self.assertEqual(
+ createstackwitheunsupportedversionresponse.status_code, 400)
print(" ")
-
print('->>>>>>> test List Stack ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18004/v1/tenantabc123/stacks"
liststackresponse = requests.get(url, headers=headers)
self.assertEqual(liststackresponse.status_code, 200)
- self.assertEqual(json.loads(liststackresponse.content)["stacks"][0]["stack_status"], "CREATE_COMPLETE")
+ self.assertEqual(json.loads(liststackresponse.content)[
+ "stacks"][0]["stack_status"], "CREATE_COMPLETE")
print(" ")
-
print('->>>>>>> test Show Stack ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:18004/v1/tenantabc123showStack/stacks/%s"% json.loads(createstackresponse.content)['stack']['id']
+ url = "http://0.0.0.0:18004/v1/tenantabc123showStack/stacks/%s" % json.loads(
+ createstackresponse.content)['stack']['id']
liststackdetailsresponse = requests.get(url, headers=headers)
self.assertEqual(liststackdetailsresponse.status_code, 200)
- self.assertEqual(json.loads(liststackdetailsresponse.content)["stack"]["stack_status"], "CREATE_COMPLETE")
+ self.assertEqual(json.loads(liststackdetailsresponse.content)[
+ "stack"]["stack_status"], "CREATE_COMPLETE")
print(" ")
print('->>>>>>> test Show Non-Exisitng Stack ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18004/v1/tenantabc123showStack/stacks/non_exisitng_id123"
- listnonexistingstackdetailsresponse = requests.get(url, headers=headers)
+ listnonexistingstackdetailsresponse = requests.get(
+ url, headers=headers)
self.assertEqual(listnonexistingstackdetailsresponse.status_code, 404)
print(" ")
print('->>>>>>> test Update Stack ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- url = "http://0.0.0.0:18004/v1/tenantabc123updateStack/stacks/%s"% json.loads(createstackresponse.content)['stack']['id']
+ url = "http://0.0.0.0:18004/v1/tenantabc123updateStack/stacks/%s" % json.loads(
+ createstackresponse.content)['stack']['id']
updatestackresponse = requests.put(url, data=json.dumps(yaml.load(test_heatapi_template_update_stack)),
- headers=headers)
+ headers=headers)
self.assertEqual(updatestackresponse.status_code, 202)
liststackdetailsresponse = requests.get(url, headers=headers)
- self.assertEqual(json.loads(liststackdetailsresponse.content)["stack"]["stack_status"], "UPDATE_COMPLETE")
+ self.assertEqual(json.loads(liststackdetailsresponse.content)[
+ "stack"]["stack_status"], "UPDATE_COMPLETE")
print(" ")
print('->>>>>>> test Update Non-Existing Stack ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:18004/v1/tenantabc123updateStack/stacks/non_existing_id_1234"
- updatenonexistingstackresponse = requests.put(url, data={"non": "sense"}, headers=headers)
+ updatenonexistingstackresponse = requests.put(
+ url, data={"non": "sense"}, headers=headers)
self.assertEqual(updatenonexistingstackresponse.status_code, 404)
print(" ")
@@ -753,19 +855,24 @@
print('->>>>>>> Create ports p1 - p4 ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
# Get network id
- network_resp = requests.get("http://0.0.0.0:19696/v2.0/networks?name=default", headers=headers)
+ network_resp = requests.get(
+ "http://0.0.0.0:19696/v2.0/networks?name=default", headers=headers)
self.assertEqual(network_resp.status_code, 200)
network_id = json.loads(network_resp.content)["networks"][0]["id"]
url = "http://0.0.0.0:19696/v2.0/ports"
port_request = '{"port": {"name": "%s", "network_id": "%s"}}'
- p1_resp = requests.post(url, data=port_request % ("p1", network_id), headers=headers)
+ p1_resp = requests.post(url, data=port_request %
+ ("p1", network_id), headers=headers)
self.assertEqual(p1_resp.status_code, 201)
- p2_resp = requests.post(url, data=port_request % ("p2", network_id), headers=headers)
+ p2_resp = requests.post(url, data=port_request %
+ ("p2", network_id), headers=headers)
self.assertEqual(p2_resp.status_code, 201)
- p3_resp = requests.post(url, data=port_request % ("p3", network_id), headers=headers)
+ p3_resp = requests.post(url, data=port_request %
+ ("p3", network_id), headers=headers)
self.assertEqual(p3_resp.status_code, 201)
- p4_resp = requests.post(url, data=port_request % ("p4", network_id), headers=headers)
+ p4_resp = requests.post(url, data=port_request %
+ ("p4", network_id), headers=headers)
self.assertEqual(p4_resp.status_code, 201)
p1_id = json.loads(p1_resp.content)["port"]["id"]
@@ -776,11 +883,14 @@
print('->>>>>>> test Neutron SFC Port Pair Create ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_pairs"
- pp1_resp = requests.post(url, data='{"port_pair": {"name": "pp1", "ingress": "%s", "egress": "%s"}}' % (p1_id, p2_id), headers=headers)
+ pp1_resp = requests.post(url, data='{"port_pair": {"name": "pp1", "ingress": "%s", "egress": "%s"}}' % (
+ p1_id, p2_id), headers=headers)
self.assertEqual(pp1_resp.status_code, 201)
- pp2_resp = requests.post(url, data='{"port_pair": {"name": "pp2", "ingress": "%s", "egress": "%s"}}' % (p3_id, p4_id), headers=headers)
+ pp2_resp = requests.post(url, data='{"port_pair": {"name": "pp2", "ingress": "%s", "egress": "%s"}}' % (
+ p3_id, p4_id), headers=headers)
self.assertEqual(pp2_resp.status_code, 201)
- pp3_resp = requests.post(url, data='{"port_pair": {"name": "pp3", "ingress": "%s", "egress": "%s"}}' % (p3_id, p4_id), headers=headers)
+ pp3_resp = requests.post(url, data='{"port_pair": {"name": "pp3", "ingress": "%s", "egress": "%s"}}' % (
+ p3_id, p4_id), headers=headers)
self.assertEqual(pp3_resp.status_code, 201)
pp1_id = json.loads(pp1_resp.content)["port_pair"]["id"]
@@ -790,9 +900,11 @@
print('->>>>>>> test Neutron SFC Port Pair Update ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_pairs/%s" % pp3_id
- pp3_update_resp = requests.put(url, data='{"port_pair": {"description": "port_pair_update"}}', headers=headers)
+ pp3_update_resp = requests.put(
+ url, data='{"port_pair": {"description": "port_pair_update"}}', headers=headers)
self.assertEqual(pp3_update_resp.status_code, 200)
- self.assertEqual(json.loads(pp3_update_resp.content)["port_pair"]["description"], "port_pair_update")
+ self.assertEqual(json.loads(pp3_update_resp.content)[
+ "port_pair"]["description"], "port_pair_update")
print('->>>>>>> test Neutron SFC Port Pair Delete ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
@@ -805,24 +917,29 @@
url = "http://0.0.0.0:19696/v2.0/sfc/port_pairs"
pp_list_resp = requests.get(url, headers=headers)
self.assertEqual(pp_list_resp.status_code, 200)
- self.assertEqual(len(json.loads(pp_list_resp.content)["port_pairs"]), 2) # only pp1 and pp2 should be left
+ # only pp1 and pp2 should be left
+ self.assertEqual(
+ len(json.loads(pp_list_resp.content)["port_pairs"]), 2)
print('->>>>>>> test Neutron SFC Port Pair Show ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_pairs/%s" % pp2_id
pp2_show_resp = requests.get(url, headers=headers)
self.assertEqual(pp2_show_resp.status_code, 200)
- self.assertEqual(json.loads(pp2_show_resp.content)["port_pair"]["name"], "pp2")
-
+ self.assertEqual(json.loads(pp2_show_resp.content)
+ ["port_pair"]["name"], "pp2")
print('->>>>>>> test Neutron SFC Port Pair Group Create ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_pair_groups"
- ppg1_resp = requests.post(url, data='{"port_pair_group": {"name": "ppg1", "port_pairs": ["%s"]}}' % (pp1_id), headers=headers)
+ ppg1_resp = requests.post(
+ url, data='{"port_pair_group": {"name": "ppg1", "port_pairs": ["%s"]}}' % (pp1_id), headers=headers)
self.assertEqual(ppg1_resp.status_code, 201)
- ppg2_resp = requests.post(url, data='{"port_pair_group": {"name": "ppg2", "port_pairs": ["%s"]}}' % (pp2_id), headers=headers)
+ ppg2_resp = requests.post(
+ url, data='{"port_pair_group": {"name": "ppg2", "port_pairs": ["%s"]}}' % (pp2_id), headers=headers)
self.assertEqual(ppg2_resp.status_code, 201)
- ppg3_resp = requests.post(url, data='{"port_pair_group": {"name": "ppg3", "port_pairs": ["%s"]}}' % (pp2_id), headers=headers)
+ ppg3_resp = requests.post(
+ url, data='{"port_pair_group": {"name": "ppg3", "port_pairs": ["%s"]}}' % (pp2_id), headers=headers)
self.assertEqual(ppg3_resp.status_code, 201)
ppg1_id = json.loads(ppg1_resp.content)["port_pair_group"]["id"]
@@ -832,9 +949,11 @@
print('->>>>>>> test Neutron SFC Port Pair Group Update ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_pair_groups/%s" % ppg3_id
- ppg3_update_resp = requests.put(url, data='{"port_pair_group": {"description": "port_pair_group_update"}}', headers=headers)
+ ppg3_update_resp = requests.put(
+ url, data='{"port_pair_group": {"description": "port_pair_group_update"}}', headers=headers)
self.assertEqual(ppg3_update_resp.status_code, 200)
- self.assertEqual(json.loads(ppg3_update_resp.content)["port_pair_group"]["description"], "port_pair_group_update")
+ self.assertEqual(json.loads(ppg3_update_resp.content)[
+ "port_pair_group"]["description"], "port_pair_group_update")
print('->>>>>>> test Neutron SFC Port Pair Group Delete ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
@@ -847,21 +966,26 @@
url = "http://0.0.0.0:19696/v2.0/sfc/port_pair_groups"
ppg_list_resp = requests.get(url, headers=headers)
self.assertEqual(ppg_list_resp.status_code, 200)
- self.assertEqual(len(json.loads(ppg_list_resp.content)["port_pair_groups"]), 2) # only ppg1 and ppg2 should be left
+ # only ppg1 and ppg2 should be left
+ self.assertEqual(
+ len(json.loads(ppg_list_resp.content)["port_pair_groups"]), 2)
print('->>>>>>> test Neutron SFC Port Pair Group Show ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_pair_groups/%s" % ppg2_id
ppg2_show_resp = requests.get(url, headers=headers)
self.assertEqual(ppg2_show_resp.status_code, 200)
- self.assertEqual(json.loads(ppg2_show_resp.content)["port_pair_group"]["name"], "ppg2")
+ self.assertEqual(json.loads(ppg2_show_resp.content)[
+ "port_pair_group"]["name"], "ppg2")
print('->>>>>>> test Neutron SFC Flow Classifier Create ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/flow_classifiers"
- fc1_resp = requests.post(url, data='{"flow_classifier": {"name": "fc1", "source_port_range_min": 22, "source_port_range_max": 4000}}', headers=headers)
+ fc1_resp = requests.post(
+ url, data='{"flow_classifier": {"name": "fc1", "source_port_range_min": 22, "source_port_range_max": 4000}}', headers=headers)
self.assertEqual(fc1_resp.status_code, 201)
- fc2_resp = requests.post(url, data='{"flow_classifier": {"name": "fc2", "source_port_range_min": 22, "source_port_range_max": 4000}}', headers=headers)
+ fc2_resp = requests.post(
+ url, data='{"flow_classifier": {"name": "fc2", "source_port_range_min": 22, "source_port_range_max": 4000}}', headers=headers)
self.assertEqual(fc2_resp.status_code, 201)
fc1_id = json.loads(fc1_resp.content)["flow_classifier"]["id"]
@@ -870,9 +994,11 @@
print('->>>>>>> test Neutron SFC Flow Classifier Update ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/flow_classifiers/%s" % fc2_id
- fc2_update_resp = requests.put(url, data='{"flow_classifier": {"description": "flow_classifier_update"}}', headers=headers)
+ fc2_update_resp = requests.put(
+ url, data='{"flow_classifier": {"description": "flow_classifier_update"}}', headers=headers)
self.assertEqual(fc2_update_resp.status_code, 200)
- self.assertEqual(json.loads(fc2_update_resp.content)["flow_classifier"]["description"], "flow_classifier_update")
+ self.assertEqual(json.loads(fc2_update_resp.content)[
+ "flow_classifier"]["description"], "flow_classifier_update")
print('->>>>>>> test Neutron SFC Flow Classifier Delete ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
@@ -885,22 +1011,25 @@
url = "http://0.0.0.0:19696/v2.0/sfc/flow_classifiers"
fc_list_resp = requests.get(url, headers=headers)
self.assertEqual(fc_list_resp.status_code, 200)
- self.assertEqual(len(json.loads(fc_list_resp.content)["flow_classifiers"]), 1) # only fc1
+ self.assertEqual(len(json.loads(fc_list_resp.content)
+ ["flow_classifiers"]), 1) # only fc1
print('->>>>>>> test Neutron SFC Flow Classifier Show ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/flow_classifiers/%s" % fc1_id
fc1_show_resp = requests.get(url, headers=headers)
self.assertEqual(fc1_show_resp.status_code, 200)
- self.assertEqual(json.loads(fc1_show_resp.content)["flow_classifier"]["name"], "fc1")
-
+ self.assertEqual(json.loads(fc1_show_resp.content)[
+ "flow_classifier"]["name"], "fc1")
print('->>>>>>> test Neutron SFC Port Chain Create ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_chains"
- pc1_resp = requests.post(url, data='{"port_chain": {"name": "pc1", "port_pair_groups": ["%s"], "flow_classifiers": ["%s"]}}' % (ppg1_id, fc1_id), headers=headers)
+ pc1_resp = requests.post(url, data='{"port_chain": {"name": "pc1", "port_pair_groups": ["%s"], "flow_classifiers": ["%s"]}}' % (
+ ppg1_id, fc1_id), headers=headers)
self.assertEqual(pc1_resp.status_code, 201)
- pc2_resp = requests.post(url, data='{"port_chain": {"name": "pc2", "port_pair_groups": ["%s"], "flow_classifiers": ["%s"]}}' % (ppg1_id, fc1_id), headers=headers)
+ pc2_resp = requests.post(url, data='{"port_chain": {"name": "pc2", "port_pair_groups": ["%s"], "flow_classifiers": ["%s"]}}' % (
+ ppg1_id, fc1_id), headers=headers)
self.assertEqual(pc2_resp.status_code, 201)
pc1_id = json.loads(pc1_resp.content)["port_chain"]["id"]
@@ -909,9 +1038,11 @@
print('->>>>>>> test Neutron SFC Port Chain Update ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_chains/%s" % pc2_id
- pc2_update_resp = requests.put(url, data='{"port_chain": {"description": "port_chain_update"}}', headers=headers)
+ pc2_update_resp = requests.put(
+ url, data='{"port_chain": {"description": "port_chain_update"}}', headers=headers)
self.assertEqual(pc2_update_resp.status_code, 200)
- self.assertEqual(json.loads(pc2_update_resp.content)["port_chain"]["description"], "port_chain_update")
+ self.assertEqual(json.loads(pc2_update_resp.content)[
+ "port_chain"]["description"], "port_chain_update")
print('->>>>>>> test Neutron SFC Port Chain Delete ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
@@ -924,14 +1055,17 @@
url = "http://0.0.0.0:19696/v2.0/sfc/port_chains"
pc_list_resp = requests.get(url, headers=headers)
self.assertEqual(pc_list_resp.status_code, 200)
- self.assertEqual(len(json.loads(pc_list_resp.content)["port_chains"]), 1) # only pc1
+ self.assertEqual(len(json.loads(pc_list_resp.content)
+ ["port_chains"]), 1) # only pc1
print('->>>>>>> test Neutron SFC Port Chain Show ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
url = "http://0.0.0.0:19696/v2.0/sfc/port_chains/%s" % pc1_id
pc1_show_resp = requests.get(url, headers=headers)
self.assertEqual(pc1_show_resp.status_code, 200)
- self.assertEqual(json.loads(pc1_show_resp.content)["port_chain"]["name"], "pc1")
+ self.assertEqual(json.loads(pc1_show_resp.content)
+ ["port_chain"]["name"], "pc1")
+
if __name__ == '__main__':
unittest.main()
diff --git a/src/emuvim/test/unittests/test_resourcemodel.py b/src/emuvim/test/unittests/test_resourcemodel.py
index 4a21fee..c0cf0c4 100755
--- a/src/emuvim/test/unittests/test_resourcemodel.py
+++ b/src/emuvim/test/unittests/test_resourcemodel.py
@@ -1,31 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import time
import os
import unittest
@@ -34,7 +31,6 @@
from emuvim.dcemulator.resourcemodel.upb.simple import UpbSimpleCloudDcRM, UpbOverprovisioningCloudDcRM, UpbDummyRM
-
class testResourceModel(SimpleTestTopology):
"""
Test the general resource model API and functionality.
@@ -98,15 +94,15 @@
def __init__(self):
# take defaukt values from son-emu
self.resources = dict(
- cpu_period = -1,
- cpu_quota = -1,
- mem_limit = -1,
- memswap_limit = -1
+ cpu_period=-1,
+ cpu_quota=-1,
+ mem_limit=-1,
+ memswap_limit=-1
)
- #self.cpu_period = self.resources['cpu_period']
- #self.cpu_quota = self.resources['cpu_quota']
- #self.mem_limit = self.resources['mem_limit']
- #self.memswap_limit = self.resources['memswap_limit']
+ # self.cpu_period = self.resources['cpu_period']
+ # self.cpu_quota = self.resources['cpu_quota']
+ # self.mem_limit = self.resources['mem_limit']
+ # self.memswap_limit = self.resources['memswap_limit']
def updateCpuLimit(self, cpu_period, cpu_quota):
self.resources['cpu_period'] = cpu_period
@@ -121,8 +117,6 @@
return d
-
-
class testUpbSimpleCloudDcRM(SimpleTestTopology):
"""
Test the UpbSimpleCloudDc resource model.
@@ -139,35 +133,55 @@
E_MEM = 512
MAX_MU = 2048
# create dummy resource model environment
- reg = ResourceModelRegistrar(dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
+ reg = ResourceModelRegistrar(
+ dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
rm = UpbSimpleCloudDcRM(max_cu=MAX_CU, max_mu=MAX_MU)
reg.register("test_dc", rm)
c1 = createDummyContainerObject("c1", flavor="tiny")
rm.allocate(c1) # calculate allocation
- self.assertEqual(float(c1.resources['cpu_quota']) / c1.resources['cpu_period'], E_CPU / MAX_CU * 0.5) # validate compute result
- self.assertEqual(float(c1.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 32) # validate memory result
+ # validate compute result
+ self.assertEqual(float(
+ c1.resources['cpu_quota']) / c1.resources['cpu_period'], E_CPU / MAX_CU * 0.5)
+ # validate memory result
+ self.assertEqual(
+ float(c1.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 32)
c2 = createDummyContainerObject("c2", flavor="small")
rm.allocate(c2) # calculate allocation
- self.assertEqual(float(c2.resources['cpu_quota']) / c2.resources['cpu_period'], E_CPU / MAX_CU * 1) # validate compute result
- self.assertEqual(float(c2.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 128) # validate memory result
+ # validate compute result
+ self.assertEqual(float(
+ c2.resources['cpu_quota']) / c2.resources['cpu_period'], E_CPU / MAX_CU * 1)
+ # validate memory result
+ self.assertEqual(
+ float(c2.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 128)
c3 = createDummyContainerObject("c3", flavor="medium")
rm.allocate(c3) # calculate allocation
- self.assertEqual(float(c3.resources['cpu_quota']) / c3.resources['cpu_period'], E_CPU / MAX_CU * 4) # validate compute result
- self.assertEqual(float(c3.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 256) # validate memory result
+ # validate compute result
+ self.assertEqual(float(
+ c3.resources['cpu_quota']) / c3.resources['cpu_period'], E_CPU / MAX_CU * 4)
+ # validate memory result
+ self.assertEqual(
+ float(c3.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 256)
c4 = createDummyContainerObject("c4", flavor="large")
rm.allocate(c4) # calculate allocation
- self.assertEqual(float(c4.resources['cpu_quota']) / c4.resources['cpu_period'], E_CPU / MAX_CU * 8) # validate compute result
- self.assertEqual(float(c4.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 512) # validate memory result
+ # validate compute result
+ self.assertEqual(float(
+ c4.resources['cpu_quota']) / c4.resources['cpu_period'], E_CPU / MAX_CU * 8)
+ # validate memory result
+ self.assertEqual(
+ float(c4.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 512)
c5 = createDummyContainerObject("c5", flavor="xlarge")
rm.allocate(c5) # calculate allocation
- self.assertEqual(float(c5.resources['cpu_quota']) / c5.resources['cpu_period'], E_CPU / MAX_CU * 16) # validate compute result
- self.assertEqual(float(c5.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 1024) # validate memory result
-
+ # validate compute result
+ self.assertEqual(float(
+ c5.resources['cpu_quota']) / c5.resources['cpu_period'], E_CPU / MAX_CU * 16)
+ # validate memory result
+ self.assertEqual(
+ float(c5.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 1024)
def testAllocationCpuLimit(self):
"""
@@ -180,7 +194,8 @@
E_MEM = 512
MAX_MU = 4096
# create dummy resource model environment
- reg = ResourceModelRegistrar(dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
+ reg = ResourceModelRegistrar(
+ dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
rm = UpbSimpleCloudDcRM(max_cu=MAX_CU, max_mu=MAX_MU)
reg.register("test_dc", rm)
@@ -211,7 +226,8 @@
E_MEM = 512
MAX_MU = 2048
# create dummy resource model environment
- reg = ResourceModelRegistrar(dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
+ reg = ResourceModelRegistrar(
+ dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
rm = UpbSimpleCloudDcRM(max_cu=MAX_CU, max_mu=MAX_MU)
reg.register("test_dc", rm)
@@ -234,11 +250,9 @@
Test the free procedure.
:return:
"""
- # config
- E_CPU = 1.0
- MAX_CU = 100
# create dummy resource model environment
- reg = ResourceModelRegistrar(dc_emulation_max_cpu=1.0, dc_emulation_max_mem=512)
+ reg = ResourceModelRegistrar(
+ dc_emulation_max_cpu=1.0, dc_emulation_max_mem=512)
rm = UpbSimpleCloudDcRM(max_cu=100, max_mu=100)
reg.register("test_dc", rm)
c1 = createDummyContainerObject("c6", flavor="tiny")
@@ -279,8 +293,10 @@
self.assertTrue(len(r._allocated_compute_instances) == 1)
# check if there is a real limitation set for containers cgroup
- # deactivated for now, seems not to work in docker-in-docker setup used in CI
- self.assertEqual(float(tc1.resources['cpu_quota'])/tc1.resources['cpu_period'], 0.005)
+ # deactivated for now, seems not to work in docker-in-docker setup used
+ # in CI
+ self.assertEqual(
+ float(tc1.resources['cpu_quota']) / tc1.resources['cpu_period'], 0.005)
# check if free was called during stopCompute
self.dc[0].stopCompute("tc1")
@@ -307,39 +323,50 @@
E_MEM = 512
MAX_MU = 2048
# create dummy resource model environment
- reg = ResourceModelRegistrar(dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
+ reg = ResourceModelRegistrar(
+ dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
rm = UpbOverprovisioningCloudDcRM(max_cu=MAX_CU, max_mu=MAX_MU)
reg.register("test_dc", rm)
c1 = createDummyContainerObject("c1", flavor="small")
rm.allocate(c1) # calculate allocation
- self.assertAlmostEqual(float(c1.resources['cpu_quota']) / c1.resources['cpu_period'], E_CPU / MAX_CU * 1.0, places=5)
- self.assertAlmostEqual(float(c1.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 128)
+ self.assertAlmostEqual(float(
+ c1.resources['cpu_quota']) / c1.resources['cpu_period'], E_CPU / MAX_CU * 1.0, places=5)
+ self.assertAlmostEqual(
+ float(c1.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 128)
self.assertAlmostEqual(rm.cpu_op_factor, 1.0)
c2 = createDummyContainerObject("c2", flavor="small")
rm.allocate(c2) # calculate allocation
- self.assertAlmostEqual(float(c2.resources['cpu_quota']) / c2.resources['cpu_period'], E_CPU / MAX_CU * 1.0, places=5)
- self.assertAlmostEqual(float(c2.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 128)
+ self.assertAlmostEqual(float(
+ c2.resources['cpu_quota']) / c2.resources['cpu_period'], E_CPU / MAX_CU * 1.0, places=5)
+ self.assertAlmostEqual(
+ float(c2.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 128)
self.assertAlmostEqual(rm.cpu_op_factor, 1.0)
c3 = createDummyContainerObject("c3", flavor="small")
rm.allocate(c3) # calculate allocation
- self.assertAlmostEqual(float(c3.resources['cpu_quota']) / c3.resources['cpu_period'], E_CPU / MAX_CU * 1.0, places=5)
- self.assertAlmostEqual(float(c3.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 128)
+ self.assertAlmostEqual(float(
+ c3.resources['cpu_quota']) / c3.resources['cpu_period'], E_CPU / MAX_CU * 1.0, places=5)
+ self.assertAlmostEqual(
+ float(c3.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 128)
self.assertAlmostEqual(rm.cpu_op_factor, 1.0)
# from this container onwards, we should go to over provisioning mode:
c4 = createDummyContainerObject("c4", flavor="small")
rm.allocate(c4) # calculate allocation
- self.assertAlmostEqual(float(c4.resources['cpu_quota']) / c4.resources['cpu_period'], E_CPU / MAX_CU * (float(3) / 4), places=5)
- self.assertAlmostEqual(float(c4.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 128, places=5)
+ self.assertAlmostEqual(float(
+ c4.resources['cpu_quota']) / c4.resources['cpu_period'], E_CPU / MAX_CU * (float(3) / 4), places=5)
+ self.assertAlmostEqual(float(
+ c4.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 128, places=5)
self.assertAlmostEqual(rm.cpu_op_factor, 0.75)
c5 = createDummyContainerObject("c5", flavor="small")
rm.allocate(c5) # calculate allocation
- self.assertAlmostEqual(float(c5.resources['cpu_quota']) / c5.resources['cpu_period'], E_CPU / MAX_CU * (float(3) / 5), places=5)
- self.assertAlmostEqual(float(c5.resources['mem_limit']/1024/1024), float(E_MEM) / MAX_MU * 128)
+ self.assertAlmostEqual(float(
+ c5.resources['cpu_quota']) / c5.resources['cpu_period'], E_CPU / MAX_CU * (float(3) / 5), places=5)
+ self.assertAlmostEqual(
+ float(c5.resources['mem_limit'] / 1024 / 1024), float(E_MEM) / MAX_MU * 128)
self.assertAlmostEqual(rm.cpu_op_factor, 0.6)
@@ -359,7 +386,8 @@
E_MEM = 512
MAX_MU = 2048
# create dummy resource model environment
- reg = ResourceModelRegistrar(dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
+ reg = ResourceModelRegistrar(
+ dc_emulation_max_cpu=E_CPU, dc_emulation_max_mem=E_MEM)
rm = UpbDummyRM(max_cu=MAX_CU, max_mu=MAX_MU)
reg.register("test_dc", rm)
@@ -370,4 +398,3 @@
c2 = createDummyContainerObject("c2", flavor="small")
rm.allocate(c2) # calculate allocation
self.assertEqual(len(rm._allocated_compute_instances), 2)
-
diff --git a/src/emuvim/test/unittests/test_restapi.py b/src/emuvim/test/unittests/test_restapi.py
index 4ea8008..ef157e5 100755
--- a/src/emuvim/test/unittests/test_restapi.py
+++ b/src/emuvim/test/unittests/test_restapi.py
@@ -1,36 +1,28 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
-"""
-Test suite to automatically test emulator REST API endpoints.
-"""
-
-import time
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import unittest
from emuvim.test.api_base import SimpleTestTopology
import subprocess
@@ -60,13 +52,16 @@
print('->>>>>>> vim-emu compute start -d datacenter0 -n vnf1 ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("vim-emu compute start -d datacenter0 -n vnf1", shell=True)
+ subprocess.call(
+ "vim-emu compute start -d datacenter0 -n vnf1", shell=True)
print('->>>>>>> vim-emu compute start -d datacenter0 -n vnf2 ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("vim-emu compute start -d datacenter0 -n vnf2", shell=True)
+ subprocess.call(
+ "vim-emu compute start -d datacenter0 -n vnf2", shell=True)
print('->>>>>>> vim-emu compute start -d datacenter0 -n vnf3 ->>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("vim-emu compute start -d datacenter1 -n vnf3", shell=True)
+ subprocess.call(
+ "vim-emu compute start -d datacenter1 -n vnf3", shell=True)
subprocess.call("vim-emu compute list", shell=True)
print('->>>>>>> checking running nodes, compute list, and connectivity >>>>>>>>>>')
@@ -78,33 +73,42 @@
# check compute list result
self.assertTrue(len(self.dc[0].listCompute()) == 2)
self.assertTrue(len(self.dc[1].listCompute()) == 1)
- self.assertTrue(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
- self.assertTrue(isinstance(self.dc[0].listCompute()[1], EmulatorCompute))
- self.assertTrue(isinstance(self.dc[1].listCompute()[0], EmulatorCompute))
+ self.assertTrue(isinstance(
+ self.dc[0].listCompute()[0], EmulatorCompute))
+ self.assertTrue(isinstance(
+ self.dc[0].listCompute()[1], EmulatorCompute))
+ self.assertTrue(isinstance(
+ self.dc[1].listCompute()[0], EmulatorCompute))
self.assertTrue(self.dc[0].listCompute()[1].name == "vnf1")
self.assertTrue(self.dc[0].listCompute()[0].name == "vnf2")
self.assertTrue(self.dc[1].listCompute()[0].name == "vnf3")
# check connectivity by using ping
- self.assertTrue(self.net.ping([self.dc[0].listCompute()[1], self.dc[0].listCompute()[0]]) <= 0.0)
- self.assertTrue(self.net.ping([self.dc[0].listCompute()[0], self.dc[1].listCompute()[0]]) <= 0.0)
- self.assertTrue(self.net.ping([self.dc[1].listCompute()[0], self.dc[0].listCompute()[1]]) <= 0.0)
+ self.assertTrue(self.net.ping(
+ [self.dc[0].listCompute()[1], self.dc[0].listCompute()[0]]) <= 0.0)
+ self.assertTrue(self.net.ping(
+ [self.dc[0].listCompute()[0], self.dc[1].listCompute()[0]]) <= 0.0)
+ self.assertTrue(self.net.ping(
+ [self.dc[1].listCompute()[0], self.dc[0].listCompute()[1]]) <= 0.0)
print('network add vnf1 vnf2->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- output = subprocess.check_output("vim-emu network add -src vnf1 -dst vnf2 -b -c 10", shell=True)
+ output = subprocess.check_output(
+ "vim-emu 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('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- output = subprocess.check_output("vim-emu network remove -src vnf1 -dst vnf2 -b", shell=True)
+ output = subprocess.check_output(
+ "vim-emu network remove -src vnf1 -dst vnf2 -b", shell=True)
self.assertTrue("del-flows" in output)
self.assertTrue("success" in output)
print('>>>>> checking --> vim-emu compute stop -d datacenter0 -n vnf2 ->>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- output = subprocess.check_output("vim-emu compute stop -d datacenter0 -n vnf2", shell=True)
+ output = subprocess.check_output(
+ "vim-emu compute stop -d datacenter0 -n vnf2", shell=True)
# check number of running nodes
self.assertTrue(len(self.getContainernetContainers()) == 2)
@@ -123,7 +127,8 @@
print('>>>>> checking --> vim-emu compute status -d datacenter0 -n vnf1 ->>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- output = subprocess.check_output("vim-emu compute status -d datacenter0 -n vnf1", shell=True)
+ output = subprocess.check_output(
+ "vim-emu compute status -d datacenter0 -n vnf1", shell=True)
output = ast.literal_eval(output)
# check compute status result
@@ -138,7 +143,8 @@
print('->>>>> checking --> vim-emu datacenter status -d datacenter0 ->>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- output = subprocess.check_output("vim-emu datacenter status -d datacenter0", shell=True)
+ output = subprocess.check_output(
+ "vim-emu datacenter status -d datacenter0", shell=True)
# check datacenter status result
self.assertTrue("datacenter0" in output)
self.stopApi()
diff --git a/src/emuvim/test/unittests/test_sonata_dummy_gatekeeper.py b/src/emuvim/test/unittests/test_sonata_dummy_gatekeeper.py
index 3450ce9..cb18c57 100755
--- a/src/emuvim/test/unittests/test_sonata_dummy_gatekeeper.py
+++ b/src/emuvim/test/unittests/test_sonata_dummy_gatekeeper.py
@@ -1,40 +1,35 @@
-"""
-Copyright (c) 2015 SONATA-NFV
-ALL RIGHTS RESERVED.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
-nor the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-This work has been performed in the framework of the SONATA project,
-funded by the European Commission under Grant number 671517 through
-the Horizon 2020 and 5G-PPP programmes. The authors would like to
-acknowledge the contributions of their colleagues of the SONATA
-partner consortium (www.sonata-nfv.eu).
-"""
-
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
import time
import requests
import json
-import os
import unittest
from emuvim.test.base import SimpleTestTopology
from emuvim.api.sonata import SonataDummyGatekeeperEndpoint
from emuvim.api.sonata.dummygatekeeper import initialize_GK, parse_interface
-import mininet.clean
from ipaddress import ip_network
PACKAGE_PATH = "misc/sonata-demo-service.son"
@@ -42,10 +37,11 @@
class testSonataDummyGatekeeper(SimpleTestTopology):
-# @unittest.skip("disabled")
+ # @unittest.skip("disabled")
def test_GK_Api_start_service(self):
# create network
- self.createNet(nswitches=0, ndatacenter=2, nhosts=2, ndockers=0, enable_learning=True)
+ self.createNet(nswitches=0, ndatacenter=2, nhosts=2,
+ ndockers=0, enable_learning=True)
# setup links
self.net.addLink(self.dc[0], self.h[0])
self.net.addLink(self.dc[0], self.dc[1])
@@ -70,7 +66,8 @@
# instantiate service
self.service_uuid = json.loads(r.text).get("service_uuid")
- r2 = requests.post("http://127.0.0.1:55000/instantiations", data=json.dumps({"service_uuid": self.service_uuid}))
+ r2 = requests.post("http://127.0.0.1:55000/instantiations",
+ data=json.dumps({"service_uuid": self.service_uuid}))
self.assertEqual(r2.status_code, 201)
# give the emulator some time to instantiate everything
@@ -80,7 +77,8 @@
r3 = requests.get("http://127.0.0.1:55000/packages")
self.assertEqual(len(json.loads(r3.text).get("service_uuid_list")), 1)
r4 = requests.get("http://127.0.0.1:55000/instantiations")
- self.assertEqual(len(json.loads(r4.text).get("service_instantiations_list")), 1)
+ self.assertEqual(len(json.loads(r4.text).get(
+ "service_instantiations_list")), 1)
# check number of running nodes
self.assertTrue(len(self.getContainernetContainers()) == 3)
@@ -89,49 +87,59 @@
# check compute list result
self.assertEqual(len(self.dc[0].listCompute()), 2)
# check connectivity by using ping
- ELAN_list=[]
+ ELAN_list = []
# check E-Line connection, by checking the IP addresses
for link in self.net.deployed_elines:
- vnf_src, intf_src, vnf_sap_docker_name = parse_interface(link['connection_points_reference'][0])
+ vnf_src, intf_src, vnf_sap_docker_name = parse_interface(
+ link['connection_points_reference'][0])
print vnf_src, intf_src
src = self.net.getNodeByName(vnf_src)
if not src:
continue
network_list = src.getNetworkStatus()
- src_ip = [intf['ip'] for intf in network_list if intf['intf_name'] == intf_src][0]
- src_mask = [intf['netmask'] for intf in network_list if intf['intf_name'] == intf_src][0]
+ src_ip = [intf['ip']
+ for intf in network_list if intf['intf_name'] == intf_src][0]
+ src_mask = [intf['netmask']
+ for intf in network_list if intf['intf_name'] == intf_src][0]
- vnf_dst, intf_dst, vnf_sap_docker_name = parse_interface(link['connection_points_reference'][1])
+ vnf_dst, intf_dst, vnf_sap_docker_name = parse_interface(
+ link['connection_points_reference'][1])
dst = self.net.getNodeByName(vnf_dst)
if not dst:
continue
network_list = dst.getNetworkStatus()
- dst_ip = [intf['ip'] for intf in network_list if intf['intf_name'] == intf_dst][0]
- dst_mask = [intf['netmask'] for intf in network_list if intf['intf_name'] == intf_dst][0]
+ dst_ip = [intf['ip']
+ for intf in network_list if intf['intf_name'] == intf_dst][0]
+ dst_mask = [intf['netmask']
+ for intf in network_list if intf['intf_name'] == intf_dst][0]
- print "src = {0}:{1} ip={2} ".format(vnf_src, intf_src, src_ip, src_mask)
- print "dst = {0}:{1} ip={2} ".format(vnf_dst, intf_dst, dst_ip, dst_mask)
+ print "src = {0}:{1} ip={2} ".format(
+ vnf_src, intf_src, src_ip, src_mask)
+ print "dst = {0}:{1} ip={2} ".format(
+ vnf_dst, intf_dst, dst_ip, dst_mask)
# check if the E-Line IP's are in the same subnet
ret = ip_network(u'{0}'.format(src_ip, src_mask), strict=False)\
- .compare_networks(ip_network(u'{0}'.format(dst_ip, dst_mask),strict=False))
+ .compare_networks(ip_network(u'{0}'.format(dst_ip, dst_mask), strict=False))
self.assertTrue(ret == 0)
-
for vnf in self.dc[0].listCompute():
# check E LAN connection
network_list = vnf.getNetworkStatus()
- mgmt_ip = [intf['ip'] for intf in network_list if intf['intf_name'] == 'mgmt']
+ mgmt_ip = [intf['ip']
+ for intf in network_list if intf['intf_name'] == 'mgmt']
self.assertTrue(len(mgmt_ip) > 0)
ip_address = mgmt_ip[0]
ELAN_list.append(ip_address)
print ip_address
- # check ELAN connection by ping over the mgmt network (needs to be configured as ELAN in the test service)
+ # check ELAN connection by ping over the mgmt network (needs to be
+ # configured as ELAN in the test service)
for vnf in self.dc[0].listCompute():
network_list = vnf.getNetworkStatus()
- mgmt_ip = [intf['ip'] for intf in network_list if intf['intf_name'] == 'mgmt']
+ mgmt_ip = [intf['ip']
+ for intf in network_list if intf['intf_name'] == 'mgmt']
self.assertTrue(len(mgmt_ip) > 0)
ip_address = mgmt_ip[0]
print ELAN_list
@@ -140,7 +148,7 @@
test_ip_list.remove(ip_address)
for ip in test_ip_list:
# only take ip address, without netmask
- p = self.net.ping([vnf],manualdestip=ip.split('/')[0])
+ p = self.net.ping([vnf], manualdestip=ip.split('/')[0])
print p
self.assertTrue(p <= 0.0)
@@ -148,7 +156,7 @@
self.stopNet()
initialize_GK()
- #@unittest.skip("disabled")
+ # @unittest.skip("disabled")
def test_GK_Api_stop_service(self):
# create network
self.createNet(ndatacenter=2, nhosts=2)
@@ -176,7 +184,8 @@
# instantiate service
self.service_uuid = json.loads(r.text).get("service_uuid")
- r2 = requests.post("http://127.0.0.1:55001/instantiations", data=json.dumps({"service_uuid": self.service_uuid}))
+ r2 = requests.post("http://127.0.0.1:55001/instantiations",
+ data=json.dumps({"service_uuid": self.service_uuid}))
self.assertEqual(r2.status_code, 201)
# give the emulator some time to instantiate everything
@@ -186,7 +195,8 @@
r3 = requests.get("http://127.0.0.1:55001/packages")
self.assertEqual(len(json.loads(r3.text).get("service_uuid_list")), 1)
r4 = requests.get("http://127.0.0.1:55001/instantiations")
- self.assertEqual(len(json.loads(r4.text).get("service_instantiations_list")), 1)
+ self.assertEqual(len(json.loads(r4.text).get(
+ "service_instantiations_list")), 1)
# check number of running nodes
self.assertTrue(len(self.getContainernetContainers()) == 3)
@@ -196,18 +206,21 @@
self.assertEqual(len(self.dc[0].listCompute()), 2)
# stop the service
- service_instance_uuid = json.loads(r2.text).get("service_instance_uuid")
+ service_instance_uuid = json.loads(
+ r2.text).get("service_instance_uuid")
self.assertTrue(service_instance_uuid is not None)
- requests.delete("http://127.0.0.1:55001/instantiations", data=json.dumps({"service_uuid": self.service_uuid, "service_instance_uuid":service_instance_uuid}))
+ requests.delete("http://127.0.0.1:55001/instantiations", data=json.dumps(
+ {"service_uuid": self.service_uuid, "service_instance_uuid": service_instance_uuid}))
r5 = requests.get("http://127.0.0.1:55001/instantiations")
- self.assertTrue(len(json.loads(r5.text).get("service_instantiations_list")), 0) # note that there was 1 instance before
+ # note that there was 1 instance before
+ self.assertTrue(len(json.loads(r5.text).get(
+ "service_instantiations_list")), 0)
# stop Mininet network
self.stopNet()
initialize_GK()
-
@unittest.skip("disabled")
def test_GK_stress_service(self):
# create network
@@ -232,7 +245,8 @@
# instantiate service
self.service_uuid = json.loads(r.text).get("service_uuid")
- r2 = requests.post("http://127.0.0.1:55002/instantiations", data=json.dumps({"service_uuid": self.service_uuid}))
+ r2 = requests.post("http://127.0.0.1:55002/instantiations",
+ data=json.dumps({"service_uuid": self.service_uuid}))
self.assertEqual(r2.status_code, 201)
# give the emulator some time to instantiate everything
@@ -242,18 +256,21 @@
r3 = requests.get("http://127.0.0.1:55002/packages")
self.assertEqual(len(json.loads(r3.text).get("service_uuid_list")), 1)
r4 = requests.get("http://127.0.0.1:55002/instantiations")
- self.assertEqual(len(json.loads(r4.text).get("service_instantiations_list")), 1)
+ self.assertEqual(len(json.loads(r4.text).get(
+ "service_instantiations_list")), 1)
# stop the service
- service_instance_uuid = json.loads(r2.text).get("service_instance_uuid")
+ service_instance_uuid = json.loads(
+ r2.text).get("service_instance_uuid")
self.assertTrue(service_instance_uuid is not None)
- requests.delete("http://127.0.0.1:55002/instantiations", data=json.dumps({"service_uuid": self.service_uuid, "service_instance_uuid":service_instance_uuid}))
+ requests.delete("http://127.0.0.1:55002/instantiations", data=json.dumps(
+ {"service_uuid": self.service_uuid, "service_instance_uuid": service_instance_uuid}))
r5 = requests.get("http://127.0.0.1:55002/instantiations")
- self.assertTrue(len(json.loads(r5.text).get("service_instantiations_list")), 0) # note that there was 1 instance before
+ # note that there was 1 instance before
+ self.assertTrue(len(json.loads(r5.text).get(
+ "service_instantiations_list")), 0)
# stop Mininet network
self.stopNet()
initialize_GK()
-
-