Don't expose credentials

Don't expose credentials to tempest.conf when
--create-test-accounts is used.

When generating tempest.conf with demo creds, use
--create-accounts-file argument so that the argument
is tested in the gates.
The argument is used only on Devstack.

Tempest concurrency of devstack demo job is reduced to 1
because the minimal accounts file is used.

Change-Id: Id5c90810666d783cf3939086ef27149ef53277f8
Story: 2003016
Task: 23036
This commit is contained in:
Martin Kopec 2018-07-18 08:25:04 +00:00
parent 947946419c
commit c6ec0bdc79
9 changed files with 39 additions and 43 deletions

View File

@ -42,7 +42,7 @@
zuul_copy_output: zuul_copy_output:
'{{ devstack_base_dir }}/tempest/tempest.log': 'logs' '{{ devstack_base_dir }}/tempest/tempest.log': 'logs'
'{{ devstack_base_dir }}/tempest/etc/tempest.conf': 'logs' '{{ devstack_base_dir }}/tempest/etc/tempest.conf': 'logs'
'/etc/openstack/accounts.yaml': 'logs' '{{ zuul.project.src_dir }}/etc/accounts.yaml': 'logs'
irrelevant-files: irrelevant-files:
- config_tempest/tests/.*$ - config_tempest/tests/.*$
- ^doc/.*$ - ^doc/.*$
@ -65,6 +65,7 @@
- zuul: openstack/tempest - zuul: openstack/tempest
- zuul: openstack-dev/devstack - zuul: openstack-dev/devstack
vars: vars:
tempest_concurrency: 2
scenario: scenario000 scenario: scenario000
zuul_copy_output: zuul_copy_output:
'/opt/stack/tempest/etc/tempest.conf': 'logs' '/opt/stack/tempest/etc/tempest.conf': 'logs'
@ -85,6 +86,7 @@
vars: vars:
user: admin user: admin
cloud_user: devstack-admin cloud_user: devstack-admin
tempest_concurrency: 2
- job: - job:
name: python-tempestconf-tempest-devstack-demo name: python-tempestconf-tempest-devstack-demo
@ -97,6 +99,9 @@
cloud_user: devstack cloud_user: devstack
test_demo: True test_demo: True
cloud_admin: devstack-admin cloud_admin: devstack-admin
# concurrency is reduced in this job, because a minimal accounts
# file is used
tempest_concurrency: 1
- job: - job:
name: python-tempestconf-tempest-packstack-admin name: python-tempestconf-tempest-packstack-admin

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import os
import yaml import yaml
@ -28,7 +27,6 @@ def create_accounts_file(create, accounts_path, conf):
conf.get(section, prefix + 'username'), conf.get(section, prefix + 'username'),
conf.get(section, prefix + 'password'), conf.get(section, prefix + 'password'),
conf.get(section, prefix + 'project_name')) conf.get(section, prefix + 'project_name'))
conf.set("auth", "test_accounts_file", os.path.abspath(accounts_path))
def write_accounts_file(path, username, password, project_name): def write_accounts_file(path, username, password, project_name):

View File

@ -140,7 +140,7 @@ def read_deployer_input(deployer_input_file, conf):
def set_options(conf, deployer_input, non_admin, image_path, overrides=[], def set_options(conf, deployer_input, non_admin, image_path, overrides=[],
test_accounts=None, cloud_creds=None, accounts_path=None, cloud_creds=None,
no_default_deployer=False): no_default_deployer=False):
"""Set options in conf provided by different source. """Set options in conf provided by different source.
@ -159,8 +159,8 @@ def set_options(conf, deployer_input, non_admin, image_path, overrides=[],
:type image_path: string :type image_path: string
:param overrides: list of tuples: [(section, key, value)] :param overrides: list of tuples: [(section, key, value)]
:type overrides: list :type overrides: list
:param test_accounts: Path to the accounts.yaml file :param accounts_path: A path where accounts.yaml is or will be created.
:type test_accounts: string :type accounts_path: string
:param cloud_creds: Cloud credentials from client's config :param cloud_creds: Cloud credentials from client's config
:type cloud_creds: dict :type cloud_creds: dict
""" """
@ -190,11 +190,11 @@ def set_options(conf, deployer_input, non_admin, image_path, overrides=[],
if cloud_creds: if cloud_creds:
set_cloud_config_values(non_admin, cloud_creds, conf) set_cloud_config_values(non_admin, cloud_creds, conf)
if test_accounts: if accounts_path:
# new way for running using accounts file # new way for running using accounts file
conf.set("auth", "use_dynamic_credentials", "False") conf.set("auth", "use_dynamic_credentials", "False")
conf.set("auth", "test_accounts_file", conf.set("auth", "test_accounts_file",
os.path.abspath(test_accounts)) os.path.abspath(accounts_path))
# set overrides - values specified in CLI # set overrides - values specified in CLI
for section, key, value in overrides: for section, key, value in overrides:
@ -274,6 +274,9 @@ def parse_arguments():
raise Exception("Options '--create' and '--non-admin' cannot be used" raise Exception("Options '--create' and '--non-admin' cannot be used"
" together, since creating" " resources requires" " together, since creating" " resources requires"
" admin rights") " admin rights")
if args.test_accounts and args.create_accounts_file:
raise Exception("Options '--test-accounts' and "
"'--create-accounts-file' can't be used together.")
args.overrides = parse_overrides(args.overrides) args.overrides = parse_overrides(args.overrides)
return args return args
@ -388,12 +391,15 @@ 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))
write_credentials = kwargs.get('test_accounts') is None accounts_path = kwargs.get('test_accounts')
conf = TempestConf(write_credentials=write_credentials) if kwargs.get('create_accounts_file') is not None:
accounts_path = kwargs.get('create_accounts_file')
conf = TempestConf(write_credentials=accounts_path is None)
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('image_path', C.DEFAULT_IMAGE), kwargs.get('image_path', C.DEFAULT_IMAGE),
kwargs.get('overrides', []), kwargs.get('test_accounts'), kwargs.get('overrides', []),
accounts_path,
kwargs.get('cloud_creds')) kwargs.get('cloud_creds'))
credentials = Credentials(conf, not kwargs.get('non_admin', False)) credentials = Credentials(conf, not kwargs.get('non_admin', False))
@ -421,13 +427,11 @@ def config_tempest(**kwargs):
services.set_supported_api_versions() services.set_supported_api_versions()
services.set_service_extensions() services.set_service_extensions()
if kwargs.get('test_accounts') is None: if accounts_path is not None and kwargs.get('test_accounts') is None:
accounts_path = kwargs.get('create_accounts_file') LOG.info("Creating an accounts.yaml file in: %s", accounts_path)
if accounts_path is not None: accounts.create_accounts_file(kwargs.get('create', False),
LOG.info("Creating an accounts.yaml file in: %s", accounts_path) accounts_path,
accounts.create_accounts_file(kwargs.get('create', False), conf)
accounts_path,
conf)
# remove all unwanted values if were specified # remove all unwanted values if were specified
if remove != {}: if remove != {}:

View File

@ -17,6 +17,7 @@ import mock
import os import os
from config_tempest import accounts from config_tempest import accounts
from config_tempest import main
from config_tempest.tests.base import BaseConfigTempestTest from config_tempest.tests.base import BaseConfigTempestTest
@ -33,6 +34,7 @@ class TestAccounts(BaseConfigTempestTest):
@mock.patch('config_tempest.accounts.write_accounts_file') @mock.patch('config_tempest.accounts.write_accounts_file')
def test_create_accounts_file(self, mock_write): def test_create_accounts_file(self, mock_write):
path = "./etc/accounts.yaml" path = "./etc/accounts.yaml"
main.set_options(self.conf, None, False, "", accounts_path=path)
# credentials under auth section # credentials under auth section
accounts.create_accounts_file(True, path, self.conf) accounts.create_accounts_file(True, path, self.conf)
mock_write.assert_called_with(path, "admin", "adminPass", mock_write.assert_called_with(path, "admin", "adminPass",

View File

@ -33,34 +33,13 @@
include_role: include_role:
name: generate-tempestconf-file name: generate-tempestconf-file
vars: vars:
create_accounts_file: True
source_credentials_commands: "export HOST_IP={{ ansible_default_ipv4.address }}; source {{ devstack_base_dir }}/devstack/openrc {{ user }} {{ user }}; {{ set_auth_url }}" source_credentials_commands: "export HOST_IP={{ ansible_default_ipv4.address }}; source {{ devstack_base_dir }}/devstack/openrc {{ user }} {{ user }}; {{ set_auth_url }}"
aditional_tempestconf_params: "auth.tempest_roles Member" aditional_tempestconf_params: "auth.tempest_roles Member"
- name: Generate tempest configuration file based on cloud credentials - name: Generate tempest configuration file based on cloud credentials
include_role: include_role:
name: generate-tempestconf-file-cloud name: generate-tempestconf-file-cloud
# Let's create tempest.conf with admin permissions needed for
# tempest accounts file generation
- name: Generate configuration file for Tempest as admin
include_role:
name: generate-tempestconf-file
vars:
aditional_tempestconf_params: "auth.tempest_roles Member object-storage.operator_role Member"
output_path: "/etc/openstack/tempest_admin.conf"
source_credentials_commands: "export HOST_IP={{ ansible_default_ipv4.address }}; source {{ devstack_base_dir }}/devstack/openrc admin admin; {{ set_auth_url }}"
test_demo_user: False
user: admin
when: test_demo is defined
- name: Generate accounts file for Tempest
include_role:
name: generate-accounts-file
vars:
accounts_file_destination: "/etc/openstack"
source_credentials_commands: "export HOST_IP={{ ansible_default_ipv4.address }}; source {{ devstack_base_dir }}/devstack/openrc admin admin; {{ set_auth_url }}"
tempest_config_file: "/etc/openstack/tempest_admin.conf"
when: test_demo is defined
# run-tempest role is inherited from openstack/tempest project # run-tempest role is inherited from openstack/tempest project
- name: Run Tempest Tests - name: Run Tempest Tests
include_role: include_role:
name: run-tempest name: run-tempest
vars:
tempest_concurrency: 2

View File

@ -67,5 +67,3 @@
- name: Run Tempest Tests - name: Run Tempest Tests
include_role: include_role:
name: run-tempest name: run-tempest
vars:
tempest_concurrency: 2

View File

@ -101,3 +101,10 @@ is then copied to tempest directory.
test_accounts_file option in auth section of tempest.conf, when test_accounts_file option in auth section of tempest.conf, when
test_demo_user is set to True. test_demo_user is set to True.
.. zuul:rolevar:: create_accounts_file
:type: Boolean
:default: False
If True and demo user is used a minimal accounts.yaml file will be generated
and used during tempest testing.

View File

@ -5,3 +5,4 @@ url_cirros_image: "http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-di
aditional_tempestconf_params: "" aditional_tempestconf_params: ""
test_demo_user: False test_demo_user: False
test_accounts_file: /etc/openstack/accounts.yaml test_accounts_file: /etc/openstack/accounts.yaml
create_accounts_file: False

View File

@ -12,8 +12,10 @@ discover-tempest-config \
{% else %} {% else %}
--non-admin \ --non-admin \
{% endif %} {% endif %}
{% if test_demo_user %} {% if test_demo_user and not create_accounts_file %}
--test-accounts {{ test_accounts_file }} \ --test-accounts {{ test_accounts_file }} \
{% elif test_demo_user and create_accounts_file %}
--create-accounts-file ./etc/accounts.yaml \
{% endif %} {% endif %}
identity.uri $OS_AUTH_URL \ identity.uri $OS_AUTH_URL \
auth.admin_password $OS_PASSWORD \ auth.admin_password $OS_PASSWORD \