# Buggy code
def create(
    self,
    entity=None,
    result_state=None,
    fail_condition=lambda e: False,
    search_params=None,
    update_params=None,
    **kwargs,
):
    """
    Method which is called when state of the entity is 'present'. If user
    don't provide `entity` parameter the entity is searched using
    `search_params` parameter. If entity is found it's updated, whether
    the entity should be updated is checked by `update_check` method.
    The corresponding updated entity is build by `build_entity` method.

    Function executed after entity is created can optionally be specified
    in `post_create` parameter. Function executed after entity is updated
    can optionally be specified in `post_update` parameter.

    :param entity: Entity we want to update, if exists.
    :param result_state: State which should entity has in order to finish task.
    :param fail_condition: Function which checks incorrect state of entity, if it returns `True` Exception is raised.
    :param search_params: Dictionary of parameters to be used for search.
    :param update_params: The params which should be passed to update method.
    :param kwargs: Additional parameters passed when creating entity.
    :return: Dictionary with values returned by Ansible module.
    """
    if entity is None:
        entity = self.search_entity(search_params)

    self.pre_create(entity)

    if entity:
        # Entity exists, so update it:
        entity_service = self._service.service(entity.id)
        if not self.update_check(entity):
            new_entity = self.build_entity()
            if not self._module.check_mode:
                update_params = update_params or {}
                updated_entity = entity_service.update(new_entity, **update_params)
                self.post_update(entity)

            # Update diffs only if user specified --diff parameter,
            # so we don't useless overload API:
            if self._module._diff:
                before = get_dict_of_struct(
                    entity,
                    self._connection,
                    fetch_nested=True,
                    attributes=["name"],
                )
                after = before.copy()
                self.diff_update(after, get_dict_of_struct(new_entity))
                self._diff["before"] = before
                self._diff["after"] = after

            self.changed = True
    else:
        # Entity don't exists, so create it:
        if not self._module.check_mode:
            entity = self._service.add(self.build_entity(), **kwargs)
            self.post_create(entity)
        self.changed = True

    # Wait for the entity to be created and to be in the defined state:
    entity_service = self._service.service(entity.id)

    def state_condition(entity):
        return entity

    if result_state:

        def state_condition(entity):
            return entity and entity.status == result_state

    wait(
        service=entity_service,
        condition=state_condition,
        fail_condition=fail_condition,
        wait=self._module.params["wait"],
        timeout=self._module.params["timeout"],
        poll_interval=self._module.params["poll_interval"],
    )

    return {
        "changed": self.changed,
        "id": entity.id,
        type(entity).__name__.lower(): get_dict_of_struct(
            struct=entity,
            connection=self._connection,
            fetch_nested=self._module.params.get("fetch_nested"),
            attributes=self._module.params.get("nested_attributes"),
        ),
        "diff": self._diff,
    }


# Traceback (AttributeError)
$ ansible-playbook -vvvv -i inventory/hosts site.yml --check
ansible-playbook 2.4.3.0
config file = None
configured module search path = [u'/Users/mvrgotic/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
executable location = /usr/local/bin/ansible-playbook
python version = 2.7.14 (default, Feb  6 2018, 20:04:00) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)]
No config file found; using defaults
setting up inventory plugins
Set default localhost to localhost
Parsed /Users/mvrgotic/Git/awesome-ovirt-platform/playbooks/awesome-2113-lab-scsk/ovirt_vms/inventory/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/local/lib/python2.7/site-packages/ansible/plugins/callback/default.pyc

PLAYBOOK: site.yml ******************************************************************************************************************************************************************
1 plays in site.yml
Read vars_file 'passwords.yml'
Read vars_file 'passwords.yml'

PLAY [Spawn VM Guest(s) in Awesome] *************************************************************************************************************************************************
Read vars_file 'passwords.yml'

TASK [Login to oVirt] ***************************************************************************************************************************************************************
task path: /Users/mvrgotic/Git/awesome-ovirt-platform/playbooks/awesome-2113-lab-scsk/ovirt_vms/spawn-ovirt-vms.yml:16
Using module file /usr/local/lib/python2.7/site-packages/ansible/modules/cloud/ovirt/ovirt_auth.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: mvrgotic
<localhost> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632255.36-166348216953816 `" &amp;&amp; echo ansible-tmp-1519632255.36-166348216953816="` echo /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632255.36-166348216953816 `" ) &amp;&amp; sleep 0'
<localhost> PUT /var/folders/wm/k9rx7dw951x46dzqsrs30kmr0000gn/T/tmpNpEerq TO /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632255.36-166348216953816/ovirt_auth.py
<localhost> EXEC /bin/sh -c 'chmod u+x /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632255.36-166348216953816/ /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632255.36-166348216953816/ovirt_auth.py &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632255.36-166348216953816/ovirt_auth.py; rm -rf "/Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632255.36-166348216953816/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
ok: [localhost] => {
"ansible_facts": {
"ovirt_auth": {
"ca_file": null,
"compress": true,
"headers": null,
"insecure": true,
"kerberos": false,
"timeout": 0,
"token": "pNn-IczUx4yF9aVZlIei-mdfCcCV-KkOaveX3D99yBlMRlecQZajVAjAwyx8eNGzh6vX0TXWwn4XJZ77RI3DRw",
"url": "https://aws-engine-01.avinity.tv/ovirt-engine/api"
}
},
"changed": false,
"invocation": {
"module_args": {
"ca_file": null,
"compress": true,
"headers": null,
"insecure": true,
"kerberos": false,
"ovirt_auth": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"state": "present",
"timeout": 0,
"url": "https://aws-engine-01.avinity.tv/ovirt-engine/api",
"username": "admin@internal"
}
}
}
META: ran handlers
Read vars_file 'passwords.yml'

TASK [Spawning oVirt VM Guest(s) from 01-S-CentOS-72-20180214v1] ********************************************************************************************************************
task path: /Users/mvrgotic/Git/awesome-ovirt-platform/playbooks/awesome-2113-lab-scsk/ovirt_vms/spawn-ovirt-vms.yml:25
Using module file /usr/local/lib/python2.7/site-packages/ansible/modules/cloud/ovirt/ovirt_vms.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: mvrgotic
<localhost> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.01-204625682216668 `" &amp;&amp; echo ansible-tmp-1519632256.01-204625682216668="` echo /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.01-204625682216668 `" ) &amp;&amp; sleep 0'
<localhost> PUT /var/folders/wm/k9rx7dw951x46dzqsrs30kmr0000gn/T/tmpLCwudA TO /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.01-204625682216668/ovirt_vms.py
<localhost> EXEC /bin/sh -c 'chmod u+x /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.01-204625682216668/ /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.01-204625682216668/ovirt_vms.py &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.01-204625682216668/ovirt_vms.py; rm -rf "/Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.01-204625682216668/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/var/folders/wm/k9rx7dw951x46dzqsrs30kmr0000gn/T/ansible_mOXdyO/ansible_module_ovirt_vms.py", line 1201, in main
clone_permissions=module.params['clone_permissions'],
File "/var/folders/wm/k9rx7dw951x46dzqsrs30kmr0000gn/T/ansible_mOXdyO/ansible_modlib.zip/ansible/module_utils/ovirt.py", line 580, in create
entity_service = self._service.service(entity.id)
AttributeError: 'NoneType' object has no attribute 'id'

failed: [localhost] (item=scsk2113csm1) => {
"changed": false,
"invocation": {
"module_args": {
"allow_partial_import": null,
"boot_devices": null,
"cd_iso": null,
"clone": false,
"clone_permissions": false,
"cloud_init": {
"host_name": "scsk2113csm1"
},
"cloud_init_nics": null,
"cluster": "AWSEUOPS",
"comment": null,
"cpu_cores": null,
"cpu_shares": null,
"cpu_sockets": null,
"delete_protected": null,
"description": null,
"disk_format": "cow",
"disks": [],
"fetch_nested": false,
"force": false,
"high_availability": null,
"host": null,
"id": null,
"initrd_path": null,
"instance_type": null,
"kernel_params": null,
"kernel_path": null,
"kvm": null,
"lease": null,
"memory": null,
"memory_guaranteed": null,
"name": "scsk2113csm1",
"nested_attributes": [],
"nics": [],
"operating_system": null,
"poll_interval": 3,
"serial_policy": null,
"serial_policy_value": null,
"state": "present",
"stateless": null,
"storage_domain": null,
"sysprep": null,
"template": "01-S-CentOS-72-20180214v1",
"template_version": null,
"timeout": 180,
"timezone": null,
"type": null,
"use_latest_template_version": null,
"vmware": null,
"wait": true,
"xen": null
}
},
"item": "scsk2113csm1",
"msg": "'NoneType' object has no attribute 'id'"
}
Using module file /usr/local/lib/python2.7/site-packages/ansible/modules/cloud/ovirt/ovirt_vms.py
<localhost> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.62-247808153224737 `" &amp;&amp; echo ansible-tmp-1519632256.62-247808153224737="` echo /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.62-247808153224737 `" ) &amp;&amp; sleep 0'
<localhost> PUT /var/folders/wm/k9rx7dw951x46dzqsrs30kmr0000gn/T/tmpfVCef6 TO /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.62-247808153224737/ovirt_vms.py
<localhost> EXEC /bin/sh -c 'chmod u+x /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.62-247808153224737/ /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.62-247808153224737/ovirt_vms.py &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.62-247808153224737/ovirt_vms.py; rm -rf "/Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632256.62-247808153224737/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/var/folders/wm/k9rx7dw951x46dzqsrs30kmr0000gn/T/ansible_W3df8w/ansible_module_ovirt_vms.py", line 1201, in main
clone_permissions=module.params['clone_permissions'],
File "/var/folders/wm/k9rx7dw951x46dzqsrs30kmr0000gn/T/ansible_W3df8w/ansible_modlib.zip/ansible/module_utils/ovirt.py", line 580, in create
entity_service = self._service.service(entity.id)
AttributeError: 'NoneType' object has no attribute 'id'

failed: [localhost] (item=scsk2113csm2) => {
"changed": false,
"invocation": {
"module_args": {
"allow_partial_import": null,
"boot_devices": null,
"cd_iso": null,
"clone": false,
"clone_permissions": false,
"cloud_init": {
"host_name": "scsk2113csm2"
},
"cloud_init_nics": null,
"cluster": "AWSEUOPS",
"comment": null,
"cpu_cores": null,
"cpu_shares": null,
"cpu_sockets": null,
"delete_protected": null,
"description": null,
"disk_format": "cow",
"disks": [],
"fetch_nested": false,
"force": false,
"high_availability": null,
"host": null,
"id": null,
"initrd_path": null,
"instance_type": null,
"kernel_params": null,
"kernel_path": null,
"kvm": null,
"lease": null,
"memory": null,
"memory_guaranteed": null,
"name": "scsk2113csm2",
"nested_attributes": [],
"nics": [],
"operating_system": null,
"poll_interval": 3,
"serial_policy": null,
"serial_policy_value": null,
"state": "present",
"stateless": null,
"storage_domain": null,
"sysprep": null,
"template": "01-S-CentOS-72-20180214v1",
"template_version": null,
"timeout": 180,
"timezone": null,
"type": null,
"use_latest_template_version": null,
"vmware": null,
"wait": true,
"xen": null
}
},
"item": "scsk2113csm2",
"msg": "'NoneType' object has no attribute 'id'"
}
Using module file /usr/local/lib/python2.7/site-packages/ansible/modules/cloud/ovirt/ovirt_vms.py
<localhost> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632257.17-74238433490364 `" &amp;&amp; echo ansible-tmp-1519632257.17-74238433490364="` echo /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632257.17-74238433490364 `" ) &amp;&amp; sleep 0'
<localhost> PUT /var/folders/wm/k9rx7dw951x46dzqsrs30kmr0000gn/T/tmpOuoGrk TO /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632257.17-74238433490364/ovirt_vms.py
<localhost> EXEC /bin/sh -c 'chmod u+x /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632257.17-74238433490364/ /Users/mvrgotic/.ansible/tmp/ansible-tmp-1519632257.17-74238433490364/ovirt_vms.py &amp;&amp; sleep 0'
^C [ERROR]: User interrupted execution

# Fixed code
def create(
    self,
    entity=None,
    result_state=None,
    fail_condition=lambda e: False,
    search_params=None,
    update_params=None,
    **kwargs,
):
    """
    Method which is called when state of the entity is 'present'. If user
    don't provide `entity` parameter the entity is searched using
    `search_params` parameter. If entity is found it's updated, whether
    the entity should be updated is checked by `update_check` method.
    The corresponding updated entity is build by `build_entity` method.

    Function executed after entity is created can optionally be specified
    in `post_create` parameter. Function executed after entity is updated
    can optionally be specified in `post_update` parameter.

    :param entity: Entity we want to update, if exists.
    :param result_state: State which should entity has in order to finish task.
    :param fail_condition: Function which checks incorrect state of entity, if it returns `True` Exception is raised.
    :param search_params: Dictionary of parameters to be used for search.
    :param update_params: The params which should be passed to update method.
    :param kwargs: Additional parameters passed when creating entity.
    :return: Dictionary with values returned by Ansible module.
    """
    if entity is None:
        entity = self.search_entity(search_params)

    self.pre_create(entity)

    if entity:
        # Entity exists, so update it:
        entity_service = self._service.service(entity.id)
        if not self.update_check(entity):
            new_entity = self.build_entity()
            if not self._module.check_mode:
                update_params = update_params or {}
                updated_entity = entity_service.update(new_entity, **update_params)
                self.post_update(entity)

            # Update diffs only if user specified --diff parameter,
            # so we don't useless overload API:
            if self._module._diff:
                before = get_dict_of_struct(
                    entity,
                    self._connection,
                    fetch_nested=True,
                    attributes=["name"],
                )
                after = before.copy()
                self.diff_update(after, get_dict_of_struct(new_entity))
                self._diff["before"] = before
                self._diff["after"] = after

            self.changed = True
    else:
        # Entity don't exists, so create it:
        if not self._module.check_mode:
            entity = self._service.add(self.build_entity(), **kwargs)
            self.post_create(entity)
        self.changed = True

    if not self._module.check_mode:
        # Wait for the entity to be created and to be in the defined state:
        entity_service = self._service.service(entity.id)

        def state_condition(entity):
            return entity

        if result_state:

            def state_condition(entity):
                return entity and entity.status == result_state

        wait(
            service=entity_service,
            condition=state_condition,
            fail_condition=fail_condition,
            wait=self._module.params["wait"],
            timeout=self._module.params["timeout"],
            poll_interval=self._module.params["poll_interval"],
        )

    return {
        "changed": self.changed,
        "id": getattr(entity, "id", None),
        type(entity).__name__.lower(): get_dict_of_struct(
            struct=entity,
            connection=self._connection,
            fetch_nested=self._module.params.get("fetch_nested"),
            attributes=self._module.params.get("nested_attributes"),
        ),
        "diff": self._diff,
    }