Repository: ansible/ansible

Issue:
win_regedit case sensitivity
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
win_regedit

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.3.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170118]
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->
NA

##### SUMMARY
<!--- Explain the problem briefly -->
Module does not properly check case of data, two issues:
1. If writing a key value of ```false``` when key value was ```False``` before playbook was run  - then key is not changed.

2. if writing a key value of ```false``` (without quotes around value in data field) when key value was anything else (e.g.  ```true```) before playbook was run, then Ansible writes value as ```False```

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
Case 1:
<!--- Paste example playbooks or commands between quotes below -->
```yaml
    - name: Set value to false (from False)
      win_regedit:
          path: HKLM:\SOFTWARE\COMPANY\Product\global
          name: report_engine_issue
          type: string
          data: 'false'
          state: present
```

Case 2:
<!--- Paste example playbooks or commands between quotes below -->
```yaml
    - name: Set value to false (from True)
      win_regedit:
          path: HKLM:\SOFTWARE\COMPANY\Product\global
          name: report_engine_issue
          type: string
          data: false
          state: present
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
'global' key value is set to ```false```

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->


<!--- Paste verbatim command output between quotes below -->
Case 1:
Key value unchanged
```
ok: [mdc-nc2] => {
    "changed": false, 
    "data_changed": false, 
    "data_type_changed": false
}
```
Case 2
Key value set to ```False```, not ```false```
```
ok: [mdc-nc2] => {
    "changed": true, 
    "data_changed": true, 
    "data_type_changed": false
}
```



Discussion:
cc @joshludwig @smadam813
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
I think this is actually to do with yaml data typing, rather than any specific behavior of the module.

By quoting the data value, you tell yaml to handle the value as a string.  But the bare word false is treated as a boolean by yaml.  I believe yaml also treats Yes and No as acceptable boolean representations, so I suspect if you changed task to look like this, you would still wind up with False in the registry data (not tested).

```yaml
    - name: Set value to false (from True)
      win_regedit:
          path: HKLM:\SOFTWARE\COMPANY\Product\global
          name: report_engine_issue
          type: string
          data: No
          state: present
```
I think this edge case would be worth documenting (in win_regedit examples perhaps), but I think the principle here is if you need a string, pass the module a string.   

It's not clear to me whether or not anything should change in ansible to handle this case, though.

If we forced a type conversion in the win_regedit module itself it would still guess wrongly (as it is doing now) because the yaml parsing will have happened and typing information lost before the module parameters are passed to the module.  I don't know the core of ansible well enough to say whether anything could be done on the controller side that wouldn't affect the behavior of other modules or pre-existing playbooks.



@jhawkesworth Ok that covers case 2.
Any ideas for case 1 where the value was quoted but it recognised "False" as being the same as "false" and therefore didn't update the registry key?
Thanks for this. Pretty certain its going to be because of the -eq checks in Compare-Data function are case-insensitive.

```powershell
PS C:\Users\jon> $a = "False"
PS C:\Users\jon> $b = "false"
PS C:\Users\jon> if ($a -eq $b) { write-host "---" }
---
PS C:\Users\jon> if ($a -ceq $b) { write-host "---" }
PS C:\Users\jon>
```

Please ould you try changing the 
-eq
 to 
-ceq
 on L80 and L86 of the module and see if that behaves as you'd expect?


@jhawkesworth I made the module changes as requested.
First test run it reported a change, but no change was visible in the registry: ```mdc-nc1                    : ok=1    changed=1    unreachable=0    failed=0 ```
Second run it reported no change, and registry entry still has an uppercase F :(
```
ok: [mdc-nc1] => {
    "changed": false, 
    "data_changed": false, 
    "data_type_changed": false
}
```

Looking at the code entries that you asked me to change, I don't believe line 80 needs to be changed.  It looks to be checking for a null value, so changing the case here shouldn't make any difference.

I agree L80 probably doesn't need changing.  Having realised -eq is case insensitive I prefer to make an explict difference in the code - an 'is null' check would be better at that point anyway.  I suspect the other occurence is part of the solution to this problem though.

Clutching at straws a bit here, but could you clear out the regisry value first, then retry and see if it gets stored with a lower case F?


Ok, it's all good now @jhawkesworth.
Cleared value.  Re-run playbook, and is stored with lower case F.
Changed value manually to upper-case, re-ran playbook and it was changed back to lower-case.

The Line 86 change looks like a fix.  Happy to close.

Resolving patch:
diff --git a/lib/ansible/modules/windows/win_regedit.py b/lib/ansible/modules/windows/win_regedit.py
--- a/lib/ansible/modules/windows/win_regedit.py
+++ b/lib/ansible/modules/windows/win_regedit.py
@@ -76,6 +76,7 @@
 - Check-mode C(-C/--check) and diff output C(-D/--diff) are supported, so that you can test every change against the active configuration before
   applying changes.
 - Beware that some registry hives (C(HKEY_USERS) in particular) do not allow to create new registry paths.
+- Since ansible 2.4, when checking if a string registry value has changed, a case-sensitive test is used.  Previously the test was case-insensitive.
 author: "Adam Keech (@smadam813), Josh Ludwig (@joshludwig)"
 '''
 


Test patch: