Merge "Add share network activate and deactivate"

This commit is contained in:
Jenkins 2014-03-13 15:27:42 +00:00 committed by Gerrit Code Review
commit ebda4e3a14
8 changed files with 356 additions and 47 deletions

View File

@ -27,6 +27,11 @@
"share_network:create": [],
"share_network:delete": [],
"share_network:update": [],
"share_network:index": [],
"share_network:detail": [],
"share_network:show": [],
"share_network:add_security_service": [],
"share_network:remove_security_service": []
"share_network:remove_security_service": [],
"share_network:activate": [],
"share_network:deactivate": []
}

View File

@ -24,8 +24,11 @@ from manila.api import xmlutil
from manila.common import constants
from manila.db import api as db_api
from manila import exception
from manila import network
from manila.openstack.common import importutils
from manila.openstack.common import log as logging
from manila import policy
from manila.share import rpcapi as share_rpcapi
RESOURCE_NAME = 'share_network'
RESOURCES_NAME = 'share_networks'
@ -71,6 +74,10 @@ class ShareNetworkController(wsgi.Controller):
_view_builder_class = share_networks_views.ViewBuilder
def __init__(self):
super(ShareNetworkController, self).__init__()
self.share_rpcapi = share_rpcapi.ShareAPI()
@wsgi.serializers(xml=ShareNetworkTemplate)
def show(self, req, id):
"""Return data about the requested network info."""
@ -192,6 +199,8 @@ class ShareNetworkController(wsgi.Controller):
_actions = {
'add_security_service': self._add_security_service,
'remove_security_service': self._remove_security_service,
'activate': self._activate,
'deactivate': self._deactivate,
}
for action, data in body.iteritems():
try:
@ -201,6 +210,7 @@ class ShareNetworkController(wsgi.Controller):
raise exc.HTTPBadRequest(explanation=msg)
def _add_security_service(self, req, id, data):
"""Associate share network with a given security service."""
context = req.environ['manila.context']
policy.check_policy(context, RESOURCE_NAME, 'add_security_service')
try:
@ -221,6 +231,7 @@ class ShareNetworkController(wsgi.Controller):
return self._view_builder.build_share_network(share_network)
def _remove_security_service(self, req, id, data):
"""Dissociate share network from a given security service."""
context = req.environ['manila.context']
policy.check_policy(context, RESOURCE_NAME, 'remove_security_service')
try:
@ -240,6 +251,47 @@ class ShareNetworkController(wsgi.Controller):
return self._view_builder.build_share_network(share_network)
def _activate(self, req, id, data):
"""Activate share network."""
context = req.environ['manila.context']
policy.check_policy(context, RESOURCE_NAME, 'activate')
try:
share_network = db_api.share_network_get(context, id)
except exception.ShareNetworkNotFound as e:
msg = _("Share-network was not found. %s") % e
raise exc.HTTPNotFound(explanation=msg)
if share_network['status'] != constants.STATUS_INACTIVE:
msg = _("Share network should be 'INACTIVE'.")
raise exc.HTTPBadRequest(explanation=msg)
self.share_rpcapi.activate_network(context, id, data)
return self._view_builder.build_share_network(share_network)
def _deactivate(self, req, id, data):
context = req.environ['manila.context']
policy.check_policy(context, RESOURCE_NAME, 'deactivate')
try:
share_network = db_api.share_network_get(context, id)
except exception.ShareNetworkNotFound as e:
msg = _("Share-network was not found. %s") % e
raise exc.HTTPNotFound(explanation=msg)
if share_network['status'] != constants.STATUS_ACTIVE:
msg = _("Share network should be 'ACTIVE'.")
raise exc.HTTPBadRequest(explanation=msg)
if len(share_network['shares']) > 0:
msg = _("Share network is in use.")
raise exc.HTTPBadRequest(explanation=msg)
self.share_rpcapi.deactivate_network(context, id)
return self._view_builder.build_share_network(share_network)
def create_resource():
return wsgi.Resource(ShareNetworkController())

View File

@ -22,6 +22,7 @@ from manila.api import common
from manila.api.openstack import wsgi
from manila.api.views import shares as share_views
from manila.api import xmlutil
from manila.common import constants
from manila import exception
from manila.openstack.common import log as logging
from manila import share
@ -201,10 +202,15 @@ class ShareController(wsgi.Controller):
share_network_id = share.get('share_network_id')
if share_network_id:
try:
self.share_api.db.share_network_get(context, share_network_id)
share_network = self.share_api.db.share_network_get(
context,
share_network_id)
except exception.ShareNetworkNotFound as e:
msg = "%s" % e
raise exc.HTTPNotFound(explanation=msg)
if share_network['status'] == constants.STATUS_ERROR:
msg = _("Share network is in 'ERROR' state.")
raise exc.HTTPBadRequest(explanation=msg)
else:
kwargs['share_network_id'] = share_network_id

View File

@ -141,11 +141,15 @@ class ShareDriver(object):
return self._stats
def get_network_allocations_number(self):
"""Returns number of network allocations for creating VIFs"""
"""Returns number of network allocations for creating VIFs."""
pass
def setup_network(self, network_info):
"""Set up and configures VIFs with given network parameters"""
def setup_network(self, network_info, metadata=None):
"""Set up and configures VIFs with given network parameters."""
pass
def teardown_network(self, network_info):
"""Teardown previously configured VIFs for given network parameters."""
pass
def _update_share_status(self):

View File

@ -93,19 +93,6 @@ class ShareManager(manager.SchedulerDependentManager):
self.publish_service_capabilities(ctxt)
def _setup_share_network(self, context, network_ref):
allocation_number = self.driver.get_network_allocations_number()
if allocation_number:
network_info = self.network_api.allocate_network(
context, network_ref, count=allocation_number)
try:
self.driver.setup_network(network_info)
return network_info
except exception.ManilaException as e:
with excutils.save_and_reraise_exception():
self.db.share_network_update(context, network_ref['id'],
{'status': 'error'})
def create_share(self, context, share_id, request_spec=None,
filter_properties=None, snapshot_id=None):
"""Creates a share."""
@ -119,23 +106,18 @@ class ShareManager(manager.SchedulerDependentManager):
else:
snapshot_ref = None
network_id = share_ref.get('share_network_id', None)
if network_id:
network_ref = self.db.share_network_get(
context, share_ref['share_network_id'])
if network_ref['status'] != constants.STATUS_ACTIVE:
if network_ref['status'] in [constants.STATUS_INACTIVE,
constants.STATUS_NEW]:
network_ref = self._setup_share_network(context,
network_ref)
else:
msg = _("Network status should be ACTIVE, INACTIVE or NEW")
LOG.error(msg)
raise exception.InvalidShareNetwork(reason=msg)
share_network_id = share_ref.get('share_network_id', None)
if share_network_id:
share_network = self.db.share_network_get(context,
share_network_id)
if share_network['status'] == constants.STATUS_INACTIVE:
share_network = self._activate_share_network(
context,
share_network)
else:
network_ref = {}
share_network = {}
share_ref['network_info'] = network_ref
share_ref['network_info'] = share_network
try:
if snapshot_ref:
@ -283,3 +265,28 @@ class ShareManager(manager.SchedulerDependentManager):
"""Collect driver status and then publish it."""
self._report_driver_status(context)
self._publish_service_capabilities(context)
def activate_network(self, context, share_network_id, metadata=None):
share_network = self.db.share_network_get(context, share_network_id)
self._activate_share_network(context, share_network, metadata)
def deactivate_network(self, context, share_network_id):
share_network = self.db.share_network_get(context, share_network_id)
self.driver.teardown_network(share_network)
self.network_api.deallocate_network(context, share_network)
def _activate_share_network(self, context, share_network, metadata=None):
allocation_number = self.driver.get_network_allocations_number()
if allocation_number:
share_network = self.network_api.allocate_network(
context,
share_network,
count=allocation_number)
try:
self.driver.setup_network(share_network, metadata=metadata)
except exception.ManilaException:
with excutils.save_and_reraise_exception():
self.network_api.deallocate_network(context,
share_network)
else:
return share_network

View File

@ -91,3 +91,16 @@ class ShareAPI(manila.openstack.common.rpc.proxy.RpcProxy):
def publish_service_capabilities(self, ctxt):
self.fanout_cast(ctxt, self.make_msg('publish_service_capabilities'),
version='1.0')
def activate_network(self, context, share_network_id, metadata):
self.fanout_cast(context,
self.make_msg('activate_network',
share_network_id=share_network_id,
metadata=metadata),
version='1.0')
def deactivate_network(self, context, share_network_id):
self.fanout_cast(context,
self.make_msg('deactivate_network',
share_network_id=share_network_id),
version='1.0')

View File

@ -21,6 +21,7 @@ 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 import policy
from manila.tests.api import fakes
@ -274,3 +275,159 @@ class ShareNetworkAPITest(unittest.TestCase):
self.req,
share_nw,
body)
def test_action_add_security_service(self):
share_network_id = 'fake network id'
security_service_id = 'fake ss id'
body = {'add_security_service': {'security_service_id':
security_service_id}}
with mock.patch.object(self.controller, '_add_security_service',
mock.Mock()):
self.controller.action(self.req, share_network_id, body)
self.controller._add_security_service.assert_called_once_with(
self.req, share_network_id, body['add_security_service'])
def test_action_remove_security_service(self):
share_network_id = 'fake network id'
security_service_id = 'fake ss id'
body = {'remove_security_service': {'security_service_id':
security_service_id}}
with mock.patch.object(self.controller, '_remove_security_service',
mock.Mock()):
self.controller.action(self.req, share_network_id, body)
self.controller._remove_security_service.assert_called_once_with(
self.req, share_network_id, body['remove_security_service'])
def test_action_activate(self):
share_network_id = 'fake network id'
body = {'activate': {}}
with mock.patch.object(self.controller, '_activate', mock.Mock()):
self.controller.action(self.req, share_network_id, body)
self.controller._activate.assert_called_once_with(
self.req, share_network_id, body['activate'])
def test_action_deactivate(self):
share_network_id = 'fake network id'
body = {'deactivate': {}}
with mock.patch.object(self.controller, '_deactivate', mock.Mock()):
self.controller.action(self.req, share_network_id, body)
self.controller._deactivate.assert_called_once_with(
self.req, share_network_id, body['deactivate'])
def test_action_bad_request(self):
share_network_id = 'fake network id'
body = {'bad_action': {}}
self.assertRaises(webob_exc.HTTPBadRequest,
self.controller.action,
self.req,
share_network_id,
body)
@mock.patch.object(db_api, 'share_network_get',
mock.Mock(return_value=fake_share_network))
@mock.patch.object(policy, 'check_policy', mock.Mock())
def test_activate(self):
share_network_id = 'fake network id'
with mock.patch.object(self.controller.share_rpcapi,
'activate_network', mock.Mock()):
self.controller._activate(self.req, share_network_id, {})
policy.check_policy.assert_called_once_with(
self.context,
share_networks.RESOURCE_NAME,
'activate')
db_api.share_network_get.assert_called_once_with(
self.context,
share_network_id)
self.controller.share_rpcapi.activate_network.\
assert_called_once_with(self.context, share_network_id, {})
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
def test_activate_not_found(self):
share_network_id = 'fake network id'
db_api.share_network_get.side_effect = \
exception.ShareNetworkNotFound(share_network_id=share_network_id)
self.assertRaises(webob_exc.HTTPNotFound,
self.controller._activate,
self.req,
share_network_id,
{})
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
def test_activate_not_inactive(self):
share_network_id = 'fake network id'
share_network = fake_share_network.copy()
share_network['status'] = constants.STATUS_ERROR
db_api.share_network_get.return_value = share_network
self.assertRaises(webob_exc.HTTPBadRequest,
self.controller._activate,
self.req,
share_network_id,
{})
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
@mock.patch.object(policy, 'check_policy', mock.Mock())
def test_deactivate(self):
share_network_id = 'fake network id'
share_network = fake_share_network.copy()
share_network['status'] = constants.STATUS_ACTIVE
db_api.share_network_get.return_value = share_network
with mock.patch.object(self.controller.share_rpcapi,
'deactivate_network', mock.Mock()):
self.controller._deactivate(self.req, share_network_id, None)
policy.check_policy.assert_called_once_with(
self.context,
share_networks.RESOURCE_NAME,
'deactivate')
db_api.share_network_get.assert_called_once_with(
self.context,
share_network_id)
self.controller.share_rpcapi.deactivate_network.\
assert_called_once_with(self.context, share_network_id)
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
def test_deactivate_not_found(self):
share_network_id = 'fake network id'
db_api.share_network_get.side_effect = \
exception.ShareNetworkNotFound(share_network_id=share_network_id)
self.assertRaises(webob_exc.HTTPNotFound,
self.controller._deactivate,
self.req,
share_network_id,
None)
@mock.patch.object(db_api, 'share_network_get',
mock.Mock(return_value=fake_share_network))
def test_deactivate_not_active(self):
share_network_id = 'fake network id'
self.assertRaises(webob_exc.HTTPBadRequest,
self.controller._deactivate,
self.req,
share_network_id,
None)
@mock.patch.object(db_api, 'share_network_get', mock.Mock())
def test_deactivate_in_use(self):
share_network_id = 'fake network id'
share_network = fake_share_network.copy()
share_network['shares'].append('fake share')
db_api.share_network_get.return_value = share_network
self.assertRaises(webob_exc.HTTPBadRequest,
self.controller._deactivate,
self.req,
share_network_id,
None)

View File

@ -73,6 +73,9 @@ class FakeShareDriver(object):
def setup_network(self, context, network, policy=None):
pass
def teardown_network(self, context, network):
pass
def get_network_allocations_number(self):
pass
@ -369,23 +372,85 @@ class ShareTestCase(test.TestCase):
self.share.network_api.allocate_network = mock.Mock(
return_value={'network_info': 'network_info'})
self.share.driver.setup_network = mock.Mock()
self.share._setup_share_network(self.context, network_info)
self.share._activate_share_network(self.context, network_info)
self.share.network_api.allocate_network.assert_called_once_with(
self.context, network_info, count=555)
self.share.driver.setup_network.assert_called_once_with(
{'network_info': 'network_info'})
{'network_info': 'network_info'}, metadata=None)
def test_setup_share_network_error(self):
network_info = {'fake': 'fake', 'id': 'fakeid'}
self.share.driver.get_network_allocations_number = mock.Mock(
return_value=555)
self.share.network_api.allocate_network = mock.Mock(
return_value={'network_info': 'network_info'})
self.share.driver.setup_network = mock.Mock(
side_effect=exception.Invalid)
self.share.db.share_network_update = mock.Mock()
self.assertRaises(exception.Invalid,
self.share._setup_share_network,
self.context, network_info)
self.share.db.share_network_update.assert_called_once_with(
self.context, 'fakeid', {'status': 'error'})
drv_allocation_cnt = mock.patch.object(
self.share.driver,
'get_network_allocations_number').start()
drv_allocation_cnt.return_value = 555
nw_api_allocate_nw = mock.patch.object(self.share.network_api,
'allocate_network').start()
nw_api_allocate_nw.return_value = network_info
nw_api_deallocate_nw = mock.patch.object(self.share.network_api,
'deallocate_network').start()
with mock.patch.object(self.share.driver, 'setup_network',
mock.Mock(side_effect=exception.Invalid)):
self.assertRaises(exception.Invalid,
self.share._activate_share_network,
self.context, network_info)
nw_api_deallocate_nw.assert_called_once_with(self.context,
network_info)
drv_allocation_cnt.stop()
nw_api_allocate_nw.stop()
nw_api_deallocate_nw.stop()
def test_activate_network(self):
share_network_id = 'fake network id'
share_network = {}
db_share_nw_get = mock.patch.object(self.share.db,
'share_network_get').start()
db_share_nw_get.return_value = share_network
drv_get_alloc_cnt = mock.patch.object(
self.share.driver,
'get_network_allocations_number').start()
drv_get_alloc_cnt.return_value = 1
nw_api_allocate_nw = mock.patch.object(self.share.network_api,
'allocate_network').start()
nw_api_allocate_nw.return_value = share_network
with mock.patch.object(self.share.driver, 'setup_network',
mock.Mock()):
self.share.activate_network(self.context, share_network_id)
db_share_nw_get.assert_called_once_with(self.context,
share_network_id)
drv_get_alloc_cnt.assert_any_call()
nw_api_allocate_nw.assert_called_once_with(self.context,
share_network,
count=1)
self.share.driver.setup_network.assert_called_once_with(
share_network,
metadata=None)
db_share_nw_get.stop()
drv_get_alloc_cnt.stop()
nw_api_allocate_nw.stop()
def test_deactivate_network(self):
share_network_id = 'fake network id'
share_network = {}
db_share_nw_get = mock.patch.object(self.share.db,
'share_network_get').start()
db_share_nw_get.return_value = share_network
nw_api_deallocate_nw = mock.patch.object(self.share.network_api,
'deallocate_network').start()
with mock.patch.object(self.share.driver, 'teardown_network',
mock.Mock()):
self.share.deactivate_network(self.context, share_network_id)
db_share_nw_get.assert_called_once_with(self.context,
share_network_id)
nw_api_deallocate_nw.assert_called_once_with(self.context,
share_network)
self.share.driver.teardown_network.assert_called_once_with(
share_network)
db_share_nw_get.stop()
nw_api_deallocate_nw.stop()