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' ...@@ -31,5 +31,4 @@ PASTE_INI = '/home/user/snf-occi/ci/soi.ini'
# Volume type=2, archipelago # Volume type=2, archipelago
VOLUME_TYPE = 2 VOLUME_TYPE = 2
DISABLE_STORAGE_LINK_CREATION = False DISABLED_METHOD = ()
DISABLE_STORAGE_LINK_DELETION = False
...@@ -15,21 +15,25 @@ ...@@ -15,21 +15,25 @@
from soi.config import VOLUME_TYPE from soi.config import VOLUME_TYPE
def _openstackify_volumes_display_names(response): def _openstackify_volumes_info(volumes):
"""Add a key called 'displayName'(this is used by OpenStack) and """Adjust server_id, device_index, volume_id to OpensStack"""
place the value of Synnefo's response key (display_name)""" for volume in volumes:
volume['displayName'] = volume['display_name']
for volume_info in response: for attachment in volume['attachments']:
volume_info['displayName'] = volume_info['display_name'] attachment['serverId'] = attachment['server_id']
attachment['device'] = attachment['device_index']
attachment['volumeId'] = attachment['volume_id']
def snf_get_volumes(cls, req): def snf_get_volumes(cls, req):
"""Synnefo: list volumes""" """Synnefo: list volumes"""
req.environ['service_type'] = 'volume' req.environ['service_type'] = 'volume'
req.environ['method_name'] = 'volumes_get' req.environ['method_name'] = 'volumes_get'
req.environ['kwargs'] = {'detail': True}
response = req.get_response(cls.app) response = req.get_response(cls.app)
r = cls.get_from_response(response, "volumes", []) r = cls.get_from_response(response, "volumes", [])
_openstackify_volumes_display_names(r) _openstackify_volumes_info(r)
return r return r
......
...@@ -12,32 +12,10 @@ ...@@ -12,32 +12,10 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from soi import config from soi.utils import check_activation
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
@check_activation
def snf_get_server_volume_links(cls, req, server_id): def snf_get_server_volume_links(cls, req, server_id):
"""Synnefo: Get volumes attached to a server""" """Synnefo: Get volumes attached to a server"""
req.environ['service_type'] = 'compute' req.environ['service_type'] = 'compute'
...@@ -48,15 +26,11 @@ def snf_get_server_volume_links(cls, req, server_id): ...@@ -48,15 +26,11 @@ def snf_get_server_volume_links(cls, req, server_id):
return r return r
@check_activation
def snf_create_server_volume_link(cls, req, server_id, volume_id, def snf_create_server_volume_link(cls, req, server_id, volume_id,
dev=None): dev=None):
"""Synnefo: Attach a volume to a server""" """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) project_id = req.environ.get('HTTP_X_PROJECT_ID', None)
req.environ['service_type'] = 'compute' req.environ['service_type'] = 'compute'
...@@ -70,13 +44,9 @@ def snf_create_server_volume_link(cls, req, server_id, volume_id, ...@@ -70,13 +44,9 @@ def snf_create_server_volume_link(cls, req, server_id, volume_id,
return r return r
@check_activation
def snf_delete_server_volumes_link(cls, req, server_id, volume_id): def snf_delete_server_volumes_link(cls, req, server_id, volume_id):
"""Synnefo: Delete a volume attachment""" """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['service_type'] = 'compute'
req.environ['method_name'] = 'volume_attachment_delete' req.environ['method_name'] = 'volume_attachment_delete'
req.environ['kwargs'] = {'server_id': server_id, req.environ['kwargs'] = {'server_id': server_id,
...@@ -85,7 +55,6 @@ def snf_delete_server_volumes_link(cls, req, server_id, volume_id): ...@@ -85,7 +55,6 @@ def snf_delete_server_volumes_link(cls, req, server_id, volume_id):
function_map = { function_map = {
'get_volumes': snf_get_all_volume_links,
'get_server_volumes_link': snf_get_server_volume_links, 'get_server_volumes_link': snf_get_server_volume_links,
'create_server_volumes_link': snf_create_server_volume_link, 'create_server_volumes_link': snf_create_server_volume_link,
'delete_server_volumes_link': snf_delete_server_volumes_link, 'delete_server_volumes_link': snf_delete_server_volumes_link,
......
...@@ -17,20 +17,52 @@ from soi import storage ...@@ -17,20 +17,52 @@ from soi import storage
from mock import patch from mock import patch
def test_openstackify_volumes_display_names(): def test_openstackify_volumes_info():
"""Test _openstackify_volumes_display_names helper method""" """Test _openstackify_volumes_info helper method"""
response_result = [{'display_name': 'boot volume', 'id': '5609', }, volumes_before = [{'status': 'in_use',
{'display_name': None, 'id': '67712'}] 'user_id': '3141d95c-81fb-472f-a31a-acb4f6998b06',
openstackified_result = [{'display_name': 'boot volume', 'display_name': 'name1',
'displayName': 'boot volume', 'id': '5609'}, 'attachments': [{'server_id': '9499',
{'display_name': None, 'displayName': None, 'device_index': 0,
'id': '67712'}] '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) volumes_after = [{'status': 'in_use',
assert response_result == openstackified_result '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.DummyClass.get_from_response', return_value='g f r')
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response') @patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_get_volumes(gr, gfr, _ovdns): def test_snf_get_volumes(gr, gfr, _ovdns):
...@@ -39,7 +71,9 @@ 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) storage.snf_get_volumes(cls, req)
assert req.environ == dict( assert req.environ == dict(
service_type='volume', service_type='volume',
method_name='volumes_get') method_name='volumes_get',
kwargs={'detail': True}
)
gr.assert_called_once_with(cls.app) gr.assert_called_once_with(cls.app)
gfr.assert_called_once_with('my response', 'volumes', []) gfr.assert_called_once_with('my response', 'volumes', [])
_ovdns.assert_called_once_with('g f r') _ovdns.assert_called_once_with('g f r')
......
...@@ -19,72 +19,14 @@ import webob.exc ...@@ -19,72 +19,14 @@ import webob.exc
from nose.tools import assert_raises 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.DummyClass.get_from_response')
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response') @patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_get_server_volume_links(gr, gfr): def test_snf_get_server_volume_links(gr, gfr):
"""Test snf_get_server_volume_links method""" """Test snf_get_server_volume_links method"""
DISABLED_METHODS = ()
setattr(config, 'DISABLED_METHODS', DISABLED_METHODS)
cls, req = fakes.DummyClass(), fakes.FakeReq() cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234' server_id = '1234'
storage_link.snf_get_server_volume_links(cls, req, server_id) storage_link.snf_get_server_volume_links(cls, req, server_id)
...@@ -97,11 +39,27 @@ def test_snf_get_server_volume_links(gr, gfr): ...@@ -97,11 +39,27 @@ def test_snf_get_server_volume_links(gr, gfr):
gfr.assert_called_once_with('my response', 'volumeAttachments', []) 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.DummyClass.get_from_response')
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response') @patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_create_server_volume_link(gr, gfr): def test_snf_create_server_volume_link(gr, gfr):
"""Test snf_create_server_volume_link method""" """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() cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234' server_id = '1234'
volume_id = '666' volume_id = '666'
...@@ -125,7 +83,9 @@ def test_snf_create_server_volume_link(gr, gfr): ...@@ -125,7 +83,9 @@ def test_snf_create_server_volume_link(gr, gfr):
def test_snf_create_server_volume_link_disabled(): def test_snf_create_server_volume_link_disabled():
"""Test snf_create_server_volume_link method 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() cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234' server_id = '1234'
volume_id = '666' volume_id = '666'
...@@ -141,7 +101,9 @@ def test_snf_create_server_volume_link_disabled(): ...@@ -141,7 +101,9 @@ def test_snf_create_server_volume_link_disabled():
@patch('soi.tests.fakes.FakeReq.get_response', return_value='my response') @patch('soi.tests.fakes.FakeReq.get_response', return_value='my response')
def test_snf_delete_server_volumes_link(gr): def test_snf_delete_server_volumes_link(gr):
"""Test snf_delete_server_volumes_link method""" """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() cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234' server_id = '1234'
volume_id = '666' volume_id = '666'
...@@ -158,7 +120,9 @@ def test_snf_delete_server_volumes_link(gr): ...@@ -158,7 +120,9 @@ def test_snf_delete_server_volumes_link(gr):
def test_snf_delete_server_volumes_link_disabled(): def test_snf_delete_server_volumes_link_disabled():
"""Test snf_delete_server_volumes_link method""" """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() cls, req = fakes.DummyClass(), fakes.FakeReq()
server_id = '1234' server_id = '1234'
volume_id = '666' volume_id = '666'
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # 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): def patch_class_methods(cls, function_map):
...@@ -29,3 +32,16 @@ def empty_list_200(cls, req): ...@@ -29,3 +32,16 @@ def empty_list_200(cls, req):
req.environ['method_name'] = 'empty_list' req.environ['method_name'] = 'empty_list'
response = req.get_response(cls.app) response = req.get_response(cls.app)
return cls.get_from_response(response, 'empty list', []) 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