From be3bd48214e6719db9bd364f020ea5b652b9a536 Mon Sep 17 00:00:00 2001 From: Carlos Camacho Date: Tue, 7 Nov 2017 10:43:59 +0000 Subject: [PATCH] Load undercloud DB password to a mistral environment This patch adds a new variable to the mistral environment 'tripleo.undercloud-config' allowing to retrieve the root password for the MySQL databases. Now this variable can be accessed from any Mistral workflow. Also, this patch adds the ability of checking if the variables are not loaded properly due to an upgrade, in that case we update the Mistral environment to have all the variables in place. Change-Id: I822c3d96b5805909656d8e92e963b851f3bd77de --- instack_undercloud/tests/test_undercloud.py | 39 ++++++++++++----- instack_undercloud/undercloud.py | 46 +++++++++++++++++---- 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/instack_undercloud/tests/test_undercloud.py b/instack_undercloud/tests/test_undercloud.py index 991d8d7e0..c44d1248a 100644 --- a/instack_undercloud/tests/test_undercloud.py +++ b/instack_undercloud/tests/test_undercloud.py @@ -949,26 +949,45 @@ class TestPostConfig(base.BaseTestCase): ks_exceptions.NotFound) env = { + "UNDERCLOUD_DB_PASSWORD": "root-db-pass", "UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD": "snmpd-pass" } - json_string = '{"undercloud_ceilometer_snmpd_password": "snmpd-pass"}' - undercloud._create_mistral_config_environment(env, mock_mistral) + json_string = { + "undercloud_db_password": "root-db-pass", + "undercloud_ceilometer_snmpd_password": "snmpd-pass" + } + + undercloud._create_mistral_config_environment(json.loads( + json.dumps(env, sort_keys=True)), mock_mistral) mock_mistral.environments.create.assert_called_once_with( - name="tripleo.undercloud-config", - variables=json_string) + name='tripleo.undercloud-config', + description='Undercloud configuration parameters', + variables=json.dumps(json_string, sort_keys=True)) def test_create_config_environment_existing(self): mock_mistral = mock.Mock() - environment = collections.namedtuple('environment', ['name']) - mock_mistral.environments.get.return_value = environment( - name='overcloud') - env = { - "UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD": "snmpd-pass" + environment = collections.namedtuple('environment', + ['name', 'variables']) + + json_string = { + "undercloud_db_password": "root-db-pass", + "undercloud_ceilometer_snmpd_password": "snmpd-pass" } - undercloud._create_mistral_config_environment(env, mock_mistral) + mock_mistral.environments.get.return_value = environment( + name='tripleo.undercloud-config', + variables=json.loads(json.dumps(json_string, sort_keys=True)) + ) + + env = { + "UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD": "snmpd-pass", + "UNDERCLOUD_DB_PASSWORD": "root-db-pass" + } + + undercloud._create_mistral_config_environment(json.loads( + json.dumps(env, sort_keys=True)), mock_mistral) mock_mistral.executions.create.assert_not_called() def test_prepare_ssh_environment(self): diff --git a/instack_undercloud/undercloud.py b/instack_undercloud/undercloud.py index b6a4f882e..89c484a81 100644 --- a/instack_undercloud/undercloud.py +++ b/instack_undercloud/undercloud.py @@ -1583,19 +1583,51 @@ def _clean_os_collect_config(): def _create_mistral_config_environment(instack_env, mistral): - # Store the snmpd password in a Mistral environment so it can be accessed + # Store all the required passwords from the Undercloud + # in a Mistral environment so they can be accessed # by the Mistral actions. - snmpd_password = instack_env["UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD"] - env_name = "tripleo.undercloud-config" + config_data = { + 'undercloud_ceilometer_snmpd_password': + instack_env['UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD'], + 'undercloud_db_password': + instack_env['UNDERCLOUD_DB_PASSWORD'] + } + env_name = 'tripleo.undercloud-config' try: - mistral.environments.get(env_name) + env_data = mistral.environments.get(env_name).variables except ks_exceptions.NotFound: + # If the environment is not created, we need to + # create it with the information in config_data mistral.environments.create( name=env_name, - variables=json.dumps({ - "undercloud_ceilometer_snmpd_password": snmpd_password - })) + description='Undercloud configuration parameters', + variables=json.dumps(config_data, sort_keys=True) + ) + return + + # If we are upgrading from an environment without + # variables defined in config_data, we need to update + # the environment variables. + + for var, value in iter(config_data.items()): + if var in env_data: + if env_data[var] != config_data[var]: + # Value in config_data is different + # need to update + env_data[var] = value + else: + # The value in config_data + # is new, we need to add it + env_data[var] = value + + # Here we update the current environment + # with the variables updated + mistral.environments.update( + name=env_name, + description='Undercloud configuration parameters', + variables=json.dumps(env_data, sort_keys=True) + ) def _wait_for_mistral_execution(timeout_at, mistral, execution, message='',