Merge "Add share network activate and deactivate"
This commit is contained in:
commit
ebda4e3a14
|
@ -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": []
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue