Use Mistral for baremetal registration
Updates the baremetal registration workflows to use Mistral instead of python. Co-Authored-By: Dougal Matthews <dougal@redhat.com> Co-Authored-By: Ryan Brady <rbrady@redhat.com> Change-Id: Ide8b7753829170f503ef962b4ad4fde388cbb0ba Depends-On: Ifc6bdd273a8e129ea7c4269d00add64e72cd371b Depends-On: I910f50a377bcbc2c23b527953e9df7eee9c938a4
This commit is contained in:
parent
13c2afda86
commit
9244349742
@ -10,6 +10,7 @@ passlib>=1.6 # BSD
|
||||
python-ironic-inspector-client>=1.5.0 # Apache-2.0
|
||||
python-heatclient>=1.1.0 # Apache-2.0
|
||||
python-ironicclient>=1.1.0 # Apache-2.0
|
||||
python-mistralclient>=2.0.0 # Apache-2.0
|
||||
python-openstackclient>=2.1.0 # Apache-2.0
|
||||
six>=1.9.0 # MIT
|
||||
os-cloud-config # Apache-2.0
|
||||
|
@ -31,6 +31,11 @@ class UnknownService(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class WorkflowServiceError(Exception):
|
||||
"""The service type is unknown"""
|
||||
pass
|
||||
|
||||
|
||||
class NotFound(Exception):
|
||||
"""Resource not found"""
|
||||
pass
|
||||
@ -54,6 +59,14 @@ class IntrospectionError(RuntimeError):
|
||||
"""Introspection failed"""
|
||||
|
||||
|
||||
class RegisterOrUpdateError(WorkflowServiceError):
|
||||
"""Introspection failed"""
|
||||
|
||||
|
||||
class NodeProvideError(WorkflowServiceError):
|
||||
"""Node Provide failed."""
|
||||
|
||||
|
||||
class StateTransitionFailed(Exception):
|
||||
"""Ironic node state transition failed"""
|
||||
|
||||
|
@ -34,6 +34,8 @@ class FakeApp(object):
|
||||
class FakeClientManager(object):
|
||||
def __init__(self):
|
||||
self.identity = None
|
||||
self.workflow_engine = None
|
||||
self.tripleoclient = None
|
||||
self.auth_ref = None
|
||||
self.tripleoclient = FakeClientWrapper()
|
||||
|
||||
|
@ -13,8 +13,9 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import ironic_inspector_client
|
||||
import mock
|
||||
|
||||
import ironic_inspector_client
|
||||
from openstackclient.tests import utils
|
||||
|
||||
|
||||
@ -90,6 +91,19 @@ class FakeInspectorClient(object):
|
||||
return {uuid: self.states[uuid] for uuid in uuids}
|
||||
|
||||
|
||||
class ClientWrapper(object):
|
||||
|
||||
def __init__(self):
|
||||
self._instance = None
|
||||
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 TestBaremetal(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
@ -101,3 +115,10 @@ class TestBaremetal(utils.TestCommand):
|
||||
self.app.client_manager.baremetal_introspection = FakeInspectorClient()
|
||||
self.app.client_manager._region_name = "Arcadia"
|
||||
self.app.client_manager.session = mock.Mock()
|
||||
self.app.client_manager.workflow_engine = mock.Mock()
|
||||
self.app.client_manager.tripleoclient = ClientWrapper()
|
||||
|
||||
def tearDown(self):
|
||||
super(TestBaremetal, self).tearDown()
|
||||
|
||||
mock.patch.stopall()
|
||||
|
@ -339,10 +339,24 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
|
||||
}
|
||||
)
|
||||
self.mock_initial_nodes = {
|
||||
mock.Mock(uuid="ABCDEFGH", provision_state="enroll"),
|
||||
mock.Mock(uuid="IJKLMNOP", provision_state="enroll")
|
||||
}
|
||||
self.mock_websocket_success = [{
|
||||
"status": "SUCCESS",
|
||||
"registered_nodes": [{
|
||||
"uuid": "MOCK_NODE_UUID"
|
||||
}],
|
||||
}, {
|
||||
"status": "SUCCESS"
|
||||
}]
|
||||
|
||||
self.workflow = self.app.client_manager.workflow_engine
|
||||
tripleoclient = self.app.client_manager.tripleoclient
|
||||
websocket = tripleoclient.messaging_websocket()
|
||||
websocket.wait_for_message.side_effect = self.mock_websocket_success
|
||||
self.websocket = websocket
|
||||
|
||||
uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4")
|
||||
self.mock_uuid4 = uuid4_patcher.start()
|
||||
self.addCleanup(self.mock_uuid4.stop)
|
||||
|
||||
def tearDown(self):
|
||||
|
||||
@ -353,25 +367,38 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
os.unlink(self.yaml_file.name)
|
||||
os.unlink(self.instack_yaml.name)
|
||||
|
||||
def _check_register_call(self, mock_register_nodes, local=True, **kwargs):
|
||||
def _check_workflow_call(self, local=True, provide=True,
|
||||
kernel_name='bm-deploy-kernel',
|
||||
ramdisk_name='bm-deploy-ramdisk'):
|
||||
nodes_list = copy.deepcopy(self.nodes_list)
|
||||
for node in nodes_list:
|
||||
if local:
|
||||
node['capabilities'] = 'boot_option:local'
|
||||
else:
|
||||
node['capabilities'] = 'boot_option:netboot'
|
||||
kwargs.setdefault('kernel_name', 'bm-deploy-kernel')
|
||||
kwargs.setdefault('ramdisk_name', 'bm-deploy-ramdisk')
|
||||
|
||||
mock_register_nodes.assert_called_with(
|
||||
'http://localhost', nodes_list,
|
||||
client=self.app.client_manager.baremetal,
|
||||
keystone_client=None,
|
||||
glance_client=self.app.client_manager.image,
|
||||
**kwargs)
|
||||
call_list = [mock.call(
|
||||
'tripleo.baremetal.v1.register_or_update', workflow_input={
|
||||
'kernel_name': kernel_name,
|
||||
'nodes_json': nodes_list,
|
||||
'queue_name': 'UUID4',
|
||||
'ramdisk_name': ramdisk_name}
|
||||
)]
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_json_import(self, mock_register_nodes):
|
||||
if provide:
|
||||
call_list.append(mock.call(
|
||||
'tripleo.baremetal.v1.provide', workflow_input={
|
||||
'node_uuids': ['MOCK_NODE_UUID', ],
|
||||
'queue_name': 'UUID4'
|
||||
}
|
||||
))
|
||||
|
||||
self.workflow.executions.create.assert_has_calls(call_list)
|
||||
|
||||
self.assertEqual(self.workflow.executions.create.call_count,
|
||||
2 if provide else 1)
|
||||
|
||||
def test_json_import(self):
|
||||
|
||||
arglist = [self.json_file.name, '--json', '-s', 'http://localhost']
|
||||
|
||||
@ -381,18 +408,12 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
mock_register_nodes.return_value = self.mock_initial_nodes
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes)
|
||||
self.assertEqual(sorted([
|
||||
('ABCDEFGH', 'manage'), ('IJKLMNOP', 'manage'),
|
||||
('ABCDEFGH', 'provide'), ('IJKLMNOP', 'provide')
|
||||
]), sorted(self.baremetal.node.updates))
|
||||
self._check_workflow_call()
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_json_import_initial_state_enroll(self, mock_register_nodes):
|
||||
def test_json_import_initial_state_enroll(self):
|
||||
|
||||
arglist = [
|
||||
self.json_file.name,
|
||||
@ -407,14 +428,12 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
mock_register_nodes.return_value = self.mock_initial_nodes
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
self._check_register_call(mock_register_nodes)
|
||||
self._check_workflow_call(provide=False)
|
||||
self.assertEqual([], self.baremetal.node.updates)
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_available_does_not_require_api_1_11(self, mock_register_nodes):
|
||||
def test_available_does_not_require_api_1_11(self):
|
||||
arglist = [self.json_file.name, '--json', '-s', 'http://localhost']
|
||||
|
||||
verifylist = [
|
||||
@ -423,15 +442,9 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
]
|
||||
self.baremetal.http_client.os_ironic_api_version = '1.6'
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
mock_register_nodes.return_value = self.mock_initial_nodes
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
self._check_register_call(mock_register_nodes)
|
||||
|
||||
self.assertEqual(sorted([
|
||||
('ABCDEFGH', 'manage'), ('IJKLMNOP', 'manage'),
|
||||
('ABCDEFGH', 'provide'), ('IJKLMNOP', 'provide')
|
||||
]), sorted(self.baremetal.node.updates))
|
||||
self._check_workflow_call()
|
||||
|
||||
def test_enroll_requires_api_1_11(self):
|
||||
arglist = [
|
||||
@ -450,9 +463,9 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
self.assertRaisesRegexp(exceptions.InvalidConfiguration,
|
||||
'OS_BAREMETAL_API_VERSION',
|
||||
self.cmd.take_action, parsed_args)
|
||||
self.workflow.executions.create.assert_not_called()
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_json_import_detect_suffix(self, mock_register_nodes):
|
||||
def test_json_import_detect_suffix(self):
|
||||
|
||||
arglist = [self.json_file.name, '-s', 'http://localhost']
|
||||
|
||||
@ -465,10 +478,9 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes)
|
||||
self._check_workflow_call()
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_instack_json_import(self, mock_register_nodes):
|
||||
def test_instack_json_import(self):
|
||||
|
||||
arglist = [self.instack_json.name, '--json', '-s', 'http://localhost']
|
||||
|
||||
@ -478,18 +490,12 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
mock_register_nodes.return_value = self.mock_initial_nodes
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes)
|
||||
self.assertEqual(sorted([
|
||||
('ABCDEFGH', 'manage'), ('IJKLMNOP', 'manage'),
|
||||
('ABCDEFGH', 'provide'), ('IJKLMNOP', 'provide')
|
||||
]), sorted(self.baremetal.node.updates))
|
||||
self._check_workflow_call()
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_csv_import(self, mock_register_nodes):
|
||||
def test_csv_import(self):
|
||||
|
||||
arglist = [self.csv_file.name, '--csv', '-s', 'http://localhost']
|
||||
|
||||
@ -499,14 +505,12 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
mock_register_nodes.return_value = self.mock_initial_nodes
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes)
|
||||
self._check_workflow_call()
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_csv_import_detect_suffix(self, mock_register_nodes):
|
||||
def test_csv_import_detect_suffix(self):
|
||||
|
||||
arglist = [self.csv_file.name, '-s', 'http://localhost']
|
||||
|
||||
@ -519,10 +523,9 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes)
|
||||
self._check_workflow_call()
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_yaml_import(self, mock_register_nodes):
|
||||
def test_yaml_import(self):
|
||||
|
||||
arglist = [self.yaml_file.name, '-s', 'http://localhost']
|
||||
|
||||
@ -535,7 +538,7 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes)
|
||||
self._check_workflow_call()
|
||||
|
||||
def test_invalid_import_filetype(self):
|
||||
|
||||
@ -552,8 +555,7 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
'Invalid file extension',
|
||||
self.cmd.take_action, parsed_args)
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_instack_yaml_import(self, mock_register_nodes):
|
||||
def test_instack_yaml_import(self):
|
||||
|
||||
arglist = [self.instack_yaml.name, '-s', 'http://localhost']
|
||||
|
||||
@ -563,18 +565,12 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
mock_register_nodes.return_value = self.mock_initial_nodes
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes)
|
||||
self.assertEqual(sorted([
|
||||
('ABCDEFGH', 'manage'), ('IJKLMNOP', 'manage'),
|
||||
('ABCDEFGH', 'provide'), ('IJKLMNOP', 'provide')
|
||||
]), sorted(self.baremetal.node.updates))
|
||||
self._check_workflow_call()
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_netboot(self, mock_register_nodes):
|
||||
def test_netboot(self):
|
||||
|
||||
arglist = [self.json_file.name, '-s', 'http://localhost',
|
||||
'--instance-boot-option', 'netboot']
|
||||
@ -587,10 +583,9 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes, local=False)
|
||||
self._check_workflow_call(local=False)
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_custom_image(self, mock_register_nodes):
|
||||
def test_custom_image(self):
|
||||
|
||||
arglist = [self.json_file.name, '-s', 'http://localhost',
|
||||
'--deploy-kernel', 'k', '--deploy-ramdisk', 'r']
|
||||
@ -604,11 +599,9 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes, kernel_name='k',
|
||||
ramdisk_name='r')
|
||||
self._check_workflow_call(kernel_name='k', ramdisk_name='r')
|
||||
|
||||
@mock.patch('tripleo_common.utils.nodes.register_all_nodes', autospec=True)
|
||||
def test_no_image(self, mock_register_nodes):
|
||||
def test_no_image(self):
|
||||
|
||||
arglist = [self.json_file.name, '-s', 'http://localhost',
|
||||
'--no-deploy-image']
|
||||
@ -621,8 +614,7 @@ pxe_ssh,192.168.122.2,stack,"KEY2",00:0b:d0:69:7e:58""")
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self._check_register_call(mock_register_nodes, kernel_name=None,
|
||||
ramdisk_name=None)
|
||||
self._check_workflow_call(kernel_name=None, ramdisk_name=None)
|
||||
|
||||
|
||||
class TestStartBaremetalIntrospectionBulk(fakes.TestBaremetal):
|
||||
|
0
tripleoclient/tests/workflows/__init__.py
Normal file
0
tripleoclient/tests/workflows/__init__.py
Normal file
121
tripleoclient/tests/workflows/test_baremetal.py
Normal file
121
tripleoclient/tests/workflows/test_baremetal.py
Normal file
@ -0,0 +1,121 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 openstackclient.tests import utils
|
||||
|
||||
from tripleoclient import exceptions
|
||||
from tripleoclient.workflows import baremetal
|
||||
|
||||
|
||||
class TestBaremetalWorkflows(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBaremetalWorkflows, self).setUp()
|
||||
|
||||
self.app.client_manager.workflow_engine = self.workflow = 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.messaging_websocket.return_value = self.websocket
|
||||
self.app.client_manager.tripleoclient = self.tripleoclient
|
||||
|
||||
def test_register_or_update_success(self):
|
||||
|
||||
self.websocket.wait_for_message.return_value = {
|
||||
"status": "SUCCESS",
|
||||
"registered_nodes": [],
|
||||
}
|
||||
|
||||
self.assertEqual(baremetal.register_or_update(
|
||||
self.app.client_manager,
|
||||
nodes_json=[],
|
||||
queue_name="QUEUE_NAME",
|
||||
kernel_name="kernel",
|
||||
ramdisk_name="ramdisk"
|
||||
), [])
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.register_or_update',
|
||||
workflow_input={
|
||||
'kernel_name': 'kernel',
|
||||
'queue_name': 'QUEUE_NAME',
|
||||
'nodes_json': [],
|
||||
'ramdisk_name': 'ramdisk'
|
||||
})
|
||||
|
||||
def test_register_or_update_error(self):
|
||||
|
||||
self.websocket.wait_for_message.return_value = {
|
||||
"status": "FAIL",
|
||||
"message": "FAILED",
|
||||
}
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.RegisterOrUpdateError,
|
||||
baremetal.register_or_update,
|
||||
self.app.client_manager,
|
||||
nodes_json=[],
|
||||
queue_name="QUEUE_NAME",
|
||||
kernel_name="kernel",
|
||||
ramdisk_name="ramdisk"
|
||||
)
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.register_or_update',
|
||||
workflow_input={
|
||||
'kernel_name': 'kernel',
|
||||
'queue_name': 'QUEUE_NAME',
|
||||
'nodes_json': [],
|
||||
'ramdisk_name': 'ramdisk'
|
||||
})
|
||||
|
||||
def test_provide_success(self):
|
||||
|
||||
self.websocket.wait_for_message.return_value = {
|
||||
"status": "SUCCESS",
|
||||
}
|
||||
|
||||
baremetal.provide(self.app.client_manager, node_uuids=[],
|
||||
queue_name="QUEUE_NAME")
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.provide',
|
||||
workflow_input={
|
||||
'node_uuids': [],
|
||||
'queue_name': "QUEUE_NAME"
|
||||
})
|
||||
|
||||
def test_provide_error(self):
|
||||
|
||||
self.websocket.wait_for_message.return_value = {
|
||||
"status": "FAIL",
|
||||
"message": "Failed"
|
||||
}
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.NodeProvideError,
|
||||
baremetal.provide,
|
||||
self.app.client_manager,
|
||||
node_uuids=[],
|
||||
queue_name="QUEUE_NAME")
|
||||
|
||||
self.workflow.executions.create.assert_called_once_with(
|
||||
'tripleo.baremetal.v1.provide',
|
||||
workflow_input={
|
||||
'node_uuids': [],
|
||||
'queue_name': "QUEUE_NAME"
|
||||
})
|
@ -20,6 +20,7 @@ import csv
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import uuid
|
||||
import yaml
|
||||
|
||||
from cliff import command
|
||||
@ -28,10 +29,10 @@ import ironic_inspector_client
|
||||
from openstackclient.common import utils as osc_utils
|
||||
from openstackclient.i18n import _
|
||||
from oslo_utils import units
|
||||
from tripleo_common.utils import nodes
|
||||
|
||||
from tripleoclient import exceptions
|
||||
from tripleoclient import utils
|
||||
from tripleoclient.workflows import baremetal
|
||||
|
||||
|
||||
def _csv_to_nodes_dict(nodes_csv):
|
||||
@ -152,8 +153,7 @@ class ImportBaremetal(command.Command):
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ImportBaremetal, self).get_parser(prog_name)
|
||||
parser.add_argument('-s', '--service-host', dest='service_host',
|
||||
help=_('Nova compute service host to register '
|
||||
'nodes with'))
|
||||
help=_('Deprecated, this argument has no impact.'))
|
||||
parser.add_argument(
|
||||
'--json', dest='json', action='store_true',
|
||||
help=_('Deprecated, now detected via file extension.'))
|
||||
@ -210,34 +210,34 @@ class ImportBaremetal(command.Command):
|
||||
_("OS_BAREMETAL_API_VERSION must be >=1.11 for use of "
|
||||
"'enroll' provision state; currently %s") % api_version)
|
||||
|
||||
# NOTE (dprince) move this to tripleo-common?
|
||||
for node in nodes_config:
|
||||
caps = utils.capabilities_to_dict(node.get('capabilities', {}))
|
||||
caps.setdefault('boot_option', parsed_args.instance_boot_option)
|
||||
node['capabilities'] = utils.dict_to_capabilities(caps)
|
||||
|
||||
new_nodes = nodes.register_all_nodes(
|
||||
parsed_args.service_host,
|
||||
nodes_config,
|
||||
client=client,
|
||||
keystone_client=self.app.client_manager.identity,
|
||||
glance_client=self.app.client_manager.image,
|
||||
kernel_name=(parsed_args.deploy_kernel if not
|
||||
parsed_args.no_deploy_image else None),
|
||||
ramdisk_name=(parsed_args.deploy_ramdisk if not
|
||||
parsed_args.no_deploy_image else None))
|
||||
queue_name = str(uuid.uuid4())
|
||||
|
||||
if parsed_args.no_deploy_image:
|
||||
deploy_kernel = None
|
||||
deploy_ramdisk = None
|
||||
else:
|
||||
deploy_kernel = parsed_args.deploy_kernel
|
||||
deploy_ramdisk = parsed_args.deploy_ramdisk
|
||||
|
||||
nodes = baremetal.register_or_update(
|
||||
self.app.client_manager,
|
||||
nodes_json=nodes_config,
|
||||
queue_name=queue_name,
|
||||
kernel_name=deploy_kernel,
|
||||
ramdisk_name=deploy_ramdisk
|
||||
)
|
||||
|
||||
node_uuids = [node['uuid'] for node in nodes]
|
||||
|
||||
if parsed_args.initial_state == "available":
|
||||
manageable_node_uuids = list(utils.set_nodes_state(
|
||||
client, new_nodes, "manage", "manageable",
|
||||
skipped_states={'manageable', 'available'}
|
||||
))
|
||||
manageable_nodes = [
|
||||
n for n in new_nodes if n.uuid in manageable_node_uuids
|
||||
]
|
||||
list(utils.set_nodes_state(
|
||||
client, manageable_nodes, "provide", "available",
|
||||
skipped_states={'available'}
|
||||
))
|
||||
baremetal.provide(self.app.client_manager, node_uuids=node_uuids,
|
||||
queue_name=queue_name)
|
||||
|
||||
|
||||
class StartBaremetalIntrospectionBulk(command.Command):
|
||||
@ -257,9 +257,9 @@ class StartBaremetalIntrospectionBulk(command.Command):
|
||||
self.log.debug("Moving available/enroll nodes to manageable state.")
|
||||
available_nodes = utils.nodes_in_states(client,
|
||||
("available", "enroll"))
|
||||
for uuid in utils.set_nodes_state(client, available_nodes, 'manage',
|
||||
'manageable'):
|
||||
self.log.debug("Node {0} has been set to manageable.".format(uuid))
|
||||
for uu in utils.set_nodes_state(client, available_nodes, 'manage',
|
||||
'manageable'):
|
||||
self.log.debug("Node {0} has been set to manageable.".format(uu))
|
||||
|
||||
manageable_nodes = utils.nodes_in_states(client, ("manageable",))
|
||||
for node in manageable_nodes:
|
||||
@ -272,25 +272,25 @@ class StartBaremetalIntrospectionBulk(command.Command):
|
||||
errors = []
|
||||
successful_node_uuids = set()
|
||||
results = inspector_client.wait_for_finish(node_uuids)
|
||||
for uuid, status in results.items():
|
||||
for uu, status in results.items():
|
||||
if status['error'] is None:
|
||||
print("Introspection for UUID {0} finished successfully."
|
||||
.format(uuid))
|
||||
successful_node_uuids.add(uuid)
|
||||
.format(uu))
|
||||
successful_node_uuids.add(uu)
|
||||
else:
|
||||
print("Introspection for UUID {0} finished with error: {1}"
|
||||
.format(uuid, status['error']))
|
||||
errors.append("%s: %s" % (uuid, status['error']))
|
||||
.format(uu, status['error']))
|
||||
errors.append("%s: %s" % (uu, status['error']))
|
||||
|
||||
print("Setting manageable nodes to available...")
|
||||
|
||||
self.log.debug("Moving manageable nodes to available state.")
|
||||
successful_nodes = [n for n in manageable_nodes
|
||||
if n.uuid in successful_node_uuids]
|
||||
for uuid in utils.set_nodes_state(
|
||||
for uu in utils.set_nodes_state(
|
||||
client, successful_nodes, 'provide',
|
||||
'available', skipped_states=("available", "active")):
|
||||
print("Node {0} has been set to available.".format(uuid))
|
||||
print("Node {0} has been set to available.".format(uu))
|
||||
|
||||
if errors:
|
||||
raise exceptions.IntrospectionError(
|
||||
|
0
tripleoclient/workflows/__init__.py
Normal file
0
tripleoclient/workflows/__init__.py
Normal file
70
tripleoclient/workflows/baremetal.py
Normal file
70
tripleoclient/workflows/baremetal.py
Normal file
@ -0,0 +1,70 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 tripleoclient import exceptions
|
||||
|
||||
|
||||
def register_or_update(clients, **workflow_input):
|
||||
"""Node Registration or Update
|
||||
|
||||
Run the tripleo.baremetal.v1.register_or_update Mistral workflow.
|
||||
"""
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
tripleoclients = clients.tripleoclient
|
||||
queue_name = workflow_input['queue_name']
|
||||
|
||||
execution = workflow_client.executions.create(
|
||||
'tripleo.baremetal.v1.register_or_update',
|
||||
workflow_input=workflow_input
|
||||
)
|
||||
|
||||
with tripleoclients.messaging_websocket(queue_name) as ws:
|
||||
payload = ws.wait_for_message(execution.id)
|
||||
|
||||
if payload['status'] == 'SUCCESS':
|
||||
registered_nodes = payload['registered_nodes']
|
||||
for nd in registered_nodes:
|
||||
print('Successfully registered node UUID %s' % nd['uuid'])
|
||||
return registered_nodes
|
||||
else:
|
||||
raise exceptions.RegisterOrUpdateError(
|
||||
'Exception registering nodes: {}'.format(payload['message']))
|
||||
|
||||
|
||||
def provide(clients, **workflow_input):
|
||||
"""Provide Baremetal Nodes
|
||||
|
||||
Run the tripleo.baremetal.v1.provide Mistral workflow.
|
||||
"""
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
tripleoclients = clients.tripleoclient
|
||||
queue_name = workflow_input['queue_name']
|
||||
|
||||
execution = workflow_client.executions.create(
|
||||
'tripleo.baremetal.v1.provide',
|
||||
workflow_input={'node_uuids': workflow_input['node_uuids'],
|
||||
'queue_name': queue_name}
|
||||
)
|
||||
|
||||
with tripleoclients.messaging_websocket(queue_name) as ws:
|
||||
payload = ws.wait_for_message(execution.id)
|
||||
|
||||
if payload['status'] == 'SUCCESS':
|
||||
print('Successfully set all nodes to available.')
|
||||
else:
|
||||
raise exceptions.NodeProvideError(
|
||||
'Failed to set nodes to available state: {}'.format(
|
||||
payload['message']))
|
Loading…
Reference in New Issue
Block a user