add proxy suuport and partial success into api

Change-Id: I167d57bfeac1805a2b4bb26f9de52d0ccceeba2b
This commit is contained in:
xiaodongwang 2014-08-24 00:18:29 -07:00
parent 7ea34feb85
commit 54a7bf9d09
5 changed files with 178 additions and 12 deletions

View File

@ -18,6 +18,7 @@ import datetime
import functools
import logging
import netaddr
import requests
import simplejson as json
from flask import flash
@ -48,6 +49,7 @@ from compass.db.api import user as user_api
from compass.db.api import user_log as user_log_api
from compass.utils import flags
from compass.utils import logsetting
from compass.utils import setting_wrapper as setting
from compass.utils import util
@ -2016,14 +2018,15 @@ def add_host_network(host_id):
)
@app.route("/hosts/networks", methods=['POST'])
@app.route("/hosts/networks", methods=['PUT'])
@log_user_action
@login_required
def add_host_networks():
def update_host_networks():
"""add host networks."""
data = _get_request_data_as_list()
return utils.make_json_response(
200, host_api.add_host_networks(current_user, data)
200, host_api.add_host_networks(
current_user, data)
)
@ -2175,6 +2178,121 @@ def take_host_action(host_id):
)
def _get_headers(*keys):
headers = {}
for key in keys:
if key in request.headers:
headers[key] = request.headers[key]
return headers
def _get_response_json(response):
try:
return response.json()
except ValueError:
return response.text
@app.route("/proxy/<path:url>", methods=['GET'])
@log_user_action
@login_required
def proxy_get(url):
"""proxy url."""
headers = _get_headers(
'Content-Type', 'Accept-Encoding',
'Content-Encoding', 'Accept', 'User-Agent',
'Content-MD5', 'Transfer-Encoding', app.config['AUTH_HEADER_NAME'],
'Cookie'
)
response = requests.get(
'%s/%s' % (setting.PROXY_URL_PREFIX, url),
params=_get_request_args(),
headers=headers,
stream=True
)
logging.debug(
'proxy %s response: %s',
url, response.text
)
return utils.make_json_response(
response.status_code, _get_response_json(response)
)
@app.route("/proxy/<path:url>", methods=['POST'])
@log_user_action
@login_required
def proxy_post(url):
"""proxy url."""
headers = _get_headers(
'Content-Type', 'Accept-Encoding',
'Content-Encoding', 'Accept', 'User-Agent',
'Content-MD5', 'Transfer-Encoding',
'Cookie'
)
response = requests.post(
'%s/%s' % (setting.PROXY_URL_PREFIX, url),
data=request.data,
headers=headers
)
logging.debug(
'proxy %s response: %s',
url, response.text
)
return utils.make_json_response(
response.status_code, _get_response_json(response)
)
@app.route("/proxy/<path:url>", methods=['PUT'])
@log_user_action
@login_required
def proxy_put(url):
"""proxy url."""
headers = _get_headers(
'Content-Type', 'Accept-Encoding',
'Content-Encoding', 'Accept', 'User-Agent',
'Content-MD5', 'Transfer-Encoding',
'Cookie'
)
response = requests.put(
'%s/%s' % (setting.PROXY_URL_PREFIX, url),
data=request.data,
headers=headers
)
logging.debug(
'proxy %s response: %s',
url, response.text
)
return utils.make_json_response(
response.status_code, _get_response_json(response)
)
@app.route("/proxy/<path:url>", methods=['DELETE'])
@log_user_action
@login_required
def proxy_delete(url):
"""proxy url."""
headers = _get_headers(
'Content-Type', 'Accept-Encoding',
'Content-Encoding', 'Accept', 'User-Agent',
'Content-MD5', 'Transfer-Encoding',
'Cookie'
)
response = requests.delete(
'%s/%s' % (setting.PROXY_URL_PREFIX, url),
headers=headers
)
logging.debug(
'proxy %s response: %s',
url, response.text
)
return utils.make_json_response(
response.status_code, _get_response_json(response)
)
def init():
logging.info('init flask')
database.init()

View File

@ -27,6 +27,9 @@ class HTTPException(Exception):
self.traceback = traceback.format_exc()
self.status_code = status_code
def to_dict(self):
return {'message': str(self)}
class ItemNotFound(HTTPException):
"""Define the exception for referring non-existing object."""
@ -78,8 +81,11 @@ class ConflictObject(HTTPException):
@app.errorhandler(Exception)
def handle_exception(error):
response = {'message': str(error)}
if hasattr(error, 'traceback'):
if hasattr(error, 'to_dict'):
response = error.to_dict()
else:
response = {'message': str(error)}
if app.debug and hasattr(error, 'traceback'):
response['traceback'] = error.traceback
status_code = 400

View File

@ -539,22 +539,36 @@ def add_host_network(
)
def add_host_networks(
session, creator,
exception_when_existing=True,
exception_when_existing=False,
data=[]
):
"""Create host networks."""
hosts = []
failed_hosts = []
for host_data in data:
host_id = host_data['host_id']
networks = host_data['networks']
host_networks = []
hosts.append({'host_id': host_id, 'networks': host_networks})
failed_host_networks = []
for network in networks:
host_networks.append(_add_host_network(
session, creator, host_id, exception_when_existing,
**network
))
return hosts
try:
host_networks.append(_add_host_network(
session, creator, host_id, exception_when_existing,
**network
))
except exception.DatabaseException as error:
logging.exception(error)
failed_host_networks.append(network)
if host_networks:
hosts.append({'host_id': host_id, 'networks': host_networks})
if failed_host_networks:
failed_hosts.append({
'host_id': host_id, 'networks': failed_host_networks
})
return {
'hosts': hosts,
'failed_hosts': failed_hosts
}
@utils.supported_filters(

View File

@ -22,6 +22,9 @@ class DatabaseException(Exception):
self.traceback = traceback.format_exc()
self.status_code = 400
def to_dict(self):
return {'message': str(self)}
class RecordNotExists(DatabaseException):
"""Define the exception for referring non-existing object in DB."""
@ -82,3 +85,26 @@ class InvalidResponse(DatabaseException):
def __init__(self, message):
super(InvalidResponse, self).__init__(message)
self.status_code = 400
class MultiDatabaseException(DatabaseException):
"""Define the exception composites with multi exceptions."""
def __init__(self, exceptions):
super(MultiDatabaseException, self).__init__('multi exceptions')
self.exceptions = exceptions
self.status_code = 400
@property
def traceback(self):
tracebacks = []
for exception in self.exceptions:
tracebacks.append(exception.trackback)
def to_dict(self):
dict_info = super(MultiDatabaseException, self).to_dict()
dict_info.update({
'exceptions': [
exception.to_dict() for exception in self.exceptions
]
})
return dict_info

View File

@ -99,6 +99,8 @@ VALIDATOR_DIR = lazypy.delay(
TMPL_DIR = lazypy.delay(
lambda: os.path.join(CONFIG_DIR, 'templates')
)
PROXY_URL_PREFIX = 'http://10.145.81.205:5000'
if (
'COMPASS_IGNORE_SETTING' in os.environ and
os.environ['COMPASS_IGNORE_SETTING']