Merge "Skip BMC detection in IPA for out-of-band management"
This commit is contained in:
@@ -43,7 +43,23 @@ _LOOKUP_RETURN_FIELDS = ['uuid', 'properties', 'instance_info',
|
||||
AGENT_VALID_STATES = ['start', 'end', 'error']
|
||||
|
||||
|
||||
def config(token):
|
||||
def config(token, node=None):
|
||||
# Skip BMC detection for out-of-band management interfaces where
|
||||
# the BMC address is already known and configured in Ironic
|
||||
skip_bmc_detect = False
|
||||
if node:
|
||||
mgmt_iface = getattr(node, 'management_interface', '')
|
||||
# Out-of-band interfaces that don't need BMC detection
|
||||
skip_bmc_detect = mgmt_iface in (
|
||||
'redfish', 'idrac-redfish',
|
||||
'ilo', 'ilo5', 'ilo6',
|
||||
'irmc'
|
||||
)
|
||||
if skip_bmc_detect:
|
||||
LOG.debug('Skipping BMC detection for node %(node)s with '
|
||||
'out-of-band management interface %(interface)s',
|
||||
{'node': node.uuid, 'interface': mgmt_iface})
|
||||
|
||||
return {
|
||||
'metrics': {
|
||||
'backend': CONF.metrics.agent_backend,
|
||||
@@ -74,13 +90,16 @@ def config(token):
|
||||
'agent_md5_checksum_enable': CONF.agent.allow_md5_checksum,
|
||||
'disable_deep_image_inspection': CONF.conductor.disable_deep_image_inspection, # noqa
|
||||
'permitted_image_formats': CONF.conductor.permitted_image_formats,
|
||||
'agent_skip_bmc_detect': skip_bmc_detect,
|
||||
}
|
||||
|
||||
|
||||
def convert_with_links(node):
|
||||
token = node.driver_internal_info.get('agent_secret_token')
|
||||
# Keep raw node for management_interface check before conversion
|
||||
raw_node = node
|
||||
node = node_ctl.node_convert_with_links(node, _LOOKUP_RETURN_FIELDS)
|
||||
return {'node': node, 'config': config(token)}
|
||||
return {'node': node, 'config': config(token, raw_node)}
|
||||
|
||||
|
||||
def get_valid_mac_addresses(addresses, node_uuid=None):
|
||||
|
||||
@@ -64,7 +64,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
node.driver_internal_info = driver_internal
|
||||
self.mock_get_node_with_token.return_value = node
|
||||
|
||||
def _check_config(self, data):
|
||||
def _check_config(self, data, skip_bmc_detect=False):
|
||||
expected_config = {
|
||||
'agent_containers': {
|
||||
'allow_arbitrary_containers': CONF.agent_containers
|
||||
@@ -97,6 +97,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
'agent_md5_checksum_enable': CONF.agent.allow_md5_checksum,
|
||||
'disable_deep_image_inspection': CONF.conductor.disable_deep_image_inspection, # noqa
|
||||
'permitted_image_formats': CONF.conductor.permitted_image_formats,
|
||||
'agent_skip_bmc_detect': skip_bmc_detect,
|
||||
}
|
||||
self.assertEqual(expected_config, data['config'])
|
||||
self.assertIsNotNone(data['config']['agent_token'])
|
||||
@@ -226,6 +227,85 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
|
||||
def test_bmc_detect_skip_for_redfish(self):
|
||||
"""Test BMC detection skip is enabled for Redfish interface."""
|
||||
self.node.management_interface = 'redfish'
|
||||
self.node.save()
|
||||
self._set_secret_mock(self.node, 'test-token')
|
||||
|
||||
data = self.get_json(
|
||||
'/lookup?node_uuid=%s' % self.node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self._check_config(data, skip_bmc_detect=True)
|
||||
|
||||
def test_bmc_detect_skip_for_ilo_variants(self):
|
||||
"""Test BMC detection skip is enabled for iLO variants."""
|
||||
for ilo_interface in ['ilo', 'ilo5', 'ilo6']:
|
||||
self.node.management_interface = ilo_interface
|
||||
self.node.save()
|
||||
self._set_secret_mock(self.node, 'test-token')
|
||||
|
||||
data = self.get_json(
|
||||
'/lookup?node_uuid=%s' % self.node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self._check_config(data, skip_bmc_detect=True)
|
||||
|
||||
def test_bmc_detect_skip_for_idrac_redfish(self):
|
||||
"""Test BMC detection skip is enabled for iDRAC Redfish."""
|
||||
self.node.management_interface = 'idrac-redfish'
|
||||
self.node.save()
|
||||
self._set_secret_mock(self.node, 'test-token')
|
||||
|
||||
data = self.get_json(
|
||||
'/lookup?node_uuid=%s' % self.node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self._check_config(data, skip_bmc_detect=True)
|
||||
|
||||
def test_bmc_detect_skip_for_irmc(self):
|
||||
"""Test BMC detection skip is enabled for iRMC."""
|
||||
self.node.management_interface = 'irmc'
|
||||
self.node.save()
|
||||
self._set_secret_mock(self.node, 'test-token')
|
||||
|
||||
data = self.get_json(
|
||||
'/lookup?node_uuid=%s' % self.node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self._check_config(data, skip_bmc_detect=True)
|
||||
|
||||
def test_bmc_detect_not_skipped_for_ipmi(self):
|
||||
"""Test BMC detection is NOT skipped for IPMI interface."""
|
||||
self.node.management_interface = 'ipmitool'
|
||||
self.node.save()
|
||||
self._set_secret_mock(self.node, 'test-token')
|
||||
|
||||
data = self.get_json(
|
||||
'/lookup?node_uuid=%s' % self.node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self._check_config(data, skip_bmc_detect=False)
|
||||
|
||||
def test_bmc_detect_not_skipped_for_fake(self):
|
||||
"""Test BMC detection is NOT skipped for fake interface."""
|
||||
self.node.management_interface = 'fake'
|
||||
self.node.save()
|
||||
self._set_secret_mock(self.node, 'test-token')
|
||||
|
||||
data = self.get_json(
|
||||
'/lookup?node_uuid=%s' % self.node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self._check_config(data, skip_bmc_detect=False)
|
||||
|
||||
|
||||
@mock.patch.object(rpcapi.ConductorAPI, 'get_topic_for',
|
||||
lambda *n: 'test-topic')
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The lookup API now includes an ``agent_skip_bmc_detect`` configuration
|
||||
flag that is automatically set to True when nodes use out-of-band
|
||||
management interfaces (Redfish, iDRAC Redfish, iLO, iRMC). This tells
|
||||
the agent to skip BMC detection via ipmitool, reducing deployment
|
||||
time and avoiding unnecessary ipmitool calls when the BMC address is
|
||||
already configured in Ironic.
|
||||
Reference in New Issue
Block a user