Commit 7b2a99f9 authored by Kostas Vogias's avatar Kostas Vogias Committed by Stavros Sachtouris

Implement decorator for deactivating methods

Allow admins to declare which methods they like to disable.
Also, group common storage funcs to run from one place.
parent c325b33a
......@@ -31,5 +31,4 @@ PASTE_INI = '/home/user/snf-occi/ci/soi.ini'
# Volume type=2, archipelago
VOLUME_TYPE = 2
DISABLE_STORAGE_LINK_CREATION = False
DISABLE_STORAGE_LINK_DELETION = False
DISABLED_METHOD = ()
......@@ -15,21 +15,25 @@
from soi.config import VOLUME_TYPE
def _openstackify_volumes_display_names(response):
"""Add a key called 'displayName'(this is used by OpenStack) and
place the value of Synnefo's response key (display_name)"""
for volume_info in response:
volume_info['displayName'] = volume_info['display_name']
def _openstackify_volumes_info(volumes):
"""Adjust server_id, device_index, volume_id to OpensStack"""
for volume in volumes:
volume['displayName'] = volume['display_name']
for attachment in volume['attachments']:
attachment['serverId'] = attachment['server_id']
attachment['device'] = attachment['device_index']
attachment['volumeId'] = attachment['volume_id']
def snf_get_volumes(cls, req):
"""Synnefo: list volumes"""
req.environ['service_type'] = 'volume'
req.environ['method_name'] = 'volumes_get'
req.environ['kwargs'] = {'detail': True}
response = req.get_response(cls.app)
r = cls.get_from_response(response, "volumes", [])
_openstackify_volumes_display_names(r)
_openstackify_volumes_info(r)
return r
......
......@@ -12,32 +12,10 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from soi import config
import webob.exc
def _openstackify_volumes_info(volumes):
"""Adjust server_id, device_index, volume_id to OpensStack"""
for volume in volumes:
volume['displayName'] = volume['display_name']
for attachment in volume['attachments']:
attachment['serverId'] = attachment['server_id']
attachment['device'] = attachment['device_index']
attachment['volumeId'] = attachment['volume_id']
def snf_get_all_volume_links(cls, req):
"""Synnefo: get all volume attachments """
req.environ['service_type'] = 'volume'
req.environ['method_name'] = 'volumes_get'
req.environ['kwargs'] = {'detail': True}
response = req.get_response(cls.app)
r = cls.get_from_response(response, "volumes", [])
_openstackify_volumes_info(r)
return r
from soi.utils import check_activation
@check_activation
def snf_get_server_volume_links(cls, req, server_id):
"""Synnefo: Get volumes attached to a server"""
req.environ['service_type'] = 'compute'
......@@ -48,15 +26,11 @@ def snf_get_server_volume_links(cls, req, server_id):
return r
@check_activation
def snf_create_server_volume_link(cls, req, server_id, volume_id,
dev=None):
"""Synnefo: Attach a volume to a server"""
if config.DISABLE_STORAGE_LINK_CREATION:
msg = 'attaching a volume to a server'
raise webob.exc.HTTPNotImplemented(
explanation="Method for {0} is not supported".format(msg))
project_id = req.environ.get('HTTP_X_PROJECT_ID', None)
req.environ['service_type'] = 'compute'
......@@ -70,13 +44,9 @@ def snf_create_server_volume_link(cls, req, server_id, volume_id,
return r
@check_activation
def snf_delete_server_volumes_link(cls, req, server_id, volume_id):
"""Synnefo: Delete a volume attachment"""
if config.DISABLE_STORAGE_LINK_DELETION:
msg = 'deleting a server`s volume link'
raise webob.exc.HTTPNotImplemented(
explanation="Method for {0} is not supported".format(msg))
req.environ['service_type'] = 'compute'
req.environ['method_name'] = 'volume_attachment_delete'
req.environ['kwargs'] = {'server_id': server_id,
......@@ -85,7 +55,6 @@ def snf_delete_server_volumes_link(cls, req, server_id, volume_id):
function_map = {
'get_volumes': snf_get_all_volume_links,
'get_server_volumes_link': snf_get_server_volume_links,
'create_server_volumes_link': snf_create_server_volume_link,
'delete_server_volumes_link': snf_delete_server_volumes_link,
......
......@@ -17,20 +17,52 @@ from soi import storage
from mock import patch
def test_openstackify_volumes_display_names():
"""Test _openstackify_volumes_display_names helper method"""
response_result = [{'display_name': 'boot volume', 'id': '5609', },
{'display_name': None, 'id': '67712'}]
openstackified_result = [{'display_name': 'boot volume',
'displayName': 'boot volume', 'id': '5609'},
{'display_name': None, 'displayName': None,
'id': '67712'}]
def test_openstackify_volumes_info():
"""Test _openstackify_volumes_info helper method"""
volumes_before = [{'status': 'in_use',
'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
'display_name': 'name1',
'attachments': [{'server_id': '9499',
'device_index': 0,
'volume_id': '5609'}]},
{'status': 'in_use',
'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
'display_name': 'name2',
'attachments': [{'server_id': '681849',
'device_index': 0,
'volume_id': '67712'}]
}]
storage._openstackify_volumes_display_names(response_result)
assert response_result == openstackified_result
volumes_after = [{'status': 'in_use',
'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
'display_name': 'name1',
'displayName': 'name1',
'attachments': [{
'server_id': '9499',
'serverId': '9499',
'device_index': 0,
'device': 0,
'volume_id': '5609',
'volumeId': '5609'
}]},
{'status': 'in_use',
'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
'display_name': 'name2',
'displayName': 'name2',
'attachments': [{
'server_id': '681849',
'device_index': 0,
'volume_id': '67712',
'serverId': '681849',
'device': 0,
'volumeId': '67712'
}]
}]
storage._openstackify_volumes_info(volumes_before)
assert volumes_before == volumes_after
@patch('soi.storage._openstackify_volumes_display_names')
@patch('soi.storage._openstackify_volumes_info')
@patch('soi.tests.fakes.DummyClass.get_from_response', return_value='g f r')
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_get_volumes(gr, gfr, _ovdns):
......@@ -39,7 +71,9 @@ def test_snf_get_volumes(gr, gfr, _ovdns):
storage.snf_get_volumes(cls, req)
assert req.environ == dict(
service_type='volume',
method_name='volumes_get')
method_name='volumes_get',
kwargs={'detail': True}
)
gr.assert_called_once_with(cls.app)
gfr.assert_called_once_with('my response', 'volumes', [])
_ovdns.assert_called_once_with('g f r')
......
......@@ -19,72 +19,14 @@ import webob.exc
from nose.tools import assert_raises
def test_openstackify_volumes_info():
"""Test _openstackify_volumes_info helper method"""
volumes_before = [{'status': 'in_use',
'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
'display_name': 'name1',
'attachments': [{'server_id': '9499',
'device_index': 0,
'volume_id': '5609'}]},
{'status': 'in_use',
'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
'display_name': 'name2',
'attachments': [{'server_id': '681849',
'device_index': 0,
'volume_id': '67712'}]
}]
volumes_after = [{'status': 'in_use',
'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
'display_name': 'name1',
'displayName': 'name1',
'attachments': [{
'server_id': '9499',
'serverId': '9499',
'device_index': 0,
'device': 0,
'volume_id': '5609',
'volumeId': '5609'
}]},
{'status': 'in_use',
'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
'display_name': 'name2',
'displayName': 'name2',
'attachments': [{
'server_id': '681849',
'device_index': 0,
'volume_id': '67712',
'serverId': '681849',
'device': 0,
'volumeId': '67712'
}]
}]
storage_link._openstackify_volumes_info(volumes_before)
assert volumes_before == volumes_after
@patch('soi.storage_link._openstackify_volumes_info')
@patch('soi.tests.fakes.DummyClass.get_from_response', return_value='g f r')
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_get_all_volume_links(gr, gfr, ovi):
"""Test snf_get_all_volume_links method"""
cls, req = fakes.DummyClass(), fakes.FakeReq()
storage_link.snf_get_all_volume_links(cls, req)
assert req.environ == dict(
service_type='volume',
method_name='volumes_get',
kwargs={'detail': True}
)
gr.assert_called_once_with(cls.app)
gfr.assert_called_once_with('my response', 'volumes', [])
ovi.assert_called_once_with('g f r')
@patch('soi.tests.fakes.DummyClass.get_from_response')
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_get_server_volume_links(gr, gfr):
"""Test snf_get_server_volume_links method"""
DISABLED_METHODS = ()
setattr(config, 'DISABLED_METHODS', DISABLED_METHODS)
cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234'
storage_link.snf_get_server_volume_links(cls, req, server_id)
......@@ -97,11 +39,27 @@ def test_snf_get_server_volume_links(gr, gfr):
gfr.assert_called_once_with('my response', 'volumeAttachments', [])
def test_snf_get_server_volume_links_disabled():
"""Test snf_get_server_volume_links method"""
DISABLED_METHODS = ('snf_get_server_volume_links')
setattr(config, 'DISABLED_METHODS', DISABLED_METHODS)
cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234'
assert_raises(webob.exc.HTTPNotImplemented,
storage_link.snf_get_server_volume_links, cls, req,
server_id)
@patch('soi.tests.fakes.DummyClass.get_from_response')
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_create_server_volume_link(gr, gfr):
"""Test snf_create_server_volume_link method"""
setattr(config, "DISABLE_STORAGE_LINK_CREATION", False)
DISABLED_METHODS = ()
setattr(config, 'DISABLED_METHODS', DISABLED_METHODS)
cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234'
volume_id = '666'
......@@ -125,7 +83,9 @@ def test_snf_create_server_volume_link(gr, gfr):
def test_snf_create_server_volume_link_disabled():
"""Test snf_create_server_volume_link method disabled"""
setattr(config, "DISABLE_STORAGE_LINK_CREATION", True)
DISABLED_METHODS = ('snf_create_server_volume_link')
setattr(config, 'DISABLED_METHODS', DISABLED_METHODS)
cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234'
volume_id = '666'
......@@ -141,7 +101,9 @@ def test_snf_create_server_volume_link_disabled():
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_delete_server_volumes_link(gr):
"""Test snf_delete_server_volumes_link method"""
setattr(config, "DISABLE_STORAGE_LINK_DELETION", False)
DISABLED_METHODS = ()
setattr(config, 'DISABLED_METHODS', DISABLED_METHODS)
cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234'
volume_id = '666'
......@@ -158,7 +120,9 @@ def test_snf_delete_server_volumes_link(gr):
def test_snf_delete_server_volumes_link_disabled():
"""Test snf_delete_server_volumes_link method"""
setattr(config, "DISABLE_STORAGE_LINK_DELETION", True)
DISABLED_METHODS = ('snf_delete_server_volumes_link')
setattr(config, 'DISABLED_METHODS', DISABLED_METHODS)
cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234'
volume_id = '666'
......
......@@ -12,6 +12,9 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from functools import wraps
import webob.exc
import config
def patch_class_methods(cls, function_map):
......@@ -29,3 +32,16 @@ def empty_list_200(cls, req):
req.environ['method_name'] = 'empty_list'
response = req.get_response(cls.app)
return cls.get_from_response(response, 'empty list', [])
def check_activation(func):
@wraps(func)
def wrapper(*args, **kwargs):
disabled_methods = getattr(config, 'DISABLED_METHODS', None)
func_full_name = func.__module__ + '.' + func.__name__
if disabled_methods and func_full_name in disabled_methods:
raise webob.exc.HTTPNotImplemented(
explanation="Method: {0} is disabled".
format(func_full_name))
return func(*args, **kwargs)
return wrapper
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment