from cinder.volume import configuration as conf
from cinder.volume.drivers import coraid
from cinder.volume.drivers.coraid import CoraidDriver
+from cinder.volume.drivers.coraid import CoraidESMException
from cinder.volume.drivers.coraid import CoraidRESTClient
import cookielib
fake_esm_ipaddress = "192.168.0.1"
-fake_esm_username = "admin"
+fake_esm_username = "darmok"
+fake_esm_group = "tanagra"
fake_esm_password = "12345678"
fake_volume_name = "volume-12345678-1234-1234-1234-1234567890ab"
"metaCROp": "noAction",
"message": None}
+fake_group_fullpath = "admin group:%s" % (fake_esm_group)
+fake_group_id = 4
+fake_login_reply = {"values": [
+ {"fullPath": fake_group_fullpath,
+ "groupId": fake_group_id}],
+ "message": "",
+ "state": "adminSucceed",
+ "metaCROp": "noAction"}
+
+fake_group_fail_fullpath = "fail group:%s" % (fake_esm_group)
+fake_group_fail_id = 5
+fake_login_reply_group_fail = {"values": [
+ {"fullPath": fake_group_fail_fullpath,
+ "groupId": fake_group_fail_id}],
+ "message": "",
+ "state": "adminSucceed",
+ "metaCROp": "noAction"}
+
class TestCoraidDriver(test.TestCase):
def setUp(self):
configuration.append_config_values(mox.IgnoreArg())
configuration.coraid_esm_address = fake_esm_ipaddress
configuration.coraid_user = fake_esm_username
+ configuration.coraid_group = fake_esm_group
configuration.coraid_password = fake_esm_password
self.drv = CoraidDriver(configuration=configuration)
lambda *_, **__: self.rest_mock)
self.drv = CoraidRESTClient(fake_esm_ipaddress,
fake_esm_username,
+ fake_esm_group,
fake_esm_password)
+ def test__get_group_id(self):
+ setattr(self.rest_mock, '_get_group_id',
+ lambda *_: True)
+ self.assertEquals(self.drv._get_group_id(fake_esm_group,
+ fake_login_reply),
+ fake_group_id)
+
+ def test__set_group(self):
+ setattr(self.rest_mock, '_set_group',
+ lambda *_: fake_group_id)
+ self.stubs.Set(CoraidRESTClient, '_esm',
+ lambda *_: fake_login_reply)
+ self.drv._set_group(fake_login_reply)
+
+ def test__set_group_fails_no_group(self):
+ setattr(self.rest_mock, '_set_group',
+ lambda *_: False)
+ self.stubs.Set(CoraidRESTClient, '_esm',
+ lambda *_: fake_login_reply_group_fail)
+ self.assertRaises(CoraidESMException,
+ self.drv._set_group,
+ fake_login_reply_group_fail)
+
def test__configure(self):
setattr(self.rest_mock, '_configure',
lambda *_: True)
Desc : Driver to store volumes on Coraid Appliances.
Require : Coraid EtherCloud ESM, Coraid VSX and Coraid SRX.
Author : Jean-Baptiste RANSY <openstack@alyseo.com>
+Contrib : Larry Matter <support@coraid.com>
"""
import cookielib
cfg.StrOpt('coraid_user',
default='admin',
help='User name to connect to Coraid ESM'),
+ cfg.StrOpt('coraid_group',
+ default=False,
+ help='Group name of coraid_user (must have admin privilege)'),
cfg.StrOpt('coraid_password',
default='password',
help='Password to connect to Coraid ESM'),
class CoraidRESTClient(object):
"""Executes volume driver commands on Coraid ESM EtherCloud Appliance."""
- def __init__(self, ipaddress, user, password):
+ def __init__(self, ipaddress, user, group, password):
self.url = "https://%s:8443/" % ipaddress
self.user = user
+ self.group = group
self.password = password
self.session = False
self.cookiejar = cookielib.CookieJar()
self.session = time.time() + 1100
msg = _('Update session cookie %(session)s')
LOG.debug(msg % dict(session=self.session))
+ self._set_group(reply)
return True
else:
errmsg = response.get('message', '')
raise CoraidESMException(msg % dict(message=errmsg))
return True
+ def _set_group(self, reply):
+ """Set effective group."""
+ if self.group:
+ group = self.group
+ groupId = self._get_group_id(group, reply)
+ if groupId:
+ url = ('admin?op=setRbacGroup&groupId=%s' % (groupId))
+ data = 'Group'
+ reply = self._esm(url, data)
+ if reply.get('state') == 'adminSucceed':
+ return True
+ else:
+ errmsg = reply.get('message', '')
+ msg = _('Error while trying to set group: %(message)s')
+ raise CoraidRESTException(msg % dict(message=errmsg))
+ else:
+ msg = _('Unable to find group: %(group)s')
+ raise CoraidESMException(msg % dict(group=group))
+ return True
+
+ def _get_group_id(self, groupName, loginResult):
+ """Map group name to group ID."""
+ # NOTE(lmatter): All other groups are under the admin group
+ fullName = "admin group:%s" % groupName
+ groupId = False
+ for kid in loginResult['values']:
+ fullPath = kid['fullPath']
+ if fullPath == fullName:
+ return kid['groupId']
+ return False
+
def _esm(self, url=False, data=None):
"""
_esm represent the entry point to send requests to ESM Appliance.
"""Initialize the volume driver."""
self.esm = CoraidRESTClient(self.configuration.coraid_esm_address,
self.configuration.coraid_user,
+ self.configuration.coraid_group,
self.configuration.coraid_password)
def check_for_setup_error(self):