community.zabbix
community.zabbix copied to clipboard
Calls to 6.4 server fail due to "user" parameter being deprecated/removed and httpapi variables won't work with set_fact per example
SUMMARY
Using server_url/login_user/login_password with modules to authenticate to 6.4.1 fails due to "user" parameter on user.login being deprecated/removed and "username" being required.
Furthermore, attempting to set variable "ansible_httpapi_pass" for httpapi with set_fact per examples fails. Since the parameter isn't being passed as "username" and that method is deprecated, we're attempted to switch to use httpapi.
ISSUE TYPE
- Bug Report
COMPONENT NAME
Noticed with proxy_info but appears to be present in other modules
ANSIBLE VERSION
ansible [core 2.14.3]
CONFIGURATION
OS / ENVIRONMENT / Zabbix Version
Target host is RHEL 7, host running ansible is Rocky Linux 8.5
STEPS TO REPRODUCE
# This errors after upgrading Zabbix server to 6.4 because "user" is no longer a parameter for user.login.
- name: Get proxy
community.zabbix.zabbix_proxy_info:
server_url: "https://<server_fqdn>/zabbix/api_jsonrpc.php"
login_user: zabbixapi
login_password: "<password>"
proxy_name: "<proxy_name>"
register: zabbix_proxy
delegate_to: localhost
# This works but we need to be able to make ansible_httpapi_pass set dynamically with set_fact so it's not stored in the play code itself and is sourced from our secret management system.
- name: Get proxy
community.zabbix.zabbix_proxy_info:
proxy_name: "<proxy_name>"
register: zabbix_proxy
delegate_to: localhost
vars:
ansible_network_os: community.zabbix.zabbix
ansible_connection: httpapi
ansible_httpapi_port: 443
ansible_httpapi_use_ssl: true
ansible_httpapi_validate_certs: true
ansible_host: <server_fqdn>
ansible_user: zabbixapi
ansible_httpapi_pass: "<password>"
# If we use set_fact for "ansible_httpapi_pass" (per the examples) above the task it fails.
- set_fact:
ansible_httpapi_pass: "<password>"
- name: Get proxy
community.zabbix.zabbix_proxy_info:
proxy_name: "<proxy_name>"
register: zabbix_proxy
delegate_to: localhost
vars:
ansible_network_os: community.zabbix.zabbix
ansible_connection: httpapi
ansible_httpapi_port: 443
ansible_httpapi_use_ssl: true
ansible_httpapi_validate_certs: true
ansible_host: <server_fqdn>
ansible_user: zabbixapi
EXPECTED RESULTS
Proxy object returned
ACTUAL RESULTS
Error with server_url/login_user/login_password:
TASK [zabbix-agent : Get proxy] *********************************************************************************************************************************************************************
[WARNING]: Option "server_url" is deprecated with the move to httpapi connection and will be removed in the next release
[WARNING]: Option "login_user" is deprecated with the move to httpapi connection and will be removed in the next release
[WARNING]: Option "login_password" is deprecated with the move to httpapi connection and will be removed in the next release
fatal: [<host_fqdn> -> localhost]: FAILED! => {"changed": false, "msg": "Failed to connect to Zabbix server: ('Error -32602: Invalid params., Invalid parameter \"/\": unexpected parameter \"user\". while sending {\"jsonrpc\": \"2.0\", \"method\": \"user.login\", \"params\": {\"user\": \"zabbixapi\", \"password\": \"********\"}, \"id\": 0}', -32602)"}
Error with httapi using set_fact:
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible.module_utils.connection.ConnectionError: REST API returned {'code': -32602, 'message': 'Invalid params.', 'data': 'Invalid parameter "/password": a character string is expected.'} when sending {"jsonrpc": "2.0", "method": "user.login", "id": "42ac1f5d-3503-465f-9f7e-7232ac0931a4", "params": {"username": "zabbixapi", "password": null}}
Please update to the latest version 1.9.3 of this collection. This has been fixed for Zabbix 6.4.
I am running version 1.9.3. Initially I found that 1.9.2 was installed at a different location than where 1.9.3 got installed when I updated but I've now have 1.9.3 in both locations and it's still failing with the same error. Here's my output showing the version:
ansible-galaxy collection list community.zabbix
# /usr/local/lib/python3.9/site-packages/ansible_collections
Collection Version
---------------- -------
community.zabbix 1.9.3
# /home/vagrant/.ansible/collections/ansible_collections
Collection Version
---------------- -------
community.zabbix 1.9.3
I also put a debug line in my play to output the version right before it runs the task that errors and it's showing 1.9.3:
- name: Check version of community.zabbix
ansible.builtin.debug:
msg: "community.zabbix version {{ lookup('community.general.collection_version', 'community.zabbix') }}"
TASK [zabbix-agent : Check version of community.zabbix] ********************************************************************************************************************************************************* ok: [<server_fqdn>] => { "msg": "community.zabbix version 1.9.3" }
TASK [zabbix-agent : Get active server certificate] ************************************************************************************************************************************************************* [WARNING]: Option "server_url" is deprecated with the move to httpapi connection and will be removed in the next release [WARNING]: Option "login_user" is deprecated with the move to httpapi connection and will be removed in the next release [WARNING]: Option "login_password" is deprecated with the move to httpapi connection and will be removed in the next release fatal: [<server_fqdn> -> localhost]: FAILED! => {"changed": false, "msg": "Failed to connect to Zabbix server: ('Error -32602: Invalid params., Invalid parameter "/": unexpected parameter "user". while sending {"jsonrpc": "2.0", "method": "user.login", "params": {"user": "zabbixapi", "password": "********"}, "id": 0}', -32602)"}
We've continued to look into this and found that a fix for the "user" to "username" parameter was delivered with 1.9.3 (https://github.com/ansible-collections/community.zabbix/pull/927) for httpapi. The issue we're hitting is with the zabbix-api Python module which is getting called with the task we're using. The fix for that module has not been merged yet but is documented here: https://github.com/gescheit/scripts/pull/37. The call to that module is in https://github.com/ansible-collections/community.zabbix/blob/main/plugins/module_utils/wrappers.py.
How do we modify our task so it flows through httpapi instead of using zabbix-api?
- name: Get proxy
community.zabbix.zabbix_proxy_info:
server_url: "https://<server_fqdn>/zabbix/api_jsonrpc.php"
login_user: zabbixapi
login_password: "<password>"
proxy_name: "<proxy_name>"
register: zabbix_proxy
delegate_to: localhost
@flowerysong we're running ansible.netcommon 5.1.0 so not sure if it's the same issue?
ansible-galaxy collection list ansible.netcommon
# /usr/local/lib/python3.9/site-packages/ansible_collections
Collection Version
----------------- -------
ansible.netcommon 5.1.0
Nope, that would be unrelated then.
You need to make sure you're setting the variables for the correct host; delegation changes the source of connection variables, so in your example if you don't want to use a variable on the task (which you haven't provided an actual reason you can't do, task vars are perfectly capable of using data from secret management systems) you need to set ansible_httpapi_pass on localhost, not the current inventory host.
Alternatively, remove delegate_to: localhost, since the httpapi connection plugin runs modules on localhost anyway. Or add a new inventory entry for your Zabbix host and delegate to that. Lots of ways to get it working.
@flowerysong thanks, with your information I was able to convert from using server_url, login_user and login_password which uses Python's zabbix_api to httpapi in this module.
Maybe it'll help someone else so I'm posting a sample below. My zabbix_server, zabbix_api_user, zabbix_api_user_password and zabbix_active_server variables are set elsewhere depending on environment/other variables and can vary depending on the target host. Next step will be to stop using user/pass and switch to an API token with ansible_zabbix_auth_key...
- name: "Set variables for using community.zabbix httpapi with {{ zabbix_server }}"
set_fact:
ansible_network_os: community.zabbix.zabbix
ansible_connection: httpapi
ansible_httpapi_use_ssl: true
ansible_httpapi_validate_certs: true
ansible_user: "{{ hostvars[inventory_hostname].zabbix_api_user }}"
ansible_httpapi_pass: "{{ hostvars[inventory_hostname].zabbix_api_user_password.secret_value }}"
delegate_facts: true
delegate_to: "{{ zabbix_server }}"
# Get active server issuer if proxy
- name: Get active server certificate (httpapi)
community.zabbix.zabbix_proxy_info:
proxy_name: "{{ zabbix_active_server }}"
register: zabbix_proxy
when: zabbix_active_server_is_proxy
delegate_to: "{{ zabbix_server }}"
So in summary you can't use server_url/login_user/login_password with this module against a Zabbix server running 6.4+ until the zabbix_api Python module is updated to use "username" instead of "user" since this Ansible module leverages it (https://github.com/gescheit/scripts/pull/37). Not sure if that's an "issue" or should just be a documented FYI for people. Also community.zabbix httpapi works, you just need to scope your variables differently than if you used the previous method.
i am getting a similar error with v1.9.3. of plugin and server 6.4 using ansible inventory:
ansible-collection iinstall --> community.zabbix:1.9.3 was installed successfully
$ ansible-inventory --list -i zabbix_inventory.yaml -vvv
--> `Failed to connect to Zabbix server: ('Error -32602: Invalid params., Invalid parameter "/": unexpected parameter "user". while sending {"jsonrpc": "2.0", "method": "user.login", "params": {"user": "...", "password": "..."}, "id": 0}', -32602)
...
--> Failed to parse zabbix_inventory.yaml with auto plugin: ('Error -32600: Invalid request., Invalid parameter "/auth": cannot be empty. while sending {"jsonrpc": "2.0", "method": "host.get",
"params": {"selectGroups": ["name"]}, "auth": "", "id": 2}', -32600)
ALSO: my server_url variable is ending with "/" because otherwise i get some urlLib error so i have now: "https://host.com/"
UPDATE: i can confirm i am using the most recent related libraries:
$ pip list | grep zab
zabbix-api 0.5.5
$ ansible-galaxy collection list community.zabbix
# ......./.ansible/collections/ansible_collections
Collection Version
---------------- -------
community.zabbix 1.9.3
@chrisallennc did you also encounter the same issue ?
@dberardo-com Correct, that's the error I saw. You can see it's passing "user" as the parameter to the API which the API isn't accepting since it's not a valid parameter.
To get around it you can pull/get the changes from the branch of the zabbix-api Python module mentioned here: https://github.com/gescheit/scripts/pull/37 or modify your community.zabbix Ansible tasks to use httpapi instead.
great, i have installed the repo via pip and it fixed the issue. Will wait for that PR to be merged then
I hope this is on-topic, but as a fellow user who is trying to figure out how the new httpapi workflow works, this seemed like a mostly relevant issue.
I found it really confusing that the variables http_login_user and http_login_password are in the role, but it doesn't seem as though these are used... instead it only uses the values from the host facts or the ansible username/pass it seems. Does anyone know why this is, and why we have these http_login_ variables then?
For example:
- name: Set facts for Zabbix httpapi
ansible.builtin.set_fact:
ansible_network_os: community.zabbix.zabbix
ansible_connection: httpapi
ansible_httpapi_use_ssl: false
ansible_httpapi_validate_certs: false
ansible_zabbix_url_path: ''
ansible_user: SetFactUser
ansible_httpapi_pass: SetFactPass
- name: Import Zabbix host groups
community.zabbix.zabbix_template:
http_login_user: HttpLoginUser
http_login_password: HttpLoginPass
template_json:
zabbix_export:
version: '6.0'
groups:
- name: 'Test123'
uuid: 0658ff47441444e0911da72ed3db99db
state: present
results in these params:
\"params\": {\"username\": \"SetFactUser\", \"password\": \"SetFactPass\"}}\n"
but, if I remove the "SetFactUser" and "SetFactPass" from set_fact, then it seems to use the ansible user and doesn't send any password at all. What is the point of http_login_user/http_login_password then, if we are only using the values from facts?
For example:
tasks:
- name: Set facts for Zabbix httpapi
ansible.builtin.set_fact:
ansible_network_os: community.zabbix.zabbix
ansible_connection: httpapi
ansible_httpapi_use_ssl: false
ansible_httpapi_validate_certs: false
ansible_zabbix_url_path: ''
- name: Import Zabbix host groups
community.zabbix.zabbix_template:
http_login_user: HttpLoginUser
http_login_password: HttpLoginPass
template_json:
zabbix_export:
version: '6.0'
groups:
- name: 'Test123'
uuid: 0658ff47441444e0911da72ed3db99db
state: present
results in these params:
\"params\": {\"username\": \"ansible\", \"password\": null}}\n"
Sorry, I'm sure this is a noob question but the documentation doesn't seem clear after the switch to httpapi and we could probably benefit from improving that.
@mcbrineellis you are mixing roles and modules. In Ansible there is a gazilliion way to do the same thing. What are you trying to achieve?
@BGmot not exactly the same cause as @mcbrineellis but sort of the same problem. I used to be able to add hosts to my zabbix server with an ansible role. I used a local action to do so.
Here the role I used to run.
- name: Create a new host or update an existing host's info local_action: module: zabbix_host server_url: https://blabla.com login_user: ansible login_password: "{{zabbix_ansible_password}}" host_name: "{{inventory_hostname_short}}" visible_name: "{{inventory_hostname_short}}" description: "{{inventory_hostname_short}}" host_groups: - flexbuf link_templates: - Chassis by IPMI - power.consumption status: enabled state: present inventory_mode: disabled ipmi_authtype: 2 ipmi_privilege: 2 ipmi_username: zabbix ipmi_password: "{{ipmi_zabbix_password}}" interfaces: #ipmi - type: 3 main: 1 useip: 0 dns: "{{inventory_hostname_short}}.ipmi" port: "623" #zabbix agent - type: 1 main: 1 useip: 0 dns: "{{inventory_hostname_short}}" port: "10050"
I have not been able to do the same thing with the api setup, I just dont seem to get how it works or how it has to be setup.
Could you provide an example of the playbook and role to add a group of hosts to the zabbix server?
try this:
- name: Create a new host or update an existing host's info
vars:
gather_facts: false
ansible_user: "username_to_login_into_zabbix"
ansible_httpapi_use_ssl: true
ansible_httpapi_validate_certs: false
ansible_zabbix_url_path: "/"
ansible_network_os: community.zabbix.zabbix
ansible_connection: httpapi
community.zabbix.zabbix_host:
host_name: "{{inventory_hostname_short}}"
... all your stuff related to host config
delegate_to: blabla.com
become: false
Gives me an error.
fatal: [client -> zabbix server]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n File "/home/xxxx/.ansible/tmp/ansible-local-10146kYsdH5/ansible-tmp-1684938779.39-10162-267067470114535/AnsiballZ_zabbix_host.py", line 102, in
Heres the role I used
- name: Create a new host or update an existing host's info vars: gather_facts: false ansible_user: "username_to_login_into_zabbix" ansible_httpapi_use_ssl: true ansible_httpapi_validate_certs: false ansible_zabbix_url_path: "/" ansible_network_os: community.zabbix.zabbix ansible_connection: httpapi community.zabbix.zabbix_host: host_name: "{{inventory_hostname_short}}" visible_name: "{{inventory_hostname_short}}" description: "{{inventory_hostname_short}}" host_groups: - node link_templates: - Chassis by IPMI - Linux by Zabbix agent status: enabled state: present inventory_mode: disabled ipmi_authtype: 2 ipmi_privilege: 2 ipmi_username: xxxx ipmi_password: "{{ipmi_zabbix_password}}" interfaces: #ipmi - type: 3 main: 1 useip: 0 dns: "{{inventory_hostname_short}}.ipmi" port: "623" #zabbix agent - type: 1 main: 1 useip: 0 dns: "{{inventory_hostname_short}}" port: "10050" delegate_to: zabbixserver.com become: false
"File not found" means you did not provide correct path, by default it is https://blabla.com/zabbix, where ansible_zabbix_url_path would be "zabbix" according to your first message I set it to "/" because you posted https://blabla.com/, try removing ansible_zabbix_url_path or set it according to your real path.
The path of the zabbix server is without the /zabbix so https://zabbixserver.com/ so the ansible_zabbix_url_path should be "/" right?
right
Changing the delegate option to a faulty one shows the actual url its trying to connect to in the error message. It looks like the ansible_zabbix_url_path is completely ignored. Its always https://servername/zabbix/api_jsonrpc.php.
Which probably means I'm not setting it in the right place. If have set it with set facts in the playbook and with vars in the role but that does not help.