Repository: ansible/ansible

Issue:
UnboundLocalError in `cloudflare_dns` module in check mode
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
`cloudflare_dns`

##### ANSIBLE VERSION
```
ansible 2.4.0 (devel a06014663c) last updated 2017/04/18 07:08:27 (GMT +100)
  config file = 
  configured module search path = [u'/Users/jack/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/jack/Projects/ansible/lib/ansible
  executable location = /Users/jack/Projects/ansible/bin/ansible
  python version = 2.7.10 (default, Jul 30 2016, 18:31:42) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
```

##### CONFIGURATION
None

##### OS / ENVIRONMENT
N/A

##### SUMMARY
Using the `cloudflare_dns` module in check mode, where a change would be made, causes an `UnboundLocalError` to be thrown.

Without check mode, or if no changes would be made, the module works as expected.

##### STEPS TO REPRODUCE

Playbook:

```yaml
- hosts: localhost
  connection: local
  
  tasks:
  - name: create dns record
    cloudflare_dns:
      zone: example.com
      record: a-record-that-does-not-exist
      type: A
      value: 1.2.3.4
      state: present
      account_email: foo@example.com
      account_api_token: aabbccddeeff
```

Command:

```bash
ansible-playbook example.yml --check
```

##### EXPECTED RESULTS
A `changed` result to be outputted, and no record created.

##### ACTUAL RESULTS
An error is thrown:

```
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: UnboundLocalError: local variable 'result' referenced before assignment
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_ioQv52/ansible_module_cloudflare_dns.py\", line 648, in <module>\n    main()\n  File \"/tmp/ansible_ioQv52/ansible_module_cloudflare_dns.py\", line 636, in main\n    result,changed = cf_api.ensure_dns_record()\n  File \"/tmp/ansible_ioQv52/ansible_module_cloudflare_dns.py\", line 584, in ensure_dns_record\n    return result,self.changed\nUnboundLocalError: local variable 'result' referenced before assignment\n", "module_stdout": "", "msg": "MODULE FAILURE"}
```

The error cleaned up:

```
UnboundLocalError: local variable 'result' referenced before assignment

Traceback (most recent call last):
  File "/tmp/ansible_ioQv52/ansible_module_cloudflare_dns.py", line 648, in <module>
    main()
  File "/tmp/ansible_ioQv52/ansible_module_cloudflare_dns.py", line 636, in main
    result,changed = cf_api.ensure_dns_record()
  File "/tmp/ansible_ioQv52/ansible_module_cloudflare_dns.py", line 584, in ensure_dns_record
    return result,self.changed
```


Discussion:
cc @mgruener
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
resolved_by_pr 23683

Resolving patch:
diff --git a/lib/ansible/modules/net_tools/cloudflare_dns.py b/lib/ansible/modules/net_tools/cloudflare_dns.py
--- a/lib/ansible/modules/net_tools/cloudflare_dns.py
+++ b/lib/ansible/modules/net_tools/cloudflare_dns.py
@@ -596,13 +596,17 @@ def ensure_dns_record(self,**kwargs):
             if (type == 'CNAME') and (cur_record['content'] != new_record['content']):
                 do_update = True
             if do_update:
-                if not self.module.check_mode:
+                if self.module.check_mode:
+                    result = new_record
+                else:
                     result, info = self._cf_api_call('/zones/{0}/dns_records/{1}'.format(zone_id,records[0]['id']),'PUT',new_record)
                 self.changed = True
                 return result,self.changed
             else:
                 return records,self.changed
-        if not self.module.check_mode:
+        if self.module.check_mode:
+            result = new_record
+        else:
             result, info = self._cf_api_call('/zones/{0}/dns_records'.format(zone_id),'POST',new_record)
         self.changed = True
         return result,self.changed


Test patch: