ansible-collections / community.zabbix

Zabbix Ansible modules

Home Page:http://galaxy.ansible.com/community/zabbix

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Role zabbix_agent fails with new httpapi

mathieumd opened this issue · comments

SUMMARY

I upgraded community.zabbix from v1.6.0 to v2.3.1 and saw that you moved from depending on zabbix-api to using httpapi (good move, BTW!) But it looks like zabbix_agent role is not working anymore:

  1. it's API tasks are missing become: false in tasks/api.yml, as shown by zabbix_host module's examples. (and probably other tasks too, no?) Without it, it would error about sudo requiring a password.
  2. even after manually adding it, it still fails, but now with this error:

ConnectionError: Could not get API version from Zabbix. Got HTTP code 412. Got version {}

It's not a Zabbix nor API error, as direct access through Curl is working well (both through user.login or token):

# user.login
curl -k -X POST -H 'Content-Type: application/json-rpc' -d @zab.json \
  https://zabbix.example.com/api_jsonrpc.php

{"jsonrpc":"2.0","result":"82be5aa28b979d24c667a62f7077f71a","id":1}

cat zab.json
{
    "jsonrpc": "2.0",
    "method": "user.login",
    "id": 1,
    "auth":null,
    "params": {
        "user": "ansible",
        "password": "xxxxx"
    }
}
# token
curl -k -X POST -H 'Content-Type: application/json-rpc' -d @zab2.json \
  https://zabbix.example.com/api_jsonrpc.php \
  |jq '.result |length'

400

cat zab2.json
{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "output": [
            "hostid",
            "host"
        ],
        "selectInterfaces": [
            "interfaceid",
            "ip"
        ]
    },
    "id": 2,
    "auth": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

PS: As I used curl's -k, I also tried to add the vars ansible_httpapi_validate_certs: false to the task, but it didn't change anything.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

zabbix_agent

ANSIBLE VERSION
ansible [core 2.16.4]
  config file = /home/mathieu/ansible/ansible.cfg
  configured module search path = ['/home/mathieu/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/mathieu/ansible/.collections
  executable location = /usr/bin/ansible
  python version = 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
CONFIGURATION
ANSIBLE_NOCOWS(/home/mathieu/ansible/ansible.cfg) = True
CACHE_PLUGIN(/home/mathieu/ansible/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/home/mathieu/ansible/ansible.cfg) = .facts_cache
CACHE_PLUGIN_TIMEOUT(/home/mathieu/ansible/ansible.cfg) = 900
CALLBACKS_ENABLED(/home/mathieu/ansible/ansible.cfg) = ['syslog_json']
COLLECTIONS_PATHS(/home/mathieu/ansible/ansible.cfg) = ['/home/mathieu/ansible/.collections']
CONFIG_FILE() = /home/mathieu/ansible/ansible.cfg
DEFAULT_GATHERING(/home/mathieu/ansible/ansible.cfg) = smart
DEFAULT_HOST_LIST(/home/mathieu/ansible/ansible.cfg) = ['/home/mathieu/ansible/inventory']
DEFAULT_LOAD_CALLBACK_PLUGINS(/home/mathieu/ansible/ansible.cfg) = True
DEFAULT_ROLES_PATH(/home/mathieu/ansible/ansible.cfg) = ['/home/mathieu/ansible/.roles']
EDITOR(env: EDITOR) = /usr/bin/vim
PAGER(env: PAGER) = /usr/bin/less
OS / ENVIRONMENT / Zabbix Version

Zabbix 6.0 LTS

STEPS TO REPRODUCE
- name: Install and manage Zabbix Agent
  hosts: [ 'all' ]
  become: True
  collections: [ 'community.zabbix', 'debops.debops' ]
  pre_tasks:
    - ...
    # - name: Set credentials to access Zabbix Server API
    #   ansible.builtin.set_fact:
    #     ansible_user: '{{zabbix_api_login_user}}'
    #     ansible_httpapi_pass: '{{zabbix_api_login_pass}}'
    #   tags: [ 'role::zabbix_agent' ]
    - name: Set API token
      ansible.builtin.set_fact:
        ansible_zabbix_auth_key: '{{zabbix_api_token}}'
      tags: [ 'role::zabbix_agent' ]
  roles:
    - ...
    - role: zabbix_agent
      tags: [ 'role::zabbix_agent' ]
ansible-playbook playbooks/monitoring.yml --diff -l example-target1 -t role::zabbix_agent
EXPECTED RESULTS

The creation of the host in Zabbix should success, like it did before moving to httpapi.

ACTUAL RESULTS
TASK [community.zabbix.zabbix_agent : API | Create a new host using agent2 or update an existing host's info] *********************************************************************************
FAILED - RETRYING: [example-target1 -> zabbix.example.com]: API | Create a new host using agent2 or update an existing host's info (3 retries left).
FAILED - RETRYING: [example-target1 -> zabbix.example.com]: API | Create a new host using agent2 or update an existing host's info (2 retries left).
FAILED - RETRYING: [example-target1 -> zabbix.example.com]: API | Create a new host using agent2 or update an existing host's info (1 retries left).
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible.module_utils.connection.ConnectionError: Could not get API version from Zabbix. Got HTTP code 412. Got version {}
fatal: [example-target1 -> zabbix.example.com]: FAILED! => {"attempts": 3, "changed": false, "module_stderr": "Traceback (most recent call last):\n  File \"/home/mathieu/.ansible/tmp/ansible-local-4440244xsco_6v/ansible-tmp-1711357640.4967582-448032-209810283639235/AnsiballZ_zabbix_host.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/home/mathieu/.ansible/tmp/ansible-local-4440244xsco_6v/ansible-tmp-1711357640.4967582-448032-209810283639235/AnsiballZ_zabbix_host.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/mathieu/.ansible/tmp/ansible-local-4440244xsco_6v/ansible-tmp-1711357640.4967582-448032-209810283639235/AnsiballZ_zabbix_host.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.community.zabbix.plugins.modules.zabbix_host', init_globals=dict(_module_fqn='ansible_collections.community.zabbix.plugins.modules.zabbix_host', _modlib_path=modlib_path),\n  File \"<frozen runpy>\", line 226, in run_module\n  File \"<frozen runpy>\", line 98, in _run_module_code\n  File \"<frozen runpy>\", line 88, in _run_code\n  File \"/tmp/ansible_community.zabbix.zabbix_host_payload_z5eubtrt/ansible_community.zabbix.zabbix_host_payload.zip/ansible_collections/community/zabbix/plugins/modules/zabbix_host.py\", line 1250, in <module>\n  File \"/tmp/ansible_community.zabbix.zabbix_host_payload_z5eubtrt/ansible_community.zabbix.zabbix_host_payload.zip/ansible_collections/community/zabbix/plugins/modules/zabbix_host.py\", line 1052, in main\n  File \"/tmp/ansible_community.zabbix.zabbix_host_payload_z5eubtrt/ansible_community.zabbix.zabbix_host_payload.zip/ansible_collections/community/zabbix/plugins/module_utils/base.py\", line 20, in __init__\n  File \"/tmp/ansible_community.zabbix.zabbix_host_payload_z5eubtrt/ansible_community.zabbix.zabbix_host_payload.zip/ansible_collections/community/zabbix/plugins/module_utils/api_request.py\", line 53, in api_version\n  File \"/tmp/ansible_community.zabbix.zabbix_host_payload_z5eubtrt/ansible_community.zabbix.zabbix_host_payload.zip/ansible/module_utils/connection.py\", line 200, in __rpc__\nansible.module_utils.connection.ConnectionError: Could not get API version from Zabbix. Got HTTP code 412. Got version {}\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

Am I missing something?

Note that even defining ansible_zabbix_auth_key directly into the vars section of the task, as suggested by #1073 (comment), did not change anything for me.

Finally I made it working!

  1. the become: false may not be required; but
  2. I had to explicitely set ansible_zabbix_url_path: '' in my inventory; and
  3. I had to add ansible_zabbix_auth_key: '{{zabbix_api_token}}' in tasks/main.yml's vars.
  4. Note that the set_fact for ansible_zabbix_auth_key is not working and not needed.

I guess points 1 and 3 (and 4?) should be fixed in zabbix_agent role.

In my opinion the role should not explicitly set become:, it should (as it does now) inherit the settings that the user provided. You enabled privilege escalation when you called the role. If that results in issues in your environment you should fix how you call the role.

As for ansible_zabbix_auth_key, this also shouldn't require any role changes. This is a connection variable, so you need to make sure you're setting it for zabbix_api_server_host, which your set_fact will not do. This would normally be done at the inventory level, but you should also be able to get it working by setting the variable at a level that the role will inherit (play vars, role vars, or role parameters) or by running set_fact against the correct host.

In my opinion the role should not explicitly set become:, it should (as it does now) inherit the settings that the user provided.

Agree with that, even though I wonder if there could be any use for calling a web API through sudo.

You enabled privilege escalation when you called the role. If that results in issues in your environment you should fix how you call the role.

Well, the role zabbix_agent is not the only one called in my playbook, and the other does requires become. I'm not sure hardcoding become in all tasks (as done in zabbix_agent) should be applied to any other plays.

But anyway, setting become or not was a false track.

As for ansible_zabbix_auth_key, this also shouldn't require any role changes. This is a connection variable, so you need to make sure you're setting it for zabbix_api_server_host, which your set_fact will not do. This would normally be done at the inventory level, but you should also be able to get it working by setting the variable at a level that the role will inherit (play vars, role vars, or role parameters) or by running set_fact against the correct host.

Sure. I must have been confused in my tests by the doc examples, which actually use set_fact for ansible_zabbix_auth_key. I though it didn't work by setting it in inventory/group_vars/all, but it does. Sorry.