Remove VxFlex OS credentials from connection_properties

VxFlex OS password is not stored in block_device_mapping table. Instead of this
passwords are stored in separate file and are retrieved during each attach/detach
operation.

Closes-Bug: #1823200
Change-Id: Iab54c515fe7be252df52b1a0503a251779805759
This commit is contained in:
Ivan Pchelintsev 2020-06-01 11:28:08 +03:00
parent 6ed805abe4
commit 5414305a2b
4 changed files with 84 additions and 4 deletions

View File

@ -30,6 +30,7 @@ from os_brick import utils
LOG = logging.getLogger(__name__)
DEVICE_SCAN_ATTEMPTS_DEFAULT = 3
CONNECTOR_CONF_PATH = '/opt/emc/scaleio/openstack/connector.conf'
synchronized = lockutils.synchronized_with_prefix('os-brick-')
@ -86,6 +87,19 @@ class ScaleIOConnector(base.BaseLinuxConnector):
LOG.error(msg)
raise exception.BrickException(message=msg)
@staticmethod
def _get_connector_password(config_group, failed_over):
LOG.info("Get ScaleIO connector password from configuration file")
try:
return priv_scaleio.get_connector_password(CONNECTOR_CONF_PATH,
config_group,
failed_over)
except Exception as e:
msg = _("Error getting ScaleIO connector password from "
"configuration file: %s") % e
LOG.error(msg)
raise exception.BrickException(message=msg)
def _rescan_vols(self):
LOG.info("ScaleIO rescan volumes")
@ -306,8 +320,10 @@ class ScaleIOConnector(base.BaseLinuxConnector):
self.server_ip = connection_properties['serverIP']
self.server_port = connection_properties['serverPort']
self.server_username = connection_properties['serverUsername']
self.server_password = connection_properties['serverPassword']
self.server_token = connection_properties['serverToken']
self.server_password = self._get_connector_password(
connection_properties['config_group'],
connection_properties['failed_over'],
)
self.iops_limit = connection_properties['iopsLimit']
self.bandwidth_limit = connection_properties['bandwidthLimit']
device_info = {'type': 'block',

View File

@ -11,12 +11,14 @@
# under the License.
from binascii import hexlify
import configparser
from contextlib import contextmanager
from fcntl import ioctl
import os
import struct
import uuid
from os_brick import exception
from os_brick import privileged
SCINI_DEVICE_PATH = '/dev/scini'
@ -70,3 +72,32 @@ def rescan_vols(op_code):
with open_scini_device() as fd:
ioctl(fd, op_code, struct.pack('Q', 0))
@privileged.default.entrypoint
def get_connector_password(filename, config_group, failed_over):
"""Read ScaleIO connector configuration file and get appropriate password.
:param filename: path to connector configuration file
:type filename: str
:param config_group: name of section in configuration file
:type config_group: str
:param failed_over: flag representing if storage is in failed over state
:type failed_over: bool
:return: connector password
:rtype: str
"""
if not os.path.isfile(filename):
msg = (
"ScaleIO connector configuration file "
"is not found in path %s." % filename
)
raise exception.BrickException(message=msg)
conf = configparser.ConfigParser()
conf.read(filename)
password_key = (
"replicating_san_password" if failed_over else "san_password"
)
return conf[config_group][password_key]

View File

@ -46,8 +46,8 @@ class ScaleIOConnectorTestCase(test_connector.ConnectorTestCase):
'scaleIO_volume_id': self.vol['provider_id'],
'serverPort': 443,
'serverUsername': 'test',
'serverPassword': 'fake',
'serverToken': 'fake_token',
'config_group': 'test',
'failed_over': False,
'iopsLimit': None,
'bandwidthLimit': None
}
@ -84,6 +84,9 @@ class ScaleIOConnectorTestCase(test_connector.ConnectorTestCase):
return_value=["emc-vol-{}".format(self.vol['id'])])
# Patch scaleio privileged calls
self.get_password_mock = self.mock_object(scaleio.priv_scaleio,
'get_connector_password',
return_value='fake_password')
self.get_guid_mock = self.mock_object(scaleio.priv_scaleio, 'get_guid',
return_value=self.fake_guid)
self.rescan_vols_mock = self.mock_object(scaleio.priv_scaleio,
@ -169,6 +172,7 @@ class ScaleIOConnectorTestCase(test_connector.ConnectorTestCase):
self.connector.connect_volume(self.fake_connection_properties)
self.get_guid_mock.assert_called_once_with(
self.connector.GET_GUID_OP_CODE)
self.get_password_mock.assert_called_once()
def test_connect_volume_without_volume_id(self):
"""Successful connect to volume without a Volume Id"""

View File

@ -0,0 +1,29 @@
---
security:
- |
Dell EMC VxFlex OS driver: This release contains a fix for
`Bug #1823200 <https://bugs.launchpad.net/cinder/+bug/1823200>`_.
See `OSSN-0086 <https://wiki.openstack.org/wiki/OSSN/OSSN-0086>`_
for details.
upgrade:
- |
The fix for `Bug #1823200
<https://bugs.launchpad.net/cinder/+bug/1823200>`_ requires that a
configuration file be deployed on compute nodes, cinder nodes, and
anywhere you would perform a volume attachment in your deployment,
when using Cinder with a Dell EMC VxFlex OS backend. See the
`Dell EMC VxFlex OS (ScaleIO) Storage driver
<https://docs.openstack.org/cinder/latest/configuration/block-storage/drivers/dell-emc-vxflex-driver.html>`_
documentation for details about this configuration file.
fixes:
- |
`Bug #1823200 <https://bugs.launchpad.net/cinder/+bug/1823200>`_:
This release contains an updated connector for use with the Dell EMC
VxFlex OS backend. It requires that a configuration file be deployed
on compute nodes, cinder nodes, and anywhere you would perform a
volume attachment in your deployment. See the
`Dell EMC VxFlex OS (ScaleIO) Storage driver
<https://docs.openstack.org/cinder/latest/configuration/block-storage/drivers/dell-emc-vxflex-driver.html>`_
documentation for details about the configuration file, and see
`OSSN-0086 <https://wiki.openstack.org/wiki/OSSN/OSSN-0086>`_ for
more information about the security vulnerability.