remove os-disk-config part 4
There are no test changes as all new code is tested by the extension_info functional tests, and should we want to eliminate the extension_info portion of our API later, new tests would just make this much harder to tear down. This modifies default policy to drop os-disk-config as well as modifying extension tests to pass even though we're injecting additional hardcoded items into the list for compatibility. Part of bp:api-no-more-extensions Change-Id: I0192ccef7e858fd0ff15c339f683abaabbdc09b7
This commit is contained in:
parent
fbc3c5ab3c
commit
525285eb1c
@ -65,8 +65,6 @@
|
||||
"os_compute_api:os-create-backup": "rule:admin_or_owner",
|
||||
"os_compute_api:os-deferred-delete": "rule:admin_or_owner",
|
||||
"os_compute_api:os-deferred-delete:discoverable": "@",
|
||||
"os_compute_api:os-disk-config": "rule:admin_or_owner",
|
||||
"os_compute_api:os-disk-config:discoverable": "@",
|
||||
"os_compute_api:os-evacuate": "rule:admin_api",
|
||||
"os_compute_api:os-evacuate:discoverable": "@",
|
||||
"os_compute_api:os-extended-server-attributes": "rule:admin_api",
|
||||
|
@ -1,53 +0,0 @@
|
||||
# Copyright 2011 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Disk Config extension."""
|
||||
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
from nova.i18n import _
|
||||
|
||||
ALIAS = 'os-disk-config'
|
||||
API_DISK_CONFIG = "OS-DCF:diskConfig"
|
||||
INTERNAL_DISK_CONFIG = "auto_disk_config"
|
||||
authorize = extensions.os_compute_soft_authorizer(ALIAS)
|
||||
|
||||
|
||||
def disk_config_to_api(value):
|
||||
return 'AUTO' if value else 'MANUAL'
|
||||
|
||||
|
||||
def disk_config_from_api(value):
|
||||
if value == 'AUTO':
|
||||
return True
|
||||
elif value == 'MANUAL':
|
||||
return False
|
||||
else:
|
||||
msg = _("%s must be either 'MANUAL' or 'AUTO'.") % API_DISK_CONFIG
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
|
||||
class DiskConfig(extensions.V21APIExtensionBase):
|
||||
"""Disk Management Extension."""
|
||||
|
||||
name = "DiskConfig"
|
||||
alias = ALIAS
|
||||
version = 1
|
||||
|
||||
def get_controller_extensions(self):
|
||||
return []
|
||||
|
||||
def get_resources(self):
|
||||
return []
|
@ -99,6 +99,18 @@ v21_to_v2_alias_mapping = {
|
||||
'os-instance-usage-audit-log': 'os-instance_usage_audit_log',
|
||||
}
|
||||
|
||||
# NOTE(sdague): this is the list of extension metadata that we display
|
||||
# to the user for features that we provide. This exists for legacy
|
||||
# purposes because applications were once asked to look for these
|
||||
# things to decide if a feature is enabled. As we remove extensions
|
||||
# completely from the code we're going to have a static list here to
|
||||
# keep the surface metadata the same.
|
||||
hardcoded_extensions = [
|
||||
{'name': 'DiskConfig',
|
||||
'alias': 'os-disk-config',
|
||||
'description': 'Disk Management Extension.'}
|
||||
]
|
||||
|
||||
# V2.1 does not support XML but we need to keep an entry in the
|
||||
# /extensions information returned to the user for backwards
|
||||
# compatibility
|
||||
@ -107,10 +119,10 @@ FAKE_UPDATED_DATE = "2014-12-03T00:00:00Z"
|
||||
|
||||
|
||||
class FakeExtension(object):
|
||||
def __init__(self, name, alias):
|
||||
def __init__(self, name, alias, description=""):
|
||||
self.name = name
|
||||
self.alias = alias
|
||||
self.__doc__ = ""
|
||||
self.__doc__ = description
|
||||
self.version = -1
|
||||
|
||||
|
||||
@ -129,8 +141,8 @@ class ExtensionInfoController(wsgi.Controller):
|
||||
ext_data["links"] = []
|
||||
return ext_data
|
||||
|
||||
def _create_fake_ext(self, alias, name):
|
||||
return FakeExtension(alias, name)
|
||||
def _create_fake_ext(self, name, alias, description=""):
|
||||
return FakeExtension(name, alias, description)
|
||||
|
||||
def _add_vif_extension(self, discoverable_extensions):
|
||||
vif_extension = {}
|
||||
@ -144,6 +156,14 @@ class ExtensionInfoController(wsgi.Controller):
|
||||
"""Filter extensions list based on policy."""
|
||||
|
||||
discoverable_extensions = dict()
|
||||
|
||||
for item in hardcoded_extensions:
|
||||
discoverable_extensions[item['alias']] = self._create_fake_ext(
|
||||
item['name'],
|
||||
item['alias'],
|
||||
item['description']
|
||||
)
|
||||
|
||||
for alias, ext in six.iteritems(self.extension_info.get_extensions()):
|
||||
authorize = extensions.os_compute_soft_authorizer(alias)
|
||||
if authorize(context, action='discoverable'):
|
||||
|
61
nova/api/openstack/compute/helpers.py
Normal file
61
nova/api/openstack/compute/helpers.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright 2016 HPE, Inc.
|
||||
#
|
||||
# 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 webob import exc
|
||||
|
||||
from nova.i18n import _
|
||||
|
||||
API_DISK_CONFIG = "OS-DCF:diskConfig"
|
||||
|
||||
|
||||
def disk_config_from_api(value):
|
||||
if value == 'AUTO':
|
||||
return True
|
||||
elif value == 'MANUAL':
|
||||
return False
|
||||
else:
|
||||
msg = _("%s must be either 'MANUAL' or 'AUTO'.") % API_DISK_CONFIG
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
|
||||
def translate_attributes(server_dict, operation_kwargs):
|
||||
"""Translate REST attributes on create to server object kwargs.
|
||||
|
||||
Our REST API is relatively fixed, but internal representations
|
||||
change over time, this is a translator for inbound REST request
|
||||
attributes that modifies the server dict that we get and adds
|
||||
appropriate attributes to ``operation_kwargs`` that will be passed
|
||||
down to instance objects later.
|
||||
|
||||
It's done in a common function as this is used for create / resize
|
||||
/ rebuild / update
|
||||
|
||||
The ``server_dict`` is a representation of the server in
|
||||
question. During ``create`` and ``update`` operations this will
|
||||
actually be the ``server`` element of the request body.
|
||||
|
||||
During actions, such as ``rebuild`` and ``resize`` this will be
|
||||
the attributes passed to the action object during the
|
||||
operation. This is equivalent to the ``server`` object.
|
||||
|
||||
Not all operations support all attributes listed here. Which is
|
||||
why it's important to only set operation_kwargs if there is
|
||||
something to set. Input validation will ensure that we are only
|
||||
operating on appropriate attributes for each operation.
|
||||
"""
|
||||
# Disk config
|
||||
auto_disk_config_raw = server_dict.pop(API_DISK_CONFIG, None)
|
||||
if auto_disk_config_raw is not None:
|
||||
auto_disk_config = disk_config_from_api(auto_disk_config_raw)
|
||||
operation_kwargs['auto_disk_config'] = auto_disk_config
|
@ -29,7 +29,7 @@ from webob import exc
|
||||
|
||||
from nova.api.openstack import api_version_request
|
||||
from nova.api.openstack import common
|
||||
from nova.api.openstack.compute import disk_config
|
||||
from nova.api.openstack.compute import helpers
|
||||
from nova.api.openstack.compute.schemas import servers as schema_servers
|
||||
from nova.api.openstack.compute.views import servers as views_servers
|
||||
from nova.api.openstack import extensions
|
||||
@ -55,16 +55,6 @@ CONF = nova.conf.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def translate_attributes(server_dict, server_kwargs):
|
||||
# Disk config
|
||||
# Translate create kwargs to internal representation
|
||||
auto_disk_config_raw = server_dict.pop("OS-DCF:diskConfig", None)
|
||||
if auto_disk_config_raw is not None:
|
||||
auto_disk_config = disk_config.disk_config_from_api(
|
||||
auto_disk_config_raw)
|
||||
server_kwargs['auto_disk_config'] = auto_disk_config
|
||||
|
||||
|
||||
class ServersController(wsgi.Controller):
|
||||
"""The Server API base controller class for the OpenStack API."""
|
||||
|
||||
@ -567,7 +557,7 @@ class ServersController(wsgi.Controller):
|
||||
|
||||
availability_zone = create_kwargs.pop("availability_zone", None)
|
||||
|
||||
translate_attributes(server_dict, create_kwargs)
|
||||
helpers.translate_attributes(server_dict, create_kwargs)
|
||||
|
||||
target = {
|
||||
'project_id': context.project_id,
|
||||
@ -815,7 +805,7 @@ class ServersController(wsgi.Controller):
|
||||
self.update_extension_manager.map(self._update_extension_point,
|
||||
body['server'], update_dict)
|
||||
|
||||
translate_attributes(body['server'], update_dict)
|
||||
helpers.translate_attributes(body['server'], update_dict)
|
||||
|
||||
instance = self._get_server(ctxt, req, id, is_detail=True)
|
||||
try:
|
||||
@ -980,7 +970,7 @@ class ServersController(wsgi.Controller):
|
||||
flavor_ref = str(resize_dict["flavorRef"])
|
||||
|
||||
resize_kwargs = {}
|
||||
translate_attributes(resize_dict, resize_kwargs)
|
||||
helpers.translate_attributes(resize_dict, resize_kwargs)
|
||||
|
||||
self._resize(req, id, flavor_ref, **resize_kwargs)
|
||||
|
||||
@ -1015,7 +1005,7 @@ class ServersController(wsgi.Controller):
|
||||
self.rebuild_extension_manager.map(self._rebuild_extension_point,
|
||||
rebuild_dict, rebuild_kwargs)
|
||||
|
||||
translate_attributes(rebuild_dict, rebuild_kwargs)
|
||||
helpers.translate_attributes(rebuild_dict, rebuild_kwargs)
|
||||
|
||||
for request_attribute, instance_attribute in attr_map.items():
|
||||
try:
|
||||
|
@ -17,7 +17,6 @@
|
||||
from oslo_utils import strutils
|
||||
|
||||
from nova.api.openstack import common
|
||||
from nova.api.openstack.compute import disk_config
|
||||
from nova.image import glance
|
||||
from nova import utils
|
||||
|
||||
@ -76,8 +75,8 @@ class ViewBuilder(common.ViewBuilder):
|
||||
auto_disk_config = image_dict['metadata'].get("auto_disk_config", None)
|
||||
if auto_disk_config is not None:
|
||||
value = strutils.bool_from_string(auto_disk_config)
|
||||
image_dict["OS-DCF:diskConfig"] = \
|
||||
disk_config.disk_config_to_api(value)
|
||||
image_dict["OS-DCF:diskConfig"] = (
|
||||
'AUTO' if value else 'MANUAL')
|
||||
|
||||
return dict(image=image_dict)
|
||||
|
||||
|
@ -25,6 +25,10 @@ from nova.tests.unit.api.openstack import fakes
|
||||
|
||||
FAKE_UPDATED_DATE = extension_info.FAKE_UPDATED_DATE
|
||||
|
||||
# NOTE(sdague): this whole test module is short term while we shift
|
||||
# the extensions into main path code. Some short cuts are taken in the
|
||||
# interim to keep these extension tests.
|
||||
|
||||
|
||||
class fake_extension(object):
|
||||
def __init__(self, name, alias, description, version):
|
||||
@ -76,8 +80,15 @@ class ExtensionInfoTest(test.NoDBTestCase):
|
||||
self.stubs.Set(policy, 'enforce', fake_policy_enforce)
|
||||
req = fakes.HTTPRequestV21.blank('/extensions')
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(3, len(res_dict['extensions']))
|
||||
for e in res_dict['extensions']:
|
||||
# NOTE(sdague): because of hardcoded extensions the count is
|
||||
# going to grow, and that's fine. We'll just check that it's
|
||||
# greater than the 3 that we inserted.
|
||||
self.assertGreaterEqual(len(res_dict['extensions']), 3)
|
||||
|
||||
# NOTE(sdague): filter the extension list by only ones that
|
||||
# are the fake alias names, otherwise we get errors as we
|
||||
# migrate extensions into the hardcoded list.
|
||||
for e in [x for x in res_dict['extensions'] if '-alias' in x['alias']]:
|
||||
self.assertIn(e['alias'], fake_extensions)
|
||||
self.assertEqual(e['name'], fake_extensions[e['alias']].name)
|
||||
self.assertEqual(e['alias'], fake_extensions[e['alias']].alias)
|
||||
@ -106,8 +117,15 @@ class ExtensionInfoTest(test.NoDBTestCase):
|
||||
self.stubs.Set(policy, 'enforce', fake_policy_enforce_selective)
|
||||
req = fakes.HTTPRequestV21.blank('/extensions')
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(2, len(res_dict['extensions']))
|
||||
for e in res_dict['extensions']:
|
||||
# NOTE(sdague): because of hardcoded extensions the count is
|
||||
# going to grow, and that's fine. We'll just check that it's
|
||||
# greater than the 2 that we inserted.
|
||||
self.assertGreaterEqual(len(res_dict['extensions']), 2)
|
||||
|
||||
# NOTE(sdague): filter the extension list by only ones that
|
||||
# are the fake alias names, otherwise we get errors as we
|
||||
# migrate extensions into the hardcoded list.
|
||||
for e in [x for x in res_dict['extensions'] if '-alias' in x['alias']]:
|
||||
self.assertNotEqual('ext1-alias', e['alias'])
|
||||
self.assertIn(e['alias'], fake_extensions)
|
||||
self.assertEqual(e['name'], fake_extensions[e['alias']].name)
|
||||
@ -131,7 +149,10 @@ class ExtensionInfoV21Test(test.NoDBTestCase):
|
||||
def test_extension_info_list(self):
|
||||
req = fakes.HTTPRequest.blank('/extensions')
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(12, len(res_dict['extensions']))
|
||||
# NOTE(sdague): because of hardcoded extensions the count is
|
||||
# going to grow, and that's fine. We'll just check that it's
|
||||
# greater than the 12 that we inserted.
|
||||
self.assertGreaterEqual(len(res_dict['extensions']), 12)
|
||||
|
||||
expected_output = copy.deepcopy(simulated_extension_list)
|
||||
del expected_output['images']
|
||||
@ -155,7 +176,10 @@ class ExtensionInfoV21Test(test.NoDBTestCase):
|
||||
expected_output['os-server-start-stop'] = fake_extension(
|
||||
'ServerStartStop', 'os-server-start-stop', '', -1)
|
||||
|
||||
for e in res_dict['extensions']:
|
||||
# NOTE(sdague): filter the extension list by only ones that
|
||||
# are the fake alias names, otherwise we get errors as we
|
||||
# migrate extensions into the hardcoded list.
|
||||
for e in [x for x in res_dict['extensions'] if '-alias' in x['alias']]:
|
||||
self.assertIn(e['alias'], expected_output)
|
||||
self.assertEqual(e['name'], expected_output[e['alias']].name)
|
||||
self.assertEqual(e['alias'], expected_output[e['alias']].alias)
|
||||
|
@ -59,7 +59,6 @@ policy_data = """
|
||||
"os_compute_api:os-consoles:show": "",
|
||||
"os_compute_api:os-create-backup": "",
|
||||
"os_compute_api:os-deferred-delete": "",
|
||||
"os_compute_api:os-disk-config": "",
|
||||
"os_compute_api:os-evacuate": "is_admin:True",
|
||||
"os_compute_api:os-extended-server-attributes": "",
|
||||
"os_compute_api:os-extended-status": "",
|
||||
|
@ -376,7 +376,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
|
||||
"os_compute_api:os-console-output",
|
||||
"os_compute_api:os-remote-consoles",
|
||||
"os_compute_api:os-deferred-delete",
|
||||
"os_compute_api:os-disk-config",
|
||||
"os_compute_api:os-extended-status",
|
||||
"os_compute_api:os-extended-availability-zone",
|
||||
"os_compute_api:os-extended-volumes",
|
||||
@ -435,7 +434,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
|
||||
"os_compute_api:os-remote-consoles:discoverable",
|
||||
"os_compute_api:os-create-backup:discoverable",
|
||||
"os_compute_api:os-deferred-delete:discoverable",
|
||||
"os_compute_api:os-disk-config:discoverable",
|
||||
"os_compute_api:os-evacuate:discoverable",
|
||||
"os_compute_api:os-extended-server-attributes:discoverable",
|
||||
"os_compute_api:os-extended-status:discoverable",
|
||||
|
16
releasenotes/notes/extensions_remove-37e9d4092981abbe.yaml
Normal file
16
releasenotes/notes/extensions_remove-37e9d4092981abbe.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
|
||||
The following policy enforcement points have been removed as part
|
||||
of the restructuring of the Nova API code. The attributes that
|
||||
could have been hidden with these policy points will now always be
|
||||
shown / accepted.
|
||||
|
||||
* os_compute_api:os-disk-config - show / accept
|
||||
``OS-DCF:diskConfig`` parameter
|
||||
|
||||
The following entry points have been removed
|
||||
|
||||
* nova.api.v21.extensions.server.resize - allowed accepting
|
||||
additional parameters on resize requests.
|
@ -84,7 +84,6 @@ nova.api.v21.extensions =
|
||||
consoles = nova.api.openstack.compute.consoles:Consoles
|
||||
create_backup = nova.api.openstack.compute.create_backup:CreateBackup
|
||||
deferred_delete = nova.api.openstack.compute.deferred_delete:DeferredDelete
|
||||
disk_config = nova.api.openstack.compute.disk_config:DiskConfig
|
||||
evacuate = nova.api.openstack.compute.evacuate:Evacuate
|
||||
extended_availability_zone = nova.api.openstack.compute.extended_availability_zone:ExtendedAvailabilityZone
|
||||
extended_server_attributes = nova.api.openstack.compute.extended_server_attributes:ExtendedServerAttributes
|
||||
|
Loading…
Reference in New Issue
Block a user