# Buggy code
def get_bios_boot_order(self):
    result = {}
    boot_device_list = []
    boot_device_details = []
    key = "Bios"
    bootsources = "BootSources"
    # Get these entries, but does not fail if not found
    properties = ["Index", "Id", "Name", "Enabled"]

    # Search for 'key' entry and extract URI from it
    response = self.get_request(self.root_uri + self.systems_uri)
    if response["ret"] is False:
        return response
    result["ret"] = True
    data = response["data"]

    if key not in data:
        return {"ret": False, "msg": "Key %s not found" % key}

    bios_uri = data[key]["@odata.id"]

    # Get boot mode first as it will determine what attribute to read
    response = self.get_request(self.root_uri + bios_uri)
    if response["ret"] is False:
        return response
    data = response["data"]
    boot_mode = data["Attributes"]["BootMode"]
    if boot_mode == "Uefi":
        boot_seq = "UefiBootSeq"
    else:
        boot_seq = "BootSeq"

    response = self.get_request(self.root_uri + self.systems_uri + "/" + bootsources)
    if response["ret"] is False:
        return response
    result["ret"] = True
    data = response["data"]

    boot_device_list = data["Attributes"][boot_seq]
    for b in boot_device_list:
        boot_device = {}
        for property in properties:
            if property in b:
                boot_device[property] = b[property]
        boot_device_details.append(boot_device)
    result["entries"] = boot_device_details
    return result


# Traceback (KeyError)
redfish$ ansible/bin/ansible-playbook test_redfish.yml -vvvv

ansible-playbook 2.8.0.dev0 (devel 518f80c3fb) last updated 2018/10/11 16:25:06 (GMT -400)
config file = None
configured module search path = [u'/home/xander/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /mnt/c/Users/amadsen/Coding/redfish/ansible/lib/ansible
executable location = ansible/bin/ansible-playbook
python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
No config file found; using defaults
setting up inventory plugins
[WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

[WARNING]: No inventory was parsed, only implicit localhost is available

[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

Loading callback plugin default of type stdout, v2.0 from /mnt/c/Users/amadsen/Coding/redfish/ansible/lib/ansible/plugins/callback/default.pyc

PLAYBOOK: test_redfish.yml *************************************************************************************************************************1 plays in test_redfish.yml

PLAY [Test Redfish modules!] ***********************************************************************************************************************META: ran handlers

TASK [Get all information available in System category] ********************************************************************************************task path: /mnt/c/Users/amadsen/Coding/redfish/test_redfish.yml:12
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: xander
<127.0.0.1> EXEC /bin/sh -c 'echo ~xander &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196 `" &amp;&amp; echo ansible-tmp-1540398196.31-202659559090196="` echo /home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196 `" ) &amp;&amp; sleep 0'
Using module file /mnt/c/Users/amadsen/Coding/redfish/ansible/lib/ansible/modules/remote_management/redfish/redfish_facts.py
<127.0.0.1> PUT /home/xander/.ansible/tmp/ansible-local-206504PW1hZ/tmp25SJAQ TO /home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/ /home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python /home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py", line 113, in <module>
_ansiballz_main()
File "/home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py", line 105, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py", line 48, in invoke_module
imp.load_module('__main__', mod, module, MOD_DESC)
File "/tmp/ansible_redfish_facts_payload_q2Fkwl/__main__.py", line 267, in <module>
File "/tmp/ansible_redfish_facts_payload_q2Fkwl/__main__.py", line 218, in main
File "/tmp/ansible_redfish_facts_payload_q2Fkwl/ansible_redfish_facts_payload.zip/ansible/module_utils/redfish_utils.py", line 557, in get_bios_boot_order
KeyError: 'BootMode'

failed: [localhost] (item=GetBiosBootOrder) => {
"changed": false,
"item": "GetBiosBootOrder",
"module_stderr": "Traceback (most recent call last):\n  File \"/home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py\", line 113, in <module>\n    _ansiballz_main()\n  File \"/home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py\", line 105, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/xander/.ansible/tmp/ansible-tmp-1540398196.31-202659559090196/AnsiballZ_redfish_facts.py\", line 48, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/tmp/ansible_redfish_facts_payload_q2Fkwl/__main__.py\", line 267, in <module>\n  File \"/tmp/ansible_redfish_facts_payload_q2Fkwl/__main__.py\", line 218, in main\n  File \"/tmp/ansible_redfish_facts_payload_q2Fkwl/ansible_redfish_facts_payload.zip/ansible/module_utils/redfish_utils.py\", line 557, in get_bios_boot_order\nKeyError: 'BootMode'\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}
to retry, use: --limit @/mnt/c/Users/amadsen/Coding/redfish/test_redfish.retry

PLAY RECAP *****************************************************************************************************************************************localhost                  : ok=0    changed=0    unreachable=0    failed=1

# Fixed code
def get_bios_boot_order(self):
    result = {}
    # Get these entries from BootOption, if present
    properties = ["DisplayName", "BootOptionReference"]

    # Retrieve System resource
    response = self.get_request(self.root_uri + self.systems_uri)
    if response["ret"] is False:
        return response
    result["ret"] = True
    data = response["data"]

    # Confirm needed Boot properties are present
    if "Boot" not in data or "BootOrder" not in data["Boot"]:
        return {"ret": False, "msg": "Key BootOrder not found"}

    boot = data["Boot"]
    boot_order = boot["BootOrder"]

    # Retrieve BootOptions if present
    if "BootOptions" in boot and "@odata.id" in boot["BootOptions"]:
        boot_options_uri = boot["BootOptions"]["@odata.id"]
        # Get BootOptions resource
        response = self.get_request(self.root_uri + boot_options_uri)
        if response["ret"] is False:
            return response
        data = response["data"]

        # Retrieve Members array
        if "Members" not in data:
            return {"ret": False, "msg": "Members not found in BootOptionsCollection"}
        members = data["Members"]
    else:
        members = []

    # Build dict of BootOptions keyed by BootOptionReference
    boot_options_dict = {}
    for member in members:
        if "@odata.id" not in member:
            return {"ret": False, "msg": "@odata.id not found in BootOptions"}
        boot_option_uri = member["@odata.id"]
        response = self.get_request(self.root_uri + boot_option_uri)
        if response["ret"] is False:
            return response
        data = response["data"]
        if "BootOptionReference" not in data:
            return {"ret": False, "msg": "BootOptionReference not found in BootOption"}
        boot_option_ref = data["BootOptionReference"]

        # fetch the props to display for this boot device
        boot_props = {}
        for prop in properties:
            if prop in data:
                boot_props[prop] = data[prop]

        boot_options_dict[boot_option_ref] = boot_props

    # Build boot device list
    boot_device_list = []
    for ref in boot_order:
        boot_device_list.append(
            boot_options_dict.get(ref, {"BootOptionReference": ref})
        )

    result["entries"] = boot_device_list
    return result