]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add https options and minor code changes
authornikeshm <Nikesh.Mahalaka@dothill.com>
Fri, 21 Aug 2015 20:39:51 +0000 (02:09 +0530)
committernikeshm <Nikesh.Mahalaka@dothill.com>
Mon, 24 Aug 2015 20:01:16 +0000 (01:31 +0530)
Adds https options x_verify_certificate and x_verify_certificate_path
in DotHill and rebranded drivers.

Minor cosmetic changes like replacing 'realstor' with 'virtual'
and 'wbi' with 'api'. Adding default value for 'x_backend_type'
and 'x_api_protocol' options. Minor code optimization for
finding array iSCSI addresses.

Here 'x' stands for dothill or hpmsa or lenovo.

DocImpact
Change-Id: I7a5924bbd56053aee6d652842b48e913c54ae7dd
Closes-Bug: #1486160
Co-Authored-By: Lakshman <lakshminarayanat@vedams.com>
Co-Authored-By: Chris Maio <chris.maio@dothill.com>
cinder/tests/unit/test_dothill.py
cinder/volume/drivers/dothill/dothill_client.py
cinder/volume/drivers/dothill/dothill_common.py
cinder/volume/drivers/dothill/dothill_fc.py
cinder/volume/drivers/dothill/dothill_iscsi.py
cinder/volume/drivers/lenovo/lenovo_client.py
cinder/volume/drivers/lenovo/lenovo_common.py
cinder/volume/drivers/san/hp/hpmsa_client.py
cinder/volume/drivers/san/hp/hpmsa_common.py

index 6b9365bb1edb707652b408506136bbd92a2beb68..6b55fa0af2da4a50c5be6b2d59bc0a3f7bfc23bf 100644 (file)
@@ -51,7 +51,7 @@ response_stats_linear = '''<RESPONSE><OBJECT basetype="virtual-disks">
                     <PROPERTY name="size-numeric">3863830528</PROPERTY>
                     <PROPERTY name="freespace-numeric">3863830528</PROPERTY>
                     </OBJECT></RESPONSE>'''
-response_stats_realstor = '''<RESPONSE><OBJECT basetype="pools">
+response_stats_virtual = '''<RESPONSE><OBJECT basetype="pools">
                 <PROPERTY name="total-size-numeric">3863830528</PROPERTY>
                 <PROPERTY name="total-avail-numeric">3863830528</PROPERTY>
                 </OBJECT></RESPONSE>'''
@@ -87,7 +87,7 @@ response_ports = '''<RESPONSE>
                  </RESPONSE>'''
 
 response_ports_linear = response_ports % {'ip': 'primary-ip-address'}
-response_ports_realstor = response_ports % {'ip': 'ip-address'}
+response_ports_virtual = response_ports % {'ip': 'ip-address'}
 
 
 invalid_xml = '''<RESPONSE></RESPONSE>'''
@@ -146,8 +146,9 @@ class TestDotHillClient(test.TestCase):
         self.passwd = '!manage'
         self.ip = '10.0.0.1'
         self.protocol = 'http'
+        self.ssl_verify = False
         self.client = dothill.DotHillClient(self.ip, self.login, self.passwd,
-                                            self.protocol)
+                                            self.protocol, self.ssl_verify)
 
     @mock.patch('requests.get')
     def test_login(self, mock_requests_get):
@@ -219,13 +220,13 @@ class TestDotHillClient(test.TestCase):
         stats = {'free_capacity_gb': 1979,
                  'total_capacity_gb': 1979}
         linear = etree.XML(response_stats_linear)
-        realstor = etree.XML(response_stats_realstor)
-        mock_request.side_effect = [linear, realstor]
+        virtual = etree.XML(response_stats_virtual)
+        mock_request.side_effect = [linear, virtual]
 
         self.assertEqual(stats, self.client.backend_stats('OpenStack',
                                                           'linear'))
-        self.assertEqual(stats, self.client.backend_stats('OpenStack',
-                                                          'realstor'))
+        self.assertEqual(stats, self.client.backend_stats('A',
+                                                          'virtual'))
 
     @mock.patch.object(dothill.DotHillClient, '_request')
     def test_get_lun(self, mock_request):
@@ -266,10 +267,10 @@ class TestDotHillClient(test.TestCase):
     def test_get_iscsi_portals(self, mock_request):
         portals = {'10.0.0.12': 'Up', '10.0.0.11': 'Up'}
         mock_request.side_effect = [etree.XML(response_ports_linear),
-                                    etree.XML(response_ports_realstor)]
-        ret = self.client.get_active_iscsi_target_portals('linear')
+                                    etree.XML(response_ports_virtual)]
+        ret = self.client.get_active_iscsi_target_portals()
         self.assertEqual(portals, ret)
-        ret = self.client.get_active_iscsi_target_portals('realstor')
+        ret = self.client.get_active_iscsi_target_portals()
         self.assertEqual(portals, ret)
 
 
@@ -279,7 +280,7 @@ class FakeConfiguration1(object):
     san_ip = '10.0.0.1'
     san_login = 'manage'
     san_password = '!manage'
-    dothill_wbi_protocol = 'http'
+    dothill_api_protocol = 'http'
 
     def safe_get(self, key):
         return 'fakevalue'
index 5cc864805e98e777bcd3a094d7fbbdf77c0b7aad..c1da831328ab384651920e4ae0b1fe1cb9e7eff5 100644 (file)
@@ -30,11 +30,12 @@ LOG = logging.getLogger(__name__)
 
 
 class DotHillClient(object):
-    def __init__(self, host, login, password, protocol):
+    def __init__(self, host, login, password, protocol, ssl_verify):
         self._login = login
         self._password = password
         self._base_url = "%s://%s/api" % (protocol, host)
         self._session_key = None
+        self.ssl_verify = ssl_verify
 
     def _get_auth_token(self, xml):
         """Parse an XML authentication reply to extract the session key."""
@@ -53,7 +54,7 @@ class DotHillClient(object):
 
         url = self._base_url + "/login/" + digest
         try:
-            xml = requests.get(url)
+            xml = requests.get(url, verify=self.ssl_verify)
         except requests.exceptions.RequestException:
             raise exception.DotHillConnectionError
 
@@ -96,7 +97,7 @@ class DotHillClient(object):
         url = self._build_request_url(path, *args, **kargs)
         headers = {'dataType': 'api', 'sessionKey': self._session_key}
         try:
-            xml = requests.get(url, headers=headers)
+            xml = requests.get(url, headers=headers, verify=self.ssl_verify)
             tree = etree.XML(xml.text.encode('utf8'))
         except Exception:
             raise exception.DotHillConnectionError
@@ -109,7 +110,7 @@ class DotHillClient(object):
     def logout(self):
         url = self._base_url + '/exit'
         try:
-            requests.get(url)
+            requests.get(url, verify=self.ssl_verify)
             return True
         except Exception:
             return False
@@ -275,10 +276,10 @@ class DotHillClient(object):
         return host_status
 
     def _safe_hostname(self, hostname):
-        """DotHill hostname restrictions.
+        """Modify an initiator name to match firmware requirements.
 
-           A host name cannot include " , \ in linear and " , < > \ in realstor
-           and can have a max of 15 bytes in linear and 32 bytes in realstor.
+           Initiator name cannot include certain characters and cannot exceed
+           15 bytes in 'T' firmware (32 bytes in 'G' firmware).
         """
         for ch in [',', '"', '\\', '<', '>']:
             if ch in hostname:
@@ -288,16 +289,14 @@ class DotHillClient(object):
             index = 15
         return hostname[:index]
 
-    def get_active_iscsi_target_portals(self, backend_type):
+    def get_active_iscsi_target_portals(self):
         # This function returns {'ip': status,}
         portals = {}
-        prop = ""
+        prop = 'ip-address'
         tree = self._request("/show/ports")
-        if backend_type == "linear":
-            prop = "primary-ip-address"
-        else:
-            prop = "ip-address"
-
+        for el in tree.xpath("//PROPERTY[@name='primary-ip-address']"):
+            prop = 'primary-ip-address'
+            break
         iscsi_ips = [ip.text for ip in tree.xpath(
                      "//PROPERTY[@name='%s']" % prop)]
         if not iscsi_ips:
index 21dc9f16c9a98e4a4c5b3535238df636bf19a09b..2c395137d748f59e0e9f44488e5301f1f8257d62 100644 (file)
@@ -32,20 +32,28 @@ LOG = logging.getLogger(__name__)
 
 common_opt = [
     cfg.StrOpt('dothill_backend_name',
-               default='OpenStack',
-               help="VDisk or Pool name to use for volume creation."),
+               default='A',
+               help="Pool or Vdisk name to use for volume creation."),
     cfg.StrOpt('dothill_backend_type',
-               choices=['linear', 'realstor'],
-               help="linear (for VDisk) or realstor (for Pool)."),
-    cfg.StrOpt('dothill_wbi_protocol',
+               choices=['linear', 'virtual'],
+               default='virtual',
+               help="linear (for Vdisk) or virtual (for Pool)."),
+    cfg.StrOpt('dothill_api_protocol',
                choices=['http', 'https'],
-               help="DotHill web interface protocol."),
+               default='https',
+               help="DotHill API interface protocol."),
+    cfg.BoolOpt('dothill_verify_certificate',
+                default=False,
+                help="Whether to verify DotHill array SSL certificate."),
+    cfg.StrOpt('dothill_verify_certificate_path',
+               default=None,
+               help="DotHill array SSL certificate path."),
 ]
 
 iscsi_opt = [
     cfg.ListOpt('dothill_iscsi_ips',
                 default=[],
-                help="List of comma separated target iSCSI IP addresses."),
+                help="List of comma-separated target iSCSI IP addresses."),
 ]
 
 CONF = cfg.CONF
@@ -63,10 +71,16 @@ class DotHillCommon(object):
         self.vendor_name = "DotHill"
         self.backend_name = self.config.dothill_backend_name
         self.backend_type = self.config.dothill_backend_type
+        self.api_protocol = self.config.dothill_api_protocol
+        ssl_verify = False
+        if (self.api_protocol == 'https' and
+           self.config.dothill_verify_certificate):
+            ssl_verify = self.config.dothill_verify_certificate_path or True
         self.client = dothill.DotHillClient(self.config.san_ip,
                                             self.config.san_login,
                                             self.config.san_password,
-                                            self.config.dothill_wbi_protocol)
+                                            self.api_protocol,
+                                            ssl_verify)
 
     def get_version(self):
         return self.VERSION
@@ -75,7 +89,7 @@ class DotHillCommon(object):
         self.client_login()
         self._validate_backend()
         if (self.backend_type == "linear" or
-            (self.backend_type == "realstor" and
+            (self.backend_type == "virtual" and
              self.backend_name not in ['A', 'B'])):
                 self._get_owner_info(self.backend_name)
                 self._get_serial_number()
@@ -194,7 +208,7 @@ class DotHillCommon(object):
             raise exception.VolumeAttached(volume_id=volume['id'])
 
     def create_cloned_volume(self, volume, src_vref):
-        if self.backend_type == "realstor" and self.backend_name in ["A", "B"]:
+        if self.backend_type == "virtual" and self.backend_name in ["A", "B"]:
             msg = _("Create volume from volume(clone) does not have support "
                     "for virtual pool A and B.")
             LOG.error(msg)
@@ -223,7 +237,7 @@ class DotHillCommon(object):
             self.client_logout()
 
     def create_volume_from_snapshot(self, volume, snapshot):
-        if self.backend_type == "realstor" and self.backend_name in ["A", "B"]:
+        if self.backend_type == "virtual" and self.backend_name in ["A", "B"]:
             msg = _('Create volume from snapshot does not have support '
                     'for virtual pool A and B.')
             LOG.error(msg)
@@ -290,7 +304,7 @@ class DotHillCommon(object):
                                                       self.backend_type)
             pool.update(backend_stats)
             if (self.backend_type == "linear" or
-                (self.backend_type == "realstor" and
+                (self.backend_type == "virtual" and
                  self.backend_name not in ['A', 'B'])):
                 pool['location_info'] = ('%s:%s:%s:%s' %
                                          (src_type,
@@ -362,8 +376,7 @@ class DotHillCommon(object):
 
     def get_active_iscsi_target_portals(self):
         try:
-            return self.client.get_active_iscsi_target_portals(
-                self.backend_type)
+            return self.client.get_active_iscsi_target_portals()
         except exception.DotHillRequestError as ex:
             LOG.exception(_LE("Error getting active ISCSI target portals."))
             raise exception.Invalid(ex)
index 443cfc5a2383ed648d6a4a44dad80cc177bb6f7f..9bbebe40dc9f7837fa57ba8f2fa4b77dc6675490 100644 (file)
@@ -33,7 +33,7 @@ class DotHillFCDriver(cinder.volume.driver.FibreChannelDriver):
                      cinder/volume/drivers/san/hp"
         1.0    - Version developed for DotHill arrays with the following
                  modifications:
-                     - added support for v3 API(realstor feature)
+                     - added support for v3 API(virtual pool feature)
                      - added support for retype volume
                      - added support for manage/unmanage volume
                      - added initiator target mapping in FC zoning
index 84f5933c3f50584fc7d32c78c7c4170e1ebf77db..e6ddc1dac975e8096b5babd04655a128c9ae01f2 100644 (file)
@@ -39,7 +39,7 @@ class DotHillISCSIDriver(cinder.volume.driver.ISCSIDriver):
                  modifications:
                      - added iSCSI support
                      - added CHAP support in iSCSI
-                     - added support for v3 API(realstor feature)
+                     - added support for v3 API(virtual pool feature)
                      - added support for retype volume
                      - added support for manage/unmanage volume
                      - added https support
index 1518f53dde70b8353ca0873a5fe74197f58cc746..07e807cdbf19a5460565baae6d9ba050a57b1f8f 100644 (file)
@@ -19,5 +19,6 @@ from cinder.volume.drivers.dothill import dothill_client
 
 class LenovoClient(dothill_client.DotHillClient):
 
-    def __init__(self, host, login, password, protocol):
-        super(LenovoClient, self).__init__(host, login, password, protocol)
+    def __init__(self, host, login, password, protocol, ssl_verify):
+        super(LenovoClient, self).__init__(host, login, password, protocol,
+                                           ssl_verify)
index 9b3878376b5d3a93faf872c7ebbb5ae08d17aaeb..95cb91e9bf63946126bdc793be2e23c56ce55b36 100644 (file)
@@ -21,20 +21,28 @@ from cinder.volume.drivers.lenovo import lenovo_client
 
 common_opt = [
     cfg.StrOpt('lenovo_backend_name',
-               default='OpenStack',
-               help="VDisk or Pool name to use for volume creation."),
+               default='A',
+               help="Pool or Vdisk name to use for volume creation."),
     cfg.StrOpt('lenovo_backend_type',
-               choices=['linear', 'realstor'],
-               help="linear (for VDisk) or realstor (for Pool)."),
-    cfg.StrOpt('lenovo_wbi_protocol',
+               choices=['linear', 'virtual'],
+               default='virtual',
+               help="linear (for VDisk) or virtual (for Pool)."),
+    cfg.StrOpt('lenovo_api_protocol',
                choices=['http', 'https'],
-               help="Lenovo web interface protocol."),
+               default='https',
+               help="Lenovo api interface protocol."),
+    cfg.BoolOpt('lenovo_verify_certificate',
+                default=False,
+                help="Whether to verify Lenovo array SSL certificate."),
+    cfg.StrOpt('lenovo_verify_certificate_path',
+               default=None,
+               help="Lenovo array SSL certificate path.")
 ]
 
 iscsi_opt = [
     cfg.ListOpt('lenovo_iscsi_ips',
                 default=[],
-                help="List of comma separated target iSCSI IP addresses."),
+                help="List of comma-separated target iSCSI IP addresses."),
 ]
 
 CONF = cfg.CONF
@@ -50,8 +58,13 @@ class LenovoCommon(dothill_common.DotHillCommon):
         self.vendor_name = "Lenovo"
         self.backend_name = self.config.lenovo_backend_name
         self.backend_type = self.config.lenovo_backend_type
-        self.wbi_protocol = self.config.lenovo_wbi_protocol
+        self.api_protocol = self.config.lenovo_api_protocol
+        ssl_verify = False
+        if (self.api_protocol == 'https' and
+           self.config.lenovo_verify_certificate):
+            ssl_verify = self.config.lenovo_verify_certificate_path or True
         self.client = lenovo_client.LenovoClient(self.config.san_ip,
                                                  self.config.san_login,
                                                  self.config.san_password,
-                                                 self.wbi_protocol)
+                                                 self.api_protocol,
+                                                 ssl_verify)
index 43185525bc7d59d29fdd0e892414800f974f688c..bec7bfd444198629db6d3ae80e6281dde912363c 100644 (file)
@@ -19,6 +19,6 @@ from cinder.volume.drivers.dothill import dothill_client
 
 class HPMSAClient(dothill_client.DotHillClient):
 
-    def __init__(self, host, login, password, protocol):
+    def __init__(self, host, login, password, protocol, ssl_verify):
         super(HPMSAClient, self).__init__(host, login, password,
-                                          protocol)
+                                          protocol, ssl_verify)
index 051ae4b7637d835866e27c3e645851187104ead4..8c16bc33cf46c250cb2bb2d4b378930ae5b5d0ce 100644 (file)
@@ -21,20 +21,29 @@ from cinder.volume.drivers.san.hp import hpmsa_client
 
 common_opt = [
     cfg.StrOpt('hpmsa_backend_name',
-               default='OpenStack',
-               help="VDisk or Pool name to use for volume creation."),
+               default='A',
+               help="Pool or Vdisk name to use for volume creation."),
     cfg.StrOpt('hpmsa_backend_type',
-               choices=['linear', 'realstor'],
-               help="linear (for VDisk) or realstor (for Pool)."),
-    cfg.StrOpt('hpmsa_wbi_protocol',
+               choices=['linear', 'virtual'],
+               default='virtual',
+               help="linear (for Vdisk) or virtual (for Pool)."),
+    cfg.StrOpt('hpmsa_api_protocol',
                choices=['http', 'https'],
-               help="HPMSA web interface protocol."),
+               default='https',
+               help="HPMSA API interface protocol."),
+    cfg.BoolOpt('hpmsa_verify_certificate',
+                default=False,
+                help="Whether to verify HPMSA array SSL certificate."),
+    cfg.StrOpt('hpmsa_verify_certificate_path',
+               default=None,
+               help="HPMSA array SSL certificate path."),
+
 ]
 
 iscsi_opt = [
     cfg.ListOpt('hpmsa_iscsi_ips',
                 default=[],
-                help="List of comma separated target iSCSI IP addresses."),
+                help="List of comma-separated target iSCSI IP addresses."),
 ]
 
 CONF = cfg.CONF
@@ -50,7 +59,14 @@ class HPMSACommon(dothill_common.DotHillCommon):
         self.vendor_name = "HPMSA"
         self.backend_name = self.config.hpmsa_backend_name
         self.backend_type = self.config.hpmsa_backend_type
+        self.api_protocol = self.config.hpmsa_api_protocol
+        ssl_verify = False
+        if (self.api_protocol == 'https' and
+           self.config.hpmsa_verify_certificate):
+            ssl_verify = self.config.hpmsa_verify_certificate_path or True
+
         self.client = hpmsa_client.HPMSAClient(self.config.san_ip,
                                                self.config.san_login,
                                                self.config.san_password,
-                                               self.config.hpmsa_wbi_protocol)
+                                               self.api_protocol,
+                                               ssl_verify)