Add 'openstack overcloud node provide' command

Change-Id: Id8660fc63ff29478b4f40d9a3f656e26f8149426
Partial-Bug: #1595205
This commit is contained in:
Julie Pichon 2016-06-27 10:11:42 +01:00
parent f1398ac51b
commit 13011dc041
4 changed files with 144 additions and 0 deletions

View File

@ -67,6 +67,7 @@ openstack.tripleoclient.v1 =
overcloud_image_build = tripleoclient.v1.overcloud_image:BuildOvercloudImage
overcloud_image_upload = tripleoclient.v1.overcloud_image:UploadOvercloudImage
overcloud_node_delete = tripleoclient.v1.overcloud_node:DeleteNode
overcloud_node_provide = tripleoclient.v1.overcloud_node:ProvideNode
overcloud_profiles_match = tripleoclient.v1.overcloud_profiles:MatchProfiles
overcloud_profiles_list = tripleoclient.v1.overcloud_profiles:ListProfiles
overcloud_update_stack = tripleoclient.v1.overcloud_update:UpdateOvercloud

View File

@ -21,6 +21,13 @@ class FakeClientWrapper(object):
def __init__(self):
self._instance = mock.Mock()
self._mock_websocket = mock.Mock()
self._mock_websocket.__enter__ = mock.Mock(
return_value=self._mock_websocket)
self._mock_websocket.__exit__ = mock.Mock()
def messaging_websocket(self, queue_name='tripleo'):
return self._mock_websocket
class TestDeleteNode(utils.TestCommand):
@ -31,3 +38,17 @@ class TestDeleteNode(utils.TestCommand):
self.app.client_manager.auth_ref = mock.Mock(auth_token="TOKEN")
self.app.client_manager.orchestration = mock.Mock()
self.app.client_manager.tripleoclient = FakeClientWrapper()
class TestOvercloudNode(utils.TestCommand):
def setUp(self):
super(TestOvercloudNode, self).setUp()
self.app.client_manager.baremetal = mock.Mock()
self.app.client_manager.workflow_engine = mock.Mock()
self.app.client_manager.tripleoclient = FakeClientWrapper()
uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4")
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)

View File

@ -15,6 +15,9 @@
import mock
from openstackclient.tests import utils as test_utils
from tripleoclient.tests.v1.overcloud_node import fakes
from tripleoclient.v1 import overcloud_node
@ -42,3 +45,86 @@ class TestDeleteNode(fakes.TestDeleteNode):
scale_manager.scaledown(parsed_args.nodes)
scale_manager.scaledown.assert_called_once_with(['instance1',
'instance2'])
class TestProvideNode(fakes.TestOvercloudNode):
def setUp(self):
super(TestProvideNode, self).setUp()
self.workflow = self.app.client_manager.workflow_engine
client = self.app.client_manager.tripleoclient
self.websocket = client.messaging_websocket()
# Get the command object to test
self.cmd = overcloud_node.ProvideNode(self.app, None)
def test_provide_all_manageable_nodes(self):
self.websocket.wait_for_message.return_value = {
"status": "SUCCESS",
"message": ""
}
parsed_args = self.check_parser(self.cmd,
['--all-manageable'],
[('all_manageable', True)])
self.cmd.take_action(parsed_args)
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.provide_manageable_nodes',
workflow_input={'queue_name': 'UUID4'}
)
def test_provide_one_node(self):
node_id = 'node_uuid1'
self.websocket.wait_for_message.return_value = {
"status": "SUCCESS",
"message": "Success"
}
parsed_args = self.check_parser(self.cmd,
[node_id],
[('node_uuids', [node_id])])
self.cmd.take_action(parsed_args)
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.provide', workflow_input={
'node_uuids': [node_id],
'queue_name': 'UUID4'}
)
def test_provide_multiple_nodes(self):
node_id1 = 'node_uuid1'
node_id2 = 'node_uuid2'
self.websocket.wait_for_message.return_value = {
"status": "SUCCESS",
"message": "Success"
}
argslist = [node_id1, node_id2]
verifylist = [('node_uuids', [node_id1, node_id2])]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.provide', workflow_input={
'node_uuids': [node_id1, node_id2],
'queue_name': 'UUID4'
}
)
def test_provide_no_node_or_flag_specified(self):
self.assertRaises(test_utils.ParserException,
self.check_parser,
self.cmd, [], [])
def test_provide_uuids_and_all_both_specified(self):
argslist = ['node_id1', 'node_id2', '--all-manageable']
verifylist = [('node_uuids', ['node_id1', 'node_id2']),
('all_manageable', True)]
self.assertRaises(test_utils.ParserException,
self.check_parser,
self.cmd, argslist, verifylist)

View File

@ -14,6 +14,7 @@
#
import logging
import uuid
from cliff import command
from openstackclient.common import utils
@ -21,6 +22,7 @@ from openstackclient.i18n import _
from tripleo_common import scale
from tripleoclient import constants
from tripleoclient.workflows import baremetal
class DeleteNode(command.Command):
@ -62,3 +64,37 @@ class DeleteNode(command.Command):
print("deleting nodes {0} from stack {1}".format(parsed_args.nodes,
parsed_args.stack))
scale_manager.scaledown(parsed_args.nodes)
class ProvideNode(command.Command):
"""Mark nodes as available based on UUIDs or current 'manageable' state."""
log = logging.getLogger(__name__ + ".ProvideNode")
def get_parser(self, prog_name):
parser = super(ProvideNode, self).get_parser(prog_name)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('node_uuids',
nargs="*",
metavar="<node_uuid>",
default=[],
help=_('Ironic UUIDs for the node(s) to be '
'provided'))
group.add_argument("--all-manageable",
action='store_true',
help=_("Provide all nodes currently in 'manageable'"
" state"))
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args)
queue_name = str(uuid.uuid4())
if parsed_args.node_uuids:
baremetal.provide(self.app.client_manager,
node_uuids=parsed_args.node_uuids,
queue_name=queue_name)
else:
baremetal.provide_manageable_nodes(self.app.client_manager,
queue_name=queue_name)