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:
parent
846e7f35d4
commit
a85ad62d85
|
@ -33,11 +33,26 @@ class TestDeleteNode(fakes.TestDeleteNode):
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = overcloud_node.DeleteNode(self.app, None)
|
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
|
# TODO(someone): This test does not pass with autospec=True, it should
|
||||||
# probably be fixed so that it can pass with that.
|
# probably be fixed so that it can pass with that.
|
||||||
@mock.patch('tripleo_common.scale.ScaleManager')
|
def test_node_delete(self):
|
||||||
def test_node_delete(self, scale_manager):
|
|
||||||
argslist = ['instance1', 'instance2', '--templates',
|
argslist = ['instance1', 'instance2', '--templates',
|
||||||
'--stack', 'overcloud']
|
'--stack', 'overcloud']
|
||||||
verifylist = [
|
verifylist = [
|
||||||
|
@ -45,10 +60,21 @@ class TestDeleteNode(fakes.TestDeleteNode):
|
||||||
('nodes', ['instance1', 'instance2'])
|
('nodes', ['instance1', 'instance2'])
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
|
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
|
||||||
|
|
||||||
|
self.websocket.wait_for_message.return_value = {
|
||||||
|
"status": "SUCCESS"
|
||||||
|
}
|
||||||
|
|
||||||
self.cmd.take_action(parsed_args)
|
self.cmd.take_action(parsed_args)
|
||||||
scale_manager.scaledown(parsed_args.nodes)
|
|
||||||
scale_manager.scaledown.assert_called_once_with(['instance1',
|
# Verify
|
||||||
'instance2'])
|
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):
|
class TestProvideNode(fakes.TestOvercloudNode):
|
||||||
|
|
|
@ -20,11 +20,11 @@ import uuid
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
from osc_lib.i18n import _
|
from osc_lib.i18n import _
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
from tripleo_common import scale
|
|
||||||
|
|
||||||
from tripleoclient import constants
|
from tripleoclient import constants
|
||||||
from tripleoclient import utils as oooutils
|
from tripleoclient import utils as oooutils
|
||||||
from tripleoclient.workflows import baremetal
|
from tripleoclient.workflows import baremetal
|
||||||
|
from tripleoclient.workflows import scale
|
||||||
|
|
||||||
|
|
||||||
class DeleteNode(command.Command):
|
class DeleteNode(command.Command):
|
||||||
|
@ -42,14 +42,21 @@ class DeleteNode(command.Command):
|
||||||
default=utils.env('OVERCLOUD_STACK_NAME'))
|
default=utils.env('OVERCLOUD_STACK_NAME'))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--templates', nargs='?', const=constants.TRIPLEO_HEAT_TEMPLATES,
|
'--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(
|
parser.add_argument(
|
||||||
'-e', '--environment-file', metavar='<HEAT ENVIRONMENT FILE>',
|
'-e', '--environment-file', metavar='<HEAT ENVIRONMENT FILE>',
|
||||||
action='append', dest='environment_files',
|
action='append', dest='environment_files',
|
||||||
help=_('Environment files to be passed to the heat stack-create '
|
help=_("Environment files to be passed to the heat stack-create "
|
||||||
'or heat stack-update command. (Can be specified more than '
|
"or heat stack-update command. (Can be specified more than "
|
||||||
'once.)')
|
"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
|
return parser
|
||||||
|
@ -58,14 +65,10 @@ class DeleteNode(command.Command):
|
||||||
self.log.debug("take_action(%s)" % parsed_args)
|
self.log.debug("take_action(%s)" % parsed_args)
|
||||||
clients = self.app.client_manager
|
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,
|
print("deleting nodes {0} from stack {1}".format(parsed_args.nodes,
|
||||||
parsed_args.stack))
|
parsed_args.stack))
|
||||||
scale_manager.scaledown(parsed_args.nodes)
|
|
||||||
|
scale.scale_down(clients, parsed_args.stack, parsed_args.nodes)
|
||||||
|
|
||||||
|
|
||||||
class ProvideNode(command.Command):
|
class ProvideNode(command.Command):
|
||||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue