Make redfish_system_id
property optional
The `redfish_system_id` property of redfish hardware type has been made optional. If not specified in `driver_info`, and the target BMC manages a single ComputerSystem, ironic will assume that system. Otherwise, ironic will fail requiring explicit `redfish_system_id` specification in `driver_info`. Also bumpted sushy dependency to >= 3.1.0. Change-Id: I425baa7c7294c6c8a707e89df63a17da8e49b666 Story: 2007258 Task: 38619
This commit is contained in:
parent
0d0a8a6631
commit
c99347faef
@ -56,11 +56,14 @@ field:
|
|||||||
missing, https is assumed.
|
missing, https is assumed.
|
||||||
For example: https://mgmt.vendor.com. This is required.
|
For example: https://mgmt.vendor.com. This is required.
|
||||||
|
|
||||||
- ``redfish_system_id``: The canonical path to the System resource that
|
- ``redfish_system_id``: The canonical path to the ComputerSystem resource
|
||||||
the driver will interact with. It should include
|
that the driver will interact with. It should include
|
||||||
the root service, version and the unique
|
the root service, version and the unique resource
|
||||||
resource path to the System. For example:
|
path to the ComputerSystem. This property is only
|
||||||
/redfish/v1/Systems/1. This is required.
|
required if target BMC manages more than one
|
||||||
|
ComputerSystem. Otherwise ironic will pick the only
|
||||||
|
available ComputerSystem automatically. For
|
||||||
|
example: /redfish/v1/Systems/1.
|
||||||
|
|
||||||
- ``redfish_username``: User account with admin/server-profile access
|
- ``redfish_username``: User account with admin/server-profile access
|
||||||
privilege. Although not required, it is highly
|
privilege. Although not required, it is highly
|
||||||
|
@ -11,7 +11,7 @@ python-dracclient>=3.1.0,<4.0.0
|
|||||||
python-xclarityclient>=0.1.6
|
python-xclarityclient>=0.1.6
|
||||||
|
|
||||||
# The Redfish hardware type uses the Sushy library
|
# The Redfish hardware type uses the Sushy library
|
||||||
sushy>=2.0.0
|
sushy>=3.1.0
|
||||||
|
|
||||||
# Ansible-deploy interface
|
# Ansible-deploy interface
|
||||||
ansible>=2.5
|
ansible>=2.5
|
||||||
|
@ -37,16 +37,19 @@ REQUIRED_PROPERTIES = {
|
|||||||
'must include the authority portion of the URL. '
|
'must include the authority portion of the URL. '
|
||||||
'If the scheme is missing, https is assumed. '
|
'If the scheme is missing, https is assumed. '
|
||||||
'For example: https://mgmt.vendor.com. Required'),
|
'For example: https://mgmt.vendor.com. Required'),
|
||||||
|
}
|
||||||
|
|
||||||
|
OPTIONAL_PROPERTIES = {
|
||||||
'redfish_system_id': _('The canonical path to the ComputerSystem '
|
'redfish_system_id': _('The canonical path to the ComputerSystem '
|
||||||
'resource that the driver will interact with. '
|
'resource that the driver will interact with. '
|
||||||
'It should include the root service, version and '
|
'It should include the root service, version and '
|
||||||
'the unique resource path to a ComputerSystem '
|
'the unique resource path to a ComputerSystem '
|
||||||
'within the same authority as the redfish_address '
|
'within the same authority as the redfish_address '
|
||||||
'property. For example: /redfish/v1/Systems/1. '
|
'property. For example: /redfish/v1/Systems/1. '
|
||||||
'Required')
|
'This property is only required if target BMC '
|
||||||
}
|
'manages more than one ComputerSystem. Otherwise '
|
||||||
|
'ironic will pick the only available '
|
||||||
OPTIONAL_PROPERTIES = {
|
'ComputerSystem automatically.'),
|
||||||
'redfish_username': _('User account with admin/server-profile access '
|
'redfish_username': _('User account with admin/server-profile access '
|
||||||
'privilege. Although this property is not '
|
'privilege. Although this property is not '
|
||||||
'mandatory it\'s highly recommended to set a '
|
'mandatory it\'s highly recommended to set a '
|
||||||
@ -109,8 +112,10 @@ def parse_driver_info(node):
|
|||||||
'driver_info/redfish_address on node %(node)s') %
|
'driver_info/redfish_address on node %(node)s') %
|
||||||
{'address': address, 'node': node.uuid})
|
{'address': address, 'node': node.uuid})
|
||||||
|
|
||||||
|
redfish_system_id = driver_info.get('redfish_system_id')
|
||||||
|
if redfish_system_id is not None:
|
||||||
try:
|
try:
|
||||||
system_id = urlparse.quote(driver_info['redfish_system_id'])
|
redfish_system_id = urlparse.quote(redfish_system_id)
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
raise exception.InvalidParameterValue(
|
raise exception.InvalidParameterValue(
|
||||||
_('Invalid value "%(value)s" set in '
|
_('Invalid value "%(value)s" set in '
|
||||||
@ -154,7 +159,7 @@ def parse_driver_info(node):
|
|||||||
{'value': auth_type, 'node': node.uuid})
|
{'value': auth_type, 'node': node.uuid})
|
||||||
|
|
||||||
return {'address': address,
|
return {'address': address,
|
||||||
'system_id': system_id,
|
'system_id': redfish_system_id,
|
||||||
'username': driver_info.get('redfish_username'),
|
'username': driver_info.get('redfish_username'),
|
||||||
'password': driver_info.get('redfish_password'),
|
'password': driver_info.get('redfish_password'),
|
||||||
'verify_ca': verify_ca,
|
'verify_ca': verify_ca,
|
||||||
@ -234,7 +239,7 @@ def get_system(node):
|
|||||||
:raises: RedfishError if the System is not registered in Redfish
|
:raises: RedfishError if the System is not registered in Redfish
|
||||||
"""
|
"""
|
||||||
driver_info = parse_driver_info(node)
|
driver_info = parse_driver_info(node)
|
||||||
system_id = driver_info['system_id']
|
system_id = driver_info.get('system_id')
|
||||||
|
|
||||||
@retrying.retry(
|
@retrying.retry(
|
||||||
retry_on_exception=(
|
retry_on_exception=(
|
||||||
@ -249,7 +254,8 @@ def get_system(node):
|
|||||||
except sushy.exceptions.ResourceNotFoundError as e:
|
except sushy.exceptions.ResourceNotFoundError as e:
|
||||||
LOG.error('The Redfish System "%(system)s" was not found for '
|
LOG.error('The Redfish System "%(system)s" was not found for '
|
||||||
'node %(node)s. Error %(error)s',
|
'node %(node)s. Error %(error)s',
|
||||||
{'system': system_id, 'node': node.uuid, 'error': e})
|
{'system': system_id or '<default>',
|
||||||
|
'node': node.uuid, 'error': e})
|
||||||
raise exception.RedfishError(error=e)
|
raise exception.RedfishError(error=e)
|
||||||
# TODO(lucasagomes): We should look at other types of
|
# TODO(lucasagomes): We should look at other types of
|
||||||
# ConnectionError such as AuthenticationError or SSLError and stop
|
# ConnectionError such as AuthenticationError or SSLError and stop
|
||||||
@ -259,7 +265,7 @@ def get_system(node):
|
|||||||
'Redfish at address "%(address)s" using auth type '
|
'Redfish at address "%(address)s" using auth type '
|
||||||
'"%(auth_type)s" when fetching System "%(system)s". '
|
'"%(auth_type)s" when fetching System "%(system)s". '
|
||||||
'Error: %(error)s',
|
'Error: %(error)s',
|
||||||
{'system': system_id,
|
{'system': system_id or '<default>',
|
||||||
'address': driver_info['address'],
|
'address': driver_info['address'],
|
||||||
'auth_type': driver_info['auth_type'],
|
'auth_type': driver_info['auth_type'],
|
||||||
'node': node.uuid, 'error': e})
|
'node': node.uuid, 'error': e})
|
||||||
|
@ -122,6 +122,10 @@ class RedfishUtilsTestCase(db_base.DbTestCase):
|
|||||||
'The value should be a path',
|
'The value should be a path',
|
||||||
redfish_utils.parse_driver_info, self.node)
|
redfish_utils.parse_driver_info, self.node)
|
||||||
|
|
||||||
|
def test_parse_driver_info_missing_system_id(self):
|
||||||
|
self.node.driver_info.pop('redfish_system_id')
|
||||||
|
redfish_utils.parse_driver_info(self.node)
|
||||||
|
|
||||||
def test_parse_driver_info_valid_string_value_verify_ca(self):
|
def test_parse_driver_info_valid_string_value_verify_ca(self):
|
||||||
for value in ('0', 'f', 'false', 'off', 'n', 'no'):
|
for value in ('0', 'f', 'false', 'off', 'n', 'no'):
|
||||||
self.node.driver_info['redfish_verify_ca'] = value
|
self.node.driver_info['redfish_verify_ca'] = value
|
||||||
@ -182,6 +186,15 @@ class RedfishUtilsTestCase(db_base.DbTestCase):
|
|||||||
fake_conn.get_system.assert_called_once_with(
|
fake_conn.get_system.assert_called_once_with(
|
||||||
'/redfish/v1/Systems/FAKESYSTEM')
|
'/redfish/v1/Systems/FAKESYSTEM')
|
||||||
|
|
||||||
|
@mock.patch.object(sushy, 'Sushy', autospec=True)
|
||||||
|
@mock.patch('ironic.drivers.modules.redfish.utils.'
|
||||||
|
'SessionCache._sessions', {})
|
||||||
|
def test_get_system_multiple_systems(self, mock_sushy):
|
||||||
|
self.node.driver_info.pop('redfish_system_id')
|
||||||
|
fake_conn = mock_sushy.return_value
|
||||||
|
redfish_utils.get_system(self.node)
|
||||||
|
fake_conn.get_system.assert_called_once_with(None)
|
||||||
|
|
||||||
@mock.patch('time.sleep', autospec=True)
|
@mock.patch('time.sleep', autospec=True)
|
||||||
@mock.patch.object(sushy, 'Sushy', autospec=True)
|
@mock.patch.object(sushy, 'Sushy', autospec=True)
|
||||||
@mock.patch('ironic.drivers.modules.redfish.utils.'
|
@mock.patch('ironic.drivers.modules.redfish.utils.'
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The ``redfish_system_id`` property of redfish hardware type has been made
|
||||||
|
optional. If not specified in ``driver_info``, and the target BMC manages
|
||||||
|
a single ComputerSystem, ironic will assume that system. Otherwise, ironic
|
||||||
|
will fail requiring explicit ``redfish_system_id`` specification in
|
||||||
|
``driver_info``. The minimum version for the sushy library is now
|
||||||
|
3.1.0.
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user