Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Commit ebe270c

Browse files
committed
Use parameters from existing Heat stack if it already exists
Users upgrading from Mitaka will have a stack and no plan. When instack-undercloud creates the plan it will generate new passwords. With this change it will take the passwords from the Heat stack. Closes-Bug: #1638003 Change-Id: I3ea6bbd0d9c5dd345b8a4a26a1788326e09d4209
1 parent 2af623f commit ebe270c

File tree

3 files changed

+81
-5
lines changed

3 files changed

+81
-5
lines changed

tripleo_common/actions/parameters.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
# under the License.
2929
import logging
3030

31+
from heatclient import exc as heat_exc
3132
from mistral.workflow import utils as mistral_workflow_utils
3233

3334
from tripleo_common.actions import base
@@ -143,6 +144,8 @@ def __init__(self, container=constants.DEFAULT_CONTAINER_NAME):
143144
self.container = container
144145

145146
def run(self):
147+
148+
orchestration = self._get_orchestration_client()
146149
wc = self._get_workflow_client()
147150
try:
148151
wf_env = wc.environments.get(self.container)
@@ -151,7 +154,13 @@ def run(self):
151154
LOG.exception(msg)
152155
return mistral_workflow_utils.Result("", msg)
153156

154-
passwords = password_utils.generate_overcloud_passwords(wc)
157+
try:
158+
stack_env = orchestration.stacks.environment(
159+
stack_id=self.container)
160+
except heat_exc.HTTPNotFound:
161+
stack_env = None
162+
163+
passwords = password_utils.generate_overcloud_passwords(wc, stack_env)
155164

156165
# if passwords don't yet exist in mistral environment
157166
if 'passwords' not in wf_env.variables:

tripleo_common/tests/actions/test_parameters.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,16 @@ def test_run(self, mock_ctx, mock_get_workflow_client):
173173

174174
class GeneratePasswordsActionTest(base.TestCase):
175175

176+
@mock.patch('tripleo_common.actions.base.TripleOAction.'
177+
'_get_orchestration_client')
176178
@mock.patch('tripleo_common.utils.passwords.'
177179
'get_snmpd_readonly_user_password')
178180
@mock.patch('tripleo_common.actions.base.TripleOAction.'
179181
'_get_workflow_client', return_value="TestPassword")
180182
@mock.patch('mistral.context.ctx')
181183
def test_run(self, mock_ctx, mock_get_workflow_client,
182-
mock_get_snmpd_readonly_user_password):
184+
mock_get_snmpd_readonly_user_password,
185+
mock_get_orchestration_client):
183186

184187
mock_get_snmpd_readonly_user_password.return_value = "TestPassword"
185188

@@ -195,20 +198,29 @@ def test_run(self, mock_ctx, mock_get_workflow_client,
195198
mock_mistral.environments.get.return_value = mock_env
196199
mock_get_workflow_client.return_value = mock_mistral
197200

201+
mock_orchestration = mock.MagicMock()
202+
mock_orchestration.stacks.environment.return_value = {
203+
'parameter_defaults': {}
204+
}
205+
mock_get_orchestration_client.return_value = mock_orchestration
206+
198207
action = parameters.GeneratePasswordsAction()
199208
result = action.run()
200209

201210
for password_param_name in constants.PASSWORD_PARAMETER_NAMES:
202211
self.assertTrue(password_param_name in result,
203212
"%s is not in %s" % (password_param_name, result))
204213

214+
@mock.patch('tripleo_common.actions.base.TripleOAction.'
215+
'_get_orchestration_client')
205216
@mock.patch('tripleo_common.utils.passwords.'
206217
'get_snmpd_readonly_user_password')
207218
@mock.patch('tripleo_common.actions.base.TripleOAction.'
208219
'_get_workflow_client')
209220
@mock.patch('mistral.context.ctx')
210221
def test_run_passwords_exist(self, mock_ctx, mock_get_workflow_client,
211-
mock_get_snmpd_readonly_user_password):
222+
mock_get_snmpd_readonly_user_password,
223+
mock_get_orchestration_client):
212224

213225
mock_get_snmpd_readonly_user_password.return_value = "TestPassword"
214226

@@ -225,8 +237,58 @@ def test_run_passwords_exist(self, mock_ctx, mock_get_workflow_client,
225237
mock_mistral.environments.get.return_value = mock_env
226238
mock_get_workflow_client.return_value = mock_mistral
227239

240+
mock_orchestration = mock.MagicMock()
241+
mock_orchestration.stacks.environment.return_value = {
242+
'parameter_defaults': {}
243+
}
244+
mock_get_orchestration_client.return_value = mock_orchestration
245+
228246
action = parameters.GeneratePasswordsAction()
229247
result = action.run()
230248

231249
# ensure old passwords used and no new generation
232250
self.assertEqual(_EXISTING_PASSWORDS, result)
251+
252+
@mock.patch('tripleo_common.actions.base.TripleOAction.'
253+
'_get_orchestration_client')
254+
@mock.patch('tripleo_common.utils.passwords.'
255+
'get_snmpd_readonly_user_password')
256+
@mock.patch('tripleo_common.actions.base.TripleOAction.'
257+
'_get_workflow_client')
258+
@mock.patch('mistral.context.ctx')
259+
def test_passwords_exist_in_heat(self, mock_ctx, mock_get_workflow_client,
260+
mock_get_snmpd_readonly_user_password,
261+
mock_get_orchestration_client):
262+
263+
mock_get_snmpd_readonly_user_password.return_value = "TestPassword"
264+
265+
existing_passwords = _EXISTING_PASSWORDS.copy()
266+
existing_passwords.pop("AdminPassword")
267+
268+
mock_ctx.return_value = mock.MagicMock()
269+
mock_mistral = mock.MagicMock()
270+
mock_env = mock.MagicMock()
271+
mock_env.name = constants.DEFAULT_CONTAINER_NAME
272+
mock_env.variables = {
273+
'temp_environment': 'temp_environment',
274+
'template': 'template',
275+
'environments': [{u'path': u'environments/test.yaml'}],
276+
'passwords': existing_passwords
277+
}
278+
mock_mistral.environments.get.return_value = mock_env
279+
mock_get_workflow_client.return_value = mock_mistral
280+
281+
mock_orchestration = mock.MagicMock()
282+
mock_orchestration.stacks.environment.return_value = {
283+
'parameter_defaults': {
284+
'AdminPassword': 'ExistingPasswordInHeat',
285+
}
286+
}
287+
mock_get_orchestration_client.return_value = mock_orchestration
288+
289+
action = parameters.GeneratePasswordsAction()
290+
result = action.run()
291+
292+
existing_passwords["AdminPassword"] = "ExistingPasswordInHeat"
293+
# ensure old passwords used and no new generation
294+
self.assertEqual(existing_passwords, result)

tripleo_common/utils/passwords.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
LOG = logging.getLogger(__name__)
2727

2828

29-
def generate_overcloud_passwords(mistralclient):
29+
def generate_overcloud_passwords(mistralclient, stack_env=None):
3030
"""Create the passwords needed for the overcloud
3131
3232
This will create the set of passwords required by the overcloud, store
@@ -36,8 +36,13 @@ def generate_overcloud_passwords(mistralclient):
3636
passwords = {}
3737

3838
for name in constants.PASSWORD_PARAMETER_NAMES:
39+
40+
# Support users upgrading from Mitaka or otherwise creating a plan for
41+
# a Heat stack that already exists.
42+
if stack_env and name in stack_env.get('parameter_defaults', {}):
43+
passwords[name] = stack_env['parameter_defaults'][name]
3944
# CephX keys aren't random strings
40-
if name.startswith("Ceph"):
45+
elif name.startswith("Ceph"):
4146
passwords[name] = create_cephx_key()
4247
# The SnmpdReadonlyUserPassword is stored in a mistral env.
4348
elif name == 'SnmpdReadonlyUserPassword':

0 commit comments

Comments
 (0)