Repository: ansible/ansible-modules-core

Issue:
ini_file module: bracklets in key break idempotence
Issue Type: Bug Report
Ansible Version: ansible-playbook 2.0.0 (devel 5d645f3a8b) last updated 2015/11/13 13:27:13 (GMT +200)
Environment: Ubuntu 15.04
Summary: When using ini_file for modifying /etc/php5/fpm/pool.d/www.conf it will not recognize strings  which include "[" or "]" in key and append it again to the file. Using Ansible 1.9.4 this works just as expected.

Example: You want to set

```
php_admin_value[sendmail_path]: "/usr/sbin/sendmail -t -i -f an@onymo.us"
```

using this hash:

``` yaml
php_admin_value[sendmail_path]:
    value: '"/usr/sbin/sendmail -t -i -f an@onymo.us"'
```

On first run Ansible will append this string to the file just as expected. On second run it will append it again, even though it's already present. When removing the bracklets it will only be inserted once.

Removing the bracklets from value will work as expected (not changed one second run)

ini_file module: bracklets in key break idempotence
Issue Type: Bug Report
Ansible Version: ansible-playbook 2.0.0 (devel 5d645f3a8b) last updated 2015/11/13 13:27:13 (GMT +200)
Environment: Ubuntu 15.04
Summary: When using ini_file for modifying /etc/php5/fpm/pool.d/www.conf it will not recognize strings  which include "[" or "]" in key and append it again to the file. Using Ansible 1.9.4 this works just as expected.

Example: You want to set

```
php_admin_value[sendmail_path]: "/usr/sbin/sendmail -t -i -f an@onymo.us"
```

using this hash:

``` yaml
php_admin_value[sendmail_path]:
    value: '"/usr/sbin/sendmail -t -i -f an@onymo.us"'
```

On first run Ansible will append this string to the file just as expected. On second run it will append it again, even though it's already present. When removing the bracklets it will only be inserted once.

Removing the bracklets from value will work as expected (not changed one second run)



Discussion:
[module: files/ini_file.py]

@theraser Thanks for submitting this bug report.

@jpmens @noseka1 -- thanks in advance for taking a look at this bug report and for your ongoing work in maintaining this module.

Thanks for reporting the issue. I think I could fix the problem. The respective pull request is here:
https://github.com/ansible/ansible-modules-core/pull/2590

[module: files/ini_file.py]

@theraser Thanks for submitting this bug report.

@jpmens @noseka1 -- thanks in advance for taking a look at this bug report and for your ongoing work in maintaining this module.

Thanks for reporting the issue. I think I could fix the problem. The respective pull request is here:
https://github.com/ansible/ansible-modules-core/pull/2590


Resolving patch:
diff --git a/files/ini_file.py b/files/ini_file.py
--- a/files/ini_file.py
+++ b/files/ini_file.py
@@ -99,6 +99,22 @@
 import sys
 import os
 
+# ==============================================================
+# match_opt
+
+def match_opt(option, line):
+  option = re.escape(option)
+  return re.match('%s *=' % option, line) \
+    or re.match('# *%s *=' % option, line) \
+    or re.match('; *%s *=' % option, line)
+
+# ==============================================================
+# match_active_opt
+
+def match_active_opt(option, line):
+  option = re.escape(option)
+  return re.match('%s *=' % option, line)
+
 # ==============================================================
 # do_ini
 
@@ -141,9 +157,7 @@ def do_ini(module, filename, section=None, option=None, value=None, state='prese
             if within_section and option:
                 if state == 'present':
                     # change the existing option line
-                    if re.match('%s *=' % option, line) \
-                            or re.match('# *%s *=' % option, line) \
-                            or re.match('; *%s *=' % option, line):
+                    if match_opt(option, line):
                         newline = '%s = %s\n' % (option, value)
                         changed = ini_lines[index] != newline
                         ini_lines[index] = newline
@@ -154,14 +168,14 @@ def do_ini(module, filename, section=None, option=None, value=None, state='prese
                                 line = ini_lines[index]
                                 if line.startswith('['):
                                     break
-                                if re.match('%s *=' % option, line):
+                                if match_active_opt(option, line):
                                     del ini_lines[index]
                                 else:
                                     index = index + 1
                         break
                 else:
                     # comment out the existing option line
-                    if re.match('%s *=' % option, line):
+                    if match_active_opt(option, line):
                         ini_lines[index] = '#%s' % ini_lines[index]
                         changed = True
                         break


Test patch: