Disable DEPRECATED API versions by default
API v1.0 has been deprecated for a while and v1.1 will be deprecated soon. We shouldn't be enabling deprecated API versions by default. This patch adds a decorator to disable deprecated APIs by default unless they have been explicitly enabled in the environment. Co-Authored-By: Fei Long Wang <flwang@catalyst.net.nz> Change-Id: I62fb4d18bc6c9f5455bff0d56e42269b4590b454
This commit is contained in:
parent
9f5b518150
commit
f38cecfdfc
@ -84,6 +84,7 @@ function configure_zaqar {
|
|||||||
iniset $ZAQAR_CONF DEFAULT debug True
|
iniset $ZAQAR_CONF DEFAULT debug True
|
||||||
iniset $ZAQAR_CONF DEFAULT unreliable True
|
iniset $ZAQAR_CONF DEFAULT unreliable True
|
||||||
iniset $ZAQAR_CONF DEFAULT admin_mode True
|
iniset $ZAQAR_CONF DEFAULT admin_mode True
|
||||||
|
iniset $ZAQAR_CONF DEFAULT enable_deprecated_api_versions 1
|
||||||
iniset $ZAQAR_CONF signed_url secret_key notreallysecret
|
iniset $ZAQAR_CONF signed_url secret_key notreallysecret
|
||||||
|
|
||||||
if is_service_enabled key; then
|
if is_service_enabled key; then
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Currently, the v1 API is still accessible though it has been deprecated
|
||||||
|
for a while. And we're going to deprecate v1.1 soon. To keep the backward
|
||||||
|
compatibility, a new config option - ``enable_deprecated_api_versions``
|
||||||
|
is added so that operator can totally turn off an API version or still
|
||||||
|
support it by adding the API version to the list of the new config option.
|
@ -31,6 +31,10 @@ _GENERAL_OPTIONS = (
|
|||||||
deprecated_opts=[cfg.DeprecatedOpt('sharding')]),
|
deprecated_opts=[cfg.DeprecatedOpt('sharding')]),
|
||||||
cfg.BoolOpt('unreliable', default=False,
|
cfg.BoolOpt('unreliable', default=False,
|
||||||
help='Disable all reliability constraints.'),
|
help='Disable all reliability constraints.'),
|
||||||
|
cfg.ListOpt('enable_deprecated_api_versions', default=[],
|
||||||
|
item_type=cfg.types.List(item_type=cfg.types.String(
|
||||||
|
choices=('1', '1.1'))),
|
||||||
|
help='List of deprecated API versions to enable.'),
|
||||||
)
|
)
|
||||||
|
|
||||||
_DRIVER_OPTIONS = (
|
_DRIVER_OPTIONS = (
|
||||||
|
@ -20,6 +20,9 @@ from oslo_cache import core
|
|||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
|
|
||||||
|
from zaqar.i18n import _LW
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -183,3 +186,35 @@ def lazy_property(write=False, delete=True):
|
|||||||
fdel=delete and deleter,
|
fdel=delete and deleter,
|
||||||
doc=fn.__doc__)
|
doc=fn.__doc__)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def api_version_manager(version_info):
|
||||||
|
"""Manage API versions based on their status
|
||||||
|
|
||||||
|
This decorator disables `DEPRECATED` APIs by default unless the user
|
||||||
|
explicitly enables it by adding it to the `enable_deprecated_api_versions`
|
||||||
|
configuration option.
|
||||||
|
|
||||||
|
:param version_info: Dictionary containing the API version info.
|
||||||
|
"""
|
||||||
|
api_version = version_info['id']
|
||||||
|
api_updated = version_info['updated']
|
||||||
|
deprecated = version_info['status'] == 'DEPRECATED'
|
||||||
|
|
||||||
|
def wrapper(fn):
|
||||||
|
@functools.wraps(fn)
|
||||||
|
def register_api(driver, conf):
|
||||||
|
if (deprecated and
|
||||||
|
[api_version] not in conf.enable_deprecated_api_versions):
|
||||||
|
return None
|
||||||
|
|
||||||
|
if deprecated:
|
||||||
|
LOG.warning(_LW('Enabling API version %(version)s. '
|
||||||
|
'This version was marked as deprecated in '
|
||||||
|
'%(updated)s. Using it may expose security '
|
||||||
|
'issues, unexpected behavior or damage your '
|
||||||
|
'data.') % {'version': api_version,
|
||||||
|
'updated': api_updated})
|
||||||
|
return fn(driver, conf)
|
||||||
|
return register_api
|
||||||
|
return wrapper
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
debug = False
|
debug = False
|
||||||
verbose = False
|
verbose = False
|
||||||
admin_mode = False
|
admin_mode = False
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
debug = False
|
debug = False
|
||||||
verbose = False
|
verbose = False
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = invalid
|
transport = invalid
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
# run_tests = True
|
# run_tests = True
|
||||||
unreliable = True
|
unreliable = True
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[zaqar]
|
[zaqar]
|
||||||
# url = http://0.0.0.0:8888
|
# url = http://0.0.0.0:8888
|
||||||
|
@ -5,6 +5,8 @@ verbose = True
|
|||||||
# Show debugging output in logs (sets DEBUG log level output)
|
# Show debugging output in logs (sets DEBUG log level output)
|
||||||
debug = True
|
debug = True
|
||||||
|
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
# Log to this file!
|
# Log to this file!
|
||||||
; log_file = /var/log/zaqar/server.log
|
; log_file = /var/log/zaqar/server.log
|
||||||
|
|
||||||
@ -20,6 +22,7 @@ debug = True
|
|||||||
;syslog_log_facility = LOG_LOCAL0
|
;syslog_log_facility = LOG_LOCAL0
|
||||||
|
|
||||||
unreliable = True
|
unreliable = True
|
||||||
|
enable_deprecated_api_versions = 1, 1.1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
# Transport driver module (e.g., wsgi, zmq)
|
# Transport driver module (e.g., wsgi, zmq)
|
||||||
|
@ -3,6 +3,7 @@ auth_strategy = keystone
|
|||||||
|
|
||||||
debug = False
|
debug = False
|
||||||
verbose = False
|
verbose = False
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
unreliable = True
|
unreliable = True
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
auth_strategy = keystone
|
auth_strategy = keystone
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
unreliable = True
|
unreliable = True
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
debug = False
|
debug = False
|
||||||
verbose = False
|
verbose = False
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
debug = False
|
debug = False
|
||||||
verbose = False
|
verbose = False
|
||||||
unreliable = True
|
unreliable = True
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
debug = False
|
debug = False
|
||||||
verbose = False
|
verbose = False
|
||||||
unreliable = True
|
unreliable = True
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
message_store = mongodb
|
message_store = mongodb
|
@ -2,6 +2,7 @@
|
|||||||
pooling = True
|
pooling = True
|
||||||
admin_mode = True
|
admin_mode = True
|
||||||
unreliable = True
|
unreliable = True
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
message_store = mongodb
|
message_store = mongodb
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
debug = False
|
debug = False
|
||||||
verbose = False
|
verbose = False
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
pooling = True
|
pooling = True
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
debug = False
|
debug = False
|
||||||
verbose = False
|
verbose = False
|
||||||
admin_mode = False
|
admin_mode = False
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
pooling = True
|
pooling = True
|
||||||
admin_mode = True
|
admin_mode = True
|
||||||
|
enable_deprecated_api_versions = 1
|
||||||
|
|
||||||
[drivers]
|
[drivers]
|
||||||
transport = wsgi
|
transport = wsgi
|
||||||
|
@ -18,12 +18,17 @@ from oslo_cache import core
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from zaqar.common import cache as oslo_cache
|
from zaqar.common import cache as oslo_cache
|
||||||
|
from zaqar.common import configs
|
||||||
from zaqar.common import decorators
|
from zaqar.common import decorators
|
||||||
from zaqar.tests import base
|
from zaqar.tests import base
|
||||||
|
|
||||||
|
|
||||||
class TestDecorators(base.TestBase):
|
class TestDecorators(base.TestBase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestDecorators, self).setUp()
|
||||||
|
self.conf.register_opts(configs._GENERAL_OPTIONS)
|
||||||
|
|
||||||
def test_memoized_getattr(self):
|
def test_memoized_getattr(self):
|
||||||
|
|
||||||
class TestClass(object):
|
class TestClass(object):
|
||||||
@ -141,3 +146,40 @@ class TestDecorators(base.TestBase):
|
|||||||
|
|
||||||
self.assertEqual(name, user)
|
self.assertEqual(name, user)
|
||||||
self.assertEqual(2 + i, instance.user_gets)
|
self.assertEqual(2 + i, instance.user_gets)
|
||||||
|
|
||||||
|
def test_api_version_manager(self):
|
||||||
|
self.config(enable_deprecated_api_versions=[])
|
||||||
|
# 1. Test accessing current API version
|
||||||
|
VERSION = {
|
||||||
|
'id': '1',
|
||||||
|
'status': 'CURRENT',
|
||||||
|
'updated': 'Just yesterday'
|
||||||
|
}
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
|
def public_endpoint_1(driver, conf):
|
||||||
|
return True
|
||||||
|
|
||||||
|
self.assertTrue(public_endpoint_1(None, self.conf))
|
||||||
|
|
||||||
|
# 2. Test accessing deprecated API version
|
||||||
|
VERSION = {
|
||||||
|
'id': '1',
|
||||||
|
'status': 'DEPRECATED',
|
||||||
|
'updated': 'A long time ago'
|
||||||
|
}
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
|
def public_endpoint_2(driver, conf):
|
||||||
|
self.fail('Deprecated API enabled')
|
||||||
|
|
||||||
|
public_endpoint_2(None, self.conf)
|
||||||
|
|
||||||
|
# 3. Test enabling deprecated API version
|
||||||
|
self.config(enable_deprecated_api_versions=[['1']])
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
|
def public_endpoint_3(driver, conf):
|
||||||
|
return True
|
||||||
|
|
||||||
|
self.assertTrue(public_endpoint_3(None, self.conf))
|
||||||
|
@ -131,8 +131,9 @@ class Driver(transport.DriverBase):
|
|||||||
self.app.add_error_handler(Exception, self._error_handler)
|
self.app.add_error_handler(Exception, self._error_handler)
|
||||||
|
|
||||||
for version_path, endpoints in catalog:
|
for version_path, endpoints in catalog:
|
||||||
for route, resource in endpoints:
|
if endpoints:
|
||||||
self.app.add_route(version_path + route, resource)
|
for route, resource in endpoints:
|
||||||
|
self.app.add_route(version_path + route, resource)
|
||||||
|
|
||||||
def _init_middleware(self):
|
def _init_middleware(self):
|
||||||
"""Initialize WSGI middlewarez."""
|
"""Initialize WSGI middlewarez."""
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from zaqar.common import decorators
|
||||||
from zaqar.transport.wsgi.v1_0 import claims
|
from zaqar.transport.wsgi.v1_0 import claims
|
||||||
from zaqar.transport.wsgi.v1_0 import health
|
from zaqar.transport.wsgi.v1_0 import health
|
||||||
from zaqar.transport.wsgi.v1_0 import homedoc
|
from zaqar.transport.wsgi.v1_0 import homedoc
|
||||||
@ -46,10 +47,8 @@ VERSION = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
def public_endpoints(driver, conf):
|
def public_endpoints(driver, conf):
|
||||||
LOG.warning('Zaqar\'s API version 1.0 will be turned off by default '
|
|
||||||
'during the Newton cycle')
|
|
||||||
|
|
||||||
queue_controller = driver._storage.queue_controller
|
queue_controller = driver._storage.queue_controller
|
||||||
message_controller = driver._storage.message_controller
|
message_controller = driver._storage.message_controller
|
||||||
claim_controller = driver._storage.claim_controller
|
claim_controller = driver._storage.claim_controller
|
||||||
@ -96,6 +95,7 @@ def public_endpoints(driver, conf):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
def private_endpoints(driver, conf):
|
def private_endpoints(driver, conf):
|
||||||
if not conf.pooling:
|
if not conf.pooling:
|
||||||
return []
|
return []
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from zaqar.common import decorators
|
||||||
from zaqar.transport.wsgi.v1_1 import claims
|
from zaqar.transport.wsgi.v1_1 import claims
|
||||||
from zaqar.transport.wsgi.v1_1 import flavors
|
from zaqar.transport.wsgi.v1_1 import flavors
|
||||||
from zaqar.transport.wsgi.v1_1 import health
|
from zaqar.transport.wsgi.v1_1 import health
|
||||||
@ -47,6 +48,7 @@ VERSION = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
def public_endpoints(driver, conf):
|
def public_endpoints(driver, conf):
|
||||||
LOG.warning('Zaqar\'s API version 1.1 will enter deprecation during the '
|
LOG.warning('Zaqar\'s API version 1.1 will enter deprecation during the '
|
||||||
'Newton cycle. As part of that, it will be marked as '
|
'Newton cycle. As part of that, it will be marked as '
|
||||||
@ -104,6 +106,7 @@ def public_endpoints(driver, conf):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
def private_endpoints(driver, conf):
|
def private_endpoints(driver, conf):
|
||||||
|
|
||||||
catalogue = [
|
catalogue = [
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations under
|
# License for the specific language governing permissions and limitations under
|
||||||
# the License.
|
# the License.
|
||||||
|
|
||||||
|
from zaqar.common import decorators
|
||||||
from zaqar.transport.wsgi.v2_0 import claims
|
from zaqar.transport.wsgi.v2_0 import claims
|
||||||
from zaqar.transport.wsgi.v2_0 import flavors
|
from zaqar.transport.wsgi.v2_0 import flavors
|
||||||
from zaqar.transport.wsgi.v2_0 import health
|
from zaqar.transport.wsgi.v2_0 import health
|
||||||
@ -44,6 +45,7 @@ VERSION = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
def public_endpoints(driver, conf):
|
def public_endpoints(driver, conf):
|
||||||
queue_controller = driver._storage.queue_controller
|
queue_controller = driver._storage.queue_controller
|
||||||
message_controller = driver._storage.message_controller
|
message_controller = driver._storage.message_controller
|
||||||
@ -117,6 +119,7 @@ def public_endpoints(driver, conf):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@decorators.api_version_manager(VERSION)
|
||||||
def private_endpoints(driver, conf):
|
def private_endpoints(driver, conf):
|
||||||
|
|
||||||
catalogue = [
|
catalogue = [
|
||||||
|
Loading…
Reference in New Issue
Block a user