Use the generic preservation method for plan-environment.yaml

This reuses the previously introduced generic file preservation method
in a deployment plan to keep plan-environment.yaml too.

We can also get rid of the separate password keeping, as they are part
of the plan-environment.yaml.

Partial-Bug: #1749700
Change-Id: Ib64296daaa81ff4fb19f1c199ecd6507ab2fb71c
This commit is contained in:
Jiri Stransky 2018-02-13 12:28:52 +01:00
parent 78e24e21c4
commit d1db364fec
2 changed files with 128 additions and 33 deletions

View File

@ -211,6 +211,107 @@ class TestPlanCreationWorkflows(utils.TestCommand):
'generate_passwords': False})
class TestPlanUpdateWorkflows(base.TestCommand):
def setUp(self):
super(TestPlanUpdateWorkflows, self).setUp()
self.app.client_manager.workflow_engine = self.workflow = mock.Mock()
self.app.client_manager.tripleoclient = self.tripleoclient = \
mock.Mock()
self.tripleoclient.object_store = self.object_store = mock.Mock()
self.websocket = mock.Mock()
self.websocket.__enter__ = lambda s: self.websocket
self.websocket.__exit__ = lambda s, *exc: None
self.tripleoclient.messaging_websocket.return_value = self.websocket
self.workflow.action_executions.create.return_value = mock.Mock(
output='{"result": ""}')
self.message_success = iter([{
"execution": {"id": "IDID"},
"status": "SUCCESS",
}])
self.websocket.wait_for_messages.return_value = self.message_success
self.object_store.get_container.return_value = (
{},
[
{'name': 'plan-environment.yaml'},
{'name': 'user-environment.yaml'},
]
)
def get_object(*args, **kwargs):
if args[0] != 'test-overcloud':
raise RuntimeError('Unexpected container')
if args[1] == 'plan-environment.yaml':
return {}, ('passwords: somepasswords\n'
'plan-environment.yaml: mock content\n')
# Generic return valuebased on param,
# e.g. 'plan-environment.yaml: mock content'
return {}, '{0}: mock content\n'.format(args[1])
self.object_store.get_object.side_effect = get_object
@mock.patch('tripleoclient.workflows.plan_management.tarball',
autospec=True)
@mock.patch('tripleo_common.utils.swift.empty_container',
autospec=True)
def test_update_plan_from_templates_keep_env(
self, mock_empty_container, mock_tarball):
plan_management.update_plan_from_templates(
self.app.client_manager,
'test-overcloud',
'/tht-root/',
keep_env=True)
mock_empty_container.assert_called_once_with(
self.object_store, 'test-overcloud')
# make sure we're pushing the saved files back to plan
self.object_store.put_object.assert_has_calls(
[
mock.call('test-overcloud', 'plan-environment.yaml',
'passwords: somepasswords\n'
'plan-environment.yaml: mock content\n'),
mock.call('test-overcloud', 'user-environment.yaml',
'user-environment.yaml: mock content\n'),
],
any_order=True,
)
self.workflow.executions.create.assert_called_once_with(
'tripleo.plan_management.v1.update_deployment_plan',
workflow_input={'container': 'test-overcloud',
'generate_passwords': True, 'source_url': None})
@mock.patch('tripleoclient.workflows.plan_management.tarball',
autospec=True)
@mock.patch('tripleo_common.utils.swift.empty_container',
autospec=True)
def test_update_plan_from_templates_recreate_env(
self, mock_empty_container, mock_tarball):
plan_management.update_plan_from_templates(
self.app.client_manager,
'test-overcloud',
'/tht-root/')
mock_empty_container.assert_called_once_with(
self.object_store, 'test-overcloud')
# make sure passwords got persisted
self.object_store.put_object.assert_called_with(
'test-overcloud', 'plan-environment.yaml',
'passwords: somepasswords\n'
'plan-environment.yaml: mock content\n'
)
self.workflow.executions.create.assert_called_once_with(
'tripleo.plan_management.v1.update_deployment_plan',
workflow_input={'container': 'test-overcloud',
'generate_passwords': True, 'source_url': None})
class TestUpdatePasswords(base.TestCase):
YAML_CONTENTS = """version: 1.0

View File

@ -147,31 +147,21 @@ def update_plan_from_templates(clients, name, tht_root, roles_file=None,
generate_passwords=True, plan_env_file=None,
networks_file=None, keep_env=False):
swift_client = clients.tripleoclient.object_store
passwords = None
keep_file_contents = {}
# If the plan environment was migrated to Swift, save the generated
# 'passwords' if they exist as they can't be recreated from the
# templates content.
passwords = []
# If the user provides a plan-environment files, then used it
if plan_env_file:
with open(os.path.abspath(plan_env_file)) as content:
env = yaml.load(content.read())
else:
try:
env = yaml.safe_load(swift_client.get_object(
name, constants.PLAN_ENVIRONMENT)[1])
except swift_exc.ClientException:
pass
if keep_env:
keep_file_contents = _load_content_or_file(
swift_client,
name,
{
constants.PLAN_ENVIRONMENT: plan_env_file,
constants.USER_ENVIRONMENT: None,
}
)
elif not plan_env_file:
passwords = _load_passwords(swift_client, name)
keep_file_contents = _load_content_or_file(
swift_client,
name,
{
constants.USER_ENVIRONMENT: None,
}
)
passwords = env.get('passwords', [])
# TODO(dmatthews): Removing the existing plan files should probably be
# a Mistral action.
print("Removing the current plan files")
@ -189,22 +179,20 @@ def update_plan_from_templates(clients, name, tht_root, roles_file=None,
# need to special-case plan-environment.yaml to avoid this.
print("Uploading new plan files")
_upload_templates(swift_client, name, tht_root, roles_file, plan_env_file,
networks_file)
if keep_env:
_upload_templates(swift_client, name, tht_root, roles_file=roles_file,
plan_env_file=None, networks_file=networks_file)
for filename in keep_file_contents:
_upload_file_content(swift_client, name, filename,
keep_file_contents[filename])
update_deployment_plan(clients, container=name,
generate_passwords=generate_passwords,
source_url=None, plan_environment=env)
else:
_upload_templates(swift_client, name, tht_root, roles_file,
plan_env_file, networks_file)
_update_passwords(swift_client, name, passwords)
update_deployment_plan(clients, container=name,
generate_passwords=generate_passwords,
source_url=None)
update_deployment_plan(clients, container=name,
generate_passwords=generate_passwords,
source_url=None)
def _load_content_or_file(swift_client, container, remote_and_local_map):
@ -247,6 +235,12 @@ def _upload_file_content(swift_client, container, filename, content):
swift_client.put_object(container, filename, content)
def _load_passwords(swift_client, name):
plan_env = yaml.safe_load(swift_client.get_object(
name, constants.PLAN_ENVIRONMENT)[1])
return plan_env['passwords']
def _update_passwords(swift_client, name, passwords):
# Update the plan environment with the generated passwords. This
# will be solved more elegantly once passwords are saved in a