Port availability zones to core API
Changes: - Register availability zones API as core API using old link. - Remove extension code for availability zones. - Leave rename of API url for future update which will be done with bump of microversion after port of all extensions to core API. Partially implements bp ext-to-core Change-Id: Ifc75ef2d16121634ad12e5e12960c928e4d24b90
This commit is contained in:
parent
099145a07b
commit
e4428f5e6c
@ -5,6 +5,8 @@
|
||||
|
||||
"admin_api": "is_admin:True",
|
||||
|
||||
"availability_zone:index": "rule:default",
|
||||
|
||||
"share:create": "",
|
||||
"share:delete": "rule:default",
|
||||
"share:get": "rule:default",
|
||||
|
@ -31,6 +31,7 @@ from manila import exception
|
||||
from manila.i18n import _
|
||||
from manila.i18n import _LE
|
||||
from manila.i18n import _LI
|
||||
from manila import policy
|
||||
from manila import wsgi
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
@ -1110,6 +1111,12 @@ class Controller(object):
|
||||
|
||||
return decorator
|
||||
|
||||
def authorize(self, context, action):
|
||||
try:
|
||||
policy.check_policy(context, self.resource_name, action)
|
||||
except exception.PolicyNotAuthorized:
|
||||
raise webob.exc.HTTPForbidden()
|
||||
|
||||
@staticmethod
|
||||
def is_valid_body(body, entity_name):
|
||||
if not (body and entity_name in body):
|
||||
|
@ -13,31 +13,26 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from manila.api import extensions
|
||||
from manila.api.openstack import wsgi
|
||||
from manila.api.views import availability_zones as availability_zones_views
|
||||
from manila import db
|
||||
|
||||
authorize = extensions.extension_authorizer('share', 'availability_zones')
|
||||
|
||||
class AvailabilityZoneController(wsgi.Controller):
|
||||
"""The Availability Zone API controller for the OpenStack API."""
|
||||
|
||||
resource_name = "availability_zone"
|
||||
_view_builder_class = availability_zones_views.ViewBuilder
|
||||
|
||||
class Controller(wsgi.Controller):
|
||||
def index(self, req):
|
||||
self.authorize(req.environ['manila.context'], 'index')
|
||||
return self._index(req)
|
||||
|
||||
def _index(self, req):
|
||||
"""Describe all known availability zones."""
|
||||
context = req.environ['manila.context']
|
||||
authorize(context)
|
||||
azs = db.availability_zone_get_all(context)
|
||||
return {'availability_zones': azs}
|
||||
views = db.availability_zone_get_all(req.environ['manila.context'])
|
||||
return self._view_builder.detail_list(views)
|
||||
|
||||
|
||||
class Availability_zones(extensions.ExtensionDescriptor):
|
||||
"""Describe Availability Zones."""
|
||||
|
||||
name = 'AvailabilityZones'
|
||||
alias = 'os-availability-zone'
|
||||
updated = '2015-07-28T00:00:00+00:00'
|
||||
|
||||
def get_resources(self):
|
||||
controller = Controller()
|
||||
res = extensions.ResourceExtension(Availability_zones.alias,
|
||||
controller)
|
||||
return [res]
|
||||
def create_resource():
|
||||
return wsgi.Resource(AvailabilityZoneController())
|
@ -23,6 +23,7 @@ from oslo_log import log
|
||||
|
||||
from manila.api import extensions
|
||||
import manila.api.openstack
|
||||
from manila.api.v1 import availability_zones
|
||||
from manila.api.v1 import cgsnapshots
|
||||
from manila.api.v1 import consistency_groups
|
||||
from manila.api.v1 import limits
|
||||
@ -56,6 +57,14 @@ class APIRouter(manila.api.openstack.APIRouter):
|
||||
|
||||
mapper.redirect("", "/")
|
||||
|
||||
self.resources["availability_zones"] = (
|
||||
availability_zones.create_resource())
|
||||
mapper.resource("availability-zone",
|
||||
# TODO(vponomaryov): rename 'os-availability-zone' to
|
||||
# 'availability-zones' when API urls rename happens.
|
||||
"os-availability-zone",
|
||||
controller=self.resources["availability_zones"])
|
||||
|
||||
self.resources['shares'] = shares.create_resource()
|
||||
mapper.resource("share", "shares",
|
||||
controller=self.resources['shares'],
|
||||
|
@ -19,7 +19,6 @@ from manila.api.openstack import wsgi
|
||||
from manila.api.views import share_instance as instance_view
|
||||
from manila import db
|
||||
from manila import exception
|
||||
from manila import policy
|
||||
from manila import share
|
||||
|
||||
|
||||
@ -33,16 +32,10 @@ class ShareInstancesController(wsgi.Controller):
|
||||
self.share_api = share.API()
|
||||
super(ShareInstancesController, self).__init__()
|
||||
|
||||
def _authorize(self, context, action):
|
||||
try:
|
||||
policy.check_policy(context, self.resource_name, action)
|
||||
except exception.PolicyNotAuthorized:
|
||||
raise exc.HTTPForbidden()
|
||||
|
||||
@wsgi.Controller.api_version("2.3")
|
||||
def index(self, req):
|
||||
context = req.environ['manila.context']
|
||||
self._authorize(context, 'index')
|
||||
self.authorize(context, 'index')
|
||||
|
||||
instances = db.share_instances_get_all(context)
|
||||
return self._view_builder.detail_list(req, instances)
|
||||
@ -50,7 +43,7 @@ class ShareInstancesController(wsgi.Controller):
|
||||
@wsgi.Controller.api_version("2.3")
|
||||
def show(self, req, id):
|
||||
context = req.environ['manila.context']
|
||||
self._authorize(context, 'show')
|
||||
self.authorize(context, 'show')
|
||||
|
||||
try:
|
||||
instance = db.share_instance_get(context, id)
|
||||
@ -62,7 +55,7 @@ class ShareInstancesController(wsgi.Controller):
|
||||
@wsgi.Controller.api_version("2.3")
|
||||
def get_share_instances(self, req, share_id):
|
||||
context = req.environ['manila.context']
|
||||
self._authorize(context, 'index')
|
||||
self.authorize(context, 'index')
|
||||
|
||||
try:
|
||||
share = self.share_api.get(context, share_id)
|
||||
@ -74,4 +67,4 @@ class ShareInstancesController(wsgi.Controller):
|
||||
|
||||
|
||||
def create_resource():
|
||||
return wsgi.Resource(ShareInstancesController())
|
||||
return wsgi.Resource(ShareInstancesController())
|
||||
|
31
manila/api/views/availability_zones.py
Normal file
31
manila/api/views/availability_zones.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Copyright (c) 2015 Mirantis inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 manila.api import common
|
||||
|
||||
|
||||
class ViewBuilder(common.ViewBuilder):
|
||||
|
||||
_collection_name = "availability_zones"
|
||||
|
||||
def _detail(self, availability_zone):
|
||||
"""Detailed view of an single availability zone."""
|
||||
keys = ('id', 'name', 'created_at', 'updated_at')
|
||||
return {key: availability_zone.get(key) for key in keys}
|
||||
|
||||
def detail_list(self, availability_zones):
|
||||
"""Detailed view of a list of availability zones."""
|
||||
azs = [self._detail(az) for az in availability_zones]
|
||||
return {self._collection_name: azs}
|
@ -1,38 +0,0 @@
|
||||
# Copyright 2015 Mirantis Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from manila.api.contrib import availability_zones
|
||||
from manila import db
|
||||
from manila import test
|
||||
from manila.tests.api import fakes
|
||||
|
||||
|
||||
class AvailabilityZonesApiTest(test.TestCase):
|
||||
def setUp(self):
|
||||
super(AvailabilityZonesApiTest, self).setUp()
|
||||
self.controller = availability_zones.Controller()
|
||||
|
||||
def test_index(self):
|
||||
fake_az = [{'test': 'test'}]
|
||||
self.mock_object(db, 'availability_zone_get_all',
|
||||
mock.Mock(return_value=fake_az))
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/types/1')
|
||||
|
||||
actual_result = self.controller.index(req)
|
||||
|
||||
self.assertDictMatch({'availability_zones': fake_az}, actual_result)
|
||||
db.availability_zone_get_all.assert_called_once_with(mock.ANY)
|
71
manila/tests/api/v1/test_availability_zones.py
Normal file
71
manila/tests/api/v1/test_availability_zones.py
Normal file
@ -0,0 +1,71 @@
|
||||
# Copyright (c) 2015 Mirantis 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.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from manila.api.v1 import availability_zones
|
||||
from manila import context
|
||||
from manila import test
|
||||
from manila.tests.api import fakes
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class AvailabilityZonesAPITest(test.TestCase):
|
||||
|
||||
def test_instantiate_controller(self):
|
||||
controller = availability_zones.AvailabilityZoneController()
|
||||
|
||||
self.assertTrue(hasattr(controller, "resource_name"))
|
||||
self.assertEqual("availability_zone", controller.resource_name)
|
||||
self.assertTrue(hasattr(controller, "_view_builder"))
|
||||
self.assertTrue(hasattr(controller._view_builder, "detail_list"))
|
||||
|
||||
@ddt.data('1.0', '2.0', '2.6')
|
||||
def test_index(self, version):
|
||||
azs = [
|
||||
{
|
||||
"id": "fake_id1",
|
||||
"name": "fake_name1",
|
||||
"created_at": "fake_created_at",
|
||||
"updated_at": "fake_updated_at",
|
||||
},
|
||||
{
|
||||
"id": "fake_id2",
|
||||
"name": "fake_name2",
|
||||
"created_at": "fake_created_at",
|
||||
"updated_at": "fake_updated_at",
|
||||
"deleted": "False",
|
||||
"redundant_key": "redundant_value",
|
||||
},
|
||||
]
|
||||
self.mock_object(availability_zones.db, 'availability_zone_get_all',
|
||||
mock.Mock(return_value=azs))
|
||||
controller = availability_zones.AvailabilityZoneController()
|
||||
ctxt = context.RequestContext("admin", "fake", True)
|
||||
req = fakes.HTTPRequest.blank('/shares', version=version)
|
||||
req.environ['manila.context'] = ctxt
|
||||
|
||||
result = controller.index(req)
|
||||
|
||||
availability_zones.db.availability_zone_get_all.\
|
||||
assert_called_once_with(ctxt)
|
||||
self.assertTrue(isinstance(result, dict))
|
||||
self.assertEqual(["availability_zones"], list(result.keys()))
|
||||
self.assertTrue(isinstance(result["availability_zones"], list))
|
||||
self.assertEqual(2, len(result["availability_zones"]))
|
||||
self.assertTrue(azs[0] in result["availability_zones"])
|
||||
azs[1].pop("deleted")
|
||||
azs[1].pop("redundant_key")
|
||||
self.assertTrue(azs[1] in result["availability_zones"])
|
@ -4,6 +4,8 @@
|
||||
"admin_or_owner": "is_admin:True or project_id:%(project_id)s",
|
||||
"default": "rule:admin_or_owner",
|
||||
|
||||
"availability_zone:index": "rule:default",
|
||||
|
||||
"share:create": "",
|
||||
"share:list_by_share_server_id": "rule:admin_api",
|
||||
"share:get": "",
|
||||
|
@ -24,10 +24,13 @@ class AvailabilityZonesTest(base.BaseSharesTest):
|
||||
self.assertTrue(len(availability_zones) > 0)
|
||||
keys = ("created_at", "updated_at", "name", "id")
|
||||
for az in availability_zones:
|
||||
self.assertEqual(len(keys), len(az))
|
||||
for key in keys:
|
||||
self.assertIn(key, az)
|
||||
|
||||
@test.attr(type=["smoke", "gate"])
|
||||
def test_list_availability_zones_extension(self):
|
||||
def test_list_availability_zones_extension_url(self):
|
||||
# NOTE(vponomaryov): remove this test with removal of availability zone
|
||||
# extension url support.
|
||||
azs = self.shares_client.list_availability_zones()
|
||||
self._list_availability_zones_assertions(azs)
|
||||
|
Loading…
Reference in New Issue
Block a user