Simplify Fetching the passwords from Mistral

This patch removes some of the indirection, deception and complexity in
tripleoclients password handling. At the end of the Newton cycle the
password generation was moved to Mistral. tripleoclient was updated, but
some methods got left behind in the process.

Before this patch, we had one utils function, that called another, that
called a workflow wrapper. The tests then embraced this oportunity and
mocked at different levels of abstraction, some of the tests even mocked
it out in mutliple places to be safe.

This patch replces that with a small function in overcloud_deploy. Once
the post-deploy steps are removed, there will be less of a need for the
password generation and it can hopefully be deprecated with that code.

Change-Id: Icf77dae225caa716c35ce5ded83f7356c958d695
This commit is contained in:
Dougal Matthews 2016-12-12 13:26:07 +00:00
parent c01936666e
commit 07b7449ffa
6 changed files with 50 additions and 79 deletions

View File

@ -36,7 +36,6 @@ class FakeClientManager(object):
def __init__(self):
self.identity = None
self.workflow_engine = None
self.tripleoclient = None
self.auth_ref = None
self.tripleoclient = FakeClientWrapper()
self.workflow_engine = mock.Mock()
@ -58,5 +57,8 @@ class FakeWebSocket(object):
class FakeClientWrapper(object):
def messaging_websocket(self, queue_name):
return FakeWebSocket()
def __init__(self):
self.ws = FakeWebSocket()
def messaging_websocket(self, queue_name="tripleo"):
return self.ws

View File

@ -110,7 +110,7 @@ class FakeClientWrapper(object):
self._instance = mock.Mock()
self.object_store = FakeObjectClient()
def messaging_websocket(self, queue_name):
def messaging_websocket(self, queue_name="tripleo"):
return fakes.FakeWebSocket()

View File

@ -67,8 +67,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'_deploy_postconfig', autospec=True)
@mock.patch('tripleoclient.utils.create_tempest_deployer_input',
autospec=True)
@mock.patch('tripleoclient.utils.generate_overcloud_passwords',
autospec=True)
@mock.patch('tripleoclient.utils.write_overcloudrc', autospec=True)
@mock.patch('os_cloud_config.keystone.setup_endpoints', autospec=True)
@mock.patch('time.sleep', return_value=None)
@ -90,7 +88,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_remove_known_hosts, mock_keystone_initialize,
mock_sleep, mock_setup_endpoints,
mock_write_overcloudrc,
mock_generate_overcloud_passwords,
mock_create_tempest_deployer_input,
mock_deploy_postconfig,
mock_create_parameters_env,
@ -106,8 +103,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_uuid1.return_value = "uuid"
mock_time.return_value = 123456789
mock_generate_overcloud_passwords.return_value = {}
clients = self.app.client_manager
orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
@ -186,8 +181,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'_create_parameters_env', autospec=True)
@mock.patch('tripleoclient.utils.create_tempest_deployer_input',
autospec=True)
@mock.patch('tripleoclient.utils.generate_overcloud_passwords',
autospec=True)
@mock.patch('tripleoclient.utils.write_overcloudrc', autospec=True)
@mock.patch('os_cloud_config.utils.clients.get_nova_bm_client',
autospec=True)
@ -216,7 +209,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_sleep, mock_setup_endpoints,
mock_get_keystone_client, mock_get_nova_bm_client,
mock_write_overcloudrc,
mock_generate_overcloud_passwords,
mock_create_tempest_deployer_input,
mock_create_parameters_env, mock_validate_args,
mock_breakpoints_cleanup, mock_tarball,
@ -232,8 +224,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_uuid1.return_value = "uuid"
mock_time.return_value = 123456789
mock_generate_overcloud_passwords.return_value = {}
clients = self.app.client_manager
orchestration_client = clients.orchestration
mock_stack = fakes.create_tht_stack()
@ -320,8 +310,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'_deploy_postconfig', autospec=True)
@mock.patch('tripleoclient.utils.create_tempest_deployer_input',
autospec=True)
@mock.patch('tripleoclient.utils.generate_overcloud_passwords',
autospec=True)
@mock.patch('tripleoclient.utils.write_overcloudrc', autospec=True)
@mock.patch('os_cloud_config.keystone.setup_endpoints', autospec=True)
@mock.patch('time.sleep', return_value=None)
@ -342,7 +330,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_keystone_initialize,
mock_sleep, mock_setup_endpoints,
mock_write_overcloudrc,
mock_generate_overcloud_passwords,
mock_create_tempest_deployer_input,
mock_deploy_postconfig,
mock_breakpoints_cleanup,
@ -353,8 +340,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
('templates', '/home/stack/tripleo-heat-templates'),
]
mock_generate_overcloud_passwords.return_value = {}
clients = self.app.client_manager
orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
@ -652,8 +637,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'_deploy_postconfig', autospec=True)
@mock.patch('tripleoclient.utils.create_tempest_deployer_input',
autospec=True)
@mock.patch('tripleoclient.utils.generate_overcloud_passwords',
autospec=True)
@mock.patch('tripleoclient.utils.write_overcloudrc', autospec=True)
@mock.patch('os_cloud_config.keystone.setup_endpoints', autospec=True)
@mock.patch('time.sleep', return_value=None)
@ -679,7 +662,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_keystone_initialize,
mock_sleep, mock_setup_endpoints,
mock_write_overcloudrc,
mock_generate_overcloud_passwords,
mock_create_tempest_deployer_input,
mock_deploy_postconfig,
mock_breakpoints_cleanup,
@ -701,7 +683,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_tmpdir.return_value = None
mock_tmpdir.return_value = '/tmp/tht'
mock_process_env.return_value = [{}, fakes.create_env()]
mock_generate_overcloud_passwords.return_value = {}
mock_get_template_contents.return_value = [{}, "template"]
wait_for_stack_ready_mock.return_value = True
@ -916,12 +897,17 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_create_tempest_deployer_input.assert_called_with()
@mock.patch('tripleoclient.utils.get_password')
@mock.patch('tripleoclient.workflows.parameters.get_overcloud_passwords')
@mock.patch('tripleoclient.constants.SERVICE_LIST',
{'nova': {'password_field': 'OVERCLOUD_NOVA_PASSWORD'}})
{'nova': {'password_field': 'NovaPassword'}})
@mock.patch('os_cloud_config.keystone.initialize')
@mock.patch('os_cloud_config.utils.clients.get_keystone_client')
def test_keystone_init(self, mock_gkc, mock_init, mock_gp):
mock_gp.return_value = {
"AdminPassword": "password",
"AdminToken": "token",
"NovaPassword": "nova-password"
}
mock_ksc = mock.Mock()
mock_gkc.return_value = mock_ksc
mock_ksc.services.find.return_value = True
@ -933,13 +919,18 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.assertFalse(mock_init.called)
@mock.patch('tripleoclient.utils.get_password')
@mock.patch('tripleoclient.workflows.parameters.get_overcloud_passwords')
@mock.patch('tripleoclient.constants.SERVICE_LIST',
{'nova': {'password_field': 'OVERCLOUD_NOVA_PASSWORD'}})
{'nova': {'password_field': 'NovaPassword'}})
@mock.patch('os_cloud_config.keystone.setup_endpoints')
@mock.patch('os_cloud_config.keystone.initialize')
@mock.patch('os_cloud_config.utils.clients.get_keystone_client')
def test_keystone_init_occ(self, mock_gkc, mock_init, mock_se, mock_gp):
mock_gp.return_value = {
"AdminPassword": "password",
"AdminToken": "token",
"NovaPassword": "nova-password"
}
mock_ksc = mock.Mock()
mock_gkc.return_value = mock_ksc
mock_ksc.services.find.side_effect = kscexc.NotFound()
@ -952,15 +943,20 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.assertTrue(mock_init.called)
@mock.patch('tripleoclient.utils.get_password')
@mock.patch('tripleoclient.workflows.parameters.get_overcloud_passwords')
@mock.patch('tripleoclient.constants.SERVICE_LIST',
{'nova': {'password_field': 'OVERCLOUD_NOVA_PASSWORD'},
'unexistent': {'password_field': 'OVERCLOUD_NOVA_PASSWORD'}})
{'nova': {'password_field': 'NovaPassword'},
'unexistent': {'password_field': 'NovaPassword'}})
@mock.patch('os_cloud_config.keystone.setup_endpoints')
@mock.patch('os_cloud_config.keystone.initialize')
@mock.patch('os_cloud_config.utils.clients.get_keystone_client')
def test_keystone_init_occ_w_entry_not_in_endpoint_map(
self, mock_gkc, mock_init, mock_se, mock_gp):
mock_gp.return_value = {
"AdminPassword": "password",
"AdminToken": "token",
"NovaPassword": "nova-password"
}
mock_ksc = mock.Mock()
mock_gkc.return_value = mock_ksc
mock_ksc.services.find.side_effect = kscexc.NotFound()
@ -972,6 +968,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
self.cmd._keystone_init(ip, ip, args, stack)
self.assertTrue(mock_init.called)
self.assertEqual(mock_gp.call_count, 1)
@mock.patch('tripleoclient.utils.check_nodes_count')
@mock.patch('tripleoclient.utils.check_hypervisor_stats')
@ -1046,7 +1043,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
autospec=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_create_parameters_env')
@mock.patch('tripleoclient.utils.generate_overcloud_passwords')
@mock.patch('tripleoclient.utils.write_overcloudrc')
@mock.patch('heatclient.common.template_utils.'
'process_environment_and_files', autospec=True)
@ -1057,7 +1053,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_get_template_contents,
mock_process_env,
mock_write_overcloudrc,
mock_generate_overcloud_passwords,
mock_create_parameters_env,
mock_tarball):
@ -1074,8 +1069,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
workflow_client.action_executions.create.return_value = mock.MagicMock(
output='{"result":[]}')
mock_generate_overcloud_passwords.return_value = {}
def _custom_create_params_env(parameters):
parameter_defaults = {"parameter_defaults": parameters}
return parameter_defaults
@ -1103,7 +1096,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'_create_parameters_env')
@mock.patch('tripleoclient.utils.create_tempest_deployer_input',
autospec=True)
@mock.patch('tripleoclient.utils.generate_overcloud_passwords')
@mock.patch('tripleoclient.utils.write_overcloudrc')
@mock.patch('os_cloud_config.utils.clients.get_nova_bm_client',
autospec=True)
@ -1136,7 +1128,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_get_keystone_client,
mock_get_nova_bm_client,
mock_write_overcloudrc,
mock_generate_overcloud_passwords,
mock_create_tempest_deployer_input,
mock_create_parameters_env,
mock_validate_args,
@ -1155,8 +1146,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_uuid1.return_value = "uuid"
mock_time.return_value = 123456789
mock_generate_overcloud_passwords.return_value = {}
clients = self.app.client_manager
orchestration_client = clients.orchestration
mock_stack = fakes.create_tht_stack()

View File

@ -25,7 +25,7 @@ class FakeClientWrapper(object):
self._instance = mock.Mock()
self.object_store = FakeObjectClient()
def messaging_websocket(self, queue_name):
def messaging_websocket(self, queue_name="tripleo"):
return fakes.FakeWebSocket()

View File

@ -25,7 +25,6 @@ import socket
import subprocess
import sys
import time
import uuid
import yaml
from heatclient.common import event_utils
@ -35,20 +34,6 @@ from osc_lib.i18n import _LI
from six.moves import configparser
from tripleoclient import exceptions
from tripleoclient.workflows import parameters
def generate_overcloud_passwords(clients, plan_name):
"""Retrieve passwords needed for the overcloud
This will retrieve the set of passwords required by the overcloud stored
in the deployment plan and accessible via a workflow.
"""
workflow_input = {
"container": plan_name,
"queue_name": str(uuid.uuid4()),
}
return parameters.get_overcloud_passwords(clients, **workflow_input)
def bracket_ipv6(address):
@ -363,20 +348,6 @@ def get_endpoint(key, stack):
return get_service_ips(stack).get(key + 'Vip')
__password_cache = None
def get_password(clients, plan_name, pass_name):
"""Retrieve a password by name, such as 'AdminPassword'.
Raises KeyError if password does not exist.
"""
global __password_cache
if __password_cache is None:
__password_cache = generate_overcloud_passwords(clients, plan_name)
return __password_cache[pass_name]
def get_stack(orchestration_client, stack_name):
"""Get the ID for the current deployed overcloud stack if it exists.

View File

@ -24,6 +24,7 @@ import shutil
import six
import tempfile
import time
import uuid
import yaml
from heatclient.common import template_utils
@ -53,6 +54,10 @@ class DeployOvercloud(command.Command):
predeploy_errors = 0
predeploy_warnings = 0
def __init__(self, *args, **kwargs):
self._password_cache = None
super(DeployOvercloud, self).__init__(*args, **kwargs)
def _update_parameters(self, args, network_client, stack):
parameters = {}
@ -464,6 +469,17 @@ class DeployOvercloud(command.Command):
def _is_tls_enabled(self, overcloud_endpoint):
return overcloud_endpoint.startswith('https')
def _get_password(self, stack_name, password_name):
# NOTE(d0ugal): This method is only used during the post-deploy config
# steps that are now deprecated. It should be removed when they are.
if self._password_cache is None:
self._password_cache = workflow_params.get_overcloud_passwords(
self.app.client_manager,
container=stack_name,
queue_name=str(uuid.uuid4()))
return self._password_cache[password_name]
def _keystone_init(self, overcloud_endpoint, overcloud_ip_or_fqdn,
parsed_args, stack):
keystone_admin_ip = utils.get_endpoint('KeystoneAdmin', stack)
@ -480,9 +496,7 @@ class DeployOvercloud(command.Command):
keystone_client = occ_clients.get_keystone_client(
'admin',
utils.get_password(self.app.client_manager,
stack.stack_name,
'AdminPassword'),
self._get_password(stack.stack_name, "AdminPassword"),
'admin',
overcloud_endpoint)
@ -524,13 +538,9 @@ class DeployOvercloud(command.Command):
# TODO(rbrady): check usages of get_password
keystone.initialize(
keystone_admin_ip,
utils.get_password(self.app.client_manager,
stack.stack_name,
'AdminToken'),
self._get_password(stack.stack_name, "AdminToken"),
'admin@example.com',
utils.get_password(self.app.client_manager,
stack.stack_name,
'AdminPassword'),
self._get_password(stack.stack_name, "AdminPassword"),
ssl=keystone_tls_host,
public=overcloud_ip_or_fqdn,
user=parsed_args.overcloud_ssh_user,
@ -580,8 +590,7 @@ class DeployOvercloud(command.Command):
service_data = {}
password_field = data.get('password_field')
if password_field:
service_data['password'] = utils.get_password(
self.app.client_manager,
service_data['password'] = self._get_password(
stack.stack_name,
password_field)