OpenStack API: Replaced Flask with WSGI
[osm/vim-emu.git] / src / emuvim / api / openstack / openstack_dummies / neutron_dummy_api.py
old mode 100644 (file)
new mode 100755 (executable)
index 38a5ad4..385163c
@@ -1,12 +1,43 @@
+"""
+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 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
 import json
 import uuid
 import copy
 
+LOG = logging.getLogger("api.openstack.neutron")
+
 
 class NeutronDummyApi(BaseOpenstackDummy):
     def __init__(self, ip, port, compute):
@@ -14,7 +45,6 @@ class NeutronDummyApi(BaseOpenstackDummy):
         self.compute = compute
 
         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})
@@ -49,20 +79,62 @@ class NeutronDummyApi(BaseOpenstackDummy):
         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):
@@ -73,7 +145,7 @@ 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()
 
@@ -100,7 +172,7 @@ 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()
@@ -151,7 +223,7 @@ 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__))
         try:
             if request.args.get('name'):
                 tmp_network = NeutronShowNetwork(self.api)
@@ -181,7 +253,7 @@ class NeutronListNetworks(Resource):
             return Response(json.dumps(network_dict), status=200, mimetype='application/json')
 
         except Exception as ex:
-            logging.exception("Neutron: List networks exception.")
+            LOG.exception("Neutron: List networks exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -198,7 +270,7 @@ 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):
@@ -245,7 +317,7 @@ 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']
@@ -256,7 +328,7 @@ class NeutronCreateNetwork(Resource):
             net = self.api.compute.create_network(name)
             return Response(json.dumps({"network": net.create_network_dict()}), status=201, mimetype='application/json')
         except Exception as ex:
-            logging.exception("Neutron: Create network excepiton.")
+            LOG.exception("Neutron: Create network excepiton.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -275,7 +347,7 @@ 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]
@@ -300,7 +372,7 @@ class NeutronUpdateNetwork(Resource):
             return Response('Network not found.\n', status=404, mimetype='application/json')
 
         except Exception as ex:
-            logging.exception("Neutron: Show networks exception.")
+            LOG.exception("Neutron: Show networks exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -319,7 +391,7 @@ 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',
@@ -336,7 +408,7 @@ class NeutronDeleteNetwork(Resource):
 
             return Response('Network ' + str(network_id) + ' deleted.\n', status=204, mimetype='application/json')
         except Exception as ex:
-            logging.exception("Neutron: Delete network exception.")
+            LOG.exception("Neutron: Delete network exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -352,7 +424,7 @@ 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)
@@ -381,7 +453,7 @@ class NeutronListSubnets(Resource):
             return Response(json.dumps(subnet_dict), status=200, mimetype='application/json')
 
         except Exception as ex:
-            logging.exception("Neutron: List subnets exception.")
+            LOG.exception("Neutron: List subnets exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -398,7 +470,7 @@ 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):
@@ -426,7 +498,7 @@ class NeutronShowSubnet(Resource):
             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.")
+            LOG.exception("Neutron: Show subnet exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -445,7 +517,7 @@ 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'])
@@ -478,7 +550,7 @@ class NeutronCreateSubnet(Resource):
             return Response(json.dumps({'subnet': net.create_subnet_dict()}), status=201, mimetype='application/json')
 
         except Exception as ex:
-            logging.exception("Neutron: Create network excepiton.")
+            LOG.exception("Neutron: Create network excepiton.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -497,7 +569,7 @@ 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:
@@ -529,7 +601,7 @@ class NeutronUpdateSubnet(Resource):
             return Response('Network not found.\n', status=404, mimetype='application/json')
 
         except Exception as ex:
-            logging.exception("Neutron: Show networks exception.")
+            LOG.exception("Neutron: Show networks exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -548,7 +620,7 @@ 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:
@@ -570,7 +642,7 @@ class NeutronDeleteSubnet(Resource):
 
             return Response('Could not find subnet.', status=404, mimetype='application/json')
         except Exception as ex:
-            logging.exception("Neutron: Delete subnet exception.")
+            LOG.exception("Neutron: Delete subnet exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -586,7 +658,7 @@ 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)
@@ -614,7 +686,7 @@ class NeutronListPorts(Resource):
             return Response(json.dumps(port_dict), status=200, mimetype='application/json')
 
         except Exception as ex:
-            logging.exception("Neutron: List ports exception.")
+            LOG.exception("Neutron: List ports exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -631,7 +703,7 @@ 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):
@@ -657,7 +729,7 @@ class NeutronShowPort(Resource):
                 tmp_dict["port"] = tmp_port_dict
             return Response(json.dumps(tmp_dict), status=200, mimetype='application/json')
         except Exception as ex:
-            logging.exception("Neutron: Show port exception.")
+            LOG.exception("Neutron: Show port exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -674,7 +746,7 @@ 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']
@@ -721,7 +793,7 @@ class NeutronCreatePort(Resource):
             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.")
+            LOG.exception("Neutron: Show port exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -740,7 +812,7 @@ 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)
@@ -782,7 +854,7 @@ class NeutronUpdatePort(Resource):
             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.")
+            LOG.exception("Neutron: Update port exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -801,7 +873,7 @@ 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:
@@ -826,7 +898,7 @@ class NeutronDeletePort(Resource):
             return Response('Port ' + port_id + ' deleted.\n', status=204, mimetype='application/json')
 
         except Exception as ex:
-            logging.exception("Neutron: Delete port exception.")
+            LOG.exception("Neutron: Delete port exception.")
             return Response(ex.message, status=500, mimetype='application/json')
 
 
@@ -845,7 +917,7 @@ class NeutronAddFloatingIp(Resource):
         resp["floatingips"] = list()
         # create a list of floting IP definitions and return it
         for i in range(100, 110):
-            ip=dict()
+            ip = dict()
             ip["router_id"] = "router_id"
             ip["description"] = "hardcoded in api"
             ip["created_at"] = "router_id"
@@ -862,7 +934,6 @@ class NeutronAddFloatingIp(Resource):
             resp["floatingips"].append(ip)
         return Response(json.dumps(resp), status=200, mimetype='application/json')
 
-
     def post(self):
         """
         Adds a floating IP to neutron.
@@ -870,7 +941,7 @@ class NeutronAddFloatingIp(Resource):
         :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)
@@ -911,5 +982,5 @@ class NeutronAddFloatingIp(Resource):
 
             return Response(json.dumps(response), status=200, mimetype='application/json')
         except Exception as ex:
-            logging.exception("Neutron: Create FloatingIP exception %s.", ex)
+            LOG.exception("Neutron: Create FloatingIP exception %s.", ex)
             return Response(ex.message, status=500, mimetype='application/json')