import base64
import urllib2
-from oslo.config import cfg
+import mox as mox_lib
from cinder import test
+from cinder.volume import configuration as conf
from cinder.volume.drivers import nexenta
from cinder.volume.drivers.nexenta import jsonrpc
from cinder.volume.drivers.nexenta import volume
-CONF = cfg.CONF
-
-
class TestNexentaDriver(test.TestCase):
TEST_VOLUME_NAME = 'volume1'
TEST_VOLUME_NAME2 = 'volume2'
def setUp(self):
super(TestNexentaDriver, self).setUp()
- self.flags(
- nexenta_host='1.1.1.1',
- nexenta_volume='cinder',
- nexenta_target_prefix='iqn:',
- nexenta_target_group_prefix='cinder/',
- nexenta_blocksize='8K',
- nexenta_sparse=True,
- )
+ self.configuration = mox_lib.MockObject(conf.Configuration)
+ self.configuration.san_ip = '1.1.1.1'
+ self.configuration.san_login = 'admin'
+ self.configuration.san_password = 'nexenta'
+ self.configuration.nexenta_volume = 'cinder'
+ self.configuration.nexenta_rest_port = 2000
+ self.configuration.nexenta_rest_protocol = 'http'
+ self.configuration.iscsi_port = 3260
+ self.configuration.nexenta_target_prefix = 'iqn:'
+ self.configuration.nexenta_target_group_prefix = 'cinder/'
+ self.configuration.nexenta_blocksize = '8K'
+ self.configuration.nexenta_sparse = True
self.nms_mock = self.mox.CreateMockAnything()
for mod in ['volume', 'zvol', 'iscsitarget', 'appliance',
'stmf', 'scsidisk', 'snapshot']:
setattr(self.nms_mock, mod, self.mox.CreateMockAnything())
self.stubs.Set(jsonrpc, 'NexentaJSONProxy',
lambda *_, **__: self.nms_mock)
- self.drv = volume.NexentaDriver()
+ self.drv = volume.NexentaDriver(configuration=self.configuration)
self.drv.do_setup({})
def test_setup_error(self):
self.assertEquals(
retval,
{'provider_location':
- '%s:%s,1 %s%s 0' % (CONF.nexenta_host,
- CONF.nexenta_iscsi_target_portal_port,
- CONF.nexenta_target_prefix,
+ '%s:%s,1 %s%s 0' % (self.configuration.san_ip,
+ self.configuration.iscsi_port,
+ self.configuration.nexenta_target_prefix,
self.TEST_VOLUME_NAME)})
def __get_test(i):
'available': '5368709120G',
'health': 'ONLINE'}
self.nms_mock.volume.get_child_props(
- CONF.nexenta_volume,
+ self.configuration.nexenta_volume,
'health|size|used|available').AndReturn(stats)
self.mox.ReplayAll()
stats = self.drv.get_volume_stats(True)
self.assertEquals(stats['storage_protocol'], 'iSCSI')
- self.assertEquals(stats['volume_backend_name'], 'NexentaDriver')
self.assertEquals(stats['total_capacity_gb'], 5368709120.0)
self.assertEquals(stats['free_capacity_gb'], 5368709120.0)
self.assertEquals(stats['reserved_percentage'], 0)
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2013 Nexenta Systems, Inc.
+# 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.
+"""
+:mod:`nexenta.options` -- Contains configuration options for Nexenta drivers.
+=============================================================================
+
+.. automodule:: nexenta.options
+.. moduleauthor:: Victor Rodionov <victor.rodionov@nexenta.com>
+.. moduleauthor:: Yuriy Taraday <yorik.sar@gmail.com>
+"""
+
+from oslo.config import cfg
+
+NEXENTA_CONNECTION_OPTIONS = [
+ cfg.IntOpt('nexenta_rest_port',
+ default=2000,
+ help='HTTP port to connect to Nexenta REST API server'),
+ cfg.StrOpt('nexenta_rest_protocol',
+ default='auto',
+ help='Use http or https for REST connection (default auto)'),
+]
+
+NEXENTA_ISCSI_OPTIONS = [
+ cfg.StrOpt('nexenta_volume',
+ default='cinder',
+ help='pool on SA that will hold all volumes'),
+ cfg.StrOpt('nexenta_target_prefix',
+ default='iqn.1986-03.com.sun:02:cinder-',
+ help='IQN prefix for iSCSI targets'),
+ cfg.StrOpt('nexenta_target_group_prefix',
+ default='cinder/',
+ help='prefix for iSCSI target groups on SA'),
+]
+
+NEXENTA_VOLUME_OPTIONS = [
+ cfg.StrOpt('nexenta_blocksize',
+ default='',
+ help='block size for volumes (blank=default,8KB)'),
+ cfg.BoolOpt('nexenta_sparse',
+ default=False,
+ help='flag to create sparse volumes'),
+]
from cinder.volume import driver
from cinder.volume.drivers import nexenta
from cinder.volume.drivers.nexenta import jsonrpc
+from cinder.volume.drivers.nexenta import options
VERSION = '1.0'
LOG = logging.getLogger(__name__)
-NEXENTA_OPTS = [
- cfg.StrOpt('nexenta_host',
- default='',
- help='IP address of Nexenta SA'),
- cfg.IntOpt('nexenta_rest_port',
- default=2000,
- help='HTTP port to connect to Nexenta REST API server'),
- cfg.StrOpt('nexenta_rest_protocol',
- default='auto',
- help='Use http or https for REST connection (default auto)'),
- cfg.StrOpt('nexenta_user',
- default='admin',
- help='User name to connect to Nexenta SA'),
- cfg.StrOpt('nexenta_password',
- default='nexenta',
- help='Password to connect to Nexenta SA',
- secret=True),
- cfg.IntOpt('nexenta_iscsi_target_portal_port',
- default=3260,
- help='Nexenta target portal port'),
- cfg.StrOpt('nexenta_volume',
- default='cinder',
- help='pool on SA that will hold all volumes'),
- cfg.StrOpt('nexenta_target_prefix',
- default='iqn.1986-03.com.sun:02:cinder-',
- help='IQN prefix for iSCSI targets'),
- cfg.StrOpt('nexenta_target_group_prefix',
- default='cinder/',
- help='prefix for iSCSI target groups on SA'),
- cfg.StrOpt('nexenta_blocksize',
- default='',
- help='block size for volumes (blank=default,8KB)'),
- cfg.BoolOpt('nexenta_sparse',
- default=False,
- help='flag to create sparse volumes'),
-]
-
CONF = cfg.CONF
-CONF.register_opts(NEXENTA_OPTS)
+CONF.register_opts(options.NEXENTA_CONNECTION_OPTIONS)
+CONF.register_opts(options.NEXENTA_ISCSI_OPTIONS)
+CONF.register_opts(options.NEXENTA_VOLUME_OPTIONS)
class NexentaDriver(driver.ISCSIDriver): # pylint: disable=R0921
super(NexentaDriver, self).__init__(*args, **kwargs)
self.nms = None
if self.configuration:
- self.configuration.append_config_values(NEXENTA_OPTS)
+ self.configuration.append_config_values(
+ options.NEXENTA_CONNECTION_OPTIONS)
+ self.configuration.append_config_values(
+ options.NEXENTA_ISCSI_OPTIONS)
+ self.configuration.append_config_values(
+ options.NEXENTA_VOLUME_OPTIONS)
def do_setup(self, context):
- protocol = CONF.nexenta_rest_protocol
+ protocol = self.configuration.nexenta_rest_protocol
auto = protocol == 'auto'
if auto:
protocol = 'http'
self.nms = jsonrpc.NexentaJSONProxy(
- '%s://%s:%s/rest/nms/' % (protocol, CONF.nexenta_host,
- CONF.nexenta_rest_port),
- CONF.nexenta_user, CONF.nexenta_password, auto=auto)
+ '%s://%s:%s/rest/nms/' % (protocol, self.configuration.san_ip,
+ self.configuration.nexenta_rest_port),
+ self.configuration.san_login, self.configuration.san_password,
+ auto=auto)
def check_for_setup_error(self):
"""Verify that the volume for our zvols exists.
:raise: :py:exc:`LookupError`
"""
- if not self.nms.volume.object_exists(CONF.nexenta_volume):
+ if not self.nms.volume.object_exists(
+ self.configuration.nexenta_volume):
raise LookupError(_("Volume %s does not exist in Nexenta SA"),
- CONF.nexenta_volume)
+ self.configuration.nexenta_volume)
def _get_zvol_name(self, volume_name):
"""Return zvol name that corresponds given volume name."""
- return '%s/%s' % (CONF.nexenta_volume, volume_name)
+ return '%s/%s' % (self.configuration.nexenta_volume, volume_name)
def _get_target_name(self, volume_name):
"""Return iSCSI target name to access volume."""
- return '%s%s' % (CONF.nexenta_target_prefix, volume_name)
+ return '%s%s' % (self.configuration.nexenta_target_prefix, volume_name)
def _get_target_group_name(self, volume_name):
"""Return Nexenta iSCSI target group name for volume."""
- return '%s%s' % (CONF.nexenta_target_group_prefix, volume_name)
+ return '%s%s' % (self.configuration.nexenta_target_group_prefix,
+ volume_name)
def _get_clone_snap_name(self, volume):
"""Return name for snapshot that will be used to clone the volume."""
self.nms.zvol.create(
self._get_zvol_name(volume['name']),
'%sG' % (volume['size'],),
- CONF.nexenta_blocksize, CONF.nexenta_sparse)
+ self.configuration.nexenta_blocksize,
+ self.configuration.nexenta_sparse)
def extend_volume(self, volume, new_size):
"""Extend an existing volume.
raise
LOG.info(_('Ignored LUN mapping entry addition error "%s"'
' while ensuring export'), exc)
- return '%s:%s,1 %s 0' % (CONF.nexenta_host,
- CONF.nexenta_iscsi_target_portal_port,
- target_name)
+ return '%s:%s,1 %s 0' % (self.configuration.san_ip,
+ self.configuration.iscsi_port, target_name)
def create_export(self, _ctx, volume):
"""Create new export for zvol.
data["driver_version"] = VERSION
data["storage_protocol"] = 'iSCSI'
- stats = self.nms.volume.get_child_props(CONF.nexenta_volume,
- 'health|size|used|available')
+ stats = self.nms.volume.get_child_props(
+ self.configuration.nexenta_volume, 'health|size|used|available')
total_unit = stats['size'][-1]
total_amount = float(stats['size'][:-1])
free_unit = stats['available'][-1]