Add chap support to CloudByte cinder driver
CloudByte iSCSI cinder driver currently does not support iSCSI CHAP security setting. This opens a security vulnerability whereby any host machine can mount a CloudByte iSCSI volumes created via OpenStack. This patch adds CHAP authentication support for the CloudByte iSCSI cinder driver. Admin has to manually add the auth group and chap username/password in CloudByte storage. Driver uses the first user found in auth group. DocImpact Change-Id: I2c4c8320c7471e5cf2e2e242dbe1729c8974bf28 Implements: blueprint add-chap-authentication-support-to-cloudbyte-cinder-driver
This commit is contained in:
parent
b6681fb3fb
commit
ed3f36bc94
@ -577,6 +577,34 @@ FAKE_UPDATE_QOS_GROUP_RESPONSE = """{ "updateqosresponse" : {
|
||||
}]
|
||||
}}"""
|
||||
|
||||
# A fake list iSCSI auth user response of cloudbyte's elasticenter
|
||||
FAKE_LIST_ISCSI_AUTH_USER_RESPONSE = """{ "listiSCSIAuthUsersResponse" : {
|
||||
"count":1 ,
|
||||
"authuser" : [{
|
||||
"id": "53d00164-a974-31b8-a854-bd346a8ea937",
|
||||
"accountid": "12d41531-c41a-4ab7-abe2-ce0db2570119",
|
||||
"authgroupid": "537744eb-c594-3145-85c0-96079922b894",
|
||||
"chapusername": "fakeauthgroupchapuser",
|
||||
"chappassword": "fakeauthgroupchapsecret",
|
||||
"mutualchapusername": "fakeauthgroupmutualchapuser",
|
||||
"mutualchappassword": "fakeauthgroupmutualchapsecret"
|
||||
}]
|
||||
}}"""
|
||||
|
||||
# A fake list iSCSI auth group response of cloudbyte's elasticenter
|
||||
FAKE_LIST_ISCSI_AUTH_GROUP_RESPONSE = """{ "listiSCSIAuthGroupResponse" : {
|
||||
"count":2 ,
|
||||
"authgroup" : [{
|
||||
"id": "32d935ee-a60f-3681-b792-d8ccfe7e8e7f",
|
||||
"name": "None",
|
||||
"comment": "None"
|
||||
}, {
|
||||
"id": "537744eb-c594-3145-85c0-96079922b894",
|
||||
"name": "fakeauthgroup",
|
||||
"comment": "Fake Auth Group For Openstack "
|
||||
}]
|
||||
}}"""
|
||||
|
||||
|
||||
# This dict maps the http commands of elasticenter
|
||||
# with its respective fake responses
|
||||
@ -588,8 +616,6 @@ MAP_COMMAND_TO_FAKE_RESPONSE["listFileSystem"] = (
|
||||
json.loads(FAKE_LIST_FILE_SYSTEM_RESPONSE))
|
||||
MAP_COMMAND_TO_FAKE_RESPONSE["deleteSnapshot"] = (
|
||||
json.loads(FAKE_DELETE_STORAGE_SNAPSHOT_RESPONSE))
|
||||
MAP_COMMAND_TO_FAKE_RESPONSE["listStorageSnapshots"] = (
|
||||
json.loads(FAKE_LIST_STORAGE_SNAPSHOTS_RESPONSE))
|
||||
MAP_COMMAND_TO_FAKE_RESPONSE["updateVolumeiSCSIService"] = (
|
||||
json.loads(FAKE_UPDATE_VOLUME_ISCSI_SERVICE_RESPONSE))
|
||||
MAP_COMMAND_TO_FAKE_RESPONSE["createStorageSnapshot"] = (
|
||||
@ -616,12 +642,10 @@ MAP_COMMAND_TO_FAKE_RESPONSE['updateQosGroup'] = (
|
||||
json.loads(FAKE_UPDATE_QOS_GROUP_RESPONSE))
|
||||
MAP_COMMAND_TO_FAKE_RESPONSE['listStorageSnapshots'] = (
|
||||
json.loads(FAKE_LIST_STORAGE_SNAPSHOTS_RESPONSE))
|
||||
|
||||
# This dict maps the http commands of elasticenter
|
||||
# with its respective fake json responses
|
||||
MAP_COMMAND_TO_FAKE_JSON_RESPONSE = {}
|
||||
|
||||
MAP_COMMAND_TO_FAKE_JSON_RESPONSE["listTsm"] = FAKE_LIST_TSM_RESPONSE
|
||||
MAP_COMMAND_TO_FAKE_RESPONSE['listiSCSIAuthUser'] = (
|
||||
json.loads(FAKE_LIST_ISCSI_AUTH_USER_RESPONSE))
|
||||
MAP_COMMAND_TO_FAKE_RESPONSE['listiSCSIAuthGroup'] = (
|
||||
json.loads(FAKE_LIST_ISCSI_AUTH_GROUP_RESPONSE))
|
||||
|
||||
|
||||
class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
@ -641,6 +665,7 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
# override some parts of driver configuration
|
||||
self.driver.configuration.cb_tsm_name = 'openstack'
|
||||
self.driver.configuration.cb_account_name = 'CustomerA'
|
||||
self.driver.configuration.cb_auth_group = 'fakeauthgroup'
|
||||
|
||||
def _side_effect_api_req(self, cmd, params, version='1.0'):
|
||||
"""This is a side effect function.
|
||||
@ -681,6 +706,30 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
|
||||
return MAP_COMMAND_TO_FAKE_RESPONSE[cmd]
|
||||
|
||||
def _side_effect_api_req_to_list_iscsi_auth_group(self, cmd, params,
|
||||
version='1.0'):
|
||||
"""This is a side effect function."""
|
||||
if cmd == 'listiSCSIAuthGroup':
|
||||
return {}
|
||||
|
||||
return MAP_COMMAND_TO_FAKE_RESPONSE[cmd]
|
||||
|
||||
def _side_effect_api_req_to_list_iscsi_auth_user(self, cmd, params,
|
||||
version='1.0'):
|
||||
"""This is a side effect function."""
|
||||
if cmd == 'listiSCSIAuthUser':
|
||||
return {}
|
||||
|
||||
return MAP_COMMAND_TO_FAKE_RESPONSE[cmd]
|
||||
|
||||
def _side_effect_enable_chap(self):
|
||||
"""This is a side effect function."""
|
||||
self.driver.cb_use_chap = True
|
||||
|
||||
def _side_effect_disable_chap(self):
|
||||
"""This is a side effect function."""
|
||||
self.driver.cb_use_chap = False
|
||||
|
||||
def _side_effect_api_req_to_list_filesystem(
|
||||
self, cmd, params, version='1.0'):
|
||||
"""This is a side effect function."""
|
||||
@ -934,6 +983,9 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
|
||||
# Test - I
|
||||
|
||||
# enable CHAP
|
||||
self._side_effect_enable_chap()
|
||||
|
||||
# configure the mocks with respective side-effects
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
|
||||
@ -945,15 +997,53 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
'openstack', self.driver.configuration.cb_tsm_name)
|
||||
self.assertEqual(
|
||||
'CustomerA', self.driver.configuration.cb_account_name)
|
||||
self.assertEqual(
|
||||
'fakeauthgroup', self.driver.configuration.cb_auth_group)
|
||||
|
||||
# assert the result
|
||||
self.assertEqual(
|
||||
'CHAP fakeauthgroupchapuser fakeauthgroupchapsecret',
|
||||
provider_details['provider_auth'])
|
||||
self.assertThat(
|
||||
provider_details['provider_location'],
|
||||
matchers.Contains('172.16.50.35:3260'))
|
||||
|
||||
# assert that 9 api calls were invoked
|
||||
self.assertEqual(9, mock_api_req.call_count)
|
||||
# assert the invoked api calls to CloudByte Storage
|
||||
self.assertEqual(11, mock_api_req.call_count)
|
||||
|
||||
# Test - II
|
||||
|
||||
# reset the mock
|
||||
mock_api_req.reset_mock()
|
||||
|
||||
# disable CHAP
|
||||
self._side_effect_disable_chap()
|
||||
|
||||
# configure the mocks with respective side-effects
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
|
||||
# now run the test
|
||||
provider_details = self.driver.create_volume(volume)
|
||||
|
||||
# assert equality checks for certain configuration attributes
|
||||
self.assertEqual(
|
||||
'openstack', self.driver.configuration.cb_tsm_name)
|
||||
self.assertEqual(
|
||||
'CustomerA', self.driver.configuration.cb_account_name)
|
||||
|
||||
# assert the result
|
||||
self.assertEqual(
|
||||
None,
|
||||
provider_details['provider_auth'])
|
||||
self.assertThat(
|
||||
provider_details['provider_location'],
|
||||
matchers.Contains('172.16.50.35:3260'))
|
||||
|
||||
# assert the invoked api calls to CloudByte Storage
|
||||
self.assertEqual(9, mock_api_req.call_count)
|
||||
|
||||
# Test - III
|
||||
|
||||
# reconfigure the dependencies
|
||||
volume['id'] = 'NotExists'
|
||||
del volume['size']
|
||||
@ -970,7 +1060,7 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
"CloudByte storage."):
|
||||
self.driver.create_volume(volume)
|
||||
|
||||
# Test - III
|
||||
# Test - IV
|
||||
|
||||
# reconfigure the dependencies
|
||||
volume['id'] = 'abc'
|
||||
@ -989,7 +1079,7 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
'creating volume'):
|
||||
self.driver.create_volume(volume)
|
||||
|
||||
# Test - IV
|
||||
# Test - V
|
||||
|
||||
# reconfigure the dependencies
|
||||
# reset the mocks
|
||||
@ -1122,11 +1212,51 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
|
||||
# Test - I
|
||||
|
||||
# enable CHAP
|
||||
self._side_effect_enable_chap()
|
||||
|
||||
# configure the mocks with respective side-effects
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
|
||||
# now run the test
|
||||
self.driver.create_volume_from_snapshot(cloned_volume, snapshot)
|
||||
provider_details = (
|
||||
self.driver.create_volume_from_snapshot(cloned_volume, snapshot))
|
||||
|
||||
# assert the result
|
||||
self.assertEqual(
|
||||
'CHAP fakeauthgroupchapuser fakeauthgroupchapsecret',
|
||||
provider_details['provider_auth'])
|
||||
self.assertEqual(
|
||||
'20.10.22.56:3260 '
|
||||
'iqn.2014-06.acc1.openstacktsm:acc1DS1Snap1clone1 0',
|
||||
provider_details['provider_location'])
|
||||
|
||||
# assert the invoked api calls to CloudByte Storage
|
||||
self.assertEqual(4, mock_api_req.call_count)
|
||||
|
||||
# Test - II
|
||||
|
||||
# reset the mocks
|
||||
mock_api_req.reset_mock()
|
||||
|
||||
# disable CHAP
|
||||
self._side_effect_disable_chap()
|
||||
|
||||
# configure the mocks with respective side-effects
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
|
||||
# now run the test
|
||||
provider_details = (
|
||||
self.driver.create_volume_from_snapshot(cloned_volume, snapshot))
|
||||
|
||||
# assert the result
|
||||
self.assertEqual(
|
||||
None,
|
||||
provider_details['provider_auth'])
|
||||
self.assertEqual(
|
||||
'20.10.22.56:3260 '
|
||||
'iqn.2014-06.acc1.openstacktsm:acc1DS1Snap1clone1 0',
|
||||
provider_details['provider_location'])
|
||||
|
||||
# assert n api calls were invoked
|
||||
self.assertEqual(1, mock_api_req.call_count)
|
||||
@ -1160,7 +1290,10 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
'_api_request_for_cloudbyte')
|
||||
def test_create_export(self, mock_api_req):
|
||||
|
||||
# prepare the input test data
|
||||
# Test - I
|
||||
|
||||
# enable CHAP
|
||||
self._side_effect_enable_chap()
|
||||
|
||||
# configure the mocks with respective side-effects
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
@ -1169,13 +1302,35 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
model_update = self.driver.create_export({}, {})
|
||||
|
||||
# assert the result
|
||||
self.assertEqual(None, model_update['provider_auth'])
|
||||
self.assertEqual('CHAP fakeauthgroupchapuser fakeauthgroupchapsecret',
|
||||
model_update['provider_auth'])
|
||||
|
||||
# Test - II
|
||||
|
||||
# reset the mocks
|
||||
mock_api_req.reset_mock()
|
||||
|
||||
# disable CHAP
|
||||
self._side_effect_disable_chap()
|
||||
|
||||
# configure the mocks with respective side-effects
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
|
||||
# now run the test
|
||||
model_update = self.driver.create_export({}, {})
|
||||
|
||||
# assert the result
|
||||
self.assertEqual(None,
|
||||
model_update['provider_auth'])
|
||||
|
||||
@mock.patch.object(cloudbyte.CloudByteISCSIDriver,
|
||||
'_api_request_for_cloudbyte')
|
||||
def test_ensure_export(self, mock_api_req):
|
||||
|
||||
# prepare the input test data
|
||||
# Test - I
|
||||
|
||||
# enable CHAP
|
||||
self._side_effect_enable_chap()
|
||||
|
||||
# configure the mock with respective side-effects
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
@ -1184,14 +1339,31 @@ class CloudByteISCSIDriverTestCase(testtools.TestCase):
|
||||
model_update = self.driver.ensure_export({}, {})
|
||||
|
||||
# assert the result to have a provider_auth attribute
|
||||
self.assertEqual(None, model_update['provider_auth'])
|
||||
self.assertEqual('CHAP fakeauthgroupchapuser fakeauthgroupchapsecret',
|
||||
model_update['provider_auth'])
|
||||
|
||||
# Test - II
|
||||
|
||||
# reset the mocks
|
||||
mock_api_req.reset_mock()
|
||||
|
||||
# disable CHAP
|
||||
self._side_effect_disable_chap()
|
||||
|
||||
# configure the mocks with respective side-effects
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
|
||||
# now run the test
|
||||
model_update = self.driver.create_export({}, {})
|
||||
|
||||
# assert the result
|
||||
self.assertEqual(None,
|
||||
model_update['provider_auth'])
|
||||
|
||||
@mock.patch.object(cloudbyte.CloudByteISCSIDriver,
|
||||
'_api_request_for_cloudbyte')
|
||||
def test_get_volume_stats(self, mock_api_req):
|
||||
|
||||
# prepare the input test data
|
||||
|
||||
# configure the mock with a side-effect
|
||||
mock_api_req.side_effect = self._side_effect_api_req
|
||||
|
||||
|
@ -36,9 +36,10 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
|
||||
Version history:
|
||||
1.0.0 - Initial driver
|
||||
1.1.0 - Add chap support and minor bug fixes
|
||||
"""
|
||||
|
||||
VERSION = '1.0.0'
|
||||
VERSION = '1.1.0'
|
||||
volume_stats = {}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -49,6 +50,7 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
options.cloudbyte_create_volume_opts)
|
||||
self.configuration.append_config_values(
|
||||
options.cloudbyte_connection_opts)
|
||||
self.cb_use_chap = self.configuration.use_chap_auth
|
||||
self.get_volume_stats()
|
||||
|
||||
def _get_url(self, cmd, params, apikey):
|
||||
@ -374,7 +376,7 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
|
||||
return qosgroup_id
|
||||
|
||||
def _build_provider_details_from_volume(self, volume):
|
||||
def _build_provider_details_from_volume(self, volume, chap):
|
||||
model_update = {}
|
||||
|
||||
model_update['provider_location'] = (
|
||||
@ -384,14 +386,21 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
# Will provide CHAP Authentication on forthcoming patches/release
|
||||
model_update['provider_auth'] = None
|
||||
|
||||
if chap:
|
||||
model_update['provider_auth'] = ('CHAP %(username)s %(password)s'
|
||||
% chap)
|
||||
|
||||
model_update['provider_id'] = volume['id']
|
||||
|
||||
LOG.debug("CloudByte volume [%(vol)s] properties: [%(props)s].",
|
||||
{'vol': volume['iqnname'], 'props': model_update})
|
||||
LOG.debug("CloudByte volume iqn: [%(iqn)s] provider id: [%(proid)s].",
|
||||
{'iqn': volume['iqnname'], 'proid': volume['id']})
|
||||
|
||||
return model_update
|
||||
|
||||
def _build_provider_details_from_response(self, cb_volumes, volume_name):
|
||||
def _build_provider_details_from_response(self,
|
||||
cb_volumes,
|
||||
volume_name,
|
||||
chap):
|
||||
"""Get provider information."""
|
||||
|
||||
model_update = {}
|
||||
@ -399,7 +408,8 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
|
||||
for vol in volumes:
|
||||
if vol['name'] == volume_name:
|
||||
model_update = self._build_provider_details_from_volume(vol)
|
||||
model_update = self._build_provider_details_from_volume(vol,
|
||||
chap)
|
||||
break
|
||||
|
||||
return model_update
|
||||
@ -457,12 +467,16 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
else:
|
||||
return iscsi_id
|
||||
|
||||
def _request_update_iscsi_service(self, iscsi_id, ig_id):
|
||||
def _request_update_iscsi_service(self, iscsi_id, ig_id, ag_id):
|
||||
params = {
|
||||
"id": iscsi_id,
|
||||
"igid": ig_id
|
||||
}
|
||||
|
||||
if ag_id:
|
||||
params['authgroupid'] = ag_id
|
||||
params['authmethod'] = "CHAP"
|
||||
|
||||
self._api_request_for_cloudbyte(
|
||||
'updateVolumeiSCSIService', params)
|
||||
|
||||
@ -570,6 +584,97 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
|
||||
return data
|
||||
|
||||
def _get_auth_group_id_from_response(self, data):
|
||||
"""Find iSCSI auth group id."""
|
||||
|
||||
chap_group = self.configuration.cb_auth_group
|
||||
|
||||
ag_list_res = data.get('listiSCSIAuthGroupResponse')
|
||||
|
||||
if ag_list_res is None:
|
||||
msg = _("Null response received from CloudByte's "
|
||||
"list iscsi auth groups.")
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
ag_list = ag_list_res.get('authgroup')
|
||||
|
||||
if ag_list is None:
|
||||
msg = _('No iscsi auth groups were found in CloudByte.')
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
ag_id = None
|
||||
|
||||
for ag in ag_list:
|
||||
if ag.get('name') == chap_group:
|
||||
ag_id = ag['id']
|
||||
break
|
||||
else:
|
||||
msg = _("Auth group [%s] details not found in "
|
||||
"CloudByte storage.") % chap_group
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
return ag_id
|
||||
|
||||
def _get_auth_group_info(self, account_id, ag_id):
|
||||
"""Fetch the auth group details."""
|
||||
|
||||
params = {"accountid": account_id, "authgroupid": ag_id}
|
||||
|
||||
auth_users = self._api_request_for_cloudbyte(
|
||||
'listiSCSIAuthUser', params)
|
||||
|
||||
auth_user_details_res = auth_users.get('listiSCSIAuthUsersResponse')
|
||||
|
||||
if auth_user_details_res is None:
|
||||
msg = _("No response was received from CloudByte storage "
|
||||
"list iSCSI auth user API call.")
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
auth_user_details = auth_user_details_res.get('authuser')
|
||||
|
||||
if auth_user_details is None:
|
||||
msg = _("Auth user details not found in CloudByte storage.")
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
chapuser = auth_user_details[0].get('chapusername')
|
||||
chappassword = auth_user_details[0].get('chappassword')
|
||||
|
||||
if chapuser is None or chappassword is None:
|
||||
msg = _("Invalid chap user details found in CloudByte storage.")
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
|
||||
data = {'username': chapuser, 'password': chappassword, 'ag_id': ag_id}
|
||||
|
||||
return data
|
||||
|
||||
def _get_chap_info(self, account_id):
|
||||
"""Fetch the chap details."""
|
||||
|
||||
params = {"accountid": account_id}
|
||||
|
||||
iscsi_auth_data = self._api_request_for_cloudbyte(
|
||||
'listiSCSIAuthGroup', params)
|
||||
|
||||
ag_id = self._get_auth_group_id_from_response(
|
||||
iscsi_auth_data)
|
||||
|
||||
return self._get_auth_group_info(account_id, ag_id)
|
||||
|
||||
def _export(self):
|
||||
model_update = {'provider_auth': None}
|
||||
|
||||
if self.cb_use_chap is True:
|
||||
account_name = self.configuration.cb_account_name
|
||||
|
||||
account_id = self._get_account_id_from_name(account_name)
|
||||
|
||||
chap = self._get_chap_info(account_id)
|
||||
|
||||
model_update['provider_auth'] = ('CHAP %(username)s %(password)s'
|
||||
% chap)
|
||||
|
||||
return model_update
|
||||
|
||||
def create_volume(self, volume):
|
||||
|
||||
tsm_name = self.configuration.cb_tsm_name
|
||||
@ -636,16 +741,25 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
LOG.debug("Updating iscsi service for CloudByte volume [%s].",
|
||||
cb_volume_name)
|
||||
|
||||
ag_id = None
|
||||
chap_info = {}
|
||||
|
||||
if self.cb_use_chap is True:
|
||||
chap_info = self._get_chap_info(account_id)
|
||||
ag_id = chap_info['ag_id']
|
||||
|
||||
# Update the iscsi service with above fetched iscsi_id & ig_id
|
||||
self._request_update_iscsi_service(iscsi_id, ig_id)
|
||||
self._request_update_iscsi_service(iscsi_id, ig_id, ag_id)
|
||||
|
||||
LOG.debug("CloudByte volume [%(vol)s] updated with "
|
||||
"iscsi id [%(iscsi)s] and ig id [%(ig)s].",
|
||||
{'vol': cb_volume_name, 'iscsi': iscsi_id, 'ig': ig_id})
|
||||
"iscsi id [%(iscsi)s] and initiator group [%(ig)s] and "
|
||||
"authentication group [%(ag)s].",
|
||||
{'vol': cb_volume_name, 'iscsi': iscsi_id,
|
||||
'ig': ig_id, 'ag': ag_id})
|
||||
|
||||
# Provide the model after successful completion of above steps
|
||||
provider = self._build_provider_details_from_response(
|
||||
cb_volumes, cb_volume_name)
|
||||
cb_volumes, cb_volume_name, chap_info)
|
||||
|
||||
LOG.info(_LI("Successfully created a CloudByte volume [%(cb_vol)s] "
|
||||
"w.r.t OpenStack volume [%(stack_vol)s]."),
|
||||
@ -829,7 +943,20 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
'cb_snap': cb_snapshot_path,
|
||||
'stack_vol': parent_volume_id})
|
||||
|
||||
return self._build_provider_details_from_volume(cb_vol)
|
||||
chap_info = {}
|
||||
|
||||
if self.cb_use_chap is True:
|
||||
account_name = self.configuration.cb_account_name
|
||||
|
||||
# Get account id of this account
|
||||
account_id = self._get_account_id_from_name(account_name)
|
||||
|
||||
chap_info = self._get_chap_info(account_id)
|
||||
|
||||
model_update = self._build_provider_details_from_volume(cb_vol,
|
||||
chap_info)
|
||||
|
||||
return model_update
|
||||
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Delete a snapshot at CloudByte."""
|
||||
@ -888,21 +1015,13 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
|
||||
|
||||
def create_export(self, context, volume):
|
||||
"""Setup the iscsi export info."""
|
||||
model_update = {}
|
||||
|
||||
# Will provide CHAP Authentication on forthcoming patches/release
|
||||
model_update['provider_auth'] = None
|
||||
|
||||
return model_update
|
||||
return self._export()
|
||||
|
||||
def ensure_export(self, context, volume):
|
||||
"""Verify the iscsi export info."""
|
||||
model_update = {}
|
||||
|
||||
# Will provide CHAP Authentication on forthcoming patches/release
|
||||
model_update['provider_auth'] = None
|
||||
|
||||
return model_update
|
||||
return self._export()
|
||||
|
||||
def get_volume_stats(self, refresh=False):
|
||||
"""Get volume statistics.
|
||||
|
@ -38,7 +38,14 @@ cloudbyte_connection_opts = [
|
||||
default=3,
|
||||
help="Will confirm a successful volume "
|
||||
"creation in CloudByte storage by making "
|
||||
"this many number of attempts."), ]
|
||||
"this many number of attempts."),
|
||||
cfg.StrOpt("cb_auth_group",
|
||||
default="None",
|
||||
help="This corresponds to the discovery authentication "
|
||||
"group in CloudByte storage. "
|
||||
"Chap users are added to this group. "
|
||||
"Driver uses the first user found for this group. "
|
||||
"Default value is None."), ]
|
||||
|
||||
cloudbyte_add_qosgroup_opts = [
|
||||
cfg.DictOpt('cb_add_qosgroup',
|
||||
|
Loading…
Reference in New Issue
Block a user