Migrate the CLI introspection from Mistral to Ansible
The baremetal introspection command has been implemented in v2 using an ansible playbook instead of a mistral workflow. Story: 2007212 Task: 38444 Task: 38445 Change-Id: I61a4d1ae241bd3877abbc77bf4bad226d2502379
This commit is contained in:
parent
712d8d7a61
commit
73dfcd1b96
@ -71,7 +71,7 @@ openstack.tripleoclient.v2 =
|
||||
overcloud_node_configure = tripleoclient.v1.overcloud_node:ConfigureNode
|
||||
overcloud_node_delete = tripleoclient.v1.overcloud_node:DeleteNode
|
||||
overcloud_node_import = tripleoclient.v1.overcloud_node:ImportNode
|
||||
overcloud_node_introspect = tripleoclient.v1.overcloud_node:IntrospectNode
|
||||
overcloud_node_introspect = tripleoclient.v2.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
|
||||
@ -123,6 +123,7 @@ openstack.tripleoclient.v2 =
|
||||
tripleo_validator_run = tripleoclient.v1.tripleo_validator:TripleOValidatorRun
|
||||
tripleo_validator_show = tripleoclient.v1.tripleo_validator:TripleOValidatorShow
|
||||
tripleo_validator_show_parameter = tripleoclient.v1.tripleo_validator:TripleOValidatorShowParameter
|
||||
|
||||
oslo.config.opts =
|
||||
undercloud_config = tripleoclient.config.undercloud:list_opts
|
||||
standalone_config = tripleoclient.config.standalone:list_opts
|
||||
|
0
tripleoclient/tests/v2/overcloud_node/__init__.py
Normal file
0
tripleoclient/tests/v2/overcloud_node/__init__.py
Normal file
51
tripleoclient/tests/v2/overcloud_node/fakes.py
Normal file
51
tripleoclient/tests/v2/overcloud_node/fakes.py
Normal file
@ -0,0 +1,51 @@
|
||||
# Copyright 2015 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
import mock
|
||||
from osc_lib.tests import utils
|
||||
|
||||
|
||||
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)
|
||||
# Return False to avoid silencing exceptions
|
||||
self._mock_websocket.__exit__ = mock.Mock(return_value=False)
|
||||
|
||||
def messaging_websocket(self):
|
||||
return self._mock_websocket
|
||||
|
||||
|
||||
class TestDeleteNode(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDeleteNode, self).setUp()
|
||||
|
||||
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()
|
149
tripleoclient/tests/v2/overcloud_node/test_overcloud_node.py
Normal file
149
tripleoclient/tests/v2/overcloud_node/test_overcloud_node.py
Normal file
@ -0,0 +1,149 @@
|
||||
# Copyright 2015 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
import mock
|
||||
|
||||
from osc_lib.tests import utils as test_utils
|
||||
|
||||
from tripleoclient import constants
|
||||
from tripleoclient.tests.v2.overcloud_node import fakes
|
||||
from tripleoclient.v2 import overcloud_node
|
||||
|
||||
|
||||
class TestIntrospectNode(fakes.TestOvercloudNode):
|
||||
|
||||
def setUp(self):
|
||||
super(TestIntrospectNode, self).setUp()
|
||||
|
||||
# Get the command object to test
|
||||
self.workflow = self.app.client_manager.workflow_engine
|
||||
execution = mock.Mock()
|
||||
execution.id = "IDID"
|
||||
self.workflow.executions.create.return_value = execution
|
||||
client = self.app.client_manager.tripleoclient
|
||||
self.websocket = client.messaging_websocket()
|
||||
self.websocket.wait_for_messages.return_value = iter([{
|
||||
"status": "SUCCESS",
|
||||
"message": "Success",
|
||||
"introspected_nodes": {},
|
||||
"execution_id": execution.id
|
||||
}] * 2)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = overcloud_node.IntrospectNode(self.app, None)
|
||||
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_introspect_all_manageable_nodes_without_provide(self,
|
||||
mock_playbook):
|
||||
parsed_args = self.check_parser(self.cmd,
|
||||
['--all-manageable'],
|
||||
[('all_manageable', True)])
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_playbook.assert_called_once_with(
|
||||
workdir=mock.ANY,
|
||||
playbook=mock.ANY,
|
||||
inventory=mock.ANY,
|
||||
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||
extra_vars={
|
||||
'node_uuids': [],
|
||||
'run_validations': False,
|
||||
'concurrency': 20,
|
||||
'all_manageable': True
|
||||
}
|
||||
)
|
||||
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_introspect_all_manageable_nodes_with_provide(self,
|
||||
mock_playbook):
|
||||
parsed_args = self.check_parser(self.cmd,
|
||||
['--all-manageable', '--provide'],
|
||||
[('all_manageable', True),
|
||||
('provide', True)])
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_playbook.assert_called_once_with(
|
||||
workdir=mock.ANY,
|
||||
playbook='cli-baremetal-introspect.yaml',
|
||||
inventory=mock.ANY,
|
||||
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||
extra_vars={
|
||||
'node_uuids': [],
|
||||
'run_validations': False,
|
||||
'concurrency': 20,
|
||||
'all_manageable': True
|
||||
}
|
||||
)
|
||||
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_introspect_nodes_without_provide(self, mock_playbook):
|
||||
nodes = ['node_uuid1', 'node_uuid2']
|
||||
parsed_args = self.check_parser(self.cmd,
|
||||
nodes,
|
||||
[('node_uuids', nodes)])
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_playbook.assert_called_once_with(
|
||||
workdir=mock.ANY,
|
||||
playbook='cli-baremetal-introspect.yaml',
|
||||
inventory=mock.ANY,
|
||||
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||
extra_vars={
|
||||
'node_uuids': nodes,
|
||||
'run_validations': False,
|
||||
'concurrency': 20,
|
||||
'all_manageable': False
|
||||
}
|
||||
)
|
||||
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_introspect_nodes_with_provide(self, mock_playbook):
|
||||
nodes = ['node_uuid1', 'node_uuid2']
|
||||
argslist = nodes + ['--provide']
|
||||
parsed_args = self.check_parser(self.cmd,
|
||||
argslist,
|
||||
[('node_uuids', nodes),
|
||||
('provide', True)])
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_playbook.assert_called_once_with(
|
||||
workdir=mock.ANY,
|
||||
playbook='cli-baremetal-introspect.yaml',
|
||||
inventory=mock.ANY,
|
||||
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||
extra_vars={
|
||||
'node_uuids': nodes,
|
||||
'run_validations': False,
|
||||
'concurrency': 20,
|
||||
'all_manageable': False
|
||||
}
|
||||
)
|
||||
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_introspect_no_node_or_flag_specified(self, mock_playbook):
|
||||
self.assertRaises(test_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd, [], [])
|
||||
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_introspect_uuids_and_all_both_specified(self, mock_playbook):
|
||||
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)
|
98
tripleoclient/v2/overcloud_node.py
Normal file
98
tripleoclient/v2/overcloud_node.py
Normal file
@ -0,0 +1,98 @@
|
||||
# Copyright 2015 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
from osc_lib.i18n import _
|
||||
|
||||
from tripleoclient import command
|
||||
from tripleoclient import constants
|
||||
from tripleoclient import utils as oooutils
|
||||
from tripleoclient.workflows import baremetal
|
||||
|
||||
# NOTE(cloudnull): V1 imports, These classes will be removed as they're
|
||||
# converted from mistral to ansible.
|
||||
from tripleoclient.v1.overcloud_node import CleanNode # noqa
|
||||
from tripleoclient.v1.overcloud_node import ConfigureNode # noqa
|
||||
from tripleoclient.v1.overcloud_node import DeleteNode # noqa
|
||||
from tripleoclient.v1.overcloud_node import DiscoverNode # noqa
|
||||
from tripleoclient.v1.overcloud_node import ImportNode # noqa
|
||||
from tripleoclient.v1.overcloud_node import ProvideNode # noqa
|
||||
from tripleoclient.v1.overcloud_node import ProvisionNode # noqa
|
||||
from tripleoclient.v1.overcloud_node import UnprovisionNode # noqa
|
||||
|
||||
|
||||
class IntrospectNode(command.Command):
|
||||
"""Introspect specified nodes or all nodes in 'manageable' state."""
|
||||
|
||||
log = logging.getLogger(__name__ + ".IntrospectNode")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(IntrospectNode, 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 '
|
||||
'introspected'))
|
||||
group.add_argument("--all-manageable",
|
||||
action='store_true',
|
||||
help=_("Introspect all nodes currently in "
|
||||
"'manageable' state"))
|
||||
parser.add_argument('--provide',
|
||||
action='store_true',
|
||||
help=_('Provide (make available) the nodes once '
|
||||
'introspected'))
|
||||
parser.add_argument('--run-validations', action='store_true',
|
||||
default=False,
|
||||
help=_('Run the pre-deployment validations. These '
|
||||
'external validations are from the TripleO '
|
||||
'Validations project.'))
|
||||
parser.add_argument('--concurrency', type=int,
|
||||
default=20,
|
||||
help=_('Maximum number of nodes to introspect at '
|
||||
'once.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
|
||||
extra_vars = {
|
||||
"node_uuids": parsed_args.node_uuids,
|
||||
"run_validations": parsed_args.run_validations,
|
||||
"concurrency": parsed_args.concurrency,
|
||||
"all_manageable": parsed_args.all_manageable,
|
||||
}
|
||||
|
||||
with oooutils.TempDirs() as tmp:
|
||||
oooutils.run_ansible_playbook(
|
||||
playbook='cli-baremetal-introspect.yaml',
|
||||
inventory='localhost,',
|
||||
workdir=tmp,
|
||||
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||
extra_vars=extra_vars
|
||||
)
|
||||
|
||||
# NOTE(cloudnull): This is using the old provide function, in a future
|
||||
# release this may be ported to a standalone playbook
|
||||
if parsed_args.provide:
|
||||
if parsed_args.node_uuids:
|
||||
baremetal.provide(
|
||||
self.app.client_manager,
|
||||
node_uuids=parsed_args.node_uuids,
|
||||
)
|
||||
else:
|
||||
baremetal.provide_manageable_nodes(self.app.client_manager)
|
Loading…
x
Reference in New Issue
Block a user