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 functools
import logging import logging
import netaddr import netaddr
import requests
import simplejson as json import simplejson as json
from flask import flash 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.db.api import user_log as user_log_api
from compass.utils import flags from compass.utils import flags
from compass.utils import logsetting from compass.utils import logsetting
from compass.utils import setting_wrapper as setting
from compass.utils import util 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 @log_user_action
@login_required @login_required
def add_host_networks(): def update_host_networks():
"""add host networks.""" """add host networks."""
data = _get_request_data_as_list() data = _get_request_data_as_list()
return utils.make_json_response( 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(): def init():
logging.info('init flask') logging.info('init flask')
database.init() database.init()

View File

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

View File

@ -539,22 +539,36 @@ def add_host_network(
) )
def add_host_networks( def add_host_networks(
session, creator, session, creator,
exception_when_existing=True, exception_when_existing=False,
data=[] data=[]
): ):
"""Create host networks.""" """Create host networks."""
hosts = [] hosts = []
failed_hosts = []
for host_data in data: for host_data in data:
host_id = host_data['host_id'] host_id = host_data['host_id']
networks = host_data['networks'] networks = host_data['networks']
host_networks = [] host_networks = []
hosts.append({'host_id': host_id, 'networks': host_networks}) failed_host_networks = []
for network in networks: for network in networks:
try:
host_networks.append(_add_host_network( host_networks.append(_add_host_network(
session, creator, host_id, exception_when_existing, session, creator, host_id, exception_when_existing,
**network **network
)) ))
return hosts 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( @utils.supported_filters(

View File

@ -22,6 +22,9 @@ class DatabaseException(Exception):
self.traceback = traceback.format_exc() self.traceback = traceback.format_exc()
self.status_code = 400 self.status_code = 400
def to_dict(self):
return {'message': str(self)}
class RecordNotExists(DatabaseException): class RecordNotExists(DatabaseException):
"""Define the exception for referring non-existing object in DB.""" """Define the exception for referring non-existing object in DB."""
@ -82,3 +85,26 @@ class InvalidResponse(DatabaseException):
def __init__(self, message): def __init__(self, message):
super(InvalidResponse, self).__init__(message) super(InvalidResponse, self).__init__(message)
self.status_code = 400 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( TMPL_DIR = lazypy.delay(
lambda: os.path.join(CONFIG_DIR, 'templates') lambda: os.path.join(CONFIG_DIR, 'templates')
) )
PROXY_URL_PREFIX = 'http://10.145.81.205:5000'
if ( if (
'COMPASS_IGNORE_SETTING' in os.environ and 'COMPASS_IGNORE_SETTING' in os.environ and
os.environ['COMPASS_IGNORE_SETTING'] os.environ['COMPASS_IGNORE_SETTING']