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: Ib7778ba9d38a68d8b56ca632c5f1c353d55830b0
This commit is contained in:
Ivan Pchelintsev 2020-06-02 16:23:04 +03:00
parent 6e4e8901fe
commit 72c6368117
2 changed files with 39 additions and 4 deletions

View File

@ -15,6 +15,8 @@
import json import json
import os import os
import requests import requests
import six
from six.moves import configparser
from six.moves import urllib from six.moves import urllib
from oslo_concurrency import lockutils from oslo_concurrency import lockutils
@ -29,6 +31,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-')
@ -39,6 +42,7 @@ class ScaleIOConnector(base.BaseLinuxConnector):
VOLUME_NOT_MAPPED_ERROR = 84 VOLUME_NOT_MAPPED_ERROR = 84
VOLUME_ALREADY_MAPPED_ERROR = 81 VOLUME_ALREADY_MAPPED_ERROR = 81
GET_GUID_CMD = ['/opt/emc/scaleio/sdc/bin/drv_cfg', '--query_guid'] GET_GUID_CMD = ['/opt/emc/scaleio/sdc/bin/drv_cfg', '--query_guid']
GET_PASSWORD_CMD = ['cat', CONNECTOR_CONF_PATH]
def __init__(self, root_helper, driver=None, def __init__(self, root_helper, driver=None,
device_scan_attempts=initiator.DEVICE_SCAN_ATTEMPTS_DEFAULT, device_scan_attempts=initiator.DEVICE_SCAN_ATTEMPTS_DEFAULT,
@ -221,6 +225,32 @@ class ScaleIOConnector(base.BaseLinuxConnector):
{'volume_id': volume_id}) {'volume_id': volume_id})
return volume_id return volume_id
def _get_connector_password(self, config_group):
LOG.info("Get ScaleIO connector password from configuration file")
if not os.path.isfile(CONNECTOR_CONF_PATH):
msg = ("ScaleIO connector configuration file "
"is not found in path %s." % CONNECTOR_CONF_PATH)
raise exception.BrickException(message=msg)
try:
(out, err) = self._execute(*self.GET_PASSWORD_CMD,
run_as_root=True,
root_helper=self._root_helper)
conf = configparser.ConfigParser()
conf.readfp(six.StringIO(out))
return conf[config_group]["san_password"]
except putils.ProcessExecutionError as e:
msg = _("Error reading ScaleIO connector "
"configuration file: %s") % e.stderr
LOG.error(msg)
raise exception.BrickException(message=msg)
except Exception as e:
msg = _("Error getting ScaleIO connector password from "
"configuration file: %s") % e
LOG.error(msg)
raise exception.BrickException(message=msg)
def _check_response(self, response, request, is_get_request=True, def _check_response(self, response, request, is_get_request=True,
params=None): params=None):
if response.status_code == 401 or response.status_code == 403: if response.status_code == 401 or response.status_code == 403:
@ -269,8 +299,9 @@ 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'],
)
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

@ -47,8 +47,7 @@ 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',
'iopsLimit': None, 'iopsLimit': None,
'bandwidthLimit': None 'bandwidthLimit': None
} }
@ -84,6 +83,10 @@ class ScaleIOConnectorTestCase(test_connector.ConnectorTestCase):
self.mock_object(os, 'listdir', self.mock_object(os, 'listdir',
return_value=["emc-vol-{}".format(self.vol['id'])]) return_value=["emc-vol-{}".format(self.vol['id'])])
self.get_password_mock = self.mock_object(scaleio.ScaleIOConnector,
'_get_connector_password',
return_value='fake_password')
# The actual ScaleIO connector # The actual ScaleIO connector
self.connector = scaleio.ScaleIOConnector( self.connector = scaleio.ScaleIOConnector(
'sudo', execute=self.fake_execute) 'sudo', execute=self.fake_execute)
@ -170,6 +173,7 @@ class ScaleIOConnectorTestCase(test_connector.ConnectorTestCase):
def test_connect_volume(self): def test_connect_volume(self):
"""Successful connect to volume""" """Successful connect to volume"""
self.connector.connect_volume(self.fake_connection_properties) self.connector.connect_volume(self.fake_connection_properties)
self.get_password_mock.assert_called_once()
def test_connect_with_bandwidth_limit(self): def test_connect_with_bandwidth_limit(self):
"""Successful connect to volume with bandwidth limit""" """Successful connect to volume with bandwidth limit"""