Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

community.postgresql.pg_hba can bring a pg_hba.conf into an unmanageable state. #705

Open
Tetha opened this issue Jun 14, 2024 · 4 comments

Comments

@Tetha
Copy link

Tetha commented Jun 14, 2024

SUMMARY

Moin,

the plugin community.postgresql.pg_hba is able to bring a pg_hba file into a state it cannot modify again. This then requires some manual cleanup, and results in a bunch of rather confusing error messages.

For the record, I've setup a separate ansible installation for this reproduction so I could check this issue with the latest ansible and latest community.postgresql. Hence why I have to wrestle a bit with environment variables in places.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

community.postgresql.postgresql_pg_hba

ANSIBLE VERSION
ansible [core 2.17.0]
  config file = /home/tetha/.ansible.cfg
  configured module search path = ['/home/tetha/Stuff/2024-06/14-ansible-repro', '/home/tetha/Projects/ansible/library']
  ansible python module location = /home/tetha/Stuff/2024-06/14-ansible-repro/venv/lib/python3.10/site-packages/ansible
  ansible collection location = /home/tetha/.ansible/collections:/usr/share/ansible/collections
  executable location = ./venv/bin/ansible
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/home/tetha/Stuff/2024-06/14-ansible-repro/venv/bin/python3)
  jinja version = 3.1.4
  libyaml = True

We also see this behavior with ansible 2.13.

COLLECTION VERSION
# /home/tetha/Stuff/2024-06/14-ansible-repro/test_collections/ansible_collections
Collection           Version
-------------------- -------
community.postgresql 3.4.1  

# /home/tetha/Stuff/2024-06/14-ansible-repro/venv/lib/python3.10/site-packages/ansible_collections
Collection           Version
-------------------- -------
community.postgresql 3.4.1  

We've also encountered this with version 2.2.0

CONFIGURATION
CACHE_PLUGIN(/home/tetha/.ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/home/tetha/.ansible.cfg) = /home/tetha/.cache/ansible_fact_cache
CACHE_PLUGIN_TIMEOUT(/home/tetha/.ansible.cfg) = 3600
CALLBACKS_ENABLED(/home/tetha/.ansible.cfg) = ['timer', 'profile_tasks', 'profile_roles']
CONFIG_FILE() = /home/tetha/.ansible.cfg
DEFAULT_MODULE_PATH(env: ANSIBLE_LIBRARY) = ['/home/tetha/Stuff/2024-06/14-ansible-repro', '/home/tetha/Projects/ansible/library']
DEFAULT_MODULE_UTILS_PATH(env: ANSIBLE_MODULE_UTILS) = ['/home/tetha/Projects/ansible/library/module_utils']
DEFAULT_ROLES_PATH(env: ANSIBLE_ROLES_PATH) = ['/home/tetha/Stuff/2024-06/14-ansible-repro', '/home/tetha/Projects/ansible']
EDITOR(env: EDITOR) = vim
INTERPRETER_PYTHON(/home/tetha/.ansible.cfg) = auto
INVENTORY_CACHE_ENABLED(/home/tetha/.ansible.cfg) = True
PAGER(env: PAGER) = less
SHOW_CUSTOM_STATS(/home/tetha/.ansible.cfg) = True
OS / ENVIRONMENT

This is an up-to-date Ubuntu 22.04 Jammy running python 3.10.

STEPS TO REPRODUCE

I've included a simple playbook here. This playbook crashes in the second task upon the first run, and afterwards it crashes in the first task, too. Most modifications of the pg_hba now fail.

Naturally, no one would write such a user manually, but this occured when mis-handling a loop and wrote pretty much the sample user content into the pg_hba.conf

- hosts: localhost
  tasks:
    - community.postgresql.postgresql_pg_hba:
        dest: pg_hba.conf
        users: '{ "oh": "no" }'
        state: present
        contype: host
        create: true
    - community.postgresql.postgresql_pg_hba:
        dest: pg_hba.conf
        users: oops
        state: present
        contype: host
        create: true
EXPECTED RESULTS

I would expect the first pg_hba invocation to error out, because it would lead to the file being unmanageable by the plugin, I think. Especially because this also prevents postgres from loading this file, so it's not ideal to have this config in such a state.

ACTUAL RESULTS

The first run with a valid or without an existing pg_hba.conf looks like this:

[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
ansible-playbook [core 2.17.0]
  config file = /home/tetha/.ansible.cfg
  configured module search path = ['/home/tetha/Stuff/2024-06/14-ansible-repro', '/home/tetha/Projects/ansible/library']
  ansible python module location = /home/tetha/Stuff/2024-06/14-ansible-repro/venv/lib/python3.10/site-packages/ansible
  ansible collection location = /home/tetha/.ansible/collections:/usr/share/ansible/collections
  executable location = ./venv/bin/ansible-playbook
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/home/tetha/Stuff/2024-06/14-ansible-repro/venv/bin/python3)
  jinja version = 3.1.4
  libyaml = True
Using /home/tetha/.ansible.cfg as config file
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
redirecting (type: callback) ansible.builtin.timer to ansible.posix.timer
redirecting (type: callback) ansible.builtin.profile_tasks to ansible.posix.profile_tasks
redirecting (type: callback) ansible.builtin.profile_roles to ansible.posix.profile_roles
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
 ______________________
< PLAYBOOK: repro.yaml >
 ----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

1 plays in repro.yaml
 __________________
< PLAY [localhost] >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

 ________________________
< TASK [Gathering Facts] >
 ------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

task path: /home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:1
Freitag 14 Juni 2024  15:54:46 +0200 (0:00:00.055)       0:00:00.055 ********** 
Freitag 14 Juni 2024  15:54:46 +0200 (0:00:00.055)       0:00:00.055 ********** 
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: tetha
<127.0.0.1> EXEC /bin/sh -c 'echo ~tetha && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/tetha/.ansible/tmp `"&& mkdir "` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373286.4376261-99586-275264173215600 `" && echo ansible-tmp-1718373286.4376261-99586-275264173215600="` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373286.4376261-99586-275264173215600 `" ) && sleep 0'
Using module file /home/tetha/Stuff/2024-06/14-ansible-repro/venv/lib/python3.10/site-packages/ansible/modules/setup.py
<127.0.0.1> PUT /home/tetha/.ansible/tmp/ansible-local-9957782yltq_b/tmp8pe9_cmj TO /home/tetha/.ansible/tmp/ansible-tmp-1718373286.4376261-99586-275264173215600/AnsiballZ_setup.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/tetha/.ansible/tmp/ansible-tmp-1718373286.4376261-99586-275264173215600/ /home/tetha/.ansible/tmp/ansible-tmp-1718373286.4376261-99586-275264173215600/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/home/tetha/Stuff/2024-06/14-ansible-repro/venv/bin/python3 /home/tetha/.ansible/tmp/ansible-tmp-1718373286.4376261-99586-275264173215600/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/tetha/.ansible/tmp/ansible-tmp-1718373286.4376261-99586-275264173215600/ > /dev/null 2>&1 && sleep 0'
ok: [localhost]
 _______________________________________________
< TASK [community.postgresql.postgresql_pg_hba] >
 -----------------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

task path: /home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:3
Freitag 14 Juni 2024  15:54:47 +0200 (0:00:01.078)       0:00:01.134 ********** 
Freitag 14 Juni 2024  15:54:47 +0200 (0:00:01.078)       0:00:01.134 ********** 
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: tetha
<127.0.0.1> EXEC /bin/sh -c 'echo ~tetha && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/tetha/.ansible/tmp `"&& mkdir "` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373287.515695-99754-201314377687294 `" && echo ansible-tmp-1718373287.515695-99754-201314377687294="` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373287.515695-99754-201314377687294 `" ) && sleep 0'
Using module file /home/tetha/.ansible/collections/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py
<127.0.0.1> PUT /home/tetha/.ansible/tmp/ansible-local-9957782yltq_b/tmpy0xw0p2_ TO /home/tetha/.ansible/tmp/ansible-tmp-1718373287.515695-99754-201314377687294/AnsiballZ_postgresql_pg_hba.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/tetha/.ansible/tmp/ansible-tmp-1718373287.515695-99754-201314377687294/ /home/tetha/.ansible/tmp/ansible-tmp-1718373287.515695-99754-201314377687294/AnsiballZ_postgresql_pg_hba.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/home/tetha/Stuff/2024-06/14-ansible-repro/venv/bin/python3 /home/tetha/.ansible/tmp/ansible-tmp-1718373287.515695-99754-201314377687294/AnsiballZ_postgresql_pg_hba.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/tetha/.ansible/tmp/ansible-tmp-1718373287.515695-99754-201314377687294/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true,
    "diff": {
        "after": {
            "file": "pg_hba.conf",
            "pg_hba": [
                "host\tall\t{ \"oh\": \"no\" }\tsamehost\tmd5"
            ]
        },
        "before": {
            "file": "pg_hba.conf",
            "pg_hba": []
        }
    },
    "invocation": {
        "module_args": {
            "address": "samehost",
            "attributes": null,
            "backup": false,
            "backup_file": null,
            "comment": null,
            "contype": "host",
            "create": true,
            "databases": "all",
            "dest": "pg_hba.conf",
            "group": null,
            "keep_comments_at_rules": false,
            "method": "md5",
            "mode": null,
            "netmask": null,
            "options": null,
            "order": "sdu",
            "overwrite": false,
            "owner": null,
            "rules": null,
            "rules_behavior": "conflict",
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "state": "present",
            "unsafe_writes": false,
            "users": "{ \"oh\": \"no\" }"
        }
    },
    "msgs": [
        "Adding rule {'type': 'host', 'db': 'all', 'usr': '{ \"oh\": \"no\" }', 'src': 'samehost', 'method': 'md5'}",
        "Changed",
        "Writing"
    ],
    "pg_hba": [
        {
            "db": "all",
            "method": "md5",
            "src": "samehost",
            "type": "host",
            "usr": "{ \"oh\": \"no\" }"
        }
    ]
}
 _______________________________________________
< TASK [community.postgresql.postgresql_pg_hba] >
 -----------------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

task path: /home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:9
Freitag 14 Juni 2024  15:54:47 +0200 (0:00:00.165)       0:00:01.299 ********** 
Freitag 14 Juni 2024  15:54:47 +0200 (0:00:00.165)       0:00:01.299 ********** 
The full traceback is:
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_o1oas00k/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 804, in main
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_o1oas00k/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 340, in __init__
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_o1oas00k/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 380, in read
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_o1oas00k/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 513, in __init__
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_o1oas00k/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 587, in fromline
fatal: [localhost]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "address": "samehost",
            "attributes": null,
            "backup": false,
            "backup_file": null,
            "comment": null,
            "contype": "host",
            "create": true,
            "databases": "all",
            "dest": "pg_hba.conf",
            "group": null,
            "keep_comments_at_rules": false,
            "method": "md5",
            "mode": null,
            "netmask": null,
            "options": null,
            "order": "sdu",
            "overwrite": false,
            "owner": null,
            "rules": null,
            "rules_behavior": "conflict",
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "state": "present",
            "unsafe_writes": false,
            "users": "oops"
        }
    },
    "msg": "Error reading file:\nRule host\tall\t{ \"oh\": \"no\" }\tsamehost\tmd5 of 'host' type has invalid auth-method '\"no\"'"
}
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: tetha
<127.0.0.1> EXEC /bin/sh -c 'echo ~tetha && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/tetha/.ansible/tmp `"&& mkdir "` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373287.680575-99780-168711075296016 `" && echo ansible-tmp-1718373287.680575-99780-168711075296016="` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373287.680575-99780-168711075296016 `" ) && sleep 0'
Using module file /home/tetha/.ansible/collections/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py
<127.0.0.1> PUT /home/tetha/.ansible/tmp/ansible-local-9957782yltq_b/tmpa2de_034 TO /home/tetha/.ansible/tmp/ansible-tmp-1718373287.680575-99780-168711075296016/AnsiballZ_postgresql_pg_hba.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/tetha/.ansible/tmp/ansible-tmp-1718373287.680575-99780-168711075296016/ /home/tetha/.ansible/tmp/ansible-tmp-1718373287.680575-99780-168711075296016/AnsiballZ_postgresql_pg_hba.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/home/tetha/Stuff/2024-06/14-ansible-repro/venv/bin/python3 /home/tetha/.ansible/tmp/ansible-tmp-1718373287.680575-99780-168711075296016/AnsiballZ_postgresql_pg_hba.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/tetha/.ansible/tmp/ansible-tmp-1718373287.680575-99780-168711075296016/ > /dev/null 2>&1 && sleep 0'
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

localhost                  : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

Playbook run took 0 days, 0 hours, 0 minutes, 1 seconds
Freitag 14 Juni 2024  15:54:47 +0200 (0:00:00.106)       0:00:01.406 ********** 
=============================================================================== 
Gathering Facts --------------------------------------------------------- 1.08s
/home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:1 --------------------
community.postgresql.postgresql_pg_hba ---------------------------------- 0.17s
/home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:3 --------------------
community.postgresql.postgresql_pg_hba ---------------------------------- 0.11s
/home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:9 --------------------
Freitag 14 Juni 2024  15:54:47 +0200 (0:00:00.106)       0:00:01.406 ********** 
=============================================================================== 
gather_facts ------------------------------------------------------------ 1.08s
community.postgresql.postgresql_pg_hba ---------------------------------- 0.27s
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
total ------------------------------------------------------------------- 1.35s

and results in a pg_hba.conf like this:

host	all	{ "oh": "no" }	samehost	md5

A second ansible run after this crashes in the first pg_hba invocation:

[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
ansible-playbook [core 2.17.0]
  config file = /home/tetha/.ansible.cfg
  configured module search path = ['/home/tetha/Stuff/2024-06/14-ansible-repro', '/home/tetha/Projects/ansible/library']
  ansible python module location = /home/tetha/Stuff/2024-06/14-ansible-repro/venv/lib/python3.10/site-packages/ansible
  ansible collection location = /home/tetha/.ansible/collections:/usr/share/ansible/collections
  executable location = ./venv/bin/ansible-playbook
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/home/tetha/Stuff/2024-06/14-ansible-repro/venv/bin/python3)
  jinja version = 3.1.4
  libyaml = True
Using /home/tetha/.ansible.cfg as config file
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
redirecting (type: callback) ansible.builtin.timer to ansible.posix.timer
redirecting (type: callback) ansible.builtin.profile_tasks to ansible.posix.profile_tasks
redirecting (type: callback) ansible.builtin.profile_roles to ansible.posix.profile_roles
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
 ______________________
< PLAYBOOK: repro.yaml >
 ----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

1 plays in repro.yaml
 __________________
< PLAY [localhost] >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

 ________________________
< TASK [Gathering Facts] >
 ------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

task path: /home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:1
Freitag 14 Juni 2024  15:56:09 +0200 (0:00:00.055)       0:00:00.055 ********** 
Freitag 14 Juni 2024  15:56:09 +0200 (0:00:00.055)       0:00:00.055 ********** 
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: tetha
<127.0.0.1> EXEC /bin/sh -c 'echo ~tetha && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/tetha/.ansible/tmp `"&& mkdir "` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373369.4282665-99972-199185975752250 `" && echo ansible-tmp-1718373369.4282665-99972-199185975752250="` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373369.4282665-99972-199185975752250 `" ) && sleep 0'
Using module file /home/tetha/Stuff/2024-06/14-ansible-repro/venv/lib/python3.10/site-packages/ansible/modules/setup.py
<127.0.0.1> PUT /home/tetha/.ansible/tmp/ansible-local-99963uibetuor/tmpbowre77a TO /home/tetha/.ansible/tmp/ansible-tmp-1718373369.4282665-99972-199185975752250/AnsiballZ_setup.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/tetha/.ansible/tmp/ansible-tmp-1718373369.4282665-99972-199185975752250/ /home/tetha/.ansible/tmp/ansible-tmp-1718373369.4282665-99972-199185975752250/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/home/tetha/Stuff/2024-06/14-ansible-repro/venv/bin/python3 /home/tetha/.ansible/tmp/ansible-tmp-1718373369.4282665-99972-199185975752250/AnsiballZ_setup.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/tetha/.ansible/tmp/ansible-tmp-1718373369.4282665-99972-199185975752250/ > /dev/null 2>&1 && sleep 0'
ok: [localhost]
 _______________________________________________
< TASK [community.postgresql.postgresql_pg_hba] >
 -----------------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

task path: /home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:3
Freitag 14 Juni 2024  15:56:10 +0200 (0:00:01.131)       0:00:01.187 ********** 
Freitag 14 Juni 2024  15:56:10 +0200 (0:00:01.131)       0:00:01.186 ********** 
The full traceback is:
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_s53grq9l/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 804, in main
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_s53grq9l/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 340, in __init__
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_s53grq9l/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 380, in read
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_s53grq9l/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 513, in __init__
  File "/tmp/ansible_community.postgresql.postgresql_pg_hba_payload_s53grq9l/ansible_community.postgresql.postgresql_pg_hba_payload.zip/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py", line 587, in fromline
fatal: [localhost]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "address": "samehost",
            "attributes": null,
            "backup": false,
            "backup_file": null,
            "comment": null,
            "contype": "host",
            "create": true,
            "databases": "all",
            "dest": "pg_hba.conf",
            "group": null,
            "keep_comments_at_rules": false,
            "method": "md5",
            "mode": null,
            "netmask": null,
            "options": null,
            "order": "sdu",
            "overwrite": false,
            "owner": null,
            "rules": null,
            "rules_behavior": "conflict",
            "selevel": null,
            "serole": null,
            "setype": null,
            "seuser": null,
            "state": "present",
            "unsafe_writes": false,
            "users": "{ \"oh\": \"no\" }"
        }
    },
    "msg": "Error reading file:\nRule host\tall\t{ \"oh\": \"no\" }\tsamehost\tmd5 of 'host' type has invalid auth-method '\"no\"'"
}
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: tetha
<127.0.0.1> EXEC /bin/sh -c 'echo ~tetha && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/tetha/.ansible/tmp `"&& mkdir "` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373370.5585496-100106-38796347460149 `" && echo ansible-tmp-1718373370.5585496-100106-38796347460149="` echo /home/tetha/.ansible/tmp/ansible-tmp-1718373370.5585496-100106-38796347460149 `" ) && sleep 0'
Using module file /home/tetha/.ansible/collections/ansible_collections/community/postgresql/plugins/modules/postgresql_pg_hba.py
<127.0.0.1> PUT /home/tetha/.ansible/tmp/ansible-local-99963uibetuor/tmpi8xh8j7n TO /home/tetha/.ansible/tmp/ansible-tmp-1718373370.5585496-100106-38796347460149/AnsiballZ_postgresql_pg_hba.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /home/tetha/.ansible/tmp/ansible-tmp-1718373370.5585496-100106-38796347460149/ /home/tetha/.ansible/tmp/ansible-tmp-1718373370.5585496-100106-38796347460149/AnsiballZ_postgresql_pg_hba.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/home/tetha/Stuff/2024-06/14-ansible-repro/venv/bin/python3 /home/tetha/.ansible/tmp/ansible-tmp-1718373370.5585496-100106-38796347460149/AnsiballZ_postgresql_pg_hba.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /home/tetha/.ansible/tmp/ansible-tmp-1718373370.5585496-100106-38796347460149/ > /dev/null 2>&1 && sleep 0'
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

Playbook run took 0 days, 0 hours, 0 minutes, 1 seconds
Freitag 14 Juni 2024  15:56:10 +0200 (0:00:00.166)       0:00:01.353 ********** 
=============================================================================== 
Gathering Facts --------------------------------------------------------- 1.13s
/home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:1 --------------------
community.postgresql.postgresql_pg_hba ---------------------------------- 0.17s
/home/tetha/Stuff/2024-06/14-ansible-repro/repro.yaml:3 --------------------
Freitag 14 Juni 2024  15:56:10 +0200 (0:00:00.166)       0:00:01.353 ********** 
=============================================================================== 
gather_facts ------------------------------------------------------------ 1.13s
community.postgresql.postgresql_pg_hba ---------------------------------- 0.17s
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
total ------------------------------------------------------------------- 1.30s
@Tetha
Copy link
Author

Tetha commented Jun 15, 2024

Hmm, I've been looking at this a bit.

There is a clean way to handle this, which requires a bit more work:

I guess based off of the spec in the hba documentation: https://www.postgresql.org/docs/current/auth-pg-hba-conf.html , we could add a simple two-step validation for the rule key values:

  • If the value contains no space, we're all good and just continue
  • If the value contains a space, however, we need to check two things:
    • The first and last character of the value should be a quote (or should we add that automatically?)
    • and there should be no further quote in there

This would slot in right there: https://github.com/ansible-collections/community.postgresql/blob/main/plugins/modules/postgresql_pg_hba.py#L803

In that case, this split also has to be extended to handle quoted values, which isn't a big deal:

https://github.com/ansible-collections/community.postgresql/blob/main/plugins/modules/postgresql_pg_hba.py#L568

Alternatively, we could just disallow spaces in rule values.

I'm fine setting up either.

@betanummeric
Copy link
Member

Hi @Tetha, thanks for pointing that out. The parsing/serialization done by the postgresql_pg_hba module is not safe for all possible inputs.
This relates to (maybe even duplicates) issue #420, which links some attempted fixes. We should implement some proper parsing supporting fields with (almost) arbitrary characters.

@toydarian
Copy link
Contributor

@betanummeric do you suggest to use lark or a similar library? Or should we parse it with regexes?

@betanummeric
Copy link
Member

Hi @toydarian, I didn't know about lark. Do you have experience with that?
Last year I attempted to do the parsing with regexes (#458), but I never had time to properly test and finish that.

Adding any new library has these drawbacks:

  • a thing more we need to update
  • the module gets slightly bigger (more data to copy around everywhere)
  • it could be abandoned by the library maintainers
  • new attack surface (what if the library has a security issue?)

Of course implementing the parsing on our own (with regexes) may not be perfect either. That can get complex to write and maintain and contain bugs as well.

I would prefer trying to extend the already-existing custom parsing to fix the known bugs and see how complex that gets, before trying with a new dependency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants