Select Roles Workflow
This patch adds a workflow that takes a list of role names as input and populates roles_data.yaml in container in Swift with respective roles from 'roles directory'. Change-Id: I6c2a0d120d3e362df1ce1b701597d062783a48a4 Implements: blueprint tripleo-common-select-roles-workflow
This commit is contained in:
parent
a9e26a8d77
commit
f70830b425
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds a workflow that takes a list of role names as input and populates
|
||||||
|
roles_data.yaml in deployment plan with respective roles from
|
||||||
|
the '/roles directory'.
|
|
@ -113,6 +113,7 @@ mistral.actions =
|
||||||
tripleo.plan.update_from_dir = tripleo_common.actions.plan:UpdatePlanFromDirAction
|
tripleo.plan.update_from_dir = tripleo_common.actions.plan:UpdatePlanFromDirAction
|
||||||
tripleo.plan.update_networks = tripleo_common.actions.plan:UpdateNetworksAction
|
tripleo.plan.update_networks = tripleo_common.actions.plan:UpdateNetworksAction
|
||||||
tripleo.plan.update_plan_environment = tripleo_common.actions.plan:UpdatePlanEnvironmentAction
|
tripleo.plan.update_plan_environment = tripleo_common.actions.plan:UpdatePlanEnvironmentAction
|
||||||
|
tripleo.plan.gather_roles = tripleo_common.actions.plan:GatherRolesAction
|
||||||
tripleo.plan.update_roles = tripleo_common.actions.plan:UpdateRolesAction
|
tripleo.plan.update_roles = tripleo_common.actions.plan:UpdateRolesAction
|
||||||
tripleo.plan.validate_roles = tripleo_common.actions.plan:ValidateRolesDataAction
|
tripleo.plan.validate_roles = tripleo_common.actions.plan:ValidateRolesDataAction
|
||||||
tripleo.logging_to_swift.format_messages = tripleo_common.actions.logging_to_swift:FormatMessagesAction
|
tripleo.logging_to_swift.format_messages = tripleo_common.actions.logging_to_swift:FormatMessagesAction
|
||||||
|
|
|
@ -434,3 +434,32 @@ class UpdateRolesAction(base.TripleOAction):
|
||||||
save_roles = sorted(role_data_to_save, key=itemgetter('name'),
|
save_roles = sorted(role_data_to_save, key=itemgetter('name'),
|
||||||
reverse=True)
|
reverse=True)
|
||||||
return actions.Result(data={'roles': save_roles})
|
return actions.Result(data={'roles': save_roles})
|
||||||
|
|
||||||
|
|
||||||
|
class GatherRolesAction(actions.Action):
|
||||||
|
"""Gather role definitions
|
||||||
|
|
||||||
|
Check each role name from the input, check if it exists in
|
||||||
|
roles_data.yaml, if yes, use that role definition, if not, get the
|
||||||
|
role definition from roles directory. Return the gathered role
|
||||||
|
definitions.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, role_names, current_roles, available_roles):
|
||||||
|
super(GatherRolesAction, self).__init__()
|
||||||
|
self.role_names = role_names
|
||||||
|
self.current_roles = current_roles
|
||||||
|
self.available_roles = available_roles
|
||||||
|
|
||||||
|
def run(self, context):
|
||||||
|
err_msgs = []
|
||||||
|
# merge the two lists of dicts in the proper order. last in wins, so
|
||||||
|
# a current role shall be favored over an available role.
|
||||||
|
gathered_roles = [role for role in {
|
||||||
|
x['name']: x for x in self.available_roles + self.current_roles
|
||||||
|
}.values() if role['name'] in self.role_names]
|
||||||
|
|
||||||
|
if err_msgs:
|
||||||
|
return actions.Result(error="/n".join(err_msgs))
|
||||||
|
|
||||||
|
return actions.Result(data={'gathered_roles': gathered_roles})
|
||||||
|
|
|
@ -273,7 +273,6 @@ class DeletePlanActionTest(base.TestCase):
|
||||||
swift = mock.MagicMock()
|
swift = mock.MagicMock()
|
||||||
swift.get_account.return_value = ({}, [
|
swift.get_account.return_value = ({}, [
|
||||||
{'name': self.container_name},
|
{'name': self.container_name},
|
||||||
{'name': "%s-swift-rings" % self.container_name},
|
|
||||||
{'name': 'test'},
|
{'name': 'test'},
|
||||||
])
|
])
|
||||||
swift.get_container.return_value = (
|
swift.get_container.return_value = (
|
||||||
|
@ -305,39 +304,7 @@ class DeletePlanActionTest(base.TestCase):
|
||||||
swift.delete_object.assert_has_calls(
|
swift.delete_object.assert_has_calls(
|
||||||
mock_calls, any_order=True)
|
mock_calls, any_order=True)
|
||||||
|
|
||||||
mock_calls = [
|
swift.delete_container.assert_called_with(self.container_name)
|
||||||
mock.call(self.container_name),
|
|
||||||
mock.call("%s-swift-rings" % self.container_name)
|
|
||||||
]
|
|
||||||
self.assertEqual(2, swift.delete_container.call_count)
|
|
||||||
swift.delete_container.assert_has_calls(mock_calls)
|
|
||||||
|
|
||||||
@mock.patch('tripleo_common.actions.base.TripleOAction.get_object_client')
|
|
||||||
@mock.patch(
|
|
||||||
'tripleo_common.actions.base.TripleOAction.get_orchestration_client')
|
|
||||||
def test_run_no_containers(
|
|
||||||
self, get_orchestration_client, get_obj_client_mock):
|
|
||||||
|
|
||||||
# setup swift
|
|
||||||
swift = mock.MagicMock()
|
|
||||||
# There are no swift containers because they were either accidentally
|
|
||||||
# removed or not created.
|
|
||||||
swift.get_account.return_value = ({}, [])
|
|
||||||
|
|
||||||
get_obj_client_mock.return_value = swift
|
|
||||||
|
|
||||||
# setup heat
|
|
||||||
heat = mock.MagicMock()
|
|
||||||
heat.stacks.get = mock.Mock(
|
|
||||||
side_effect=heatexceptions.HTTPNotFound)
|
|
||||||
get_orchestration_client.return_value = heat
|
|
||||||
|
|
||||||
action = plan.DeletePlanAction(self.container_name)
|
|
||||||
action.run(self.ctx)
|
|
||||||
|
|
||||||
# The operation was successfully finished and we didn't try to remove
|
|
||||||
# nonexistent containers.
|
|
||||||
self.assertEqual(0, swift.delete_container.call_count)
|
|
||||||
|
|
||||||
|
|
||||||
class ListRolesActionTest(base.TestCase):
|
class ListRolesActionTest(base.TestCase):
|
||||||
|
@ -603,3 +570,23 @@ class UpdateRolesActionTest(base.TestCase):
|
||||||
result = action.run(self.ctx)
|
result = action.run(self.ctx)
|
||||||
|
|
||||||
self.assertEqual(result.data, {'roles': [UPDATED_ROLE_OBJ, ]})
|
self.assertEqual(result.data, {'roles': [UPDATED_ROLE_OBJ, ]})
|
||||||
|
|
||||||
|
|
||||||
|
class GatherRolesActionTest(base.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(GatherRolesActionTest, self).setUp()
|
||||||
|
self.container = 'overcloud'
|
||||||
|
self.ctx = mock.MagicMock()
|
||||||
|
self.current_roles = [SAMPLE_ROLE_OBJ, SAMPLE_ROLE_2_OBJ]
|
||||||
|
self.available_role = SAMPLE_ROLE_OBJ.copy()
|
||||||
|
self.available_role['name'] = 'test'
|
||||||
|
|
||||||
|
def test_roles_gathered(self):
|
||||||
|
action = plan.GatherRolesAction(['sample', 'test'], self.current_roles,
|
||||||
|
[self.available_role])
|
||||||
|
result = action.run(self.ctx)
|
||||||
|
|
||||||
|
# assert that a role was loaded from self.current_roles
|
||||||
|
self.assertTrue(result.data['gathered_roles'],
|
||||||
|
[SAMPLE_ROLE_OBJ, self.available_role])
|
||||||
|
|
|
@ -1289,4 +1289,97 @@ workflows:
|
||||||
execution: <% execution() %>
|
execution: <% execution() %>
|
||||||
updated_roles: <% $.get('updated_roles', []) %>
|
updated_roles: <% $.get('updated_roles', []) %>
|
||||||
on-success:
|
on-success:
|
||||||
- fail: <% $.get('status') = "FAILED" %>
|
- fail: <% $.get('status') = "FAILED" %>
|
||||||
|
|
||||||
|
select_roles:
|
||||||
|
description: >
|
||||||
|
takes a list of role names as input and populates roles_data.yaml in
|
||||||
|
container in Swift with respective roles from 'roles directory'
|
||||||
|
input:
|
||||||
|
- container
|
||||||
|
- role_names
|
||||||
|
- roles_data_file: 'roles_data.yaml'
|
||||||
|
- replace_all: true
|
||||||
|
- queue_name: tripleo
|
||||||
|
tags:
|
||||||
|
- tripleo-common-managed
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
get_available_roles:
|
||||||
|
workflow: list_available_roles
|
||||||
|
input:
|
||||||
|
container: <% $.container %>
|
||||||
|
queue_name: <% $.queue_name %>
|
||||||
|
publish:
|
||||||
|
available_roles: <% task().result.available_roles %>
|
||||||
|
on-success: get_current_roles
|
||||||
|
on-error: notify_zaqar
|
||||||
|
publish-on-error:
|
||||||
|
status: FAILED
|
||||||
|
message: <% task().result %>
|
||||||
|
|
||||||
|
get_current_roles:
|
||||||
|
workflow: list_roles
|
||||||
|
input:
|
||||||
|
container: <% $.container %>
|
||||||
|
roles_data_file: <% $.roles_data_file %>
|
||||||
|
queue_name: <% $.queue_name %>
|
||||||
|
publish:
|
||||||
|
current_roles: <% task().result.roles_data %>
|
||||||
|
on-success: gather_roles
|
||||||
|
on-error: notify_zaqar
|
||||||
|
publish-on-error:
|
||||||
|
status: FAILED
|
||||||
|
message: <% task().result %>
|
||||||
|
|
||||||
|
gather_roles:
|
||||||
|
description: >
|
||||||
|
for each role name from the input, check if it exists in
|
||||||
|
roles_data.yaml, if yes, use that role definition, if not, get the
|
||||||
|
role definition from roles directory. Use the gathered roles
|
||||||
|
definitions as input to updateRolesWorkflow - this ensures
|
||||||
|
configuration of the roles which are already in roles_data.yaml
|
||||||
|
will not get overridden by data from roles directory
|
||||||
|
action: tripleo.plan.gather_roles
|
||||||
|
input:
|
||||||
|
role_names: <% $.role_names %>
|
||||||
|
current_roles: <% $.current_roles %>
|
||||||
|
available_roles: <% $.available_roles %>
|
||||||
|
publish:
|
||||||
|
gathered_roles: <% task().result.gathered_roles %>
|
||||||
|
on-success: call_update_roles_workflow
|
||||||
|
on-error: notify_zaqar
|
||||||
|
publish-on-error:
|
||||||
|
status: FAILED
|
||||||
|
message: <% task().result %>
|
||||||
|
|
||||||
|
call_update_roles_workflow:
|
||||||
|
workflow: update_roles
|
||||||
|
input:
|
||||||
|
container: <% $.container %>
|
||||||
|
roles: <% $.gathered_roles %>
|
||||||
|
roles_data_file: <% $.roles_data_file %>
|
||||||
|
replace_all: <% $.replace_all %>
|
||||||
|
queue_name: <% $.queue_name %>
|
||||||
|
on-complete: notify_zaqar
|
||||||
|
publish:
|
||||||
|
selected_roles: <% task().result.updated_roles %>
|
||||||
|
status: SUCCESS
|
||||||
|
publish-on-error:
|
||||||
|
status: FAILED
|
||||||
|
message: <% task().result %>
|
||||||
|
|
||||||
|
notify_zaqar:
|
||||||
|
action: zaqar.queue_post
|
||||||
|
input:
|
||||||
|
queue_name: <% $.queue_name %>
|
||||||
|
messages:
|
||||||
|
body:
|
||||||
|
type: tripleo.plan_management.v1.select_roles
|
||||||
|
payload:
|
||||||
|
status: <% $.status %>
|
||||||
|
message: <% $.get('message', '') %>
|
||||||
|
execution: <% execution() %>
|
||||||
|
selected_roles: <% $.get('selected_roles', []) %>
|
||||||
|
on-success:
|
||||||
|
- fail: <% $.get('status') = "FAILED" %>
|
||||||
|
|
Loading…
Reference in New Issue