Add 'overcloud node clean' command to run metadata cleaning on nodes
This is a manual replacement for the disabled automated cleaning. Depends-On: I909aad89bb18bb416e9749395970617d45b247ee Change-Id: I8e7f9b1122ff697adb4538233242c7b48420b17b
This commit is contained in:
parent
6031cf2e80
commit
373a4b6b2e
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds new command to run metadata cleaning on nodes::
|
||||
|
||||
openstack overcloud node clean [--all-manageable|uuid1,uuid2,..]
|
@ -64,6 +64,7 @@ openstack.tripleoclient.v1 =
|
||||
overcloud_node_introspect = tripleoclient.v1.overcloud_node:IntrospectNode
|
||||
overcloud_node_provide = tripleoclient.v1.overcloud_node:ProvideNode
|
||||
overcloud_node_discover = tripleoclient.v1.overcloud_node:DiscoverNode
|
||||
overcloud_node_clean = tripleoclient.v1.overcloud_node:CleanNode
|
||||
overcloud_parameters_set = tripleoclient.v1.overcloud_parameters:SetParameters
|
||||
overcloud_plan_create = tripleoclient.v1.overcloud_plan:CreatePlan
|
||||
overcloud_plan_delete = tripleoclient.v1.overcloud_plan:DeletePlan
|
||||
|
@ -114,11 +114,11 @@ class TestBaremetalWorkflows(utils.TestCommand):
|
||||
'node_uuids': [],
|
||||
})
|
||||
|
||||
def test_format_provide_errors(self):
|
||||
def test_format_errors(self):
|
||||
payload = {'message': [{'result': 'Error1a\nError1b'},
|
||||
{'result': 'Error2a\nError2b\n'}]}
|
||||
|
||||
error_string = baremetal._format_provide_errors(payload)
|
||||
error_string = baremetal._format_errors(payload)
|
||||
self.assertEqual(error_string, "Error1b\nError2b")
|
||||
|
||||
def test_provide_error_with_format_message(self):
|
||||
@ -306,3 +306,63 @@ class TestBaremetalWorkflows(utils.TestCommand):
|
||||
'tripleo.baremetal.v1.configure_manageable_nodes',
|
||||
workflow_input={}
|
||||
)
|
||||
|
||||
def test_clean_nodes_success(self):
|
||||
|
||||
self.websocket.wait_for_messages.return_value = self.message_success
|
||||
|
||||
baremetal.clean_nodes(self.app.client_manager, node_uuids=[])
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.clean_nodes',
|
||||
workflow_input={
|
||||
'node_uuids': [],
|
||||
})
|
||||
|
||||
def test_clean_nodes_error(self):
|
||||
|
||||
self.websocket.wait_for_messages.return_value = self.message_failed
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.NodeConfigurationError,
|
||||
baremetal.clean_nodes,
|
||||
self.app.client_manager,
|
||||
node_uuids=[]
|
||||
)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.clean_nodes',
|
||||
workflow_input={
|
||||
'node_uuids': [],
|
||||
})
|
||||
|
||||
def test_clean_manageable_nodes_success(self):
|
||||
|
||||
self.websocket.wait_for_messages.return_value = iter([{
|
||||
"execution": {"id": "IDID"},
|
||||
"status": "SUCCESS",
|
||||
"cleaned_nodes": [],
|
||||
}])
|
||||
|
||||
baremetal.clean_manageable_nodes(
|
||||
self.app.client_manager
|
||||
)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.clean_manageable_nodes',
|
||||
workflow_input={}
|
||||
)
|
||||
|
||||
def test_clean_manageable_nodes_error(self):
|
||||
|
||||
self.websocket.wait_for_messages.return_value = self.message_failed
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.NodeConfigurationError,
|
||||
baremetal.clean_manageable_nodes,
|
||||
self.app.client_manager)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.clean_manageable_nodes',
|
||||
workflow_input={}
|
||||
)
|
||||
|
@ -122,6 +122,36 @@ class ProvideNode(command.Command):
|
||||
baremetal.provide_manageable_nodes(self.app.client_manager)
|
||||
|
||||
|
||||
class CleanNode(command.Command):
|
||||
"""Run node(s) through cleaning."""
|
||||
|
||||
log = logging.getLogger(__name__ + ".CleanNode")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CleanNode, self).get_parser(prog_name)
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('node_uuids',
|
||||
nargs="*",
|
||||
metavar="<node_uuid>",
|
||||
default=[],
|
||||
help=_('Baremetal Node UUIDs for the node(s) to be '
|
||||
'cleaned'))
|
||||
group.add_argument("--all-manageable",
|
||||
action='store_true',
|
||||
help=_("Clean all nodes currently in 'manageable'"
|
||||
" state"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
|
||||
if parsed_args.node_uuids:
|
||||
baremetal.clean_nodes(self.app.client_manager,
|
||||
node_uuids=parsed_args.node_uuids)
|
||||
else:
|
||||
baremetal.clean_manageable_nodes(self.app.client_manager)
|
||||
|
||||
|
||||
class IntrospectNode(command.Command):
|
||||
"""Introspect specified nodes or all nodes in 'manageable' state."""
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import six
|
||||
|
||||
from tripleoclient import exceptions
|
||||
from tripleoclient.workflows import base
|
||||
|
||||
@ -78,18 +80,23 @@ def register_or_update(clients, **workflow_input):
|
||||
'Exception registering nodes: {}'.format(payload['message']))
|
||||
|
||||
|
||||
def _format_provide_errors(payload):
|
||||
def _format_errors(payload):
|
||||
errors = []
|
||||
messages = payload.get('message', [])
|
||||
for msg in messages:
|
||||
# Adapt for different formats
|
||||
if isinstance(msg, six.string_types):
|
||||
text = msg
|
||||
else:
|
||||
text = msg.get('result') or msg.get('message', '')
|
||||
try:
|
||||
# With multiple workflows, the error message can become
|
||||
# quite large and unreadable as it gets passed from task to
|
||||
# task. This attempts to keep only the last, and hopefully
|
||||
# useful part.
|
||||
errors.append(msg.get('result', '').rstrip('\n').split('\n')[-1])
|
||||
errors.append(text.rstrip('\n').split('\n')[-1])
|
||||
except Exception:
|
||||
errors.append(msg.get('result', ''))
|
||||
errors.append(text)
|
||||
return '\n'.join(errors)
|
||||
|
||||
|
||||
@ -115,7 +122,7 @@ def provide(clients, **workflow_input):
|
||||
|
||||
if payload['status'] != 'SUCCESS':
|
||||
try:
|
||||
message = _format_provide_errors(payload)
|
||||
message = _format_errors(payload)
|
||||
except Exception:
|
||||
message = 'Failed.'
|
||||
raise exceptions.NodeProvideError(
|
||||
@ -330,3 +337,58 @@ def discover_and_enroll(clients, **workflow_input):
|
||||
else:
|
||||
raise exceptions.RegisterOrUpdateError(
|
||||
'Exception discovering nodes: {}'.format(payload['message']))
|
||||
|
||||
|
||||
def clean_nodes(clients, **workflow_input):
|
||||
"""Clean Baremetal Nodes
|
||||
|
||||
Run the tripleo.baremetal.v1.clean_nodes Mistral workflow.
|
||||
"""
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
tripleoclients = clients.tripleoclient
|
||||
|
||||
with tripleoclients.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.baremetal.v1.clean_nodes',
|
||||
workflow_input={'node_uuids': workflow_input['node_uuids']}
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution):
|
||||
if payload.get('message'):
|
||||
print(payload['message'])
|
||||
|
||||
if payload['status'] != 'SUCCESS':
|
||||
message = _format_errors(payload)
|
||||
raise exceptions.NodeConfigurationError(
|
||||
'Error(s) cleaning nodes:\n{}'.format(message))
|
||||
|
||||
print('Successfully cleaned nodes')
|
||||
|
||||
|
||||
def clean_manageable_nodes(clients, **workflow_input):
|
||||
"""Clean all manageable Nodes
|
||||
|
||||
Run the tripleo.baremetal.v1.clean_manageable_nodes Mistral workflow.
|
||||
"""
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
tripleoclients = clients.tripleoclient
|
||||
|
||||
with tripleoclients.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.baremetal.v1.clean_manageable_nodes',
|
||||
workflow_input=workflow_input
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution):
|
||||
if payload.get('message'):
|
||||
print(payload['message'])
|
||||
|
||||
if payload['status'] != 'SUCCESS':
|
||||
raise exceptions.NodeConfigurationError(
|
||||
'Error cleaning nodes: {}'.format(payload['message']))
|
||||
|
||||
print('Cleaned %d node(s)' % len(payload['cleaned_nodes']))
|
||||
|
Loading…
Reference in New Issue
Block a user