diff --git a/releasenotes/notes/add_message_and_attribute_registries-71e14a53bfa658da.yaml b/releasenotes/notes/add_message_and_attribute_registries-71e14a53bfa658da.yaml new file mode 100644 index 00000000..99175297 --- /dev/null +++ b/releasenotes/notes/add_message_and_attribute_registries-71e14a53bfa658da.yaml @@ -0,0 +1,8 @@ +--- +features: + - | + Adds support for returning message and attribute (particularly BIOS + attribute) registries. Also adds two additional BIOS settings - + 'SecureBootStatus' and 'SerialNumber'. 'SecureBootStatus' has 'ReadOnly' + set to true and 'SecureBootStatus' has 'IsSystemUniqueProperty' in the + registry. diff --git a/sushy_tools/emulator/main.py b/sushy_tools/emulator/main.py index e82cd0ff..458a7bdb 100755 --- a/sushy_tools/emulator/main.py +++ b/sushy_tools/emulator/main.py @@ -800,6 +800,49 @@ def volume(identity, stg_id, vol_id): return 'Not Found', 404 +@app.route('/redfish/v1/Registries') +@returns_json +def registry_file_collection(): + app.logger.debug('Serving registry file collection') + + return flask.render_template( + 'registry_file_collection.json') + + +@app.route('/redfish/v1/Registries/BiosAttributeRegistry.v1_0_0') +@returns_json +def bios_attribute_registry_file(): + app.logger.debug('Serving BIOS attribute registry file') + + return flask.render_template( + 'bios_attribute_registry_file.json') + + +@app.route('/redfish/v1/Registries/Messages') +@returns_json +def message_registry_file(): + app.logger.debug('Serving message registry file') + + return flask.render_template( + 'message_registry_file.json') + + +@app.route('/redfish/v1/Systems//Bios/BiosRegistry') +@returns_json +def bios_registry(identity): + app.logger.debug('Serving BIOS registry') + + return flask.render_template('bios_registry.json', identity=identity) + + +@app.route('/redfish/v1/Registries/Messages/Registry') +@returns_json +def message_registry(): + app.logger.debug('Serving message registry') + + return flask.render_template('message_registry.json') + + def parse_args(): parser = argparse.ArgumentParser('sushy-emulator') parser.add_argument('--config', diff --git a/sushy_tools/emulator/resources/systems/libvirtdriver.py b/sushy_tools/emulator/resources/systems/libvirtdriver.py index 0d800098..8d1ef396 100644 --- a/sushy_tools/emulator/resources/systems/libvirtdriver.py +++ b/sushy_tools/emulator/resources/systems/libvirtdriver.py @@ -127,7 +127,9 @@ class LibvirtDriver(AbstractSystemsDriver): DEFAULT_BIOS_ATTRIBUTES = {"BootMode": "Uefi", "EmbeddedSata": "Raid", "NicBoot1": "NetworkBoot", - "ProcTurboMode": "Enabled"} + "ProcTurboMode": "Enabled", + "SecureBootStatus": "Enabled", + "SerialNumber": "QPX12345"} STORAGE_POOL = 'default' diff --git a/sushy_tools/emulator/templates/bios_attribute_registry_file.json b/sushy_tools/emulator/templates/bios_attribute_registry_file.json new file mode 100644 index 00000000..e091ea22 --- /dev/null +++ b/sushy_tools/emulator/templates/bios_attribute_registry_file.json @@ -0,0 +1,20 @@ +{ + "@odata.context": "/redfish/v1/$metadata#MessageRegistryFile.MessageRegistryFile", + "@odata.id": "/redfish/v1/Registries/BiosAttributeRegistry.v1_0_0", + "@odata.type": "#MessageRegistryFile.v1_1_0.MessageRegistryFile", + "Description": "BIOS Attribute Registry File locations", + "Id": "BiosAttributeRegistry.v1_0_0", + "Languages": [ + "en" + ], + "Location": [ + { + "Language": "en", + "Uri": "/redfish/v1/Systems/Bios/BiosRegistry" + } + ], + "Name": "BIOS Attribute Registry File", + "Oem": { + }, + "Registry": "BiosAttributeRegistry1.0" +} diff --git a/sushy_tools/emulator/templates/bios_registry.json b/sushy_tools/emulator/templates/bios_registry.json new file mode 100644 index 00000000..39077b07 --- /dev/null +++ b/sushy_tools/emulator/templates/bios_registry.json @@ -0,0 +1,137 @@ +{ + "@odata.context": "/redfish/v1/$metadata#AttributeRegistry.AttributeRegistry", + "@odata.id": {{ "/redfish/v1/Systems/%s/Bios/BiosRegistry"|format(identity)|tojson }}, + "@odata.type": "#AttributeRegistry.v1_1_1.AttributeRegistry", + "Description": "This registry defines a representation of BIOS Attribute instances", + "Id": "BiosAttributeRegistryP89.v1_0_0", + "Language": "en", + "Name": "BIOS Attribute Registry", + "OwningEntity": "VendorA", + "RegistryVersion": "1.1.1", + "RegistryEntries": { + "Attributes": [ + { + "AttributeName": "ProcTurboMode", + "CurrentValue": null, + "DisplayName": "Turbo Boost", + "HelpText": "Governs the Turbo Boost Technology. This feature allows the processor cores to be automatically clocked up in frequency beyond the advertised processor speed.", + "Hidden": false, + "Immutable": false, + "ReadOnly": false, + "Type": "Enumeration", + "Value": [ + { + "ValueDisplayName": "Enabled", + "ValueName": "Enabled" + }, + { + "ValueDisplayName": "Disabled", + "ValueName": "Disabled" + } + ], + "WarningText": null, + "WriteOnly": false + }, + { + "AttributeName": "BootMode", + "CurrentValue": null, + "DisplayName": "Boot Mode", + "HelpText": "This field determines the boot mode of the system.\n\nSelecting 'UEFI' enables booting to Unified Extensible Firmware Interface (UEFI) capable operating systems.\n\nSelecting 'BIOS' (the default) ensures compatibility with operating systems that do not support UEFI.", + "Hidden": false, + "Immutable": false, + "ReadOnly": false, + "Type": "Enumeration", + "Value": [ + { + "ValueDisplayName": "BIOS", + "ValueName": "Bios" + }, + { + "ValueDisplayName": "UEFI", + "ValueName": "Uefi" + } + ], + "WarningText": null, + "WriteOnly": false + }, + { + "AttributeName": "EmbeddedSata", + "CurrentValue": null, + "DisplayName": "Embedded SATA", + "HelpText": "Allows the Embedded SATA to be set to Off, ATA, AHCI or RAID Mode.", + "Hidden": false, + "Immutable": false, + "ReadOnly": false, + "Type": "Enumeration", + "Value": [ + { + "ValueDisplayName": "ATA Mode", + "ValueName": "Ata" + }, + { + "ValueDisplayName": "AHCI Mode", + "ValueName": "Ahci" + }, + { + "ValueDisplayName": "RAID Mode", + "ValueName": "Raid" + }, + { + "ValueDisplayName": "Off", + "ValueName": "Off" + } + ], + "WarningText": null, + "WriteOnly": false + }, + { + "AttributeName": "NicBoot1", + "DisplayName": "Embedded NIC 1 Boot", + "HelpText": "Use this option to enable or disable network boot (PXE, iSCSI, FCoE or UEFI HTTP) for the selected NIC. You might need to configure the NIC firmware for the boot option to be active.", + "ReadOnly": false, + "Type": "Enumeration", + "CurrentValue": null, + "Value": [ + { + "ValueName": "NetworkBoot", + "ValueDisplayName": "Network Boot" + }, + { + "ValueName": "Disabled", + "ValueDisplayName": "Disabled" + } + ] + }, + { + "AttributeName": "SecureBootStatus", + "DisplayName": "Secure Boot Status", + "HelpText": "The current state of Secure Boot configuration.", + "ReadOnly": true, + "Immutable": true, + "Type": "Enumeration", + "CurrentValue": null, + "Value": [ + { + "ValueName": "Enabled", + "ValueDisplayName": "Enabled" + }, + { + "ValueName": "Disabled", + "ValueDisplayName": "Disabled" + } + ] + }, + { + "AttributeName": "SerialNumber", + "DisplayName": "Serial Number", + "HelpText": "Use this option to set the system serial number.", + "ReadOnly": false, + "MaxLength": 16, + "MinLength": 0, + "Type": "String", + "CurrentValue": null, + "IsSystemUniqueProperty": true + } + ] + } +} diff --git a/sushy_tools/emulator/templates/message_registry.json b/sushy_tools/emulator/templates/message_registry.json new file mode 100644 index 00000000..b293ace8 --- /dev/null +++ b/sushy_tools/emulator/templates/message_registry.json @@ -0,0 +1,62 @@ +{ + "@odata.context" : "/redfish/v1/$metadata#MessageRegistry.MessageRegistry", + "@odata.id" : "/redfish/v1/Registries/Messages/Registry", + "@odata.type" : "#MessageRegistry.v1_1_1.MessageRegistry", + "Id": "1.1.1", + "Name": "Message Registry", + "Language": "en", + "RegistryVersion": "1.1.1", + "Description": "This registry defines the messages for Redfish", + "RegistryPrefix": "Msg", + "OwningEntity": "VendorA", + "Messages": { + "AMP0300": { + "Description": "None.", + "Message": "The system board %1 current is less than the lower warning threshold.", + "Severity": "Warning", + "NumberOfArgs": 1, + "ParamTypes": [ + "string" + ], + "Resolution": "Review system power policy and review system configuration changes." + }, + "BIOS001": { + "Description": "The command was successful.", + "Message": "The command was successful", + "Severity": "Informational", + "NumberOfArgs": 0, + "Resolution": "No response action is required." + }, + "BIOS002": { + "Description": "Unable to allocate required memory to perform the requested operation", + "Message": "Resource allocation failure.", + "Severity": "Critical", + "NumberOfArgs": 0, + "Resolution": "Power cycle system." + }, + "BIOS003": { + "Description": "An invalid number of arguments was passed to the method.", + "Message": "Missing required parameter. Refer to the inserted comment.", + "Severity": "Warning", + "NumberOfArgs": 0, + "Resolution": "Enter all the required command parameters. Check documentation and try again." + }, + "BIOS004": { + "Description": "The value for the specified parameter is invalid.", + "Message": "Invalid parameter value for %1", + "Severity": "Warning", + "NumberOfArgs": 1, + "ParamTypes": [ + "string" + ], + "Resolution": "Verify that parameter values passed to the method are entered as they appear in the enumeration and parameter data type matches the documentation." + }, + "BIOS005": { + "Description": "The number of AttributeName and AttributeValue parameters do not match.", + "Message": "Mismatch in AttributeName and AttributeValue count", + "Severity": "Warning", + "NumberOfArgs": 0, + "Resolution": "Enter the same number of parameters for AttributeName and AttributeValue. Refer to documentation for method input parameter details." + } + } +} diff --git a/sushy_tools/emulator/templates/message_registry_file.json b/sushy_tools/emulator/templates/message_registry_file.json new file mode 100644 index 00000000..c37b4bd6 --- /dev/null +++ b/sushy_tools/emulator/templates/message_registry_file.json @@ -0,0 +1,20 @@ +{ + "@odata.context": "/redfish/v1/$metadata#MessageRegistryFile.MessageRegistryFile", + "@odata.id": "/redfish/v1/Registries/Messages", + "@odata.type": "#MessageRegistryFile.v1_1_1.MessageRegistryFile", + "Description": "Message Registry File locations", + "Id": "Messages", + "Languages": [ + "En" + ], + "Languages@odata.count": 1, + "Location": [ + { + "Language": "En", + "Uri": "/redfish/v1/Registries/Messages/Registry" + } + ], + "Location@odata.count": 1, + "Name": "Message Registry File", + "Registry": "Base.1.0" +} diff --git a/sushy_tools/emulator/templates/registry_file_collection.json b/sushy_tools/emulator/templates/registry_file_collection.json new file mode 100644 index 00000000..43f8d211 --- /dev/null +++ b/sushy_tools/emulator/templates/registry_file_collection.json @@ -0,0 +1,16 @@ +{ + "@odata.context": "/redfish/v1/$metadata#MessageRegistryFileCollection.MessageRegistryFileCollection", + "@odata.id": "/redfish/v1/Registries", + "@odata.type": "#MessageRegistryFileCollection.MessageRegistryFileCollection", + "Description": "Registry Repository", + "Members": [ + { + "@odata.id": "/redfish/v1/Registries/Messages" + }, + { + "@odata.id": "/redfish/v1/Registries/BiosAttributeRegistry.v1_0_0" + } + ], + "Members@odata.count": 2, + "Name": "Registry File Collection" +} diff --git a/sushy_tools/emulator/templates/root.json b/sushy_tools/emulator/templates/root.json index 8f00fc81..7557b18a 100644 --- a/sushy_tools/emulator/templates/root.json +++ b/sushy_tools/emulator/templates/root.json @@ -10,6 +10,9 @@ "Managers": { "@odata.id": "/redfish/v1/Managers" }, + "Registries": { + "@odata.id": "/redfish/v1/Registries" + }, "@odata.id": "/redfish/v1/", "@Redfish.Copyright": "Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright." } diff --git a/sushy_tools/tests/unit/emulator/domain_bios.xml b/sushy_tools/tests/unit/emulator/domain_bios.xml index 1651dbf2..6240f689 100644 --- a/sushy_tools/tests/unit/emulator/domain_bios.xml +++ b/sushy_tools/tests/unit/emulator/domain_bios.xml @@ -26,4 +26,4 @@ - + diff --git a/sushy_tools/tests/unit/emulator/resources/systems/test_libvirt.py b/sushy_tools/tests/unit/emulator/resources/systems/test_libvirt.py index e89386a2..2cd26def 100644 --- a/sushy_tools/tests/unit/emulator/resources/systems/test_libvirt.py +++ b/sushy_tools/tests/unit/emulator/resources/systems/test_libvirt.py @@ -805,7 +805,9 @@ class LibvirtDriverTestCase(base.BaseTestCase): self.assertEqual({"BootMode": "Bios", "EmbeddedSata": "Raid", "NicBoot1": "NetworkBoot", - "ProcTurboMode": "Disabled"}, + "ProcTurboMode": "Disabled", + "SecureBootStatus": "Enabled", + "SerialNumber": "QPX12345"}, bios_attributes) conn_mock.defineXML.assert_not_called() @@ -871,7 +873,9 @@ class LibvirtDriverTestCase(base.BaseTestCase): self.assertEqual({"BootMode": "Bios", "EmbeddedSata": "Raid", "NicBoot1": "NetworkBoot", - "ProcTurboMode": "Disabled"}, + "ProcTurboMode": "Disabled", + "SecureBootStatus": "Enabled", + "SerialNumber": "QPX12345"}, result.bios_attributes) self._assert_bios_xml(result.tree) diff --git a/sushy_tools/tests/unit/emulator/test_main.py b/sushy_tools/tests/unit/emulator/test_main.py index 3c2e82af..66413bc8 100644 --- a/sushy_tools/tests/unit/emulator/test_main.py +++ b/sushy_tools/tests/unit/emulator/test_main.py @@ -771,3 +771,86 @@ class StorageTestCase(EmulatorTestCase): self.assertEqual('Sample Volume 1', response.json['Name']) self.assertEqual('Mirrored', response.json['VolumeType']) self.assertEqual(23748, response.json['CapacityBytes']) + + +class RegistryTestCase(EmulatorTestCase): + + def test_registry_file_collection(self): + response = self.app.get('/redfish/v1/Registries') + self.assertEqual(200, response.status_code) + self.assertEqual('/redfish/v1/Registries', response.json['@odata.id']) + self.assertEqual( + {'@odata.id': '/redfish/v1/Registries/Messages'}, + response.json['Members'][0]) + self.assertEqual( + {'@odata.id': + '/redfish/v1/Registries/BiosAttributeRegistry.v1_0_0'}, + response.json['Members'][1]) + + def test_bios_attribute_registry_file(self): + response = self.app.get( + '/redfish/v1/Registries/BiosAttributeRegistry.v1_0_0') + self.assertEqual(200, response.status_code) + self.assertEqual('/redfish/v1/Registries/BiosAttributeRegistry.v1_0_0', + response.json['@odata.id']) + self.assertEqual( + {'Language': 'en', + 'Uri': '/redfish/v1/Systems/Bios/BiosRegistry'}, + response.json['Location'][0]) + + def test_message_registry_file(self): + response = self.app.get( + '/redfish/v1/Registries/Messages') + self.assertEqual(200, response.status_code) + self.assertEqual('/redfish/v1/Registries/Messages', + response.json['@odata.id']) + self.assertEqual({'Language': 'En', + 'Uri': '/redfish/v1/Registries/Messages/Registry'}, + response.json['Location'][0]) + + def test_bios_registry(self): + response = self.app.get( + '/redfish/v1/Systems/%s/Bios/BiosRegistry' % self.uuid) + self.assertEqual(200, response.status_code) + self.assertEqual('/redfish/v1/Systems/%s/Bios/BiosRegistry' + % self.uuid, + response.json['@odata.id']) + self.assertEqual('BIOS Attribute Registry', + response.json['Name']) + self.assertEqual('BiosAttributeRegistryP89.v1_0_0', + response.json['Id']) + entries = response.json['RegistryEntries'] + self.assertEqual(len(entries['Attributes']), 6) + self.assertEqual({'AttributeName': 'ProcTurboMode', + 'CurrentValue': None, + 'DisplayName': 'Turbo Boost', + 'HelpText': 'Governs the Turbo Boost Technology. ' + 'This feature allows the processor cores to be ' + 'automatically clocked up in frequency beyond the ' + 'advertised processor speed.', + 'Hidden': False, + 'Immutable': False, + 'ReadOnly': False, + 'Type': 'Enumeration', + 'Value': [{'ValueDisplayName': 'Enabled', + 'ValueName': 'Enabled'}, + {'ValueDisplayName': 'Disabled', + 'ValueName': 'Disabled'}], + 'WarningText': None, + 'WriteOnly': False}, + entries['Attributes'][0]) + + def test_message_registry(self): + response = self.app.get('/redfish/v1/Registries/Messages/Registry') + self.assertEqual(200, response.status_code) + self.assertEqual('/redfish/v1/Registries/Messages/Registry', + response.json['@odata.id']) + self.assertEqual('Message Registry', response.json['Name']) + self.assertEqual('1.1.1', response.json['Id']) + messages = response.json['Messages'] + self.assertEqual({"Description": "The command was successful.", + "Message": "The command was successful", + "Severity": "Informational", + "NumberOfArgs": 0, + "Resolution": "No response action is required."}, + messages['BIOS001'])