Use workflow for overcloud node delete

This patch adds support for using a workflow in tripleo-common
for deleting nodes from a stack (scale down).

Change-Id: Ia65734273d70ea0ae30d96122728950e1f0217b8
Partial-Bug: #1626736
This commit is contained in:
Ryan Brady 2016-10-06 14:04:58 -04:00
parent 846e7f35d4
commit a85ad62d85
3 changed files with 103 additions and 16 deletions

View File

@ -33,11 +33,26 @@ class TestDeleteNode(fakes.TestDeleteNode):
# Get the command object to test
self.cmd = overcloud_node.DeleteNode(self.app, None)
self.app.client_manager.workflow_engine = mock.Mock()
self.tripleoclient = mock.Mock()
self.websocket = mock.Mock()
self.websocket.__enter__ = lambda s: self.websocket
self.websocket.__exit__ = lambda s, *exc: None
self.tripleoclient = mock.Mock()
self.tripleoclient.messaging_websocket.return_value = self.websocket
self.app.client_manager.tripleoclient = self.tripleoclient
self.workflow = self.app.client_manager.workflow_engine
# Mock UUID4 generation for every test
uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4")
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)
# TODO(someone): This test does not pass with autospec=True, it should
# probably be fixed so that it can pass with that.
@mock.patch('tripleo_common.scale.ScaleManager')
def test_node_delete(self, scale_manager):
def test_node_delete(self):
argslist = ['instance1', 'instance2', '--templates',
'--stack', 'overcloud']
verifylist = [
@ -45,10 +60,21 @@ class TestDeleteNode(fakes.TestDeleteNode):
('nodes', ['instance1', 'instance2'])
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.websocket.wait_for_message.return_value = {
"status": "SUCCESS"
}
self.cmd.take_action(parsed_args)
scale_manager.scaledown(parsed_args.nodes)
scale_manager.scaledown.assert_called_once_with(['instance1',
'instance2'])
# Verify
self.workflow.executions.create.assert_called_once_with(
'tripleo.scale.v1.delete_node',
workflow_input={
'container': 'overcloud',
'queue_name': 'UUID4',
'nodes': ['instance1', 'instance2']
})
class TestProvideNode(fakes.TestOvercloudNode):

View File

@ -20,11 +20,11 @@ import uuid
from osc_lib.command import command
from osc_lib.i18n import _
from osc_lib import utils
from tripleo_common import scale
from tripleoclient import constants
from tripleoclient import utils as oooutils
from tripleoclient.workflows import baremetal
from tripleoclient.workflows import scale
class DeleteNode(command.Command):
@ -42,14 +42,21 @@ class DeleteNode(command.Command):
default=utils.env('OVERCLOUD_STACK_NAME'))
parser.add_argument(
'--templates', nargs='?', const=constants.TRIPLEO_HEAT_TEMPLATES,
help=_("The directory containing the Heat templates to deploy")
help=_("The directory containing the Heat templates to deploy. "
"This argument is deprecated. The command now utilizes "
"a deployment plan, which should be updated prior to "
"running this command, should that be required. Otherwise "
"this argument will be silently ignored."),
)
parser.add_argument(
'-e', '--environment-file', metavar='<HEAT ENVIRONMENT FILE>',
action='append', dest='environment_files',
help=_('Environment files to be passed to the heat stack-create '
'or heat stack-update command. (Can be specified more than '
'once.)')
help=_("Environment files to be passed to the heat stack-create "
"or heat stack-update command. (Can be specified more than "
"once.) This argument is deprecated. The command now "
"utilizes a deployment plan, which should be updated prior "
"to running this command, should that be required. "
"Otherwise this argument will be silently ignored."),
)
return parser
@ -58,14 +65,10 @@ class DeleteNode(command.Command):
self.log.debug("take_action(%s)" % parsed_args)
clients = self.app.client_manager
scale_manager = scale.ScaleManager(
heatclient=clients.orchestration,
stack_id=parsed_args.stack,
tht_dir=parsed_args.templates,
environment_files=parsed_args.environment_files)
print("deleting nodes {0} from stack {1}".format(parsed_args.nodes,
parsed_args.stack))
scale_manager.scaledown(parsed_args.nodes)
scale.scale_down(clients, parsed_args.stack, parsed_args.nodes)
class ProvideNode(command.Command):

View File

@ -0,0 +1,58 @@
# Copyright 2016 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import print_function
import pprint
import uuid
from tripleoclient.workflows import base
def delete_node(clients, **workflow_input):
workflow_client = clients.workflow_engine
tripleoclients = clients.tripleoclient
queue_name = workflow_input['queue_name']
execution = base.start_workflow(
workflow_client,
'tripleo.scale.v1.delete_node',
workflow_input=workflow_input
)
with tripleoclients.messaging_websocket(queue_name) as ws:
message = ws.wait_for_message(execution.id)
assert message['status'] == "SUCCESS", pprint.pformat(message)
def scale_down(clients, plan_name, nodes, timeout=None):
"""Deletes overcloud nodes from a heat stack.
:param clients: openstack clients
:param plan_name: name of the container holding the plan data
:param nodes: list of node id's to remove from the stack
:param timeout: timeout for stack update operation
"""
workflow_input = {
"container": plan_name,
"nodes": nodes,
"queue_name": str(uuid.uuid4()),
}
if timeout is not None:
workflow_input['timeout'] = timeout
delete_node(clients, **workflow_input)