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: Iaa337518d6e6542a93d9e4f5d4d72094e9279c53
This commit is contained in:
Ivan Pchelintsev 2020-06-01 11:41:50 +03:00
parent 55cfc97581
commit a1c9f64944
4 changed files with 84 additions and 4 deletions

View File

@ -30,6 +30,7 @@ from os_brick import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
DEVICE_SCAN_ATTEMPTS_DEFAULT = 3 DEVICE_SCAN_ATTEMPTS_DEFAULT = 3
CONNECTOR_CONF_PATH = '/opt/emc/scaleio/openstack/connector.conf'
synchronized = lockutils.synchronized_with_prefix('os-brick-') synchronized = lockutils.synchronized_with_prefix('os-brick-')
@ -86,6 +87,19 @@ class ScaleIOConnector(base.BaseLinuxConnector):
LOG.error(msg) LOG.error(msg)
raise exception.BrickException(message=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): def _rescan_vols(self):
LOG.info("ScaleIO rescan volumes") LOG.info("ScaleIO rescan volumes")
@ -306,8 +320,10 @@ class ScaleIOConnector(base.BaseLinuxConnector):
self.server_ip = connection_properties['serverIP'] self.server_ip = connection_properties['serverIP']
self.server_port = connection_properties['serverPort'] self.server_port = connection_properties['serverPort']
self.server_username = connection_properties['serverUsername'] self.server_username = connection_properties['serverUsername']
self.server_password = connection_properties['serverPassword'] self.server_password = self._get_connector_password(
self.server_token = connection_properties['serverToken'] connection_properties['config_group'],
connection_properties['failed_over'],
)
self.iops_limit = connection_properties['iopsLimit'] self.iops_limit = connection_properties['iopsLimit']
self.bandwidth_limit = connection_properties['bandwidthLimit'] self.bandwidth_limit = connection_properties['bandwidthLimit']
device_info = {'type': 'block', device_info = {'type': 'block',

View File

@ -11,12 +11,14 @@
# under the License. # under the License.
from binascii import hexlify from binascii import hexlify
import configparser
from contextlib import contextmanager from contextlib import contextmanager
from fcntl import ioctl from fcntl import ioctl
import os import os
import struct import struct
import uuid import uuid
from os_brick import exception
from os_brick import privileged from os_brick import privileged
SCINI_DEVICE_PATH = '/dev/scini' SCINI_DEVICE_PATH = '/dev/scini'
@ -70,3 +72,32 @@ def rescan_vols(op_code):
with open_scini_device() as fd: with open_scini_device() as fd:
ioctl(fd, op_code, struct.pack('Q', 0)) 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

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