X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2Fvim-emu.git;a=blobdiff_plain;f=src%2Femuvim%2Fapi%2Frest%2Frest_api_endpoint.py;h=d2abde85f670403d6c7c846596e027253c80cc10;hp=b2a7b86a475e7da7fcf86efe846b2d72e42b2b7b;hb=655815663bf8234c837793db7a5e2e3c50164d3f;hpb=6dcec5542d668c188ffcf491a8abaac4c5735040 diff --git a/src/emuvim/api/rest/rest_api_endpoint.py b/src/emuvim/api/rest/rest_api_endpoint.py index b2a7b86..d2abde8 100755 --- a/src/emuvim/api/rest/rest_api_endpoint.py +++ b/src/emuvim/api/rest/rest_api_endpoint.py @@ -1,40 +1,38 @@ -""" -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). import logging import threading -from flask import Flask +from flask import Flask, send_from_directory from flask_restful import Api -from gevent.wsgi import WSGIServer +from gevent.pywsgi import WSGIServer # 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 @@ -46,7 +44,8 @@ from monitor import MonitorInterfaceAction, MonitorFlowAction, MonitorLinkAction import pkg_resources from os import path -logging.basicConfig(level=logging.INFO) + +logging.basicConfig() class RestApiEndpoint(object): @@ -60,31 +59,36 @@ class RestApiEndpoint(object): 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_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__) self.api = Api(self.app) - # setup endpoints + # define dashboard endpoints + db_dir, db_file = self.get_dashboard_path() + + @self.app.route('/dashboard/') + def db_file(path): + logging.info("[DB] Serving: {}".format(path)) + return send_from_directory(db_dir, path) + # define REST API endpoints # compute related actions (start/stop VNFs, get info) - self.api.add_resource(Compute, "/restapi/compute//") + self.api.add_resource( + Compute, "/restapi/compute//") self.api.add_resource(ComputeList, - "/restapi/compute", - "/restapi/compute/") - self.api.add_resource(ComputeResources, "/restapi/compute/resources//") + "/restapi/compute", + "/restapi/compute/") + self.api.add_resource( + ComputeResources, "/restapi/compute/resources//") - self.api.add_resource(DatacenterStatus, "/restapi/datacenter/") + self.api.add_resource( + DatacenterStatus, "/restapi/datacenter/") self.api.add_resource(DatacenterList, "/restapi/datacenter") - # network related actions (setup chaining between VNFs) self.api.add_resource(NetworkAction, "/restapi/network") @@ -95,7 +99,8 @@ class RestApiEndpoint(object): # 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 +115,19 @@ class RestApiEndpoint(object): 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 get_dashboard_path(self): + """ + Return absolute path to dashboard files. + """ + db_file = pkg_resources.resource_filename( + 'emuvim.dashboard', "index.html") + db_dir = path.dirname(db_file) + logging.info("[DB] Serving emulator dashboard from: {} and {}" + .format(db_dir, db_file)) + return db_dir, db_file def connectDatacenter(self, dc): compute.dcs[dc.label] = dc @@ -127,17 +142,25 @@ class RestApiEndpoint(object): self.__class__.__name__, self.ip, self.port)) def start(self): - thread = threading.Thread(target=self._start_flask, args=()) - thread.daemon = True - thread.start() - logging.info("Started API endpoint @ http://%s:%d" % (self.ip, self.port)) + 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)) + + 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) - 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 - ) - http_server.serve_forever() + # 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, + # 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()