Support "--pre-delete" argument for hook-clear
This changes: 1. Add "--pre-delete" argument for cmd "heat hook-clear" to clear pre-delete hooks. 2. Add "--pre-delete" argument for osc cmd "openstack stack hook clear" to clear pre-delete hooks. 3. Support to poll pre-delete hooks for "heat hook-poll" and "openstack stack hook poll". Change-Id: Ic5a6e1b7588e3f9ad49eaaf8085f18ec74fc629e Closes-Bug: #1567814
This commit is contained in:
@@ -31,6 +31,10 @@ def get_hook_events(hc, stack_id, event_args, nested_depth=0,
|
||||
stack_action_reason = 'Stack UPDATE started'
|
||||
hook_event_reason = 'UPDATE paused until Hook pre-update is cleared'
|
||||
hook_clear_event_reason = 'Hook pre-update is cleared'
|
||||
elif hook_type == 'pre-delete':
|
||||
stack_action_reason = 'Stack DELETE started'
|
||||
hook_event_reason = 'DELETE paused until Hook pre-delete is cleared'
|
||||
hook_clear_event_reason = 'Hook pre-delete is cleared'
|
||||
else:
|
||||
raise exc.CommandError(_('Unexpected hook type %s') % hook_type)
|
||||
|
||||
|
@@ -56,8 +56,9 @@ def clear_wildcard_hooks(hc, stack_id, stack_patterns, hook_type,
|
||||
|
||||
|
||||
def get_hook_type_via_status(hc, stack_id):
|
||||
# Figure out if the hook should be pre-create or pre-update based
|
||||
# on the stack status, also sanity assertions that we're in-progress.
|
||||
# Figure out if the hook should be pre-create, pre-update or
|
||||
# pre-delete based on the stack status, also sanity assertions
|
||||
# that we're in-progress.
|
||||
try:
|
||||
stack = hc.stacks.get(stack_id=stack_id)
|
||||
except exc.HTTPNotFound:
|
||||
@@ -71,8 +72,10 @@ def get_hook_type_via_status(hc, stack_id):
|
||||
hook_type = 'pre-create'
|
||||
elif 'UPDATE' in stack.stack_status:
|
||||
hook_type = 'pre-update'
|
||||
elif 'DELETE' in stack.stack_status:
|
||||
hook_type = 'pre-delete'
|
||||
else:
|
||||
raise exc.CommandError(_('Unexpected stack status %s, '
|
||||
'only create/update supported')
|
||||
'only create, update and delete supported')
|
||||
% stack.stack_status)
|
||||
return hook_type
|
||||
|
@@ -1219,6 +1219,11 @@ class StackHookClear(command.Command):
|
||||
action='store_true',
|
||||
help=_('Clear the pre-update hooks')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--pre-delete',
|
||||
action='store_true',
|
||||
help=_('Clear the pre-delete hooks')
|
||||
)
|
||||
parser.add_argument(
|
||||
'hook',
|
||||
metavar='<resource>',
|
||||
@@ -1246,6 +1251,8 @@ def _hook_clear(args, heat_client):
|
||||
hook_type = 'pre-create'
|
||||
elif args.pre_update:
|
||||
hook_type = 'pre-update'
|
||||
elif args.pre_delete:
|
||||
hook_type = 'pre-delete'
|
||||
else:
|
||||
hook_type = hook_utils.get_hook_type_via_status(heat_client,
|
||||
args.stack)
|
||||
|
@@ -1299,3 +1299,12 @@ class TestStackHookClear(TestStack):
|
||||
data={'unset_hook': 'pre-update'},
|
||||
resource_name='resource',
|
||||
stack_id='my_stack')
|
||||
|
||||
def test_hook_clear_pre_delete(self):
|
||||
arglist = ['my_stack', 'resource', '--pre-delete']
|
||||
parsed_args = self.check_parser(self.cmd, arglist, [])
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.mock_client.resources.signal.assert_called_once_with(
|
||||
data={'unset_hook': 'pre-delete'},
|
||||
resource_name='resource',
|
||||
stack_id='my_stack')
|
||||
|
@@ -3718,6 +3718,21 @@ class ShellTestHookFunctions(ShellBase):
|
||||
self.assertNotRegexpMatches(list_text, 'n_eventid1')
|
||||
self.assertNotRegexpMatches(list_text, 'n_eventid2')
|
||||
|
||||
def test_hook_poll_pre_delete(self):
|
||||
self.register_keystone_auth_fixture()
|
||||
stack_id = 'teststack/1'
|
||||
nested_id = 'nested/2'
|
||||
self._stub_responses(stack_id, nested_id, 'DELETE')
|
||||
self.m.ReplayAll()
|
||||
list_text = self.shell('hook-poll %s --nested-depth 1' % stack_id)
|
||||
hook_reason = 'DELETE paused until Hook pre-delete is cleared'
|
||||
required = ['id', 'p_eventid2', 'stack_name', 'teststack', hook_reason]
|
||||
for r in required:
|
||||
self.assertRegex(list_text, r)
|
||||
self.assertNotRegexpMatches(list_text, 'p_eventid1')
|
||||
self.assertNotRegexpMatches(list_text, 'n_eventid1')
|
||||
self.assertNotRegexpMatches(list_text, 'n_eventid2')
|
||||
|
||||
def test_hook_poll_bad_status(self):
|
||||
self.register_keystone_auth_fixture()
|
||||
stack_id = 'teststack/1'
|
||||
@@ -3752,12 +3767,12 @@ class ShellTestHookFunctions(ShellBase):
|
||||
def test_hook_poll_clear_bad_action(self):
|
||||
self.register_keystone_auth_fixture()
|
||||
stack_id = 'teststack/1'
|
||||
self._stub_stack_response(stack_id, action='DELETE')
|
||||
self._stub_stack_response(stack_id, action='BADACTION')
|
||||
self.m.ReplayAll()
|
||||
error = self.assertRaises(
|
||||
exc.CommandError, self.shell,
|
||||
'hook-clear %s aresource' % stack_id)
|
||||
self.assertIn('Unexpected stack status DELETE_IN_PROGRESS',
|
||||
self.assertIn('Unexpected stack status BADACTION_IN_PROGRESS',
|
||||
str(error))
|
||||
|
||||
|
||||
|
@@ -269,6 +269,21 @@ class TestHooks(testtools.TestCase):
|
||||
self.assertEqual('bp', payload['resource_name'])
|
||||
self.assertEqual('mystack', payload['stack_id'])
|
||||
|
||||
def test_clear_pre_delete_hooks(self):
|
||||
type(self.args).hook = mock.PropertyMock(
|
||||
return_value=['bp'])
|
||||
type(self.args).pre_delete = mock.PropertyMock(return_value=True)
|
||||
bp = mock.Mock()
|
||||
type(bp).resource_name = 'bp'
|
||||
self.client.resources.list = mock.Mock(return_value=[bp])
|
||||
|
||||
shell.do_hook_clear(self.client, self.args)
|
||||
self.assertEqual(1, self.client.resources.signal.call_count)
|
||||
payload = self.client.resources.signal.call_args_list[0][1]
|
||||
self.assertEqual({'unset_hook': 'pre-delete'}, payload['data'])
|
||||
self.assertEqual('bp', payload['resource_name'])
|
||||
self.assertEqual('mystack', payload['stack_id'])
|
||||
|
||||
def test_clear_nested_hook(self):
|
||||
type(self.args).hook = mock.PropertyMock(
|
||||
return_value=['a/b/bp'])
|
||||
|
@@ -1104,6 +1104,8 @@ def do_resource_mark_unhealthy(hc, args):
|
||||
help=_('Clear the pre-create hooks (optional)'))
|
||||
@utils.arg('--pre-update', action='store_true', default=False,
|
||||
help=_('Clear the pre-update hooks (optional)'))
|
||||
@utils.arg('--pre-delete', action='store_true', default=False,
|
||||
help=_('Clear the pre-delete hooks (optional)'))
|
||||
@utils.arg('hook', metavar='<RESOURCE>', nargs='+',
|
||||
help=_('Resource names with hooks to clear. Resources '
|
||||
'in nested stacks can be set using slash as a separator: '
|
||||
@@ -1118,6 +1120,8 @@ def do_hook_clear(hc, args):
|
||||
hook_type = 'pre-create'
|
||||
elif args.pre_update:
|
||||
hook_type = 'pre-update'
|
||||
elif args.pre_delete:
|
||||
hook_type = 'pre-delete'
|
||||
else:
|
||||
hook_type = hook_utils.get_hook_type_via_status(hc, args.id)
|
||||
|
||||
|
Reference in New Issue
Block a user