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
changes/49/570749/7
Martin Kopec 4 years ago
parent bc17fffac7
commit ed5163e729
  1. 19
      config_tempest/constants.py
  2. 7
      config_tempest/main.py
  3. 31
      config_tempest/tempest_conf.py
  4. 2
      config_tempest/tests/test_tempest_conf.py
  5. 7
      releasenotes/notes/Do-not-expose-user-credentials-1ffba4d72798b5c9.yaml

@ -27,6 +27,25 @@ DEFAULT_IMAGE = ("http://download.cirros-cloud.net/0.3.5/"
"cirros-0.3.5-x86_64-disk.img")
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
SERVICE_NAMES = {
'baremetal': 'ironic',

@ -359,7 +359,8 @@ def config_tempest(**kwargs):
remove = parse_values_to_remove(kwargs.get('remove', []))
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'),
kwargs.get('non_admin', False),
kwargs.get('overrides', []), kwargs.get('test_accounts'),
@ -403,9 +404,7 @@ def config_tempest(**kwargs):
LOG.info("Removing configuration: %s", str(remove))
conf.remove_values(remove)
out_path = kwargs.get('out', 'etc/tempest.conf')
LOG.info("Creating configuration file %s", os.path.abspath(out_path))
with open(out_path, 'w') as f:
conf.write(f)
conf.write(out_path)
def main():

@ -14,9 +14,10 @@
# under the License.
import ConfigParser
import os
import sys
from constants import LOG
import constants as C
from oslo_config import cfg
import tempest.config
@ -31,6 +32,10 @@ class TempestConf(ConfigParser.SafeConfigParser):
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):
"""Returns boolean value of the string value given.
@ -63,7 +68,8 @@ class TempestConf(ConfigParser.SafeConfigParser):
else:
return self.CONF.get(section).get(key)
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):
"""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":
self.add_section(section)
if not priority and (section, key) in self.priority_sectionkeys:
LOG.debug("Option '[%s] %s = %s' was defined by user, NOT"
" overwriting into value '%s'", section, key,
self.get(section, key), value)
C.LOG.debug("Option '[%s] %s = %s' was defined by user, NOT"
" overwriting into value '%s'", section, key,
self.get(section, key), value)
return False
if priority:
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)
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):
"""Remove values from configuration file specified in arguments.
@ -125,7 +140,7 @@ class TempestConf(ConfigParser.SafeConfigParser):
self.set(section, key, ",".join(conf_values))
except ConfigParser.NoOptionError:
# 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:
# 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:
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):
self.conf.remove_values({"notExistSection.key": []})
# 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…
Cancel
Save