diff options
Diffstat (limited to 'moonv4/moon_consul/moon_consul/http_server.py')
-rw-r--r-- | moonv4/moon_consul/moon_consul/http_server.py | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/moonv4/moon_consul/moon_consul/http_server.py b/moonv4/moon_consul/moon_consul/http_server.py new file mode 100644 index 00000000..c3d13378 --- /dev/null +++ b/moonv4/moon_consul/moon_consul/http_server.py @@ -0,0 +1,134 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from flask import Flask, request +from flask_cors import CORS, cross_origin +from flask_restful import Resource, Api, reqparse +import logging +from moon_consul import __version__ +from moon_consul.api.generic import API +from moon_consul.api.database import Database +from moon_consul.api.messenger import Messenger +from moon_consul.api.openstack import Keystone +from moon_consul.api.slave import Slave +from moon_consul.api.system import Docker, Components +from moon_utilities import exceptions + +logger = logging.getLogger(__name__) + + +class Server: + """Base class for HTTP server""" + + def __init__(self, host="localhost", port=80, api=None, **kwargs): + """Run a server + + :param host: hostname of the server + :param port: port for the running server + :param kwargs: optional parameters + :return: a running server + """ + self._host = host + self._port = port + self._api = api + self._extra = kwargs + + @property + def host(self): + return self._host + + @host.setter + def host(self, name): + self._host = name + + @host.deleter + def host(self): + self._host = "" + + @property + def port(self): + return self._port + + @port.setter + def port(self, number): + self._port = number + + @port.deleter + def port(self): + self._port = 80 + + def run(self): + raise NotImplementedError() + +__API__ = ( + API, + Database, Docker, Messenger, Keystone, Slave, Components + ) + + +class Root(Resource): + """ + The root of the web service + """ + __urls__ = ("/", ) + __methods = ("get", "post", "put", "delete", "options") + + def get(self): + tree = {"/": {"methods": ("get",), "description": "List all methods for that service."}} + for item in __API__: + tree[item.__name__] = {"urls": item.__urls__} + _methods = [] + for _method in self.__methods: + if _method in dir(item): + _methods.append(_method) + tree[item.__name__]["methods"] = _methods + tree[item.__name__]["description"] = item.__doc__.strip() + return { + "version": __version__, + "tree": tree + } + + +class HTTPServer(Server): + + def __init__(self, host="localhost", port=80, conf=None, **kwargs): + super(HTTPServer, self).__init__(host=host, port=port, **kwargs) + self.app = Flask(__name__) + self.conf = conf + # Todo : specify only few urls instead of * + # CORS(self.app) + self.api = Api(self.app) + self.__set_route() + # self.__hook_errors() + + @self.app.errorhandler(exceptions.AuthException) + def _auth_exception(error): + return {"error": "Unauthorized"}, 401 + + def __hook_errors(self): + # FIXME (dthom): it doesn't work + def get_404_json(e): + return {"error": "Error", "code": 404, "description": e} + self.app.register_error_handler(404, get_404_json) + + def get_400_json(e): + return {"error": "Error", "code": 400, "description": e} + self.app.register_error_handler(400, lambda e: get_400_json) + self.app.register_error_handler(403, exceptions.AuthException) + + def __set_route(self): + self.api.add_resource(Root, '/') + + for api in __API__: + self.api.add_resource( + api, *api.__urls__, + resource_class_kwargs={ + "conf": self.conf, + } + ) + + def run(self): + self.app.run(debug=True, host=self._host, port=self._port) # nosec + |