Adds an option for setting the http boot uri
In order to utilize Http Boot from URL, we need to be able to set the the parameter to the remote BMC. This enables a greater level of security as the URL and ultimately the instruction comes from an authenticated source, i.e. the BMC connection, and not DHCP which is the fallback if a target is set to UefiHttp. We now also unset the the http boot uri if it is set and we're not setting an explicit URI to use. This keeps the state of the data clean in order to prevent any unexpected behavior. Change-Id: I73ae614ffe735bd055090ded32926a5416a12fc0
This commit is contained in:
parent
82772d3424
commit
7340b340c1
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Adds functionality to the ``set_system_boot_options`` method
|
||||
permitting an ``http_boot_uri`` option to be set.
|
||||
- |
|
||||
Adds an ``http_boot_uri`` option to the System boot object,
|
||||
permitting an API client user to view what the BMC's
|
||||
redfish ``HttpBootUri`` setting is.
|
|
@ -56,6 +56,8 @@ class BootField(base.CompositeField):
|
|||
|
||||
target = base.MappedField('BootSourceOverrideTarget', sys_cons.BootSource)
|
||||
|
||||
http_boot_uri = base.Field('HttpBootUri')
|
||||
|
||||
|
||||
class MemorySummaryField(base.CompositeField):
|
||||
health = base.Field(['Status', 'HealthRollup'])
|
||||
|
@ -212,7 +214,8 @@ class System(base.ResourceBase):
|
|||
return {v for v in sys_cons.BootSource
|
||||
if v.value in self.boot.allowed_values}
|
||||
|
||||
def set_system_boot_options(self, target=None, enabled=None, mode=None):
|
||||
def set_system_boot_options(self, target=None, enabled=None, mode=None,
|
||||
http_boot_uri=None):
|
||||
"""Set boot source and/or boot frequency and/or boot mode.
|
||||
|
||||
Set the boot source and/or boot frequency and/or boot mode to use
|
||||
|
@ -220,10 +223,19 @@ class System(base.ResourceBase):
|
|||
|
||||
:param target: The target boot source,
|
||||
a :py:class:`sushy.BootSource` value. Optional.
|
||||
:param enabled: How long the override be enabled,
|
||||
:param enabled: How long the override is enabled,
|
||||
a :py:class:`sushy.BootSourceOverrideEnabled` value. Optional.
|
||||
:param mode: The boot mode,
|
||||
a :py:class:`sushy.BootSourceOverrideMode` value. Optional.
|
||||
:param http_boot_uri: The requested HTTP Boot URI to transmit to the
|
||||
BMC. Only valid when BootSourceOverrideTarget is set to UefiHTTP,
|
||||
when utilizing the ``target`` parameter. If no value is supplied,
|
||||
and the target is set to UefiHTTP, then an empty value will be
|
||||
sent to the BMC to remove any prior setting, allowing the host
|
||||
to load configuration from DHCP.
|
||||
If not explicitly set, any value will be removed from a BMC when
|
||||
UefiHttp boot is not engaged.
|
||||
|
||||
:raises: InvalidParameterValueError, if any information passed is
|
||||
invalid.
|
||||
"""
|
||||
|
@ -235,6 +247,7 @@ class System(base.ResourceBase):
|
|||
settings_boot_section = settings_resp.json().get('Boot', {})
|
||||
else:
|
||||
settings_resp = None
|
||||
settings_boot_section = {}
|
||||
|
||||
if target is not None:
|
||||
valid_targets = self.get_allowed_system_boot_source_values()
|
||||
|
@ -293,6 +306,25 @@ class System(base.ResourceBase):
|
|||
else:
|
||||
data['Boot']['BootSourceOverrideMode'] = fishy_mode
|
||||
|
||||
if target == sys_cons.BootSource.UEFI_HTTP:
|
||||
# The http_boot_uri value *can* be set independently of the
|
||||
# target, but the BMC will just ignore it unless the target
|
||||
# is set. So we should only, and explicitly set it when we've
|
||||
# been requested to boot from UefiHTTP.
|
||||
if not http_boot_uri:
|
||||
# This should clear out any old entries, as no URI translates
|
||||
# to the intent of "use whatever the dhcp server says".
|
||||
data['Boot']['HttpBootUri'] = None
|
||||
else:
|
||||
# Explicilty set the URI.
|
||||
data['Boot']['HttpBootUri'] = http_boot_uri
|
||||
elif not http_boot_uri:
|
||||
# We're not doing boot from URL, we should cleanup any setting
|
||||
# which may be from a prior step/call.
|
||||
if settings_boot_section.get('HttpBootUri'):
|
||||
# If the setting is present, and has any value, unset it.
|
||||
data['Boot']['HttpBootUri'] = None
|
||||
|
||||
# TODO(lucasagomes): Check the return code and response body ?
|
||||
# Probably we should call refresh() as well.
|
||||
if settings_data.get('Boot'):
|
||||
|
|
|
@ -36,10 +36,12 @@
|
|||
"Utilities",
|
||||
"Diags",
|
||||
"SDCard",
|
||||
"UefiTarget"
|
||||
"UefiTarget",
|
||||
"UefiHttp"
|
||||
],
|
||||
"BootSourceOverrideMode": "UEFI",
|
||||
"UefiTargetBootSourceOverride": "/0x31/0x33/0x01/0x01"
|
||||
"UefiTargetBootSourceOverride": "/0x31/0x33/0x01/0x01",
|
||||
"HttpBootUri": "https://Contoso.lan/boot.iso"
|
||||
},
|
||||
"TrustedModules": [
|
||||
{
|
||||
|
|
|
@ -243,7 +243,8 @@ class SystemTestCase(base.TestCase):
|
|||
sushy.BootSource.UTILITIES,
|
||||
sushy.BootSource.DIAGS,
|
||||
sushy.BootSource.SD_CARD,
|
||||
sushy.BootSource.UEFI_TARGET])
|
||||
sushy.BootSource.UEFI_TARGET,
|
||||
sushy.BootSource.UEFI_HTTP])
|
||||
self.assertEqual(expected, values)
|
||||
self.assertIsInstance(values, set)
|
||||
|
||||
|
@ -477,6 +478,57 @@ class SystemTestCase(base.TestCase):
|
|||
data={'Boot': {'BootSourceOverrideMode': 'UEFI'}},
|
||||
etag='"3d7b838291941d"')
|
||||
|
||||
def test_set_system_boot_options_httpbooturi(self):
|
||||
self.sys_inst.set_system_boot_options(
|
||||
sushy.BootSource.UEFI_HTTP,
|
||||
enabled=sushy.BootSourceOverrideEnabled.ONCE,
|
||||
mode=sushy.BootSourceOverrideMode.UEFI,
|
||||
http_boot_uri='http://test.lan/test_image.iso'
|
||||
)
|
||||
self.sys_inst._conn.patch.assert_called_once_with(
|
||||
'/redfish/v1/Systems/437XR1138R2',
|
||||
data={'Boot': {'BootSourceOverrideTarget': 'UefiHttp',
|
||||
'BootSourceOverrideEnabled': 'Once',
|
||||
'BootSourceOverrideMode': 'UEFI',
|
||||
'HttpBootUri': 'http://test.lan/test_image.iso'}},
|
||||
etag=mock.ANY)
|
||||
|
||||
def test_set_system_boot_options_httpboot(self):
|
||||
self.sys_inst.set_system_boot_options(
|
||||
sushy.BootSource.UEFI_HTTP,
|
||||
enabled=sushy.BootSourceOverrideEnabled.ONCE,
|
||||
mode=sushy.BootSourceOverrideMode.UEFI
|
||||
)
|
||||
self.sys_inst._conn.patch.assert_called_once_with(
|
||||
'/redfish/v1/Systems/437XR1138R2',
|
||||
data={'Boot': {'BootSourceOverrideTarget': 'UefiHttp',
|
||||
'BootSourceOverrideEnabled': 'Once',
|
||||
'BootSourceOverrideMode': 'UEFI',
|
||||
'HttpBootUri': None}},
|
||||
etag=mock.ANY)
|
||||
|
||||
def test_set_system_boot_options_httpboot_unset(self):
|
||||
self.sys_inst._settings = mock.Mock()
|
||||
self.sys_inst._settings.resource_uri = 'meow'
|
||||
settings_body = json.dumps(
|
||||
{'Boot': {'HttpBootUri': 'http://foo.bar'}}
|
||||
)
|
||||
|
||||
get_settings = mock.MagicMock()
|
||||
get_settings.json.return_value = settings_body
|
||||
self.conn.get.side_effect = get_settings
|
||||
|
||||
self.sys_inst.set_system_boot_options(
|
||||
sushy.BootSource.HDD,
|
||||
mode=sushy.BootSourceOverrideMode.UEFI
|
||||
)
|
||||
self.sys_inst._conn.patch.assert_called_once_with(
|
||||
'/redfish/v1/Systems/437XR1138R2',
|
||||
data={'Boot': {'BootSourceOverrideTarget': 'Hdd',
|
||||
'BootSourceOverrideMode': 'UEFI',
|
||||
'HttpBootUri': None}},
|
||||
etag=mock.ANY)
|
||||
|
||||
def test_set_system_boot_source(self):
|
||||
self.sys_inst.set_system_boot_source(
|
||||
sushy.BootSource.PXE,
|
||||
|
@ -512,6 +564,16 @@ class SystemTestCase(base.TestCase):
|
|||
'BootSourceOverrideTarget': 'Hdd'}},
|
||||
etag=None)
|
||||
|
||||
def test_set_system_boot_unsets_http_boot_uri(self):
|
||||
self.sys_inst.set_system_boot_source(
|
||||
sushy.BootSource.HDD,
|
||||
enabled=sushy.BootSourceOverrideEnabled.ONCE)
|
||||
self.sys_inst._conn.patch.assert_called_once_with(
|
||||
'/redfish/v1/Systems/437XR1138R2',
|
||||
data={'Boot': {'BootSourceOverrideEnabled': 'Once',
|
||||
'BootSourceOverrideTarget': 'Hdd'}},
|
||||
etag=mock.ANY)
|
||||
|
||||
def test_set_system_boot_source_invalid_target(self):
|
||||
self.assertRaises(exceptions.InvalidParameterValueError,
|
||||
self.sys_inst.set_system_boot_source,
|
||||
|
|
Loading…
Reference in New Issue