diff --git a/tripleoclient/exceptions.py b/tripleoclient/exceptions.py index d0767e468..345118b35 100644 --- a/tripleoclient/exceptions.py +++ b/tripleoclient/exceptions.py @@ -60,3 +60,7 @@ class StateTransitionFailed(Exception): class ProfileMatchingError(Exception): """Failed to validate or assign node profiles""" + + +class PasswordFileNotFound(Exception): + """Password file for the Heat stack not found in the current working dir""" diff --git a/tripleoclient/tests/test_utils.py b/tripleoclient/tests/test_utils.py index bbf4d85e7..00934b507 100644 --- a/tripleoclient/tests/test_utils.py +++ b/tripleoclient/tests/test_utils.py @@ -18,12 +18,12 @@ from uuid import uuid4 import mock import os.path import tempfile +from unittest import TestCase from tripleoclient import exceptions from tripleoclient.tests.v1.utils import ( generate_overcloud_passwords_mock) from tripleoclient import utils -from unittest import TestCase class TestPasswordsUtil(TestCase): @@ -36,7 +36,8 @@ class TestPasswordsUtil(TestCase): mock_open = mock.mock_open() with mock.patch('six.moves.builtins.open', mock_open): - passwords = utils.generate_overcloud_passwords() + passwords = utils.generate_overcloud_passwords( + create_password_file=True) self.assertEqual(sorted(mock_open().write.mock_calls), [ mock.call('NEUTRON_METADATA_PROXY_SHARED_SECRET=PASSWORD\n'), @@ -59,6 +60,14 @@ class TestPasswordsUtil(TestCase): self.assertEqual(len(passwords), 15) + def test_generate_passwords_update(self): + + mock_open = mock.mock_open() + + with mock.patch('six.moves.builtins.open', mock_open): + with self.assertRaises(exceptions.PasswordFileNotFound): + utils.generate_overcloud_passwords() + @mock.patch("os.path.isfile", return_value=True) @mock.patch("passlib.utils.generate_password", return_value="PASSWORD") diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index 2be21de79..6401e5fbb 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -19,6 +19,7 @@ import hashlib import json import logging import os +import os.path import passlib.utils as passutils import six import struct @@ -53,7 +54,8 @@ _PASSWORD_NAMES = ( ) -def generate_overcloud_passwords(output_file="tripleo-overcloud-passwords"): +def generate_overcloud_passwords(output_file="tripleo-overcloud-passwords", + create_password_file=False): """Create the passwords needed for the overcloud This will create the set of passwords required by the overcloud, store @@ -61,10 +63,17 @@ def generate_overcloud_passwords(output_file="tripleo-overcloud-passwords"): file already exists the existing passwords will be returned instead, """ + log = logging.getLogger(__name__ + ".generate_overcloud_passwords") + + log.debug("Using password file: {0}".format(os.path.abspath(output_file))) + passwords = {} if os.path.isfile(output_file): with open(output_file) as f: passwords = dict(line.split('=') for line in f.read().splitlines()) + elif not create_password_file: + raise exceptions.PasswordFileNotFound( + "The password file could not be found!") for name in _PASSWORD_NAMES: if not passwords.get(name): diff --git a/tripleoclient/v1/overcloud_deploy.py b/tripleoclient/v1/overcloud_deploy.py index f9ad8a9c7..697c4e098 100644 --- a/tripleoclient/v1/overcloud_deploy.py +++ b/tripleoclient/v1/overcloud_deploy.py @@ -51,7 +51,7 @@ class DeployOvercloud(command.Command): predeploy_errors = 0 predeploy_warnings = 0 - def set_overcloud_passwords(self, parameters, parsed_args): + def set_overcloud_passwords(self, stack_is_new, parameters): """Add passwords to the parameters dictionary :param parameters: A dictionary for the passwords to be added to @@ -61,7 +61,9 @@ class DeployOvercloud(command.Command): undercloud_ceilometer_snmpd_password = utils.get_config_value( "auth", "undercloud_ceilometer_snmpd_password") - passwords = utils.generate_overcloud_passwords() + passwords = utils.generate_overcloud_passwords( + create_password_file=stack_is_new) + ceilometer_pass = passwords['OVERCLOUD_CEILOMETER_PASSWORD'] ceilometer_secret = passwords['OVERCLOUD_CEILOMETER_SECRET'] parameters['AdminPassword'] = passwords['OVERCLOUD_ADMIN_PASSWORD'] @@ -90,11 +92,13 @@ class DeployOvercloud(command.Command): def _update_parameters(self, args, network_client, stack): parameters = constants.PARAMETERS.copy() - if stack is None: + stack_is_new = stack is None + + if stack_is_new: parameters.update(constants.NEW_STACK_PARAMETERS) self.log.debug("Generating overcloud passwords") - self.set_overcloud_passwords(parameters, args) + self.set_overcloud_passwords(stack_is_new, parameters) timestamp = int(time.time()) parameters['DeployIdentifier'] = timestamp @@ -131,7 +135,7 @@ class DeployOvercloud(command.Command): ('NeutronMechanismDrivers', 'neutron_mechanism_drivers') ) - if stack is None: + if stack_is_new: new_stack_args = ( ('NeutronNetworkType', 'neutron_network_type'), ('NeutronTunnelIdRanges', 'neutron_tunnel_id_ranges'), @@ -185,7 +189,7 @@ class DeployOvercloud(command.Command): if int(parameters.get('CephStorageCount', 0)) > 0: - if stack is None: + if stack_is_new: parameters.update({ 'CephClusterFSID': six.text_type(uuid.uuid1()), 'CephMonKey': utils.create_cephx_key(),