Add support for Host header in REST queries
Can use host request headers if enable_host_header is set to true in config file. If host header is not specified or host header is turned off, it will use the default api_base_uri. Also added unit tests. Change-Id: Ia353c116485f3e7112bcfde11457cdf7fe006422 Closes-bug: 1446387
This commit is contained in:
parent
1175e59d46
commit
1e266b1634
@ -25,6 +25,8 @@ cfg.CONF.register_opts([
|
||||
help='Number of api worker processes to spawn'),
|
||||
cfg.IntOpt('threads', default=1000,
|
||||
help='Number of api greenthreads to spawn'),
|
||||
cfg.BoolOpt('enable-host-header', default=False,
|
||||
help='Enable host request headers'),
|
||||
cfg.StrOpt('api-base-uri', default='http://127.0.0.1:9001/'),
|
||||
cfg.StrOpt('api_host', default='0.0.0.0',
|
||||
help='API Host'),
|
||||
|
@ -16,6 +16,8 @@
|
||||
import flask
|
||||
from oslo_config import cfg
|
||||
|
||||
cfg.CONF.import_opt('enable_host_header', 'designate.api', group='service:api')
|
||||
|
||||
|
||||
def factory(global_config, **local_conf):
|
||||
app = flask.Flask('designate.api.versions')
|
||||
@ -24,24 +26,32 @@ def factory(global_config, **local_conf):
|
||||
|
||||
base = cfg.CONF['service:api'].api_base_uri.rstrip('/')
|
||||
|
||||
def _version(version, status):
|
||||
def _host_header_links():
|
||||
del versions[:]
|
||||
host_url = flask.request.host_url
|
||||
_version('v1', 'DEPRECATED', host_url)
|
||||
_version('v2', 'CURRENT', host_url)
|
||||
|
||||
def _version(version, status, base_uri):
|
||||
versions.append({
|
||||
'id': '%s' % version,
|
||||
'status': status,
|
||||
'links': [{
|
||||
'href': base + '/' + version,
|
||||
'href': base_uri + '/' + version,
|
||||
'rel': 'self'
|
||||
}]
|
||||
})
|
||||
|
||||
if cfg.CONF['service:api'].enable_api_v1:
|
||||
_version('v1', 'DEPRECATED')
|
||||
_version('v1', 'DEPRECATED', base)
|
||||
|
||||
if cfg.CONF['service:api'].enable_api_v2:
|
||||
_version('v2', 'CURRENT')
|
||||
_version('v2', 'CURRENT', base)
|
||||
|
||||
@app.route('/', methods=['GET'])
|
||||
def version_list():
|
||||
if cfg.CONF['service:api'].enable_host_header:
|
||||
_host_header_links()
|
||||
|
||||
return flask.jsonify({
|
||||
"versions": {
|
||||
|
@ -21,6 +21,7 @@ from designate.objects import base as obj_base
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
cfg.CONF.import_opt('api_base_uri', 'designate.api', group='service:api')
|
||||
cfg.CONF.import_opt('enable_host_header', 'designate.api', group='service:api')
|
||||
|
||||
|
||||
class APIv2Adapter(base.DesignateAdapter):
|
||||
@ -77,8 +78,16 @@ class APIv2Adapter(base.DesignateAdapter):
|
||||
|
||||
@classmethod
|
||||
def _get_resource_links(cls, object, request):
|
||||
if cfg.CONF['service:api'].enable_host_header:
|
||||
try:
|
||||
base_uri = request.host_url
|
||||
except Exception:
|
||||
base_uri = cls.BASE_URI
|
||||
else:
|
||||
base_uri = cls.BASE_URI
|
||||
|
||||
return {'self': '%s%s/%s' %
|
||||
(cls.BASE_URI, cls._get_path(request), object.id)}
|
||||
(base_uri, cls._get_path(request), object.id)}
|
||||
|
||||
@classmethod
|
||||
def _get_path(cls, request):
|
||||
@ -119,8 +128,16 @@ class APIv2Adapter(base.DesignateAdapter):
|
||||
if extra_params is not None:
|
||||
params.update(extra_params)
|
||||
|
||||
if cfg.CONF['service:api'].enable_host_header:
|
||||
try:
|
||||
base_uri = request.host_url
|
||||
except Exception:
|
||||
base_uri = cls.BASE_URI
|
||||
else:
|
||||
base_uri = cls.BASE_URI
|
||||
|
||||
href = "%s%s?%s" % (
|
||||
cls.BASE_URI,
|
||||
base_uri,
|
||||
cls._get_path(request),
|
||||
parse.urlencode(params))
|
||||
|
||||
|
52
designate/tests/test_api/test_v2/test_hostheaders.py
Normal file
52
designate/tests/test_api/test_v2/test_hostheaders.py
Normal file
@ -0,0 +1,52 @@
|
||||
# Copyright (c) 2015 Rackspace Hosting
|
||||
#
|
||||
# Author: Mimi Lee <mimi.lee@rackspace.com>
|
||||
#
|
||||
# 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.
|
||||
|
||||
from designate.tests.test_api.test_v2 import ApiV2TestCase
|
||||
|
||||
|
||||
class ApiV2HostHeadersTest(ApiV2TestCase):
|
||||
def setUp(self):
|
||||
super(ApiV2HostHeadersTest, self).setUp()
|
||||
|
||||
# Ensure v2 API and host headers are enabled
|
||||
self.config(enable_api_v2=True, group='service:api')
|
||||
self.config(enable_host_header=True, group='service:api')
|
||||
|
||||
def test_host_header(self):
|
||||
# Create a zone with host header
|
||||
fixture = self.get_domain_fixture(fixture=0)
|
||||
response = self.client.post_json('/zones/',
|
||||
fixture,
|
||||
headers={'Host': 'testhost.com'})
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(202, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the host request header url
|
||||
self.assertTrue('http://testhost.com/zones/' in
|
||||
response.json_body['links']['self'])
|
||||
|
||||
# Get zone with host header
|
||||
response = self.client.get('/zones/',
|
||||
headers={'Host': 'testhost.com'})
|
||||
|
||||
# Check the headers are what we expect
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
|
||||
# Check the host request header url
|
||||
self.assertTrue('http://testhost.com/zones' in
|
||||
response.json_body['links']['self'])
|
@ -84,6 +84,9 @@ debug = False
|
||||
# Number of api greenthreads to spawn
|
||||
#threads = 1000
|
||||
|
||||
# Enable host request headers
|
||||
#enable_host_header = False
|
||||
|
||||
# The base uri used in responses
|
||||
#api_base_uri = 'http://127.0.0.1:9001/'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user