]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fix 3PAR drivers to work in multi-backend mode.
authorWalter A. Boring IV <walter.boring@hp.com>
Thu, 28 Feb 2013 18:06:02 +0000 (10:06 -0800)
committerWalter A. Boring IV <walter.boring@hp.com>
Tue, 5 Mar 2013 17:08:16 +0000 (09:08 -0800)
The 3PAR drivers weren't updated when the multi backend
patch landed on G3 day.  This patch implements the new config
mechanism to accessing FLAGS, so that it works when an admin
has multiple drivers active.

This fixes
bug 1131346

Change-Id: Icc5475d15bfd0fa14aae12ab8a8370a894e46857

cinder/tests/test_hp3par.py
cinder/volume/drivers/san/hp/hp_3par_common.py
cinder/volume/drivers/san/hp/hp_3par_fc.py
cinder/volume/drivers/san/hp/hp_3par_iscsi.py

index 1e51da04981c2b3f7b11e295579c233f545c4923..39b40655324ec92cb96bfa28f835b153801f395f 100644 (file)
 """
 Unit tests for OpenStack Cinder volume drivers
 """
+import mox
 import shutil
 import tempfile
 
 from hp3parclient import exceptions as hpexceptions
 
 from cinder import exception
-import cinder.flags
 from cinder.openstack.common import log as logging
 from cinder import test
+from cinder.volume import configuration as conf
 from cinder.volume.drivers.san.hp import hp_3par_fc as hpfcdriver
 from cinder.volume.drivers.san.hp import hp_3par_iscsi as hpdriver
 
-FLAGS = cinder.flags.FLAGS
-
 LOG = logging.getLogger(__name__)
 
 HP3PAR_DOMAIN = 'OpenStack',
@@ -294,7 +293,7 @@ class HP3PARBaseDriver():
                  'host': 'fakehost'}
 
     def fake_create_client(self):
-        return FakeHP3ParClient(FLAGS.hp3par_api_url)
+        return FakeHP3ParClient(self.driver.configuration.hp3par_api_url)
 
     def fake_get_3par_host(self, hostname):
         if hostname not in self._hosts:
@@ -377,35 +376,40 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
     def setUp(self):
         self.tempdir = tempfile.mkdtemp()
         super(TestHP3PARFCDriver, self).setUp()
-        self.flags(
-            hp3par_username='testUser',
-            hp3par_password='testPassword',
-            hp3par_api_url='https://1.1.1.1/api/v1',
-            hp3par_domain=HP3PAR_DOMAIN,
-            hp3par_cpg=HP3PAR_CPG,
-            hp3par_cpg_snap=HP3PAR_CPG_SNAP,
-            iscsi_ip_address='1.1.1.2',
-            iscsi_port='1234',
-            san_ip='2.2.2.2',
-            san_login='test',
-            san_password='test'
-        )
+
+        configuration = mox.MockObject(conf.Configuration)
+        configuration.hp3par_debug = False
+        configuration.hp3par_username = 'testUser'
+        configuration.hp3par_password = 'testPassword'
+        configuration.hp3par_api_url = 'https://1.1.1.1/api/v1'
+        configuration.hp3par_domain = HP3PAR_DOMAIN
+        configuration.hp3par_cpg = HP3PAR_CPG
+        configuration.hp3par_cpg_snap = HP3PAR_CPG_SNAP
+        configuration.iscsi_ip_address = '1.1.1.2'
+        configuration.iscsi_port = '1234'
+        configuration.san_ip = '2.2.2.2'
+        configuration.san_login = 'test'
+        configuration.san_password = 'test'
+        configuration.hp3par_snapshot_expiration = ""
+        configuration.hp3par_snapshot_retention = ""
         self.stubs.Set(hpfcdriver.HP3PARFCDriver, "_create_client",
                        self.fake_create_client)
         self.stubs.Set(hpfcdriver.HP3PARFCDriver,
                        "_create_3par_fibrechan_host",
                        self.fake_create_3par_fibrechan_host)
 
-        self.stubs.Set(hpfcdriver.HP3PARCommon, "_get_3par_host",
+        self.stubs.Set(hpfcdriver.hpcommon.HP3PARCommon, "_get_3par_host",
                        self.fake_get_3par_host)
-        self.stubs.Set(hpfcdriver.HP3PARCommon, "_delete_3par_host",
+        self.stubs.Set(hpfcdriver.hpcommon.HP3PARCommon, "_delete_3par_host",
                        self.fake_delete_3par_host)
-        self.stubs.Set(hpdriver.HP3PARCommon, "_create_3par_vlun",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_create_3par_vlun",
                        self.fake_create_3par_vlun)
-        self.stubs.Set(hpdriver.HP3PARCommon, "get_ports",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "get_ports",
                        self.fake_get_ports)
 
-        self.driver = hpfcdriver.HP3PARFCDriver()
+        self.configuration = configuration
+
+        self.driver = hpfcdriver.HP3PARFCDriver(configuration=configuration)
         self.driver.do_setup(None)
 
     def tearDown(self):
@@ -467,9 +471,9 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
 
     def test_create_cloned_volume(self):
         self.flags(lock_path=self.tempdir)
-        self.stubs.Set(hpdriver.HP3PARCommon, "_get_volume_state",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_get_volume_state",
                        self.fake_get_volume_state)
-        self.stubs.Set(hpdriver.HP3PARCommon, "_copy_volume",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_copy_volume",
                        self.fake_copy_volume)
         self.state_tries = 0
         volume = {'name': HP3PARBaseDriver.VOLUME_NAME,
@@ -502,19 +506,23 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
     def setUp(self):
         self.tempdir = tempfile.mkdtemp()
         super(TestHP3PARISCSIDriver, self).setUp()
-        self.flags(
-            hp3par_username='testUser',
-            hp3par_password='testPassword',
-            hp3par_api_url='https://1.1.1.1/api/v1',
-            hp3par_domain=HP3PAR_DOMAIN,
-            hp3par_cpg=HP3PAR_CPG,
-            hp3par_cpg_snap=HP3PAR_CPG_SNAP,
-            iscsi_ip_address='1.1.1.2',
-            iscsi_port='1234',
-            san_ip='2.2.2.2',
-            san_login='test',
-            san_password='test'
-        )
+
+        configuration = mox.MockObject(conf.Configuration)
+        configuration.hp3par_debug = False
+        configuration.hp3par_username = 'testUser'
+        configuration.hp3par_password = 'testPassword'
+        configuration.hp3par_api_url = 'https://1.1.1.1/api/v1'
+        configuration.hp3par_domain = HP3PAR_DOMAIN
+        configuration.hp3par_cpg = HP3PAR_CPG
+        configuration.hp3par_cpg_snap = HP3PAR_CPG_SNAP
+        configuration.iscsi_ip_address = '1.1.1.2'
+        configuration.iscsi_port = '1234'
+        configuration.san_ip = '2.2.2.2'
+        configuration.san_login = 'test'
+        configuration.san_password = 'test'
+        configuration.hp3par_snapshot_expiration = ""
+        configuration.hp3par_snapshot_retention = ""
+
         self.stubs.Set(hpdriver.HP3PARISCSIDriver, "_create_client",
                        self.fake_create_client)
         self.stubs.Set(hpdriver.HP3PARISCSIDriver,
@@ -526,14 +534,14 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
                        "_iscsi_discover_target_iqn",
                        self.fake_iscsi_discover_target_iqn)
 
-        self.stubs.Set(hpdriver.HP3PARCommon, "_get_3par_host",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_get_3par_host",
                        self.fake_get_3par_host)
-        self.stubs.Set(hpdriver.HP3PARCommon, "_delete_3par_host",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_delete_3par_host",
                        self.fake_delete_3par_host)
-        self.stubs.Set(hpdriver.HP3PARCommon, "_create_3par_vlun",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_create_3par_vlun",
                        self.fake_create_3par_vlun)
 
-        self.driver = hpdriver.HP3PARISCSIDriver()
+        self.driver = hpdriver.HP3PARISCSIDriver(configuration=configuration)
         self.driver.do_setup(None)
 
         target_iqn = 'iqn.2000-05.com.3pardata:21810002ac00383d'
@@ -579,9 +587,6 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
         self.assertFalse(metadata['3ParName'] is None)
         self.assertEqual(metadata['CPG'], HP3PAR_CPG)
         self.assertEqual(metadata['snapCPG'], HP3PAR_CPG_SNAP)
-        expected_location = "%s:%s" % (FLAGS.iscsi_ip_address,
-                                       FLAGS.iscsi_port)
-        self.assertEqual(model_update['provider_location'], expected_location)
 
     def test_initialize_connection(self):
         self.flags(lock_path=self.tempdir)
@@ -605,9 +610,9 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
 
     def test_create_cloned_volume(self):
         self.flags(lock_path=self.tempdir)
-        self.stubs.Set(hpdriver.HP3PARCommon, "_get_volume_state",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_get_volume_state",
                        self.fake_get_volume_state)
-        self.stubs.Set(hpdriver.HP3PARCommon, "_copy_volume",
+        self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_copy_volume",
                        self.fake_copy_volume)
         self.state_tries = 0
         volume = {'name': HP3PARBaseDriver.VOLUME_NAME,
index 4d62805717c88b387e447edd6e3f67da59e1ec19..871d2cad9dc05ccfff892e25eb8754540ab8730f 100644 (file)
@@ -21,6 +21,9 @@
 Volume driver common utilities for HP 3PAR Storage array
 The 3PAR drivers requires 3.1.2 firmware on the 3PAR array.
 
+You will need to install the python hp3parclient.
+sudo pip install hp3parclient
+
 The drivers uses both the REST service and the SSH
 command line to correctly operate.  Since the
 ssh credentials and the REST credentials can be different
@@ -47,7 +50,6 @@ from oslo.config import cfg
 
 from cinder import context
 from cinder import exception
-from cinder import flags
 from cinder.openstack.common import lockutils
 from cinder.openstack.common import log as logging
 from cinder import utils
@@ -90,9 +92,6 @@ hp3par_opts = [
                 help="Enable HTTP debugging to 3PAR")
 ]
 
-FLAGS = flags.FLAGS
-FLAGS.register_opts(hp3par_opts)
-
 
 class HP3PARCommon():
 
@@ -116,12 +115,13 @@ class HP3PARCommon():
                             '10 - ONTAP-legacy',
                             '11 - VMWare']
 
-    def __init__(self):
+    def __init__(self, config):
         self.sshpool = None
+        self.config = config
 
-    def check_flags(self, FLAGS, required_flags):
+    def check_flags(self, options, required_flags):
         for flag in required_flags:
-            if not getattr(FLAGS, flag, None):
+            if not getattr(options, flag, None):
                 raise exception.InvalidInput(reason=_('%s is not set') % flag)
 
     def _get_3par_vol_name(self, volume_id):
@@ -239,14 +239,17 @@ exit
 
     def _run_ssh(self, command, check_exit=True, attempts=1):
         if not self.sshpool:
-            self.sshpool = utils.SSHPool(FLAGS.san_ip,
-                                         FLAGS.san_ssh_port,
-                                         FLAGS.ssh_conn_timeout,
-                                         FLAGS.san_login,
-                                         password=FLAGS.san_password,
-                                         privatekey=FLAGS.san_private_key,
-                                         min_size=FLAGS.ssh_min_pool_conn,
-                                         max_size=FLAGS.ssh_max_pool_conn)
+            self.sshpool = utils.SSHPool(self.config.san_ip,
+                                         self.config.san_ssh_port,
+                                         self.config.ssh_conn_timeout,
+                                         self.config.san_login,
+                                         password=self.config.san_password,
+                                         privatekey=
+                                         self.config.san_private_key,
+                                         min_size=
+                                         self.config.ssh_min_pool_conn,
+                                         max_size=
+                                         self.config.ssh_max_pool_conn)
         try:
             total_attempts = attempts
             with self.sshpool.item() as ssh:
@@ -415,7 +418,7 @@ exit
 
         if refresh:
             try:
-                cpg = client.getCPG(FLAGS.hp3par_cpg)
+                cpg = client.getCPG(self.config.hp3par_cpg)
                 if 'limitMiB' not in cpg['SDGrowth']:
                     total_capacity = 'infinite'
                     free_capacity = 'infinite'
@@ -427,7 +430,8 @@ exit
                 self.stats['total_capacity_gb'] = total_capacity
                 self.stats['free_capacity_gb'] = free_capacity
             except hpexceptions.HTTPNotFound:
-                err = _("CPG (%s) doesn't exist on array") % FLAGS.hp3par_cpg
+                err = (_("CPG (%s) doesn't exist on array")
+                       % self.config.hp3par_cpg)
                 LOG.error(err)
                 raise exception.InvalidInput(reason=err)
 
@@ -484,8 +488,7 @@ exit
         return persona_id[0]
 
     @lockutils.synchronized('3par', 'cinder-', True)
-    def create_volume(self, volume, client, FLAGS):
-        """ Create a new volume. """
+    def create_volume(self, volume, client):
         LOG.debug("CREATE VOLUME (%s : %s %s)" %
                   (volume['display_name'], volume['name'],
                    self._get_3par_vol_name(volume['id'])))
@@ -505,7 +508,7 @@ exit
                 volume_type = self._get_volume_type(type_id)
 
             cpg = self._get_volume_type_value(volume_type, 'cpg',
-                                              FLAGS.hp3par_cpg)
+                                              self.config.hp3par_cpg)
 
             # if provisioning is not set use thin
             default_prov = self.valid_prov_values[0]
@@ -525,10 +528,10 @@ exit
                 ttpv = False
 
             # default to hp3par_cpg if hp3par_cpg_snap is not set.
-            if FLAGS.hp3par_cpg_snap == "":
-                snap_default = FLAGS.hp3par_cpg
+            if self.config.hp3par_cpg_snap == "":
+                snap_default = self.config.hp3par_cpg
             else:
-                snap_default = FLAGS.hp3par_cpg_snap
+                snap_default = self.config.hp3par_cpg_snap
             snap_cpg = self._get_volume_type_value(volume_type,
                                                    'snap_cpg',
                                                    snap_default)
@@ -563,7 +566,7 @@ exit
             LOG.error(str(ex))
             raise exception.CinderException(ex.get_description())
 
-        metadata = {'3ParName': volume_name, 'CPG': FLAGS.hp3par_cpg,
+        metadata = {'3ParName': volume_name, 'CPG': self.config.hp3par_cpg,
                     'snapCPG': extras['snapCPG']}
         return metadata
 
@@ -583,14 +586,14 @@ exit
         return status
 
     @lockutils.synchronized('3parclone', 'cinder-', True)
-    def create_cloned_volume(self, volume, src_vref, client, FLAGS):
+    def create_cloned_volume(self, volume, src_vref, client):
 
         try:
             orig_name = self._get_3par_vol_name(volume['source_volid'])
             vol_name = self._get_3par_vol_name(volume['id'])
             # We need to create a new volume first.  Otherwise you
             # can't delete the original
-            new_vol = self.create_volume(volume, client, FLAGS)
+            new_vol = self.create_volume(volume, client)
 
             # make the 3PAR copy the contents.
             # can't delete the original until the copy is done.
@@ -627,7 +630,6 @@ exit
 
     @lockutils.synchronized('3par', 'cinder-', True)
     def delete_volume(self, volume, client):
-        """ Delete a volume. """
         try:
             volume_name = self._get_3par_vol_name(volume['id'])
             client.deleteVolume(volume_name)
@@ -654,8 +656,8 @@ exit
                    pprint.pformat(snapshot['display_name'])))
 
         if snapshot['volume_size'] != volume['size']:
-            err = "You cannot change size of the volume.  It must \
-be the same as it's Snapshot."
+            err = "You cannot change size of the volume.  It must "
+            "be the same as the snapshot."
             LOG.error(err)
             raise exception.InvalidInput(reason=err)
 
@@ -683,8 +685,7 @@ be the same as it's Snapshot."
             raise exception.NotFound()
 
     @lockutils.synchronized('3par', 'cinder-', True)
-    def create_snapshot(self, snapshot, client, FLAGS):
-        """ Creates a snapshot. """
+    def create_snapshot(self, snapshot, client):
         LOG.debug("Create Snapshot\n%s" % pprint.pformat(snapshot))
 
         try:
@@ -708,11 +709,13 @@ be the same as it's Snapshot."
 
             optional = {'comment': json.dumps(extra),
                         'readOnly': True}
-            if FLAGS.hp3par_snapshot_expiration:
-                optional['expirationHours'] = FLAGS.hp3par_snapshot_expiration
+            if self.config.hp3par_snapshot_expiration:
+                optional['expirationHours'] = (
+                    self.config.hp3par_snapshot_expiration)
 
-            if FLAGS.hp3par_snapshot_retention:
-                optional['retentionHours'] = FLAGS.hp3par_snapshot_retention
+            if self.config.hp3par_snapshot_retention:
+                optional['retentionHours'] = (
+                    self.config.hp3par_snapshot_retention)
 
             client.createSnapshot(snap_name, vol_name, optional)
         except hpexceptions.HTTPForbidden:
@@ -722,7 +725,6 @@ be the same as it's Snapshot."
 
     @lockutils.synchronized('3par', 'cinder-', True)
     def delete_snapshot(self, snapshot, client):
-        """ Driver entry point for deleting a snapshot. """
         LOG.debug("Delete Snapshot\n%s" % pprint.pformat(snapshot))
 
         try:
index 9e5b97cc97642cd3f142d98e8f3d4d4f07347520..d48612fb7a35005df0656467d01b86762655c1ce 100644 (file)
 #
 """
 Volume driver for HP 3PAR Storage array. This driver requires 3.1.2 firmware
-on the 3PAR array. Set the following in the cinder.conf file to enable the
+on the 3PAR array.
+
+You will need to install the python hp3parclient.
+sudo pip install hp3parclient
+
+Set the following in the cinder.conf file to enable the
 3PAR Fibre Channel Driver along with the required flags:
 
 volume_driver=cinder.volume.drivers.san.hp.hp_3par_fc.HP3PARFCDriver
@@ -30,17 +35,15 @@ from hp3parclient import exceptions as hpexceptions
 from oslo.config import cfg
 
 from cinder import exception
-from cinder import flags
 from cinder.openstack.common import lockutils
 from cinder.openstack.common import log as logging
 import cinder.volume.driver
-from cinder.volume.drivers.san.hp.hp_3par_common import HP3PARCommon
+from cinder.volume.drivers.san.hp import hp_3par_common as hpcommon
+from cinder.volume.drivers.san import san
 
 VERSION = 1.0
 LOG = logging.getLogger(__name__)
 
-FLAGS = flags.FLAGS
-
 
 class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
     """OpenStack Fibre Channel driver to enable 3PAR storage array.
@@ -54,19 +57,21 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
         super(HP3PARFCDriver, self).__init__(*args, **kwargs)
         self.client = None
         self.common = None
+        self.configuration.append_config_values(hpcommon.hp3par_opts)
+        self.configuration.append_config_values(san.san_opts)
 
     def _init_common(self):
-        return HP3PARCommon()
+        return hpcommon.HP3PARCommon(self.configuration)
 
     def _check_flags(self):
         """Sanity check to ensure we have required options set."""
         required_flags = ['hp3par_api_url', 'hp3par_username',
                           'hp3par_password',
                           'san_ip', 'san_login', 'san_password']
-        self.common.check_flags(FLAGS, required_flags)
+        self.common.check_flags(self.configuration, required_flags)
 
     def _create_client(self):
-        return client.HP3ParClient(FLAGS.hp3par_api_url)
+        return client.HP3ParClient(self.configuration.hp3par_api_url)
 
     def get_volume_stats(self, refresh):
         stats = self.common.get_volume_stats(refresh, self.client)
@@ -78,29 +83,32 @@ class HP3PARFCDriver(cinder.volume.driver.FibreChannelDriver):
         self.common = self._init_common()
         self._check_flags()
         self.client = self._create_client()
-        if FLAGS.hp3par_debug:
+        if self.configuration.hp3par_debug:
             self.client.debug_rest(True)
 
         try:
             LOG.debug("Connecting to 3PAR")
-            self.client.login(FLAGS.hp3par_username, FLAGS.hp3par_password)
+            self.client.login(self.configuration.hp3par_username,
+                              self.configuration.hp3par_password)
         except hpexceptions.HTTPUnauthorized as ex:
             LOG.warning("Failed to connect to 3PAR (%s) because %s" %
-                       (FLAGS.hp3par_api_url, str(ex)))
+                       (self.configuration.hp3par_api_url, str(ex)))
             msg = _("Login to 3PAR array invalid")
             raise exception.InvalidInput(reason=msg)
 
         # make sure the CPG exists
         try:
-            cpg = self.client.getCPG(FLAGS.hp3par_cpg)
+            cpg = self.client.getCPG(self.configuration.hp3par_cpg)
         except hpexceptions.HTTPNotFound as ex:
-            err = _("CPG (%s) doesn't exist on array") % FLAGS.hp3par_cpg
+            err = (_("CPG (%s) doesn't exist on array")
+                   % self.configuration.hp3par_cpg)
             LOG.error(err)
             raise exception.InvalidInput(reason=err)
 
-        if 'domain' not in cpg and cpg['domain'] != FLAGS.hp3par_domain:
+        if ('domain' not in cpg
+            and cpg['domain'] != self.configuration.hp3par_domain):
             err = "CPG's domain '%s' and config option hp3par_domain '%s' \
-must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
+must be the same" % (cpg['domain'], self.configuration.hp3par_domain)
             LOG.error(err)
             raise exception.InvalidInput(reason=err)
 
@@ -109,18 +117,15 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
         self._check_flags()
 
     def create_volume(self, volume):
-        """ Create a new volume. """
-        metadata = self.common.create_volume(volume, self.client, FLAGS)
+        metadata = self.common.create_volume(volume, self.client)
         return {'metadata': metadata}
 
     def create_cloned_volume(self, volume, src_vref):
-        """ Clone an existing volume. """
         new_vol = self.common.create_cloned_volume(volume, src_vref,
-                                                   self.client, FLAGS)
+                                                   self.client)
         return {'metadata': new_vol}
 
     def delete_volume(self, volume):
-        """ Delete a volume. """
         self.common.delete_volume(volume, self.client)
 
     def create_volume_from_snapshot(self, volume, snapshot):
@@ -132,11 +137,9 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
         self.common.create_volume_from_snapshot(volume, snapshot, self.client)
 
     def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        self.common.create_snapshot(snapshot, self.client, FLAGS)
+        self.common.create_snapshot(snapshot, self.client)
 
     def delete_snapshot(self, snapshot):
-        """Driver entry point for deleting a snapshot."""
         self.common.delete_snapshot(snapshot, self.client)
 
     def initialize_connection(self, volume, connector):
@@ -224,7 +227,8 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
             persona_id = self.common.get_persona_type(volume)
             # host doesn't exist, we have to create it
             self._create_3par_fibrechan_host(hostname, connector['wwpns'],
-                                             FLAGS.hp3par_domain, persona_id)
+                                             self.configuration.hp3par_domain,
+                                             persona_id)
             host = self.common._get_3par_host(hostname)
 
         return host
@@ -233,9 +237,7 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
         pass
 
     def ensure_export(self, context, volume):
-        """Exports the volume."""
         pass
 
     def remove_export(self, context, volume):
-        """Removes an export for a logical volume."""
         pass
index 5b76900749378c78bcb450f41062de91b1fd18ae..dea8bf1ccff9fd59782bec52fa72d31c6b5346f9 100644 (file)
 #
 """
 Volume driver for HP 3PAR Storage array. This driver requires 3.1.2 firmware
-on the 3PAR array. Set the following in the cinder.conf file to enable the
+on the 3PAR array.
+
+You will need to install the python hp3parclient.
+sudo pip install hp3parclient
+
+Set the following in the cinder.conf file to enable the
 3PAR iSCSI Driver along with the required flags:
 
 volume_driver=cinder.volume.drivers.san.hp.hp_3par_iscsi.HP3PARISCSIDriver
@@ -29,17 +34,15 @@ from hp3parclient import client
 from hp3parclient import exceptions as hpexceptions
 
 from cinder import exception
-from cinder import flags
 from cinder.openstack.common import lockutils
 from cinder.openstack.common import log as logging
 import cinder.volume.driver
-from cinder.volume.drivers.san.hp.hp_3par_common import HP3PARCommon
+from cinder.volume.drivers.san.hp import hp_3par_common as hpcommon
+from cinder.volume.drivers.san import san
 
 VERSION = 1.0
 LOG = logging.getLogger(__name__)
 
-FLAGS = flags.FLAGS
-
 
 class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
     """OpenStack iSCSI driver to enable 3PAR storage array.
@@ -52,9 +55,11 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
         super(HP3PARISCSIDriver, self).__init__(*args, **kwargs)
         self.client = None
         self.common = None
+        self.configuration.append_config_values(hpcommon.hp3par_opts)
+        self.configuration.append_config_values(san.san_opts)
 
     def _init_common(self):
-        return HP3PARCommon()
+        return hpcommon.HP3PARCommon(self.configuration)
 
     def _check_flags(self):
         """Sanity check to ensure we have required options set."""
@@ -62,10 +67,10 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
                           'hp3par_password', 'iscsi_ip_address',
                           'iscsi_port', 'san_ip', 'san_login',
                           'san_password']
-        self.common.check_flags(FLAGS, required_flags)
+        self.common.check_flags(self.configuration, required_flags)
 
     def _create_client(self):
-        return client.HP3ParClient(FLAGS.hp3par_api_url)
+        return client.HP3ParClient(self.configuration.hp3par_api_url)
 
     def get_volume_stats(self, refresh):
         stats = self.common.get_volume_stats(refresh, self.client)
@@ -77,34 +82,37 @@ class HP3PARISCSIDriver(cinder.volume.driver.ISCSIDriver):
         self.common = self._init_common()
         self._check_flags()
         self.client = self._create_client()
-        if FLAGS.hp3par_debug:
+        if self.configuration.hp3par_debug:
             self.client.debug_rest(True)
 
         try:
             LOG.debug("Connecting to 3PAR")
-            self.client.login(FLAGS.hp3par_username, FLAGS.hp3par_password)
+            self.client.login(self.configuration.hp3par_username,
+                              self.configuration.hp3par_password)
         except hpexceptions.HTTPUnauthorized as ex:
             LOG.warning("Failed to connect to 3PAR (%s) because %s" %
-                       (FLAGS.hp3par_api_url, str(ex)))
+                       (self.configuration.hp3par_api_url, str(ex)))
             msg = _("Login to 3PAR array invalid")
             raise exception.InvalidInput(reason=msg)
 
         # make sure the CPG exists
         try:
-            cpg = self.client.getCPG(FLAGS.hp3par_cpg)
+            cpg = self.client.getCPG(self.configuration.hp3par_cpg)
         except hpexceptions.HTTPNotFound as ex:
-            err = _("CPG (%s) doesn't exist on array") % FLAGS.hp3par_cpg
+            err = (_("CPG (%s) doesn't exist on array")
+                   % self.configuration.hp3par_cpg)
             LOG.error(err)
             raise exception.InvalidInput(reason=err)
 
-        if 'domain' not in cpg and cpg['domain'] != FLAGS.hp3par_domain:
+        if ('domain' not in cpg and
+            cpg['domain'] != self.configuration.hp3par_domain):
             err = "CPG's domain '%s' and config option hp3par_domain '%s' \
-must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
+must be the same" % (cpg['domain'], self.configuration.hp3par_domain)
             LOG.error(err)
             raise exception.InvalidInput(reason=err)
 
         # make sure ssh works.
-        self._iscsi_discover_target_iqn(FLAGS.iscsi_ip_address)
+        self._iscsi_discover_target_iqn(self.configuration.iscsi_ip_address)
 
     def check_for_setup_error(self):
         """Returns an error if prerequisites aren't met."""
@@ -112,24 +120,24 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
 
     @lockutils.synchronized('3par-vol', 'cinder-', True)
     def create_volume(self, volume):
-        """ Create a new volume. """
-        metadata = self.common.create_volume(volume, self.client, FLAGS)
+        metadata = self.common.create_volume(volume, self.client)
 
         return {'provider_location': "%s:%s" %
-                (FLAGS.iscsi_ip_address, FLAGS.iscsi_port),
+                (self.configuration.iscsi_ip_address,
+                 self.configuration.iscsi_port),
                 'metadata': metadata}
 
     def create_cloned_volume(self, volume, src_vref):
         """ Clone an existing volume. """
         new_vol = self.common.create_cloned_volume(volume, src_vref,
-                                                   self.client, FLAGS)
+                                                   self.client)
         return {'provider_location': "%s:%s" %
-                (FLAGS.iscsi_ip_address, FLAGS.iscsi_port),
+                (self.configuration.iscsi_ip_address,
+                 self.configuration.iscsi_port),
                 'metadata': new_vol}
 
     @lockutils.synchronized('3par-vol', 'cinder-', True)
     def delete_volume(self, volume):
-        """ Delete a volume. """
         self.common.delete_volume(volume, self.client)
 
     @lockutils.synchronized('3par-vol', 'cinder-', True)
@@ -143,12 +151,10 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
 
     @lockutils.synchronized('3par-snap', 'cinder-', True)
     def create_snapshot(self, snapshot):
-        """Creates a snapshot."""
-        self.common.create_snapshot(snapshot, self.client, FLAGS)
+        self.common.create_snapshot(snapshot, self.client)
 
     @lockutils.synchronized('3par-snap', 'cinder-', True)
     def delete_snapshot(self, snapshot):
-        """Driver entry point for deleting a snapshot."""
         self.common.delete_snapshot(snapshot, self.client)
 
     @lockutils.synchronized('3par-attach', 'cinder-', True)
@@ -178,7 +184,8 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
           * create vlun on the 3par
         """
         # get the target_iqn on the 3par interface.
-        target_iqn = self._iscsi_discover_target_iqn(FLAGS.iscsi_ip_address)
+        target_iqn = self._iscsi_discover_target_iqn(
+            self.configuration.iscsi_ip_address)
 
         # we have to make sure we have a host
         host = self._create_host(volume, connector)
@@ -188,7 +195,8 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
 
         info = {'driver_volume_type': 'iscsi',
                 'data': {'target_portal': "%s:%s" %
-                         (FLAGS.iscsi_ip_address, FLAGS.iscsi_port),
+                         (self.configuration.iscsi_ip_address,
+                          self.configuration.iscsi_port),
                          'target_iqn': target_iqn,
                          'target_lun': vlun['lun'],
                          'target_discovered': True
@@ -246,7 +254,8 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
             persona_id = self.common.get_persona_type(volume)
             # host doesn't exist, we have to create it
             self._create_3par_iscsi_host(hostname, connector['initiator'],
-                                         FLAGS.hp3par_domain, persona_id)
+                                         self.configuration.hp3par_domain,
+                                         persona_id)
             host = self.common._get_3par_host(hostname)
 
         return host
@@ -257,10 +266,8 @@ must be the same" % (cpg['domain'], FLAGS.hp3par_domain)
 
     @lockutils.synchronized('3par-exp', 'cinder-', True)
     def ensure_export(self, context, volume):
-        """Exports the volume."""
         pass
 
     @lockutils.synchronized('3par-exp', 'cinder-', True)
     def remove_export(self, context, volume):
-        """Removes an export for a logical volume."""
         pass