diff options
Diffstat (limited to 'opnfv_testapi/common')
-rw-r--r-- | opnfv_testapi/common/__init__.py | 8 | ||||
-rw-r--r-- | opnfv_testapi/common/check.py | 114 | ||||
-rw-r--r-- | opnfv_testapi/common/config.py | 79 | ||||
-rw-r--r-- | opnfv_testapi/common/message.py | 54 | ||||
-rw-r--r-- | opnfv_testapi/common/raises.py | 39 | ||||
-rw-r--r-- | opnfv_testapi/common/utils.py | 43 |
6 files changed, 337 insertions, 0 deletions
diff --git a/opnfv_testapi/common/__init__.py b/opnfv_testapi/common/__init__.py new file mode 100644 index 0000000..05c0c93 --- /dev/null +++ b/opnfv_testapi/common/__init__.py @@ -0,0 +1,8 @@ +############################################################################## +# Copyright (c) 2015 Orange +# guyrodrigue.koffi@orange.com / koffirodrigue@gmail.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## diff --git a/opnfv_testapi/common/check.py b/opnfv_testapi/common/check.py new file mode 100644 index 0000000..24ba876 --- /dev/null +++ b/opnfv_testapi/common/check.py @@ -0,0 +1,114 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corp +# feng.xiaowei@zte.com.cn +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +import functools + +from tornado import gen +from tornado import web + +from opnfv_testapi.common import message +from opnfv_testapi.common import raises +from opnfv_testapi.db import api as dbapi + + +def authenticate(method): + @web.asynchronous + @gen.coroutine + @functools.wraps(method) + def wrapper(self, *args, **kwargs): + if self.auth: + try: + token = self.request.headers['X-Auth-Token'] + except KeyError: + raises.Unauthorized(message.unauthorized()) + query = {'access_token': token} + check = yield dbapi.db_find_one('tokens', query) + if not check: + raises.Forbidden(message.invalid_token()) + ret = yield gen.coroutine(method)(self, *args, **kwargs) + raise gen.Return(ret) + return wrapper + + +def not_exist(xstep): + @functools.wraps(xstep) + def wrap(self, *args, **kwargs): + query = kwargs.get('query') + data = yield dbapi.db_find_one(self.table, query) + if not data: + raises.NotFound(message.not_found(self.table, query)) + ret = yield gen.coroutine(xstep)(self, data, *args, **kwargs) + raise gen.Return(ret) + + return wrap + + +def no_body(xstep): + @functools.wraps(xstep) + def wrap(self, *args, **kwargs): + if self.json_args is None: + raises.BadRequest(message.no_body()) + ret = yield gen.coroutine(xstep)(self, *args, **kwargs) + raise gen.Return(ret) + + return wrap + + +def miss_fields(xstep): + @functools.wraps(xstep) + def wrap(self, *args, **kwargs): + fields = kwargs.pop('miss_fields', []) + if fields: + for miss in fields: + miss_data = self.json_args.get(miss) + if miss_data is None or miss_data == '': + raises.BadRequest(message.missing(miss)) + ret = yield gen.coroutine(xstep)(self, *args, **kwargs) + raise gen.Return(ret) + return wrap + + +def carriers_exist(xstep): + @functools.wraps(xstep) + def wrap(self, *args, **kwargs): + carriers = kwargs.pop('carriers', {}) + if carriers: + for table, query in carriers: + exist = yield dbapi.db_find_one(table, query()) + if not exist: + raises.Forbidden(message.not_found(table, query())) + ret = yield gen.coroutine(xstep)(self, *args, **kwargs) + raise gen.Return(ret) + return wrap + + +def new_not_exists(xstep): + @functools.wraps(xstep) + def wrap(self, *args, **kwargs): + query = kwargs.get('query') + if query: + to_data = yield dbapi.db_find_one(self.table, query()) + if to_data: + raises.Forbidden(message.exist(self.table, query())) + ret = yield gen.coroutine(xstep)(self, *args, **kwargs) + raise gen.Return(ret) + return wrap + + +def updated_one_not_exist(xstep): + @functools.wraps(xstep) + def wrap(self, data, *args, **kwargs): + db_keys = kwargs.pop('db_keys', []) + query = self._update_query(db_keys, data) + if query: + to_data = yield dbapi.db_find_one(self.table, query) + if to_data: + raises.Forbidden(message.exist(self.table, query)) + ret = yield gen.coroutine(xstep)(self, data, *args, **kwargs) + raise gen.Return(ret) + return wrap diff --git a/opnfv_testapi/common/config.py b/opnfv_testapi/common/config.py new file mode 100644 index 0000000..75dbc35 --- /dev/null +++ b/opnfv_testapi/common/config.py @@ -0,0 +1,79 @@ +############################################################################## +# Copyright (c) 2015 Orange +# guyrodrigue.koffi@orange.com / koffirodrigue@gmail.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +# feng.xiaowei@zte.com.cn remove prepare_put_request 5-30-2016 +############################################################################## +import ConfigParser +import argparse +import os +import sys + + +class Config(object): + + def __init__(self): + self.config_file = None + self._set_config_file() + self._parse() + self._parse_per_page() + self.static_path = os.path.join( + os.path.dirname(os.path.normpath(__file__)), + os.pardir, + 'static') + self.base_path = "/home/testapi" + + def _parse(self): + if not os.path.exists(self.config_file): + raise Exception("%s not found" % self.config_file) + + config = ConfigParser.RawConfigParser() + config.read(self.config_file) + self._parse_section(config) + + def _parse_section(self, config): + [self._parse_item(config, section) for section in (config.sections())] + + def _parse_item(self, config, section): + [setattr(self, '{}_{}'.format(section, k), self._parse_value(v)) + for k, v in config.items(section)] + + def _parse_per_page(self): + if not hasattr(self, 'api_results_per_page'): + self.api_results_per_page = 20 + + @staticmethod + def _parse_value(value): + try: + value = int(value) + except: + if str(value).lower() == 'true': + value = True + elif str(value).lower() == 'false': + value = False + return value + + def _set_config_file(self): + if not self._set_sys_config_file(): + self._set_default_config_file() + + def _set_sys_config_file(self): + parser = argparse.ArgumentParser() + parser.add_argument("-c", "--config-file", dest='config_file', + help="Config file location", metavar="FILE") + args, _ = parser.parse_known_args(sys.argv) + try: + self.config_file = args.config_file + finally: + return self.config_file is not None + + def _set_default_config_file(self): + is_venv = os.getenv('VIRTUAL_ENV') + self.config_file = os.path.join('/' if not is_venv else is_venv, + 'etc/opnfv_testapi/config.ini') + + +CONF = Config() diff --git a/opnfv_testapi/common/message.py b/opnfv_testapi/common/message.py new file mode 100644 index 0000000..61ce03d --- /dev/null +++ b/opnfv_testapi/common/message.py @@ -0,0 +1,54 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corp +# feng.xiaowei@zte.com.cn +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +not_found_base = 'Could Not Found' +exist_base = 'Already Exists' + + +def key_error(key): + return "KeyError: '{}'".format(key) + + +def no_body(): + return 'No Body' + + +def not_found(key, value): + return '{} {} [{}]'.format(not_found_base, key, value) + + +def missing(name): + return '{} Missing'.format(name) + + +def exist(key, value): + return '{} [{}] {}'.format(key, value, exist_base) + + +def bad_format(error): + return 'Bad Format [{}]'.format(error) + + +def unauthorized(): + return 'No Authentication Header' + + +def invalid_token(): + return 'Invalid Token' + + +def no_update(): + return 'Nothing to update' + + +def must_int(name): + return '{} must be int'.format(name) + + +def no_auth(): + return 'No permission to operate. Please ask Administrator for details.' diff --git a/opnfv_testapi/common/raises.py b/opnfv_testapi/common/raises.py new file mode 100644 index 0000000..ec6b8a5 --- /dev/null +++ b/opnfv_testapi/common/raises.py @@ -0,0 +1,39 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corp +# feng.xiaowei@zte.com.cn +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +import httplib + +from tornado import web + + +class Raiser(object): + code = httplib.OK + + def __init__(self, reason): + raise web.HTTPError(self.code, reason) + + +class BadRequest(Raiser): + code = httplib.BAD_REQUEST + + +class Forbidden(Raiser): + code = httplib.FORBIDDEN + + +class NotFound(Raiser): + code = httplib.NOT_FOUND + + +class Unauthorized(Raiser): + code = httplib.UNAUTHORIZED + + +class CodeTBD(object): + def __init__(self, code, reason): + raise web.HTTPError(code, reason) diff --git a/opnfv_testapi/common/utils.py b/opnfv_testapi/common/utils.py new file mode 100644 index 0000000..107c709 --- /dev/null +++ b/opnfv_testapi/common/utils.py @@ -0,0 +1,43 @@ +import logging +import smtplib +from email.mime.text import MIMEText + +LOG = logging.getLogger(__name__) +LOG.setLevel(logging.DEBUG) + + +def send_email(subject, content): + MAIL_LIST = ['cvp@opnfv.org'] + HOST = "smtp.gmail.com" + USER = "opnfv.cvp" + PASSWD = "opnfv@cvp" + + sender = 'cvp<{}@gmail.com>'.format(USER) + msg = MIMEText(content, _subtype='plain') + msg['Subject'] = subject + msg['From'] = sender + msg['To'] = ";".join(MAIL_LIST) + + _send_email(HOST, sender, USER, PASSWD, MAIL_LIST, msg) + + +def _send_email(host, + sender, + user, + passwd, + receivers, + msg): + + client = smtplib.SMTP() + try: + client.connect(host, 25) + LOG.debug('Success to connect server') + client.starttls() + client.login(user, passwd) + LOG.debug('Success to login') + LOG.debug('Start to sending email') + client.sendmail(sender, receivers, msg.as_string()) + client.close() + except Exception: + LOG.exception('Error when sending email') + raise |