X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=src%2Femuvim%2Fapi%2Fopenstack%2Fopenstack_dummies%2Fneutron_dummy_api.py;h=6f6d3dc958d901b71d1942a6d8ff8cd2522606f6;hb=refs%2Fchanges%2F26%2F6026%2F1;hp=ca1ff3d5077bfd7e55fac1d61c3c0cb69d15b791;hpb=c9abfbec5b0e0ae589c8ad66426e207fbe2385b1;p=osm%2Fvim-emu.git 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 ca1ff3d..6f6d3dc 100755 --- a/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py +++ b/src/emuvim/api/openstack/openstack_dummies/neutron_dummy_api.py @@ -1,13 +1,41 @@ +""" +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") @@ -16,8 +44,11 @@ class NeutronDummyApi(BaseOpenstackDummy): 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}) @@ -52,20 +83,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): - LOG.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/.json", + "/v2.0/sfc/port_pairs/", + resource_class_kwargs={'api': self}) + self.api.add_resource(SFC.PortPairsDelete, "/v2.0/sfc/port_pairs/.json", + "/v2.0/sfc/port_pairs/", + 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/.json", + "/v2.0/sfc/port_pairs/", + 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/.json", + "/v2.0/sfc/port_pair_groups/", + resource_class_kwargs={'api': self}) + self.api.add_resource(SFC.PortPairGroupDelete, "/v2.0/sfc/port_pair_groups/.json", + "/v2.0/sfc/port_pair_groups/", + 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/.json", + "/v2.0/sfc/port_pair_groups/", + resource_class_kwargs={'api': self}) -class Shutdown(Resource): - def get(self): - LOG.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/.json", + "/v2.0/sfc/flow_classifiers/", + resource_class_kwargs={'api': self}) + self.api.add_resource(SFC.FlowClassifierDelete, "/v2.0/sfc/flow_classifiers/.json", + "/v2.0/sfc/flow_classifiers/", + 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/.json", + "/v2.0/sfc/flow_classifiers/", + 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/.json", + "/v2.0/sfc/port_chains/", + resource_class_kwargs={'api': self}) + self.api.add_resource(SFC.PortChainDelete, "/v2.0/sfc/port_chains/.json", + "/v2.0/sfc/port_chains/", + 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/.json", + "/v2.0/sfc/port_chains/", + resource_class_kwargs={'api': self}) class NeutronListAPIVersions(Resource): @@ -155,14 +228,19 @@ class NeutronListNetworks(Resource): :rtype: :class:`flask.response` """ 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() @@ -180,7 +258,7 @@ class NeutronListNetworks(Resource): 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') except Exception as ex: @@ -337,7 +415,7 @@ class NeutronDeleteNetwork(Resource): 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: LOG.exception("Neutron: Delete network exception.") return Response(ex.message, status=500, mimetype='application/json') @@ -458,6 +536,7 @@ class NeutronCreateSubnet(Resource): 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') if "id" in subnet_dict["subnet"]: @@ -558,6 +637,9 @@ class NeutronDeleteSubnet(Resource): 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) + 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( @@ -568,8 +650,7 @@ class NeutronDeleteSubnet(Resource): 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') except Exception as ex: @@ -826,7 +907,7 @@ class NeutronDeletePort(Resource): # 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: LOG.exception("Neutron: Delete port exception.") @@ -848,7 +929,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" @@ -865,7 +946,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.