Skip to content

Commit

Permalink
Adding bios registries command to redfish_info (ansible-collections#7144
Browse files Browse the repository at this point in the history
)

* added bios attribute registry

* changelog

* changed bios registry function

* Added credential based support

* removed request and added workaround for HPE servers

* Update plugins/module_utils/redfish_utils.py

Agreed

Co-authored-by: Felix Fontein <[email protected]>

* Update plugins/module_utils/redfish_utils.py

Agreed

Co-authored-by: Felix Fontein <[email protected]>

* Added vendor specific changes

---------

Co-authored-by: Ramasamy <[email protected]>
Co-authored-by: Felix Fontein <[email protected]>
  • Loading branch information
3 people authored and Eric Trombly committed Oct 25, 2023
1 parent 24987a2 commit 7946034
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- redfish_info - add support for ``GetBiosRegistries`` command (https://github.com/ansible-collections/community.general/pull/7144).
105 changes: 102 additions & 3 deletions plugins/module_utils/redfish_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import os
import random
import string
import gzip
from io import BytesIO
from ansible.module_utils.urls import open_url
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.common.text.converters import to_text
Expand Down Expand Up @@ -128,8 +130,10 @@ def _check_request_payload(self, req_pyld, cur_pyld, uri):
return resp

# The following functions are to send GET/POST/PATCH/DELETE requests
def get_request(self, uri):
def get_request(self, uri, override_headers=None):
req_headers = dict(GET_HEADERS)
if override_headers:
req_headers.update(override_headers)
username, password, basic_auth = self._auth_params(req_headers)
try:
# Service root is an unauthenticated resource; remove credentials
Expand All @@ -141,8 +145,13 @@ def get_request(self, uri):
force_basic_auth=basic_auth, validate_certs=False,
follow_redirects='all',
use_proxy=True, timeout=self.timeout)
data = json.loads(to_native(resp.read()))
headers = dict((k.lower(), v) for (k, v) in resp.info().items())
if override_headers:
resp = gzip.open(BytesIO(resp.read()), 'rt', encoding='utf-8')
data = json.loads(to_native(resp.read()))
headers = req_headers
else:
data = json.loads(to_native(resp.read()))
headers = dict((k.lower(), v) for (k, v) in resp.info().items())
except HTTPError as e:
msg = self._get_extended_message(e)
return {'ret': False,
Expand Down Expand Up @@ -3630,3 +3639,93 @@ def create_volume(self, volume_details, storage_subsystem_id):

return {'ret': True, 'changed': True,
'msg': "Volume Created"}

def get_bios_registries(self):
# Get /redfish/v1
response = self.get_request(self.root_uri + self.systems_uri)
if not response["ret"]:
return response

server_details = response["data"]

# Get Registries URI
if "Bios" not in server_details:
msg = "Getting BIOS URI failed, Key 'Bios' not found in /redfish/v1/Systems/1/ response: %s"
return {
"ret": False,
"msg": msg % str(server_details)
}

bios_uri = server_details["Bios"]["@odata.id"]
bios_resp = self.get_request(self.root_uri + bios_uri)
if not bios_resp["ret"]:
return bios_resp

bios_data = bios_resp["data"]
attribute_registry = bios_data["AttributeRegistry"]

reg_uri = self.root_uri + self.service_root + "Registries/" + attribute_registry
reg_resp = self.get_request(reg_uri)
if not reg_resp["ret"]:
return reg_resp

reg_data = reg_resp["data"]

# Get BIOS attribute registry URI
lst = []

# Get the location URI
response = self.check_location_uri(reg_data, reg_uri)
if not response["ret"]:
return response

rsp_data, rsp_uri = response["rsp_data"], response["rsp_uri"]

if "RegistryEntries" not in rsp_data:
return {
"msg": "'RegistryEntries' not present in %s response, %s" % (rsp_uri, str(rsp_data)),
"ret": False
}

return {
"bios_registry": rsp_data,
"bios_registry_uri": rsp_uri,
"ret": True
}

def check_location_uri(self, resp_data, resp_uri):
# Get the location URI response
# return {"msg": self.creds, "ret": False}
vendor = self._get_vendor()['Vendor']
rsp_uri = ""
for loc in resp_data['Location']:
if loc['Language'] == "en":
rsp_uri = loc['Uri']
if vendor == 'HPE':
# WORKAROUND
# HPE systems with iLO 4 will have BIOS Atrribute Registries location URI as a dictonary with key 'extref'
# Hence adding condition to fetch the Uri
if type(loc['Uri']) is dict and "extref" in loc['Uri'].keys():
rsp_uri = loc['Uri']['extref']
if not rsp_uri:
msg = "Language 'en' not found in BIOS Atrribute Registries location, URI: %s, response: %s"
return {
"ret": False,
"msg": msg % (resp_uri, str(resp_data))
}

res = self.get_request(self.root_uri + rsp_uri)
if res['ret'] is False:
# WORKAROUND
# HPE systems with iLO 4 or iLO5 compresses (gzip) for some URIs
# Hence adding encoding to the header
if vendor == 'HPE':
override_headers = {"Accept-Encoding": "gzip"}
res = self.get_request(self.root_uri + rsp_uri, override_headers=override_headers)
if res['ret']:
return {
"ret": True,
"rsp_data": res["data"],
"rsp_uri": rsp_uri
}
return res
12 changes: 11 additions & 1 deletion plugins/modules/redfish_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,14 @@
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
- name: Get BIOS registry
community.general.redfish_info:
category: Systems
command: GetBiosRegistries
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
'''

RETURN = '''
Expand All @@ -355,7 +363,7 @@
"Systems": ["GetSystemInventory", "GetPsuInventory", "GetCpuInventory",
"GetMemoryInventory", "GetNicInventory", "GetHealthReport",
"GetStorageControllerInventory", "GetDiskInventory", "GetVolumeInventory",
"GetBiosAttributes", "GetBootOrder", "GetBootOverride", "GetVirtualMedia"],
"GetBiosAttributes", "GetBootOrder", "GetBootOverride", "GetVirtualMedia", "GetBiosRegistries"],
"Chassis": ["GetFanInventory", "GetPsuInventory", "GetChassisPower",
"GetChassisThermals", "GetChassisInventory", "GetHealthReport", "GetHPEThermalConfig", "GetHPEFanPercentMin"],
"Accounts": ["ListUsers"],
Expand Down Expand Up @@ -489,6 +497,8 @@ def main():
result["health_report"] = rf_utils.get_multi_system_health_report()
elif command == "GetVirtualMedia":
result["virtual_media"] = rf_utils.get_multi_virtualmedia(category)
elif command == "GetBiosRegistries":
result["bios_registries"] = rf_utils.get_bios_registries()

elif category == "Chassis":
# execute only if we find Chassis resource
Expand Down

0 comments on commit 7946034

Please sign in to comment.