Update export system configuration
- Add optional parameters export_use and include_in_export to private export system configuration method. - Add public export_system_configuration method. Story: 2003594 Task: 41575 Change-Id: Id8d66cdec203308771ab4cb8909505f96b984296
This commit is contained in:
parent
1020e805d3
commit
03278551f1
|
@ -58,3 +58,56 @@ IMPORT_SHUTDOWN_NO_REBOOT = 'no shutdown'
|
||||||
|
|
||||||
No shutdown performed. Explicit reboot is necessary to apply changes.
|
No shutdown performed. Explicit reboot is necessary to apply changes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# ExportUse in ExportSystemConfiguration
|
||||||
|
EXPORT_USE_DEFAULT = 'Default'
|
||||||
|
"""Default export type
|
||||||
|
|
||||||
|
Leaves some attributes commented out and requires user to enable them before
|
||||||
|
they can be applied during import.
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXPORT_USE_CLONE = 'Clone'
|
||||||
|
"""Clone export type suitable for cloning a 'golden' configuration.
|
||||||
|
|
||||||
|
Compared to Default export type, more attributes are enabled and
|
||||||
|
storage settings adjusted to aid in cloning process.
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXPORT_USE_REPLACE = 'Replace'
|
||||||
|
"""Replace export type suited for retiring or replacing complete configuration.
|
||||||
|
|
||||||
|
Compared to Clone export type, most attributes are enabled and storage settings
|
||||||
|
adjusted to aid in the replace process.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# IncludeInExport in ExportSystemConfiguration
|
||||||
|
INCLUDE_EXPORT_DEFAULT = 'Default'
|
||||||
|
"""Default for what to include in export.
|
||||||
|
|
||||||
|
Does not include read-only attributes, and depending on Export Use, passwords
|
||||||
|
are marked as ****** (for Default) or are set to default password values (for
|
||||||
|
Clone and Replace).
|
||||||
|
"""
|
||||||
|
|
||||||
|
INCLUDE_EXPORT_READ_ONLY = 'Include read only attributes'
|
||||||
|
"""Includes read-only attributes.
|
||||||
|
|
||||||
|
In addition to values included by Default option, this also includes read-only
|
||||||
|
attributes that cannot be changed via Import and are provided for informational
|
||||||
|
purposes only.
|
||||||
|
"""
|
||||||
|
|
||||||
|
INCLUDE_EXPORT_PASSWORD_HASHES = 'Include password hash values'
|
||||||
|
"""Include password hashes.
|
||||||
|
|
||||||
|
When using Clone or Replace, include password hashes, instead of default
|
||||||
|
password. Can be used to replicate passwords across systems.
|
||||||
|
"""
|
||||||
|
|
||||||
|
INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES = ('Include read only attributes and '
|
||||||
|
'password hash values')
|
||||||
|
"""Includes both read-only attributes and password hashes.
|
||||||
|
|
||||||
|
INCLUDE_EXPORT_READ_ONLY and INCLUDE_EXPORT_PASSWORD_HASHES combined
|
||||||
|
"""
|
||||||
|
|
|
@ -47,6 +47,10 @@ class SharedParameters(base.CompositeField):
|
||||||
|
|
||||||
class ExportActionField(common.ActionField):
|
class ExportActionField(common.ActionField):
|
||||||
shared_parameters = SharedParameters('ShareParameters')
|
shared_parameters = SharedParameters('ShareParameters')
|
||||||
|
allowed_export_use_values = base.Field(
|
||||||
|
'ExportUse@Redfish.AllowableValues', adapter=list)
|
||||||
|
allowed_include_in_export_values = base.Field(
|
||||||
|
'IncludeInExport@Redfish.AllowableValues', adapter=list)
|
||||||
|
|
||||||
|
|
||||||
class ImportActionField(common.ActionField):
|
class ImportActionField(common.ActionField):
|
||||||
|
@ -270,18 +274,60 @@ VFDD\
|
||||||
set(mgr_maps.EXPORT_CONFIG_VALUE_MAP).
|
set(mgr_maps.EXPORT_CONFIG_VALUE_MAP).
|
||||||
intersection(allowed_values)])
|
intersection(allowed_values)])
|
||||||
|
|
||||||
def _export_system_configuration(self, target):
|
def get_allowed_export_use_values(self):
|
||||||
|
"""Get allowed export use values of export system configuration.
|
||||||
|
|
||||||
|
:returns: A set of allowed export use values.
|
||||||
|
"""
|
||||||
|
export_action = self._actions.export_system_configuration
|
||||||
|
allowed_values = export_action.allowed_export_use_values
|
||||||
|
|
||||||
|
if not allowed_values:
|
||||||
|
LOG.warning('Could not figure out the allowed values for the '
|
||||||
|
'export use of export system configuration at %s',
|
||||||
|
self.path)
|
||||||
|
return set(mgr_maps.EXPORT_USE_VALUE_MAP_REV)
|
||||||
|
|
||||||
|
return set([mgr_maps.EXPORT_USE_VALUE_MAP[value] for value in
|
||||||
|
set(mgr_maps.EXPORT_USE_VALUE_MAP).
|
||||||
|
intersection(allowed_values)])
|
||||||
|
|
||||||
|
def get_allowed_include_in_export_values(self):
|
||||||
|
"""Get allowed include in export values of export system configuration.
|
||||||
|
|
||||||
|
:returns: A set of allowed include in export values.
|
||||||
|
"""
|
||||||
|
export_action = self._actions.export_system_configuration
|
||||||
|
allowed_values = export_action.allowed_include_in_export_values
|
||||||
|
|
||||||
|
if not allowed_values:
|
||||||
|
LOG.warning('Could not figure out the allowed values for the '
|
||||||
|
'include in export of export system configuration at '
|
||||||
|
'%s', self.path)
|
||||||
|
return set(mgr_maps.INCLUDE_EXPORT_VALUE_MAP_REV)
|
||||||
|
|
||||||
|
return set([mgr_maps.INCLUDE_EXPORT_VALUE_MAP[value] for value
|
||||||
|
in set(mgr_maps.INCLUDE_EXPORT_VALUE_MAP).
|
||||||
|
intersection(allowed_values)])
|
||||||
|
|
||||||
|
def _export_system_configuration(
|
||||||
|
self, target, export_use=mgr_cons.EXPORT_USE_DEFAULT,
|
||||||
|
include_in_export=mgr_cons.INCLUDE_EXPORT_DEFAULT):
|
||||||
"""Export system configuration.
|
"""Export system configuration.
|
||||||
|
|
||||||
It exports system configuration for specified target
|
It exports system configuration for specified target like NIC, BIOS,
|
||||||
like NIC, BIOS, RAID.
|
RAID and allows to configure purpose for export and what to include.
|
||||||
|
|
||||||
:param target: Component of the system to export the
|
:param target: Component of the system to export the
|
||||||
configuration from. Can be the entire system.
|
configuration from. Can be the entire system.
|
||||||
Valid values can be gotten from
|
Valid values can be gotten from
|
||||||
`get_allowed_export_target_values`.
|
`get_allowed_export_system_config_values`.
|
||||||
:returns: a response object containing configuration details for
|
:param export_use: Export use. Optional, defaults to "Default".
|
||||||
the specified target.
|
Valid values can be gotten from `get_allowed_export_use_values`.
|
||||||
|
:param include_in_export: What to include in export. Optional. Defaults
|
||||||
|
to "Default". Valid values can be gotten from
|
||||||
|
`get_allowed_include_in_export_values`.
|
||||||
|
:returns: Response object containing configuration details.
|
||||||
:raises: InvalidParameterValueError on invalid target.
|
:raises: InvalidParameterValueError on invalid target.
|
||||||
:raises: ExtensionError on failure to perform requested
|
:raises: ExtensionError on failure to perform requested
|
||||||
operation
|
operation
|
||||||
|
@ -292,13 +338,30 @@ VFDD\
|
||||||
parameter='target', value=target,
|
parameter='target', value=target,
|
||||||
valid_values=valid_allowed_targets)
|
valid_values=valid_allowed_targets)
|
||||||
|
|
||||||
|
allowed_export_use = self.get_allowed_export_use_values()
|
||||||
|
if export_use not in allowed_export_use:
|
||||||
|
raise sushy.exceptions.InvalidParameterValueError(
|
||||||
|
parameter='export_use', value=export_use,
|
||||||
|
valid_values=allowed_export_use)
|
||||||
|
|
||||||
|
allowed_include_in_export = self.get_allowed_include_in_export_values()
|
||||||
|
if include_in_export not in allowed_include_in_export:
|
||||||
|
raise sushy.exceptions.InvalidParameterValueError(
|
||||||
|
parameter='include_in_export', value=include_in_export,
|
||||||
|
valid_values=allowed_include_in_export)
|
||||||
|
|
||||||
target = mgr_maps.EXPORT_CONFIG_VALUE_MAP_REV[target]
|
target = mgr_maps.EXPORT_CONFIG_VALUE_MAP_REV[target]
|
||||||
|
export_use = mgr_maps.EXPORT_USE_VALUE_MAP_REV[export_use]
|
||||||
|
include_in_export =\
|
||||||
|
mgr_maps.INCLUDE_EXPORT_VALUE_MAP_REV[include_in_export]
|
||||||
|
|
||||||
action_data = {
|
action_data = {
|
||||||
'ShareParameters': {
|
'ShareParameters': {
|
||||||
'Target': target
|
'Target': target
|
||||||
},
|
},
|
||||||
'ExportFormat': "JSON"
|
'ExportFormat': "JSON",
|
||||||
|
'ExportUse': export_use,
|
||||||
|
'IncludeInExport': include_in_export
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -318,6 +381,21 @@ VFDD\
|
||||||
LOG.error('Dell OEM export system configuration failed : %s', exc)
|
LOG.error('Dell OEM export system configuration failed : %s', exc)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def export_system_configuration(self):
|
||||||
|
"""Export system configuration.
|
||||||
|
|
||||||
|
Exports ALL targets for cloning and includes password hashes.
|
||||||
|
|
||||||
|
:returns: Response object containing configuration details.
|
||||||
|
:raises: InvalidParameterValueError on invalid target.
|
||||||
|
:raises: ExtensionError on failure to perform requested
|
||||||
|
operation
|
||||||
|
"""
|
||||||
|
return self._export_system_configuration(
|
||||||
|
mgr_cons.EXPORT_TARGET_ALL,
|
||||||
|
export_use=mgr_cons.EXPORT_USE_CLONE,
|
||||||
|
include_in_export=mgr_cons.INCLUDE_EXPORT_PASSWORD_HASHES)
|
||||||
|
|
||||||
def get_pxe_port_macs_bios(self, ethernet_interfaces_mac):
|
def get_pxe_port_macs_bios(self, ethernet_interfaces_mac):
|
||||||
"""Get a list of pxe port MAC addresses for BIOS.
|
"""Get a list of pxe port MAC addresses for BIOS.
|
||||||
|
|
||||||
|
|
|
@ -41,3 +41,23 @@ IMPORT_SHUTDOWN_VALUE_MAP = {
|
||||||
|
|
||||||
IMPORT_SHUTDOWN_VALUE_MAP_REV =\
|
IMPORT_SHUTDOWN_VALUE_MAP_REV =\
|
||||||
utils.revert_dictionary(IMPORT_SHUTDOWN_VALUE_MAP)
|
utils.revert_dictionary(IMPORT_SHUTDOWN_VALUE_MAP)
|
||||||
|
|
||||||
|
EXPORT_USE_VALUE_MAP = {
|
||||||
|
'Default': mgr_cons.EXPORT_USE_DEFAULT,
|
||||||
|
'Clone': mgr_cons.EXPORT_USE_CLONE,
|
||||||
|
'Replace': mgr_cons.EXPORT_USE_REPLACE
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_USE_VALUE_MAP_REV = utils.revert_dictionary(EXPORT_USE_VALUE_MAP)
|
||||||
|
|
||||||
|
INCLUDE_EXPORT_VALUE_MAP = {
|
||||||
|
'Default': mgr_cons.INCLUDE_EXPORT_DEFAULT,
|
||||||
|
'IncludeReadOnly': mgr_cons.INCLUDE_EXPORT_READ_ONLY,
|
||||||
|
'IncludePasswordHashValues':
|
||||||
|
mgr_cons.INCLUDE_EXPORT_PASSWORD_HASHES,
|
||||||
|
'IncludeReadOnly,IncludePasswordHashValues':
|
||||||
|
mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES
|
||||||
|
}
|
||||||
|
|
||||||
|
INCLUDE_EXPORT_VALUE_MAP_REV =\
|
||||||
|
utils.revert_dictionary(INCLUDE_EXPORT_VALUE_MAP)
|
||||||
|
|
|
@ -100,7 +100,26 @@ class ManagerTestCase(BaseTestCase):
|
||||||
'/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager'
|
'/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager'
|
||||||
'.ExportSystemConfiguration', data={'ShareParameters':
|
'.ExportSystemConfiguration', data={'ShareParameters':
|
||||||
{'Target': 'ALL'},
|
{'Target': 'ALL'},
|
||||||
'ExportFormat': 'JSON'})
|
'ExportFormat': 'JSON',
|
||||||
|
'ExportUse': 'Default',
|
||||||
|
'IncludeInExport': 'Default'})
|
||||||
|
|
||||||
|
@mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {})
|
||||||
|
def test__export_system_configuration_nondefault(self):
|
||||||
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
oem._export_system_configuration(
|
||||||
|
target=mgr_cons.EXPORT_TARGET_RAID,
|
||||||
|
export_use=mgr_cons.EXPORT_USE_CLONE,
|
||||||
|
include_in_export=mgr_cons.INCLUDE_EXPORT_READ_ONLY)
|
||||||
|
|
||||||
|
self.conn.post.assert_called_once_with(
|
||||||
|
'/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager'
|
||||||
|
'.ExportSystemConfiguration', data={'ShareParameters':
|
||||||
|
{'Target': 'RAID'},
|
||||||
|
'ExportFormat': 'JSON',
|
||||||
|
'ExportUse': 'Clone',
|
||||||
|
'IncludeInExport':
|
||||||
|
'IncludeReadOnly'})
|
||||||
|
|
||||||
@mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {})
|
@mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {})
|
||||||
def test__export_system_configuration_invalid_target(self):
|
def test__export_system_configuration_invalid_target(self):
|
||||||
|
@ -109,6 +128,87 @@ class ManagerTestCase(BaseTestCase):
|
||||||
self.assertRaises(sushy.exceptions.InvalidParameterValueError,
|
self.assertRaises(sushy.exceptions.InvalidParameterValueError,
|
||||||
oem._export_system_configuration, target)
|
oem._export_system_configuration, target)
|
||||||
|
|
||||||
|
def test__export_system_configuration_invalid_export_use(self):
|
||||||
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
self.assertRaises(sushy.exceptions.InvalidParameterValueError,
|
||||||
|
oem._export_system_configuration, "RAID",
|
||||||
|
export_use="ABC")
|
||||||
|
|
||||||
|
def test__export_system_configuration_invalid_include_in_export(self):
|
||||||
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
self.assertRaises(sushy.exceptions.InvalidParameterValueError,
|
||||||
|
oem._export_system_configuration, "RAID",
|
||||||
|
include_in_export="ABC")
|
||||||
|
|
||||||
|
@mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {})
|
||||||
|
def test_get_allowed_export_use_values(self):
|
||||||
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
expected_values = {mgr_cons.EXPORT_USE_DEFAULT,
|
||||||
|
mgr_cons.EXPORT_USE_CLONE,
|
||||||
|
mgr_cons.EXPORT_USE_REPLACE}
|
||||||
|
allowed_values = oem.get_allowed_export_use_values()
|
||||||
|
self.assertIsInstance(allowed_values, set)
|
||||||
|
self.assertEqual(expected_values, allowed_values)
|
||||||
|
|
||||||
|
@mock.patch.object(oem_manager, 'LOG', autospec=True)
|
||||||
|
def test_get_allowed_export_use_values_missing(self, mock_log):
|
||||||
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
export_action = ('OemManager.v1_0_0'
|
||||||
|
'#OemManager.ExportSystemConfiguration')
|
||||||
|
oem.json['Actions']['Oem'][export_action].pop(
|
||||||
|
'ExportUse@Redfish.AllowableValues')
|
||||||
|
oem.refresh()
|
||||||
|
expected_values = {mgr_cons.EXPORT_USE_DEFAULT,
|
||||||
|
mgr_cons.EXPORT_USE_CLONE,
|
||||||
|
mgr_cons.EXPORT_USE_REPLACE}
|
||||||
|
allowed_values = oem.get_allowed_export_use_values()
|
||||||
|
self.assertIsInstance(allowed_values, set)
|
||||||
|
self.assertEqual(expected_values, allowed_values)
|
||||||
|
mock_log.warning.assert_called_once()
|
||||||
|
|
||||||
|
@mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {})
|
||||||
|
def test_get_allowed_include_in_export_values(self):
|
||||||
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
expected_values = {mgr_cons.INCLUDE_EXPORT_DEFAULT,
|
||||||
|
mgr_cons.INCLUDE_EXPORT_READ_ONLY,
|
||||||
|
mgr_cons.INCLUDE_EXPORT_PASSWORD_HASHES,
|
||||||
|
mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES}
|
||||||
|
allowed_values = oem.get_allowed_include_in_export_values()
|
||||||
|
self.assertIsInstance(allowed_values, set)
|
||||||
|
self.assertEqual(expected_values, allowed_values)
|
||||||
|
|
||||||
|
@mock.patch.object(oem_manager, 'LOG', autospec=True)
|
||||||
|
def test_get_allowed_include_in_export_values_missing(self, mock_log):
|
||||||
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
export_action = ('OemManager.v1_0_0'
|
||||||
|
'#OemManager.ExportSystemConfiguration')
|
||||||
|
oem.json['Actions']['Oem'][export_action].pop(
|
||||||
|
'IncludeInExport@Redfish.AllowableValues')
|
||||||
|
oem.refresh()
|
||||||
|
expected_values = {mgr_cons.INCLUDE_EXPORT_DEFAULT,
|
||||||
|
mgr_cons.INCLUDE_EXPORT_READ_ONLY,
|
||||||
|
mgr_cons.INCLUDE_EXPORT_PASSWORD_HASHES,
|
||||||
|
mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES}
|
||||||
|
allowed_values = oem.get_allowed_include_in_export_values()
|
||||||
|
self.assertIsInstance(allowed_values, set)
|
||||||
|
self.assertEqual(expected_values, allowed_values)
|
||||||
|
mock_log.warning.assert_called_once()
|
||||||
|
|
||||||
|
@mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {})
|
||||||
|
def test_export_system_configuration(self):
|
||||||
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
oem._export_system_configuration = mock.Mock()
|
||||||
|
mock_response = mock.Mock()
|
||||||
|
oem._export_system_configuration.return_value = mock_response
|
||||||
|
|
||||||
|
response = oem.export_system_configuration()
|
||||||
|
|
||||||
|
self.assertEqual(mock_response, response)
|
||||||
|
oem._export_system_configuration.assert_called_once_with(
|
||||||
|
mgr_cons.EXPORT_TARGET_ALL,
|
||||||
|
export_use=mgr_cons.EXPORT_USE_CLONE,
|
||||||
|
include_in_export=mgr_cons.INCLUDE_EXPORT_PASSWORD_HASHES)
|
||||||
|
|
||||||
@mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {})
|
@mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {})
|
||||||
def test_get_pxe_port_macs_bios(self):
|
def test_get_pxe_port_macs_bios(self):
|
||||||
oem = self.manager.get_oem_extension('Dell')
|
oem = self.manager.get_oem_extension('Dell')
|
||||||
|
|
Loading…
Reference in New Issue