Don't expose user credentials
When --test-accounts is used, don't print any user credentials to a tempest.conf file. Depends-On: https://review.openstack.org/#/c/570822/ Change-Id: Ic7977ed9e0e03d04aca446407b22a9a73c2dca98
This commit is contained in:
parent
bc17fffac7
commit
ed5163e729
@ -27,6 +27,25 @@ DEFAULT_IMAGE = ("http://download.cirros-cloud.net/0.3.5/"
|
|||||||
"cirros-0.3.5-x86_64-disk.img")
|
"cirros-0.3.5-x86_64-disk.img")
|
||||||
DEFAULT_IMAGE_FORMAT = 'qcow2'
|
DEFAULT_IMAGE_FORMAT = 'qcow2'
|
||||||
|
|
||||||
|
# The dict holds the credentials, which are not supposed to be printed
|
||||||
|
# to a tempest.conf when --test-accounts CLI parameter is used.
|
||||||
|
ALL_CREDENTIALS_KEYS = {
|
||||||
|
"auth.admin_username": [],
|
||||||
|
"auth.admin_password": [],
|
||||||
|
"auth.admin_project_name": [],
|
||||||
|
"auth.admin_domain_name": [],
|
||||||
|
"identity.username": [],
|
||||||
|
"identity.password": [],
|
||||||
|
"identity.tenant_name": [],
|
||||||
|
"identity.alt_username": [],
|
||||||
|
"identity.alt_password": [],
|
||||||
|
"identity.alt_tenant_name": [],
|
||||||
|
"identity.admin_username": [],
|
||||||
|
"identity.admin_password": [],
|
||||||
|
"identity.admin_tenant_name": [],
|
||||||
|
"identity.admin_domain_name": [],
|
||||||
|
}
|
||||||
|
|
||||||
# services and their codenames
|
# services and their codenames
|
||||||
SERVICE_NAMES = {
|
SERVICE_NAMES = {
|
||||||
'baremetal': 'ironic',
|
'baremetal': 'ironic',
|
||||||
|
@ -359,7 +359,8 @@ def config_tempest(**kwargs):
|
|||||||
remove = parse_values_to_remove(kwargs.get('remove', []))
|
remove = parse_values_to_remove(kwargs.get('remove', []))
|
||||||
set_logging(kwargs.get('debug', False), kwargs.get('verbose', False))
|
set_logging(kwargs.get('debug', False), kwargs.get('verbose', False))
|
||||||
|
|
||||||
conf = tempest_conf.TempestConf()
|
write_credentials = kwargs.get('test_accounts') is None
|
||||||
|
conf = tempest_conf.TempestConf(write_credentials=write_credentials)
|
||||||
set_options(conf, kwargs.get('deployer_input'),
|
set_options(conf, kwargs.get('deployer_input'),
|
||||||
kwargs.get('non_admin', False),
|
kwargs.get('non_admin', False),
|
||||||
kwargs.get('overrides', []), kwargs.get('test_accounts'),
|
kwargs.get('overrides', []), kwargs.get('test_accounts'),
|
||||||
@ -403,9 +404,7 @@ def config_tempest(**kwargs):
|
|||||||
LOG.info("Removing configuration: %s", str(remove))
|
LOG.info("Removing configuration: %s", str(remove))
|
||||||
conf.remove_values(remove)
|
conf.remove_values(remove)
|
||||||
out_path = kwargs.get('out', 'etc/tempest.conf')
|
out_path = kwargs.get('out', 'etc/tempest.conf')
|
||||||
LOG.info("Creating configuration file %s", os.path.abspath(out_path))
|
conf.write(out_path)
|
||||||
with open(out_path, 'w') as f:
|
|
||||||
conf.write(f)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from constants import LOG
|
import constants as C
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
import tempest.config
|
import tempest.config
|
||||||
|
|
||||||
@ -31,6 +32,10 @@ class TempestConf(ConfigParser.SafeConfigParser):
|
|||||||
|
|
||||||
CONF = tempest.config.TempestConfigPrivate(parse_conf=False)
|
CONF = tempest.config.TempestConfigPrivate(parse_conf=False)
|
||||||
|
|
||||||
|
def __init__(self, write_credentials=True, **kwargs):
|
||||||
|
self.write_credentials = write_credentials
|
||||||
|
ConfigParser.SafeConfigParser.__init__(self, **kwargs)
|
||||||
|
|
||||||
def get_bool_value(self, value):
|
def get_bool_value(self, value):
|
||||||
"""Returns boolean value of the string value given.
|
"""Returns boolean value of the string value given.
|
||||||
|
|
||||||
@ -63,7 +68,8 @@ class TempestConf(ConfigParser.SafeConfigParser):
|
|||||||
else:
|
else:
|
||||||
return self.CONF.get(section).get(key)
|
return self.CONF.get(section).get(key)
|
||||||
except cfg.NoSuchOptError:
|
except cfg.NoSuchOptError:
|
||||||
LOG.warning("Option %s is not defined in %s section", key, section)
|
C.LOG.warning("Option %s is not defined in %s section",
|
||||||
|
key, section)
|
||||||
|
|
||||||
def set(self, section, key, value, priority=False):
|
def set(self, section, key, value, priority=False):
|
||||||
"""Set value in configuration, similar to `SafeConfigParser.set`
|
"""Set value in configuration, similar to `SafeConfigParser.set`
|
||||||
@ -88,16 +94,25 @@ class TempestConf(ConfigParser.SafeConfigParser):
|
|||||||
if not self.has_section(section) and section.lower() != "default":
|
if not self.has_section(section) and section.lower() != "default":
|
||||||
self.add_section(section)
|
self.add_section(section)
|
||||||
if not priority and (section, key) in self.priority_sectionkeys:
|
if not priority and (section, key) in self.priority_sectionkeys:
|
||||||
LOG.debug("Option '[%s] %s = %s' was defined by user, NOT"
|
C.LOG.debug("Option '[%s] %s = %s' was defined by user, NOT"
|
||||||
" overwriting into value '%s'", section, key,
|
" overwriting into value '%s'", section, key,
|
||||||
self.get(section, key), value)
|
self.get(section, key), value)
|
||||||
return False
|
return False
|
||||||
if priority:
|
if priority:
|
||||||
self.priority_sectionkeys.add((section, key))
|
self.priority_sectionkeys.add((section, key))
|
||||||
LOG.debug("Setting [%s] %s = %s", section, key, value)
|
C.LOG.debug("Setting [%s] %s = %s", section, key, value)
|
||||||
ConfigParser.SafeConfigParser.set(self, section, key, value)
|
ConfigParser.SafeConfigParser.set(self, section, key, value)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def write(self, out_path):
|
||||||
|
C.LOG.info("Creating configuration file %s", os.path.abspath(out_path))
|
||||||
|
if not self.write_credentials:
|
||||||
|
C.LOG.info("Credentials will not be printed to a tempest.conf, "
|
||||||
|
"writing credentials is disabled.")
|
||||||
|
self.remove_values(C.ALL_CREDENTIALS_KEYS)
|
||||||
|
with open(out_path, 'w') as f:
|
||||||
|
ConfigParser.SafeConfigParser.write(self, f)
|
||||||
|
|
||||||
def remove_values(self, to_remove):
|
def remove_values(self, to_remove):
|
||||||
"""Remove values from configuration file specified in arguments.
|
"""Remove values from configuration file specified in arguments.
|
||||||
|
|
||||||
@ -125,7 +140,7 @@ class TempestConf(ConfigParser.SafeConfigParser):
|
|||||||
self.set(section, key, ",".join(conf_values))
|
self.set(section, key, ",".join(conf_values))
|
||||||
except ConfigParser.NoOptionError:
|
except ConfigParser.NoOptionError:
|
||||||
# only inform a user, option specified by him doesn't exist
|
# only inform a user, option specified by him doesn't exist
|
||||||
LOG.error(sys.exc_info()[1])
|
C.LOG.error(sys.exc_info()[1])
|
||||||
except ConfigParser.NoSectionError:
|
except ConfigParser.NoSectionError:
|
||||||
# only inform a user, section specified by him doesn't exist
|
# only inform a user, section specified by him doesn't exist
|
||||||
LOG.error(sys.exc_info()[1])
|
C.LOG.error(sys.exc_info()[1])
|
||||||
|
@ -102,7 +102,7 @@ class TestTempestConf(BaseConfigTempestTest):
|
|||||||
else:
|
else:
|
||||||
self.assertTrue(ext in conf_exts)
|
self.assertTrue(ext in conf_exts)
|
||||||
|
|
||||||
@mock.patch('config_tempest.tempest_conf.LOG')
|
@mock.patch('config_tempest.tempest_conf.C.LOG')
|
||||||
def test_remove_not_defined_values(self, mock_logging):
|
def test_remove_not_defined_values(self, mock_logging):
|
||||||
self.conf.remove_values({"notExistSection.key": []})
|
self.conf.remove_values({"notExistSection.key": []})
|
||||||
# check if LOG.error was called
|
# check if LOG.error was called
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
When --test-accounts parameter (specifying a path to a accounts.yaml file)
|
||||||
|
is used, don't write any user credentials to tempest.conf.
|
||||||
|
This will make it easier for users who run tempest tests with accounts.yaml
|
||||||
|
file and want to share their tempest.conf without exposing their credentials.
|
Loading…
Reference in New Issue
Block a user