From 552609114c6e8aa9ad6a6faf19b2e9f112af8641 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Wed, 29 Aug 2018 14:46:57 -0400 Subject: [PATCH] Add method to clear system configuration Reset to factory defaults is a relatively common request, provide an extensible hook. Use the standard redfish method on current systems. Change-Id: I92a17a7434eeab0d8f455cf609ca2db764fe4a17 --- pyghmi/ipmi/command.py | 8 ++++++++ pyghmi/ipmi/oem/generic.py | 4 ++++ pyghmi/ipmi/oem/lenovo/handler.py | 5 +++++ pyghmi/ipmi/oem/lenovo/imm.py | 9 +++++++++ pyghmi/util/webclient.py | 7 ++++--- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/pyghmi/ipmi/command.py b/pyghmi/ipmi/command.py index 8a408939..b1565eff 100644 --- a/pyghmi/ipmi/command.py +++ b/pyghmi/ipmi/command.py @@ -761,6 +761,14 @@ class Command(object): self.oem_init() return self._oem.set_system_configuration(changeset) + def clear_system_configuration(self): + """Clear the Bios/UEFI configuration + + This requests the system revert to factory default settings + """ + self.oem_init() + self._oem.clear_system_configuration() + def set_net_configuration(self, ipv4_address=None, ipv4_configuration=None, ipv4_gateway=None, channel=None): """Set network configuration data. diff --git a/pyghmi/ipmi/oem/generic.py b/pyghmi/ipmi/oem/generic.py index 7fec0901..a0dc3dce 100644 --- a/pyghmi/ipmi/oem/generic.py +++ b/pyghmi/ipmi/oem/generic.py @@ -56,6 +56,10 @@ class OEMHandler(object): if evdata[0] & 0b110000 == 0b100000: event['oem_byte3'] = evdata[2] + def clear_system_configuration(self): + raise exc.UnsupportedFunctionality( + 'Clearing system configuration not implemented for this platform') + def get_oem_inventory_descriptions(self): """Get descriptions of available additional inventory items diff --git a/pyghmi/ipmi/oem/lenovo/handler.py b/pyghmi/ipmi/oem/lenovo/handler.py index 86a9c938..57b64747 100755 --- a/pyghmi/ipmi/oem/lenovo/handler.py +++ b/pyghmi/ipmi/oem/lenovo/handler.py @@ -933,6 +933,11 @@ class OEMHandler(generic.OEMHandler): return self.immhandler.set_system_configuration(changeset) return super(OEMHandler, self).set_system_configuration(changeset) + def clear_system_configuration(self): + if self.has_xcc: + return self.immhandler.clear_system_configuration() + return super(OEMHandler, self).clear_system_configuration() + def detach_remote_media(self): if self.has_imm: self.immhandler.detach_remote_media() diff --git a/pyghmi/ipmi/oem/lenovo/imm.py b/pyghmi/ipmi/oem/lenovo/imm.py index 6fcda973..90d1b16f 100644 --- a/pyghmi/ipmi/oem/lenovo/imm.py +++ b/pyghmi/ipmi/oem/lenovo/imm.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import base64 from datetime import datetime import errno import json @@ -685,6 +686,14 @@ class XCCClient(IMMClient): dsc = dsc[0] return {'height': int(dsc['u-height']), 'slot': int(dsc['slot'])} + def clear_system_configuration(self): + self.wc.grab_json_response( + '/redfish/v1/Systems/1/Bios/Actions/Bios.ResetBios', + {'Action': 'Bios.ResetBios'}, + headers={'Authorization': 'Basic ' + base64.b64encode( + self.username + ':' + self.password), + 'Content-Type': 'application/json'}) + def get_webclient(self, login=True): cv = self.ipmicmd.certverify wc = webclient.SecureHTTPConnection(self.imm, 443, verifycallback=cv) diff --git a/pyghmi/util/webclient.py b/pyghmi/util/webclient.py index e9829e19..18ddb83b 100644 --- a/pyghmi/util/webclient.py +++ b/pyghmi/util/webclient.py @@ -151,14 +151,15 @@ class SecureHTTPConnection(httplib.HTTPConnection, object): raise return rsp - def grab_json_response(self, url, data=None, referer=None): + def grab_json_response(self, url, data=None, referer=None, headers=None): webclient = self.dupe() if isinstance(data, dict): data = json.dumps(data) if data: - webclient.request('POST', url, data, referer=referer) + webclient.request('POST', url, data, referer=referer, + headers=headers) else: - webclient.request('GET', url, referer=referer) + webclient.request('GET', url, referer=referer, headers=headers) rsp = webclient.getresponse() if rsp.status == 200: return json.loads(rsp.read())