Add cinder volume drivers for NEC V series Storage
VStorageISCSIDriver is an iSCSI driver. VStorageFCDriver is a Fibre Channel driver. These drivers import Hitachi driver, and parameters are customized for NEC. Implements: blueprint nec-v-volume-driver Change-Id: I7e7ebea51f8c3c80df99eb85a8327e5b8d1b63c6
This commit is contained in:
parent
4082ed3bea
commit
c4f5564d99
@ -138,6 +138,8 @@ from cinder.volume.drivers import linstordrv as \
|
||||
from cinder.volume.drivers import lvm as cinder_volume_drivers_lvm
|
||||
from cinder.volume.drivers.macrosan import driver as \
|
||||
cinder_volume_drivers_macrosan_driver
|
||||
from cinder.volume.drivers.nec.v import nec_v_rest as \
|
||||
cinder_volume_drivers_nec_v_necvrest
|
||||
from cinder.volume.drivers.netapp import options as \
|
||||
cinder_volume_drivers_netapp_options
|
||||
from cinder.volume.drivers.nexenta import options as \
|
||||
@ -353,6 +355,9 @@ def list_opts():
|
||||
cinder_volume_drivers_linstordrv.linstor_opts,
|
||||
cinder_volume_drivers_lvm.volume_opts,
|
||||
cinder_volume_drivers_macrosan_driver.config.macrosan_opts,
|
||||
cinder_volume_drivers_nec_v_necvrest.COMMON_VOLUME_OPTS,
|
||||
cinder_volume_drivers_nec_v_necvrest.REST_VOLUME_OPTS,
|
||||
cinder_volume_drivers_nec_v_necvrest.FC_VOLUME_OPTS,
|
||||
cinder_volume_drivers_netapp_options.netapp_proxy_opts,
|
||||
cinder_volume_drivers_netapp_options.netapp_connection_opts,
|
||||
cinder_volume_drivers_netapp_options.netapp_transport_opts,
|
||||
|
0
cinder/tests/unit/volume/drivers/nec/v/__init__.py
Normal file
0
cinder/tests/unit/volume/drivers/nec/v/__init__.py
Normal file
383
cinder/tests/unit/volume/drivers/nec/v/test_nec_rest_fc.py
Normal file
383
cinder/tests/unit/volume/drivers/nec/v/test_nec_rest_fc.py
Normal file
@ -0,0 +1,383 @@
|
||||
# Copyright (C) 2021 NEC corporation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
"""Unit tests for NEC Driver."""
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from oslo_config import cfg
|
||||
import requests
|
||||
|
||||
from cinder import context as cinder_context
|
||||
from cinder import db
|
||||
from cinder.tests.unit import fake_volume
|
||||
from cinder.tests.unit import test
|
||||
from cinder.volume import configuration as conf
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest_api
|
||||
from cinder.volume.drivers.nec.v import nec_v_fc
|
||||
from cinder.volume.drivers.nec.v import nec_v_rest
|
||||
from cinder.volume import volume_utils
|
||||
|
||||
# Configuration parameter values
|
||||
CONFIG_MAP = {
|
||||
'serial': '886000123456',
|
||||
'my_ip': '127.0.0.1',
|
||||
'rest_server_ip_addr': '172.16.18.108',
|
||||
'rest_server_ip_port': '23451',
|
||||
'port_id': 'CL1-A',
|
||||
'host_grp_name': 'NEC-0123456789abcdef',
|
||||
'host_mode': 'LINUX/IRIX',
|
||||
'host_wwn': '0123456789abcdef',
|
||||
'target_wwn': '1111111123456789',
|
||||
'user_id': 'user',
|
||||
'user_pass': 'password',
|
||||
'pool_name': 'test_pool',
|
||||
'auth_user': 'auth_user',
|
||||
'auth_password': 'auth_password',
|
||||
}
|
||||
|
||||
# Dummy response
|
||||
DEFAULT_CONNECTOR = {
|
||||
'host': 'host',
|
||||
'ip': CONFIG_MAP['my_ip'],
|
||||
'wwpns': [CONFIG_MAP['host_wwn']],
|
||||
'multipath': False,
|
||||
}
|
||||
|
||||
# Dummy response for REST API
|
||||
POST_SESSIONS_RESULT = {
|
||||
"token": "b74777a3-f9f0-4ea8-bd8f-09847fac48d3",
|
||||
"sessionId": 0,
|
||||
}
|
||||
|
||||
GET_PORTS_RESULT = {
|
||||
"data": [
|
||||
{
|
||||
"portId": CONFIG_MAP['port_id'],
|
||||
"portType": "FIBRE",
|
||||
"portAttributes": [
|
||||
"TAR",
|
||||
"MCU",
|
||||
"RCU",
|
||||
"ELUN"
|
||||
],
|
||||
"fabricMode": True,
|
||||
"portConnection": "PtoP",
|
||||
"lunSecuritySetting": True,
|
||||
"wwn": CONFIG_MAP['target_wwn'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
GET_HOST_WWNS_RESULT = {
|
||||
"data": [
|
||||
{
|
||||
"hostGroupNumber": 0,
|
||||
"hostWwn": CONFIG_MAP['host_wwn'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
COMPLETED_SUCCEEDED_RESULT = {
|
||||
"status": "Completed",
|
||||
"state": "Succeeded",
|
||||
"affectedResources": ('a/b/c/1',),
|
||||
}
|
||||
|
||||
|
||||
def _brick_get_connector_properties(multipath=False, enforce_multipath=False):
|
||||
"""Return a predefined connector object."""
|
||||
return DEFAULT_CONNECTOR
|
||||
|
||||
|
||||
class FakeResponse():
|
||||
|
||||
def __init__(self, status_code, data=None, headers=None):
|
||||
self.status_code = status_code
|
||||
self.data = data
|
||||
self.text = data
|
||||
self.content = data
|
||||
self.headers = {'Content-Type': 'json'} if headers is None else headers
|
||||
|
||||
def json(self):
|
||||
return self.data
|
||||
|
||||
|
||||
class VStorageRESTFCDriverTest(test.TestCase):
|
||||
"""Unit test class for NEC REST interface fibre channel module."""
|
||||
|
||||
test_existing_ref = {'source-id': '1'}
|
||||
test_existing_ref_name = {
|
||||
'source-name': '15960cc7-38c9-4c5b-b4f1-365be5eeed45'}
|
||||
|
||||
def setUp(self):
|
||||
"""Set up the test environment."""
|
||||
def _set_required(opts, required):
|
||||
for opt in opts:
|
||||
opt.required = required
|
||||
|
||||
# Initialize Cinder and avoid checking driver options.
|
||||
rest_required_opts = [
|
||||
opt for opt in nec_v_rest.REST_VOLUME_OPTS if opt.required]
|
||||
common_required_opts = [
|
||||
opt for opt in nec_v_rest.COMMON_VOLUME_OPTS if opt.required]
|
||||
_set_required(rest_required_opts, False)
|
||||
_set_required(common_required_opts, False)
|
||||
super(VStorageRESTFCDriverTest, self).setUp()
|
||||
_set_required(rest_required_opts, True)
|
||||
_set_required(common_required_opts, True)
|
||||
|
||||
self.configuration = mock.Mock(conf.Configuration)
|
||||
self.ctxt = cinder_context.get_admin_context()
|
||||
self._setup_config()
|
||||
self._setup_driver()
|
||||
|
||||
def _setup_config(self):
|
||||
"""Set configuration parameter values."""
|
||||
self.configuration.config_group = "REST"
|
||||
|
||||
self.configuration.volume_backend_name = "RESTFC"
|
||||
self.configuration.volume_driver = (
|
||||
"cinder.volume.drivers.nec.v.nec_v_fc.VStorageFCDriver")
|
||||
self.configuration.reserved_percentage = "0"
|
||||
self.configuration.use_multipath_for_image_xfer = False
|
||||
self.configuration.enforce_multipath_for_image_xfer = False
|
||||
self.configuration.max_over_subscription_ratio = 500.0
|
||||
self.configuration.driver_ssl_cert_verify = False
|
||||
|
||||
self.configuration.nec_v_storage_id = CONFIG_MAP['serial']
|
||||
self.configuration.nec_v_pool = "30"
|
||||
self.configuration.nec_v_snap_pool = None
|
||||
self.configuration.nec_v_ldev_range = "0-1"
|
||||
self.configuration.nec_v_target_ports = [CONFIG_MAP['port_id']]
|
||||
self.configuration.nec_v_compute_target_ports = [
|
||||
CONFIG_MAP['port_id']]
|
||||
self.configuration.nec_v_group_create = True
|
||||
self.configuration.nec_v_group_delete = True
|
||||
self.configuration.nec_v_copy_speed = 3
|
||||
self.configuration.nec_v_copy_check_interval = 3
|
||||
self.configuration.nec_v_async_copy_check_interval = 10
|
||||
|
||||
self.configuration.san_login = CONFIG_MAP['user_id']
|
||||
self.configuration.san_password = CONFIG_MAP['user_pass']
|
||||
self.configuration.san_ip = CONFIG_MAP[
|
||||
'rest_server_ip_addr']
|
||||
self.configuration.san_api_port = CONFIG_MAP[
|
||||
'rest_server_ip_port']
|
||||
self.configuration.nec_v_rest_disable_io_wait = True
|
||||
self.configuration.nec_v_rest_tcp_keepalive = True
|
||||
self.configuration.nec_v_discard_zero_page = True
|
||||
self.configuration.nec_v_rest_number = "0"
|
||||
self.configuration.nec_v_lun_timeout = hbsd_rest._LUN_TIMEOUT
|
||||
self.configuration.nec_v_lun_retry_interval = (
|
||||
hbsd_rest._LUN_RETRY_INTERVAL)
|
||||
self.configuration.nec_v_restore_timeout = hbsd_rest._RESTORE_TIMEOUT
|
||||
self.configuration.nec_v_state_transition_timeout = (
|
||||
hbsd_rest._STATE_TRANSITION_TIMEOUT)
|
||||
self.configuration.nec_v_lock_timeout = hbsd_rest_api._LOCK_TIMEOUT
|
||||
self.configuration.nec_v_rest_timeout = hbsd_rest_api._REST_TIMEOUT
|
||||
self.configuration.nec_v_extend_timeout = (
|
||||
hbsd_rest_api._EXTEND_TIMEOUT)
|
||||
self.configuration.nec_v_exec_retry_interval = (
|
||||
hbsd_rest_api._EXEC_RETRY_INTERVAL)
|
||||
self.configuration.nec_v_rest_connect_timeout = (
|
||||
hbsd_rest_api._DEFAULT_CONNECT_TIMEOUT)
|
||||
self.configuration.nec_v_rest_job_api_response_timeout = (
|
||||
hbsd_rest_api._JOB_API_RESPONSE_TIMEOUT)
|
||||
self.configuration.nec_v_rest_get_api_response_timeout = (
|
||||
hbsd_rest_api._GET_API_RESPONSE_TIMEOUT)
|
||||
self.configuration.nec_v_rest_server_busy_timeout = (
|
||||
hbsd_rest_api._REST_SERVER_BUSY_TIMEOUT)
|
||||
self.configuration.nec_v_rest_keep_session_loop_interval = (
|
||||
hbsd_rest_api._KEEP_SESSION_LOOP_INTERVAL)
|
||||
self.configuration.nec_v_rest_another_ldev_mapped_retry_timeout = (
|
||||
hbsd_rest_api._ANOTHER_LDEV_MAPPED_RETRY_TIMEOUT)
|
||||
self.configuration.nec_v_rest_tcp_keepidle = (
|
||||
hbsd_rest_api._TCP_KEEPIDLE)
|
||||
self.configuration.nec_v_rest_tcp_keepintvl = (
|
||||
hbsd_rest_api._TCP_KEEPINTVL)
|
||||
self.configuration.nec_v_rest_tcp_keepcnt = (
|
||||
hbsd_rest_api._TCP_KEEPCNT)
|
||||
self.configuration.nec_v_host_mode_options = []
|
||||
|
||||
self.configuration.nec_v_zoning_request = False
|
||||
|
||||
self.configuration.san_thin_provision = True
|
||||
self.configuration.san_private_key = ''
|
||||
self.configuration.san_clustername = ''
|
||||
self.configuration.san_ssh_port = '22'
|
||||
self.configuration.san_is_local = False
|
||||
self.configuration.ssh_conn_timeout = '30'
|
||||
self.configuration.ssh_min_pool_conn = '1'
|
||||
self.configuration.ssh_max_pool_conn = '5'
|
||||
|
||||
self.configuration.use_chap_auth = True
|
||||
self.configuration.chap_username = CONFIG_MAP['auth_user']
|
||||
self.configuration.chap_password = CONFIG_MAP['auth_password']
|
||||
|
||||
self.configuration.safe_get = self._fake_safe_get
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.my_ip = CONFIG_MAP['my_ip']
|
||||
|
||||
def _fake_safe_get(self, value):
|
||||
"""Retrieve a configuration value avoiding throwing an exception."""
|
||||
try:
|
||||
val = getattr(self.configuration, value)
|
||||
except AttributeError:
|
||||
val = None
|
||||
return val
|
||||
|
||||
@mock.patch.object(requests.Session, "request")
|
||||
@mock.patch.object(
|
||||
volume_utils, 'brick_get_connector_properties',
|
||||
side_effect=_brick_get_connector_properties)
|
||||
def _setup_driver(
|
||||
self, brick_get_connector_properties=None, request=None):
|
||||
"""Set up the driver environment."""
|
||||
self.driver = nec_v_fc.VStorageFCDriver(
|
||||
configuration=self.configuration, db=db)
|
||||
request.side_effect = [FakeResponse(200, POST_SESSIONS_RESULT),
|
||||
FakeResponse(200, GET_PORTS_RESULT),
|
||||
FakeResponse(200, GET_HOST_WWNS_RESULT)]
|
||||
self.driver.do_setup(None)
|
||||
self.driver.check_for_setup_error()
|
||||
self.driver.local_path(None)
|
||||
# stop the Loopingcall within the do_setup treatment
|
||||
self.driver.common.client.keep_session_loop.stop()
|
||||
|
||||
def tearDown(self):
|
||||
self.client = None
|
||||
super(VStorageRESTFCDriverTest, self).tearDown()
|
||||
|
||||
# API test cases
|
||||
def test_configuration(self):
|
||||
drv = nec_v_fc.VStorageFCDriver(
|
||||
configuration=self.configuration, db=db)
|
||||
self.assertEqual(drv.configuration.hitachi_storage_id,
|
||||
drv.configuration.nec_v_storage_id)
|
||||
self.assertEqual(drv.configuration.hitachi_pool,
|
||||
drv.configuration.nec_v_pool)
|
||||
self.assertEqual(drv.configuration.hitachi_snap_pool,
|
||||
drv.configuration.nec_v_snap_pool)
|
||||
self.assertEqual(drv.configuration.hitachi_ldev_range,
|
||||
drv.configuration.nec_v_ldev_range)
|
||||
self.assertEqual(drv.configuration.hitachi_target_ports,
|
||||
drv.configuration.nec_v_target_ports)
|
||||
self.assertEqual(drv.configuration.hitachi_compute_target_ports,
|
||||
drv.configuration.nec_v_compute_target_ports)
|
||||
self.assertEqual(drv.configuration.hitachi_group_create,
|
||||
drv.configuration.nec_v_group_create)
|
||||
self.assertEqual(drv.configuration.hitachi_group_delete,
|
||||
drv.configuration.nec_v_group_delete)
|
||||
self.assertEqual(drv.configuration.hitachi_copy_speed,
|
||||
drv.configuration.nec_v_copy_speed)
|
||||
self.assertEqual(drv.configuration.hitachi_copy_check_interval,
|
||||
drv.configuration.nec_v_copy_check_interval)
|
||||
self.assertEqual(drv.configuration.hitachi_async_copy_check_interval,
|
||||
drv.configuration.nec_v_async_copy_check_interval)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_disable_io_wait,
|
||||
drv.configuration.nec_v_rest_disable_io_wait)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_tcp_keepalive,
|
||||
drv.configuration.nec_v_rest_tcp_keepalive)
|
||||
self.assertEqual(drv.configuration.hitachi_discard_zero_page,
|
||||
drv.configuration.nec_v_discard_zero_page)
|
||||
self.assertEqual(drv.configuration.hitachi_lun_timeout,
|
||||
drv.configuration.nec_v_lun_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_lun_retry_interval,
|
||||
drv.configuration.nec_v_lun_retry_interval)
|
||||
self.assertEqual(drv.configuration.hitachi_restore_timeout,
|
||||
drv.configuration.nec_v_restore_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_state_transition_timeout,
|
||||
drv.configuration.nec_v_state_transition_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_lock_timeout,
|
||||
drv.configuration.nec_v_lock_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_timeout,
|
||||
drv.configuration.nec_v_rest_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_extend_timeout,
|
||||
drv.configuration.nec_v_extend_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_exec_retry_interval,
|
||||
drv.configuration.nec_v_exec_retry_interval)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_connect_timeout,
|
||||
drv.configuration.nec_v_rest_connect_timeout)
|
||||
self.assertEqual(
|
||||
drv.configuration.hitachi_rest_job_api_response_timeout,
|
||||
drv.configuration.nec_v_rest_job_api_response_timeout)
|
||||
self.assertEqual(
|
||||
drv.configuration.hitachi_rest_get_api_response_timeout,
|
||||
drv.configuration.nec_v_rest_get_api_response_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_server_busy_timeout,
|
||||
drv.configuration.nec_v_rest_server_busy_timeout)
|
||||
self.assertEqual(
|
||||
drv.configuration.hitachi_rest_keep_session_loop_interval,
|
||||
drv.configuration.nec_v_rest_keep_session_loop_interval)
|
||||
self.assertEqual(
|
||||
drv.configuration.hitachi_rest_another_ldev_mapped_retry_timeout,
|
||||
drv.configuration.nec_v_rest_another_ldev_mapped_retry_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_tcp_keepidle,
|
||||
drv.configuration.nec_v_rest_tcp_keepidle)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_tcp_keepintvl,
|
||||
drv.configuration.nec_v_rest_tcp_keepintvl)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_tcp_keepcnt,
|
||||
drv.configuration.nec_v_rest_tcp_keepcnt)
|
||||
self.assertEqual(drv.configuration.hitachi_host_mode_options,
|
||||
drv.configuration.nec_v_host_mode_options)
|
||||
self.assertEqual(drv.configuration.hitachi_zoning_request,
|
||||
drv.configuration.nec_v_zoning_request)
|
||||
|
||||
def test_driverinfo(self):
|
||||
drv = nec_v_fc.VStorageFCDriver(
|
||||
configuration=self.configuration, db=db)
|
||||
self.assertEqual(drv.common.driver_info['version'],
|
||||
"1.0.0")
|
||||
self.assertEqual(drv.common.driver_info['proto'],
|
||||
"FC")
|
||||
self.assertEqual(drv.common.driver_info['hba_id'],
|
||||
"wwpns")
|
||||
self.assertEqual(drv.common.driver_info['hba_id_type'],
|
||||
"World Wide Name")
|
||||
self.assertEqual(drv.common.driver_info['msg_id']['target'].msg_id,
|
||||
308)
|
||||
self.assertEqual(drv.common.driver_info['volume_backend_name'],
|
||||
"NECFC")
|
||||
self.assertEqual(drv.common.driver_info['volume_type'],
|
||||
"fibre_channel")
|
||||
self.assertEqual(drv.common.driver_info['param_prefix'],
|
||||
"nec_v")
|
||||
self.assertEqual(drv.common.driver_info['vendor_name'],
|
||||
"NEC")
|
||||
self.assertEqual(drv.common.driver_info['driver_prefix'],
|
||||
"NEC")
|
||||
self.assertEqual(drv.common.driver_info['driver_file_prefix'],
|
||||
"nec")
|
||||
self.assertEqual(drv.common.driver_info['target_prefix'],
|
||||
"NEC-")
|
||||
self.assertEqual(drv.common.driver_info['hdp_vol_attr'],
|
||||
"DP")
|
||||
self.assertEqual(drv.common.driver_info['hdt_vol_attr'],
|
||||
"DT")
|
||||
self.assertEqual(drv.common.driver_info['nvol_ldev_type'],
|
||||
"DP-VOL")
|
||||
self.assertEqual(drv.common.driver_info['target_iqn_suffix'],
|
||||
".nec-target")
|
||||
self.assertEqual(drv.common.driver_info['pair_attr'],
|
||||
"SS")
|
||||
|
||||
@mock.patch.object(requests.Session, "request")
|
||||
def test_create_volume(self, request):
|
||||
request.return_value = FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)
|
||||
ret = self.driver.create_volume(fake_volume.fake_volume_obj(self.ctxt))
|
||||
self.assertEqual('1', ret['provider_location'])
|
||||
self.assertEqual(2, request.call_count)
|
403
cinder/tests/unit/volume/drivers/nec/v/test_nec_rest_iscsi.py
Normal file
403
cinder/tests/unit/volume/drivers/nec/v/test_nec_rest_iscsi.py
Normal file
@ -0,0 +1,403 @@
|
||||
# Copyright (C) 2021 NEC corporation
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
"""Unit tests for NEC Driver."""
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from oslo_config import cfg
|
||||
import requests
|
||||
|
||||
from cinder import context as cinder_context
|
||||
from cinder import db
|
||||
from cinder.tests.unit import fake_volume
|
||||
from cinder.tests.unit import test
|
||||
from cinder.volume import configuration as conf
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest_api
|
||||
from cinder.volume.drivers.nec.v import nec_v_iscsi
|
||||
from cinder.volume.drivers.nec.v import nec_v_rest
|
||||
from cinder.volume import volume_utils
|
||||
|
||||
# Configuration parameter values
|
||||
CONFIG_MAP = {
|
||||
'serial': '886000123456',
|
||||
'my_ip': '127.0.0.1',
|
||||
'rest_server_ip_addr': '172.16.18.108',
|
||||
'rest_server_ip_port': '23451',
|
||||
'port_id': 'CL1-A',
|
||||
'host_grp_name': 'NEC-127.0.0.1',
|
||||
'host_mode': 'LINUX/IRIX',
|
||||
'host_iscsi_name': 'iqn.nec-test-host',
|
||||
'target_iscsi_name': 'iqn.nec-test-target',
|
||||
'user_id': 'user',
|
||||
'user_pass': 'password',
|
||||
'ipv4Address': '111.22.333.44',
|
||||
'tcpPort': '5555',
|
||||
'auth_user': 'auth_user',
|
||||
'auth_password': 'auth_password',
|
||||
}
|
||||
|
||||
DEFAULT_CONNECTOR = {
|
||||
'host': 'host',
|
||||
'ip': CONFIG_MAP['my_ip'],
|
||||
'initiator': CONFIG_MAP['host_iscsi_name'],
|
||||
'multipath': False,
|
||||
}
|
||||
|
||||
# Dummy response for REST API
|
||||
POST_SESSIONS_RESULT = {
|
||||
"token": "b74777a3-f9f0-4ea8-bd8f-09847fac48d3",
|
||||
"sessionId": 0,
|
||||
}
|
||||
|
||||
GET_PORTS_RESULT = {
|
||||
"data": [
|
||||
{
|
||||
"portId": CONFIG_MAP['port_id'],
|
||||
"portType": "ISCSI",
|
||||
"portAttributes": [
|
||||
"TAR",
|
||||
"MCU",
|
||||
"RCU",
|
||||
"ELUN"
|
||||
],
|
||||
"portSpeed": "AUT",
|
||||
"loopId": "00",
|
||||
"fabricMode": False,
|
||||
"lunSecuritySetting": True,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
GET_PORT_RESULT = {
|
||||
"ipv4Address": CONFIG_MAP['ipv4Address'],
|
||||
"tcpPort": CONFIG_MAP['tcpPort'],
|
||||
}
|
||||
|
||||
GET_HOST_ISCSIS_RESULT = {
|
||||
"data": [
|
||||
{
|
||||
"hostGroupNumber": 0,
|
||||
"iscsiName": CONFIG_MAP['host_iscsi_name'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
GET_HOST_GROUP_RESULT = {
|
||||
"hostGroupName": CONFIG_MAP['host_grp_name'],
|
||||
"iscsiName": CONFIG_MAP['target_iscsi_name'],
|
||||
}
|
||||
|
||||
GET_HOST_GROUPS_RESULT = {
|
||||
"data": [
|
||||
{
|
||||
"hostGroupNumber": 0,
|
||||
"portId": CONFIG_MAP['port_id'],
|
||||
"hostGroupName": "NEC-test",
|
||||
"iscsiName": CONFIG_MAP['target_iscsi_name'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
COMPLETED_SUCCEEDED_RESULT = {
|
||||
"status": "Completed",
|
||||
"state": "Succeeded",
|
||||
"affectedResources": ('a/b/c/1',),
|
||||
}
|
||||
|
||||
|
||||
def _brick_get_connector_properties(multipath=False, enforce_multipath=False):
|
||||
"""Return a predefined connector object."""
|
||||
return DEFAULT_CONNECTOR
|
||||
|
||||
|
||||
class FakeResponse():
|
||||
|
||||
def __init__(self, status_code, data=None, headers=None):
|
||||
self.status_code = status_code
|
||||
self.data = data
|
||||
self.text = data
|
||||
self.content = data
|
||||
self.headers = {'Content-Type': 'json'} if headers is None else headers
|
||||
|
||||
def json(self):
|
||||
return self.data
|
||||
|
||||
|
||||
class VStorageRESTISCSIDriverTest(test.TestCase):
|
||||
"""Unit test class for NEC REST interface iSCSI module."""
|
||||
|
||||
test_existing_ref = {'source-id': '1'}
|
||||
test_existing_ref_name = {
|
||||
'source-name': '15960cc7-38c9-4c5b-b4f1-365be5eeed45'}
|
||||
|
||||
def setUp(self):
|
||||
"""Set up the test environment."""
|
||||
def _set_required(opts, required):
|
||||
for opt in opts:
|
||||
opt.required = required
|
||||
|
||||
# Initialize Cinder and avoid checking driver options.
|
||||
rest_required_opts = [
|
||||
opt for opt in nec_v_rest.REST_VOLUME_OPTS if opt.required]
|
||||
common_required_opts = [
|
||||
opt for opt in nec_v_rest.COMMON_VOLUME_OPTS if opt.required]
|
||||
_set_required(rest_required_opts, False)
|
||||
_set_required(common_required_opts, False)
|
||||
super(VStorageRESTISCSIDriverTest, self).setUp()
|
||||
_set_required(rest_required_opts, True)
|
||||
_set_required(common_required_opts, True)
|
||||
|
||||
self.configuration = mock.Mock(conf.Configuration)
|
||||
self.ctxt = cinder_context.get_admin_context()
|
||||
self._setup_config()
|
||||
self._setup_driver()
|
||||
|
||||
def _setup_config(self):
|
||||
"""Set configuration parameter values."""
|
||||
self.configuration.config_group = "REST"
|
||||
|
||||
self.configuration.volume_backend_name = "RESTISCSI"
|
||||
self.configuration.volume_driver = (
|
||||
"cinder.volume.drivers.nec.v.nec_v_iscsi.VStorageISCSIDriver")
|
||||
self.configuration.reserved_percentage = "0"
|
||||
self.configuration.use_multipath_for_image_xfer = False
|
||||
self.configuration.enforce_multipath_for_image_xfer = False
|
||||
self.configuration.max_over_subscription_ratio = 500.0
|
||||
self.configuration.driver_ssl_cert_verify = False
|
||||
|
||||
self.configuration.nec_v_storage_id = CONFIG_MAP['serial']
|
||||
self.configuration.nec_v_pool = "30"
|
||||
self.configuration.nec_v_snap_pool = None
|
||||
self.configuration.nec_v_ldev_range = "0-1"
|
||||
self.configuration.nec_v_target_ports = [CONFIG_MAP['port_id']]
|
||||
self.configuration.nec_v_compute_target_ports = [
|
||||
CONFIG_MAP['port_id']]
|
||||
self.configuration.nec_v_group_create = True
|
||||
self.configuration.nec_v_group_delete = True
|
||||
self.configuration.nec_v_copy_speed = 3
|
||||
self.configuration.nec_v_copy_check_interval = 3
|
||||
self.configuration.nec_v_async_copy_check_interval = 10
|
||||
|
||||
self.configuration.san_login = CONFIG_MAP['user_id']
|
||||
self.configuration.san_password = CONFIG_MAP['user_pass']
|
||||
self.configuration.san_ip = CONFIG_MAP[
|
||||
'rest_server_ip_addr']
|
||||
self.configuration.san_api_port = CONFIG_MAP[
|
||||
'rest_server_ip_port']
|
||||
self.configuration.nec_v_rest_disable_io_wait = True
|
||||
self.configuration.nec_v_rest_tcp_keepalive = True
|
||||
self.configuration.nec_v_discard_zero_page = True
|
||||
self.configuration.nec_v_rest_number = "0"
|
||||
self.configuration.nec_v_lun_timeout = hbsd_rest._LUN_TIMEOUT
|
||||
self.configuration.nec_v_lun_retry_interval = (
|
||||
hbsd_rest._LUN_RETRY_INTERVAL)
|
||||
self.configuration.nec_v_restore_timeout = hbsd_rest._RESTORE_TIMEOUT
|
||||
self.configuration.nec_v_state_transition_timeout = (
|
||||
hbsd_rest._STATE_TRANSITION_TIMEOUT)
|
||||
self.configuration.nec_v_lock_timeout = hbsd_rest_api._LOCK_TIMEOUT
|
||||
self.configuration.nec_v_rest_timeout = hbsd_rest_api._REST_TIMEOUT
|
||||
self.configuration.nec_v_extend_timeout = (
|
||||
hbsd_rest_api._EXTEND_TIMEOUT)
|
||||
self.configuration.nec_v_exec_retry_interval = (
|
||||
hbsd_rest_api._EXEC_RETRY_INTERVAL)
|
||||
self.configuration.nec_v_rest_connect_timeout = (
|
||||
hbsd_rest_api._DEFAULT_CONNECT_TIMEOUT)
|
||||
self.configuration.nec_v_rest_job_api_response_timeout = (
|
||||
hbsd_rest_api._JOB_API_RESPONSE_TIMEOUT)
|
||||
self.configuration.nec_v_rest_get_api_response_timeout = (
|
||||
hbsd_rest_api._GET_API_RESPONSE_TIMEOUT)
|
||||
self.configuration.nec_v_rest_server_busy_timeout = (
|
||||
hbsd_rest_api._REST_SERVER_BUSY_TIMEOUT)
|
||||
self.configuration.nec_v_rest_keep_session_loop_interval = (
|
||||
hbsd_rest_api._KEEP_SESSION_LOOP_INTERVAL)
|
||||
self.configuration.nec_v_rest_another_ldev_mapped_retry_timeout = (
|
||||
hbsd_rest_api._ANOTHER_LDEV_MAPPED_RETRY_TIMEOUT)
|
||||
self.configuration.nec_v_rest_tcp_keepidle = (
|
||||
hbsd_rest_api._TCP_KEEPIDLE)
|
||||
self.configuration.nec_v_rest_tcp_keepintvl = (
|
||||
hbsd_rest_api._TCP_KEEPINTVL)
|
||||
self.configuration.nec_v_rest_tcp_keepcnt = (
|
||||
hbsd_rest_api._TCP_KEEPCNT)
|
||||
self.configuration.nec_v_host_mode_options = []
|
||||
|
||||
self.configuration.use_chap_auth = True
|
||||
self.configuration.chap_username = CONFIG_MAP['auth_user']
|
||||
self.configuration.chap_password = CONFIG_MAP['auth_password']
|
||||
|
||||
self.configuration.san_thin_provision = True
|
||||
self.configuration.san_private_key = ''
|
||||
self.configuration.san_clustername = ''
|
||||
self.configuration.san_ssh_port = '22'
|
||||
self.configuration.san_is_local = False
|
||||
self.configuration.ssh_conn_timeout = '30'
|
||||
self.configuration.ssh_min_pool_conn = '1'
|
||||
self.configuration.ssh_max_pool_conn = '5'
|
||||
|
||||
self.configuration.safe_get = self._fake_safe_get
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.my_ip = CONFIG_MAP['my_ip']
|
||||
|
||||
def _fake_safe_get(self, value):
|
||||
"""Retrieve a configuration value avoiding throwing an exception."""
|
||||
try:
|
||||
val = getattr(self.configuration, value)
|
||||
except AttributeError:
|
||||
val = None
|
||||
return val
|
||||
|
||||
@mock.patch.object(requests.Session, "request")
|
||||
@mock.patch.object(
|
||||
volume_utils, 'brick_get_connector_properties',
|
||||
side_effect=_brick_get_connector_properties)
|
||||
def _setup_driver(
|
||||
self, brick_get_connector_properties=None, request=None):
|
||||
"""Set up the driver environment."""
|
||||
self.driver = nec_v_iscsi.VStorageISCSIDriver(
|
||||
configuration=self.configuration, db=db)
|
||||
request.side_effect = [FakeResponse(200, POST_SESSIONS_RESULT),
|
||||
FakeResponse(200, GET_PORTS_RESULT),
|
||||
FakeResponse(200, GET_PORT_RESULT),
|
||||
FakeResponse(200, GET_HOST_ISCSIS_RESULT),
|
||||
FakeResponse(200, GET_HOST_GROUP_RESULT)]
|
||||
self.driver.do_setup(None)
|
||||
self.driver.check_for_setup_error()
|
||||
self.driver.local_path(None)
|
||||
# stop the Loopingcall within the do_setup treatment
|
||||
self.driver.common.client.keep_session_loop.stop()
|
||||
|
||||
def tearDown(self):
|
||||
self.client = None
|
||||
super(VStorageRESTISCSIDriverTest, self).tearDown()
|
||||
|
||||
# API test cases
|
||||
def test_configuration(self):
|
||||
drv = nec_v_iscsi.VStorageISCSIDriver(
|
||||
configuration=self.configuration, db=db)
|
||||
self.assertEqual(drv.configuration.hitachi_storage_id,
|
||||
drv.configuration.nec_v_storage_id)
|
||||
self.assertEqual(drv.configuration.hitachi_pool,
|
||||
drv.configuration.nec_v_pool)
|
||||
self.assertEqual(drv.configuration.hitachi_snap_pool,
|
||||
drv.configuration.nec_v_snap_pool)
|
||||
self.assertEqual(drv.configuration.hitachi_ldev_range,
|
||||
drv.configuration.nec_v_ldev_range)
|
||||
self.assertEqual(drv.configuration.hitachi_target_ports,
|
||||
drv.configuration.nec_v_target_ports)
|
||||
self.assertEqual(drv.configuration.hitachi_compute_target_ports,
|
||||
drv.configuration.nec_v_compute_target_ports)
|
||||
self.assertEqual(drv.configuration.hitachi_group_create,
|
||||
drv.configuration.nec_v_group_create)
|
||||
self.assertEqual(drv.configuration.hitachi_group_delete,
|
||||
drv.configuration.nec_v_group_delete)
|
||||
self.assertEqual(drv.configuration.hitachi_copy_speed,
|
||||
drv.configuration.nec_v_copy_speed)
|
||||
self.assertEqual(drv.configuration.hitachi_copy_check_interval,
|
||||
drv.configuration.nec_v_copy_check_interval)
|
||||
self.assertEqual(drv.configuration.hitachi_async_copy_check_interval,
|
||||
drv.configuration.nec_v_async_copy_check_interval)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_disable_io_wait,
|
||||
drv.configuration.nec_v_rest_disable_io_wait)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_tcp_keepalive,
|
||||
drv.configuration.nec_v_rest_tcp_keepalive)
|
||||
self.assertEqual(drv.configuration.hitachi_discard_zero_page,
|
||||
drv.configuration.nec_v_discard_zero_page)
|
||||
self.assertEqual(drv.configuration.hitachi_lun_timeout,
|
||||
drv.configuration.nec_v_lun_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_lun_retry_interval,
|
||||
drv.configuration.nec_v_lun_retry_interval)
|
||||
self.assertEqual(drv.configuration.hitachi_restore_timeout,
|
||||
drv.configuration.nec_v_restore_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_state_transition_timeout,
|
||||
drv.configuration.nec_v_state_transition_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_lock_timeout,
|
||||
drv.configuration.nec_v_lock_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_timeout,
|
||||
drv.configuration.nec_v_rest_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_extend_timeout,
|
||||
drv.configuration.nec_v_extend_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_exec_retry_interval,
|
||||
drv.configuration.nec_v_exec_retry_interval)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_connect_timeout,
|
||||
drv.configuration.nec_v_rest_connect_timeout)
|
||||
self.assertEqual(
|
||||
drv.configuration.hitachi_rest_job_api_response_timeout,
|
||||
drv.configuration.nec_v_rest_job_api_response_timeout)
|
||||
self.assertEqual(
|
||||
drv.configuration.hitachi_rest_get_api_response_timeout,
|
||||
drv.configuration.nec_v_rest_get_api_response_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_server_busy_timeout,
|
||||
drv.configuration.nec_v_rest_server_busy_timeout)
|
||||
self.assertEqual(
|
||||
drv.configuration.hitachi_rest_keep_session_loop_interval,
|
||||
drv.configuration.nec_v_rest_keep_session_loop_interval)
|
||||
self.assertEqual(
|
||||
drv.configuration.hitachi_rest_another_ldev_mapped_retry_timeout,
|
||||
drv.configuration.nec_v_rest_another_ldev_mapped_retry_timeout)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_tcp_keepidle,
|
||||
drv.configuration.nec_v_rest_tcp_keepidle)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_tcp_keepintvl,
|
||||
drv.configuration.nec_v_rest_tcp_keepintvl)
|
||||
self.assertEqual(drv.configuration.hitachi_rest_tcp_keepcnt,
|
||||
drv.configuration.nec_v_rest_tcp_keepcnt)
|
||||
self.assertEqual(drv.configuration.hitachi_host_mode_options,
|
||||
drv.configuration.nec_v_host_mode_options)
|
||||
|
||||
def test_driverinfo(self):
|
||||
drv = nec_v_iscsi.VStorageISCSIDriver(
|
||||
configuration=self.configuration, db=db)
|
||||
self.assertEqual(drv.common.driver_info['version'],
|
||||
"1.0.0")
|
||||
self.assertEqual(drv.common.driver_info['proto'],
|
||||
"iSCSI")
|
||||
self.assertEqual(drv.common.driver_info['hba_id'],
|
||||
"initiator")
|
||||
self.assertEqual(drv.common.driver_info['hba_id_type'],
|
||||
"iSCSI initiator IQN")
|
||||
self.assertEqual(drv.common.driver_info['msg_id']['target'].msg_id,
|
||||
309)
|
||||
self.assertEqual(drv.common.driver_info['volume_backend_name'],
|
||||
"NECiSCSI")
|
||||
self.assertEqual(drv.common.driver_info['volume_type'],
|
||||
"iscsi")
|
||||
self.assertEqual(drv.common.driver_info['param_prefix'],
|
||||
"nec_v")
|
||||
self.assertEqual(drv.common.driver_info['vendor_name'],
|
||||
"NEC")
|
||||
self.assertEqual(drv.common.driver_info['driver_prefix'],
|
||||
"NEC")
|
||||
self.assertEqual(drv.common.driver_info['driver_file_prefix'],
|
||||
"nec")
|
||||
self.assertEqual(drv.common.driver_info['target_prefix'],
|
||||
"NEC-")
|
||||
self.assertEqual(drv.common.driver_info['hdp_vol_attr'],
|
||||
"DP")
|
||||
self.assertEqual(drv.common.driver_info['hdt_vol_attr'],
|
||||
"DT")
|
||||
self.assertEqual(drv.common.driver_info['nvol_ldev_type'],
|
||||
"DP-VOL")
|
||||
self.assertEqual(drv.common.driver_info['target_iqn_suffix'],
|
||||
".nec-target")
|
||||
self.assertEqual(drv.common.driver_info['pair_attr'],
|
||||
"SS")
|
||||
|
||||
@mock.patch.object(requests.Session, "request")
|
||||
def test_create_volume(self, request):
|
||||
request.return_value = FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)
|
||||
ret = self.driver.create_volume(fake_volume.fake_volume_obj(self.ctxt))
|
||||
self.assertEqual('1', ret['provider_location'])
|
||||
self.assertEqual(2, request.call_count)
|
0
cinder/volume/drivers/nec/v/__init__.py
Normal file
0
cinder/volume/drivers/nec/v/__init__.py
Normal file
72
cinder/volume/drivers/nec/v/nec_v_fc.py
Normal file
72
cinder/volume/drivers/nec/v/nec_v_fc.py
Normal file
@ -0,0 +1,72 @@
|
||||
# Copyright (C) 2021 NEC corporation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
"""Fibre channel module for NEC Driver."""
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.hitachi import hbsd_common
|
||||
from cinder.volume.drivers.hitachi import hbsd_fc
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest
|
||||
from cinder.volume.drivers.hitachi import hbsd_utils
|
||||
from cinder.volume.drivers.nec.v import nec_v_rest as rest
|
||||
from cinder.volume.drivers.nec.v import nec_v_utils as utils
|
||||
|
||||
MSG = hbsd_utils.HBSDMsg
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class VStorageFCDriver(hbsd_fc.HBSDFCDriver):
|
||||
"""Fibre channel class for NEC Driver.
|
||||
|
||||
Version history:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
1.0.0 - Initial driver.
|
||||
|
||||
"""
|
||||
|
||||
VERSION = utils.VERSION
|
||||
|
||||
# ThirdPartySystems wiki page
|
||||
CI_WIKI_NAME = utils.CI_WIKI_NAME
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize instance variables."""
|
||||
super(VStorageFCDriver, self).__init__(*args, **kwargs)
|
||||
self.configuration.append_config_values(rest.COMMON_VOLUME_OPTS)
|
||||
self.configuration.append_config_values(rest.FC_VOLUME_OPTS)
|
||||
|
||||
def _init_common(self, conf, db):
|
||||
utils.DRIVER_INFO['proto'] = 'FC'
|
||||
utils.DRIVER_INFO['hba_id'] = 'wwpns'
|
||||
utils.DRIVER_INFO['hba_id_type'] = 'World Wide Name'
|
||||
utils.DRIVER_INFO['msg_id'] = {
|
||||
'target': MSG.CREATE_HOST_GROUP_FAILED}
|
||||
utils.DRIVER_INFO['volume_backend_name'] = '%(prefix)sFC' % {
|
||||
'prefix': utils.DRIVER_PREFIX}
|
||||
utils.DRIVER_INFO['volume_type'] = 'fibre_channel'
|
||||
|
||||
return rest.VStorageRESTFC(conf, utils.DRIVER_INFO, db)
|
||||
|
||||
@staticmethod
|
||||
def get_driver_options():
|
||||
additional_opts = driver.BaseVD._get_oslo_driver_opts(
|
||||
*(hbsd_common._INHERITED_VOLUME_OPTS +
|
||||
hbsd_rest._REQUIRED_REST_OPTS +
|
||||
['driver_ssl_cert_verify', 'driver_ssl_cert_path',
|
||||
'san_api_port']))
|
||||
return (rest.COMMON_VOLUME_OPTS + rest.REST_VOLUME_OPTS +
|
||||
rest.FC_VOLUME_OPTS + additional_opts)
|
71
cinder/volume/drivers/nec/v/nec_v_iscsi.py
Normal file
71
cinder/volume/drivers/nec/v/nec_v_iscsi.py
Normal file
@ -0,0 +1,71 @@
|
||||
# Copyright (C) 2021 NEC corporation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
"""iSCSI channel module for NEC Driver."""
|
||||
|
||||
from cinder import interface
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.hitachi import hbsd_common
|
||||
from cinder.volume.drivers.hitachi import hbsd_iscsi
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest
|
||||
from cinder.volume.drivers.hitachi import hbsd_utils
|
||||
from cinder.volume.drivers.nec.v import nec_v_rest as rest
|
||||
from cinder.volume.drivers.nec.v import nec_v_utils as utils
|
||||
|
||||
MSG = hbsd_utils.HBSDMsg
|
||||
|
||||
|
||||
@interface.volumedriver
|
||||
class VStorageISCSIDriver(hbsd_iscsi.HBSDISCSIDriver):
|
||||
"""iSCSI class for NEC Driver.
|
||||
|
||||
Version history:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
1.0.0 - Initial driver.
|
||||
|
||||
"""
|
||||
|
||||
VERSION = utils.VERSION
|
||||
|
||||
# ThirdPartySystems wiki page
|
||||
CI_WIKI_NAME = utils.CI_WIKI_NAME
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize instance variables."""
|
||||
super(VStorageISCSIDriver, self).__init__(*args, **kwargs)
|
||||
self.configuration.append_config_values(rest.COMMON_VOLUME_OPTS)
|
||||
|
||||
def _init_common(self, conf, db):
|
||||
utils.DRIVER_INFO['proto'] = 'iSCSI'
|
||||
utils.DRIVER_INFO['hba_id'] = 'initiator'
|
||||
utils.DRIVER_INFO['hba_id_type'] = 'iSCSI initiator IQN'
|
||||
utils.DRIVER_INFO['msg_id'] = {
|
||||
'target': MSG.CREATE_ISCSI_TARGET_FAILED}
|
||||
utils.DRIVER_INFO['volume_backend_name'] = '%(prefix)siSCSI' % {
|
||||
'prefix': utils.DRIVER_PREFIX}
|
||||
utils.DRIVER_INFO['volume_type'] = 'iscsi'
|
||||
|
||||
return rest.VStorageRESTISCSI(conf, utils.DRIVER_INFO, db)
|
||||
|
||||
@staticmethod
|
||||
def get_driver_options():
|
||||
additional_opts = driver.BaseVD._get_oslo_driver_opts(
|
||||
*(hbsd_common._INHERITED_VOLUME_OPTS +
|
||||
hbsd_rest._REQUIRED_REST_OPTS +
|
||||
['driver_ssl_cert_verify', 'driver_ssl_cert_path',
|
||||
'san_api_port']))
|
||||
return (rest.COMMON_VOLUME_OPTS + rest.REST_VOLUME_OPTS +
|
||||
additional_opts)
|
279
cinder/volume/drivers/nec/v/nec_v_rest.py
Normal file
279
cinder/volume/drivers/nec/v/nec_v_rest.py
Normal file
@ -0,0 +1,279 @@
|
||||
# Copyright (C) 2021 NEC corporation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
"""REST interface for NEC Driver."""
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from cinder.volume import configuration
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest_api
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest_fc
|
||||
from cinder.volume.drivers.hitachi import hbsd_rest_iscsi
|
||||
|
||||
COMMON_VOLUME_OPTS = [
|
||||
cfg.StrOpt(
|
||||
'nec_v_storage_id',
|
||||
default=None,
|
||||
help='Product number of the storage system.'),
|
||||
cfg.StrOpt(
|
||||
'nec_v_pool',
|
||||
default=None,
|
||||
help='Pool number or pool name of the DP pool.'),
|
||||
cfg.StrOpt(
|
||||
'nec_v_snap_pool',
|
||||
default=None,
|
||||
help='Pool number or pool name of the snapshot pool.'),
|
||||
cfg.StrOpt(
|
||||
'nec_v_ldev_range',
|
||||
default=None,
|
||||
help='Range of the LDEV numbers in the format of \'xxxx-yyyy\' that '
|
||||
'can be used by the driver. Values can be in decimal format '
|
||||
'(e.g. 1000) or in colon-separated hexadecimal format '
|
||||
'(e.g. 00:03:E8).'),
|
||||
cfg.ListOpt(
|
||||
'nec_v_target_ports',
|
||||
default=[],
|
||||
help='IDs of the storage ports used to attach volumes to the '
|
||||
'controller node. To specify multiple ports, connect them by '
|
||||
'commas (e.g. CL1-A,CL2-A).'),
|
||||
cfg.ListOpt(
|
||||
'nec_v_compute_target_ports',
|
||||
default=[],
|
||||
help='IDs of the storage ports used to attach volumes to compute '
|
||||
'nodes. To specify multiple ports, connect them by commas '
|
||||
'(e.g. CL1-A,CL2-A).'),
|
||||
cfg.BoolOpt(
|
||||
'nec_v_group_create',
|
||||
default=False,
|
||||
help='If True, the driver will create host groups or iSCSI targets on '
|
||||
'storage ports as needed.'),
|
||||
cfg.BoolOpt(
|
||||
'nec_v_group_delete',
|
||||
default=False,
|
||||
help='If True, the driver will delete host groups or iSCSI targets on '
|
||||
'storage ports as needed.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_copy_speed',
|
||||
default=3,
|
||||
min=1, max=15,
|
||||
help='Copy speed of storage system. 1 or 2 indicates '
|
||||
'low speed, 3 indicates middle speed, and a value between 4 and '
|
||||
'15 indicates high speed.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_copy_check_interval',
|
||||
default=3,
|
||||
min=1, max=600,
|
||||
help='Interval in seconds to check copying status during a volume '
|
||||
'copy.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_async_copy_check_interval',
|
||||
default=10,
|
||||
min=1, max=600,
|
||||
help='Interval in seconds to check asynchronous copying status during '
|
||||
'a copy pair deletion or data restoration.'),
|
||||
]
|
||||
|
||||
REST_VOLUME_OPTS = [
|
||||
cfg.BoolOpt(
|
||||
'nec_v_rest_disable_io_wait',
|
||||
default=True,
|
||||
help='It may take some time to detach volume after I/O. '
|
||||
'This option will allow detaching volume to complete '
|
||||
'immediately.'),
|
||||
cfg.BoolOpt(
|
||||
'nec_v_rest_tcp_keepalive',
|
||||
default=True,
|
||||
help='Enables or disables use of REST API tcp keepalive'),
|
||||
cfg.BoolOpt(
|
||||
'nec_v_discard_zero_page',
|
||||
default=True,
|
||||
help='Enable or disable zero page reclamation in a DP-VOL.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_lun_timeout',
|
||||
default=hbsd_rest._LUN_TIMEOUT,
|
||||
help='Maximum wait time in seconds for adding a LUN to complete.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_lun_retry_interval',
|
||||
default=hbsd_rest._LUN_RETRY_INTERVAL,
|
||||
help='Retry interval in seconds for REST API adding a LUN.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_restore_timeout',
|
||||
default=hbsd_rest._RESTORE_TIMEOUT,
|
||||
help='Maximum wait time in seconds for the restore operation to '
|
||||
'complete.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_state_transition_timeout',
|
||||
default=hbsd_rest._STATE_TRANSITION_TIMEOUT,
|
||||
help='Maximum wait time in seconds for a volume transition to '
|
||||
'complete.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_lock_timeout',
|
||||
default=hbsd_rest_api._LOCK_TIMEOUT,
|
||||
help='Maximum wait time in seconds for storage to be unlocked.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_timeout',
|
||||
default=hbsd_rest_api._REST_TIMEOUT,
|
||||
help='Maximum wait time in seconds for REST API execution to '
|
||||
'complete.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_extend_timeout',
|
||||
default=hbsd_rest_api._EXTEND_TIMEOUT,
|
||||
help='Maximum wait time in seconds for a volume extention to '
|
||||
'complete.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_exec_retry_interval',
|
||||
default=hbsd_rest_api._EXEC_RETRY_INTERVAL,
|
||||
help='Retry interval in seconds for REST API execution.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_connect_timeout',
|
||||
default=hbsd_rest_api._DEFAULT_CONNECT_TIMEOUT,
|
||||
help='Maximum wait time in seconds for REST API connection to '
|
||||
'complete.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_job_api_response_timeout',
|
||||
default=hbsd_rest_api._JOB_API_RESPONSE_TIMEOUT,
|
||||
help='Maximum wait time in seconds for a response from REST API.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_get_api_response_timeout',
|
||||
default=hbsd_rest_api._GET_API_RESPONSE_TIMEOUT,
|
||||
help='Maximum wait time in seconds for a response against GET method '
|
||||
'of REST API.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_server_busy_timeout',
|
||||
default=hbsd_rest_api._REST_SERVER_BUSY_TIMEOUT,
|
||||
help='Maximum wait time in seconds when REST API returns busy.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_keep_session_loop_interval',
|
||||
default=hbsd_rest_api._KEEP_SESSION_LOOP_INTERVAL,
|
||||
help='Loop interval in seconds for keeping REST API session.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_another_ldev_mapped_retry_timeout',
|
||||
default=hbsd_rest_api._ANOTHER_LDEV_MAPPED_RETRY_TIMEOUT,
|
||||
help='Retry time in seconds when new LUN allocation request fails.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_tcp_keepidle',
|
||||
default=hbsd_rest_api._TCP_KEEPIDLE,
|
||||
help='Wait time in seconds for sending a first TCP keepalive packet.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_tcp_keepintvl',
|
||||
default=hbsd_rest_api._TCP_KEEPINTVL,
|
||||
help='Interval of transmissions in seconds for TCP keepalive packet.'),
|
||||
cfg.IntOpt(
|
||||
'nec_v_rest_tcp_keepcnt',
|
||||
default=hbsd_rest_api._TCP_KEEPCNT,
|
||||
help='Maximum number of transmissions for TCP keepalive packet.'),
|
||||
cfg.ListOpt(
|
||||
'nec_v_host_mode_options',
|
||||
default=[],
|
||||
help='Host mode option for host group or iSCSI target'),
|
||||
]
|
||||
|
||||
FC_VOLUME_OPTS = [
|
||||
cfg.BoolOpt(
|
||||
'nec_v_zoning_request',
|
||||
default=False,
|
||||
help='If True, the driver will configure FC zoning between the server '
|
||||
'and the storage system provided that FC zoning manager is '
|
||||
'enabled.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(COMMON_VOLUME_OPTS, group=configuration.SHARED_CONF_GROUP)
|
||||
CONF.register_opts(REST_VOLUME_OPTS, group=configuration.SHARED_CONF_GROUP)
|
||||
CONF.register_opts(FC_VOLUME_OPTS, group=configuration.SHARED_CONF_GROUP)
|
||||
|
||||
|
||||
def update_conf(conf):
|
||||
# COMMON_VOLUME_OPTS
|
||||
conf.hitachi_storage_id = conf.nec_v_storage_id
|
||||
conf.hitachi_pool = conf.nec_v_pool
|
||||
conf.hitachi_snap_pool = conf.nec_v_snap_pool
|
||||
conf.hitachi_ldev_range = conf.nec_v_ldev_range
|
||||
conf.hitachi_target_ports = conf.nec_v_target_ports
|
||||
conf.hitachi_compute_target_ports = (
|
||||
conf.nec_v_compute_target_ports)
|
||||
conf.hitachi_group_create = conf.nec_v_group_create
|
||||
conf.hitachi_group_delete = conf.nec_v_group_delete
|
||||
conf.hitachi_copy_speed = conf.nec_v_copy_speed
|
||||
conf.hitachi_copy_check_interval = (
|
||||
conf.nec_v_copy_check_interval)
|
||||
conf.hitachi_async_copy_check_interval = (
|
||||
conf.nec_v_async_copy_check_interval)
|
||||
|
||||
# REST_VOLUME_OPTS
|
||||
conf.hitachi_rest_disable_io_wait = (
|
||||
conf.nec_v_rest_disable_io_wait)
|
||||
conf.hitachi_rest_tcp_keepalive = (
|
||||
conf.nec_v_rest_tcp_keepalive)
|
||||
conf.hitachi_discard_zero_page = (
|
||||
conf.nec_v_discard_zero_page)
|
||||
conf.hitachi_lun_timeout = conf.nec_v_lun_timeout
|
||||
conf.hitachi_lun_retry_interval = (
|
||||
conf.nec_v_lun_retry_interval)
|
||||
conf.hitachi_restore_timeout = conf.nec_v_restore_timeout
|
||||
conf.hitachi_state_transition_timeout = (
|
||||
conf.nec_v_state_transition_timeout)
|
||||
conf.hitachi_lock_timeout = conf.nec_v_lock_timeout
|
||||
conf.hitachi_rest_timeout = conf.nec_v_rest_timeout
|
||||
conf.hitachi_extend_timeout = conf.nec_v_extend_timeout
|
||||
conf.hitachi_exec_retry_interval = (
|
||||
conf.nec_v_exec_retry_interval)
|
||||
conf.hitachi_rest_connect_timeout = (
|
||||
conf.nec_v_rest_connect_timeout)
|
||||
conf.hitachi_rest_job_api_response_timeout = (
|
||||
conf.nec_v_rest_job_api_response_timeout)
|
||||
conf.hitachi_rest_get_api_response_timeout = (
|
||||
conf.nec_v_rest_get_api_response_timeout)
|
||||
conf.hitachi_rest_server_busy_timeout = (
|
||||
conf.nec_v_rest_server_busy_timeout)
|
||||
conf.hitachi_rest_keep_session_loop_interval = (
|
||||
conf.nec_v_rest_keep_session_loop_interval)
|
||||
conf.hitachi_rest_another_ldev_mapped_retry_timeout = (
|
||||
conf.nec_v_rest_another_ldev_mapped_retry_timeout)
|
||||
conf.hitachi_rest_tcp_keepidle = (
|
||||
conf.nec_v_rest_tcp_keepidle)
|
||||
conf.hitachi_rest_tcp_keepintvl = (
|
||||
conf.nec_v_rest_tcp_keepintvl)
|
||||
conf.hitachi_rest_tcp_keepcnt = (
|
||||
conf.nec_v_rest_tcp_keepcnt)
|
||||
conf.hitachi_host_mode_options = (
|
||||
conf.nec_v_host_mode_options)
|
||||
|
||||
return conf
|
||||
|
||||
|
||||
class VStorageRESTFC(hbsd_rest_fc.HBSDRESTFC):
|
||||
"""REST interface fibre channel class."""
|
||||
|
||||
def __init__(self, conf, storage_protocol, db):
|
||||
"""Initialize instance variables."""
|
||||
conf.append_config_values(COMMON_VOLUME_OPTS)
|
||||
conf.append_config_values(REST_VOLUME_OPTS)
|
||||
conf.append_config_values(FC_VOLUME_OPTS)
|
||||
super(VStorageRESTFC, self).__init__(conf, storage_protocol, db)
|
||||
self.conf = update_conf(self.conf)
|
||||
# FC_VOLUME_OPTS
|
||||
self.conf.hitachi_zoning_request = self.conf.nec_v_zoning_request
|
||||
|
||||
|
||||
class VStorageRESTISCSI(hbsd_rest_iscsi.HBSDRESTISCSI):
|
||||
"""REST interface iSCSI channel class."""
|
||||
|
||||
def __init__(self, conf, storage_protocol, db):
|
||||
"""Initialize instance variables."""
|
||||
conf.append_config_values(COMMON_VOLUME_OPTS)
|
||||
conf.append_config_values(REST_VOLUME_OPTS)
|
||||
super(VStorageRESTISCSI, self).__init__(conf, storage_protocol, db)
|
||||
self.conf = update_conf(self.conf)
|
50
cinder/volume/drivers/nec/v/nec_v_utils.py
Normal file
50
cinder/volume/drivers/nec/v/nec_v_utils.py
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2021 NEC corporation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
"""Utility module for NEC Driver."""
|
||||
|
||||
VERSION = '1.0.0'
|
||||
CI_WIKI_NAME = 'NEC_V_Cinder_CI'
|
||||
PARAM_PREFIX = 'nec_v'
|
||||
VENDOR_NAME = 'NEC'
|
||||
DRIVER_PREFIX = 'NEC'
|
||||
DRIVER_FILE_PREFIX = 'nec'
|
||||
TARGET_PREFIX = 'NEC-'
|
||||
HDP_VOL_ATTR = 'DP'
|
||||
HDT_VOL_ATTR = 'DT'
|
||||
NVOL_LDEV_TYPE = 'DP-VOL'
|
||||
TARGET_IQN_SUFFIX = '.nec-target'
|
||||
PAIR_ATTR = 'SS'
|
||||
|
||||
DRIVER_INFO = {
|
||||
'version': VERSION,
|
||||
'proto': '',
|
||||
'hba_id': '',
|
||||
'hba_id_type': '',
|
||||
'msg_id': {
|
||||
'target': '',
|
||||
},
|
||||
'volume_backend_name': '',
|
||||
'volume_type': '',
|
||||
'param_prefix': PARAM_PREFIX,
|
||||
'vendor_name': VENDOR_NAME,
|
||||
'driver_prefix': DRIVER_PREFIX,
|
||||
'driver_file_prefix': DRIVER_FILE_PREFIX,
|
||||
'target_prefix': TARGET_PREFIX,
|
||||
'hdp_vol_attr': HDP_VOL_ATTR,
|
||||
'hdt_vol_attr': HDT_VOL_ATTR,
|
||||
'nvol_ldev_type': NVOL_LDEV_TYPE,
|
||||
'target_iqn_suffix': TARGET_IQN_SUFFIX,
|
||||
'pair_attr': PAIR_ATTR,
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
===========================
|
||||
NEC Storage V series driver
|
||||
===========================
|
||||
|
||||
NEC Storage V series driver provides Fibre Channel and iSCSI support for
|
||||
NEC V series storages.
|
||||
|
||||
System requirements
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Supported models:
|
||||
|
||||
+-----------------+------------------------+
|
||||
| Storage model | Firmware version |
|
||||
+=================+========================+
|
||||
| V100, | 93-04-21 or later |
|
||||
| V300 | |
|
||||
+-----------------+------------------------+
|
||||
|
||||
Required storage licenses:
|
||||
|
||||
* iStorage Local Replication
|
||||
Local Replication Software
|
||||
|
||||
|
||||
Supported operations
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Create, delete, attach, and detach volumes.
|
||||
* Create, list, and delete volume snapshots.
|
||||
* Create a volume from a snapshot.
|
||||
* Create, list, update, and delete consistency groups.
|
||||
* Create, list, and delete consistency group snapshots.
|
||||
* Copy a volume to an image.
|
||||
* Copy an image to a volume.
|
||||
* Clone a volume.
|
||||
* Extend a volume.
|
||||
* Migrate a volume.
|
||||
* Get volume statistics.
|
||||
* Efficient non-disruptive volume backup.
|
||||
* Manage and unmanage a volume.
|
||||
* Attach a volume to multiple instances at once (multi-attach).
|
||||
* Revert a volume to a snapshot.
|
||||
|
||||
.. note::
|
||||
|
||||
A volume with snapshots cannot be extended in this driver.
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
Set up NEC V series storage
|
||||
---------------------------
|
||||
|
||||
You need to specify settings as described below for storage systems. For
|
||||
details about each setting, see the user's guide of the storage systems.
|
||||
|
||||
Common resources:
|
||||
|
||||
- ``All resources``
|
||||
All storage resources, such as DP pools and host groups, can not have a
|
||||
name including blank space in order for the driver to use them.
|
||||
|
||||
- ``User accounts``
|
||||
Create a storage device account belonging to the Administrator User Group.
|
||||
|
||||
- ``DP Pool``
|
||||
Create a DP pool that is used by the driver.
|
||||
|
||||
- ``Resource group``
|
||||
If using a new resource group for exclusive use by an OpenStack system,
|
||||
create a new resource group, and assign the necessary resources, such as
|
||||
LDEVs, port, and host group (iSCSI target) to the created resource.
|
||||
|
||||
- ``Ports``
|
||||
Enable Port Security for the ports used by the driver.
|
||||
|
||||
If you use iSCSI:
|
||||
|
||||
- ``Ports``
|
||||
Assign an IP address and a TCP port number to the port.
|
||||
|
||||
Set up NEC V series storage volume driver
|
||||
-----------------------------------------
|
||||
|
||||
Set the volume driver to NEC V series storage driver by setting the
|
||||
volume_driver option in the cinder.conf file as follows:
|
||||
|
||||
If you use Fibre Channel:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[Storage1]
|
||||
volume_driver = cinder.volume.drivers.nec.v.nec_v_fc.VStorageFCDriver
|
||||
volume_backend_name = Storage1
|
||||
san_ip = 1.2.3.4
|
||||
san_api_port = 23451
|
||||
san_login = userid
|
||||
san_password = password
|
||||
nec_v_storage_id = 123456789012
|
||||
nec_v_pool = pool0
|
||||
|
||||
If you use iSCSI:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[Storage1]
|
||||
volume_driver = cinder.volume.drivers.nec.v.nec_v_iscsi.VStorageISCSIDriver
|
||||
volume_backend_name = Storage1
|
||||
san_ip = 1.2.3.4
|
||||
san_api_port = 23451
|
||||
san_login = userid
|
||||
san_password = password
|
||||
nec_v_storage_id = 123456789012
|
||||
nec_v_pool = pool0
|
||||
|
||||
This table shows configuration options for NEC V series storage driver.
|
||||
|
||||
.. config-table::
|
||||
:config-target: NEC V series storage driver
|
||||
|
||||
cinder.volume.drivers.nec.v.nec_v_rest
|
||||
|
||||
Required options
|
||||
----------------
|
||||
|
||||
- ``san_ip``
|
||||
IP address of SAN controller
|
||||
|
||||
- ``san_login``
|
||||
Username for SAN controller
|
||||
|
||||
- ``san_password``
|
||||
Password for SAN controller
|
||||
|
||||
- ``nec_v_storage_id``
|
||||
Product number of the storage system.
|
||||
|
||||
- ``nec_v_pool``
|
||||
Pool number or pool name of the DP pool.
|
||||
|
@ -135,6 +135,9 @@ title=MacroSAN Storage Driver (iSCSI, FC)
|
||||
[driver.nec]
|
||||
title=NEC Storage M Series Driver (iSCSI, FC)
|
||||
|
||||
[driver.nec_v]
|
||||
title=NEC Storage V Series Driver (iSCSI, FC)
|
||||
|
||||
[driver.netapp_ontap]
|
||||
title=NetApp Data ONTAP Driver (iSCSI, NFS, FC)
|
||||
|
||||
@ -257,6 +260,7 @@ driver.linbit_linstor=complete
|
||||
driver.lvm=complete
|
||||
driver.macrosan=complete
|
||||
driver.nec=complete
|
||||
driver.nec_v=complete
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=complete
|
||||
@ -327,6 +331,7 @@ driver.linbit_linstor=complete
|
||||
driver.lvm=complete
|
||||
driver.macrosan=complete
|
||||
driver.nec=complete
|
||||
driver.nec_v=complete
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=complete
|
||||
@ -400,6 +405,7 @@ driver.linbit_linstor=missing
|
||||
driver.lvm=missing
|
||||
driver.macrosan=complete
|
||||
driver.nec=complete
|
||||
driver.nec_v=missing
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
@ -472,6 +478,7 @@ driver.linbit_linstor=missing
|
||||
driver.lvm=missing
|
||||
driver.macrosan=complete
|
||||
driver.nec=missing
|
||||
driver.nec_v=missing
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
@ -545,6 +552,7 @@ driver.linbit_linstor=missing
|
||||
driver.lvm=missing
|
||||
driver.macrosan=missing
|
||||
driver.nec=missing
|
||||
driver.nec_v=complete
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
@ -617,6 +625,7 @@ driver.linbit_linstor=missing
|
||||
driver.lvm=complete
|
||||
driver.macrosan=complete
|
||||
driver.nec=complete
|
||||
driver.nec_v=complete
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
@ -690,6 +699,7 @@ driver.linbit_linstor=missing
|
||||
driver.lvm=missing
|
||||
driver.macrosan=complete
|
||||
driver.nec=complete
|
||||
driver.nec_v=missing
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
@ -763,6 +773,7 @@ driver.linbit_linstor=missing
|
||||
driver.lvm=complete
|
||||
driver.macrosan=missing
|
||||
driver.nec=complete
|
||||
driver.nec_v=complete
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
@ -833,6 +844,7 @@ driver.linbit_linstor=missing
|
||||
driver.lvm=complete
|
||||
driver.macrosan=missing
|
||||
driver.nec=complete
|
||||
driver.nec_v=complete
|
||||
driver.netapp_ontap=complete
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
@ -907,6 +919,7 @@ driver.linbit_linstor=missing
|
||||
driver.lvm=missing
|
||||
driver.macrosan=complete
|
||||
driver.nec=missing
|
||||
driver.nec_v=missing
|
||||
driver.netapp_ontap=missing
|
||||
driver.netapp_solidfire=complete
|
||||
driver.nexenta=missing
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added backend FC and iSCSI drivers for NEC V series Storage.
|
Loading…
x
Reference in New Issue
Block a user