Add share's networks API
Add server side for share's networks. Implemented controller will carry user requests to the DB and thus will allow user to manage share's networks data. Add share's networks support to the share API. Partially implements bp: join-tenant-network Change-Id: Ie4f3945255a049e80083f08a39d7f703a5c75c5e
This commit is contained in:
parent
d3131f40d2
commit
c81ad66e7e
|
@ -28,6 +28,7 @@ from manila.api import versions
|
|||
|
||||
from manila.api.v1 import security_service
|
||||
from manila.api.v1 import share_metadata
|
||||
from manila.api.v1 import share_networks
|
||||
from manila.api.v1 import share_snapshots
|
||||
from manila.api.v1 import shares
|
||||
|
||||
|
@ -86,3 +87,9 @@ class APIRouter(manila.api.openstack.APIRouter):
|
|||
security_service.create_resource()
|
||||
mapper.resource("security-service", "security-services",
|
||||
controller=self.resources['security_services'])
|
||||
|
||||
self.resources['share_networks'] = share_networks.create_resource()
|
||||
mapper.resource(share_networks.RESOURCE_NAME,
|
||||
'share-networks',
|
||||
controller=self.resources['share_networks'],
|
||||
member={'action': 'POST'})
|
||||
|
|
|
@ -113,25 +113,31 @@ class SecurityServiceController(wsgi.Controller):
|
|||
search_opts = {}
|
||||
search_opts.update(req.GET)
|
||||
|
||||
common.remove_invalid_options(
|
||||
context, search_opts, self._get_security_services_search_options())
|
||||
if 'all_tenants' in search_opts:
|
||||
security_services = db.security_service_get_all(context)
|
||||
del search_opts['all_tenants']
|
||||
if 'share_network_id' in search_opts:
|
||||
share_nw = db.share_network_get(context,
|
||||
search_opts['share_network_id'])
|
||||
security_services = share_nw['security_services']
|
||||
else:
|
||||
security_services = db.security_service_get_all_by_project(
|
||||
context, context.project_id)
|
||||
|
||||
if search_opts:
|
||||
results = []
|
||||
not_found = object()
|
||||
for service in security_services:
|
||||
for opt, value in search_opts.iteritems():
|
||||
if service.get(opt, not_found) != value:
|
||||
break
|
||||
else:
|
||||
results.append(service)
|
||||
security_services = results
|
||||
common.remove_invalid_options(
|
||||
context,
|
||||
search_opts,
|
||||
self._get_security_services_search_options())
|
||||
if 'all_tenants' in search_opts:
|
||||
security_services = db.security_service_get_all(context)
|
||||
del search_opts['all_tenants']
|
||||
else:
|
||||
security_services = db.security_service_get_all_by_project(
|
||||
context, context.project_id)
|
||||
if search_opts:
|
||||
results = []
|
||||
not_found = object()
|
||||
for service in security_services:
|
||||
for opt, value in search_opts.iteritems():
|
||||
if service.get(opt, not_found) != value:
|
||||
break
|
||||
else:
|
||||
results.append(service)
|
||||
security_services = results
|
||||
|
||||
limited_list = common.limited(security_services, req)
|
||||
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
# Copyright 2014 NetApp
|
||||
# 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.
|
||||
|
||||
"""The shares api."""
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from manila.api.openstack import wsgi
|
||||
from manila.api.views import share_networks as share_networks_views
|
||||
from manila.api import xmlutil
|
||||
from manila.common import constants
|
||||
from manila.db import api as db_api
|
||||
from manila import exception
|
||||
from manila.openstack.common import log as logging
|
||||
|
||||
RESOURCE_NAME = 'share_network'
|
||||
RESOURCES_NAME = 'share_networks'
|
||||
LOG = logging.getLogger(__name__)
|
||||
SHARE_NETWORK_ATTRS = ('id',
|
||||
'project_id',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'neutron_net_id',
|
||||
'neutron_subnet_id',
|
||||
'network_type',
|
||||
'segmentation_id',
|
||||
'cidr',
|
||||
'ip_version',
|
||||
'name',
|
||||
'description',
|
||||
'status')
|
||||
|
||||
|
||||
def _make_share_network(elem):
|
||||
for attr in SHARE_NETWORK_ATTRS:
|
||||
elem.set(attr)
|
||||
|
||||
|
||||
class ShareNetworkTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement(RESOURCE_NAME, selector=RESOURCE_NAME)
|
||||
_make_share_network(root)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class ShareNetworksTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement(RESOURCES_NAME)
|
||||
elem = xmlutil.SubTemplateElement(root, RESOURCE_NAME,
|
||||
selector=RESOURCES_NAME)
|
||||
_make_share_network(elem)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class ShareNetworkController(wsgi.Controller):
|
||||
"""The Share Network API controller for the OpenStack API."""
|
||||
|
||||
_view_builder_class = share_networks_views.ViewBuilder
|
||||
|
||||
@wsgi.serializers(xml=ShareNetworkTemplate)
|
||||
def show(self, req, id):
|
||||
"""Return data about the requested network info."""
|
||||
context = req.environ['manila.context']
|
||||
|
||||
try:
|
||||
share_network = db_api.share_network_get(context, id)
|
||||
except exception.ShareNetworkNotFound as e:
|
||||
msg = "%s" % e
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
|
||||
return self._view_builder.build_share_network(share_network)
|
||||
|
||||
def delete(self, req, id):
|
||||
"""Delete specified share network."""
|
||||
context = req.environ['manila.context']
|
||||
|
||||
try:
|
||||
share_network = db_api.share_network_get(context, id)
|
||||
except exception.ShareNetworkNotFound as e:
|
||||
msg = "%s" % e
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
|
||||
if share_network['status'] == constants.STATUS_ACTIVE:
|
||||
msg = "Network %s is in use" % id
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
db_api.share_network_delete(context, id)
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.serializers(xml=ShareNetworksTemplate)
|
||||
def index(self, req):
|
||||
"""Returns a summary list of share's networks."""
|
||||
context = req.environ['manila.context']
|
||||
|
||||
search_opts = {}
|
||||
search_opts.update(req.GET)
|
||||
|
||||
if search_opts.pop('all_tenants', None):
|
||||
networks = db_api.share_network_get_all(context)
|
||||
else:
|
||||
networks = db_api.share_network_get_all_by_project(
|
||||
context,
|
||||
context.project_id)
|
||||
|
||||
if search_opts:
|
||||
for key, value in search_opts.iteritems():
|
||||
networks = [network for network in networks
|
||||
if network[key] == value]
|
||||
return self._view_builder.build_share_networks(networks)
|
||||
|
||||
@wsgi.serializers(xml=ShareNetworkTemplate)
|
||||
def update(self, req, id, body):
|
||||
"""Update specified share network."""
|
||||
context = req.environ['manila.context']
|
||||
|
||||
if not body or RESOURCE_NAME not in body:
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
|
||||
try:
|
||||
share_network = db_api.share_network_get(context, id)
|
||||
except exception.ShareNetworkNotFound as e:
|
||||
msg = "%s" % e
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
|
||||
if share_network['status'] == constants.STATUS_ACTIVE:
|
||||
msg = "Network %s is in use" % id
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
update_values = body[RESOURCE_NAME]
|
||||
|
||||
try:
|
||||
share_network = db_api.share_network_update(context,
|
||||
id,
|
||||
update_values)
|
||||
except exception.DBError:
|
||||
msg = "Could not save supplied data due to database error"
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return self._view_builder.build_share_network(share_network)
|
||||
|
||||
@wsgi.serializers(xml=ShareNetworkTemplate)
|
||||
def create(self, req, body):
|
||||
"""Creates a new share network."""
|
||||
context = req.environ['manila.context']
|
||||
|
||||
if not body or RESOURCE_NAME not in body:
|
||||
raise exc.HTTPUnprocessableEntity()
|
||||
|
||||
values = body[RESOURCE_NAME]
|
||||
values['project_id'] = context.project_id
|
||||
|
||||
try:
|
||||
share_network = db_api.share_network_create(context, values)
|
||||
except exception.DBError:
|
||||
msg = "Could not save supplied data due to database error"
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return self._view_builder.build_share_network(share_network)
|
||||
|
||||
@wsgi.serializers(xml=ShareNetworkTemplate)
|
||||
def action(self, req, id, body):
|
||||
_actions = {
|
||||
'add_security_service': self._add_security_service,
|
||||
'remove_security_service': self._remove_security_service,
|
||||
}
|
||||
for action, data in body.iteritems():
|
||||
try:
|
||||
return _actions[action](req, id, data)
|
||||
except KeyError:
|
||||
msg = _("Share networks does not have %s action") % action
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
def _add_security_service(self, req, id, data):
|
||||
context = req.environ['manila.context']
|
||||
try:
|
||||
share_network = db_api.share_network_add_security_service(
|
||||
context,
|
||||
id,
|
||||
data['security_service_id'])
|
||||
except KeyError:
|
||||
msg = "Malformed request body"
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
except exception.NotFound as e:
|
||||
msg = "%s" % e
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
except exception.ShareNetworkSecurityServiceAssociationError as e:
|
||||
msg = "%s" % e
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return self._view_builder.build_share_network(share_network)
|
||||
|
||||
def _remove_security_service(self, req, id, data):
|
||||
context = req.environ['manila.context']
|
||||
try:
|
||||
share_network = db_api.share_network_remove_security_service(
|
||||
context,
|
||||
id,
|
||||
data['security_service_id'])
|
||||
except KeyError:
|
||||
msg = "Malformed request body"
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
except exception.NotFound as e:
|
||||
msg = "%s" % e
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
except exception.ShareNetworkSecurityServiceDissociationError as e:
|
||||
msg = "%s" % e
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return self._view_builder.build_share_network(share_network)
|
||||
|
||||
|
||||
def create_resource():
|
||||
return wsgi.Resource(ShareNetworkController())
|
|
@ -198,6 +198,8 @@ class ShareController(wsgi.Controller):
|
|||
else:
|
||||
kwargs['snapshot'] = None
|
||||
|
||||
kwargs['share_network_id'] = share.get('share_network_id')
|
||||
|
||||
display_name = share.get('display_name')
|
||||
display_description = share.get('display_description')
|
||||
new_share = self.share_api.create(context,
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2014 OpenStack LLC.
|
||||
# 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):
|
||||
"""Model a server API response as a python dictionary."""
|
||||
|
||||
_collection_name = 'share_networks'
|
||||
|
||||
def build_share_network(self, share_network):
|
||||
"""View of a share network."""
|
||||
|
||||
return {'share_network': self._build_share_network_view(share_network)}
|
||||
|
||||
def build_share_networks(self, share_networks):
|
||||
return {'share_networks':
|
||||
[self._build_share_network_view(share_network)
|
||||
for share_network in share_networks]}
|
||||
|
||||
def _build_share_network_view(self, share_network):
|
||||
return {
|
||||
'id': share_network.get('id'),
|
||||
'project_id': share_network.get('project_id'),
|
||||
'created_at': share_network.get('created_at'),
|
||||
'updated_at': share_network.get('updated_at'),
|
||||
'neutron_net_id': share_network.get('neutron_net_id'),
|
||||
'neutron_subnet_id': share_network.get('neutron_subnet_id'),
|
||||
'network_type': share_network.get('network_type'),
|
||||
'segmentation_id': share_network.get('segmentation_id'),
|
||||
'cidr': share_network.get('cidr'),
|
||||
'ip_version': share_network.get('ip_version'),
|
||||
'name': share_network.get('name'),
|
||||
'description': share_network.get('description'),
|
||||
'status': share_network.get('status'),
|
||||
}
|
|
@ -60,6 +60,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||
'name': share.get('display_name'),
|
||||
'description': share.get('display_description'),
|
||||
'snapshot_id': share.get('snapshot_id'),
|
||||
'share_network_id': share.get('share_network_id'),
|
||||
'share_proto': share.get('share_proto'),
|
||||
'export_location': share.get('export_location'),
|
||||
'metadata': metadata,
|
||||
|
|
|
@ -49,7 +49,8 @@ class API(base.Base):
|
|||
super(API, self).__init__(db_driver)
|
||||
|
||||
def create(self, context, share_proto, size, name, description,
|
||||
snapshot=None, availability_zone=None, metadata=None):
|
||||
snapshot=None, availability_zone=None, metadata=None,
|
||||
share_network_id=None):
|
||||
"""Create new share."""
|
||||
policy.check_policy(context, 'create')
|
||||
|
||||
|
@ -125,6 +126,7 @@ class API(base.Base):
|
|||
'user_id': context.user_id,
|
||||
'project_id': context.project_id,
|
||||
'snapshot_id': snapshot_id,
|
||||
'share_network_id': share_network_id,
|
||||
'availability_zone': availability_zone,
|
||||
'metadata': metadata,
|
||||
'status': "creating",
|
||||
|
|
|
@ -39,6 +39,7 @@ def stub_share(id, **kwargs):
|
|||
'display_description': 'displaydesc',
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'snapshot_id': '2',
|
||||
'share_network_id': None
|
||||
}
|
||||
share.update(kwargs)
|
||||
return share
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
# Copyright 2014 NetApp
|
||||
# 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
|
||||
import unittest
|
||||
from webob import exc as webob_exc
|
||||
|
||||
from manila.api.v1 import share_networks
|
||||
from manila.common import constants
|
||||
from manila.db import api as db_api
|
||||
from manila import exception
|
||||
from manila.tests.api import fakes
|
||||
|
||||
|
||||
fake_share_network = {'id': 'fake network id',
|
||||
'project_id': 'fake project',
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
'neutron_net_id': 'fake net id',
|
||||
'neutron_subnet_id': 'fake subnet id',
|
||||
'network_type': 'vlan',
|
||||
'segmentation_id': 1000,
|
||||
'cidr': '10.0.0.0/24',
|
||||
'ip_version': 4,
|
||||
'name': 'fake name',
|
||||
'description': 'fake description',
|
||||
'status': constants.STATUS_INACTIVE,
|
||||
'shares': [],
|
||||
'network_allocations': [],
|
||||
'security_services': []
|
||||
}
|
||||
|
||||
|
||||
class ShareNetworkAPITest(unittest.TestCase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ShareNetworkAPITest, self).__init__(*args, **kwargs)
|
||||
self.controller = share_networks.ShareNetworkController()
|
||||
self.req = fakes.HTTPRequest.blank('/share-networks')
|
||||
self.context = self.req.environ['manila.context']
|
||||
self.body = {share_networks.RESOURCE_NAME: {'name': 'fake name'}}
|
||||
|
||||
def _check_share_network_view(self, view, share_nw):
|
||||
self.assertEqual(view['id'], share_nw['id'])
|
||||
self.assertEqual(view['project_id'], share_nw['project_id'])
|
||||
self.assertEqual(view['created_at'], share_nw['created_at'])
|
||||
self.assertEqual(view['updated_at'], share_nw['updated_at'])
|
||||
self.assertEqual(view['neutron_net_id'],
|
||||
share_nw['neutron_net_id'])
|
||||
self.assertEqual(view['neutron_subnet_id'],
|
||||
share_nw['neutron_subnet_id'])
|
||||
self.assertEqual(view['network_type'], share_nw['network_type'])
|
||||
self.assertEqual(view['segmentation_id'],
|
||||
share_nw['segmentation_id'])
|
||||
self.assertEqual(view['cidr'], share_nw['cidr'])
|
||||
self.assertEqual(view['ip_version'], share_nw['ip_version'])
|
||||
self.assertEqual(view['name'], share_nw['name'])
|
||||
self.assertEqual(view['description'], share_nw['description'])
|
||||
self.assertEqual(view['status'], share_nw['status'])
|
||||
|
||||
self.assertEqual(view['created_at'], None)
|
||||
self.assertEqual(view['updated_at'], None)
|
||||
self.assertFalse('shares' in view)
|
||||
self.assertFalse('network_allocations' in view)
|
||||
self.assertFalse('security_services' in view)
|
||||
|
||||
def test_create_nominal(self):
|
||||
with mock.patch.object(db_api,
|
||||
'share_network_create',
|
||||
mock.Mock(return_value=fake_share_network)):
|
||||
|
||||
result = self.controller.create(self.req, self.body)
|
||||
|
||||
db_api.share_network_create.assert_called_once_with(
|
||||
self.req.environ['manila.context'],
|
||||
self.body[share_networks.RESOURCE_NAME])
|
||||
|
||||
self._check_share_network_view(
|
||||
result[share_networks.RESOURCE_NAME],
|
||||
fake_share_network)
|
||||
|
||||
def test_create_db_api_exception(self):
|
||||
with mock.patch.object(db_api,
|
||||
'share_network_create',
|
||||
mock.Mock(side_effect=exception.DBError)):
|
||||
self.assertRaises(webob_exc.HTTPBadRequest,
|
||||
self.controller.create,
|
||||
self.req,
|
||||
self.body)
|
||||
|
||||
def test_create_wrong_body(self):
|
||||
body = None
|
||||
self.assertRaises(webob_exc.HTTPUnprocessableEntity,
|
||||
self.controller.create,
|
||||
self.req,
|
||||
body)
|
||||
|
||||
@mock.patch.object(db_api, 'share_network_get',
|
||||
mock.Mock(return_value=fake_share_network))
|
||||
def test_delete_nominal(self):
|
||||
share_nw = 'fake network id'
|
||||
|
||||
with mock.patch.object(db_api, 'share_network_delete'):
|
||||
self.controller.delete(self.req, share_nw)
|
||||
db_api.share_network_delete.assert_called_once_with(
|
||||
self.req.environ['manila.context'],
|
||||
share_nw)
|
||||
|
||||
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
|
||||
def test_delete_not_found(self):
|
||||
share_nw = 'fake network id'
|
||||
db_api.share_network_get.side_effect = exception.ShareNetworkNotFound(
|
||||
share_network_id=share_nw)
|
||||
|
||||
self.assertRaises(webob_exc.HTTPNotFound,
|
||||
self.controller.delete,
|
||||
self.req,
|
||||
share_nw)
|
||||
|
||||
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
|
||||
def test_delete_in_use(self):
|
||||
share_nw = fake_share_network.copy()
|
||||
share_nw['status'] = constants.STATUS_ACTIVE
|
||||
|
||||
db_api.share_network_get.return_value = share_nw
|
||||
|
||||
self.assertRaises(webob_exc.HTTPBadRequest,
|
||||
self.controller.delete,
|
||||
self.req,
|
||||
share_nw['id'])
|
||||
|
||||
def test_show_nominal(self):
|
||||
share_nw = 'fake network id'
|
||||
with mock.patch.object(db_api,
|
||||
'share_network_get',
|
||||
mock.Mock(return_value=fake_share_network)):
|
||||
result = self.controller.show(self.req, share_nw)
|
||||
|
||||
db_api.share_network_get.assert_called_once_with(
|
||||
self.req.environ['manila.context'],
|
||||
share_nw)
|
||||
|
||||
self._check_share_network_view(
|
||||
result[share_networks.RESOURCE_NAME],
|
||||
fake_share_network)
|
||||
|
||||
def test_show_not_found(self):
|
||||
share_nw = 'fake network id'
|
||||
test_exception = exception.ShareNetworkNotFound()
|
||||
with mock.patch.object(db_api,
|
||||
'share_network_get',
|
||||
mock.Mock(side_effect=test_exception)):
|
||||
self.assertRaises(webob_exc.HTTPNotFound,
|
||||
self.controller.show,
|
||||
self.req,
|
||||
share_nw)
|
||||
|
||||
def test_index_no_filters(self):
|
||||
networks = [fake_share_network]
|
||||
with mock.patch.object(db_api,
|
||||
'share_network_get_all_by_project',
|
||||
mock.Mock(return_value=networks)):
|
||||
|
||||
result = self.controller.index(self.req)
|
||||
|
||||
db_api.share_network_get_all_by_project.assert_called_once_with(
|
||||
self.context,
|
||||
self.context.project_id)
|
||||
|
||||
self.assertEqual(len(result[share_networks.RESOURCES_NAME]), 1)
|
||||
self._check_share_network_view(
|
||||
result[share_networks.RESOURCES_NAME][0],
|
||||
fake_share_network)
|
||||
|
||||
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
|
||||
def test_update_nominal(self):
|
||||
share_nw = 'fake network id'
|
||||
db_api.share_network_get.return_value = fake_share_network
|
||||
|
||||
body = {share_networks.RESOURCE_NAME: {'name': 'new name'}}
|
||||
|
||||
with mock.patch.object(db_api,
|
||||
'share_network_update',
|
||||
mock.Mock(return_value=fake_share_network)):
|
||||
result = self.controller.update(self.req, share_nw, body)
|
||||
|
||||
db_api.share_network_update.assert_called_once_with(
|
||||
self.req.environ['manila.context'],
|
||||
share_nw,
|
||||
body[share_networks.RESOURCE_NAME])
|
||||
|
||||
self._check_share_network_view(
|
||||
result[share_networks.RESOURCE_NAME],
|
||||
fake_share_network)
|
||||
|
||||
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
|
||||
def test_update_not_found(self):
|
||||
share_nw = 'fake network id'
|
||||
db_api.share_network_get.side_effect = exception.ShareNetworkNotFound(
|
||||
share_network_id=share_nw)
|
||||
|
||||
self.assertRaises(webob_exc.HTTPNotFound,
|
||||
self.controller.update,
|
||||
self.req,
|
||||
share_nw,
|
||||
self.body)
|
||||
|
||||
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
|
||||
def test_update_in_use(self):
|
||||
share_nw = fake_share_network.copy()
|
||||
share_nw['status'] = constants.STATUS_ACTIVE
|
||||
|
||||
db_api.share_network_get.return_value = share_nw
|
||||
|
||||
self.assertRaises(webob_exc.HTTPBadRequest,
|
||||
self.controller.update,
|
||||
self.req,
|
||||
share_nw['id'],
|
||||
self.body)
|
||||
|
||||
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
|
||||
def test_update_db_api_exception(self):
|
||||
share_nw = 'fake network id'
|
||||
db_api.share_network_get.return_value = fake_share_network
|
||||
|
||||
body = {share_networks.RESOURCE_NAME: {'neutron_subnet_id':
|
||||
'new subnet'}}
|
||||
|
||||
with mock.patch.object(db_api,
|
||||
'share_network_update',
|
||||
mock.Mock(side_effect=exception.DBError)):
|
||||
self.assertRaises(webob_exc.HTTPBadRequest,
|
||||
self.controller.update,
|
||||
self.req,
|
||||
share_nw,
|
||||
body)
|
|
@ -145,6 +145,7 @@ class ShareApiTest(test.TestCase):
|
|||
'metadata': {},
|
||||
'size': 1,
|
||||
'snapshot_id': '2',
|
||||
'share_network_id': None,
|
||||
'status': 'fakestatus',
|
||||
'links': [{'href': 'http://localhost/v1/fake/shares/1',
|
||||
'rel': 'self'},
|
||||
|
@ -246,6 +247,7 @@ class ShareApiTest(test.TestCase):
|
|||
'metadata': {},
|
||||
'id': '1',
|
||||
'snapshot_id': '2',
|
||||
'share_network_id': None,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'size': 1,
|
||||
'links': [
|
||||
|
|
|
@ -40,6 +40,7 @@ def fake_share(id, **kwargs):
|
|||
'user_id': 'fakeuser',
|
||||
'project_id': 'fakeproject',
|
||||
'snapshot_id': None,
|
||||
'share_network_id': None,
|
||||
'availability_zone': 'fakeaz',
|
||||
'status': 'fakestatus',
|
||||
'display_name': 'fakename',
|
||||
|
|
Loading…
Reference in New Issue