# Buggy code
def set_manager_attributes(self, attr):
    attributes = "Attributes"

    # Example: manager_attr = {\"name\":\"value\"}
    # Check if value is a number. If so, convert to int.
    if attr["mgr_attr_value"].isdigit():
        manager_attr = '{"%s": %i}' % (
            attr["mgr_attr_name"],
            int(attr["mgr_attr_value"]),
        )
    else:
        manager_attr = '{"%s": "%s"}' % (attr["mgr_attr_name"], attr["mgr_attr_value"])

    payload = {"Attributes": json.loads(manager_attr)}
    response = self.patch_request(
        self.root_uri + self.manager_uri + "/" + attributes, payload, HEADERS
    )
    if response["ret"] is False:
        return response
    return {"ret": True}


# Traceback (KeyError)
TASK [Enable NTP in the OOB Controller] *******************************************************************************************************************************************************************
task path: /home/xxxx/yyyy/test01_bmc_setup.yml:26
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: KeyError: 'changed'
The full traceback is:
Traceback (most recent call last):
File "/home/xxxx/.ansible/tmp/ansible-tmp-1543355194.27-98542354862727/AnsiballZ_redfish_config.py", line 113, in <module>
_ansiballz_main()
File "/home/xxxx/.ansible/tmp/ansible-tmp-1543355194.27-98542354862727/AnsiballZ_redfish_config.py", line 105, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/xxxx/.ansible/tmp/ansible-tmp-1543355194.27-98542354862727/AnsiballZ_redfish_config.py", line 48, in invoke_module
imp.load_module('__main__', mod, module, MOD_DESC)
File "/data/tmp/ansible_redfish_config_payload_QCPf9S/__main__.py", line 236, in <module>
File "/data/tmp/ansible_redfish_config_payload_QCPf9S/__main__.py", line 230, in main
KeyError: 'changed'

fatal: [localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n  File \"/home/xxxx/.ansible/tmp/ansible-tmp-1543355194.27-98542354862727/AnsiballZ_redfish_config.py\", line 113, in <module>\n    _ansiballz_main()\n  File \"/home/xxxx/.ansible/tmp/ansible-tmp-1543355194.27-98542354862727/AnsiballZ_redfish_config.py\", line 105, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/xxxx/.ansible/tmp/ansible-tmp-1543355194.27-98542354862727/AnsiballZ_redfish_config.py\", line 48, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/data/tmp/ansible_redfish_config_payload_QCPf9S/__main__.py\", line 236, in <module>\n  File \"/data/tmp/ansible_redfish_config_payload_QCPf9S/__main__.py\", line 230, in main\nKeyError: 'changed'\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}

# Fixed code
def set_manager_attributes(self, attr):
    result = {}
    # Here I'm making the assumption that the key 'Attributes' is part of the URI.
    # It may not, but in the hardware I tested with, getting to the final URI where
    # the Manager Attributes are, appear to be part of a specific OEM extension.
    key = "Attributes"

    # Search for key entry and extract URI from it
    response = self.get_request(self.root_uri + self.manager_uri + "/" + key)
    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}

    # Check if attribute exists
    if attr["mgr_attr_name"] not in data[key]:
        return {
            "ret": False,
            "msg": "Manager attribute %s not found" % attr["mgr_attr_name"],
        }

    # Example: manager_attr = {\"name\":\"value\"}
    # Check if value is a number. If so, convert to int.
    if attr["mgr_attr_value"].isdigit():
        manager_attr = '{"%s": %i}' % (
            attr["mgr_attr_name"],
            int(attr["mgr_attr_value"]),
        )
    else:
        manager_attr = '{"%s": "%s"}' % (attr["mgr_attr_name"], attr["mgr_attr_value"])

    # Find out if value is already set to what we want. If yes, return
    if data[key][attr["mgr_attr_name"]] == attr["mgr_attr_value"]:
        return {"ret": True, "changed": False, "msg": "Manager attribute already set"}

    payload = {"Attributes": json.loads(manager_attr)}
    response = self.patch_request(
        self.root_uri + self.manager_uri + "/" + key, payload, HEADERS
    )
    if response["ret"] is False:
        return response
    return {
        "ret": True,
        "changed": True,
        "msg": "Modified Manager attribute %s" % attr["mgr_attr_name"],
    }