Redfish request library
Change-Id: Iafa8c273dfe476c3418c03db21c3580c5d685ece
Signed-off-by: Sushil Singh <susilsi7@in.ibm.com>
diff --git a/lib/redfish_request.py b/lib/redfish_request.py
new file mode 100644
index 0000000..a79e43b
--- /dev/null
+++ b/lib/redfish_request.py
@@ -0,0 +1,355 @@
+#!/usr/bin/env python
+
+import requests
+import urllib.request
+from urllib3.exceptions import InsecureRequestWarning
+from getpass import getpass
+import sys
+import os
+import ssl
+import json
+import random
+import secrets
+import string
+
+from robot.api import logger
+from robot.libraries.BuiltIn import BuiltIn
+from robot.api.deco import keyword
+
+
+class redfish_request(object):
+
+ @staticmethod
+ def generate_clientid():
+ r"""
+ Generate 10 character unique id.
+
+ e.g. "oMBhLv2Q9e"
+
+ """
+
+ clientid = ''.join(secrets.choice(
+ string.ascii_letters + string.digits) for i in range(10))
+ clientid = ''.join(str(i) for i in clientid)
+
+ return clientid
+
+ @staticmethod
+ def form_url(url):
+ r"""
+ Form a complete path for user url.
+
+ Description of argument(s):
+ url Url passed by user e.g. /redfish/v1/Systems/system.
+ """
+
+ openbmc_host = \
+ BuiltIn().get_variable_value("${OPENBMC_HOST}", default="")
+ https_port = BuiltIn().get_variable_value("${HTTPS_PORT}", default="")
+ form_url = \
+ "https://" + str(openbmc_host) + ":" + str(https_port) + str(url)
+
+ return form_url
+
+ @staticmethod
+ def log_console(response):
+ r"""
+ Print function for console.
+
+ Description of argument(s):
+ response Response from requests.
+ """
+
+ logger.console(msg='', newline=True)
+ logger.info("Response : [%s]" % response.status_code,
+ also_console=True)
+ logger.console(msg='', newline=True)
+
+ def request_login(self, headers, url, credential, timeout=10):
+ r"""
+ Redfish request to create a session.
+
+ Description of argument(s):
+ headers By default headers is assigned as application/json.
+ If user assign the headers,
+ then default headers is not considered.
+ url Requested path from user.
+ credential User has to assign the credential like username and
+ password.
+ UserName = xxxxxxxx Password = xxxxxxxx
+ Client id, user need to assign None in order to auto
+ generate, else user can assign any value.
+ timeout By default timeout is set to 10 seconds.
+ If user assign the timeout, then default timeout
+ value is not considered.
+ """
+
+ if headers == "None":
+ headers = dict()
+ headers['Content-Type'] = 'application/json'
+
+ client_id = credential['Oem']['OpenBMC'].get('ClientID', "None")
+
+ if "None" == client_id:
+ self.clientid = redfish_request.generate_clientid()
+ credential['Oem']['OpenBMC']['ClientID'] = self.clientid
+
+ logger.console(msg='', newline=True)
+ requests.packages.urllib3.\
+ disable_warnings(category=InsecureRequestWarning)
+ response = redfish_request.request_post(self, headers=headers,
+ url=url, data=credential)
+
+ return response
+
+ def request_get(self, headers, url, timeout=10, verify=False):
+ r"""
+ Redfish get request.
+
+ Description of argument(s):
+ headers By default headers is assigned as application/json.
+ If user assign the headers, then default headers is not
+ considered.
+ url Requested path from user.
+ timeout By default timeout is set to 10 seconds.
+ If user assign the timeout, then default timeout value
+ is not considered.
+ verify By default verify is set to false means no certificate
+ verification is performed
+ else in case of true, certificate needs to be verified.
+ If user assign the verify, then default verify value
+ is not considered.
+ """
+
+ if headers.get('Content-Type', None) is None:
+ headers['Content-Type'] = 'application/json'
+
+ url = redfish_request.form_url(url)
+
+ logger.console(msg='', newline=True)
+ msg = "Request Method : GET ,headers = " + \
+ json.dumps(headers) + " ,uri = " + str(url) + " ,timeout = " + \
+ str(timeout) + " ,verify = " + str(verify)
+ logger.info(msg, also_console=True)
+
+ response = requests.get(url, headers=headers,
+ timeout=timeout, verify=verify)
+ redfish_request.log_console(response)
+
+ return response
+
+ def request_patch(self, headers, url, data=None, timeout=10, verify=False):
+ r"""
+ Redfish patch request.
+
+ Description of argument(s):
+ headers By default headers is assigned as application/json.
+ If user assign the headers, then default headers is not
+ considered.
+ url Requested path from user.
+ data By default data is None.
+ If user assign the data, then default data value is not
+ considered.
+ timeout By default timeout is set to 10 seconds.
+ If user assign the timeout, then default timeout value
+ is not considered.
+ verify By default verify is set to false means no certificate
+ verification is performed
+ else in case of true, certificate needs to be verified.
+ If user assign the verify, then default verify value
+ is not considered.
+ """
+
+ if headers.get('Content-Type', None) is None:
+ headers['Content-Type'] = 'application/json'
+
+ url = redfish_request.form_url(url)
+
+ logger.console(msg='', newline=True)
+ msg = "Request Method : PATCH ,headers = " + \
+ json.dumps(headers) + " ,uri = " + str(url) + " ,data = " + \
+ json.dumps(data) + " ,timeout = " + str(timeout) + \
+ " ,verify = " + str(verify)
+ logger.info(msg, also_console=True)
+
+ response = requests.patch(url, headers=headers, data=data,
+ timeout=timeout, verify=verify)
+ redfish_request.log_console(response)
+
+ return response
+
+ def request_post(self, headers, url, data=None, timeout=10, verify=False):
+ r"""
+ Redfish post request.
+
+ Description of argument(s):
+ headers By default headers is assigned as application/json.
+ If user assign the headers, then default headers is not
+ considered.
+ url Requested path from user.
+ data By default data is None.
+ If user assign the data, then default data value is not
+ considered.
+ timeout By default timeout is set to 10 seconds.
+ If user assign the timeout, then default timeout value
+ is not considered.
+ verify By default verify is set to false means no
+ certificate verification is performed
+ else in case of true, certificate needs to be verified.
+ If user assign the verify, then default verify value
+ is not considered.
+ """
+
+ if headers.get('Content-Type', None) is None:
+ headers['Content-Type'] = 'application/json'
+
+ url = redfish_request.form_url(url)
+
+ logger.console(msg='', newline=True)
+ msg = "Request Method : POST ,headers = " + \
+ json.dumps(headers) + " ,uri = " + str(url) + " ,data = " + \
+ json.dumps(data) + " ,timeout = " + str(timeout) + \
+ " ,verify = " + str(verify)
+ logger.info(msg, also_console=True)
+
+ response = requests.post(url, headers=headers, data=json.dumps(data),
+ timeout=timeout, verify=verify)
+ redfish_request.log_console(response)
+
+ return response
+
+ def request_put(self, headers, url, files=None, data=None,
+ timeout=10, verify=False):
+ r"""
+ Redfish put request.
+
+ Description of argument(s):
+ headers By default headers is assigned as application/json.
+ If user assign the headers, then default headers is not
+ considered.
+ url Requested path from user.
+ files By default files is None.
+ If user assign the files, then default files value
+ is not considered.
+ data By default data is None.
+ If user pass the data, then default data value is not
+ considered.
+ timeout By default timeout is set to 10 seconds.
+ If user pass the timeout, then default timeout value
+ is not considered.
+ verify By default verify is set to false means no
+ certificate verification is performed
+ else in case of true, certificate needs to be verified.
+ If user assign the verify, then default verify value
+ is not considered.
+ """
+
+ if headers.get('Content-Type', None) is None:
+ headers['Content-Type'] = 'application/json'
+
+ url = redfish_request.form_url(url)
+
+ logger.console(msg='', newline=True)
+ msg = "Request Method : PUT ,headers = " + \
+ json.dumps(headers) + " ,uri = " + str(url) + " ,data = " + \
+ json.dumps(data) + " ,timeout = " + str(timeout) + \
+ " ,verify = " + str(verify)
+ logger.info(msg, also_console=True)
+
+ response = requests.put(url, headers=headers, files=files, data=data,
+ timeout=timeout, verify=verify)
+ redfish_request.log_console(response)
+
+ return response
+
+ def request_delete(self, headers, url, data=None, timeout=10, verify=False):
+ r"""
+ Redfish delete request.
+
+ Description of argument(s):
+ headers By default headers is assigned as application/json.
+ If user pass the headers then default header is not
+ considered.
+ url Requested path from user.
+ data By default data is None.
+ If user pass the data, then default data value is not
+ considered.
+ timeout By default timeout is set to 10 seconds.
+ If user pass the timeout, then default timeout value
+ is not considered.
+ verify By default verify is set to false means no
+ certificate verification is performed
+ else in case of true, certificate needs to be verified.
+ If user assign the verify, then default verify value
+ is not considered.
+ """
+
+ if headers.get('Content-Type', None) is None:
+ headers['Content-Type'] = 'application/json'
+
+ url = redfish_request.form_url(url)
+
+ logger.console(msg='', newline=True)
+ msg = "Request Method : DELETE ,headers = " + \
+ json.dumps(headers) + " ,uri = " + str(url) + " ,data = " + \
+ json.dumps(data) + " ,timeout = " + str(timeout) + \
+ " ,verify = " + str(verify)
+ logger.console(msg='', newline=True)
+
+ response = requests.delete(url, headers=headers, data=data,
+ timeout=timeout, verify=verify)
+ redfish_request.log_console(response)
+
+ return response
+
+ @staticmethod
+ def dict_parse(variable, lookup_dict):
+ r"""
+ Find a variable in dict.
+
+ Description of argument(s):
+ variable Variable that need to be searched in dict.
+ lookup_dict Disctionay contains variables.
+ """
+
+ result = lookup_dict.get(variable, None)
+ return result
+
+ @staticmethod
+ def get_target_actions(target_attribute, response):
+ r"""
+ Get target entry of the searched target attribute.
+
+ Description of argument(s):
+ target_attribute Name of the attribute (e.g. 'Manager.Reset').
+ response Response from url.
+
+ 'Actions' : {
+ '#Manager.Reset' : {
+ '@Redfish.ActionInfo' : '/redfish/v1/Managers/bmc/ResetActionInfo',
+ 'target' : '/redfish/v1/Managers/bmc/Actions/Manager.Reset'
+ }
+ }
+ """
+
+ lookup_list = ["Actions", "#" + attribute, "target"]
+ for lookup_item in lookup_list:
+ response = redfish_request.dict_parse(lookup_item, response)
+ if response is not None and type(response) is dict():
+ continue
+ else:
+ return response
+ return None
+
+ @staticmethod
+ def get_attribute(attribute, data):
+ r"""
+ Get resource attribute.
+
+ Description of argument(s):
+ attribute Pass the attribute needs to be searched.
+ data Pass the request response.
+ """
+
+ value = data.get(attribute, None)
+ return value