Repository: ansible-collections/community.general

Issue:
Module postgresql_pg_hba Throws KeyError When Setting Method Options
<!--- Verify first that your issue is not already reported on GitHub -->
<!--- Also test if the latest release and devel branch are affected too -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
Using Ansible embedded in Red Hat Satellite 6.6 receiving KeyError: 'options' for simple task to modify pg_hba.conf
**Note:** Hostname and User ID redacted.

If this has already been fixed in a later version, a back port (and possibly a Bugzilla) is needed to include in Red Hat Satellite.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below, use your best guess if unsure -->
postgresql_pg_hba

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```paste below
ansible 2.8.16
  config file = /home/********/.ansible.cfg
  configured module search path = [u'/home/********/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Mar 20 2020, 17:08:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```paste below
ANSIBLE_PIPELINING(/home/********/.ansible.cfg) = True
DEFAULT_HOST_LIST(/home/********/.ansible.cfg) = [u'/home/********/cpe-ansible/inventory']
DEFAULT_TIMEOUT(/home/********/.ansible.cfg) = 30
DEFAULT_VAULT_IDENTITY_LIST(/home/********/.ansible.cfg) = [u'satellite@~/ansible/.satellite', u'cache@~/ansible/.cache'
RETRY_FILES_ENABLED(/home/********/.ansible.cfg) = False
```

##### OS / ENVIRONMENT
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->
Red Hat Enterprise Linux 7.9 (kernel: 3.10.0-1127.19.1.el7.x86_64)
Red Hat Satellite 6.6.3
FIPS mode enabled

##### STEPS TO REPRODUCE
<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: configure user id map for local connections
  postgresql_pg_hba:
    dest:      "/var/lib/pgsql/10/data/pg_hba.conf"
    contype:   local
    databases: all
    method:    peer
    options:   "map=sysmap"
    users:     all
```
pg_hba.conf
```
local   replication     all     peer
local   all     all     peer
host    replication     all     127.0.0.1/32    scram-sha-256
host    replication     all     ::1/128 scram-sha-256
host    all     all     127.0.0.1/32    scram-sha-256
host    all     all     ::1/128 scram-sha-256
host    all     all     10.xxx.xx.0/23  scram-sha-256
```


<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- Describe what you expected to happen when running the steps above -->
```
TASK [CPE.postgresql : configure user id map for local connections] *********************************************************
ok: [********.vha.med.va.gov]
```

##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes -->
```paste below
TASK [CPE.postgresql : configure user id map for local connections] *********************************************************
task path: /home/********/.ansible/roles/CPE.postgresql/tasks/main.yml:70
Using module file /usr/lib/python2.7/site-packages/ansible/modules/database/postgresql/postgresql_pg_hba.py
Pipelining is enabled.
<********.vha.med.va.gov> ESTABLISH SSH CONNECTION FOR USER: None
<********.vha.med.va.gov> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=30 -o ControlPath=/home/********/.ansible/cp/6e7932688e ********.vha.med.va.gov '/bin/sh -c '"'"'sudo -H -S -n  -u root /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-mjjreuqbecefkovouzbfqpmzeznirqju ; /usr/bin/python'"'"'"'"'"'"'"'"' && sleep 0'"'"''
Escalation succeeded
<********.vha.med.va.gov> (1, '', 'FIPS mode initialized\r\nTraceback (most recent call last):\n  File "<stdin>", line 114, in <module>\n  File "<stdin>", line 106, in _ansiballz_main\n  File "<stdin>", line 49, in invoke_module\n  File "/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py", line 755, in <module>\n  File "/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py", line 727, in main\n  File "/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py", line 338, in add_rule\nKeyError: \'options\'\n')
<********.vha.med.va.gov> Failed to connect to the host via ssh: FIPS mode initialized
Traceback (most recent call last):
  File "<stdin>", line 114, in <module>
  File "<stdin>", line 106, in _ansiballz_main
  File "<stdin>", line 49, in invoke_module
  File "/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py", line 755, in <module>
  File "/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py", line 727, in main
  File "/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py", line 338, in add_rule
KeyError: 'options'
fatal: [********.vha.med.va.gov]: FAILED! => {
    "changed": false,
    "module_stderr": "FIPS mode initialized\r\nTraceback (most recent call last):\n  File \"<stdin>\", line 114, in <module>\n  File \"<stdin>\", line 106, in _ansiballz_main\n  File \"<stdin>\", line 49, in invoke_module\n  File \"/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py\", line 755, in <module>\n  File \"/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py\", line 727, in main\n  File \"/tmp/ansible_postgresql_pg_hba_payload_eaUKvE/__main__.py\", line 338, in add_rule\nKeyError: 'options'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

```



Discussion:
Files identified in the description:
* [`plugins/modules/database/postgresql/postgresql_pg_hba.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/database/postgresql/postgresql_pg_hba.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @Andersson007 @Dorn- @andytom @ilicmilan @jbscalia @kostiantyn-nemchenko @matburt @nerzhul @sebasmannem @tcraxs
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Please note that Ansible 2.8 only receives security fixes.

In any case, the error happens here: https://github.com/ansible/ansible/blob/stable-2.8/lib/ansible/modules/database/postgresql/postgresql_pg_hba.py#L338
Looks like the code hasn't changed: https://github.com/ansible-collections/community.general/blob/main/plugins/modules/database/postgresql/postgresql_pg_hba.py#L338
@vhaispdeaded thanks for reporting this! @felixfontein thanks for the information!
I already emailed @sebasmannem, the author, he takes care of the module

Resolving patch:
diff --git a/plugins/modules/database/postgresql/postgresql_pg_hba.py b/plugins/modules/database/postgresql/postgresql_pg_hba.py
--- a/plugins/modules/database/postgresql/postgresql_pg_hba.py
+++ b/plugins/modules/database/postgresql/postgresql_pg_hba.py
@@ -335,7 +335,7 @@ def add_rule(self, rule):
             ekeys = set(list(oldrule.keys()) + list(rule.keys()))
             ekeys.remove('line')
             for k in ekeys:
-                if oldrule[k] != rule[k]:
+                if oldrule.get(k) != rule.get(k):
                     raise PgHbaRuleChanged('{0} changes {1}'.format(rule, oldrule))
         except PgHbaRuleChanged:
             self.rules[key] = rule


Test patch:
diff --git a/tests/integration/targets/postgresql_pg_hba/tasks/postgresql_pg_hba_initial.yml b/tests/integration/targets/postgresql_pg_hba/tasks/postgresql_pg_hba_initial.yml
--- a/tests/integration/targets/postgresql_pg_hba/tasks/postgresql_pg_hba_initial.yml
+++ b/tests/integration/targets/postgresql_pg_hba/tasks/postgresql_pg_hba_initial.yml
@@ -58,6 +58,20 @@
   register: pg_hba_change
   with_items: "{{pg_hba_test_ips}}"
 
+- name: Able to add options on rule without
+  postgresql_pg_hba:
+    dest: "/tmp/pg_hba.conf"
+    users: "+some"
+    order: "sud"
+    state: "present"
+    contype: "local"
+    method: "cert"
+    options: "{{ item }}"
+    address: ""
+  with_items:
+  - ""
+  - "clientcert=1"
+
 - name: Retain options even if they contain spaces
   postgresql_pg_hba:
     dest: "/tmp/pg_hba.conf"