]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Storwize/SVC: Optional CHAP authentication
authorAvishay Traeger <avishay@il.ibm.com>
Thu, 12 Sep 2013 10:50:07 +0000 (13:50 +0300)
committerAvishay Traeger <avishay@il.ibm.com>
Tue, 17 Sep 2013 18:29:18 +0000 (21:29 +0300)
The Storwize/SVC driver doesn't work with Nova drivers that don't
support CHAP (e.g., HyperV). This patch makes CHAP optional.

DocImpact

Closes-Bug: #1224334
Change-Id: I22df4b916b2800a53c1e4968913f7e95965eaf4b

cinder/tests/test_storwize_svc.py
cinder/volume/drivers/storwize_svc.py
etc/cinder/cinder.conf.sample

index 5c21156d2eb4e6f34b15fe479a29e48c58851e22..408b5d963b0744593b268bdb5440c25a0980469c 100644 (file)
@@ -483,7 +483,7 @@ port_speed!N/A
         host_infos = []
 
         for hk, hv in self._hosts_list.iteritems():
-            if not host_name or hv['host_name'] == host_name:
+            if not host_name or hv['host_name'].startswith(host_name):
                 for mk, mv in self._mappings_list.iteritems():
                     if mv['host'] == hv['host_name']:
                         if not target_wwpn or target_wwpn in hv['wwpns']:
@@ -968,7 +968,7 @@ port_speed!N/A
         for mapping_id in mapping_ids:
             if self._mappings_list[mapping_id]['host'] == host:
                 this_mapping = mapping_id
-        if this_mapping == None:
+        if this_mapping is None:
             return self._errors['CMMVC5753E']
 
         del self._mappings_list[this_mapping]
@@ -1310,6 +1310,12 @@ port_speed!N/A
             host_info['wwpns'] = host_info['wwpns'] + connector['wwpns']
         self._hosts_list[connector['host']] = host_info
 
+    def _host_in_list(self, host_name):
+        for k, v in self._hosts_list.iteritems():
+            if k.startswith(host_name):
+                return k
+        return None
+
     # The main function to run commands on the management simulator
     def execute_command(self, cmd, check_exit_code=True):
         try:
@@ -1934,19 +1940,35 @@ class StorwizeSVCDriverTestCase(test.TestCase):
 
         # Check cases with no auth set for host
         if self.USESIM:
-            for case in ['no_info', 'no_auth_set']:
-                conn_na = {'initiator': 'test:init:%s' %
-                                        random.randint(10000, 99999),
-                           'ip': '11.11.11.11',
-                           'host': 'host-%s' % case}
-                self.sim._add_host_to_list(conn_na)
-                volume1['volume_type_id'] = types['iSCSI']['id']
-                if case == 'no_info':
-                    self.sim.error_injection('lsiscsiauth', 'no_info')
-                self.driver.initialize_connection(volume1, conn_na)
-                ret = self.driver._get_chap_secret_for_host(conn_na['host'])
-                self.assertNotEqual(ret, None)
-                self.driver.terminate_connection(volume1, conn_na)
+            for auth_enabled in [True, False]:
+                for host_exists in ['yes-auth', 'yes-noauth', 'no']:
+                    self._set_flag('storwize_svc_iscsi_chap_enabled',
+                                   auth_enabled)
+                    case = 'en' + str(auth_enabled) + 'ex' + str(host_exists)
+                    conn_na = {'initiator': 'test:init:%s' %
+                                            random.randint(10000, 99999),
+                               'ip': '11.11.11.11',
+                               'host': 'host-%s' % case}
+                    if host_exists.startswith('yes'):
+                        self.sim._add_host_to_list(conn_na)
+                        if host_exists == 'yes-auth':
+                            kwargs = {'chapsecret': 'foo',
+                                      'obj': conn_na['host']}
+                            self.sim._cmd_chhost(**kwargs)
+                    volume1['volume_type_id'] = types['iSCSI']['id']
+
+                    init_ret = self.driver.initialize_connection(volume1,
+                                                                 conn_na)
+                    host_name = self.sim._host_in_list(conn_na['host'])
+                    chap_ret = self.driver._get_chap_secret_for_host(host_name)
+                    if auth_enabled or host_exists == 'yes-auth':
+                        self.assertIn('auth_password', init_ret['data'])
+                        self.assertNotEqual(chap_ret, None)
+                    else:
+                        self.assertNotIn('auth_password', init_ret['data'])
+                        self.assertEqual(chap_ret, None)
+                    self.driver.terminate_connection(volume1, conn_na)
+        self._set_flag('storwize_svc_iscsi_chap_enabled', True)
 
         # Test no preferred node
         if self.USESIM:
index 581627a05309a9ec07683dff2b782433bac23639..83f813fa005223c6bb97aefacddb9735d9fdfe9e 100644 (file)
@@ -95,6 +95,10 @@ storwize_svc_opts = [
     cfg.StrOpt('storwize_svc_connection_protocol',
                default='iSCSI',
                help='Connection protocol (iSCSI/FC)'),
+    cfg.BoolOpt('storwize_svc_iscsi_chap_enabled',
+                default=True,
+                help='Configure CHAP authentication for iSCSI connections '
+                     '(Default: Enabled)'),
     cfg.BoolOpt('storwize_svc_multipath_enabled',
                 default=False,
                 help='Connect with multipath (FC only; iSCSI multipath is '
@@ -423,8 +427,8 @@ class StorwizeSVCDriver(san.SanDriver):
             return None
 
         host_lines = out.strip().split('\n')
-        self._assert_ssh_return(len(host_lines), '_get_chap_secret_for_host',
-                                ssh_cmd, out, err)
+        if not len(host_lines):
+            return None
 
         header = host_lines.pop(0).split('!')
         self._assert_ssh_return('name' in header, '_get_chap_secret_for_host',
@@ -766,8 +770,12 @@ class StorwizeSVCDriver(san.SanDriver):
 
         if vol_opts['protocol'] == 'iSCSI':
             chap_secret = self._get_chap_secret_for_host(host_name)
-            if chap_secret is None:
+            chap_enabled = self.configuration.storwize_svc_iscsi_chap_enabled
+            if chap_enabled and chap_secret is None:
                 chap_secret = self._add_chapsecret_to_host(host_name)
+            elif not chap_enabled and chap_secret:
+                LOG.warning(_('CHAP secret exists for host but CHAP is '
+                              'disabled'))
 
         volume_attributes = self._get_vdisk_attributes(volume_name)
         lun_id = self._map_vol_to_host(volume_name, host_name)
@@ -823,9 +831,10 @@ class StorwizeSVCDriver(san.SanDriver):
                     ipaddr = preferred_node_entry['ipv6'][0]
                 properties['target_portal'] = '%s:%s' % (ipaddr, '3260')
                 properties['target_iqn'] = preferred_node_entry['iscsi_name']
-                properties['auth_method'] = 'CHAP'
-                properties['auth_username'] = connector['initiator']
-                properties['auth_password'] = chap_secret
+                if chap_secret:
+                    properties['auth_method'] = 'CHAP'
+                    properties['auth_username'] = connector['initiator']
+                    properties['auth_password'] = chap_secret
             else:
                 type_str = 'fibre_channel'
                 conn_wwpns = self._get_conn_fc_wwpns(host_name)
index 03790856dbb66752718bf39097fdedfd6613cc54..c988d7e63cfcea09619dc04c0654828e543bc15e 100644 (file)
 # Connection protocol (iSCSI/FC) (string value)
 #storwize_svc_connection_protocol=iSCSI
 
+# Configure CHAP authentication for iSCSI connections
+# (Default: Enabled) (boolean value)
+#storwize_svc_iscsi_chap_enabled=true
+
 # Connect with multipath (FC only; iSCSI multipath is
 # controlled by Nova) (boolean value)
 #storwize_svc_multipath_enabled=false
 #volume_dd_blocksize=1M
 
 
-# Total option count: 379
+# Total option count: 380