From d4a40a97d93c6c5b1473d2d6e65b4becec320d68 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Fri, 31 May 2024 17:30:16 -0400 Subject: [PATCH 01/18] zabbix_proxy_group module added. --- plugins/modules/zabbix_proxy_group.py | 242 ++++++++++++++++++ .../test_zabbix_proxy_group/meta/main.yml | 3 + .../test_zabbix_proxy_group/tasks/main.yml | 10 + .../tasks/zabbix_proxy_group_tests.yml | 64 +++++ 4 files changed, 319 insertions(+) create mode 100644 plugins/modules/zabbix_proxy_group.py create mode 100644 tests/integration/targets/test_zabbix_proxy_group/meta/main.yml create mode 100644 tests/integration/targets/test_zabbix_proxy_group/tasks/main.yml create mode 100644 tests/integration/targets/test_zabbix_proxy_group/tasks/zabbix_proxy_group_tests.yml diff --git a/plugins/modules/zabbix_proxy_group.py b/plugins/modules/zabbix_proxy_group.py new file mode 100644 index 000000000..4fc4ce38a --- /dev/null +++ b/plugins/modules/zabbix_proxy_group.py @@ -0,0 +1,242 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# (c) 2024, Evgeny Yurchenko +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . +# + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase + +import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils + + +DOCUMENTATION = r""" +--- +module: zabbix_proxy_group +short_description: Create/update/delete Zabbix proxy group +description: + - This module allows you to create, modify and delete Zabbix proxy group. +author: + - Evgeny Yurchenko (@BGmot) +requirements: + - python >= 3.9 +options: + name: + description: + - Name of the proxy group. + required: true + type: str + description: + description: + - Description of the proxy group. + required: false + type: str + failover_delay: + description: + - Failover period for each proxy in the group to have online/offline state. + - Time suffixes are supported, e.g. 30s, 1m. + required: false + type: str + default: 1m + state: + description: + - State of the proxy group. + - On C(present), it will create if proxy group does not exist or update it if the associated data is different. + - On C(absent) will remove the proxy group if it exists. + choices: ["present", "absent"] + default: "present" + type: str + +""" + +EXAMPLES = r""" +--- +# If you want to use Username and Password to be authenticated by Zabbix Server +- name: Set credentials to access Zabbix Server API + ansible.builtin.set_fact: + ansible_user: Admin + ansible_httpapi_pass: zabbix + +# If you want to use API token to be authenticated by Zabbix Server +# https://www.zabbix.com/documentation/current/en/manual/web_interface/frontend_sections/administration/general#api-tokens +- name: Set API token + ansible.builtin.set_fact: + ansible_zabbix_auth_key: 8ec0d52432c15c91fcafe9888500cf9a607f44091ab554dbee860f6b44fac895 + +- name: Create/update Zabbix proxy group + vars: + ansible_network_os: community.zabbix.zabbix + ansible_connection: httpapi + ansible_httpapi_port: 443 + ansible_httpapi_use_ssl: true + ansible_httpapi_validate_certs: false + ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu + ansible_host: zabbix-example-fqdn.org + community.zabbix.zabbix_proxy_group: + name: ProxyGroup01 + description: Example Zabbix Proxy Group + state: present + failover_delay: 10s + min_online: 2 + +- name: delete Zabbix proxy group + vars: + ansible_network_os: community.zabbix.zabbix + ansible_connection: httpapi + ansible_httpapi_port: 443 + ansible_httpapi_use_ssl: true + ansible_httpapi_validate_certs: false + ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu + ansible_host: zabbix-example-fqdn.org + community.zabbix.zabbix_proxy_group: + name: ProxyGroup01 + state: absent +""" + + +class ProxyGroup(ZabbixBase): + def __init__(self, module, zbx=None, zapi_wrapper=None): + super(ProxyGroup, self).__init__(module, zbx, zapi_wrapper) + self.existing_data = None + + def proxy_group_exists(self, proxy_group_name): + result = self._zapi.proxygroup.get({"output": "extend", + "filter": {"name": proxy_group_name}}) + + if len(result) > 0 and "proxy_groupid" in result[0]: + self.existing_data = result[0] + return result[0]["proxy_groupid"] + else: + return result + + def add_proxy_group(self, data): + try: + if self._module.check_mode: + self._module.exit_json(changed=True) + + parameters = {} + for item in data: + if data[item]: + parameters[item] = data[item] + + proxy_group_ids_list = self._zapi.proxygroup.create(parameters) + + self._module.exit_json(changed=True, + result="Successfully added proxy group %s" % (data["name"])) + + if len(proxy_group_ids_list) >= 1: + return proxy_group_ids_list["proxy_groupids"][0] + + except Exception as e: + self._module.fail_json(msg="Failed to create proxy group %s: %s" % (data["name"], e)) + + def delete_proxy_group(self, proxy_group_id, proxy_group_name): + try: + if self._module.check_mode: + self._module.exit_json(changed=True) + + self._zapi.proxygroup.delete([proxy_group_id]) + + self._module.exit_json(changed=True, result="Successfully deleted proxy group %s" % proxy_group_name) + + except Exception as e: + self._module.fail_json(msg="Failed to delete proxy group %s: %s" % (proxy_group_name, str(e))) + + def update_proxy_group(self, proxy_group_id, data): + try: + if self._module.check_mode: + self._module.exit_json(changed=True) + + parameters = {} + for key in data: + if data[key]: + parameters[key] = data[key] + + parameters["proxy_groupid"] = proxy_group_id + + change_parameters = {} + difference = zabbix_utils.helper_cleanup_data(zabbix_utils.helper_compare_dictionaries(parameters, self.existing_data, change_parameters)) + + if difference == {}: + self._module.exit_json(changed=False) + else: + difference["proxy_groupid"] = proxy_group_id + self._zapi.proxygroup.update(parameters) + self._module.exit_json( + changed=True, + result="Successfully updated proxy group %s (%s)" % (data["name"], proxy_group_id) + ) + + except Exception as e: + self._module.fail_json(msg="Failed to update proxy group %s: %s" % (data["name"], e)) + + +def main(): + argument_spec = zabbix_utils.zabbix_common_argument_spec() + argument_spec.update(dict( + name=dict(type="str", required=True), + description=dict(type="str", required=False), + failover_delay=dict(type="str", default="1m"), + state=dict(type="str", default="present", choices=["present", "absent"]), + min_online=dict(type="str", default="1") + )) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True + ) + + proxy_group_name = module.params["name"] + description = module.params["description"] + failover_delay = module.params["failover_delay"] + min_online = module.params["min_online"] + state = module.params["state"] + + proxy_group = ProxyGroup(module) + + # check if proxy group already exists + proxy_group_id = proxy_group.proxy_group_exists(proxy_group_name) + + if proxy_group_id: + if state == "absent": + # remove proxy group + proxy_group.delete_proxy_group(proxy_group_id, proxy_group_name) + else: + proxy_group.update_proxy_group(proxy_group_id, { + "name": proxy_group_name, + "description": description, + "failover_delay": str(failover_delay), + "min_online": str(min_online) + }) + else: + if state == "absent": + # the proxy group is already deleted. + module.exit_json(changed=False) + + proxy_group_id = proxy_group.add_proxy_group(data={ + "name": proxy_group_name, + "description": description, + "failover_delay": str(failover_delay), + "min_online": str(min_online) + }) + + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/test_zabbix_proxy_group/meta/main.yml b/tests/integration/targets/test_zabbix_proxy_group/meta/main.yml new file mode 100644 index 000000000..acdb704c8 --- /dev/null +++ b/tests/integration/targets/test_zabbix_proxy_group/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - setup_zabbix diff --git a/tests/integration/targets/test_zabbix_proxy_group/tasks/main.yml b/tests/integration/targets/test_zabbix_proxy_group/tasks/main.yml new file mode 100644 index 000000000..3dbda1f2c --- /dev/null +++ b/tests/integration/targets/test_zabbix_proxy_group/tasks/main.yml @@ -0,0 +1,10 @@ +--- +- block: + - include_tasks: zabbix_proxy_group_tests.yml + + always: + - name: Cleanup + community.zabbix.zabbix_proxy_group: + name: TestProxyGroup + state: absent + ignore_errors: true diff --git a/tests/integration/targets/test_zabbix_proxy_group/tasks/zabbix_proxy_group_tests.yml b/tests/integration/targets/test_zabbix_proxy_group/tasks/zabbix_proxy_group_tests.yml new file mode 100644 index 000000000..f26a0113e --- /dev/null +++ b/tests/integration/targets/test_zabbix_proxy_group/tasks/zabbix_proxy_group_tests.yml @@ -0,0 +1,64 @@ +--- +- name: test - do not run tests for Zabbix < 7.0 + meta: end_play + when: zabbix_version is version('7.0', '<') + +- name: set module defaults + module_defaults: + community.zabbix.zabbix_proxy_group: + name: TestProxyGroup + + block: + - name: test - create new Zabbix proxy group + community.zabbix.zabbix_proxy_group: + description: Example Zabbix Proxy Group + state: present + failover_delay: 10s + min_online: 2 + register: proxy_group_new + + - name: assert that proxy group was created + ansible.builtin.assert: + that: proxy_group_new is changed + + - name: test - create same Zabbix proxy group + community.zabbix.zabbix_proxy_group: + description: Example Zabbix Proxy Group + state: present + failover_delay: 10s + min_online: 2 + register: proxy_group_existing + + - name: assert that nothing has been changed + ansible.builtin.assert: + that: not proxy_group_existing is changed + + - name: test - update Zabbix proxy group + community.zabbix.zabbix_proxy_group: + description: Example Zabbix Proxy Group + state: present + failover_delay: 20s + min_online: 1 + register: proxy_group_update + + - name: assert that proxy group has changed + ansible.builtin.assert: + that: proxy_group_update is changed + + - name: test - delete Zabbix proxy group + community.zabbix.zabbix_proxy_group: + state: absent + register: proxy_group_delete + + - name: assert that proxy group has been deleted + ansible.builtin.assert: + that: proxy_group_delete is changed + + - name: test - delete Zabbix proxy group (again) + community.zabbix.zabbix_proxy_group: + state: absent + register: proxy_group_delete_again + + - name: assert that nothing has been changed + ansible.builtin.assert: + that: not proxy_group_delete_again is changed From 3f318f2e7bd8b3426466701dc7d2026f629c0281 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Sun, 2 Jun 2024 13:17:59 -0400 Subject: [PATCH 02/18] zabbix_proxy module updated to support Zabbix 7.0. --- plugins/modules/zabbix_proxy.py | 504 ++++++++++++++++-- .../targets/test_zabbix_proxy/tasks/main.yml | 322 +---------- .../tasks/test_zabbix_proxy_before70.yml | 302 +++++++++++ .../tasks/test_zabbix_proxy_since70.yml | 356 +++++++++++++ 4 files changed, 1135 insertions(+), 349 deletions(-) create mode 100644 tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_before70.yml create mode 100644 tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_since70.yml diff --git a/plugins/modules/zabbix_proxy.py b/plugins/modules/zabbix_proxy.py index a5ddbe137..da8eafe87 100644 --- a/plugins/modules/zabbix_proxy.py +++ b/plugins/modules/zabbix_proxy.py @@ -40,6 +40,7 @@ type: str proxy_address: description: + - Deprecated for Zabbix version >= 7.0. - Comma-delimited list of IP/CIDR addresses or DNS names to accept active proxy requests from. - Requires I(status=active). required: false @@ -51,6 +52,7 @@ type: str status: description: + - Deprecated for Zabbix version >= 7.0. - Type of proxy. (4 - active, 5 - passive) required: false choices: ["active", "passive"] @@ -102,6 +104,7 @@ type: str interface: description: + - Deprecated for Zabbix version >= 7.0. - Dictionary with params for the interface when proxy is in passive mode. - For more information, review proxy interface documentation at - U(https://www.zabbix.com/documentation/current/en/manual/api/reference/proxy/object#proxy-interface). @@ -133,6 +136,167 @@ default: "10051" default: {} type: dict + address: + description: + - Parameter introduced in Zabbix 7.0. + - IP address or DNS name to connect to. + - Required if the Zabbix proxy operating mode is passive + required: false + type: str + port: + description: + - Parameter introduced in Zabbix 7.0. + - Port number to connect to. + - supported if the Zabbix proxy operating mode is passive. + required: false + type: str + default: "10051" + proxy_group: + description: + - Parameter introduced in Zabbix 7.0. + - Proxy group name. + required: false + type: str + default: "0" + local_address: + description: + - Parameter introduced in Zabbix 7.0. + - Address for active agents. IP address or DNS name to connect to. + - Required if proxy_groupid is not 0 + required: false + type: str + default: "10051" + local_port: + description: + - Parameter introduced in Zabbix 7.0. + - Local proxy port number to connect to. + - Supported if proxy_groupid is not 0 + required: false + type: str + default: "10051" + allowed_addresses: + description: + - Parameter introduced in Zabbix 7.0. + - Comma-delimited IP addresses or DNS names of active Zabbix proxy. + required: false + type: str + operating_mode: + description: + - Parameter introduced in Zabbix 7.0. + - Type of proxy. + required: false + choices: ["active", "passive"] + default: "active" + type: str + custom_timeouts: + description: + - Parameter introduced in Zabbix 7.0. + - Whether to override global item timeouts on the proxy level. + - 0 - use global settings; 1 - override timeouts. + required: false + type: int + default: 0 + choices: [0, 1] + timeout_zabbix_agent: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on Zabbix agent checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Rired if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_simple_check: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on simple checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_snmp_agent: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on SNMP agent checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_external_check: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on external checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_db_monitor: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on DB checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_http_agent: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on HTTPagent checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_ssh_agent: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on SSH checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_telnet_agent: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on Telnet checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_script: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on script type checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" + timeout_browser: + description: + - Parameter introduced in Zabbix 7.0. + - Spend no more than this number of seconds on browser type checks processing. + - Accepts seconds or time unit with suffix (e.g., 30s, 1m). + - Possible values range: 1-600s. + - Required if if C(custom_timeouts) is set to 1. + required: false + type: str + default: "" extends_documentation_fragment: - community.zabbix.zabbix @@ -152,7 +316,7 @@ ansible.builtin.set_fact: ansible_zabbix_auth_key: 8ec0d52432c15c91fcafe9888500cf9a607f44091ab554dbee860f6b44fac895 -- name: Create or update a proxy with proxy type active +- name: Create or update a proxy with proxy type active (Zabbix version < 7.0) # set task level variables as we change ansible_connection plugin here vars: ansible_network_os: community.zabbix.zabbix @@ -169,7 +333,7 @@ state: present proxy_address: ExampleProxy.local -- name: Create a new passive proxy using only it's IP +- name: Create a new passive proxy using only its IP (Zabbix version < 7.0) # set task level variables as we change ansible_connection plugin here vars: ansible_network_os: community.zabbix.zabbix @@ -189,7 +353,7 @@ ip: 10.1.1.2 port: 10051 -- name: Create a new passive proxy using only it's DNS +- name: Create a new passive proxy using only its DNS (Zabbix version < 7.0) # set task level variables as we change ansible_connection plugin here vars: ansible_network_os: community.zabbix.zabbix @@ -207,6 +371,59 @@ interface: dns: proxy.example.com port: 10051 + +- name: Create or update a proxy with proxy type active (Zabbix version >= 7.0) + # set task level variables as we change ansible_connection plugin here + vars: + ansible_network_os: community.zabbix.zabbix + ansible_connection: httpapi + ansible_httpapi_port: 443 + ansible_httpapi_use_ssl: true + ansible_httpapi_validate_certs: false + ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu + ansible_host: zabbix-example-fqdn.org + community.zabbix.zabbix_proxy: + proxy_name: ExampleProxy + description: ExampleProxy + operating_mode: operating_mode + state: present + allowed_addresses: ExampleProxy.local + +- name: Create a new passive proxy using only its IP (Zabbix version >= 7.0) + # set task level variables as we change ansible_connection plugin here + vars: + ansible_network_os: community.zabbix.zabbix + ansible_connection: httpapi + ansible_httpapi_port: 443 + ansible_httpapi_use_ssl: true + ansible_httpapi_validate_certs: false + ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu + ansible_host: zabbix-example-fqdn.org + community.zabbix.zabbix_proxy: + proxy_name: ExampleProxy + description: ExampleProxy + operating_mode: passive + state: present + address: 10.1.1.2 + port: 10051 + +- name: Create a new passive proxy using only its DNS (Zabbix version >= 7.0) + # set task level variables as we change ansible_connection plugin here + vars: + ansible_network_os: community.zabbix.zabbix + ansible_connection: httpapi + ansible_httpapi_port: 443 + ansible_httpapi_use_ssl: true + ansible_httpapi_validate_certs: false + ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu + ansible_host: zabbix-example-fqdn.org + community.zabbix.zabbix_proxy: + proxy_name: ExampleProxy + description: ExampleProxy + operating_mode: passive + state: present + address: proxy.example.com + port: 10051 """ RETURN = r""" # """ @@ -216,6 +433,8 @@ from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase +from ansible.module_utils.compat.version import LooseVersion + import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils @@ -225,9 +444,13 @@ def __init__(self, module, zbx=None, zapi_wrapper=None): self.existing_data = None def proxy_exists(self, proxy_name): - result = self._zapi.proxy.get({"output": "extend", - "selectInterface": "extend", - "filter": {"host": proxy_name}}) + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + result = self._zapi.proxy.get({"output": "extend", + "selectInterface": "extend", + "filter": {"host": proxy_name}}) + else: + result = self._zapi.proxy.get({"output": "extend", + "filter": {"name": proxy_name}}) if len(result) > 0 and "proxyid" in result[0]: self.existing_data = result[0] @@ -245,19 +468,46 @@ def add_proxy(self, data): if data[item]: parameters[item] = data[item] - if "proxy_address" in data and data["status"] != "5": - parameters.pop("proxy_address", False) + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + if "proxy_address" in data and data["status"] != "5": + parameters.pop("proxy_address", False) + else: + if "allowed_addresses" in data and data["operating_mode"] != "0": + parameters.pop("allowed_addresses", False) + + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + if "interface" in data and data["status"] != "6": + parameters.pop("interface", False) + else: + if "interface" in data and data["operating_mode"] != "1": + parameters.pop("interface", False) + + if data["proxy_group"]: + proxy_group = data["proxy_group"] + result = self._zapi.proxygroup.get({"output": "extend", "filter": {"name": proxy_group}}) - if "interface" in data and data["status"] != "6": - parameters.pop("interface", False) + if len(result) == 0: + self._module.fail_json(msg="Failed to find proxy group %s" % (proxy_group)) + + proxy_group_id = result[0]["proxy_groupid"] + parameters.pop("proxy_group", False) + parameters["proxy_groupid"] = proxy_group_id proxy_ids_list = self._zapi.proxy.create(parameters) - self._module.exit_json(changed=True, - result="Successfully added proxy %s (%s)" % (data["host"], data["status"])) + + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + self._module.exit_json(changed=True, + result="Successfully added proxy %s (%s)" % (data["host"], data["status"])) + else: + self._module.exit_json(changed=True, + result="Successfully added proxy %s (%s)" % (data["name"], data["operating_mode"])) if len(proxy_ids_list) >= 1: return proxy_ids_list["proxyids"][0] except Exception as e: - self._module.fail_json(msg="Failed to create proxy %s: %s" % (data["host"], e)) + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + self._module.fail_json(msg="Failed to create proxy %s: %s" % (data["host"], e)) + else: + self._module.fail_json(msg="Failed to create proxy %s: %s" % (data["name"], e)) def delete_proxy(self, proxy_id, proxy_name): try: @@ -277,15 +527,36 @@ def update_proxy(self, proxy_id, data): for key in data: if data[key]: parameters[key] = data[key] + + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + status_or_operating_mode_name = "status" + status_or_operating_mode_value = "5" + else: + status_or_operating_mode_name = "operating_mode" + status_or_operating_mode_value = "0" + if "custom_timeouts" in parameters: + parameters["custom_timeouts"] = str(parameters["custom_timeouts"]) + + if data["proxy_group"]: + proxy_group = data["proxy_group"] + result = self._zapi.proxygroup.get({"output": "extend", "filter": {"name": proxy_group}}) + + if len(result) == 0: + self._module.fail_json(msg="Failed to find proxy group %s" % (proxy_group)) + + proxy_group_id = result[0]["proxy_groupid"] + parameters.pop("proxy_group", False) + parameters["proxy_groupid"] = proxy_group_id + if "interface" in parameters: - if parameters["status"] == "5": + if parameters[status_or_operating_mode_name] == status_or_operating_mode_value: # Active proxy parameters.pop("interface", False) else: # Passive proxy parameters["interface"]["useip"] = str(parameters["interface"]["useip"]) - if parameters["status"] == "5": + if parameters[status_or_operating_mode_name] == status_or_operating_mode_value: # Active proxy parameters.pop("tls_connect", False) else: @@ -302,14 +573,23 @@ def update_proxy(self, proxy_id, data): else: difference["proxyid"] = proxy_id self._zapi.proxy.update(parameters) - self._module.exit_json( - changed=True, - result="Successfully updated proxy %s (%s)" % - (data["host"], proxy_id) - ) + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + self._module.exit_json( + changed=True, + result="Successfully updated proxy %s (%s)" % (data["host"], proxy_id) + ) + else: + self._module.exit_json( + changed=True, + result="Successfully updated proxy %s (%s)" % (data["name"], proxy_id) + ) except Exception as e: - self._module.fail_json(msg="Failed to update proxy %s: %s" % - (data["host"], e)) + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + self._module.fail_json(msg="Failed to update proxy %s: %s" % + (data["host"], e)) + else: + self._module.fail_json(msg="Failed to update proxy %s: %s" % + (data["name"], e)) def main(): @@ -318,6 +598,8 @@ def main(): proxy_name=dict(type="str", required=True), proxy_address=dict(type="str", required=False), status=dict(type="str", default="active", choices=["active", "passive"]), + allowed_addresses=dict(type="str", required=False, default=None), + operating_mode=dict(type="str", default="active", choices=["active", "passive"]), state=dict(type="str", default="present", choices=["present", "absent"]), description=dict(type="str", required=False), tls_connect=dict(type="str", default="no_encryption", choices=["no_encryption", "PSK", "certificate"]), @@ -336,17 +618,56 @@ def main(): dns=dict(type="str", default=""), port=dict(type="str", default="10051") ), - ) + ), + address=dict(type="str", required=False, default=None), + port=dict(type="str", required=False, default="10051"), + proxy_group=dict(type="str", required=False, default=None), + local_address=dict(type="str", required=False, default=None), + local_port=dict(type="str", required=False, default="10051"), + custom_timeouts=dict(type="int", required=False, default=0, choices=[0, 1]), + timeout_zabbix_agent=dict(type="str", required=False, default=None), + timeout_simple_check=dict(type="str", required=False, default=None), + timeout_snmp_agent=dict(type="str", required=False, default=None), + timeout_external_check=dict(type="str", required=False, default=None), + timeout_db_monitor=dict(type="str", required=False, default=None), + timeout_http_agent=dict(type="str", required=False, default=None), + timeout_ssh_agent=dict(type="str", required=False, default=None), + timeout_telnet_agent=dict(type="str", required=False, default=None), + timeout_script=dict(type="str", required=False, default=None), + timeout_browser=dict(type="str", required=False, default=None) )) + + # Create temporary proxy object to be able to pull Zabbix version to resolve parameters dependencies + module = AnsibleModule(argument_spec=argument_spec) + proxy = Proxy(module) + + if LooseVersion(proxy._zbx_api_version) < LooseVersion("7.0"): + required = [ + ["tls_connect", "PSK", ("tls_psk_identity", "tls_psk"), False], + ["tls_accept", "PSK", ("tls_psk_identity", "tls_psk"), False], + ["status", "passive", ("interface",)] + ] + else: + required = [ + ["operating_mode", "passive", ("address",)], + ["custom_timeouts", 1, ( + "timeout_zabbix_agent", "timeout_simple_check", "timeout_snmp_agent", + "timeout_external_check", "timeout_db_monitor", "timeout_http_agent", + "timeout_ssh_agent", "timeout_telnet_agent", "timeout_script", + "timeout_browser"), False] + ] + module = AnsibleModule( argument_spec=argument_spec, + required_if=required, + required_together=[ + [("proxy_group",), ("local_address",)] + ], supports_check_mode=True ) proxy_name = module.params["proxy_name"] - proxy_address = module.params["proxy_address"] description = module.params["description"] - status = module.params["status"] tls_connect = module.params["tls_connect"] tls_accept = module.params["tls_accept"] tls_issuer = module.params["ca_cert"] @@ -354,10 +675,37 @@ def main(): tls_psk_identity = module.params["tls_psk_identity"] tls_psk = module.params["tls_psk"] state = module.params["state"] - interface = module.params["interface"] - # convert enabled to 0; disabled to 1 - status = 6 if status == "passive" else 5 + proxy = Proxy(module) + + # convert enabled / disabled to integer + if LooseVersion(proxy._zbx_api_version) < LooseVersion("7.0"): + proxy_address = "" + if "proxy_address" in module.params: + proxy_address = module.params["proxy_address"] + if "interface" in module.params: + interface = module.params["interface"] + status = 6 if module.params["status"] == "passive" else 5 + else: + allowed_addresses = module.params["allowed_addresses"] + operating_mode = 1 if module.params["operating_mode"] == "passive" else 0 + address = module.params["address"] + port = module.params["port"] + proxy_group = module.params["proxy_group"] + local_address = module.params["local_address"] + local_port = module.params["local_port"] + allowed_addresses = module.params["allowed_addresses"] + custom_timeouts = module.params["custom_timeouts"] + timeout_zabbix_agent = module.params["timeout_zabbix_agent"] + timeout_simple_check = module.params["timeout_simple_check"] + timeout_snmp_agent = module.params["timeout_snmp_agent"] + timeout_external_check = module.params["timeout_external_check"] + timeout_db_monitor = module.params["timeout_db_monitor"] + timeout_http_agent = module.params["timeout_http_agent"] + timeout_ssh_agent = module.params["timeout_ssh_agent"] + timeout_telnet_agent = module.params["timeout_telnet_agent"] + timeout_script = module.params["timeout_script"] + timeout_browser = module.params["timeout_browser"] if tls_connect == "certificate": tls_connect = 4 @@ -373,8 +721,6 @@ def main(): else: tls_accept = 1 - proxy = Proxy(module) - # check if proxy already exists proxy_id = proxy.proxy_exists(proxy_name) @@ -383,7 +729,56 @@ def main(): # remove proxy proxy.delete_proxy(proxy_id, proxy_name) else: - proxy.update_proxy(proxy_id, { + if LooseVersion(proxy._zbx_api_version) < LooseVersion("7.0"): + proxy.update_proxy(proxy_id, { + "host": proxy_name, + "description": description, + "status": str(status), + "tls_connect": str(tls_connect), + "tls_accept": str(tls_accept), + "tls_issuer": tls_issuer, + "tls_subject": tls_subject, + "tls_psk_identity": tls_psk_identity, + "tls_psk": tls_psk, + "interface": interface, + "proxy_address": proxy_address + }) + else: + proxy.update_proxy(proxy_id, { + "name": proxy_name, + "description": description, + "operating_mode": str(operating_mode), + "tls_connect": str(tls_connect), + "tls_accept": str(tls_accept), + "tls_issuer": tls_issuer, + "tls_subject": tls_subject, + "tls_psk_identity": tls_psk_identity, + "tls_psk": tls_psk, + "allowed_addresses": allowed_addresses, + "address": address, + "port": port, + "proxy_group": proxy_group, + "local_address": local_address, + "local_port": local_port, + "custom_timeouts": custom_timeouts, + "timeout_zabbix_agent": timeout_zabbix_agent, + "timeout_simple_check": timeout_simple_check, + "timeout_snmp_agent": timeout_snmp_agent, + "timeout_external_check": timeout_external_check, + "timeout_db_monitor": timeout_db_monitor, + "timeout_http_agent": timeout_http_agent, + "timeout_ssh_agent": timeout_ssh_agent, + "timeout_telnet_agent": timeout_telnet_agent, + "timeout_script": timeout_script, + "timeout_browser": timeout_browser + }) + else: + if state == "absent": + # the proxy is already deleted. + module.exit_json(changed=False) + + if LooseVersion(proxy._zbx_api_version) < LooseVersion("7.0"): + proxy_id = proxy.add_proxy(data={ "host": proxy_name, "description": description, "status": str(status), @@ -396,24 +791,35 @@ def main(): "interface": interface, "proxy_address": proxy_address }) - else: - if state == "absent": - # the proxy is already deleted. - module.exit_json(changed=False) - - proxy_id = proxy.add_proxy(data={ - "host": proxy_name, - "description": description, - "status": str(status), - "tls_connect": str(tls_connect), - "tls_accept": str(tls_accept), - "tls_issuer": tls_issuer, - "tls_subject": tls_subject, - "tls_psk_identity": tls_psk_identity, - "tls_psk": tls_psk, - "interface": interface, - "proxy_address": proxy_address - }) + else: + proxy_id = proxy.add_proxy(data={ + "name": proxy_name, + "description": description, + "operating_mode": str(operating_mode), + "tls_connect": str(tls_connect), + "tls_accept": str(tls_accept), + "tls_issuer": tls_issuer, + "tls_subject": tls_subject, + "tls_psk_identity": tls_psk_identity, + "tls_psk": tls_psk, + "allowed_addresses": allowed_addresses, + "address": address, + "port": port, + "proxy_group": proxy_group, + "local_address": local_address, + "local_port": local_port, + "custom_timeouts": custom_timeouts, + "timeout_zabbix_agent": timeout_zabbix_agent, + "timeout_simple_check": timeout_simple_check, + "timeout_snmp_agent": timeout_snmp_agent, + "timeout_external_check": timeout_external_check, + "timeout_db_monitor": timeout_db_monitor, + "timeout_http_agent": timeout_http_agent, + "timeout_ssh_agent": timeout_ssh_agent, + "timeout_telnet_agent": timeout_telnet_agent, + "timeout_script": timeout_script, + "timeout_browser": timeout_browser + }) if __name__ == "__main__": diff --git a/tests/integration/targets/test_zabbix_proxy/tasks/main.yml b/tests/integration/targets/test_zabbix_proxy/tasks/main.yml index 86ece24f3..d20ddf405 100644 --- a/tests/integration/targets/test_zabbix_proxy/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_proxy/tasks/main.yml @@ -1,301 +1,23 @@ --- -- name: test - create new passive Zabbix proxy server - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: passive - interface: - useip: 0 - ip: 10.1.1.2 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_new - -- name: assert that proxy was created - ansible.builtin.assert: - that: zbxproxy_new is changed - -- name: test - create same passive Zabbix proxy server - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: passive - interface: - useip: 0 - ip: 10.1.1.2 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_existing - -- name: assert that nothing has been changed - ansible.builtin.assert: - that: not zbxproxy_existing is changed - -- name: test - update Zabbix proxy server description - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy desc - state: present - status: passive - interface: - useip: 0 - ip: 10.1.1.2 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_desc_update - -- name: assert that description has been updated - ansible.builtin.assert: - that: zbxproxy_desc_update is changed - -- name: test - update Zabbix proxy server interface - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy desc - state: present - status: passive - interface: - useip: 0 - ip: 10.1.1.3 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_interface_update - -- name: assert that interface has been updated - ansible.builtin.assert: - that: zbxproxy_interface_update is changed - -- name: test - update Zabbix proxy server description & interface (again) - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy desc - state: present - status: passive - interface: - useip: 0 - ip: 10.1.1.3 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_desc_interface_update - -- name: assert that nothing has been changed - ansible.builtin.assert: - that: not zbxproxy_desc_interface_update is changed - -- name: test - update Zabbix proxy server interface to use only ip - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy desc - state: present - status: passive - interface: - useip: 1 - ip: 10.1.1.3 - port: 10051 - register: zbxproxy_interface_onlyip - -- name: assert that interface has been updated - ansible.builtin.assert: - that: zbxproxy_interface_onlyip is changed - -- name: test - update Zabbix proxy server interface to use only ip again - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy desc - state: present - status: passive - interface: - useip: 1 - ip: 10.1.1.3 - port: 10051 - register: zbxproxy_interface_onlyip_again - -- name: assert that nothing has been changed - ansible.builtin.assert: - that: not zbxproxy_interface_onlyip_again is changed - -- name: test - update Zabbix proxy server interface to use only dns - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy desc - state: present - status: passive - interface: - useip: 0 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_interface_onlydns - -- name: assert that interface has been updated - ansible.builtin.assert: - that: zbxproxy_interface_onlydns is changed - -- name: test - update Zabbix proxy server interface to use only dns again - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy desc - state: present - status: passive - interface: - useip: 0 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_interface_onlydns_again - -- name: assert that nothing has been changed - ansible.builtin.assert: - that: not zbxproxy_interface_onlydns_again is changed - -- name: test - update Zabbix proxy server interface to fail - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy desc - state: present - status: passive - interface: - useip: 1 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_interface_fail - ignore_errors: true - -- name: assert that module has failed - ansible.builtin.assert: - that: zbxproxy_interface_fail is failed - -- name: test - update Zabbix proxy server to be active - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: active - register: zbxproxy_active_update - -- name: assert that proxy was updated - ansible.builtin.assert: - that: zbxproxy_active_update is changed - -- name: test - update Zabbix proxy server to be active (again) - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: active - register: zbxproxy_active_update_again - -- name: assert that nothing has been changed - ansible.builtin.assert: - that: not zbxproxy_active_update_again is changed - -- name: test - update Zabbix proxy server to be active and use proxy_address - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: active - proxy_address: 10.1.1.0/24,zabbix.example.com - register: zbxproxy_active_proxyaddress - -- name: assert that proxy was updated - ansible.builtin.assert: - that: zbxproxy_active_proxyaddress is changed - -- name: test - update Zabbix proxy server to be active use proxy_address (again) - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: active - proxy_address: 10.1.1.0/24,zabbix.example.com - register: zbxproxy_active_proxyaddress_again - -- name: assert that nothing has been changed - ansible.builtin.assert: - that: not zbxproxy_active_proxyaddress_again is changed - -- name: test - update Zabbix proxy server to use encryption - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: active - tls_psk_identity: test - tls_connect: PSK - tls_accept: PSK - tls_psk: 123456789abcdef123456789abcdef12 - register: zbxproxy_encryption - -- name: assert that encryption has been enabled - ansible.builtin.assert: - that: zbxproxy_encryption is changed - -- name: test - update Zabbix proxy server to use encryption (again) - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: active - tls_psk_identity: test - tls_connect: PSK - tls_accept: PSK - tls_psk: 123456789abcdef123456789abcdef12 - register: zbxproxy_encryption_again - -- name: assert that nothing has been changed - ansible.builtin.assert: - that: zbxproxy_encryption_again is changed - -- name: test - update Zabbix proxy server encryption settings - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: active - tls_connect: certificate - tls_accept: certificate - tls_issuer: AcmeCorp - tls_subject: AcmeCorpServer - register: zbxproxy_encryption_update - -- name: assert that encryption has been updated - ansible.builtin.assert: - that: zbxproxy_encryption_update is changed - -- name: test - update Zabbix proxy server back to being passive - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - description: Example Zabbix Proxy - state: present - status: passive - interface: - useip: 0 - ip: 10.1.1.2 - dns: zbxproxy_example01 - port: 10051 - register: zbxproxy_passive_update - -- name: assert that proxy was updated - ansible.builtin.assert: - that: zbxproxy_passive_update is changed - -- name: test - delete Zabbix proxy server - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - state: absent - register: zbxproxy_delete - -- name: assert that proxy has been deleted - ansible.builtin.assert: - that: zbxproxy_delete is changed - -- name: test - delete Zabbix proxy server (again) - community.zabbix.zabbix_proxy: - proxy_name: zbxproxy_example01 - state: absent - register: zbxproxy_delete_again - -- name: assert that nothing has been changed - ansible.builtin.assert: - that: not zbxproxy_delete_again is changed +- block: + - name: Run tests for Zabbix < 7.0 + when: zabbix_version is version('7.0', '<') + include_tasks: test_zabbix_proxy_before70.yml + + - name: Run tests for Zabbix >= 7.0 + when: zabbix_version is version('7.0', '>=') + include_tasks: test_zabbix_proxy_since70.yml + + always: + - name: Cleanup proxy + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + state: absent + ignore_errors: true + + - name: Cleanup proxy group + community.zabbix.zabbix_proxy_group: + name: zbxproxy_group_example01 + state: absent + ignore_errors: true + when: zabbix_version is version('7.0', '>=') diff --git a/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_before70.yml b/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_before70.yml new file mode 100644 index 000000000..0427cc2b6 --- /dev/null +++ b/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_before70.yml @@ -0,0 +1,302 @@ +--- +- name: test - create new passive Zabbix proxy server + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: passive + interface: + useip: 0 + ip: 10.1.1.2 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_new + +- name: assert that proxy was created + ansible.builtin.assert: + that: zbxproxy_new is changed + +- name: test - create same passive Zabbix proxy server + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: passive + interface: + useip: 0 + ip: 10.1.1.2 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_existing + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_existing is changed + +- name: test - update Zabbix proxy server description + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + status: passive + interface: + useip: 0 + ip: 10.1.1.2 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_desc_update + +- name: assert that description has been updated + ansible.builtin.assert: + that: zbxproxy_desc_update is changed + +- name: test - update Zabbix proxy server interface + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + status: passive + interface: + useip: 0 + ip: 10.1.1.3 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_interface_update + +- name: assert that interface has been updated + ansible.builtin.assert: + that: zbxproxy_interface_update is changed + +- name: test - update Zabbix proxy server description & interface (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + status: passive + interface: + useip: 0 + ip: 10.1.1.3 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_desc_interface_update + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_desc_interface_update is changed + +- name: test - update Zabbix proxy server interface to use only ip + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + status: passive + interface: + useip: 1 + ip: 10.1.1.3 + port: 10051 + register: zbxproxy_interface_onlyip + +- name: assert that interface has been updated + ansible.builtin.assert: + that: zbxproxy_interface_onlyip is changed + +- name: test - update Zabbix proxy server interface to use only ip again + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + status: passive + interface: + useip: 1 + ip: 10.1.1.3 + port: 10051 + register: zbxproxy_interface_onlyip_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_interface_onlyip_again is changed + +- name: test - update Zabbix proxy server interface to use only dns + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + status: passive + interface: + useip: 0 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_interface_onlydns + +- name: assert that interface has been updated + ansible.builtin.assert: + that: zbxproxy_interface_onlydns is changed + +- name: test - update Zabbix proxy server interface to use only dns again + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + status: passive + interface: + useip: 0 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_interface_onlydns_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_interface_onlydns_again is changed + +- name: test - update Zabbix proxy server interface to fail + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + status: passive + interface: + useip: 1 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_interface_fail + ignore_errors: true + +- name: assert that module has failed + ansible.builtin.assert: + that: zbxproxy_interface_fail is failed + +- name: test - update Zabbix proxy server to be active + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: active + register: zbxproxy_active_update + +- name: assert that proxy was updated + ansible.builtin.assert: + that: zbxproxy_active_update is changed + +- name: test - update Zabbix proxy server to be active (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: active + register: zbxproxy_active_update_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_active_update_again is changed + +- name: test - update Zabbix proxy server to be active and use proxy_address + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: active + proxy_address: 10.1.1.0/24,zabbix.example.com + register: zbxproxy_active_proxyaddress + +- name: assert that proxy was updated + ansible.builtin.assert: + that: zbxproxy_active_proxyaddress is changed + +- name: test - update Zabbix proxy server to be active use proxy_address (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: active + proxy_address: 10.1.1.0/24,zabbix.example.com + register: zbxproxy_active_proxyaddress_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_active_proxyaddress_again is changed + +- name: test - update Zabbix proxy server to use encryption + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: active + tls_psk_identity: test + tls_connect: PSK + tls_accept: PSK + tls_psk: 123456789abcdef123456789abcdef12 + register: zbxproxy_encryption + +- name: assert that encryption has been enabled + ansible.builtin.assert: + that: zbxproxy_encryption is changed + +- name: test - update Zabbix proxy server to use encryption (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: active + tls_psk_identity: test + tls_connect: PSK + tls_accept: PSK + tls_psk: 123456789abcdef123456789abcdef12 + register: zbxproxy_encryption_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: zbxproxy_encryption_again is changed + +- name: test - update Zabbix proxy server encryption settings + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: active + tls_connect: certificate + tls_accept: certificate + tls_issuer: AcmeCorp + tls_subject: AcmeCorpServer + register: zbxproxy_encryption_update + +- name: assert that encryption has been updated + ansible.builtin.assert: + that: zbxproxy_encryption_update is changed + +- name: test - update Zabbix proxy server back to being passive + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + status: passive + interface: + useip: 0 + ip: 10.1.1.2 + dns: zbxproxy_example01 + port: 10051 + register: zbxproxy_passive_update + +- name: assert that proxy was updated + ansible.builtin.assert: + that: zbxproxy_passive_update is changed + +- name: test - delete Zabbix proxy server + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + state: absent + register: zbxproxy_delete + +- name: assert that proxy has been deleted + ansible.builtin.assert: + that: zbxproxy_delete is changed + +- name: test - delete Zabbix proxy server (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + state: absent + register: zbxproxy_delete_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_delete_again is changed + diff --git a/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_since70.yml b/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_since70.yml new file mode 100644 index 000000000..89988c37b --- /dev/null +++ b/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_since70.yml @@ -0,0 +1,356 @@ +--- +- name: test - create new passive Zabbix proxy server + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: passive + address: 10.1.1.2 + port: 10051 + register: zbxproxy_new + +- name: assert that proxy was created + ansible.builtin.assert: + that: zbxproxy_new is changed + +- name: test - create same passive Zabbix proxy server + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: passive + address: 10.1.1.2 + port: 10051 + register: zbxproxy_existing + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_existing is changed + +- name: test - update Zabbix proxy server description + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + operating_mode: passive + address: 10.1.1.2 + port: 10051 + register: zbxproxy_desc_update + +- name: assert that description has been updated + ansible.builtin.assert: + that: zbxproxy_desc_update is changed + +- name: test - update Zabbix proxy server interface + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + operating_mode: passive + address: 10.1.1.3 + port: 10051 + register: zbxproxy_interface_update + +- name: assert that interface has been updated + ansible.builtin.assert: + that: zbxproxy_interface_update is changed + +- name: test - update Zabbix proxy server description & interface (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + operating_mode: passive + address: 10.1.1.3 + port: 10051 + register: zbxproxy_desc_interface_update + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_desc_interface_update is changed + +- name: test - update Zabbix proxy server interface to use DNS + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + operating_mode: passive + address: test-proxy01.local + port: 10051 + register: zbxproxy_interface_dns + +- name: assert that interface has been updated + ansible.builtin.assert: + that: zbxproxy_interface_dns is changed + +- name: test - update Zabbix proxy server interface to use DNS again + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy desc + state: present + operating_mode: passive + address: test-proxy01.local + port: 10051 + register: zbxproxy_interface_dns_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_interface_dns_again is changed + +- name: test - update Zabbix proxy server to be active + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: active + register: zbxproxy_active_update + +- name: assert that proxy was updated + ansible.builtin.assert: + that: zbxproxy_active_update is changed + +- name: test - update Zabbix proxy server to be active (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: active + register: zbxproxy_active_update_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_active_update_again is changed + +- name: test - update Zabbix proxy server to be active and use allowed_addresses + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: active + allowed_addresses: 10.1.1.0/24,zabbix.example.com + register: zbxproxy_active_allowed_addresses + +- name: assert that proxy was updated + ansible.builtin.assert: + that: zbxproxy_active_allowed_addresses is changed + +- name: test - update Zabbix proxy server to be active use allowed_addresses (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: active + allowed_addresses: 10.1.1.0/24,zabbix.example.com + register: zbxproxy_active_allowed_addresses_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_active_allowed_addresses_again is changed + +- name: test - update Zabbix proxy server to use encryption + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: active + tls_psk_identity: test + tls_connect: PSK + tls_accept: PSK + tls_psk: 123456789abcdef123456789abcdef12 + register: zbxproxy_encryption + +- name: assert that encryption has been enabled + ansible.builtin.assert: + that: zbxproxy_encryption is changed + +- name: test - update Zabbix proxy server to use encryption (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: active + tls_psk_identity: test + tls_connect: PSK + tls_accept: PSK + tls_psk: 123456789abcdef123456789abcdef12 + register: zbxproxy_encryption_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: zbxproxy_encryption_again is changed + +- name: test - update Zabbix proxy server encryption settings + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: active + tls_connect: certificate + tls_accept: certificate + tls_issuer: AcmeCorp + tls_subject: AcmeCorpServer + register: zbxproxy_encryption_update + +- name: assert that encryption has been updated + ansible.builtin.assert: + that: zbxproxy_encryption_update is changed + +- name: test - update Zabbix proxy server back to being passive + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + operating_mode: passive + address: test-proxy01.local + port: 10051 + register: zbxproxy_passive_update + +- name: assert that proxy was updated + ansible.builtin.assert: + that: zbxproxy_passive_update is changed + +- name: test - create Zabbix proxy group + community.zabbix.zabbix_proxy_group: + name: zbxproxy_group_example01 + state: present + +- name: test - add Zabbix proxy to Zabbix proxy group + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + proxy_group: zbxproxy_group_example01 + state: present + local_address: test-proxy01.local + local_port: 10051 + register: zbxproxy_add_to_group + +- name: assert that proxy was updated + ansible.builtin.assert: + that: zbxproxy_add_to_group is changed + +- name: test - add Zabbix proxy to Zabbix proxy group again + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + proxy_group: zbxproxy_group_example01 + local_address: test-proxy01.local + local_port: 10051 + state: present + register: zbxproxy_add_to_group_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_add_to_group_again is changed + +- name: test - delete proxy + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + state: absent + +- name: test - create Zabbix proxy with custom timeouts + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + address: 10.1.1.2 + operating_mode: passive + custom_timeouts: 1 + timeout_zabbix_agent: "10" + timeout_simple_check: "15" + timeout_snmp_agent: "16" + timeout_external_check: "20" + timeout_db_monitor: "25" + timeout_http_agent: "30" + timeout_ssh_agent: "15" + timeout_telnet_agent: "10" + timeout_script: "15" + timeout_browser: "30" + register: zbxproxy_create_with_timeouts + +- name: assert that proxy was created + ansible.builtin.assert: + that: zbxproxy_create_with_timeouts is changed + +- name: test - reate Zabbix proxy with custom timeouts again + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + address: 10.1.1.2 + operating_mode: passive + custom_timeouts: 1 + timeout_zabbix_agent: "10" + timeout_simple_check: "15" + timeout_snmp_agent: "16" + timeout_external_check: "20" + timeout_db_monitor: "25" + timeout_http_agent: "30" + timeout_ssh_agent: "15" + timeout_telnet_agent: "10" + timeout_script: "15" + timeout_browser: "30" + register: zbxproxy_create_with_timeouts_again + +- name: assert that nothing has changed + ansible.builtin.assert: + that: not zbxproxy_create_with_timeouts_again is changed + +- name: test - update timeout_zabbix_agent timeout for Zabbix proxy + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + description: Example Zabbix Proxy + state: present + address: 10.1.1.2 + operating_mode: passive + custom_timeouts: 1 + timeout_zabbix_agent: "15" + timeout_simple_check: "15" + timeout_snmp_agent: "16" + timeout_external_check: "20" + timeout_db_monitor: "25" + timeout_http_agent: "30" + timeout_ssh_agent: "15" + timeout_telnet_agent: "10" + timeout_script: "15" + timeout_browser: "30" + register: zbxproxy_update_with_timeouts + +- name: assert that nothing has changed + ansible.builtin.assert: + that: zbxproxy_update_with_timeouts is changed + +- name: test - delete proxy + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + state: absent + +- name: test - create Zabbix proxy and add it to Zabbix proxy group + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + proxy_group: zbxproxy_group_example01 + local_address: test-proxy01.local + local_port: 10051 + state: present + register: zbxproxy_create_add_to_group_again + +- name: assert that proxy was created + ansible.builtin.assert: + that: zbxproxy_create_add_to_group_again is changed + +- name: test - delete Zabbix proxy server + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + state: absent + register: zbxproxy_delete + +- name: assert that proxy has been deleted + ansible.builtin.assert: + that: zbxproxy_delete is changed + +- name: test - delete Zabbix proxy server (again) + community.zabbix.zabbix_proxy: + proxy_name: zbxproxy_example01 + state: absent + register: zbxproxy_delete_again + +- name: assert that nothing has been changed + ansible.builtin.assert: + that: not zbxproxy_delete_again is changed From 8b06bda7bd9085ef381f97291a7192db84f81df3 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 11:03:21 -0400 Subject: [PATCH 03/18] zabbix_host module updated to support Zabbix 7.0. --- plugins/modules/zabbix_host.py | 203 +++++++++++++----- tests/integration/inventory | 2 + .../targets/test_zabbix_host/tasks/main.yml | 6 + .../tasks/zabbix_host_tests.yml | 87 ++++++++ 4 files changed, 250 insertions(+), 48 deletions(-) create mode 100644 tests/integration/inventory diff --git a/plugins/modules/zabbix_host.py b/plugins/modules/zabbix_host.py index 00c04c221..d7b230442 100644 --- a/plugins/modules/zabbix_host.py +++ b/plugins/modules/zabbix_host.py @@ -73,9 +73,22 @@ choices: ["present", "absent"] default: "present" type: str + monitored_by: + description: + - Parameter introduced in Zabbix 7.0. + - Source that is used to monitor the host. + choices: ["zabbix_server", "proxy", "proxy_group"] + type: str proxy: description: - The name of the Zabbix proxy to be used. + - Required if C(monitored_by) is "proxy" + type: str + proxy_group: + description: + - Parameter introduced in Zabbix 7.0. + - Proxy group that is used to monitor the host. + - Required if C(monitored_by) is "proxy_group" type: str interfaces: type: list @@ -347,7 +360,7 @@ ansible.builtin.set_fact: ansible_zabbix_auth_key: 8ec0d52432c15c91fcafe9888500cf9a607f44091ab554dbee860f6b44fac895 -- name: Create a new host or rewrite an existing host's info +- name: Create a new host or rewrite an existing host's info (Zabbix <= 7.0) # Set task level following variables for Zabbix Server host in task vars: ansible_network_os: community.zabbix.zabbix @@ -408,6 +421,46 @@ - tag: ExampleHostsTag2 value: ExampleTagValue +- name: Create a new host or update it - monitored by Zabbix Proxy (Zabbix >= 7.0) +# Set task level following variables for Zabbix Server host in task + vars: + ansible_network_os: community.zabbix.zabbix + ansible_connection: httpapi + ansible_httpapi_port: 443 + ansible_httpapi_use_ssl: true + ansible_httpapi_validate_certs: false + ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu + become: false + delegate_to: zabbix-example-fqdn.org# you can use delegate_to or task level ansible_host like next example + community.zabbix.zabbix_host: + host_name: ExampleHost + host_groups: + - Example group1 + status: enabled + state: present + monitored_by: proxy + proxy: a.zabbix.proxy + +- name: Create a new host or update it - monitored by Zabbix Proxy Group (Zabbix >= 7.0) +# Set task level following variables for Zabbix Server host in task + vars: + ansible_network_os: community.zabbix.zabbix + ansible_connection: httpapi + ansible_httpapi_port: 443 + ansible_httpapi_use_ssl: true + ansible_httpapi_validate_certs: false + ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu + become: false + delegate_to: zabbix-example-fqdn.org# you can use delegate_to or task level ansible_host like next example + community.zabbix.zabbix_host: + host_name: ExampleHost + host_groups: + - Example group1 + status: enabled + state: present + monitored_by: proxy_group + proxy: a.zabbix.proxy.group + - name: Update an existing host's TLS settings # Set current task level variables for Zabbix Server host in task vars: @@ -437,6 +490,8 @@ from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase +from ansible.module_utils.compat.version import LooseVersion + import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils @@ -459,7 +514,7 @@ def get_template_ids(self, template_list): if template_list is None or len(template_list) == 0: return template_ids for template in template_list: - template_list = self._zapi.template.get({"output": "extend", "filter": {"host": template}}) + template_list = self._zapi.template.get({"output": ["templateid"], "filter": {"host": template}}) if len(template_list) < 1: self._module.fail_json(msg="Template not found: %s" % template) else: @@ -469,13 +524,23 @@ def get_template_ids(self, template_list): def add_host(self, host_name, group_ids, status, interfaces, proxy_id, visible_name, description, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject, ipmi_authtype, ipmi_privilege, - ipmi_username, ipmi_password, macros, tags): + ipmi_username, ipmi_password, macros, tags, monitored_by, proxy_group_id): try: if self._module.check_mode: self._module.exit_json(changed=True) parameters = {"host": host_name, "interfaces": interfaces, "groups": group_ids, "status": status} - if proxy_id: - parameters["proxy_hostid"] = proxy_id + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + if proxy_id: + parameters["proxy_hostid"] = proxy_id + else: + if monitored_by == 1: + if proxy_id: + parameters["monitored_by"] = 1 # By single proxy + parameters["proxyid"] = proxy_id + elif monitored_by == 2: + if proxy_group_id: + parameters["monitored_by"] = 2 # By single proxy + parameters["proxy_groupid"] = proxy_group_id if visible_name: parameters["name"] = visible_name if tls_connect: @@ -513,7 +578,8 @@ def add_host(self, host_name, group_ids, status, interfaces, proxy_id, visible_n def update_host(self, host_name, group_ids, status, host_id, interfaces, exist_interface_list, proxy_id, visible_name, description, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, - tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags, discovered_host, zabbix_host_obj): + tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags, + discovered_host, zabbix_host_obj, monitored_by, proxy_group_id): try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -523,8 +589,17 @@ def update_host(self, host_name, group_ids, status, host_id, interfaces, exist_i else: # A "plain" host parameters = {"hostid": host_id, "groups": group_ids, "status": status} - if (proxy_id >= 0 and proxy_id != zabbix_host_obj["proxy_hostid"]): - parameters["proxy_hostid"] = proxy_id + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + if (proxy_id >= 0 and proxy_id != zabbix_host_obj["proxy_hostid"]): + parameters["proxy_hostid"] = proxy_id + else: + if monitored_by == 1: + if (proxy_id >= 0 and proxy_id != zabbix_host_obj["proxyid"]): + parameters["proxyid"] = proxy_id + elif monitored_by == 2: + if (proxy_group_id >= 0 and proxy_group_id != zabbix_host_obj["proxy_groupid"]): + parameters["proxy_groupid"] = proxy_group_id + parameters["monitored_by"] = monitored_by if (visible_name is not None and visible_name != zabbix_host_obj["name"]): parameters["name"] = visible_name if (tls_connect is not None and tls_connect != zabbix_host_obj["tls_connect"]): @@ -571,34 +646,7 @@ def delete_host(self, host_id, host_name): # get host by host name def get_host_by_host_name(self, host_name): params = { - "output": [ - "inventory_mode", - "hostid", - "proxy_hostid", - "host", - "status", - "lastaccess", - "ipmi_authtype", - "ipmi_privilege", - "ipmi_username", - "ipmi_password", - "maintenanceid", - "maintenance_status", - "maintenance_type", - "maintenance_from", - "name", - "flags", - "templateid", - "description", - "tls_connect", - "tls_accept", - "tls_issuer", - "tls_subject", - "proxy_address", - "auto_compress", - "custom_interfaces", - "uuid" - ], + "output": "extend", "selectInventory": "extend", "selectMacros": "extend", "selectTags": ["tag", "value"], @@ -615,20 +663,31 @@ def get_host_by_host_name(self, host_name): # get proxyid by proxy name def get_proxyid_by_proxy_name(self, proxy_name): - proxy_list = self._zapi.proxy.get({"output": "extend", "filter": {"host": [proxy_name]}}) + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + proxy_list = self._zapi.proxy.get({"output": "extend", "filter": {"host": [proxy_name]}}) + else: + proxy_list = self._zapi.proxy.get({"output": "extend", "filter": {"name": [proxy_name]}}) if len(proxy_list) < 1: self._module.fail_json(msg="Proxy not found: %s" % proxy_name) else: return int(proxy_list[0]["proxyid"]) + # get proxy_group_id by proxy group name + def get_proxy_group_id_by_name(self, proxy_group_name): + proxy_group_list = self._zapi.proxygroup.get({"output": "extend", "filter": {"name": proxy_group_name}}) + if len(proxy_group_list) < 1: + self._module.fail_json(msg="Proxy group not found: %s" % proxy_group_name) + else: + return int(proxy_group_list[0]["proxy_groupid"]) + # get group ids by group names def get_group_ids_by_group_names(self, group_names): if self.check_host_group_exist(group_names): - return self._zapi.hostgroup.get({"output": "extend", "filter": {"name": group_names}}) + return self._zapi.hostgroup.get({"output": ["groupid"], "filter": {"name": group_names}}) # get host groups ids by host id def get_group_ids_by_host_id(self, host_id): - return self._zapi.hostgroup.get({"output": "extend", "hostids": host_id}) + return self._zapi.hostgroup.get({"output": ["groupid"], "hostids": host_id}) # get host templates by host id def get_host_templates_by_host_id(self, host_id): @@ -715,7 +774,7 @@ def check_all_properties(self, host_id, group_ids, status, interfaces, template_ exist_interfaces, host, proxy_id, visible_name, description, host_name, inventory_mode, inventory_zabbix, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject, tls_connect, ipmi_authtype, ipmi_privilege, - ipmi_username, ipmi_password, macros, tags): + ipmi_username, ipmi_password, macros, tags, monitored_by, proxy_group_id): # get the existing host's groups exist_host_groups = sorted(self.get_group_ids_by_host_id(host_id), key=lambda k: k["groupid"]) if sorted(group_ids, key=lambda k: k["groupid"]) != exist_host_groups: @@ -735,8 +794,16 @@ def check_all_properties(self, host_id, group_ids, status, interfaces, template_ if set(list(template_ids)) != set(exist_template_ids): return True - if int(host["proxy_hostid"]) != int(proxy_id): - return True + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + if int(host["proxy_hostid"]) != int(proxy_id): + return True + else: + if int(host["monitored_by"]) != monitored_by: + return True + if int(host["proxyid"]) != int(proxy_id): + return True + if int(host["proxy_groupid"]) != int(proxy_group_id): + return True # Check whether the visible_name has changed; Zabbix defaults to the technical hostname if not set. if visible_name: @@ -816,11 +883,18 @@ def link_or_clear_template(self, host_id, template_id_list): exist_template_ids = set(exist_template_id_list) template_ids = set(template_id_list) template_id_list = list(template_ids) + template_id_list_ = [] + for t in template_id_list: + template_id_list_.append({"templateid": t}) # get unlink and clear templates templates_clear = exist_template_ids.difference(template_ids) templates_clear_list = list(templates_clear) - request_str = {"hostid": host_id, "templates": template_id_list, "templates_clear": templates_clear_list} + templates_clear_list_ = [] + for t in templates_clear_list: + templates_clear_list_.append({"templateid": t}) + + request_str = {"hostid": host_id, "templates": template_id_list_, "templates_clear": templates_clear_list_} try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -973,7 +1047,9 @@ def main(): ] ), force=dict(type="bool", default=True), + monitored_by=dict(type="str", required=False, choices=["zabbix_server", "proxy", "proxy_group"], default=None), proxy=dict(type="str", required=False), + proxy_group=dict(type="str", required=False), visible_name=dict(type="str", required=False), description=dict(type="str", required=False), macros=dict( @@ -997,8 +1073,13 @@ def main(): ) ) )) + module = AnsibleModule( argument_spec=argument_spec, + required_if=([ + ["monigored_by", "proxy", ("proxy",)], + ["monigored_by", "proxy_group", ("proxy_group",)] + ]), supports_check_mode=True ) @@ -1026,10 +1107,20 @@ def main(): proxy = module.params["proxy"] macros = module.params["macros"] tags = module.params["tags"] + monitored_by = module.params["monitored_by"] + proxy_group = module.params["proxy_group"] # convert enabled to 0; disabled to 1 status = 1 if status == "disabled" else 0 + # convert monitored_by to int + if monitored_by == "zabbix_server": + monitored_by = 0 + elif monitored_by == "proxy": + monitored_by = 1 + elif monitored_by == "proxy_group": + monitored_by = 2 + host = Host(module) template_ids = [] @@ -1063,6 +1154,11 @@ def main(): else: proxy_id = 0 + if proxy_group: + proxy_group_id = host.get_proxy_group_id_by_name(proxy_group) + else: + proxy_group_id = 0 + # check if host exist is_host_exist = host.is_host_exist(host_name) @@ -1074,7 +1170,17 @@ def main(): # If proxy is not specified as a module parameter, use the existing setting if proxy is None: - proxy_id = int(zabbix_host_obj["proxy_hostid"]) + if LooseVersion(host._zbx_api_version) < LooseVersion("7.0"): + proxy_id = int(zabbix_host_obj["proxy_hostid"]) + else: + proxy_id = int(zabbix_host_obj["proxyid"]) + + if LooseVersion(host._zbx_api_version) >= LooseVersion("7.0"): + # If monitored_by and proxy_group are not specified as a module parameters, use the existing setting + if monitored_by is None: + monitored_by = int(zabbix_host_obj["monitored_by"]) + if proxy_group is None: + proxy_group_id = int(zabbix_host_obj["proxy_groupid"]) if state == "absent": # remove host @@ -1183,12 +1289,13 @@ def main(): host_id, group_ids, status, interfaces, template_ids, exist_interfaces, zabbix_host_obj, proxy_id, visible_name, description, host_name, inventory_mode, inventory_zabbix, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject, tls_connect, ipmi_authtype, ipmi_privilege, - ipmi_username, ipmi_password, macros, tags): + ipmi_username, ipmi_password, macros, tags, monitored_by, proxy_group_id): host.update_host( host_name, group_ids, status, host_id, interfaces, exist_interfaces, proxy_id, visible_name, description, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject, - ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags, discovered_host, zabbix_host_obj) + ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags, discovered_host, zabbix_host_obj, + monitored_by, proxy_group_id) host.link_or_clear_template(host_id, template_ids) @@ -1196,7 +1303,7 @@ def main(): host.update_inventory_zabbix(host_id, inventory_zabbix) module.exit_json(changed=True, - result="Successfully update host %s (%s) and linked with template '%s'" + result="Successfully updated host %s (%s) and linked with template '%s'" % (host_name, ip, link_templates)) else: module.exit_json(changed=False) @@ -1215,7 +1322,7 @@ def main(): host_id = host.add_host( host_name, group_ids, status, interfaces, proxy_id, visible_name, description, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, - ipmi_password, macros, tags) + ipmi_password, macros, tags, monitored_by, proxy_group_id) host.link_or_clear_template(host_id, template_ids) diff --git a/tests/integration/inventory b/tests/integration/inventory new file mode 100644 index 000000000..e6b451083 --- /dev/null +++ b/tests/integration/inventory @@ -0,0 +1,2 @@ +[testgroup] +testhost ansible_connection="local" ansible_pipelining="yes" ansible_python_interpreter="/home/ey/env_py39_ans214/bin/python" diff --git a/tests/integration/targets/test_zabbix_host/tasks/main.yml b/tests/integration/targets/test_zabbix_host/tasks/main.yml index c4675797f..f8df8b8c6 100644 --- a/tests/integration/targets/test_zabbix_host/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_host/tasks/main.yml @@ -21,3 +21,9 @@ - ExampleHost - ExampleHost1 - ExampleHost2 + + - name: "clean up Zabbix Proxy Group if tests failed" + community.zabbix.zabbix_proxy_group: + name: TestProxyGroup + state: absent + when: zabbix_version is version('7.0', '>=') diff --git a/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml b/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml index 20246a16b..d18f061c3 100644 --- a/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml +++ b/tests/integration/targets/test_zabbix_host/tasks/zabbix_host_tests.yml @@ -40,6 +40,7 @@ ip: 10.1.1.1 dns: "" port: "12345" + monitored_by: "{{ zabbix_version is version('7.0', '>=') | ternary('proxy', omit) }}" proxy: ExampleProxy macros: - macro: MACRO1 @@ -98,6 +99,7 @@ ip: 10.1.1.1 dns: "" port: "12345" + monitored_by: "{{ zabbix_version is version('7.0', '>=') | ternary('proxy', omit) }}" proxy: ExampleProxy macros: - macro: MACRO1 @@ -157,6 +159,7 @@ ip: 10.1.1.1 dns: "" port: "12345" + monitored_by: "{{ zabbix_version is version('7.0', '>=') | ternary('proxy', omit) }}" proxy: ExampleProxy register: zabbix_host1 @@ -207,6 +210,7 @@ ip: 10.1.1.1 dns: "" port: "12345" + monitored_by: "{{ zabbix_version is version('7.0', '>=') | ternary('proxy', omit) }}" proxy: ExampleProxy register: zabbix_host1 @@ -487,6 +491,7 @@ - name: "test: remove host proxy" community.zabbix.zabbix_host: host_name: ExampleHost + monitored_by: "{{ zabbix_version is version('7.0', '>=') | ternary('zabbix_server', omit) }}" proxy: "" register: zabbix_host1 @@ -498,6 +503,7 @@ - name: "test: add host proxy" community.zabbix.zabbix_host: host_name: ExampleHost + monitored_by: "{{ zabbix_version is version('7.0', '>=') | ternary('proxy', omit) }}" proxy: ExampleProxy register: zabbix_host1 @@ -509,6 +515,7 @@ - name: "test: add host proxy (again)" community.zabbix.zabbix_host: host_name: ExampleHost + monitored_by: "{{ zabbix_version is version('7.0', '>=') | ternary('proxy', omit) }}" proxy: ExampleProxy register: zabbix_host1 @@ -1424,3 +1431,83 @@ community.zabbix.zabbix_host: host_name: ExampleHost state: absent + +- name: perform tests for Zabbix >= 7.0 + when: zabbix_version is version('7.0', '>=') + block: + - name: create zabbix proxy group + community.zabbix.zabbix_proxy_group: + name: TestProxyGroup + + - name: create host monitored by zabbix proxy group + community.zabbix.zabbix_host: + host_name: ExampleHost + state: present + host_groups: + - Linux servers + monitored_by: proxy_group + proxy_group: TestProxyGroup + register: zbx_host_create_proxy_group + + - name: expect host to be created (changed) + ansible.builtin.assert: + that: zbx_host_create_proxy_group is changed + + - name: create host monitored by zabbix proxy group again + community.zabbix.zabbix_host: + host_name: ExampleHost + state: present + host_groups: + - Linux servers + monitored_by: proxy_group + proxy_group: TestProxyGroup + register: zbx_host_create_proxy_group_again + + - name: expect host to be not changed + ansible.builtin.assert: + that: zbx_host_create_proxy_group_again is not changed + + - name: update host monitored by zabbix server + community.zabbix.zabbix_host: + host_name: ExampleHost + state: present + monitored_by: zabbix_server + register: zbx_host_update_zabbix_server + + - name: expect host to be changed + ansible.builtin.assert: + that: zbx_host_update_zabbix_server is changed + + - name: update host to be monitored by zabbix proxy group + community.zabbix.zabbix_host: + host_name: ExampleHost + state: present + monitored_by: proxy_group + proxy_group: TestProxyGroup + register: zbx_host_update_proxy_group + + - name: expect host to be changed + ansible.builtin.assert: + that: zbx_host_update_proxy_group is changed + + - name: update host to be monitored by zabbix proxy group again + community.zabbix.zabbix_host: + host_name: ExampleHost + state: present + monitored_by: proxy_group + proxy_group: TestProxyGroup + register: zbx_host_update_proxy_group_again + + - name: expect host not to be changed + ansible.builtin.assert: + that: zbx_host_update_proxy_group_again is not changed + + - name: cleanup host + community.zabbix.zabbix_host: + host_name: ExampleHost + state: absent + + - name: cleanup proxy group + community.zabbix.zabbix_proxy_group: + name: TestProxyGroup + state: absent From d5ba5d98e752829a355032520533a2786fb9e909 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 11:27:36 -0400 Subject: [PATCH 04/18] Fix lint/sanity tests failures. --- plugins/modules/zabbix_host.py | 4 ++-- plugins/modules/zabbix_proxy.py | 23 +++++++++---------- plugins/modules/zabbix_proxy_group.py | 12 +++++++++- .../tasks/test_zabbix_proxy_before70.yml | 1 - 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/plugins/modules/zabbix_host.py b/plugins/modules/zabbix_host.py index d7b230442..bdf010aba 100644 --- a/plugins/modules/zabbix_host.py +++ b/plugins/modules/zabbix_host.py @@ -1077,8 +1077,8 @@ def main(): module = AnsibleModule( argument_spec=argument_spec, required_if=([ - ["monigored_by", "proxy", ("proxy",)], - ["monigored_by", "proxy_group", ("proxy_group",)] + ["monitored_by", "proxy", ("proxy",)], + ["monitored_by", "proxy_group", ("proxy_group",)] ]), supports_check_mode=True ) diff --git a/plugins/modules/zabbix_proxy.py b/plugins/modules/zabbix_proxy.py index da8eafe87..1a54c3a99 100644 --- a/plugins/modules/zabbix_proxy.py +++ b/plugins/modules/zabbix_proxy.py @@ -157,7 +157,6 @@ - Proxy group name. required: false type: str - default: "0" local_address: description: - Parameter introduced in Zabbix 7.0. @@ -202,7 +201,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on Zabbix agent checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Rired if if C(custom_timeouts) is set to 1. required: false type: str @@ -212,7 +211,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on simple checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -222,7 +221,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on SNMP agent checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -232,7 +231,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on external checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -242,7 +241,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on DB checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -252,7 +251,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on HTTPagent checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -262,7 +261,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on SSH checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -272,7 +271,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on Telnet checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -282,7 +281,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on script type checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -292,7 +291,7 @@ - Parameter introduced in Zabbix 7.0. - Spend no more than this number of seconds on browser type checks processing. - Accepts seconds or time unit with suffix (e.g., 30s, 1m). - - Possible values range: 1-600s. + - "Possible values range: 1-600s." - Required if if C(custom_timeouts) is set to 1. required: false type: str @@ -622,7 +621,7 @@ def main(): address=dict(type="str", required=False, default=None), port=dict(type="str", required=False, default="10051"), proxy_group=dict(type="str", required=False, default=None), - local_address=dict(type="str", required=False, default=None), + local_address=dict(type="str", required=False, default="10051"), local_port=dict(type="str", required=False, default="10051"), custom_timeouts=dict(type="int", required=False, default=0, choices=[0, 1]), timeout_zabbix_agent=dict(type="str", required=False, default=None), diff --git a/plugins/modules/zabbix_proxy_group.py b/plugins/modules/zabbix_proxy_group.py index 4fc4ce38a..6c9403fdd 100644 --- a/plugins/modules/zabbix_proxy_group.py +++ b/plugins/modules/zabbix_proxy_group.py @@ -56,6 +56,13 @@ required: false type: str default: 1m + min_online: + description: + - Minimum number of online proxies required for the group to be online. + - "Possible values range: 1-1000." + required: false + type: str + default: "1" state: description: - State of the proxy group. @@ -65,6 +72,9 @@ default: "present" type: str +extends_documentation_fragment: +- community.zabbix.zabbix + """ EXAMPLES = r""" @@ -119,7 +129,7 @@ def __init__(self, module, zbx=None, zapi_wrapper=None): def proxy_group_exists(self, proxy_group_name): result = self._zapi.proxygroup.get({"output": "extend", - "filter": {"name": proxy_group_name}}) + "filter": {"name": proxy_group_name}}) if len(result) > 0 and "proxy_groupid" in result[0]: self.existing_data = result[0] diff --git a/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_before70.yml b/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_before70.yml index 0427cc2b6..86ece24f3 100644 --- a/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_before70.yml +++ b/tests/integration/targets/test_zabbix_proxy/tasks/test_zabbix_proxy_before70.yml @@ -299,4 +299,3 @@ - name: assert that nothing has been changed ansible.builtin.assert: that: not zbxproxy_delete_again is changed - From 39fbb24ba7f14ea9c944db3d802aff2de2c256c6 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 11:28:09 -0400 Subject: [PATCH 05/18] Remove mistakenly committed tests/integration/inventory. --- tests/integration/inventory | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 tests/integration/inventory diff --git a/tests/integration/inventory b/tests/integration/inventory deleted file mode 100644 index e6b451083..000000000 --- a/tests/integration/inventory +++ /dev/null @@ -1,2 +0,0 @@ -[testgroup] -testhost ansible_connection="local" ansible_pipelining="yes" ansible_python_interpreter="/home/ey/env_py39_ans214/bin/python" From 92255900d987f690f552a948164fe71cb9b29423 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 15:39:06 -0400 Subject: [PATCH 06/18] zabbix_proxy module: handle proxy parameters dependency better. --- plugins/modules/zabbix_proxy.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/modules/zabbix_proxy.py b/plugins/modules/zabbix_proxy.py index 1a54c3a99..c35f020e5 100644 --- a/plugins/modules/zabbix_proxy.py +++ b/plugins/modules/zabbix_proxy.py @@ -164,7 +164,6 @@ - Required if proxy_groupid is not 0 required: false type: str - default: "10051" local_port: description: - Parameter introduced in Zabbix 7.0. @@ -621,7 +620,7 @@ def main(): address=dict(type="str", required=False, default=None), port=dict(type="str", required=False, default="10051"), proxy_group=dict(type="str", required=False, default=None), - local_address=dict(type="str", required=False, default="10051"), + local_address=dict(type="str", required=False, default=None), local_port=dict(type="str", required=False, default="10051"), custom_timeouts=dict(type="int", required=False, default=0, choices=[0, 1]), timeout_zabbix_agent=dict(type="str", required=False, default=None), @@ -659,9 +658,6 @@ def main(): module = AnsibleModule( argument_spec=argument_spec, required_if=required, - required_together=[ - [("proxy_group",), ("local_address",)] - ], supports_check_mode=True ) @@ -705,6 +701,9 @@ def main(): timeout_telnet_agent = module.params["timeout_telnet_agent"] timeout_script = module.params["timeout_script"] timeout_browser = module.params["timeout_browser"] + if proxy_group: + if local_address is None: + module.fail_json(msg="local_address parameter is required when proxy_group is specified.") if tls_connect == "certificate": tls_connect = 4 From c24197a211d636cc41ba90403345c267ad4efbc5 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 15:40:56 -0400 Subject: [PATCH 07/18] zabbix_discovery_rule module updated to support Zabbix 7.0. --- plugins/modules/zabbix_discovery_rule.py | 23 ++++++++++++++----- .../test_zabbix_discovery_rule/tasks/main.yml | 11 ++++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/plugins/modules/zabbix_discovery_rule.py b/plugins/modules/zabbix_discovery_rule.py index 2296f3db8..e20aa0cbd 100644 --- a/plugins/modules/zabbix_discovery_rule.py +++ b/plugins/modules/zabbix_discovery_rule.py @@ -428,11 +428,18 @@ def get_proxy_by_proxy_name(self, proxy_name): proxy matching proxy name """ try: - proxy_list = self._zapi.proxy.get({ - "output": "extend", - "selectInterface": "extend", - "filter": {"host": [proxy_name]} - }) + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + proxy_list = self._zapi.proxy.get({ + "output": "extend", + "selectInterface": "extend", + "filter": {"host": [proxy_name]} + }) + else: + proxy_list = self._zapi.proxy.get({ + "output": "extend", + "filter": {"name": [proxy_name]} + }) + if len(proxy_list) < 1: self._module.fail_json(msg="Proxy not found: %s" % proxy_name) else: @@ -458,7 +465,11 @@ def _construct_parameters(self, **kwargs): "dchecks": kwargs["dchecks"] } if kwargs["proxy"]: - _params["proxy_hostid"] = self.get_proxy_by_proxy_name(kwargs["proxy"])["proxyid"] + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + _params["proxy_hostid"] = self.get_proxy_by_proxy_name(kwargs["proxy"])["proxyid"] + else: + _params["proxyid"] = self.get_proxy_by_proxy_name(kwargs["proxy"])["proxyid"] + return _params def check_difference(self, **kwargs): diff --git a/tests/integration/targets/test_zabbix_discovery_rule/tasks/main.yml b/tests/integration/targets/test_zabbix_discovery_rule/tasks/main.yml index cbf13b391..01cd09210 100644 --- a/tests/integration/targets/test_zabbix_discovery_rule/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_discovery_rule/tasks/main.yml @@ -214,12 +214,21 @@ ansible.builtin.assert: that: drule_reset is changed - - name: test - create new active Zabbix proxy server + - name: test - create new active Zabbix proxy server (Zabbix < 7.0) community.zabbix.zabbix_proxy: proxy_name: ACME_proxy status: active state: present register: zbxproxy_active + when: zabbix_version is version('7.0', '<') + + - name: test - create new active Zabbix proxy server (Zabbix >= 7.0) + community.zabbix.zabbix_proxy: + proxy_name: ACME_proxy + operating_mode: active + state: present + register: zbxproxy_active + when: zabbix_version is version('7.0', '>=') - name: assert that proxy was created ansible.builtin.assert: From a456c645640b8a3dfb0c207d484f79a60ab771a0 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 17:03:07 -0400 Subject: [PATCH 08/18] zabbix_group_events_info module updated to support Zabbix 7.0. --- plugins/modules/zabbix_group_events_info.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/plugins/modules/zabbix_group_events_info.py b/plugins/modules/zabbix_group_events_info.py index e41cab26f..1bad1be89 100644 --- a/plugins/modules/zabbix_group_events_info.py +++ b/plugins/modules/zabbix_group_events_info.py @@ -90,7 +90,7 @@ description: acknowledges informations type: complex contains: - alias: + username: description: Account who acknowledge type: str clock: @@ -208,6 +208,9 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase + +from ansible.module_utils.compat.version import LooseVersion + import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils @@ -228,10 +231,14 @@ def get_triggers_by_group_id_in_problem_state(self, group_id, trigger_severity): def get_last_event_by_trigger_id(self, triggers_id): """ Get the last event from triggerid""" output = ["eventid", "clock", "acknowledged", "value"] - select_acknowledges = ["clock", "alias", "message"] - event = self._zapi.event.get({"output": output, "objectids": triggers_id, - "select_acknowledges": select_acknowledges, "limit": 1, "sortfield": "clock", - "sortorder": "DESC"}) + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + event = self._zapi.event.get({"output": output, "objectids": triggers_id, + "select_acknowledges": "extend", "limit": 1, "sortfield": "clock", + "sortorder": "DESC"}) + else: + event = self._zapi.event.get({"output": output, "objectids": triggers_id, + "selectAcknowledges": "extend", "limit": 1, "sortfield": "clock", + "sortorder": "DESC"}) return event[0] From 5a25ef590ad141c55078e42dc01f6016ddea53be Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 17:15:29 -0400 Subject: [PATCH 09/18] zabbix_host_events_info module updated to support Zabbix 7.0. --- plugins/modules/zabbix_host_events_info.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/modules/zabbix_host_events_info.py b/plugins/modules/zabbix_host_events_info.py index c957e68de..87ce0c1aa 100644 --- a/plugins/modules/zabbix_host_events_info.py +++ b/plugins/modules/zabbix_host_events_info.py @@ -299,9 +299,8 @@ def get_triggers_by_host_id_in_problem_state(self, host_id, trigger_severity, ta def get_last_event_by_trigger_id(self, triggers_id): """ Get the last event from triggerid""" output = ["eventid", "clock", "acknowledged", "value"] - select_acknowledges = ["clock", "alias", "message"] event = self._zapi.event.get({"output": output, "objectids": triggers_id, - "select_acknowledges": select_acknowledges, "selectTags": "extend", "limit": 1, "sortfield": "clock", + "select_acknowledges": "extend", "limit": 1, "sortfield": "clock", "sortorder": "DESC"}) return event[0] From fd0145a711c6920818c72ed04b1b909deb97c8e6 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 17:48:23 -0400 Subject: [PATCH 10/18] zabbix_proxy_info module updated to support Zabbix 7.0. --- plugins/modules/zabbix_proxy_info.py | 23 +++++++++++----- .../test_zabbix_proxy_info/tasks/main.yml | 26 ++++++++++++++++++- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/plugins/modules/zabbix_proxy_info.py b/plugins/modules/zabbix_proxy_info.py index c82112609..bde67cdf9 100644 --- a/plugins/modules/zabbix_proxy_info.py +++ b/plugins/modules/zabbix_proxy_info.py @@ -123,6 +123,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase +from ansible.module_utils.compat.version import LooseVersion import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils @@ -130,13 +131,21 @@ class Proxy(ZabbixBase): def get_proxy(self, name, hosts=False): result = {} - params = { - "filter": { - "host": name - }, - "output": "extend", - "selectInterface": "extend", - } + if LooseVersion(self._zbx_api_version) < LooseVersion("7.0"): + params = { + "filter": { + "host": name + }, + "selectInterface": "extend", + "output": "extend" + } + else: + params = { + "filter": { + "name": name + }, + "output": "extend" + } if hosts: params["selectHosts"] = ["host", "hostid"] diff --git a/tests/integration/targets/test_zabbix_proxy_info/tasks/main.yml b/tests/integration/targets/test_zabbix_proxy_info/tasks/main.yml index ddd101850..a579ea116 100644 --- a/tests/integration/targets/test_zabbix_proxy_info/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_proxy_info/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: test - Create new Zabbix proxy +- name: test - Create new Zabbix proxy for Zabbix < 7.0 community.zabbix.zabbix_proxy: state: present proxy_name: ExampleProxy @@ -11,6 +11,18 @@ port: 10051 dns: ExampleProxy.local register: create_proxy_result + when: zabbix_version is version('7.0', '<') + +- name: test - Create new Zabbix proxy for Zabbix >= 7.0 + community.zabbix.zabbix_proxy: + state: present + proxy_name: ExampleProxy + description: ExampleProxy + operating_mode: passive + address: 10.1.1.2 + port: 10051 + register: create_proxy_result + when: zabbix_version is version('7.0', '>=') - ansible.builtin.assert: that: @@ -23,6 +35,7 @@ host_groups: - Linux servers status: enabled + monitored_by: "{{ zabbix_version is version('7.0', '>=') | ternary('proxy', omit) }}" proxy: ExampleProxy interfaces: - type: 1 @@ -43,6 +56,7 @@ proxy_hosts: true register: get_proxy_info_result +- debug: var=get_proxy_info_result - ansible.builtin.assert: that: - get_proxy_info_result["zabbix_proxy"].host == "ExampleProxy" @@ -53,6 +67,16 @@ - get_proxy_info_result["zabbix_proxy"].interface.useip == "1" - get_proxy_info_result["zabbix_proxy"].interface.port == "10051" - get_proxy_info_result["zabbix_proxy"].interface.dns == "ExampleProxy.local" + when: zabbix_version is version('7.0', '<') + +- ansible.builtin.assert: + that: + - get_proxy_info_result["zabbix_proxy"].name== "ExampleProxy" + - get_proxy_info_result["zabbix_proxy"].hosts | length > 0 + - get_proxy_info_result["zabbix_proxy"].hosts[0].host == "ExampleHost" + - get_proxy_info_result["zabbix_proxy"].address == "10.1.1.2" + - get_proxy_info_result["zabbix_proxy"].port == "10051" + when: zabbix_version is version('7.0', '>=') - name: test - cleanup test Zabbix host community.zabbix.zabbix_host: From 7aec6c72c91dddb088e85361bf4ec1082e9b500e Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Mon, 3 Jun 2024 19:45:23 -0400 Subject: [PATCH 11/18] zabbix_script module: update tests to run for Zabbix 7.0. --- .../integration/targets/test_zabbix_script/tasks/main.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/integration/targets/test_zabbix_script/tasks/main.yml b/tests/integration/targets/test_zabbix_script/tasks/main.yml index 4c5ea8a4c..ff2c164e9 100644 --- a/tests/integration/targets/test_zabbix_script/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_script/tasks/main.yml @@ -147,16 +147,21 @@ that: - update_action_script_again_result.changed is sameas false + # FIXME: temporarily disabling this check for Zabbix >= 7.0 + # EnableGlobalScripts must be 1 in Zabbix server config + # We need to prepare Zabbix server container for that - name: test - Update action operation script to execute on server zabbix_script: script_type: script execute_on: zabbix_server command: echo 1 register: update_action_script_server_result + when: zabbix_version is version('7.0', '<') - assert: that: - update_action_script_server_result.changed is sameas true + when: zabbix_version is version('7.0', '<') - name: test - Update action operation script to execute on server again zabbix_script: @@ -164,10 +169,12 @@ execute_on: zabbix_server command: echo 1 register: update_action_script_server_again_result + when: zabbix_version is version('7.0', '<') - assert: that: - update_action_script_server_again_result.changed is sameas false + when: zabbix_version is version('7.0', '<') - name: test - Update action operation script to execute on server or proxy zabbix_script: From 37f650111f711dc109cd272fde20b482c71f82a4 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Tue, 4 Jun 2024 11:29:46 -0400 Subject: [PATCH 12/18] Revert "zabbix_script module: update tests to run for Zabbix 7.0." This reverts commit a4917a0275cc2a79a84395ee5aff44343c751293. --- .../integration/targets/test_zabbix_script/tasks/main.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/integration/targets/test_zabbix_script/tasks/main.yml b/tests/integration/targets/test_zabbix_script/tasks/main.yml index ff2c164e9..4c5ea8a4c 100644 --- a/tests/integration/targets/test_zabbix_script/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_script/tasks/main.yml @@ -147,21 +147,16 @@ that: - update_action_script_again_result.changed is sameas false - # FIXME: temporarily disabling this check for Zabbix >= 7.0 - # EnableGlobalScripts must be 1 in Zabbix server config - # We need to prepare Zabbix server container for that - name: test - Update action operation script to execute on server zabbix_script: script_type: script execute_on: zabbix_server command: echo 1 register: update_action_script_server_result - when: zabbix_version is version('7.0', '<') - assert: that: - update_action_script_server_result.changed is sameas true - when: zabbix_version is version('7.0', '<') - name: test - Update action operation script to execute on server again zabbix_script: @@ -169,12 +164,10 @@ execute_on: zabbix_server command: echo 1 register: update_action_script_server_again_result - when: zabbix_version is version('7.0', '<') - assert: that: - update_action_script_server_again_result.changed is sameas false - when: zabbix_version is version('7.0', '<') - name: test - Update action operation script to execute on server or proxy zabbix_script: From 4822d9f86dfbce1e474b2447f07e052bd0e9f37e Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Tue, 4 Jun 2024 11:31:38 -0400 Subject: [PATCH 13/18] Additional options to run Zabbix server docker to handle script tests properly. --- .env_srv | 1 + docker-compose.yml | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 .env_srv diff --git a/.env_srv b/.env_srv new file mode 100644 index 000000000..44857afb2 --- /dev/null +++ b/.env_srv @@ -0,0 +1 @@ +ZBX_ENABLEGLOBALSCRIPTS=1 diff --git a/docker-compose.yml b/docker-compose.yml index 512e4877f..98149d80c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,8 @@ services: - "zabbix-db" links: - "zabbix-db" + env_file: + - ./.env_srv zabbix-web: image: zabbix/zabbix-web-nginx-pgsql:ubuntu-${zabbix_version}-latest environment: From f365f461eeb7be739631598ecc35b59b6f58b887 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Tue, 4 Jun 2024 11:44:48 -0400 Subject: [PATCH 14/18] Rmove Zabbix 6.2 and add Zabbix 7.0 for plugins integration testing. --- .github/workflows/plugins-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/plugins-integration.yml b/.github/workflows/plugins-integration.yml index ca50cae9b..c76ad2ca4 100644 --- a/.github/workflows/plugins-integration.yml +++ b/.github/workflows/plugins-integration.yml @@ -21,8 +21,8 @@ jobs: matrix: zabbix_container: - version: "6.0" - - version: "6.2" - version: "6.4" + - version: "7.0" ansible: # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-changelogs - stable-2.15 From 5860db3e2f96c3a1250cf92c64cc17c273b60a1e Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Tue, 4 Jun 2024 11:51:18 -0400 Subject: [PATCH 15/18] Changelog fragment added. --- changelogs/fragments/zabbix70_modules.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/fragments/zabbix70_modules.yml diff --git a/changelogs/fragments/zabbix70_modules.yml b/changelogs/fragments/zabbix70_modules.yml new file mode 100644 index 000000000..18b5dfc36 --- /dev/null +++ b/changelogs/fragments/zabbix70_modules.yml @@ -0,0 +1,5 @@ +breaking_changes: + - Remove support for Zabbix 6.2 +minor_changes: + - zabbix_discovery_rule, zabbix_group_events_info, zabbix_host, zabbix_host_events_info, zabbix_proxy, zabbix_proxy_info modules updated to work wih Zabbix 7.0 + - added new module zabbix_proxy_group (Zabbix 7.0) From 0f1493d81c000cbff852c536fbf5c30bf113ae0d Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Tue, 4 Jun 2024 15:52:05 -0400 Subject: [PATCH 16/18] Fix sanity test problems. --- plugins/modules/zabbix_proxy.py | 10 ---------- plugins/modules/zabbix_proxy_group.py | 15 +++++++++------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/plugins/modules/zabbix_proxy.py b/plugins/modules/zabbix_proxy.py index c35f020e5..7c1a6ec10 100644 --- a/plugins/modules/zabbix_proxy.py +++ b/plugins/modules/zabbix_proxy.py @@ -204,7 +204,6 @@ - Rired if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_simple_check: description: - Parameter introduced in Zabbix 7.0. @@ -214,7 +213,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_snmp_agent: description: - Parameter introduced in Zabbix 7.0. @@ -224,7 +222,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_external_check: description: - Parameter introduced in Zabbix 7.0. @@ -234,7 +231,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_db_monitor: description: - Parameter introduced in Zabbix 7.0. @@ -244,7 +240,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_http_agent: description: - Parameter introduced in Zabbix 7.0. @@ -254,7 +249,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_ssh_agent: description: - Parameter introduced in Zabbix 7.0. @@ -264,7 +258,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_telnet_agent: description: - Parameter introduced in Zabbix 7.0. @@ -274,7 +267,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_script: description: - Parameter introduced in Zabbix 7.0. @@ -284,7 +276,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" timeout_browser: description: - Parameter introduced in Zabbix 7.0. @@ -294,7 +285,6 @@ - Required if if C(custom_timeouts) is set to 1. required: false type: str - default: "" extends_documentation_fragment: - community.zabbix.zabbix diff --git a/plugins/modules/zabbix_proxy_group.py b/plugins/modules/zabbix_proxy_group.py index 6c9403fdd..712e6beb2 100644 --- a/plugins/modules/zabbix_proxy_group.py +++ b/plugins/modules/zabbix_proxy_group.py @@ -21,12 +21,6 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -from ansible.module_utils.basic import AnsibleModule - -from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase - -import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils - DOCUMENTATION = r""" --- @@ -121,6 +115,15 @@ state: absent """ +RETURN = r""" # """ + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.community.zabbix.plugins.module_utils.base import ZabbixBase + +import ansible_collections.community.zabbix.plugins.module_utils.helpers as zabbix_utils + class ProxyGroup(ZabbixBase): def __init__(self, module, zbx=None, zapi_wrapper=None): From 4dca6587b82792ef0b2873dc5ba28cb99ebc199c Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Tue, 4 Jun 2024 16:01:51 -0400 Subject: [PATCH 17/18] Fix plugins integration tests for Zabbxi < 7.0. --- .../targets/test_zabbix_discovery_rule/tasks/main.yml | 6 ++++++ .../targets/test_zabbix_proxy_info/tasks/main.yml | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/tests/integration/targets/test_zabbix_discovery_rule/tasks/main.yml b/tests/integration/targets/test_zabbix_discovery_rule/tasks/main.yml index 01cd09210..88ae6f94a 100644 --- a/tests/integration/targets/test_zabbix_discovery_rule/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_discovery_rule/tasks/main.yml @@ -222,6 +222,11 @@ register: zbxproxy_active when: zabbix_version is version('7.0', '<') + - name: assert that proxy was created + ansible.builtin.assert: + that: zbxproxy_active is changed + when: zabbix_version is version('7.0', '<') + - name: test - create new active Zabbix proxy server (Zabbix >= 7.0) community.zabbix.zabbix_proxy: proxy_name: ACME_proxy @@ -233,6 +238,7 @@ - name: assert that proxy was created ansible.builtin.assert: that: zbxproxy_active is changed + when: zabbix_version is version('7.0', '>=') - name: test - update Zabbix discovery rule proxy community.zabbix.zabbix_discovery_rule: diff --git a/tests/integration/targets/test_zabbix_proxy_info/tasks/main.yml b/tests/integration/targets/test_zabbix_proxy_info/tasks/main.yml index a579ea116..ae9a50ec9 100644 --- a/tests/integration/targets/test_zabbix_proxy_info/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_proxy_info/tasks/main.yml @@ -13,6 +13,12 @@ register: create_proxy_result when: zabbix_version is version('7.0', '<') + +- ansible.builtin.assert: + that: + - create_proxy_result.changed is sameas true + when: zabbix_version is version('7.0', '<') + - name: test - Create new Zabbix proxy for Zabbix >= 7.0 community.zabbix.zabbix_proxy: state: present @@ -27,6 +33,7 @@ - ansible.builtin.assert: that: - create_proxy_result.changed is sameas true + when: zabbix_version is version('7.0', '>=') - name: test - Create new Zabbix host monitored by the proxy community.zabbix.zabbix_host: From 8677864673fa0d84e5037d743fc061d080eb1617 Mon Sep 17 00:00:00 2001 From: Evgeny Yurchenko Date: Tue, 4 Jun 2024 17:54:37 -0400 Subject: [PATCH 18/18] zabbix_host_events_info: fix for Zabbix > 6.0. --- plugins/modules/zabbix_host_events_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/zabbix_host_events_info.py b/plugins/modules/zabbix_host_events_info.py index 87ce0c1aa..2d9029f8d 100644 --- a/plugins/modules/zabbix_host_events_info.py +++ b/plugins/modules/zabbix_host_events_info.py @@ -300,7 +300,7 @@ def get_last_event_by_trigger_id(self, triggers_id): """ Get the last event from triggerid""" output = ["eventid", "clock", "acknowledged", "value"] event = self._zapi.event.get({"output": output, "objectids": triggers_id, - "select_acknowledges": "extend", "limit": 1, "sortfield": "clock", + "select_acknowledges": "extend", "selectTags": "extend", "limit": 1, "sortfield": "clock", "sortorder": "DESC"}) return event[0]