# Buggy code
def main():
    argument_spec = tower_argument_spec()
    argument_spec.update(
        dict(
            name=dict(required=True),
            user=dict(),
            team=dict(),
            kind=dict(required=True, choices=KIND_CHOICES.keys()),
            host=dict(),
            username=dict(),
            password=dict(no_log=True),
            ssh_key_data=dict(no_log=True, type="path"),
            ssh_key_unlock=dict(no_log=True),
            authorize=dict(type="bool", default=False),
            authorize_password=dict(no_log=True),
            client=dict(),
            secret=dict(),
            tenant=dict(),
            subscription=dict(),
            domain=dict(),
            become_method=dict(),
            become_username=dict(),
            become_password=dict(no_log=True),
            vault_password=dict(no_log=True),
            description=dict(),
            organization=dict(required=True),
            project=dict(),
            state=dict(choices=["present", "absent"], default="present"),
        )
    )

    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)

    if not HAS_TOWER_CLI:
        module.fail_json(msg="ansible-tower-cli required for this module")

    name = module.params.get("name")
    organization = module.params.get("organization")
    state = module.params.get("state")

    json_output = {"credential": name, "state": state}

    tower_auth = tower_auth_config(module)
    with settings.runtime_values(**tower_auth):
        tower_check_mode(module)
        credential = tower_cli.get_resource("credential")
        try:
            params = {}
            params["create_on_missing"] = True
            params["name"] = name

            if organization:
                org_res = tower_cli.get_resource("organization")
                org = org_res.get(name=organization)
                params["organization"] = org["id"]

            try:
                tower_cli.get_resource("credential_type")
            except (ImportError, AttributeError):
                # /api/v1/ backwards compat
                # older versions of tower-cli don't *have* a credential_type
                # resource
                params["kind"] = module.params["kind"]
            else:
                credential_type = credential_type_for_v1_kind(module.params, module)
                params["credential_type"] = credential_type["id"]

            if module.params.get("description"):
                params["description"] = module.params.get("description")

            if module.params.get("user"):
                user_res = tower_cli.get_resource("user")
                user = user_res.get(username=module.params.get("user"))
                params["user"] = user["id"]

            if module.params.get("team"):
                team_res = tower_cli.get_resource("team")
                team = team_res.get(name=module.params.get("team"))
                params["team"] = team["id"]

            if module.params.get("ssh_key_data"):
                filename = module.params.get("ssh_key_data")
                if not os.path.exists(filename):
                    module.fail_json(msg="file not found: %s" % filename)
                if os.path.isdir(filename):
                    module.fail_json(
                        msg="attempted to read contents of directory: %s" % filename
                    )
                with open(filename, "rb") as f:
                    module.params["ssh_key_data"] = f.read()

            for key in (
                "authorize",
                "authorize_password",
                "client",
                "secret",
                "tenant",
                "subscription",
                "domain",
                "become_method",
                "become_username",
                "become_password",
                "vault_password",
                "project",
                "host",
                "username",
                "password",
                "ssh_key_data",
                "ssh_key_unlock",
            ):
                if "kind" in params:
                    params[key] = module.params.get(key)
                elif module.params.get(key):
                    params.setdefault("inputs", {})[key] = module.params.get(key)

            if state == "present":
                result = credential.modify(**params)
                json_output["id"] = result["id"]
            elif state == "absent":
                result = credential.delete(**params)
        except exc.NotFound as excinfo:
            module.fail_json(
                msg="Failed to update credential, organization not found: {0}".format(
                    excinfo
                ),
                changed=False,
            )
        except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo:
            module.fail_json(
                msg="Failed to update credential: {0}".format(excinfo), changed=False
            )

    json_output["changed"] = result["changed"]
    module.exit_json(**json_output)


# Traceback (tower_cli.exceptions.BadRequest)
TASK [tower-manage : Add user to team] *************************************************************************
task path: /home/ikanse/Ansible/ansible-tower-manage-playbook/roles/tower-manage/tasks/main.yml:24
Using module file /usr/lib/python2.7/site-packages/ansible/modules/web_infrastructure/ansible_tower/tower_role.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: ikanse
<localhost> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/ikanse/.ansible/tmp/ansible-tmp-1520232438.17-217702889247684 `" &amp;&amp; echo ansible-tmp-1520232438.17-217702889247684="` echo /home/ikanse/.ansible/tmp/ansible-tmp-1520232438.17-217702889247684 `" ) &amp;&amp; sleep 0'
<localhost> PUT /tmp/tmpxkOOCO TO /home/ikanse/.ansible/tmp/ansible-tmp-1520232438.17-217702889247684/tower_role.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/ikanse/.ansible/tmp/ansible-tmp-1520232438.17-217702889247684/ /home/ikanse/.ansible/tmp/ansible-tmp-1520232438.17-217702889247684/tower_role.py &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/ikanse/.ansible/tmp/ansible-tmp-1520232438.17-217702889247684/tower_role.py; rm -rf "/home/ikanse/.ansible/tmp/ansible-tmp-1520232438.17-217702889247684/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_9eTSgJ/ansible_module_tower_role.py", line 220, in <module>
main()
File "/tmp/ansible_9eTSgJ/ansible_module_tower_role.py", line 207, in main
result = role.grant(**params)
File "/usr/lib/python2.7/site-packages/tower_cli/resources/role.py", line 359, in grant
return self.role_write(fail_on_found=fail_on_found, **kwargs)
File "/usr/lib/python2.7/site-packages/tower_cli/resources/role.py", line 236, in role_write
fail_on_multiple_results=True, **data)
File "/usr/lib/python2.7/site-packages/tower_cli/models/base.py", line 286, in read
r = client.get(url, params=kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 521, in get
return self.request('GET', url, **kwargs)
File "/usr/lib/python2.7/site-packages/tower_cli/api.py", line 236, in request
kwargs.get('data', None), r.content.decode('utf8'))
tower_cli.exceptions.BadRequest: The Tower server claims it was sent a bad request.

GET https://13.126.199.60/api/v2/teams/1/object_roles/
Params: {'state': 'present', 'tower_verify_ssl': True, 'role_field': 'member_role'}
Data: None

Response: {"detail":"Role has no field named 'state'"}

fatal: [localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_9eTSgJ/ansible_module_tower_role.py\", line 220, in <module>\n    main()\n  File \"/tmp/ansible_9eTSgJ/ansible_module_tower_role.py\", line 207, in main\n    result = role.grant(**params)\n  File \"/usr/lib/python2.7/site-packages/tower_cli/resources/role.py\", line 359, in grant\n    return self.role_write(fail_on_found=fail_on_found, **kwargs)\n  File \"/usr/lib/python2.7/site-packages/tower_cli/resources/role.py\", line 236, in role_write\n    fail_on_multiple_results=True, **data)\n  File \"/usr/lib/python2.7/site-packages/tower_cli/models/base.py\", line 286, in read\n    r = client.get(url, params=kwargs)\n  File \"/usr/lib/python2.7/site-packages/requests/sessions.py\", line 521, in get\n    return self.request('GET', url, **kwargs)\n  File \"/usr/lib/python2.7/site-packages/tower_cli/api.py\", line 236, in request\n    kwargs.get('data', None), r.content.decode('utf8'))\ntower_cli.exceptions.BadRequest: The Tower server claims it was sent a bad request.\n\nGET https://13.126.199.60/api/v2/teams/1/object_roles/\nParams: {'state': 'present', 'tower_verify_ssl': True, 'role_field': 'member_role'}\nData: None\n\nResponse: {\"detail\":\"Role has no field named 'state'\"}\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 0
}

# Fixed code
def main():
    argument_spec = tower_argument_spec()
    argument_spec.update(
        dict(
            name=dict(required=True),
            user=dict(),
            team=dict(),
            kind=dict(required=True, choices=KIND_CHOICES.keys()),
            host=dict(),
            username=dict(),
            password=dict(no_log=True),
            ssh_key_data=dict(no_log=True, type="path"),
            ssh_key_unlock=dict(no_log=True),
            authorize=dict(type="bool", default=False),
            authorize_password=dict(no_log=True),
            client=dict(),
            security_token=dict(),
            secret=dict(),
            tenant=dict(),
            subscription=dict(),
            domain=dict(),
            become_method=dict(),
            become_username=dict(),
            become_password=dict(no_log=True),
            vault_password=dict(no_log=True),
            description=dict(),
            organization=dict(required=True),
            project=dict(),
            state=dict(choices=["present", "absent"], default="present"),
        )
    )

    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)

    if not HAS_TOWER_CLI:
        module.fail_json(msg="ansible-tower-cli required for this module")

    name = module.params.get("name")
    organization = module.params.get("organization")
    state = module.params.get("state")

    json_output = {"credential": name, "state": state}

    tower_auth = tower_auth_config(module)
    with settings.runtime_values(**tower_auth):
        tower_check_mode(module)
        credential = tower_cli.get_resource("credential")
        try:
            params = {}
            params["create_on_missing"] = True
            params["name"] = name

            if organization:
                org_res = tower_cli.get_resource("organization")
                org = org_res.get(name=organization)
                params["organization"] = org["id"]

            try:
                tower_cli.get_resource("credential_type")
            except (ImportError, AttributeError):
                # /api/v1/ backwards compat
                # older versions of tower-cli don't *have* a credential_type
                # resource
                params["kind"] = module.params["kind"]
            else:
                credential_type = credential_type_for_v1_kind(module.params, module)
                params["credential_type"] = credential_type["id"]

            if module.params.get("description"):
                params["description"] = module.params.get("description")

            if module.params.get("user"):
                user_res = tower_cli.get_resource("user")
                user = user_res.get(username=module.params.get("user"))
                params["user"] = user["id"]

            if module.params.get("team"):
                team_res = tower_cli.get_resource("team")
                team = team_res.get(name=module.params.get("team"))
                params["team"] = team["id"]

            if module.params.get("ssh_key_data"):
                filename = module.params.get("ssh_key_data")
                if not os.path.exists(filename):
                    module.fail_json(msg="file not found: %s" % filename)
                if os.path.isdir(filename):
                    module.fail_json(
                        msg="attempted to read contents of directory: %s" % filename
                    )
                with open(filename, "rb") as f:
                    module.params["ssh_key_data"] = to_text(f.read())

            for key in (
                "authorize",
                "authorize_password",
                "client",
                "security_token",
                "secret",
                "tenant",
                "subscription",
                "domain",
                "become_method",
                "become_username",
                "become_password",
                "vault_password",
                "project",
                "host",
                "username",
                "password",
                "ssh_key_data",
                "ssh_key_unlock",
            ):
                if "kind" in params:
                    params[key] = module.params.get(key)
                elif module.params.get(key):
                    params.setdefault("inputs", {})[key] = module.params.get(key)

            if state == "present":
                result = credential.modify(**params)
                json_output["id"] = result["id"]
            elif state == "absent":
                result = credential.delete(**params)
        except exc.NotFound as excinfo:
            module.fail_json(
                msg="Failed to update credential, organization not found: {0}".format(
                    excinfo
                ),
                changed=False,
            )
        except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo:
            module.fail_json(
                msg="Failed to update credential: {0}".format(excinfo), changed=False
            )

    json_output["changed"] = result["changed"]
    module.exit_json(**json_output)