diff --git a/cinder/opts.py b/cinder/opts.py index 0dd0816a63c..7f1561f60ee 100644 --- a/cinder/opts.py +++ b/cinder/opts.py @@ -181,7 +181,6 @@ from cinder.volume.drivers.zfssa import zfssaiscsi as \ cinder_volume_drivers_zfssa_zfssaiscsi from cinder.volume.drivers.zfssa import zfssanfs as \ cinder_volume_drivers_zfssa_zfssanfs -from cinder.volume.drivers.zte import zte_ks as cinder_volume_drivers_zte_zteks from cinder.volume import manager as cinder_volume_manager from cinder.wsgi import eventlet_server as cinder_wsgi_eventletserver from cinder.zonemanager.drivers.brocade import brcd_fabric_opts as \ @@ -372,7 +371,6 @@ def list_opts(): cinder_volume_drivers_zadara.zadara_opts, cinder_volume_drivers_zfssa_zfssaiscsi.ZFSSA_OPTS, cinder_volume_drivers_zfssa_zfssanfs.ZFSSA_OPTS, - cinder_volume_drivers_zte_zteks.zte_opts, cinder_volume_manager.volume_backend_opts, )), ('nova', diff --git a/cinder/tests/unit/volume/drivers/test_zte_ks.py b/cinder/tests/unit/volume/drivers/test_zte_ks.py deleted file mode 100644 index 557e7b077ea..00000000000 --- a/cinder/tests/unit/volume/drivers/test_zte_ks.py +++ /dev/null @@ -1,424 +0,0 @@ -# Copyright 2016 ZTE Corporation. All rights reserved -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -""" -Self test for ZTE Storage Driver platform. -""" -from oslo_config import cfg - -from cinder import exception -from cinder import test -from cinder.volume import configuration as conf -from cinder.volume.drivers.zte import zte_ks -from cinder.volume.drivers.zte import zte_pub - - -session_id = 'kfomqdnoetjcjlva' -volume_paras = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635', - 'size': 2, - 'volume_name': 'vol1', - 'id': '21ec7341-9256-497b-97d9-ef48edcf0635', - 'volume_id': '21ec7341-9256-497b-97d9-ef48edcf0635', - 'provider_auth': None, - 'project_id': 'project', - 'display_name': 'vol1', - 'source_volid': None, - 'volume_metadata': [], - 'display_description': 'test volume', - 'volume_type_id': None} - -volume_clone = {'name': 'volume-ee317512-f6a6-4284-a94e-5f4ac8783169', - 'size': 4, - 'volume_name': 'vol1', - 'id': 'ee317512-f6a6-4284-a94e-5f4ac8783169', - 'volume_id': 'ee317512-f6a6-4284-a94e-5f4ac8783169', - 'provider_auth': None, - 'project_id': 'project', - 'display_name': 'clone_vol1', - 'source_volid': None, - 'volume_metadata': [], - 'display_description': 'test clone volume', - 'volume_type_id': None} -snapvolume_paras = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635', - 'size': 2, - 'volume_size': 2, - 'volume_name': 'vol1', - 'id': '21ec7341-9256-497b-97d9-ef48edcf0635', - 'volume_id': '21ec7341-9256-497b-97d9-ef48edcf0635', - 'provider_auth': None, - 'project_id': 'project', - 'display_name': 'vol1', - 'source_volid': None, - 'volume_metadata': [], - 'display_description': 'test volume', - 'volume_type_id': None} -connector = {'ip': '10.0.0.0', - 'initiator': 'iqn.1993-08.org.debian:01:222'} -fcconnector = {'ip': '10.0.0.0', - 'wwpns': [1, 2, 3, 4, 5, 6, 7, 8]} -fake_opt = [ - cfg.StrOpt('fake_opt', default='fake', help='fake opts') -] -VolFlowLimitAttr_paras = {'sqwWriteFlowLimit': 0, - 'cVolName': 'OpenCos_5072124445952515861', - 'sqwTotalFlowLimit': 500, - 'sqwWriteIoCount': 0, - 'sqwTotalIoCount': 0, - 'sqwReadFlowLimit': 0, - 'sqwReadIoCount': 0} - -volume_name = 'OpenCos_8359669312515962256' -return_success = {'returncode': zte_pub.ZTE_SUCCESS, 'data': {}} -return_error = {'returncode': zte_pub.ZTE_ERR_LUNDEV_NOT_EXIST, 'data': {}} -return_port_error = ( - {'returncode': zte_pub.ZTE_ERR_PORT_EXIST_INOTHER, 'data': {}}) -return_host_error = ( - {'returncode': zte_pub.ZTE_ERR_HOST_EXIST_INOTHER, 'data': {}}) - -MAP_TO_RESPONSE = {} -signin_info = {'sessionID': session_id} -MAP_TO_RESPONSE['plat.session.signin'] = {'returncode': zte_pub.ZTE_SUCCESS, - 'data': signin_info} -MAP_TO_RESPONSE['plat.session.heartbeat'] = return_success -pool_info = {'sdwState': 1, 'qwTotalCapacity': 1024560, - 'qwFreeCapacity': 102456} -MAP_TO_RESPONSE['GetPoolInfo'] = {'returncode': zte_pub.ZTE_SUCCESS, - 'data': pool_info} -MAP_TO_RESPONSE['CreateVolOnPool'] = return_success -MAP_TO_RESPONSE['DelCvol'] = return_success -MAP_TO_RESPONSE['GetCvolNamesOnVol'] = { - 'returncode': zte_pub.ZTE_SUCCESS, - 'data': {'sdwCvolNum': 2, 'scCvolNames': [{'scCvolName': 'clone1'}, - {'scCvolName': 'clone2'}]}} -MAP_TO_RESPONSE['CreateSvol'] = return_success -MAP_TO_RESPONSE['DelSvol'] = return_success -MAP_TO_RESPONSE['ExpandVolOnPool'] = return_success -MAP_TO_RESPONSE['CreateCvol'] = return_success -cVolName_from_vol_name = "OpenCos_9fbc232bf71ee2fa8bd" -grp_info = {'sdwHostNum': 1, - 'tHostInfo': [{'ucHostName': 'host1'}], - 'sdwLunNum': 5, - 'cMapGrpName': 'group_cjf', - 'tLunInfo': [{'sdwLunState': 0, 'sdwBlockSize': 0, - 'sdwAccessAttr': 0, 'sdwLunId': 0, - 'cVolName': 'vol1'}, - {'sdwLunState': 0, 'sdwBlockSize': 0, - 'sdwAccessAttr': 0, 'sdwLunId': 1, - 'cVolName': volume_name}, - {'sdwLunState': 0, 'sdwBlockSize': 0, - 'sdwAccessAttr': 0, 'sdwLunId': 2, - 'cVolName': 'vol3'}, - {'sdwLunState': 0, 'sdwBlockSize': 0, - 'sdwAccessAttr': 0, 'sdwLunId': 3, - 'cVolName': cVolName_from_vol_name}, - {'sdwLunState': 0, 'sdwBlockSize': 0, - 'sdwAccessAttr': 0, 'sdwLunId': 5, - 'cVolName': 'vol4'}]} -MAP_TO_RESPONSE['GetMapGrpInfo'] = ( - {'returncode': zte_pub.ZTE_SUCCESS, 'data': grp_info}) -MAP_TO_RESPONSE['DelMapGrp'] = return_success -simple_grp_info = {'sdwMapGrpNum': 0, - 'tMapGrpSimpleInfo': [{'sdwHostNum': 0, - 'sdwLunNum': 0, - 'cMapGrpName': session_id}, - {'sdwHostNum': 1, - 'sdwLunNum': 1, - 'cMapGrpName': ''}]} -MAP_TO_RESPONSE['GetGrpSimpleInfoList'] = {'returncode': zte_pub.ZTE_SUCCESS, - 'data': simple_grp_info} -luninfo = {'sdwLunId': 3} -MAP_TO_RESPONSE['AddVolToGrp'] = {'returncode': zte_pub.ZTE_SUCCESS, - 'data': luninfo} -sys_info = {'cVendor': 'ZTE', 'cVersionName': 'V1.0', - 'storage_protocol': 'iSCSI'} -MAP_TO_RESPONSE['GetSysInfo'] = {'returncode': zte_pub.ZTE_SUCCESS, - 'data': sys_info} -cfg_info = {'sdwDeviceNum': 4, - 'tSystemNetCfg': [ - {'udwCtrlId': 0, 'udwRoleType': 0, - 'udwPortType': 1, 'udwDeviceId': 123, - 'cIpAddr': '198.51.100.20'}, - {'udwCtrlId': 0, 'udwRoleType': 0, - 'udwPortType': 1, 'udwDeviceId': 123, - 'cIpAddr': '198.51.100.21'}, - {'udwCtrlId': 0, 'udwRoleType': 0, - 'udwPortType': 1, 'udwDeviceId': 123, - 'cIpAddr': '198.51.100.22'}, - {'udwCtrlId': 0, 'udwRoleType': 0, - 'udwPortType': 1, 'udwDeviceId': 123, - 'cIpAddr': '198.51.100.23'}]} -MAP_TO_RESPONSE['GetSystemNetCfg'] = {'returncode': zte_pub.ZTE_SUCCESS, - 'data': cfg_info} -iscsi_target = { - 'tIscsiTargetInfo': [ - {'udwCtrlId': 0, - 'cTgtName': 'iqn.2099-01.cn.com.zte:usp.spr11-00:00:22:15'}, - {'udwCtrlId': 0, - 'cTgtName': 'iqn.2099-01.cn.com.zte:usp.spr11-00:00:22:25'}], - 'udwCtrlCount': 2} -MAP_TO_RESPONSE['GetIscsiTargetName'] = {'returncode': zte_pub.ZTE_SUCCESS, - 'data': iscsi_target} -MAP_TO_RESPONSE['CreateMapGrp'] = return_success -grp_info_forsearch = {'cVolName': 'vol1', - 'sdwMapGrpNum': 1, - 'cMapGrpNames': ['grp1'], - 'sdwLunLocalId': [1]} -MAP_TO_RESPONSE['GetGrpNamesOfVol'] = ( - {'returncode': zte_pub.ZTE_SUCCESS, 'data': grp_info_forsearch}) -MAP_TO_RESPONSE['CreateHost'] = return_success -MAP_TO_RESPONSE['AddPortToHost'] = return_success -MAP_TO_RESPONSE['AddHostToGrp'] = return_success -MAP_TO_RESPONSE['DelVolFromGrp'] = return_success -MAP_TO_RESPONSE['DelHostFromGrp'] = return_success -host_info = {'sdwPortNum': 2, - 'tPort': [{'cPortName': 'port1'}, - {'cPortName': 'port2'}]} -MAP_TO_RESPONSE['GetHost'] = {'returncode': zte_pub.ZTE_SUCCESS, - 'data': host_info} -MAP_TO_RESPONSE['DelPortFromHost'] = return_success -MAP_TO_RESPONSE['DelHost'] = return_success - - -class FakeZteISCSIDriver(zte_ks.ZteISCSIDriver): - def __init__(self, configuration): - self.configuration = configuration - super(FakeZteISCSIDriver, self).__init__( - configuration=self.configuration) - self.result = zte_pub.ZTE_SUCCESS - self.test_flag = True - self.portexist_flag = False - self.portexistother_flag = False - self.hostexist_flag = False - self.hostexistother_flag = False - - def _call(self, sessionid='', method='', params=None): - return_data = return_success - - if method in MAP_TO_RESPONSE.keys(): - return_data = MAP_TO_RESPONSE[method] - - if not self.test_flag: - return_data = return_error - if self.portexistother_flag: - return_data = return_port_error - if self.hostexistother_flag: - return_data = return_host_error - return return_data - - def _check_conf_file(self): - pass - - def _get_iscsi_info(self): - iscsi_info = {'DefaultTargetIPs': ["198.51.100.20"]} - - return iscsi_info - - -class ZteBaseDriverTestCase(object): - def test_create_volume_success(self): - self.driver.test_flag = True - self.driver.create_volume(volume_paras) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_create_volume_fail(self): - self.driver.test_flag = False - self.assertRaises(exception.CinderException, - self.driver.create_volume, volume_paras) - - def test_delete_volume_success(self): - self.driver.test_flag = True - self.driver.delete_volume(volume_paras) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_delete_volume_fail(self): - self.driver.test_flag = False - self.assertRaises(exception.CinderException, - self.driver.delete_volume, volume_paras) - - def test_delete_cloned_volume_success(self): - self.driver.test_flag = True - vol = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635', - 'source_volid': '68a52c1e-ecbe-4f6c-954c-9f551347ff3f'} - self.driver.delete_volume(vol) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_delete_cloned_volume_fail(self): - self.driver.test_flag = False - vol = {'name': 'volume-21ec7341-9256-497b-97d9-ef48edcf0635', - 'source_volid': '68a52c1e-ecbe-4f6c-954c-9f551347ff3f'} - self.assertRaises(exception.CinderException, - self.driver.delete_volume, vol) - - def test_create_snapshot_success(self): - self.driver.test_flag = True - snap_vol = {'name': 'snapshot-2b9b982a-8b56-46e3-9d4f-6392e8a72e6e', - 'volume_name': - 'volume-21ec7341-9256-497b-97d9-ef48edcf0635', - 'volume_size': 2} - self.driver.create_snapshot(snap_vol) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_create_snapshot_fail(self): - self.driver.test_flag = False - snap_vol = {'name': 'snapshot-2b9b982a-8b56-46e3-9d4f-6392e8a72e6e', - 'volume_name': - 'volume-21ec7341-9256-497b-97d9-ef48edcf0635', - 'volume_size': 2} - self.assertRaises(exception.CinderException, - self.driver.create_snapshot, snap_vol) - - def test_delete_snapshot_success(self): - self.driver.test_flag = True - snap_vol = {'name': 'snapshot-2b9b982a-8b56-46e3-9d4f-6392e8a72e6e'} - self.driver.delete_snapshot(snap_vol) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_delete_snapshot_fail(self): - self.driver.test_flag = False - snap_vol = {'name': 'snapshot-2b9b982a-8b56-46e3-9d4f-6392e8a72e6e'} - self.assertRaises(exception.CinderException, - self.driver.delete_snapshot, snap_vol) - - def test_extend_volume_success(self): - self.driver.test_flag = True - self.driver.extend_volume(volume_paras, 4) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_extend_volume_fail(self): - self.driver.test_flag = False - self.assertRaises(exception.CinderException, - self.driver.extend_volume, volume_paras, 4) - - def test_create_cloned_volume_success(self): - self.driver.test_flag = True - self.driver.create_cloned_volume(volume_clone, volume_paras) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_create_cloned_volume_fail(self): - self.driver.test_flag = False - self.assertRaises(exception.CinderException, - self.driver.create_cloned_volume, - volume_clone, volume_paras) - - def test_create_volume_from_snapshot_success(self): - self.driver.test_flag = True - self.driver.create_volume_from_snapshot(volume_clone, snapvolume_paras) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_create_volume_from_snapshot_fail(self): - self.driver.test_flag = False - self.assertRaises(exception.CinderException, - self.driver.create_cloned_volume, - volume_clone, volume_paras) - - -class ZteISCSIDriverTestCase(ZteBaseDriverTestCase, test.TestCase): - """Test ZTE iSCSI volume driver.""" - - def __init__(self, *args, **kwargs): - super(ZteISCSIDriverTestCase, self).__init__(*args, **kwargs) - - def setUp(self): - super(ZteISCSIDriverTestCase, self).setUp() - configuration = conf.Configuration(None) - self.configuration = configuration - - self.configuration.zteControllerIP0 = '192.0.2.2' - self.configuration.zteLocalIP = '192.0.2.8' - self.configuration.zteUserName = 'root' - self.configuration.zteUserPassword = 'root' - self.configuration.zteChunkSize = 64 - self.configuration.zteAheadReadSize = 8 - self.configuration.zteCachePolicy = 65535 - self.configuration.zteSSDCacheSwitch = 0 - self.configuration.zteStoragePool = 'pool1,pool2,pool3' - self.configuration.ztePoolVolAllocPolicy = 0 - self.configuration.ztePoolVolMovePolicy = 0 - self.configuration.ztePoolVolIsThin = 0 - self.configuration.ztePoolVolInitAllocedCapacity = 0 - self.configuration.ztePoolVolAlarmThreshold = 0 - self.configuration.ztePoolVolAlarmStopAllocFlag = 0 - - self.driver = FakeZteISCSIDriver(configuration=self.configuration) - self.driver.do_setup({}) - - def test_get_volume_stats(self): - stats = self.driver.get_volume_stats(True) - self.assertEqual("ZTE", stats["vendor_name"]) - self.assertEqual("iSCSI", stats["storage_protocol"]) - self.assertEqual("V1.0", stats["driver_version"]) - self.assertLess(0, stats["total_capacity_gb"]) - - def test_initialize_connection_success(self): - self.driver.test_flag = True - data = self.driver.initialize_connection(volume_paras, connector) - properties = data['data'] - self.assertEqual("iscsi", data["driver_volume_type"]) - self.assertEqual('iqn.2099-01.cn.com.zte:usp.spr11-00:00:22:15', - properties["target_iqn"]) - self.assertEqual(3, properties["target_lun"]) - self.assertEqual('198.51.100.20:3260', properties["target_portal"]) - - def test_initialize_connection_portexist(self): - self.driver.portexist_flag = True - data = self.driver.initialize_connection(volume_paras, connector) - properties = data['data'] - self.assertEqual("iscsi", data["driver_volume_type"]) - self.assertEqual('iqn.2099-01.cn.com.zte:usp.spr11-00:00:22:15', - properties["target_iqn"]) - self.assertEqual(3, properties["target_lun"]) - self.assertEqual('198.51.100.20:3260', properties["target_portal"]) - - def test_initialize_connection_hostexist(self): - self.driver.hostexist_flag = True - data = self.driver.initialize_connection(volume_paras, connector) - - properties = data['data'] - self.assertEqual("iscsi", data["driver_volume_type"]) - self.assertEqual('iqn.2099-01.cn.com.zte:usp.spr11-00:00:22:15', - properties["target_iqn"]) - self.assertEqual(3, properties["target_lun"]) - self.assertEqual('198.51.100.20:3260', properties["target_portal"]) - - def test_initialize_connection_portexistother(self): - self.driver.portexistother_flag = True - self.assertRaises(exception.CinderException, - self.driver.initialize_connection, - volume_paras, connector) - - def test_initialize_connection_hostexistother(self): - self.driver.hostexistother_flag = True - self.assertRaises(exception.CinderException, - self.driver.initialize_connection, - volume_paras, connector) - - def test_initialize_connection_fail(self): - self.driver.test_flag = False - self.assertRaises(exception.CinderException, - self.driver.initialize_connection, - volume_paras, connector) - - def test_terminate_connection_success(self): - self.driver.test_flag = True - vol = {'name': 'volume-ee317512-f6a6-4284-a94e-5f4ac8783169'} - self.driver.terminate_connection(vol, connector) - self.assertEqual(zte_pub.ZTE_SUCCESS, self.driver.result) - - def test_terminate_connection_fail(self): - self.driver.test_flag = False - vol = {'name': 'volume-ee317512-f6a6-4284-a94e-5f4ac8783169'} - self.assertRaises(exception.CinderException, - self.driver.terminate_connection, vol, connector) diff --git a/cinder/volume/drivers/zte/__init__.py b/cinder/volume/drivers/zte/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/cinder/volume/drivers/zte/zte_ks.py b/cinder/volume/drivers/zte/zte_ks.py deleted file mode 100644 index c6b9295c4b8..00000000000 --- a/cinder/volume/drivers/zte/zte_ks.py +++ /dev/null @@ -1,994 +0,0 @@ -# Copyright 2016 ZTE Corporation. All rights reserved -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -""" -Volume driver for ZTE storage systems. -""" - -import hashlib -import json - -from oslo_config import cfg -from oslo_log import log as logging -from oslo_utils import units -import six -from six.moves import urllib - -from cinder import exception -from cinder.i18n import _ -from cinder import interface -from cinder import utils -from cinder.volume import configuration -from cinder.volume import driver -from cinder.volume.drivers.zte import zte_pub - - -LOG = logging.getLogger(__name__) - -zte_opts = [ - cfg.IPOpt('zteControllerIP0', default=None, - help='Main controller IP.'), - cfg.IPOpt('zteControllerIP1', default=None, - help='Slave controller IP.'), - cfg.IPOpt('zteLocalIP', default=None, help='Local IP.'), - cfg.StrOpt('zteUserName', default=None, help='User name.'), - cfg.StrOpt('zteUserPassword', default=None, secret=True, - help='User password.'), - cfg.IntOpt('zteChunkSize', default=4, - help='Virtual block size of pool. ' - 'Unit : KB. ' - 'Valid value : 4, 8, 16, 32, 64, 128, 256, 512. '), - cfg.IntOpt('zteAheadReadSize', default=8, help='Cache readahead size.'), - cfg.IntOpt('zteCachePolicy', default=1, - help='Cache policy. ' - '0, Write Back; 1, Write Through.'), - cfg.IntOpt('zteSSDCacheSwitch', default=1, - help='SSD cache switch. ' - '0, OFF; 1, ON.'), - cfg.ListOpt('zteStoragePool', default=[], help='Pool name list.'), - cfg.IntOpt('ztePoolVoAllocatedPolicy', default=0, - help='Pool volume allocated policy. ' - '0, Auto; ' - '1, High Performance Tier First; ' - '2, Performance Tier First; ' - '3, Capacity Tier First.'), - cfg.IntOpt('ztePoolVolMovePolicy', default=0, - help='Pool volume move policy.' - '0, Auto; ' - '1, Highest Available; ' - '2, Lowest Available; ' - '3, No Relocation.'), - cfg.BoolOpt('ztePoolVolIsThin', default=False, - help='Whether it is a thin volume.'), - cfg.IntOpt('ztePoolVolInitAllocatedCapacity', default=0, - help='Pool volume init allocated Capacity.' - 'Unit : KB. '), - cfg.IntOpt('ztePoolVolAlarmThreshold', default=0, - help='Pool volume alarm threshold. [0, 100]'), - cfg.IntOpt('ztePoolVolAlarmStopAllocatedFlag', default=0, - help='Pool volume alarm stop allocated flag.') -] - -CONF = cfg.CONF -CONF.register_opts(zte_opts, group=configuration.SHARED_CONF_GROUP) - - -class ZTEVolumeDriver(driver.VolumeDriver): - - VERSION = "1.0.0" - - # ThirdPartySystems wiki page - CI_WIKI_NAME = "ZTE_cinder2_CI" - - def __init__(self, *args, **kwargs): - super(ZTEVolumeDriver, self).__init__(*args, **kwargs) - self.configuration.append_config_values(zte_opts) - self.url = '' - self.login_info = {} - self.session_id = '' - - def _get_md5(self, src_string): - md5obj = hashlib.md5() - md5obj.update(src_string.encode('UTF-8')) - md5_string = md5obj.hexdigest() - md5_string = md5_string[0:19] - return md5_string - - def _call_method(self, method='', params=None): - sid = self._get_sessionid() - return self._call(sid, method, params) - - def _call(self, sessin_id='', method='', params=None): - try: - params = params or {} - data = ("sessionID=" + sessin_id + "&method=" + - method + "¶ms=" + json.dumps(params)) - LOG.debug('Req Data: method %(method)s data %(data)s.', - {'method': method, 'data': data}) - headers = {"Connection": "keep-alive", - "Content-Type": "application/x-www-form-urlencoded"} - req = urllib.request.Request(self.url, data, headers) - req.get_method = lambda: 'POST' - # self.url used for req is coded to always use the HTTPS scheme - response = urllib.request.urlopen(req, # nosec - timeout= - zte_pub.ZTE_DEFAULT_TIMEOUT - ).read() - LOG.debug('Response Data: method %(method)s res %(res)s.', - {'method': method, 'res': response}) - except Exception: - LOG.exception('Bad response from server.') - msg = (_('_call failed.')) - raise exception.VolumeBackendAPIException(data=msg) - res_json = json.loads(response) - return res_json - - def _get_server(self): - controller_ip = (self.login_info['ControllerIP0'] - or self.login_info['ControllerIP1'] or '') - self.url = 'https://' + controller_ip + '/phpclient/client.php' - LOG.debug('Set ZTE server is %s.', self.url) - - def _change_server(self): - if (self.login_info['ControllerIP0'] and - self.login_info['ControllerIP1']): - controller_ip = (self.login_info['ControllerIP1'] - if self.login_info['ControllerIP0'] in self.url - else self.login_info['ControllerIP0']) - self.url = 'https://' + controller_ip + '/phpclient/client.php' - - def _user_login(self): - loginfo = {'UserName': self.login_info['UserName'], - 'UserPassword': self.login_info['UserPassword'], - 'LocalIP': self.login_info['LocalIP'], - 'LoginType': zte_pub.ZTE_WEB_LOGIN_TYPE} - - result = self._call('""', 'plat.session.signin', loginfo) - - if result['returncode'] in [zte_pub.ZTE_SUCCESS, - zte_pub.ZTE_SESSION_EXIST]: - self.session_id = result['data']['sessionID'] - return self.session_id - else: - err_msg = ( - _('Failed to login. Return code: %(ret)s.') % { - 'ret': result['returncode']}) - raise exception.VolumeBackendAPIException( - data=err_msg) - - def do_setup(self, context): - """Any initialization the volume driver does while starting.""" - self.login_info = { - 'ControllerIP0': self.configuration.zteControllerIP0, - 'ControllerIP1': self.configuration.zteControllerIP1, - 'LocalIP': self.configuration.zteLocalIP, - 'UserName': self.configuration.zteUserName, - 'UserPassword': self.configuration.zteUserPassword} - self._get_server() - try: - self.session_id = self._user_login() - except exception.VolumeBackendAPIException: - self._change_server() - self.session_id = self._user_login() - - def check_for_setup_error(self): - - zteControllerIP0 = self.configuration.zteControllerIP0 - if zteControllerIP0 is None: - msg = (_("Controller IP is missing for ZTE driver.")) - raise exception.VolumeBackendAPIException(data=msg) - - zteUserName = self.configuration.zteUserName - if zteUserName is None: - msg = (_("User Name is missing for ZTE driver.")) - raise exception.VolumeBackendAPIException(data=msg) - - zteUserPassword = self.configuration.zteUserPassword - if zteUserPassword is None: - msg = (_("User Password is missing for ZTE driver.")) - raise exception.VolumeBackendAPIException(data=msg) - - def _get_sessionid(self): - try: - sid = self.session_id - ret = self._call(sid, 'plat.session.heartbeat') - if ret['returncode'] == zte_pub.ZTE_SUCCESS: - return sid - else: - LOG.info('heartbeat failed. Return code: %(ret)s.', - {'ret': ret['returncode']}) - except Exception: - LOG.exception('_get_sessionid error.') - - self._change_server() - return self._user_login() - - def _get_pool_list(self): - pool_info_list = [] - - for pool_name in self.configuration.zteStoragePool: - if pool_name: - ret = self._call_method( - 'GetPoolInfo', { - 'scPoolName': pool_name}) - pool_info = {'name': pool_name} - if ((ret['returncode'] == zte_pub.ZTE_SUCCESS) and - (ret['data']['sdwState'] == zte_pub.ZTE_STATUS_OK)): - total_capacity = ret['data']['qwTotalCapacity'] - free_capacitity = ret['data']['qwFreeCapacity'] - pool_info['total'] = ( - float(total_capacity) / units.Ki) - pool_info['free'] = ( - float(free_capacitity) / units.Ki) - pool_info_list.append(pool_info) - if not pool_info_list: - err_msg = (_('No pool available.')) - raise exception.VolumeBackendAPIException(data=err_msg) - return pool_info_list - - def _find_pool_to_create_volume(self): - pool_list = self._get_pool_list() - pool = max(pool_list, key=lambda arg: arg['free']) - return pool['name'] - - def _create_volume_in_pool(self, volume_name, volume_size, pool_name): - - vol = { - 'scPoolName': pool_name, - 'scVolName': volume_name, - 'sdwStripeDepth': self.configuration.zteChunkSize, - 'qwCapacity': float(volume_size), - 'sdwCtrlPrefer': 0xFFFF, - 'sdwCachePolicy': self.configuration.zteCachePolicy, - 'sdwAheadReadSize': self.configuration.zteAheadReadSize, - 'sdwAllocPolicy': self.configuration.ztePoolVoAllocatedPolicy, - 'sdwMovePolicy': self.configuration.ztePoolVolMovePolicy, - 'udwIsThinVol': self.configuration.ztePoolVolIsThin, - 'uqwInitAllocedCapacity': - self.configuration.ztePoolVolInitAllocatedCapacity, - 'sdwAlarmThreshold': - self.configuration.ztePoolVolAlarmThreshold, - 'sdwAlarmStopAllocFlag': - self.configuration.ztePoolVolAlarmStopAllocatedFlag, - 'dwSSDCacheSwitch': self.configuration.zteSSDCacheSwitch} - - ret = self._call_method('CreateVolOnPool', vol) - if ret['returncode'] not in [zte_pub.ZTE_ERR_OBJECT_EXIST, - zte_pub.ZTE_SUCCESS]: - err_msg = ( - _('Create volume failed. Volume name: %(name)s. ' - 'Return code: %(ret)s.') % - {'name': volume_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException( - data=err_msg) - - def _create_volume(self, volume_name, volume_size): - pool_name = self._find_pool_to_create_volume() - if pool_name: - self._create_volume_in_pool(volume_name, volume_size, pool_name) - else: - msg = _('No pool available.') - raise exception.VolumeDriverException(message=msg) - - def create_volume(self, volume): - """Create a new volume.""" - volume_name = self._translate_volume_name(volume['name']) - - volume_size = float(volume['size'] * units.Mi) - self._create_volume(volume_name, volume_size) - - def _delete_clone_volume(self, cloned_name): - cloned_name += zte_pub.ZTE_CLONE_SUFFIX - cvol_name = {'scCvolName': cloned_name} - ret = self._call_method('DelCvol', cvol_name) - - if ret['returncode'] not in [zte_pub.ZTE_ERR_CLONE_OR_SNAP_NOT_EXIST, - zte_pub.ZTE_ERR_VAS_OBJECT_NOT_EXIST, - zte_pub.ZTE_SUCCESS]: - err_msg = (_('Delete volume failed. Clone name: %(name)s. ' - 'Return code: %(ret)s.') % - {'name': cloned_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - def _remove_volume_from_group(self, volume): - ret = self._call_method('GetGrpNamesOfVol', {'cVolName': volume}) - if ret['returncode'] == zte_pub.ZTE_SUCCESS: - group_num = int(ret['data']['sdwMapGrpNum']) - for index in range(0, group_num): - group_name = ret['data']['cMapGrpNames'][index] - lun_ID = ret['data']['sdwLunLocalId'][index] - self._map_delete_lun(lun_ID, group_name) - - def _delete_volume(self, volume_name): - vol_name = {'cVolName': volume_name} - ret = self._call_method('DelVol', vol_name) - if ret['returncode'] not in [zte_pub.ZTE_ERR_VOLUME_NOT_EXIST, - zte_pub.ZTE_ERR_LUNDEV_NOT_EXIST, - zte_pub.ZTE_SUCCESS]: - err_msg = (_('Delete volume failed. Volume name: %(name)s.' - 'Return code: %(ret)s.') % - {'name': volume_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - def delete_volume(self, volume): - """Delete a volume.""" - volume_name = self._translate_volume_name(volume['name']) - LOG.debug('delete_volume: volume name: %s.', volume_name) - - self._delete_clone_relation_by_volname(volume_name, False) - self._remove_volume_from_group(volume_name) - self._delete_volume(volume_name) - - def _delete_cvol(self, cloned_name, issnapshot): - cvol_name = {'scCvolName': cloned_name} - ret = self._call_method('SyncForceDelCvol', cvol_name) - if ret['returncode'] not in [zte_pub.ZTE_ERR_CLONE_OR_SNAP_NOT_EXIST, - zte_pub.ZTE_ERR_VAS_OBJECT_NOT_EXIST, - zte_pub.ZTE_SUCCESS]: - err_msg = (_('_delete_cvol: Failed to delete clone vol. ' - 'cloned name: %(name)s with Return code: ' - '%(ret)s.') % - {'name': cloned_name, 'ret': ret['returncode']}) - if ret['returncode'] == zte_pub.ZTE_VOLUME_TASK_NOT_FINISHED: - if issnapshot: - raise exception.SnapshotIsBusy(snapshot_name=cloned_name) - else: - raise exception.VolumeIsBusy(volume_name=cloned_name) - else: - raise exception.VolumeBackendAPIException(data=err_msg) - - def _delete_clone_relation_by_volname(self, volname, issnapshot): - svol_name = {'scVolName': volname} - LOG.debug('GetCvolNamesOnVol: volume name: %s.', volname) - - ret = self._call_method('GetCvolNamesOnVol', svol_name) - data_info = ret['data'] - if ret['returncode'] == zte_pub.ZTE_SUCCESS: - sccvolnames = data_info['scCvolNames'] - for i in range(0, ret['data']['sdwCvolNum']): - cloned_name = sccvolnames[i]['scCvolName'] - self._delete_cvol(cloned_name, issnapshot) - - cloned_name = volname + zte_pub.ZTE_CLONE_SUFFIX - self._delete_cvol(cloned_name, False) - - def _create_snapshot( - self, - snapshot_name, - src_vol, - src_vol_size, - snapshot_mode): - svol_paras = { - 'scVolName': src_vol, - 'scSnapName': snapshot_name, - 'sdwSnapType': 1, - 'swRepoSpaceAlarm': 60, - 'swRepoOverflowPolicy': 0, - 'sqwRepoCapacity': float(src_vol_size * units.Mi), - 'ucIsAgent': 0, - 'ucSnapMode': snapshot_mode, - 'is_private': 0, - 'ucIsAuto': 0} - ret = self._call_method('CreateSvol', svol_paras) - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('Failed to create snap.snap name: %(snapname)s,' - 'srvol name :%(srv)s with Return code: %(ret)s. ') % - {'snapname': snapshot_name, - 'srv': src_vol, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - def create_snapshot(self, snapshot): - """create a snapshot from volume""" - snapshot_name = self._translate_volume_name(snapshot['name']) - volume_name = self._translate_volume_name(snapshot['volume_name']) - volume_size = snapshot['volume_size'] - self._create_snapshot(snapshot_name, - volume_name, - volume_size, - zte_pub.ZTE_SNAPSHOT_MODE_RW) - - def _delete_snapshot(self, snapshot_name): - svol_name = {'scSnapName': snapshot_name} - - ret = self._call_method('DelSvol', svol_name) - if ret['returncode'] not in [zte_pub.ZTE_ERR_CLONE_OR_SNAP_NOT_EXIST, - zte_pub.ZTE_ERR_VAS_OBJECT_NOT_EXIST, - zte_pub.ZTE_SUCCESS]: - err_msg = (_('_delete_snapshot:Failed to delete snap.' - 'snap name: %(snapname)s with Return code: ' - '%(ret)s.') % - {'snapname': snapshot_name, - 'ret': ret['returncode']}) - if ret['returncode'] == zte_pub.ZTE_ERR_SNAP_EXIST_CLONE: - raise exception.SnapshotIsBusy(snapshot_name=snapshot_name) - else: - raise exception.VolumeBackendAPIException(data=err_msg) - - def delete_snapshot(self, snapshot): - """delete a snapshot volume""" - snapshot_name = self._translate_volume_name(snapshot['name']) - self._delete_clone_relation_by_volname(snapshot_name, True) - self._delete_snapshot(snapshot_name) - - def _extend_volume(self, volume_name, inc_size): - ext_vol_paras = {'scVolName': volume_name, - 'qwExpandCapacity': - float(inc_size * units.Ki)} - - ret = self._call_method('ExpandVolOnPool', ext_vol_paras) - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('_extend_volume:Failed to extend vol.vol name:' - '%(name)s with Return code: %(ret)s.') % - {'name': volume_name, 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - def extend_volume(self, volume, new_size): - """extend volume size""" - size_increase = (int(new_size)) - volume['size'] - volume_name = self._translate_volume_name(volume['name']) - self._extend_volume(volume_name, size_increase) - - def _cloned_volume(self, cloned_name, src_name, vol_size, vol_type): - self._create_volume(cloned_name, vol_size) - - cvol_paras = { - 'scCvolName': cloned_name + zte_pub.ZTE_CLONE_SUFFIX, - 'scBvolName': src_name, - 'scTargetName': cloned_name, - 'sdwInitSync': 1, - 'sdwProtectRestore': 0, - 'sdwPri': 0, - 'sdwPolicy': 0, - 'sdwBvolType': vol_type} - - ret = self._call_method('CreateCvol', cvol_paras) - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - self._delete_volume(cloned_name) - err_msg = (_('_cloned_volume: Failed to clone vol. ' - 'vol name: %(name)s with Return code: %(ret)s. ') % - {'name': src_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - def create_cloned_volume(self, volume, src_vref): - """clone a volume""" - bvol_name = self._translate_volume_name(src_vref['name']) - cvol_name = self._translate_volume_name(volume['name']) - if volume['size'] < src_vref['size']: - err_msg = (_('Cloned volume size invalid. ' - 'Clone size: %(cloned_size)s. ' - 'Src volume size: %(volume_size)s.') % - {'cloned_size': volume['size'], - 'volume_size': src_vref['size']}) - raise exception.VolumeDriverException(message=err_msg) - else: - volume_size = float( - volume['size'] * units.Mi) - - try: - self._cloned_volume( - cvol_name, - bvol_name, - volume_size, - zte_pub.ZTE_VOLUME) - except Exception: - self._delete_clone_relation_by_volname(bvol_name, False) - self._cloned_volume( - cvol_name, - bvol_name, - volume_size, - zte_pub.ZTE_VOLUME) - - def create_volume_from_snapshot(self, volume, snapshot): - """Create volume from snapshot """ - bvol_name = self._translate_volume_name(snapshot['name']) - cvol_name = self._translate_volume_name(volume['name']) - if volume['size'] < snapshot['volume_size']: - err_msg = ( - _('Cloned volume size invalid. ' - 'Clone size: %(cloned_size)s. ' - 'Src volume size: %(volume_size)s.') % - {'cloned_size': volume['size'], - 'volume_size': snapshot['volume_size']}) - raise exception.VolumeDriverException(message=err_msg) - else: - volume_size = float( - volume['size'] * units.Mi) - - try: - self._cloned_volume( - cvol_name, - bvol_name, - volume_size, - zte_pub.ZTE_SNAPSHOT) - except Exception: - self._delete_clone_relation_by_volname(bvol_name, False) - self._cloned_volume( - cvol_name, - bvol_name, - volume_size, - zte_pub.ZTE_SNAPSHOT) - - def create_export(self, context, volume, connector): - """Exports the volume """ - pass - - def ensure_export(self, context, volume): - """Driver entry point to get the export info for an existing volume.""" - pass - - def remove_export(self, context, volume_id): - """Driver entry point to remove an export for a volume.""" - pass - - def get_volume_stats(self, refresh=False): - """Get volume status.""" - if refresh: - self._update_volume_status() - - return self._stats - - def _translate_host_name(self, host_name): - new_name = 'host_' + six.text_type(self._get_md5(host_name)) - new_name = new_name.replace('-', 'R') - LOG.debug('_translate_host_name: Name in cinder: %(old)s, ' - 'new name in storage system: %(new)s.', - {'old': host_name, 'new': new_name}) - - return new_name - - def _translate_volume_name(self, vol_name): - new_name = zte_pub.ZTE_VOL_NAME_PREFIX_NEW + six.text_type( - self._get_md5(vol_name)) - new_name = new_name.replace('-', 'R') - - LOG.debug('_translate_volume_name: Name in cinder: %(old)s, ' - 'new name in storage system: %(new)s.', - {'old': vol_name, 'new': new_name}) - - return new_name - - def _get_lunid_from_vol(self, volume_name, map_group_name): - map_grp_info = {'cMapGrpName': map_group_name} - ret = self._call_method('GetMapGrpInfo', map_grp_info) - if ret['returncode'] == zte_pub.ZTE_SUCCESS: - lun_num = int(ret['data']['sdwLunNum']) - lun_info = ret['data']['tLunInfo'] - for count in range(0, lun_num): - if volume_name == lun_info[count]['cVolName']: - return lun_info[count]['sdwLunId'] - return None - elif ret['returncode'] == zte_pub.ZTE_ERR_GROUP_NOT_EXIST: - return None - else: - err_msg = (_('_get_lunid_from_vol:Get lunid from vol fail. ' - 'Group name:%(name)s vol:%(vol)s ' - 'with Return code: %(ret)s.') % - {'name': map_group_name, - 'vol': volume_name, - 'ret': ret['returncode']}) - raise exception.VolumeDriverException(message=err_msg) - - def _get_group_lunnum(self, map_group_name): - map_grp_info = {'cMapGrpName': map_group_name} - ret = self._call_method('GetMapGrpInfo', map_grp_info) - if ret['returncode'] == zte_pub.ZTE_SUCCESS: - lun_num = ret['data']['sdwLunNum'] - return int(lun_num) - elif ret['returncode'] == zte_pub.ZTE_ERR_GROUP_NOT_EXIST: - return -1 - else: - err_msg = (_('_get_group_lunnum:Get group info fail. ' - 'Group name:%(name)s with Return code: %(ret)s.') % - {'name': map_group_name, 'ret': ret['returncode']}) - raise exception.VolumeDriverException(message=err_msg) - - def _delete_group(self, map_group_name): - # before delete the group, we must delete the hosts in group - self._map_delete_host(map_group_name) - - map_grp_info = {'cMapGrpName': map_group_name} - ret = self._call_method('DelMapGrp', map_grp_info) - if ret['returncode'] not in [zte_pub.ZTE_SUCCESS, - zte_pub.ZTE_ERR_GROUP_NOT_EXIST]: - err_msg = (_('_delete_group:Del group fail. ' - 'Group name:%(name)s with Return code: %(ret)s.') % - {'name': map_group_name, 'ret': ret['returncode']}) - raise exception.VolumeDriverException(message=err_msg) - - def _map_add_lun(self, volume_name, map_group_name): - add_vol_to_grp = { - 'cMapGrpName': map_group_name, - 'sdwLunId': 0, - 'cVolName': volume_name} - ret = self._call_method('AddVolToGrp', add_vol_to_grp) - - if ret['returncode'] in [zte_pub.ZTE_SUCCESS, - zte_pub.ZTE_VOLUME_IN_GROUP, - zte_pub.ZTE_ERR_VOL_EXISTS]: - return self._get_lunid_from_vol(volume_name, map_group_name) - - err_msg = ( - _( - '_map_add_lun:fail to add vol to grp. group name:%(name)s' - ' lunid:%(lun)s ' - 'vol:%(vol)s with Return code: %(ret)s') % - {'name': map_group_name, - 'lun': 0, - 'vol': volume_name, - 'ret': ret['returncode']}) - raise exception.VolumeDriverException(message=err_msg) - - def _update_volume_group_info(self): - pool_list = self._get_pool_list() - pool_info = {'total': 0, 'free': 0} - - for item in pool_list: - pool_info['total'] += item['total'] - pool_info['free'] += item['free'] - return pool_info - - def _get_sysinfo(self): - ret = self._call_method('GetSysInfo') - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('_get_sysinfo:get sys info failed. Return code: ' - '%(ret)s.'), - {'ret': ret['returncode']}) - raise exception.VolumeDriverException(message=err_msg) - - return ret['data'] - - def _update_volume_status(self): - LOG.debug("Updating volume status") - - sys_info = self._get_sysinfo() - backend_name = self.configuration.safe_get('volume_backend_name') - pool_info = self._update_volume_group_info() - data = { - "volume_backend_name": backend_name or 'ZteISCSIDriver', - 'vendor_name': sys_info['cVendor'], - 'driver_version': sys_info['cVersionName'], - 'storage_protocol': 'iSCSI', - 'multiattach': False, - 'total_capacity_gb': pool_info['total'], - 'free_capacity_gb': pool_info['free'], - 'reserved_percentage': 0, - 'QoS_support': False} - - self._stats = data - - def _create_group(self, initiator_name, map_group_name): - pass - - def _map_delete_host(self, map_group_name): - pass - - def _map_delete_lun(self, lunid, initiator_name): - pass - - -@interface.volumedriver -class ZteISCSIDriver(ZTEVolumeDriver, driver.ISCSIDriver): - """Zte iSCSI volume driver.""" - - # ThirdPartySystems wiki page - WIKI_CI_NAME = "ZTE_cinder2_CI" - - # TODO(smcginnis) Remove driver in Queens if CI issues not fixed - SUPPORTED = False - - def __init__(self, *args, **kwargs): - super(ZteISCSIDriver, self).__init__(*args, **kwargs) - - def _map_lun(self, initiator_name, volume_name, map_group_name): - self._create_group(initiator_name, map_group_name) - return self._map_add_lun(volume_name, map_group_name) - - def _get_net_cfg_ips(self): - ret = self._call_method('GetSystemNetCfg') - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('get_Net_Cfg failed. Return code: %(ret)s.') % - {'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - targetips = [] - net_cfg_info = ret['data']['tSystemNetCfg'] - for item in range(ret['data']['sdwDeviceNum']): - if (net_cfg_info[item]['udwRoleType'] == 0 and - net_cfg_info[item]['cIpAddr']): - targetips.append(net_cfg_info[item]['cIpAddr']) - return targetips - - @utils.synchronized('zte_locked_initialize_connection') - def initialize_connection(self, volume, connector): - """Map a volume to a host and return target iSCSI information.""" - initiator_name = connector['initiator'] - volume_name = self._translate_volume_name(volume['name']) - - LOG.debug('initialize_connection: Volume name: %(volume)s. ' - 'Initiator name: %(ini)s.', - {'volume': volume_name, - 'ini': initiator_name}) - - iscsi_conf = self._get_iscsi_info() - target_ips = iscsi_conf['DefaultTargetIPs'] - - target_portals = {} - target_iqns = [] - for ip in target_ips: - iqn = self._get_tgt_iqn(ip) - if iqn: - if iqn not in target_iqns: - target_iqns.append(iqn) - target_portals[iqn] = ['%s:%s' % (ip, '3260')] - else: - target_portals[iqn].append('%s:%s' % (ip, '3260')) - if not target_iqns: - msg = (_('Failed to get target ip or iqn ' - 'for initiator %(ini)s, please check config file.') % - {'ini': initiator_name}) - raise exception.VolumeDriverException(message=msg) - - map_group_name = self._translate_grp_name(initiator_name) - lunid = self._map_lun(initiator_name, volume_name, map_group_name) - - # Return iSCSI properties. - properties = { - 'target_discovered': False, - 'target_portal': target_portals[ - target_iqns[0]][0], - 'target_iqn': target_iqns[0], - 'target_lun': lunid, - 'volume_id': volume['id']} - - if target_iqns and target_portals: - properties['target_portals'] = target_portals - properties['target_iqns'] = target_iqns - - return {'driver_volume_type': 'iscsi', 'data': properties} - - @utils.synchronized('zte_locked_initialize_connection') - def terminate_connection(self, volume, connector, **kwargs): - """Delete map between a volume and a host.""" - initiator_name = connector['initiator'] - volume_name = self._translate_volume_name(volume['name']) - LOG.debug('volume name: %(volume)s, initiator name: %(ini)s.', - {'volume': volume_name, - 'ini': initiator_name}) - - map_group_name = self._translate_grp_name(initiator_name) - lunid = self._get_lunid_from_vol(volume_name, map_group_name) - self._map_delete_lun(lunid, initiator_name) - - def _get_iscsi_info(self): - iscsi_info = {} - try: - iscsi_info['DefaultTargetIPs'] = self._get_net_cfg_ips() - if not iscsi_info['DefaultTargetIPs']: - err_msg = _('Can not get target ip address. ') - raise exception.VolumeBackendAPIException(data=err_msg) - initiator_list = [] - iscsi_info['Initiator'] = initiator_list - - except Exception: - LOG.exception('_get_iscsi_info error.') - raise - - return iscsi_info - - def _translate_grp_name(self, grp_name): - new_name = zte_pub.ZTE_HOST_GROUP_NAME_PREFIX + six.text_type( - self._get_md5(grp_name)) - new_name = new_name.replace('-', 'R') - - LOG.debug('_translate_grp_name:Name in cinder: %(old)s, ' - 'new name in storage system: %(new)s.', - {'old': grp_name, - 'new': new_name}) - - return new_name - - def _get_target_ip_ctrl(self, target_ip): - LOG.debug('_get_target_ip_ctrl:target IP is %s.', target_ip) - ret = self._call_method('GetSystemNetCfg') - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('_get_target_ip_ctrl:get iscsi port list fail. ' - 'with Return code: %(ret)s.') % - {'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - count = ret['data']['sdwDeviceNum'] - for index in range(0, count): - systemnetcfg = ret['data']['tSystemNetCfg'][index] - if target_ip == systemnetcfg['cIpAddr']: - return systemnetcfg['udwCtrlId'] - return None - - def _get_tgt_iqn(self, iscsiip): - # as the given iscsiip,we need to find it's ctrl number - ip_ctrl = self._get_target_ip_ctrl(iscsiip) - - if ip_ctrl is None: - LOG.exception('_get_tgt_iqn:get iscsi ip ctrl fail, ' - 'IP is %s.', iscsiip) - return None - - # get the ctrl iqn - ret = self._call_method('GetIscsiTargetName') - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - return None - - target_info = ret['data']['tIscsiTargetInfo'] - ctrl_count = ret['data']['udwCtrlCount'] - for index in range(0, ctrl_count): - if ip_ctrl == target_info[index]['udwCtrlId']: - return target_info[index]['cTgtName'] - return None - - def _create_group(self, initiator_name, map_group_name): - - map_grp_info = {'cMapGrpName': map_group_name} - ret = self._call_method('CreateMapGrp', map_grp_info) - - if ((ret['returncode'] == zte_pub.ZTE_SUCCESS) or - (ret['returncode'] == zte_pub.ZTE_ERR_GROUP_EXIST)): - host_name = self._translate_host_name(initiator_name) - host_info = {'cHostAlias': host_name, 'ucOs': 1, 'ucType': 1, - 'cPortName': initiator_name, - 'sdwMultiPathMode': 1, 'cMulChapPass': ''} - - # create host - ret = self._call_method('CreateHost', host_info) - if ret['returncode'] not in [zte_pub.ZTE_SUCCESS, - zte_pub.ZTE_ERR_HOSTNAME_EXIST, - zte_pub.ZTE_ERR_PORT_EXIST, - zte_pub.ZTE_ERR_PORT_EXIST_OLD]: - err_msg = ( - _('create host failed. Host name:%(name)s ' - 'with Return code: %(ret)s.') % - {'name': host_name, 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - # If port deleted by user, add it. - port_info = { - 'cHostAlias': host_name, - 'ucType': 1, - 'cPortName': initiator_name, - 'sdwMultiPathMode': 1, - 'cMulChapPass': ''} - ret = self._call_method('AddPortToHost', port_info) - if ret['returncode'] not in [zte_pub.ZTE_SUCCESS, - zte_pub.ZTE_ERR_PORT_EXIST, - zte_pub.ZTE_ERR_PORT_EXIST_OLD]: - err_msg = (_('_create_group:add port failed. Port name: ' - '%(name)s with Return code: %(ret)s.') % - {'name': initiator_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - host_in_grp = { - 'ucInitName': host_name, - 'cMapGrpName': map_group_name} - ret = self._call_method('AddHostToGrp', host_in_grp) - if ret['returncode'] not in [zte_pub.ZTE_SUCCESS, - zte_pub.ZTE_ERR_HOST_EXIST, - zte_pub.ZTE_ERR_HOST_EXIST_OLD]: - self._delete_group(map_group_name) - err_msg = (_('_create_group:add host to group failed. ' - 'group name:%(name)s init name :%(init)s ' - 'with Return code: %(ret)s.') % - {'name': map_group_name, - 'init': host_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - else: - err_msg = (_('create group failed. Group name:%(name)s ' - 'with Return code: %(ret)s.') % - {'name': map_group_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - def _map_delete_lun(self, lunid, initiator_name): - map_group_name = self._translate_grp_name(initiator_name) - - # lun not exist, no need to delete - if (lunid != zte_pub.ZTE_LUNID_NULL - and lunid is not None): - del_vol_from_grp = { - 'cMapGrpName': map_group_name, - 'sdwLunId': lunid} - ret = self._call_method('DelVolFromGrp', del_vol_from_grp) - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('_map_lun:delete lunid from group failed. ' - 'group name:%(name)s lunid : %(lun)s ' - 'with Return code: %(ret)s.') % - {'name': map_group_name, 'lun': lunid, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - # if no lun in group,then we will delete this group - lun_num = self._get_group_lunnum(map_group_name) - if lun_num == 0: - self._delete_group(map_group_name) - - def _map_delete_host(self, map_group_name): - - map_grp_info = {'cMapGrpName': map_group_name} - ret = self._call_method('GetMapGrpInfo', map_grp_info) - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('_map_delete_host:get map group info failed. ' - 'group name:%(name)s with Return code: %(ret)s.') % - {'name': map_group_name, 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - sdwhostnum = ret['data']['sdwHostNum'] - - if sdwhostnum > 0: - thostinfo = ret['data']['tHostInfo'] - for hostindex in range(0, int(sdwhostnum)): - initiator_name = thostinfo[hostindex]['ucHostName'] - host_in_grp = { - 'ucInitName': initiator_name, - 'cMapGrpName': map_group_name} - ret = self._call_method('DelHostFromGrp', host_in_grp) - if ret['returncode'] == zte_pub.ZTE_ERR_GROUP_NOT_EXIST: - continue - if ret['returncode'] not in [zte_pub.ZTE_SUCCESS, - zte_pub.ZTE_ERR_HOST_NOT_EXIST]: - msg = _('delete host from group failed. ') - raise exception.VolumeDriverException(message=msg) - - ret = self._call_method( - 'GetHost', {"cHostAlias": initiator_name}) - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('_map_delete_host:get host info failed. ' - 'host name:%(name)s with Return code: ' - '%(ret)s.') % - {'name': initiator_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - return_data = ret['data'] - portnum = return_data['sdwPortNum'] - for portindex in range(0, int(portnum)): - port_host_info = {} - port_info = return_data['tPort'] - port_name = port_info[portindex]['cPortName'] - port_host_info['cPortName'] = port_name - port_host_info['cHostAlias'] = initiator_name - - ret = self._call_method('DelPortFromHost', port_host_info) - if ret['returncode'] != zte_pub.ZTE_SUCCESS: - err_msg = (_('delete port from host failed. ' - 'host name:%(name)s, port name:%(port)s ' - 'with Return code: %(ret)s.') % - {'name': initiator_name, - 'port': port_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) - - ret = self._call_method( - 'DelHost', {"cHostAlias": initiator_name}) - if (ret['returncode'] not - in [zte_pub.ZTE_SUCCESS, - zte_pub.ZTE_ERR_HOSTNAME_NOT_EXIST]): - err_msg = (_('_map_delete_host: delete host failed. ' - 'host name:%(name)s with Return code: ' - '%(ret)s') % - {'name': initiator_name, - 'ret': ret['returncode']}) - raise exception.VolumeBackendAPIException(data=err_msg) diff --git a/cinder/volume/drivers/zte/zte_pub.py b/cinder/volume/drivers/zte/zte_pub.py deleted file mode 100644 index dc9747dfe64..00000000000 --- a/cinder/volume/drivers/zte/zte_pub.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2016 ZTE Corporation. All rights reserved -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -""" -Constants used in ZTE Volume driver. -""" - -ZTE_HOST_GROUP_NAME_PREFIX = 'HostGroup_' -ZTE_VOL_AND_SNAP_NAME_PREFIX = 'OpenStack_' -ZTE_VOL_NAME_PREFIX_NEW = 'OpenCos_' -ZTE_CLONE_SUFFIX = 'c' -ZTE_GROUP_MAX_LUN = 255 -ZTE_SUCCESS = 0 -ZTE_VOLUME_IN_GROUP = 16917029 -ZTE_WEB_LOGIN_TYPE = 5 -ZTE_ERR_GROUP_NOT_EXIST = 16916997 -ZTE_ERR_GROUP_EXIST = 16916994 -ZTE_ERR_HOSTNAME_EXIST = 16918785 -ZTE_ERR_HOSTNAME_NOT_EXIST = 16918786 -ZTE_ERR_PORT_EXIST_OLD = 16918787 -ZTE_ERR_PORT_EXIST = 16918798 -ZTE_ERR_PORT_EXIST_INOTHER = 16918799 -ZTE_ERR_HOST_NOT_EXIST = 16917004 -ZTE_ERR_HOST_EXIST_OLD = 16917002 -ZTE_ERR_HOST_EXIST = 16917015 -ZTE_ERR_HOST_EXIST_INOTHER = 16917016 -ZTE_ERR_VOLUME_NOT_EXIST = 17108999 -ZTE_ERR_OBJECT_EXIST = 16917159 -ZTE_ERR_CLONE_OR_SNAP_NOT_EXIST = 16917040 -ZTE_ERR_VOL_EXISTS = 16917000 -ZTE_ERR_LUNDEV_NOT_EXIST = 16973826 -ZTE_ERR_VAS_OBJECT_NOT_EXIST = 17436681 -ZTE_VOLUME_TASK_NOT_FINISHED = 17436959 -ZTE_ERR_SNAP_EXIST_CLONE = 16917163 -ZTE_SESSION_EXIST = 1495 -ZTE_STATUS_OK = 1 - -ZTE_VOLUME = 0 -ZTE_SNAPSHOT = 1 - -ZTE_LUNID_NULL = -1 - -ZTE_VOLUME_ALLOCATION_RATIO = 20 -ZTE_VOLUME_SNAPSHOT_PERCENT = 50 -ZTE_DEFAULT_TIMEOUT = 720 - -ZTE_SNAPSHOT_MODE_READ_ONLY = 0 -ZTE_SNAPSHOT_MODE_RW = 1 diff --git a/doc/source/configuration/block-storage/drivers/zte-storage-driver.rst b/doc/source/configuration/block-storage/drivers/zte-storage-driver.rst deleted file mode 100644 index 4044e8f44b0..00000000000 --- a/doc/source/configuration/block-storage/drivers/zte-storage-driver.rst +++ /dev/null @@ -1,158 +0,0 @@ -================== -ZTE volume drivers -================== - -The ZTE volume drivers allow ZTE KS3200 or KU5200 arrays -to be used for Block Storage in OpenStack deployments. - -System requirements -~~~~~~~~~~~~~~~~~~~ - -To use the ZTE drivers, the following prerequisites: - -- ZTE KS3200 or KU5200 array with: - - - iSCSI or FC interfaces - - 30B2 firmware or later - -- Network connectivity between the OpenStack host and the array - management interfaces - -- HTTPS or HTTP must be enabled on the array - -Supported operations -~~~~~~~~~~~~~~~~~~~~ - -- Create, delete, attach, and detach volumes. -- Create, list, and delete volume snapshots. -- Create a volume from a snapshot. -- Copy an image to a volume. -- Copy a volume to an image. -- Clone a volume. -- Extend a volume. -- Migrate a volume with back-end assistance. -- Retype a volume. -- Manage and unmanage a volume. - -Configuring the array -~~~~~~~~~~~~~~~~~~~~~ - -#. Verify that the array can be managed using an HTTPS connection. HTTP can - also be used if ``zte_api_protocol=http`` is placed into the - appropriate sections of the ``cinder.conf`` file. - - Confirm that virtual pools A and B are present if you plan to use - virtual pools for OpenStack storage. - -#. Edit the ``cinder.conf`` file to define a storage back-end entry for - each storage pool on the array that will be managed by OpenStack. Each - entry consists of a unique section name, surrounded by square brackets, - followed by options specified in ``key=value`` format. - - - The ``zte_backend_name`` value specifies the name of the storage - pool on the array. - - - The ``volume_backend_name`` option value can be a unique value, if - you wish to be able to assign volumes to a specific storage pool on - the array, or a name that is shared among multiple storage pools to - let the volume scheduler choose where new volumes are allocated. - - - The rest of the options will be repeated for each storage pool in a - given array: the appropriate cinder driver name, IP address or - host name of the array management interface; the username and password - of an array user account with ``manage`` privileges; and the iSCSI IP - addresses for the array if using the iSCSI transport protocol. - - In the examples below, two back ends are defined, one for pool A and one - for pool B, and a common ``volume_backend_name``. Use this for a - single volume type definition can be used to allocate volumes from both - pools. - - **Example: iSCSI back-end entries** - - .. code-block:: ini - - [pool-a] - zte_backend_name = A - volume_backend_name = zte-array - volume_driver = cinder.volume.drivers.zte.zte_iscsi.ZTEISCSIDriver - san_ip = 10.1.2.3 - san_login = manage - san_password = !manage - zte_iscsi_ips = 10.2.3.4,10.2.3.5 - - [pool-b] - zte_backend_name = B - volume_backend_name = zte-array - volume_driver = cinder.volume.drivers.zte.zte_iscsi.ZTEISCSIDriver - san_ip = 10.1.2.3 - san_login = manage - san_password = !manage - zte_iscsi_ips = 10.2.3.4,10.2.3.5 - - **Example: Fibre Channel back end entries** - - .. code-block:: ini - - [pool-a] - zte_backend_name = A - volume_backend_name = zte-array - volume_driver = cinder.volume.drivers.zte.zte_fc.ZTEFCDriver - san_ip = 10.1.2.3 - san_login = manage - san_password = !manage - - [pool-b] - zte_backend_name = B - volume_backend_name = zte-array - volume_driver = cinder.volume.drivers.zte.zte_fc.ZTEFCDriver - san_ip = 10.1.2.3 - san_login = manage - san_password = !manage - -#. If HTTPS is not enabled in the array, include - ``zte_api_protocol = http`` in each of the back-end definitions. - -#. If HTTPS is enabled, you can enable certificate verification with the - option ``zte_verify_certificate=True``. You may also use the - ``zte_verify_certificate_path`` parameter to specify the path to a - ``CA_BUNDLE`` file containing CAs other than those in the default list. - -#. Modify the ``[DEFAULT]`` section of the ``cinder.conf`` file to add an - ``enabled_backends`` parameter specifying the back-end entries you added, - and a ``default_volume_type`` parameter specifying the name of a volume - type that you will create in the next step. - - **Example: [DEFAULT] section changes** - - .. code-block:: ini - - [DEFAULT] - # ... - enabled_backends = pool-a,pool-b - default_volume_type = zte - -#. Create a new volume type for each distinct ``volume_backend_name`` value - that you added to the ``cinder.conf`` file. The example below - assumes that the same ``volume_backend_name=zte-array`` - option was specified in all of the - entries, and specifies that the volume type ``zte`` can be used to - allocate volumes from any of them. - - **Example: Creating a volume type** - - .. code-block:: console - - $ openstack volume type create zte - $ openstack volume type set --property volume_backend_name=zte-array zte - -#. After modifying the ``cinder.conf`` file, - restart the ``cinder-volume`` service. - -Driver-specific options -~~~~~~~~~~~~~~~~~~~~~~~ - -The following table contains the configuration options that are specific -to the ZTE drivers. - -.. include:: ../../tables/cinder-zte.inc diff --git a/doc/source/configuration/block-storage/volume-drivers.rst b/doc/source/configuration/block-storage/volume-drivers.rst index 0731a060828..df634c291ff 100644 --- a/doc/source/configuration/block-storage/volume-drivers.rst +++ b/doc/source/configuration/block-storage/volume-drivers.rst @@ -58,7 +58,6 @@ Volume drivers drivers/zadara-volume-driver.rst drivers/zfssa-iscsi-driver.rst drivers/zfssa-nfs-driver.rst - drivers/zte-storage-driver.rst To use different volume drivers for the cinder-volume service, use the parameters described in these sections. diff --git a/doc/source/configuration/tables/cinder-zte.inc b/doc/source/configuration/tables/cinder-zte.inc deleted file mode 100644 index fa7f0d75ddc..00000000000 --- a/doc/source/configuration/tables/cinder-zte.inc +++ /dev/null @@ -1,52 +0,0 @@ -.. - Warning: Do not edit this file. It is automatically generated from the - software project's code and your changes will be overwritten. - - The tool to generate this file lives in openstack-doc-tools repository. - - Please make any changes needed in the code, then run the - autogenerate-config-doc tool from the openstack-doc-tools repository, or - ask for help on the documentation mailing list, IRC channel or meeting. - -.. _cinder-zte: - -.. list-table:: Description of Zte volume driver configuration options - :header-rows: 1 - :class: config-ref-table - - * - Configuration option = Default value - - Description - * - **[DEFAULT]** - - - * - ``zteAheadReadSize`` = ``8`` - - (Integer) Cache readahead size. - * - ``zteCachePolicy`` = ``1`` - - (Integer) Cache policy. 0, Write Back; 1, Write Through. - * - ``zteChunkSize`` = ``4`` - - (Integer) Virtual block size of pool. Unit : KB. Valid value : 4, 8, 16, 32, 64, 128, 256, 512. - * - ``zteControllerIP0`` = ``None`` - - (IP) Main controller IP. - * - ``zteControllerIP1`` = ``None`` - - (IP) Slave controller IP. - * - ``zteLocalIP`` = ``None`` - - (IP) Local IP. - * - ``ztePoolVoAllocatedPolicy`` = ``0`` - - (Integer) Pool volume allocated policy. 0, Auto; 1, High Performance Tier First; 2, Performance Tier First; 3, Capacity Tier First. - * - ``ztePoolVolAlarmStopAllocatedFlag`` = ``0`` - - (Integer) Pool volume alarm stop allocated flag. - * - ``ztePoolVolAlarmThreshold`` = ``0`` - - (Integer) Pool volume alarm threshold. [0, 100] - * - ``ztePoolVolInitAllocatedCapacity`` = ``0`` - - (Integer) Pool volume init allocated Capacity.Unit : KB. - * - ``ztePoolVolIsThin`` = ``False`` - - (Integer) Whether it is a thin volume. - * - ``ztePoolVolMovePolicy`` = ``0`` - - (Integer) Pool volume move policy.0, Auto; 1, Highest Available; 2, Lowest Available; 3, No Relocation. - * - ``zteSSDCacheSwitch`` = ``1`` - - (Integer) SSD cache switch. 0, OFF; 1, ON. - * - ``zteStoragePool`` = - - (List) Pool name list. - * - ``zteUserName`` = ``None`` - - (String) User name. - * - ``zteUserPassword`` = ``None`` - - (String) User password. diff --git a/releasenotes/notes/queens-driver-removal-72a1a36689b6d890.yaml b/releasenotes/notes/queens-driver-removal-72a1a36689b6d890.yaml index 0b1be6a6c0f..2d0a45c9117 100644 --- a/releasenotes/notes/queens-driver-removal-72a1a36689b6d890.yaml +++ b/releasenotes/notes/queens-driver-removal-72a1a36689b6d890.yaml @@ -13,4 +13,5 @@ upgrade: * Reduxio * Violin * X-IO + * ZTE