+# 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.openstack_dummies.base_openstack_dummy import \
+ BaseOpenstackDummy
from datetime import datetime
+import emuvim.api.openstack.openstack_dummies.neutron_sfc_dummy_api as SFC
import logging
import json
import uuid
import copy
+LOG = logging.getLogger("api.openstack.neutron")
+
class NeutronDummyApi(BaseOpenstackDummy):
def __init__(self, ip, port, compute):
super(NeutronDummyApi, self).__init__(ip, port)
self.compute = compute
+ # create default networks (OSM usually assumes to have these
+ # pre-configured)
+ self.compute.create_network("mgmt")
+ self.compute.create_network("mgmtnet")
+
self.api.add_resource(NeutronListAPIVersions, "/")
- self.api.add_resource(Shutdown, "/shutdown")
self.api.add_resource(NeutronShowAPIv2Details, "/v2.0")
self.api.add_resource(NeutronListNetworks, "/v2.0/networks.json", "/v2.0/networks",
resource_class_kwargs={'api': self})
self.api.add_resource(NeutronAddFloatingIp, "/v2.0/floatingips.json", "/v2.0/floatingips",
resource_class_kwargs={'api': self})
- def _start_flask(self):
- logging.info("Starting %s endpoint @ http://%s:%d" % (__name__, 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)
+ # Service Function Chaining (SFC) API
+ self.api.add_resource(SFC.PortPairsCreate, "/v2.0/sfc/port_pairs.json", "/v2.0/sfc/port_pairs",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairsUpdate, "/v2.0/sfc/port_pairs/<pair_id>.json",
+ "/v2.0/sfc/port_pairs/<pair_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairsDelete, "/v2.0/sfc/port_pairs/<pair_id>.json",
+ "/v2.0/sfc/port_pairs/<pair_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairsList, "/v2.0/sfc/port_pairs.json", "/v2.0/sfc/port_pairs",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairsShow, "/v2.0/sfc/port_pairs/<pair_id>.json",
+ "/v2.0/sfc/port_pairs/<pair_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairGroupCreate, "/v2.0/sfc/port_pair_groups.json", "/v2.0/sfc/port_pair_groups",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairGroupUpdate, "/v2.0/sfc/port_pair_groups/<group_id>.json",
+ "/v2.0/sfc/port_pair_groups/<group_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairGroupDelete, "/v2.0/sfc/port_pair_groups/<group_id>.json",
+ "/v2.0/sfc/port_pair_groups/<group_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairGroupList, "/v2.0/sfc/port_pair_groups.json", "/v2.0/sfc/port_pair_groups",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortPairGroupShow, "/v2.0/sfc/port_pair_groups/<group_id>.json",
+ "/v2.0/sfc/port_pair_groups/<group_id>",
+ resource_class_kwargs={'api': self})
-class Shutdown(Resource):
- def get(self):
- logging.debug(("%s is beeing shut down") % (__name__))
- func = request.environ.get('werkzeug.server.shutdown')
- if func is None:
- raise RuntimeError('Not running with the Werkzeug Server')
- func()
+ self.api.add_resource(SFC.FlowClassifierCreate, "/v2.0/sfc/flow_classifiers.json", "/v2.0/sfc/flow_classifiers",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.FlowClassifierUpdate, "/v2.0/sfc/flow_classifiers/<flow_classifier_id>.json",
+ "/v2.0/sfc/flow_classifiers/<flow_classifier_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.FlowClassifierDelete, "/v2.0/sfc/flow_classifiers/<flow_classifier_id>.json",
+ "/v2.0/sfc/flow_classifiers/<flow_classifier_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.FlowClassifierList, "/v2.0/sfc/flow_classifiers.json", "/v2.0/sfc/flow_classifiers",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.FlowClassifierShow, "/v2.0/sfc/flow_classifiers/<flow_classifier_id>.json",
+ "/v2.0/sfc/flow_classifiers/<flow_classifier_id>",
+ resource_class_kwargs={'api': self})
+
+ self.api.add_resource(SFC.PortChainCreate, "/v2.0/sfc/port_chains.json", "/v2.0/sfc/port_chains",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortChainUpdate, "/v2.0/sfc/port_chains/<chain_id>.json",
+ "/v2.0/sfc/port_chains/<chain_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortChainDelete, "/v2.0/sfc/port_chains/<chain_id>.json",
+ "/v2.0/sfc/port_chains/<chain_id>",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortChainList, "/v2.0/sfc/port_chains.json", "/v2.0/sfc/port_chains",
+ resource_class_kwargs={'api': self})
+ self.api.add_resource(SFC.PortChainShow, "/v2.0/sfc/port_chains/<chain_id>.json",
+ "/v2.0/sfc/port_chains/<chain_id>",
+ resource_class_kwargs={'api': self})
class NeutronListAPIVersions(Resource):
:return: Returns a json with API versions.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: Neutron - List API Versions")
+ LOG.debug("API CALL: Neutron - List API Versions")
resp = dict()
resp['versions'] = dict()
}]
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):
:return: Returns a json with API details.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
resp = dict()
resp['resources'] = dict()
],
"name": "network",
"collection": "networks"
- },
+ },
{
"links": [
{
],
"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):
:return: Returns a json response, starting with 'networks' as root node.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
+ # LOG.debug("ARGS: {}".format(request.args))
try:
if request.args.get('name'):
tmp_network = NeutronShowNetwork(self.api)
- return tmp_network.get_network(request.args.get('name'), True)
+ 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)
- return tmp_network.get_network(request.args.get('id'), True)
+ response = tmp_network.get_network(
+ request.args.get('id'), True)
+ LOG.debug("{} RESPONSE (2): {}".format(
+ self.__class__.__name__, response))
+ return response
network_list = list()
network_dict = dict()
network_list.append(tmp_network_dict)
network_dict["networks"] = network_list
-
- 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:
- logging.exception("Neutron: List networks exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: List networks exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronShowNetwork(Resource):
:return: Returns a json response, starting with 'network' as root node and one network description.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
return self.get_network(network_id, False)
def get_network(self, network_name_or_id, as_list):
: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()
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(str(ex), status=500,
+ mimetype='application/json')
class NeutronCreateNetwork(Resource):
* 201, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s POST" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__))
try:
network_dict = json.loads(request.data)
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:
- logging.exception("Neutron: Create network excepiton.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Create network excepiton.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronUpdateNetwork(Resource):
* 200, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s PUT" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s PUT" % str(self.__class__.__name__))
try:
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"]
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:
- logging.exception("Neutron: Show networks exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Show networks exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronDeleteNetwork(Resource):
* 204, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s DELETE" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s DELETE" % str(self.__class__.__name__))
try:
if network_id not in self.api.compute.nets:
return Response('Could not find network. (' + network_id + ')\n',
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)
- return Response('Network ' + str(network_id) + ' deleted.\n', status=204, mimetype='application/json')
+ return Response('', status=204, mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron: Delete network exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Delete network exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronListSubnets(Resource):
:return: Returns a json response, starting with 'subnets' as root node.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
try:
if request.args.get('name'):
show_subnet = NeutronShowSubnet(self.api)
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:
- logging.exception("Neutron: List subnets exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: List subnets exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronShowSubnet(Resource):
:return: Returns a json response, starting with 'subnet' as root node and one subnet description.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
return self.get_subnet(subnet_id, False)
def get_subnet(self, subnet_name_or_id, as_list):
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:
- logging.exception("Neutron: Show subnet exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Show subnet exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronCreateSubnet(Resource):
* 201, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s POST" % str(self.__class__.__name__))
+ 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:
- 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"]
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:
- logging.exception("Neutron: Create network excepiton.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Create network excepiton.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronUpdateSubnet(Resource):
* 200, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s PUT" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s PUT" % str(self.__class__.__name__))
try:
for net in self.api.compute.nets.values():
if net.subnet_id == subnet_id:
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:
- logging.exception("Neutron: Show networks exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Show networks exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronDeleteSubnet(Resource):
* 204, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s DELETE" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s DELETE" % str(self.__class__.__name__))
try:
for net in self.api.compute.nets.values():
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))
+ continue
if port.net_name == net.name:
port.ip_address = None
self.api.compute.dc.net.removeLink(
net.delete_subnet()
- return Response('Subnet ' + str(subnet_id) + ' deleted.\n',
- 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:
- logging.exception("Neutron: Delete subnet exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Delete subnet exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronListPorts(Resource):
:return: Returns a json response, starting with 'ports' as root node.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
try:
if request.args.get('name'):
show_port = NeutronShowPort(self.api)
show_port = NeutronShowPort(self.api)
return show_port.get_port(request.args.get('id'), True)
- port_list = list()
- port_dict = dict()
-
- if len(id_list) == 0:
- for port in self.api.compute.ports.values():
- tmp_port_dict = port.create_port_dict(self.api.compute)
- port_list.append(tmp_port_dict)
- else:
- for port in self.api.compute.ports.values():
- if port.id in id_list:
- tmp_port_dict = port.create_port_dict(self.api.compute)
- port_list.append(tmp_port_dict)
+ ports = self.api.compute.ports.values()
+ if len(id_list) != 0:
+ ports = filter(lambda port: port.id in id_list, ports)
+
+ device_id = request.args.get('device_id')
+ if device_id:
+ server = self.api.compute.find_server_by_name_or_id(device_id)
+ if not server:
+ raise RuntimeError("Unable to find server '%s' in order to return it's ports" % server)
+
+ ports = filter(lambda port: (
+ any(
+ filter(
+ lambda server_port_name_or_id: (
+ port.id == server_port_name_or_id or port.name == server_port_name_or_id
+ ),
+ server.port_names
+ )
+ )
+ ), ports)
- port_dict["ports"] = port_list
+ port_dict = dict()
+ port_dict["ports"] = list(map(lambda x: x.create_port_dict(self.api.compute), ports))
- 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:
- logging.exception("Neutron: List ports exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: List ports exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronShowPort(Resource):
:return: Returns a json response, starting with 'port' as root node and one network description.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s GET" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s GET" % str(self.__class__.__name__))
return self.get_port(port_id, False)
def get_port(self, port_name_or_id, as_list):
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:
- logging.exception("Neutron: Show port exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Show port exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronCreatePort(Resource):
* 201, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s POST" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__))
try:
port_dict = json.loads(request.data)
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']:
num_ports = len(self.api.compute.ports)
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')
-
port = self.api.compute.create_port(name)
port.net_name = net.name
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:
return Response(json.dumps({'port': port.create_port_dict(self.api.compute)}), status=201,
mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron: Show port exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Show port exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronUpdatePort(Resource):
* 200, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s PUT" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s PUT" % str(self.__class__.__name__))
try:
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
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"]:
return Response(json.dumps({'port': port.create_port_dict(self.api.compute)}), status=200,
mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron: Update port exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Update port exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronDeletePort(Resource):
* 204, if everything worked out.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s DELETE" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s DELETE" % str(self.__class__.__name__))
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():
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)
# delete the port
self.api.compute.delete_port(port.id)
- return Response('Port ' + port_id + ' deleted.\n', status=204, mimetype='application/json')
+ return Response('', status=204, mimetype='application/json')
except Exception as ex:
- logging.exception("Neutron: Delete port exception.")
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Delete port exception.")
+ return Response(str(ex), status=500,
+ mimetype='application/json')
class NeutronAddFloatingIp(Resource):
def get(self):
"""
- Added a quick and dirty fake for the OSM integration. Returns a list of
- floating IPs. Has nothing to do with the setup inside the emulator.
- But its enough to make the OSM driver happy.
- @PG Sandman: Feel free to improve this and let it do something meaningful.
+ Returns a Floating IP for a port.
+
+ Currently ports are not mapped to individual IPs, but the
+ (potentially shared) Docker external IP is returned.
"""
+ port_id = request.args.get("port_id")
+ if not port_id:
+ message = "Neutron: List API for FloatingIPs is not implemented"
+ LOG.exception(message)
+ return Response(message, status=500,
+ mimetype='application/json')
+ port = self.api.compute.find_port_by_name_or_id(port_id)
+ ip = port.assigned_container.dcinfo["NetworkSettings"]["IPAddress"]
resp = dict()
- resp["floatingips"] = list()
- # create a list of floting IP definitions and return it
- for i in range(100, 110):
- ip=dict()
- ip["router_id"] = "router_id"
- ip["description"] = "hardcoded in api"
- ip["created_at"] = "router_id"
- ip["updated_at"] = "router_id"
- ip["revision_number"] = 1
- ip["tenant_id"] = "tenant_id"
- ip["project_id"] = "project_id"
- ip["floating_network_id"] = str(i)
- ip["status"] = "ACTIVE"
- ip["id"] = str(i)
- ip["port_id"] = "port_id"
- 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')
-
+ resp["floatingips"] = [
+ {'floating_ip_address': ip}
+ ]
+ return Response(json.dumps(resp), status=200,
+ mimetype='application/json')
def post(self):
"""
:return: Returns a floating network description.
:rtype: :class:`flask.response`
"""
- logging.debug("API CALL: %s POST" % str(self.__class__.__name__))
+ LOG.debug("API CALL: %s POST" % str(self.__class__.__name__))
try:
# Fiddle with floating_network !
req = json.loads(request.data)
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()))
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:
- logging.exception("Neutron: Create FloatingIP exception %s.", ex)
- return Response(ex.message, status=500, mimetype='application/json')
+ LOG.exception("Neutron: Create FloatingIP exception %s.", ex)
+ return Response(str(ex), status=500,
+ mimetype='application/json')