From 4e584a5e9ae2997ab4e54bf160ad2aca69e5ee73 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Mon, 15 Apr 2024 14:39:44 +0000 Subject: [PATCH 01/21] init commit --- plugins/modules/zabbix_item.py | 192 ++++++++++++++++++ .../targets/test_zabbix_item/meta/main.yml | 3 + .../targets/test_zabbix_item/tasks/main.yml | 12 ++ .../tasks/zabbix_item_tests.yml | 10 + 4 files changed, 217 insertions(+) create mode 100644 plugins/modules/zabbix_item.py create mode 100644 tests/integration/targets/test_zabbix_item/meta/main.yml create mode 100644 tests/integration/targets/test_zabbix_item/tasks/main.yml create mode 100644 tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py new file mode 100644 index 000000000..8095d2534 --- /dev/null +++ b/plugins/modules/zabbix_item.py @@ -0,0 +1,192 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2013-2014, Epic Games, Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + + +import copy + +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 Item(ZabbixBase): + #exist item + def is_item_exist(self, item_name, host_name): + host_id = self.get_hostid_by_host_name(host_name) + result = self._zapi.item.get({"filter": {"name": item_name, "hostid": host_id}}) + return result + + #check if host exists + def check_host_exist(self, host_name): + result = self._zapi.host.get({"filter": {"name": host_name}}) + if not result: + self._module.fail_json(msg="Host not found %s" % host_name) + return True + + def add_item(self, item_name, key, host_id, type, value_type, delay): #add more parameters + try: + if self._module.check_mode: + self._module.exit_json(changed=True) + parameters = {"name": item_name, "key_": key, "hostid": host_id, "type": type, "value_type": value_type, "delay": delay} #add more parameters + #add conditional parameters + + item_list = self._zapi.item.create(parameters) + if len(item_list) >= 1: + return item_list["itemids"][0] + except Exception as e: + self._module.fail_json(msg="Failed to create item %s: %s" % (item_name, e)) + + def update_item(self, item_name, item_id, key, delay, description): #add more parameters + try: + if self._module.check_mode: + self._module.exit_json(changed=True) + + parameters = {"itemid": item_id} + #add conditional parameters + if description is not None: + parameters["description"] = description + if key is not None: + parameters["key_"] = key + if delay is not None: + parameters["delay"] = delay + + self._zapi.item.update(parameters) + except Exception as e: + self._module.fail_json(msg="Failed to update item %s: %s" % (item_name, e)) + + def delete_item(self, item_id, item_name): + try: + if self._module.check_mode: + self._module.exit_json(changed=True) + self._zapi.item.delete([item_id]) + except Exception as e: + self._module.fail_json(msg="Failed to delete item %s: %s" % (item_name, e)) + + def get_item_by_item_name(self, item_name): + params = { # add more parameters + "output": [ + "itemid" + ], + "filter": { + "name": [item_name] + } + } + + item_list = self._zapi.item.get(params) + if len(item_list) < 1: + self._module.fail_json(msg="Item not found: %s" % item_name) + + def get_hostid_by_host_name(self, host_name): + host_list = self._zapi.host.get({"output": "extend", "filter": {"host": [host_name]}}) + if len(host_list) < 1: + self._module.fail_json(msg="Host not found: %s" % host_name) + else: + return int(host_list[0]["hostid"]) + + def check_all_properties(self, item_id, key, host_id, host_name, delay): + exist_item = self._zapi.item.get({"output": "extend", "filter": {"itemid": item_id}})[0] + exist_host = self.get_hostid_by_host_name(host_name) + if host_id != exist_host: + return True + + if key != exist_item["key_"]: + return True + if delay != exist_item["delay"]: + return True + + return False + +def main(): + argument_spec = zabbix_utils.zabbix_common_argument_spec() + argument_spec.update(dict( + item_name=dict(type="str", required=True), + key=dict(type="str", required=True), + host_name=dict(type="str", required=True), + state=dict(type="str", default="present", choices=["present", "absent"]), + status=dict(type="str", default="enabled", choices=["enabled", "disabled"]), + type=dict(type="str", choices=["zabbix_agent", "1", "zabbix_trapper", "2", "simple_check", "3", "zabbix_internal", "4", "zabbix_agent_active", "5", "web_item", "6", "external_check", "7", "database_monitor", "8", "ipmi", "9", "ssh", "10", "telnet", "11", "calculated", "12", "jmx", "13", "snmp_trap", "14", "dependent", "15", "http", "16", "snmp_agent", "17", "script", "18"], required=True), + description=dict(type="str"), + value_type=dict(type="str", choices=["float", "0", "character", "1", "log", "2", "unsigned", "3", "text", "4"], required=True), + delay=dict(type="str", default="10s") + )) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True + ) + + item_name = module.params["item_name"] + key = module.params["key"] + host_name = module.params["host_name"] + state = module.params["state"] + status = module.params["status"] + type = module.params["type"] + description = module.params["description"] + value_type = module.params["value_type"] + delay = module.params["delay"] + + + status = 1 if status == "disabled" else 0 + + type_types = {"zabbix_agent": 1, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 4, "zabbix_agent_active": 5, "web_item": 6, "external_check": 7, "database_monitor": 8, "ipmi": 9, "ssh": 10, "telnet": 11, "calculated": 12, "jmx": 13, "snmp_trap": 14, "dependent": 15, "http": 16, "snmp_agent": 17, "script": 18} + if type in list(type_types.keys()): + type_int = type_types[type] + + value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} + if value_type in list(value_type_types.keys()): + value_type_int = value_type_types[value_type] + + item = Item(module) + + # find host id + host_id = "" + if host_name is not None: + host_id = item.get_hostid_by_host_name(host_name) + if host_id is None: + module.fail_json(msg="host %s does not exist." % host_name) + else: + module.fail_json(msg="host_name must not be empty.") + + # check if item exist + is_item_exist = item.is_item_exist(item_name, host_name) + + if is_item_exist: + item_id = is_item_exist[0]["itemid"] + + if state == "absent": + # remove item + item.delete_item(item_id, item_name) + module.exit_json(changed=True, result="Successfully deleted item %s" % item_name) + else: + + + # update item + if item.check_all_properties(item_id, key, host_id, host_name, delay): + item.update_item(item_name, item_id, key, delay, description) + + module.exit_json(changed=True, result="Successfully updated item %s on host %s" % (item_name, host_name)) + else: + module.exit_json(changed=False) + + else: + if state == "absent": + # the item is already deleted. + module.exit_json(changed=False) + + if not host_id: + module.fail_json(msg="Specify a host when creating item '%s'" % item_name) + + # create item + item_id = item.add_item(item_name, key, host_id, type_int, value_type_int, delay) + + module.exit_json(changed=True, result="Successfully added item %s on host %s" % (item_name, host_name)) + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/test_zabbix_item/meta/main.yml b/tests/integration/targets/test_zabbix_item/meta/main.yml new file mode 100644 index 000000000..acdb704c8 --- /dev/null +++ b/tests/integration/targets/test_zabbix_item/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - setup_zabbix diff --git a/tests/integration/targets/test_zabbix_item/tasks/main.yml b/tests/integration/targets/test_zabbix_item/tasks/main.yml new file mode 100644 index 000000000..0463b4455 --- /dev/null +++ b/tests/integration/targets/test_zabbix_item/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- block: + # - include_tasks: zabbix_item_setup.yml + + - include_tasks: zabbix_item_tests.yml + + # - include_tasks: zabbix_item_doc.yml + + # - include_tasks: zabbix_item_teardown.yml + + # always: + # - name: "Cleanup if test failed" diff --git a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml new file mode 100644 index 000000000..98f635608 --- /dev/null +++ b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml @@ -0,0 +1,10 @@ +--- +- name: "test: create item on host ExampleHostForHostInfoModule" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForHostInfoModule + key: ExampleItem + type: simple_check + state: present + value_type: text + delay: 1m \ No newline at end of file From af836e11ce803bc2bc018c052106971abcba153a Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 17 Apr 2024 09:28:24 +0000 Subject: [PATCH 02/21] added all parameters --- plugins/modules/zabbix_item.py | 572 +++++++++++++++++++++++++++++---- 1 file changed, 511 insertions(+), 61 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 8095d2534..2163c9822 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -24,41 +24,227 @@ def is_item_exist(self, item_name, host_name): result = self._zapi.item.get({"filter": {"name": item_name, "hostid": host_id}}) return result + def get_itemid_by_item_and_hostid(self, item_name, host_id): + return self._zapi.item.get({"filter": {"name": item_name, "hostid": host_id}}) + #check if host exists def check_host_exist(self, host_name): - result = self._zapi.host.get({"filter": {"name": host_name}}) + result = self._zapi.host.get({"filter": {"host": host_name}}) if not result: self._module.fail_json(msg="Host not found %s" % host_name) return True - def add_item(self, item_name, key, host_id, type, value_type, delay): #add more parameters + def get_host_interfaceid_by_host(self, interface, host_id): + if interface: + ip, port = interface.split(":") + parameters = {"output": "extend", "hostid": host_id, "filter": {"port": port}} + if re.search(r"\w", ip): + parameters["filter"]["dns"] = ip + else: + parameters["filter"]["ip"] = ip + return self._zapi.hostinterface.get(parameters)[0]["interfaceid"] + return "0" + + def construct_preprocessing(self, preprocessing): + preprocessing_type_types = {"custom_multiplier": 1, "right_trim": 2, "left_trim": 3, "trim": 4, "regex": 5, "bool_to_dec": 6, "oct_to_dec": 7, "hex_to_dec": 8, "simple_change": 9, "change_per_sec": 10, "xml_xpath": 11, "jsonpath": 12, "in_range": 13, "regex_match": 14, "regex_not_match": 15, "json_error_check": 16, "xml_error_check": 17, "regex_error_check": 18, "discard_unchanged": 19, "discard_unchanged_with_heartbeat": 20, "javascript": 21, "prometheus_pattern": 22, "prometheus_to_json": 23, "csv_to_json": 24, "replace": 25, "check_unsupported": 26, "xml_to_json": 27, "snmp_walk_value": 28, "snmp_walk_to_json": 29} + preprocessing_error_handler_types = {"zabbix": 0, "discard": 1, "custom_value": 2, "custom_message": 3} + + for rule in preprocessing: + if rule["type"] in list(preprocessing_type_types.keys()): + rule["type"] = preprocessing_type_types[rule["type"]] + else: + rule["type"] = int(rule["type"]) + + if rule["error_handler"] in list(preprocessing_error_handler_types.keys()): + rule["error_handler"] = preprocessing_error_handler_types[rule["error_handler"]] + else: + rule["error_handler"] = int(rule["error_handler"]) + + if rule["type"] in list(1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 28, 29): + if not rule["params"]: + self._module.fail_json(msg="Option 'params' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"]]) + + if rule["error_handler"] in list(2, 3): + if not rule["error_handler_params"]: + self._module.fail_json(msg="Option 'error_handler_params' required in combination with the preprocessing error handling type %s" % list(preprocessing_type_types.keys())[rule["error_handler_type"]]) + + return preprocessing + + def add_item(self, item_name, key, host_id, type, value_type, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, item_parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) - parameters = {"name": item_name, "key_": key, "hostid": host_id, "type": type, "value_type": value_type, "delay": delay} #add more parameters - #add conditional parameters - - item_list = self._zapi.item.create(parameters) - if len(item_list) >= 1: - return item_list["itemids"][0] + else: + parameters = {"name": item_name, "key_": key, "hostid": host_id, "type": type, "value_type": value_type, "delay": update_interval} #add more parameters + #add conditional parameters + if interfaceid is not None: + parameters["interfaceid"] = interfaceid + if url is not None: + parameters["url"] = url + if allow_traps is not None: + parameters["allow_traps"] = allow_traps + if authtype is not None: + parameters["authtype"] = authtype + if description is not None: + parameters["description"] = description + if follow_redirects is not None: + parameters["follow_redirects"] = follow_redirects + if headers is not None: + parameters["headers"] = headers + if history is not None: + parameters["history"] = history + if http_proxy is not None: + parameters["http_proxy"] = http_proxy + if inventory_link is not None: + parameters["inventory_link"] = inventory_link + if ipmi_sensor is not None: + parameters["ipmi_sensor"] = ipmi_sensor + if jmx_endpoint is not None: + parameters["jmx_endpoint"] = jmx_endpoint + if logtimefmt is not None: + parameters["logtimefmt"] = logtimefmt + if master_itemid is not None: + parameters["master_itemid"] = master_itemid + if params is not None: + parameters["params"] = params + if item_parameters is not None: + parameters["parameters"] = item_parameters + if password is not None: + parameters["password"] = password + if body_type is not None: + parameters["post_type"] = body_type + if body is not None: + parameters["posts"] = body + if privatekey is not None: + parameters["privatekey"] = privatekey + if url_query is not None: + parameters["query_fields"] = url_query + if http_method is not None: + parameters["request_method"] = http_method + if retrieve_mode is not None: + parameters["retrieve_mode"] = retrieve_mode + if snmp_oid is not None: + parameters["snmp_oid"] = snmp_oid + if ssl_cert_file is not None: + parameters["ssl_cert_file"] = ssl_cert_file + if ssl_key_file is not None: + parameters["ssl_key_file"] = ssl_key_file + if ssl_key_password is not None: + parameters["ssl_key_password"] = ssl_key_password + if status_codes is not None: + parameters["status_codes"] = status_codes + if timeout is not None: + parameters["timeout"] = timeout + if trapper_hosts is not None: + parameters["trapper_hosts"] = trapper_hosts + if trends is not None: + parameters["trends"] = trends + if units is not None: + parameters["units"] = units + if username is not None: + parameters["username"] = username + if verify_host is not None: + parameters["verify_host"] = verify_host + if verify_peer is not None: + parameters["verify_peer"] = verify_peer + if tags is not None: + parameters["tags"] = tags + if preprocessing is not None: + parameters["preprocessing"] = preprocessing + # raise Exception(parameters) + item_list = self._zapi.item.create(parameters) + if len(item_list["itemids"]) >= 1: + return item_list["itemids"][0] except Exception as e: self._module.fail_json(msg="Failed to create item %s: %s" % (item_name, e)) - def update_item(self, item_name, item_id, key, delay, description): #add more parameters + def update_item(self, item_name, item_id, key, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, item_parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) - - parameters = {"itemid": item_id} - #add conditional parameters - if description is not None: - parameters["description"] = description - if key is not None: - parameters["key_"] = key - if delay is not None: - parameters["delay"] = delay - - self._zapi.item.update(parameters) + else: + parameters = {"itemid": item_id} + if item_name is not None: + parameters["name"] = item_name + if key is not None: + parameters["key_"] = key + if update_interval is not None: + parameters["delay"] = update_interval + if interfaceid is not None: + parameters["interfaceid"] = interfaceid + if url is not None: + parameters["url"] = url + if allow_traps is not None: + parameters["allow_traps"] = allow_traps + if authtype is not None: + parameters["authtype"] = authtype + if description is not None: + parameters["description"] = description + if follow_redirects is not None: + parameters["follow_redirects"] = follow_redirects + if headers is not None: + parameters["headers"] = headers + if history is not None: + parameters["history"] = history + if http_proxy is not None: + parameters["http_proxy"] = http_proxy + if inventory_link is not None: + parameters["inventory_link"] = inventory_link + if ipmi_sensor is not None: + parameters["ipmi_sensor"] = ipmi_sensor + if jmx_endpoint is not None: + parameters["jmx_endpoint"] = jmx_endpoint + if logtimefmt is not None: + parameters["logtimefmt"] = logtimefmt + if master_itemid is not None: + parameters["master_itemid"] = master_itemid + if params is not None: + parameters["params"] = params + if item_parameters is not None: + parameters["parameters"] = item_parameters + if password is not None: + parameters["password"] = password + if body_type is not None: + parameters["post_type"] = body_type + if body is not None: + parameters["posts"] = body + if privatekey is not None: + parameters["privatekey"] = privatekey + if url_query is not None: + parameters["query_fields"] = url_query + if http_method is not None: + parameters["request_method"] = http_method + if retrieve_mode is not None: + parameters["retrieve_mode"] = retrieve_mode + if snmp_oid is not None: + parameters["snmp_oid"] = snmp_oid + if ssl_cert_file is not None: + parameters["ssl_cert_file"] = ssl_cert_file + if ssl_key_file is not None: + parameters["ssl_key_file"] = ssl_key_file + if ssl_key_password is not None: + parameters["ssl_key_password"] = ssl_key_password + if status_codes is not None: + parameters["status_codes"] = status_codes + if timeout is not None: + parameters["timeout"] = timeout + if trapper_hosts is not None: + parameters["trapper_hosts"] = trapper_hosts + if trends is not None: + parameters["trends"] = trends + if units is not None: + parameters["units"] = units + if username is not None: + parameters["username"] = username + if verify_host is not None: + parameters["verify_host"] = verify_host + if verify_peer is not None: + parameters["verify_peer"] = verify_peer + if tags is not None: + parameters["tags"] = tags + if preprocessing is not None: + parameters["preprocessing"] = preprocessing + self._zapi.item.update(parameters) except Exception as e: self._module.fail_json(msg="Failed to update item %s: %s" % (item_name, e)) @@ -70,20 +256,6 @@ def delete_item(self, item_id, item_name): except Exception as e: self._module.fail_json(msg="Failed to delete item %s: %s" % (item_name, e)) - def get_item_by_item_name(self, item_name): - params = { # add more parameters - "output": [ - "itemid" - ], - "filter": { - "name": [item_name] - } - } - - item_list = self._zapi.item.get(params) - if len(item_list) < 1: - self._module.fail_json(msg="Item not found: %s" % item_name) - def get_hostid_by_host_name(self, host_name): host_list = self._zapi.host.get({"output": "extend", "filter": {"host": [host_name]}}) if len(host_list) < 1: @@ -91,16 +263,88 @@ def get_hostid_by_host_name(self, host_name): else: return int(host_list[0]["hostid"]) - def check_all_properties(self, item_id, key, host_id, host_name, delay): + def check_all_properties(self, item_id, key, host_id, host_name, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): exist_item = self._zapi.item.get({"output": "extend", "filter": {"itemid": item_id}})[0] - exist_host = self.get_hostid_by_host_name(host_name) - if host_id != exist_host: + if host_id and host_id != int(exist_item["hostid"]): return True - - if key != exist_item["key_"]: + if key and key != exist_item["key_"]: + return True + if update_interval and update_interval != exist_item["delay"]: + return True + if interfaceid and interfaceid != exist_item["interfaceid"]: + return True + if url and url != exist_item["url"]: + return True + if allow_traps and allow_traps != exist_item["allow_traps"]: + return True + if authtype and authtype != exist_item["authtype"]: + return True + if description and description != exist_item["description"]: + return True + if follow_redirects and follow_redirects != exist_item["follow_redirects"]: + return True + if headers and headers != exist_item["headers"]: + return True + if history and history != exist_item["history"]: + return True + if http_proxy and http_proxy != exist_item["http_proxy"]: + return True + if inventory_link and inventory_link != exist_item["inventory_link"]: + return True + if ipmi_sensor and ipmi_sensor != exist_item["ipmi_sensor"]: + return True + if jmx_endpoint and jmx_endpoint != exist_item["jmx_endpoint"]: + return True + if logtimefmt and logtimefmt != exist_item["logtimefmt"]: + return True + if master_itemid and master_itemid != exist_item["master_itemid"]: + return True + if params and params != exist_item["params"]: + return True + if parameters and parameters != exist_item["parameters"]: + return True + if password and password != exist_item["password"]: + return True + if body_type and body_type != exist_item["post_type"]: + return True + if body and body != exist_item["posts"]: + return True + if privatekey and privatekey != exist_item["privatekey"]: return True - if delay != exist_item["delay"]: + if url_query and url_query != exist_item["query_fields"]: return True + if http_method and http_method != exist_item["request_method"]: + return True + if retrieve_mode and retrieve_mode != exist_item["retrieve_mode"]: + return True + if snmp_oid and snmp_oid != exist_item["snmp_oid"]: + return True + if ssl_cert_file and ssl_cert_file != exist_item["ssl_cert_file"]: + return True + if ssl_key_file and ssl_key_file != exist_item["ssl_key_file"]: + return True + if ssl_key_password and ssl_key_password != exist_item["ssl_key_password"]: + return True + if status_codes and status_codes != exist_item["status_codes"]: + return True + if timeout and timeout != exist_item["timeout"]: + return True + if trapper_hosts and trapper_hosts != exist_item["trapper_hosts"]: + return True + if trends and trends != exist_item["trends"]: + return True + if units and units != exist_item["units"]: + return True + if username and username != exist_item["username"]: + return True + if verify_host and verify_host != exist_item["verify_host"]: + return True + if verify_peer and verify_peer != exist_item["verify_peer"]: + return True + if tags and tags != exist_item["tags"]: + return True + if preprocessing and preprocessing != exist_item["preprocessing"]: + return True return False @@ -108,14 +352,127 @@ def main(): argument_spec = zabbix_utils.zabbix_common_argument_spec() argument_spec.update(dict( item_name=dict(type="str", required=True), - key=dict(type="str", required=True), - host_name=dict(type="str", required=True), + key=dict(type="str", required_if=[["state", 1, ["present"]]]), + host_name=dict(type="str", required_if=[["state", 1, ["present"]]]), state=dict(type="str", default="present", choices=["present", "absent"]), status=dict(type="str", default="enabled", choices=["enabled", "disabled"]), - type=dict(type="str", choices=["zabbix_agent", "1", "zabbix_trapper", "2", "simple_check", "3", "zabbix_internal", "4", "zabbix_agent_active", "5", "web_item", "6", "external_check", "7", "database_monitor", "8", "ipmi", "9", "ssh", "10", "telnet", "11", "calculated", "12", "jmx", "13", "snmp_trap", "14", "dependent", "15", "http", "16", "snmp_agent", "17", "script", "18"], required=True), + type=dict(type="str", choices=["zabbix_agent", "0", "zabbix_trapper", "2", "simple_check", "3", "zabbix_internal", "5", "zabbix_agent_active", "7", "web_item", "9", "external_check", "10", "database_monitor", "11", "ipmi", "12", "ssh", "13", "telnet", "14", "calculated", "15", "jmx", "16", "snmp_trap", "17", "dependent", "18", "http", "19", "snmp_agent", "20", "script", "21"], required_if=[["state", 1, ["present"]]]), + value_type=dict(type="str", choices=["float", "0", "character", "1", "log", "2", "unsigned", "3", "text", "4"], required_if=[["state", 1, ["present"]]]), + update_interval=dict(type="str", default="10s", required_if=[ + ["type", 3, ["simple_check"]], + ["type", 5, ["zabbix_internal"]], + ["type", 7, ["zabbix_agent_active"]], + ["type", 10, ["external_check"]], + ["type", 11, ["database_monitor"]], + ["type", 12, ["ipmi"]], + ["type", 13, ["ssh"]], + ["type", 14, ["telnet"]], + ["type", 15, ["calculated"]], + ["type", 16, ["jmx"]], + ["type", 19, ["http"]], + ["type", 20, ["snmp_agent"]], + ["type", 21, ["script"]] + ]), + interface=dict(type="str", required_if=[ + ["type", 0, ["zabbix_agent"]], + ["type", 12, ["ipmi"]], + ["type", 16, ["jmx"]], + ["type", 17, ["snmp_trap"]], + ["type", 20, ["snmp_agent"]], + ]), + url=dict(type="str", required_if=[ + ["type", 19, ["http"]] + ]), + allow_traps=dict(type="bool"), + authtype=dict(type="str", choices=["password", "0", "publickey", "1", "none", "0", "basic", "1", "ntlm", "2", "kerberos", "3"], default="none"), description=dict(type="str"), - value_type=dict(type="str", choices=["float", "0", "character", "1", "log", "2", "unsigned", "3", "text", "4"], required=True), - delay=dict(type="str", default="10s") + follow_redirects=dict(type="bool"), + headers=dict(type="dict", elements="dict"), + history=dict(type="str"), + http_proxy=dict(type="str"), + inventory_link=dict(type="str"), + ipmi_sensor=dict(type="str", required_if=[ + ["type", 12, ["ipmi"]], + ]), + jmx_endpoint=dict(type="str"), + logtimefmt=dict(type="str"), + master_item=dict(type="str", required_if=[ + ["type", 18, ["dependent"]], + ]), + output_format=dict(type="str", choices=["raw", "0", "json", "1"]), + params=dict(type="str", required_if=[ + ["type", 11, ["database_monitor"]], + ["type", 13, ["ssh"]], + ["type", 14, ["telnet"]], + ["type", 15, ["calculated"]], + ["type", 21, ["script"]] + ]), + parameters=dict(type="str"), + password=dict(type="str", no_log=True), + body_type=dict(type="str", choices=["raw", "0", "json", "2", "xml", "3"]), + body=dict(type="str", required_if=[ + ["body_type", 1, ["json"]], + ["body_type", 2, ["xml"]], + ]), + privatekey=dict(type="str", no_log=True, required_if=[ + ["auth_type", 1, ["publickey"]] + ]), + url_query=dict(type="dict", elements="dict"), + http_method=dict(type="str", choices=["GET", "0", "POST", "1", "PUT", "2", "HEAD", "3"]), + retrieve_mode=dict(type="str", choices=["body", "0", "headers", "1", "both", "2"]), + snmp_oid=dict(type="str", required_if=[ + ["type", 20, ["snmp_agent"]], + ]), + ssl_cert_file=dict(type="str", no_log=True), + ssl_key_file=dict(type="str", no_log=True), + ssl_key_password=dict(type="str", no_log=True), + status_codes=dict(type="list", elements="str", default=["200"]), + timeout=dict(type="str"), + trapper_hosts=dict(type="str"), + trends=dict(type="str"), + units=dict(type="str"), + username=dict(type="str", no_log=True, required_if=[ + ["type", 13, ["ssh"]], + ["type", 14, ["telnet"]], + ["type", 16, ["jmx"]], + ]), + verify_host=dict(type="bool"), + verify_peer=dict(type="bool"), + tags=dict(type="list", elements="dict", default=[], options=dict( + tag=dict(type="str", required=True), + value=dict(type="str", required=True) + )), + preprocessing=dict(type="list", elements="dict", default=[], options=dict( + type=dict(type="str", required=True, choices=["custom_multiplier", "1", "right_trim", "2", "left_trim", "3", "trim", "4", "regex", "5", "bool_to_dec", "6", "oct_to_dec", "7", "hex_to_dec", "8", "simple_change", "9", "change_per_sec", "10", "xml_xpath", "11", "jsonpath", "12", "in_range", "13", "regex_match", "14", "regex_not_match", "15", "json_error_check", "16", "xml_error_check", "17", "regex_error_check", "18", "discard_unchanged", "19", "discard_unchanged_with_heartbeat", "20", "javascript", "21", "prometheus_pattern", "22", "prometheus_to_json", "23", "csv_to_json", "24", "replace", "25", "check_unsupported", "26", "xml_to_json", "27", "snmp_walk_value", "28", "snmp_walk_to_json", "29" ]), + params=dict(type="str", required_if=[ + ["type", 1, ["custom_multiplier"]], + ["type", 2, ["right_trim"]], + ["type", 3, ["left_trim"]], + ["type", 4, ["trim"]], + ["type", 5, ["regex"]], + ["type", 11, ["xml_xpath"]], + ["type", 12, ["jsonpath"]], + ["type", 13, ["in_range"]], + ["type", 14, ["regex_match"]], + ["type", 15, ["regex_not_match"]], + ["type", 16, ["json_error_check"]], + ["type", 17, ["xml_error_check"]], + ["type", 18, ["regex_error_check"]], + ["type", 20, ["discard_unchanged_with_heartbeat"]], + ["type", 21, ["javascript"]], + ["type", 22, ["prometheus_pattern"]], + ["type", 23, ["prometheus_to_json"]], + ["type", 24, ["csv_to_json"]], + ["type", 25, ["replace"]], + ["type", 28, ["snmp_walk_value"]], + ["type", 29, ["snmp_walk_to_json"]] + ]), + error_handler=dict(type="str", required=True, default="0", choices=["zabbix", "0", "discard", "1", "custom_value", "2", "custom_message", "3"]), + error_handler_params=dict(type="str", required_if=[ + ["error_handler", 2, "custom_value"], + ["error_handler", 3, "custom_message"] + ]) + )) )) module = AnsibleModule( argument_spec=argument_spec, @@ -130,21 +487,53 @@ def main(): type = module.params["type"] description = module.params["description"] value_type = module.params["value_type"] - delay = module.params["delay"] + update_interval = module.params["update_interval"] + interface = module.params["interface"] + url = module.params["url"] + allow_traps = module.params["allow_traps"] + authtype = module.params["authtype"] + description = module.params["description"] + follow_redirects = module.params["follow_redirects"] + headers = module.params["headers"] + history = module.params["history"] + http_proxy = module.params["http_proxy"] + inventory_link = module.params["inventory_link"] + ipmi_sensor = module.params["ipmi_sensor"] + jmx_endpoint = module.params["jmx_endpoint"] + logtimefmt = module.params["logtimefmt"] + master_item = module.params["master_item"] + output_format = module.params["output_format"] + params = module.params["params"] + parameters = module.params["parameters"] + password = module.params["password"] + body_type = module.params["body_type"] + body = module.params["body"] + privatekey = module.params["privatekey"] + url_query = module.params["url_query"] + http_method = module.params["http_method"] + retrieve_mode = module.params["retrieve_mode"] + snmp_oid = module.params["snmp_oid"] + ssl_cert_file = module.params["ssl_cert_file"] + ssl_key_file = module.params["ssl_key_file"] + ssl_key_password = module.params["ssl_key_password"] + status_codes = module.params["status_codes"] + timeout = module.params["timeout"] + trapper_hosts = module.params["trapper_hosts"] + trends = module.params["trends"] + units = module.params["units"] + username = module.params["username"] + verify_host = module.params["verify_host"] + verify_peer = module.params["verify_peer"] + tags = module.params["tags"] + preprocessing = module.params["preprocessing"] status = 1 if status == "disabled" else 0 - type_types = {"zabbix_agent": 1, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 4, "zabbix_agent_active": 5, "web_item": 6, "external_check": 7, "database_monitor": 8, "ipmi": 9, "ssh": 10, "telnet": 11, "calculated": 12, "jmx": 13, "snmp_trap": 14, "dependent": 15, "http": 16, "snmp_agent": 17, "script": 18} - if type in list(type_types.keys()): - type_int = type_types[type] - - value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} - if value_type in list(value_type_types.keys()): - value_type_int = value_type_types[value_type] - item = Item(module) + preprocessing = item.construct_preprocessing(preprocessing) + # find host id host_id = "" if host_name is not None: @@ -154,9 +543,71 @@ def main(): else: module.fail_json(msg="host_name must not be empty.") + # get interface id + if interface: + interface = item.get_host_interfaceid_by_host(interface, host_id) + + # convert bools/choices to integers + if allow_traps: + allow_traps = 1 if allow_traps == True else 0 + if authtype: + authtype_types = {"password": 0, "publickey": 1, "none": 0, "basic": 1, "ntlm": 2, "kerberos": 3} + if authtype in list(authtype_types.keys()): + authtype = authtype_types[authtype] + else: + authtype = int(authtype) + if follow_redirects: + follow_redirects = 1 if follow_redirects == True else 0 + if output_format: + output_format_types = {"raw": 0, "json": 1} + if output_format in list(output_format_types.keys()): + output_format = output_format_types[output_format] + else: + output_format = int(output_format) + if body_type: + body_type_types = {"raw": 0, "json": 2, "xml": 3} + if body_type in list(body_type_types.keys()): + body_type = body_type_types[body_type] + else: + body_type = int(body_type) + if http_method: + http_method_types = {"GET": 0, "POST": 1, "PUT": 2, "HEAD": 3} + if http_method in list(http_method_types.keys()): + http_method = http_method_types[http_method] + else: + http_method = int(http_method) + if retrieve_mode: + retrieve_mode_types = {"body": 0, "headers": 1, "both": 2} + if retrieve_mode in list(retrieve_mode_types.keys()): + retrieve_mode = retrieve_mode_types[retrieve_mode] + else: + retrieve_mode = int(retrieve_mode) + if verify_host: + verify_host = 1 if verify_host == True else 0 + if verify_peer: + verify_peer = 1 if verify_peer == True else 0 + # convert list to comma-seperated string + if status_codes: + status_codes = ",".join(status_codes) + + if master_item: + master_item = item.get_itemid_by_item_and_hostid(master_item, host_id) + type_types = {"zabbix_agent": 0, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 5, "zabbix_agent_active": 7, "web_item": 9, "external_check": 10, "database_monitor": 11, "ipmi": 12, "ssh": 13, "telnet": 14, "calculated": 15, "jmx": 16, "snmp_trap": 17, "dependent": 18, "http": 19, "snmp_agent": 20, "script": 21} + value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} + + if state == "present": + if type in list(type_types.keys()): + type = type_types[type] + else: + type = int(type) + + if value_type in list(value_type_types.keys()): + value_type = value_type_types[value_type] + else: + value_type = int(value_type) + # check if item exist is_item_exist = item.is_item_exist(item_name, host_name) - if is_item_exist: item_id = is_item_exist[0]["itemid"] @@ -164,12 +615,11 @@ def main(): # remove item item.delete_item(item_id, item_name) module.exit_json(changed=True, result="Successfully deleted item %s" % item_name) - else: - - + else: # update item - if item.check_all_properties(item_id, key, host_id, host_name, delay): - item.update_item(item_name, item_id, key, delay, description) + if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + # update the item + item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully updated item %s on host %s" % (item_name, host_name)) else: @@ -184,7 +634,7 @@ def main(): module.fail_json(msg="Specify a host when creating item '%s'" % item_name) # create item - item_id = item.add_item(item_name, key, host_id, type_int, value_type_int, delay) + item_id = item.add_item(item_name, key, host_id, type, value_type, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully added item %s on host %s" % (item_name, host_name)) From b0996786ce4e6da536b61dc87625b47ea57a8baa Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 17 Apr 2024 12:08:53 +0000 Subject: [PATCH 03/21] renamed trapper_hosts to allowed_hosts and added publickey parameter --- plugins/modules/zabbix_item.py | 38 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 2163c9822..2cf593fd3 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -70,7 +70,7 @@ def construct_preprocessing(self, preprocessing): return preprocessing - def add_item(self, item_name, key, host_id, type, value_type, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, item_parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def add_item(self, item_name, key, host_id, type, value_type, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -117,6 +117,8 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i parameters["posts"] = body if privatekey is not None: parameters["privatekey"] = privatekey + if publickey is not None: + parameters["publickey"] = publickey if url_query is not None: parameters["query_fields"] = url_query if http_method is not None: @@ -135,8 +137,8 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i parameters["status_codes"] = status_codes if timeout is not None: parameters["timeout"] = timeout - if trapper_hosts is not None: - parameters["trapper_hosts"] = trapper_hosts + if allowed_hosts is not None: + parameters["trapper_hosts"] = allowed_hosts if trends is not None: parameters["trends"] = trends if units is not None: @@ -158,7 +160,7 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i except Exception as e: self._module.fail_json(msg="Failed to create item %s: %s" % (item_name, e)) - def update_item(self, item_name, item_id, key, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, item_parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def update_item(self, item_name, item_id, key, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -210,6 +212,8 @@ def update_item(self, item_name, item_id, key, update_interval, interfaceid, url parameters["posts"] = body if privatekey is not None: parameters["privatekey"] = privatekey + if publickey is not None: + parameters["publickey"] = publickey if url_query is not None: parameters["query_fields"] = url_query if http_method is not None: @@ -228,8 +232,8 @@ def update_item(self, item_name, item_id, key, update_interval, interfaceid, url parameters["status_codes"] = status_codes if timeout is not None: parameters["timeout"] = timeout - if trapper_hosts is not None: - parameters["trapper_hosts"] = trapper_hosts + if allowed_hosts is not None: + parameters["trapper_hosts"] = allowed_hosts if trends is not None: parameters["trends"] = trends if units is not None: @@ -263,7 +267,7 @@ def get_hostid_by_host_name(self, host_name): else: return int(host_list[0]["hostid"]) - def check_all_properties(self, item_id, key, host_id, host_name, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def check_all_properties(self, item_id, key, host_id, host_name, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): exist_item = self._zapi.item.get({"output": "extend", "filter": {"itemid": item_id}})[0] if host_id and host_id != int(exist_item["hostid"]): return True @@ -311,6 +315,8 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if privatekey and privatekey != exist_item["privatekey"]: return True + if publickey and publickey != exist_item["publickey"]: + return True if url_query and url_query != exist_item["query_fields"]: return True if http_method and http_method != exist_item["request_method"]: @@ -329,7 +335,7 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if timeout and timeout != exist_item["timeout"]: return True - if trapper_hosts and trapper_hosts != exist_item["trapper_hosts"]: + if allowed_hosts and allowed_hosts != exist_item["trapper_hosts"]: return True if trends and trends != exist_item["trends"]: return True @@ -417,7 +423,10 @@ def main(): privatekey=dict(type="str", no_log=True, required_if=[ ["auth_type", 1, ["publickey"]] ]), - url_query=dict(type="dict", elements="dict"), + publickey=dict(type="str", no_log=True, required_if=[ + ["auth_type", 1, ["publickey"]] + ]), + url_query=dict(type="dict"), http_method=dict(type="str", choices=["GET", "0", "POST", "1", "PUT", "2", "HEAD", "3"]), retrieve_mode=dict(type="str", choices=["body", "0", "headers", "1", "both", "2"]), snmp_oid=dict(type="str", required_if=[ @@ -428,7 +437,7 @@ def main(): ssl_key_password=dict(type="str", no_log=True), status_codes=dict(type="list", elements="str", default=["200"]), timeout=dict(type="str"), - trapper_hosts=dict(type="str"), + allowed_hosts=dict(type="str"), trends=dict(type="str"), units=dict(type="str"), username=dict(type="str", no_log=True, required_if=[ @@ -509,6 +518,7 @@ def main(): body_type = module.params["body_type"] body = module.params["body"] privatekey = module.params["privatekey"] + publickey = module.params["publickey"] url_query = module.params["url_query"] http_method = module.params["http_method"] retrieve_mode = module.params["retrieve_mode"] @@ -518,7 +528,7 @@ def main(): ssl_key_password = module.params["ssl_key_password"] status_codes = module.params["status_codes"] timeout = module.params["timeout"] - trapper_hosts = module.params["trapper_hosts"] + allowed_hosts = module.params["allowed_hosts"] trends = module.params["trends"] units = module.params["units"] username = module.params["username"] @@ -617,9 +627,9 @@ def main(): module.exit_json(changed=True, result="Successfully deleted item %s" % item_name) else: # update item - if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): # update the item - item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) + item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully updated item %s on host %s" % (item_name, host_name)) else: @@ -634,7 +644,7 @@ def main(): module.fail_json(msg="Specify a host when creating item '%s'" % item_name) # create item - item_id = item.add_item(item_name, key, host_id, type, value_type, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, trapper_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) + item_id = item.add_item(item_name, key, host_id, type, value_type, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully added item %s on host %s" % (item_name, host_name)) From 494eda29843e5b8dceea6aac7ecac6354895c682 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 17 Apr 2024 12:09:44 +0000 Subject: [PATCH 04/21] fixed initial errors --- plugins/modules/zabbix_item.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 2cf593fd3..55c732178 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -34,15 +34,19 @@ def check_host_exist(self, host_name): self._module.fail_json(msg="Host not found %s" % host_name) return True - def get_host_interfaceid_by_host(self, interface, host_id): + def get_host_interfaceid_by_host(self, interface, host_id, host_name): if interface: ip, port = interface.split(":") parameters = {"output": "extend", "hostid": host_id, "filter": {"port": port}} - if re.search(r"\w", ip): + if re.search(r"[a-zA-Z]", ip): parameters["filter"]["dns"] = ip else: parameters["filter"]["ip"] = ip - return self._zapi.hostinterface.get(parameters)[0]["interfaceid"] + result = self._zapi.hostinterface.get(parameters) + if len(result) > 0: + return result[0]["interfaceid"] + else: + self._module.fail_json(msg="Host interface %s not found on host %s" % (interface, host_name)) return "0" def construct_preprocessing(self, preprocessing): @@ -393,7 +397,7 @@ def main(): authtype=dict(type="str", choices=["password", "0", "publickey", "1", "none", "0", "basic", "1", "ntlm", "2", "kerberos", "3"], default="none"), description=dict(type="str"), follow_redirects=dict(type="bool"), - headers=dict(type="dict", elements="dict"), + headers=dict(type="dict"), history=dict(type="str"), http_proxy=dict(type="str"), inventory_link=dict(type="str"), @@ -413,7 +417,7 @@ def main(): ["type", 15, ["calculated"]], ["type", 21, ["script"]] ]), - parameters=dict(type="str"), + parameters=dict(type="dict"), password=dict(type="str", no_log=True), body_type=dict(type="str", choices=["raw", "0", "json", "2", "xml", "3"]), body=dict(type="str", required_if=[ @@ -555,7 +559,7 @@ def main(): # get interface id if interface: - interface = item.get_host_interfaceid_by_host(interface, host_id) + interface = item.get_host_interfaceid_by_host(interface, host_id, host_name) # convert bools/choices to integers if allow_traps: @@ -600,8 +604,20 @@ def main(): if status_codes: status_codes = ",".join(status_codes) + if url_query: + array = [] + for q in url_query: + array.append({q: url_query[q]}) + url_query = array + if parameters: + array = [] + for p in parameters: + array.append({"name": p, "value": parameters[p]}) + parameters = array + + if master_item: - master_item = item.get_itemid_by_item_and_hostid(master_item, host_id) + master_item = item.get_itemid_by_item_and_hostid(master_item, host_id)[0]["itemid"] type_types = {"zabbix_agent": 0, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 5, "zabbix_agent_active": 7, "web_item": 9, "external_check": 10, "database_monitor": 11, "ipmi": 12, "ssh": 13, "telnet": 14, "calculated": 15, "jmx": 16, "snmp_trap": 17, "dependent": 18, "http": 19, "snmp_agent": 20, "script": 21} value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} From dc6a219fdf37cb828814d15e733ef91b2ebc1b30 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 17 Apr 2024 12:17:44 +0000 Subject: [PATCH 05/21] delay set to 0 when using specific types --- plugins/modules/zabbix_item.py | 35 ++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 55c732178..5adab8b95 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -548,6 +548,21 @@ def main(): preprocessing = item.construct_preprocessing(preprocessing) + type_types = {"zabbix_agent": 0, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 5, "zabbix_agent_active": 7, "web_item": 9, "external_check": 10, "database_monitor": 11, "ipmi": 12, "ssh": 13, "telnet": 14, "calculated": 15, "jmx": 16, "snmp_trap": 17, "dependent": 18, "http": 19, "snmp_agent": 20, "script": 21} + value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} + + if state == "present": + if type in list(type_types.keys()): + type = type_types[type] + else: + type = int(type) + + if value_type in list(value_type_types.keys()): + value_type = value_type_types[value_type] + else: + value_type = int(value_type) + + # find host id host_id = "" if host_name is not None: @@ -600,10 +615,12 @@ def main(): verify_host = 1 if verify_host == True else 0 if verify_peer: verify_peer = 1 if verify_peer == True else 0 + # convert list to comma-seperated string if status_codes: status_codes = ",".join(status_codes) - + + # convert to compatible object types if url_query: array = [] for q in url_query: @@ -615,22 +632,12 @@ def main(): array.append({"name": p, "value": parameters[p]}) parameters = array + # conditional parameter filtering + if type in list(2, 17, 18): + update_interval = "0" if master_item: master_item = item.get_itemid_by_item_and_hostid(master_item, host_id)[0]["itemid"] - type_types = {"zabbix_agent": 0, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 5, "zabbix_agent_active": 7, "web_item": 9, "external_check": 10, "database_monitor": 11, "ipmi": 12, "ssh": 13, "telnet": 14, "calculated": 15, "jmx": 16, "snmp_trap": 17, "dependent": 18, "http": 19, "snmp_agent": 20, "script": 21} - value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} - - if state == "present": - if type in list(type_types.keys()): - type = type_types[type] - else: - type = int(type) - - if value_type in list(value_type_types.keys()): - value_type = value_type_types[value_type] - else: - value_type = int(value_type) # check if item exist is_item_exist = item.is_item_exist(item_name, host_name) From 4cd65623e090de1957de3e2fd94abb045ea7c482 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 17 Apr 2024 14:17:42 +0000 Subject: [PATCH 06/21] forgot list brackets --- plugins/modules/zabbix_item.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 5adab8b95..991436c71 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -64,11 +64,11 @@ def construct_preprocessing(self, preprocessing): else: rule["error_handler"] = int(rule["error_handler"]) - if rule["type"] in list(1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 28, 29): + if rule["type"] in list([1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 28, 29]): if not rule["params"]: self._module.fail_json(msg="Option 'params' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"]]) - if rule["error_handler"] in list(2, 3): + if rule["error_handler"] in list([2, 3]): if not rule["error_handler_params"]: self._module.fail_json(msg="Option 'error_handler_params' required in combination with the preprocessing error handling type %s" % list(preprocessing_type_types.keys())[rule["error_handler_type"]]) @@ -633,7 +633,7 @@ def main(): parameters = array # conditional parameter filtering - if type in list(2, 17, 18): + if type in list([2, 17, 18]): update_interval = "0" if master_item: From 5cccf16ac62ae180c5c2701a9bc9e196be908516 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 17 Apr 2024 14:18:15 +0000 Subject: [PATCH 07/21] split up parameters --- plugins/modules/zabbix_item.py | 64 +++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 991436c71..47ff1e6e8 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -74,7 +74,7 @@ def construct_preprocessing(self, preprocessing): return preprocessing - def add_item(self, item_name, key, host_id, type, value_type, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def add_item(self, item_name, key, host_id, type, value_type, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -93,6 +93,8 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i parameters["description"] = description if follow_redirects is not None: parameters["follow_redirects"] = follow_redirects + if formula is not None: + parameters["params"] = formula if headers is not None: parameters["headers"] = headers if history is not None: @@ -109,8 +111,8 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i parameters["logtimefmt"] = logtimefmt if master_itemid is not None: parameters["master_itemid"] = master_itemid - if params is not None: - parameters["params"] = params + if script is not None: + parameters["params"] = script if item_parameters is not None: parameters["parameters"] = item_parameters if password is not None: @@ -131,6 +133,8 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i parameters["retrieve_mode"] = retrieve_mode if snmp_oid is not None: parameters["snmp_oid"] = snmp_oid + if db_query is not None: + parameters["params"] = db_query if ssl_cert_file is not None: parameters["ssl_cert_file"] = ssl_cert_file if ssl_key_file is not None: @@ -164,7 +168,7 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i except Exception as e: self._module.fail_json(msg="Failed to create item %s: %s" % (item_name, e)) - def update_item(self, item_name, item_id, key, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def update_item(self, item_name, item_id, key, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -188,6 +192,8 @@ def update_item(self, item_name, item_id, key, update_interval, interfaceid, url parameters["description"] = description if follow_redirects is not None: parameters["follow_redirects"] = follow_redirects + if formula is not None: + parameters["params"] = formula if headers is not None: parameters["headers"] = headers if history is not None: @@ -204,8 +210,8 @@ def update_item(self, item_name, item_id, key, update_interval, interfaceid, url parameters["logtimefmt"] = logtimefmt if master_itemid is not None: parameters["master_itemid"] = master_itemid - if params is not None: - parameters["params"] = params + if script is not None: + parameters["params"] = script if item_parameters is not None: parameters["parameters"] = item_parameters if password is not None: @@ -226,6 +232,8 @@ def update_item(self, item_name, item_id, key, update_interval, interfaceid, url parameters["retrieve_mode"] = retrieve_mode if snmp_oid is not None: parameters["snmp_oid"] = snmp_oid + if db_query is not None: + parameters["params"] = db_query if ssl_cert_file is not None: parameters["ssl_cert_file"] = ssl_cert_file if ssl_key_file is not None: @@ -271,7 +279,7 @@ def get_hostid_by_host_name(self, host_name): else: return int(host_list[0]["hostid"]) - def check_all_properties(self, item_id, key, host_id, host_name, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, params, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def check_all_properties(self, item_id, key, host_id, host_name, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): exist_item = self._zapi.item.get({"output": "extend", "filter": {"itemid": item_id}})[0] if host_id and host_id != int(exist_item["hostid"]): return True @@ -291,6 +299,8 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if follow_redirects and follow_redirects != exist_item["follow_redirects"]: return True + if formula and formula != exist_item["params"]: + return True if headers and headers != exist_item["headers"]: return True if history and history != exist_item["history"]: @@ -307,7 +317,7 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if master_itemid and master_itemid != exist_item["master_itemid"]: return True - if params and params != exist_item["params"]: + if script and script != exist_item["params"]: return True if parameters and parameters != exist_item["parameters"]: return True @@ -329,6 +339,8 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if snmp_oid and snmp_oid != exist_item["snmp_oid"]: return True + if db_query and db_query != exist_item["params"]: + return True if ssl_cert_file and ssl_cert_file != exist_item["ssl_cert_file"]: return True if ssl_key_file and ssl_key_file != exist_item["ssl_key_file"]: @@ -394,9 +406,12 @@ def main(): ["type", 19, ["http"]] ]), allow_traps=dict(type="bool"), - authtype=dict(type="str", choices=["password", "0", "publickey", "1", "none", "0", "basic", "1", "ntlm", "2", "kerberos", "3"], default="none"), + authtype=dict(type="str", choices=["password", "0", "publickey", "1", "none", "0", "basic", "1", "ntlm", "2", "kerberos", "3"]), description=dict(type="str"), follow_redirects=dict(type="bool"), + formula=dict(type="str", required_if=[ + ["type", 15, ["calculated"]], + ]), headers=dict(type="dict"), history=dict(type="str"), http_proxy=dict(type="str"), @@ -410,13 +425,6 @@ def main(): ["type", 18, ["dependent"]], ]), output_format=dict(type="str", choices=["raw", "0", "json", "1"]), - params=dict(type="str", required_if=[ - ["type", 11, ["database_monitor"]], - ["type", 13, ["ssh"]], - ["type", 14, ["telnet"]], - ["type", 15, ["calculated"]], - ["type", 21, ["script"]] - ]), parameters=dict(type="dict"), password=dict(type="str", no_log=True), body_type=dict(type="str", choices=["raw", "0", "json", "2", "xml", "3"]), @@ -436,6 +444,14 @@ def main(): snmp_oid=dict(type="str", required_if=[ ["type", 20, ["snmp_agent"]], ]), + script=dict(type="str", required_if=[ + ["type", 21, ["script"]], + ["type", 13, ["ssh"]], + ["type", 14, ["telnet"]] + ]), + db_query=dict(type="str", required_if=[ + ["type", 11, ["database_monitor"]] + ]), ssl_cert_file=dict(type="str", no_log=True), ssl_key_file=dict(type="str", no_log=True), ssl_key_password=dict(type="str", no_log=True), @@ -480,7 +496,7 @@ def main(): ["type", 28, ["snmp_walk_value"]], ["type", 29, ["snmp_walk_to_json"]] ]), - error_handler=dict(type="str", required=True, default="0", choices=["zabbix", "0", "discard", "1", "custom_value", "2", "custom_message", "3"]), + error_handler=dict(type="str", default="0", choices=["zabbix", "0", "discard", "1", "custom_value", "2", "custom_message", "3"]), error_handler_params=dict(type="str", required_if=[ ["error_handler", 2, "custom_value"], ["error_handler", 3, "custom_message"] @@ -507,6 +523,7 @@ def main(): authtype = module.params["authtype"] description = module.params["description"] follow_redirects = module.params["follow_redirects"] + formula = module.params["formula"] headers = module.params["headers"] history = module.params["history"] http_proxy = module.params["http_proxy"] @@ -516,7 +533,8 @@ def main(): logtimefmt = module.params["logtimefmt"] master_item = module.params["master_item"] output_format = module.params["output_format"] - params = module.params["params"] + script = module.params["script"] + db_query = module.params["db_query"] parameters = module.params["parameters"] password = module.params["password"] body_type = module.params["body_type"] @@ -635,6 +653,10 @@ def main(): # conditional parameter filtering if type in list([2, 17, 18]): update_interval = "0" + if type == 13 and authtype is None: + authtype = 0 + if type == 19 and authtype is None: + authtype = 0 if master_item: master_item = item.get_itemid_by_item_and_hostid(master_item, host_id)[0]["itemid"] @@ -650,9 +672,9 @@ def main(): module.exit_json(changed=True, result="Successfully deleted item %s" % item_name) else: # update item - if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): # update the item - item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) + item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully updated item %s on host %s" % (item_name, host_name)) else: @@ -667,7 +689,7 @@ def main(): module.fail_json(msg="Specify a host when creating item '%s'" % item_name) # create item - item_id = item.add_item(item_name, key, host_id, type, value_type, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, params, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) + item_id = item.add_item(item_name, key, host_id, type, value_type, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully added item %s on host %s" % (item_name, host_name)) From ff3456a56e1a2ee0e419217fd4886a85e0c790ab Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Thu, 18 Apr 2024 06:15:11 +0000 Subject: [PATCH 08/21] fixed preprocessing types --- plugins/modules/zabbix_item.py | 36 +++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 47ff1e6e8..940bf2390 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -67,10 +67,17 @@ def construct_preprocessing(self, preprocessing): if rule["type"] in list([1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 28, 29]): if not rule["params"]: self._module.fail_json(msg="Option 'params' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"]]) - + + if rule["type"] in list([1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,22,23,24,26,27,28,29]): + if not rule["error_handler"]: + self._module.fail_json(msg="Option 'error_handler' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"]]) + else: + rule["error_handler"] = "0" + rule["error_handler_params"] = "" + if rule["error_handler"] in list([2, 3]): if not rule["error_handler_params"]: - self._module.fail_json(msg="Option 'error_handler_params' required in combination with the preprocessing error handling type %s" % list(preprocessing_type_types.keys())[rule["error_handler_type"]]) + self._module.fail_json(msg="Option 'error_handler_params' required in combination with the preprocessing error handling type %s" % list(preprocessing_error_handler_types.keys())[rule["error_handler_type"]]) return preprocessing @@ -496,7 +503,30 @@ def main(): ["type", 28, ["snmp_walk_value"]], ["type", 29, ["snmp_walk_to_json"]] ]), - error_handler=dict(type="str", default="0", choices=["zabbix", "0", "discard", "1", "custom_value", "2", "custom_message", "3"]), + error_handler=dict(type="str", choices=["zabbix", "0", "discard", "1", "custom_value", "2", "custom_message", "3"], required_if=[ + ["type", 1, ["custom_multiplier"]], + ["type", 5, ["regex"]], + ["type", 6, ["bool_to_dec"]], + ["type", 7, ["oct_to_dec"]], + ["type", 8, ["hex_to_dec"]], + ["type", 9, ["simple_change"]], + ["type", 10, ["change_per_sec"]], + ["type", 11, ["xml_xpath"]], + ["type", 12, ["jsonpath"]], + ["type", 13, ["in_range"]], + ["type", 14, ["regex_match"]], + ["type", 15, ["regex_not_match"]], + ["type", 16, ["json_error_check"]], + ["type", 17, ["xml_error_check"]], + ["type", 18, ["regex_error_check"]], + ["type", 22, ["prometheus_pattern"]], + ["type", 23, ["prometheus_to_json"]], + ["type", 24, ["csv_to_json"]], + ["type", 26, ["check_unsupported"]], + ["type", 27, ["xml_to_json"]], + ["type", 28, ["snmp_walk_value"]], + ["type", 29, ["snmp_walk_to_json"]] + ]), error_handler_params=dict(type="str", required_if=[ ["error_handler", 2, "custom_value"], ["error_handler", 3, "custom_message"] From 08a9927f021399bf844640a8d8f0b5d2e648dc4b Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Thu, 18 Apr 2024 13:21:05 +0000 Subject: [PATCH 09/21] added parameters and tweaked existing ones --- plugins/modules/zabbix_item.py | 102 +++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 940bf2390..5fe138f40 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -34,6 +34,13 @@ def check_host_exist(self, host_name): self._module.fail_json(msg="Host not found %s" % host_name) return True + def get_hostid_by_host_name(self, host_name): + host_list = self._zapi.host.get({"output": "extend", "filter": {"host": [host_name]}}) + if len(host_list) < 1: + self._module.fail_json(msg="Host not found: %s" % host_name) + else: + return int(host_list[0]["hostid"]) + def get_host_interfaceid_by_host(self, interface, host_id, host_name): if interface: ip, port = interface.split(":") @@ -47,7 +54,7 @@ def get_host_interfaceid_by_host(self, interface, host_id, host_name): return result[0]["interfaceid"] else: self._module.fail_json(msg="Host interface %s not found on host %s" % (interface, host_name)) - return "0" + return "0" def construct_preprocessing(self, preprocessing): preprocessing_type_types = {"custom_multiplier": 1, "right_trim": 2, "left_trim": 3, "trim": 4, "regex": 5, "bool_to_dec": 6, "oct_to_dec": 7, "hex_to_dec": 8, "simple_change": 9, "change_per_sec": 10, "xml_xpath": 11, "jsonpath": 12, "in_range": 13, "regex_match": 14, "regex_not_match": 15, "json_error_check": 16, "xml_error_check": 17, "regex_error_check": 18, "discard_unchanged": 19, "discard_unchanged_with_heartbeat": 20, "javascript": 21, "prometheus_pattern": 22, "prometheus_to_json": 23, "csv_to_json": 24, "replace": 25, "check_unsupported": 26, "xml_to_json": 27, "snmp_walk_value": 28, "snmp_walk_to_json": 29} @@ -58,12 +65,7 @@ def construct_preprocessing(self, preprocessing): rule["type"] = preprocessing_type_types[rule["type"]] else: rule["type"] = int(rule["type"]) - - if rule["error_handler"] in list(preprocessing_error_handler_types.keys()): - rule["error_handler"] = preprocessing_error_handler_types[rule["error_handler"]] - else: - rule["error_handler"] = int(rule["error_handler"]) - + if rule["type"] in list([1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 28, 29]): if not rule["params"]: self._module.fail_json(msg="Option 'params' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"]]) @@ -71,6 +73,11 @@ def construct_preprocessing(self, preprocessing): if rule["type"] in list([1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,22,23,24,26,27,28,29]): if not rule["error_handler"]: self._module.fail_json(msg="Option 'error_handler' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"]]) + else: + if rule["error_handler"] in list(preprocessing_error_handler_types.keys()): + rule["error_handler"] = preprocessing_error_handler_types[rule["error_handler"]] + else: + rule["error_handler"] = int(rule["error_handler"]) else: rule["error_handler"] = "0" rule["error_handler_params"] = "" @@ -81,7 +88,7 @@ def construct_preprocessing(self, preprocessing): return preprocessing - def add_item(self, item_name, key, host_id, type, value_type, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def add_item(self, item_name, key, host_id, type, value_type, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -98,6 +105,8 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i parameters["authtype"] = authtype if description is not None: parameters["description"] = description + if convert_json is not None: + parameters["output_format"] = convert_json if follow_redirects is not None: parameters["follow_redirects"] = follow_redirects if formula is not None: @@ -168,14 +177,13 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i parameters["tags"] = tags if preprocessing is not None: parameters["preprocessing"] = preprocessing - # raise Exception(parameters) item_list = self._zapi.item.create(parameters) if len(item_list["itemids"]) >= 1: return item_list["itemids"][0] except Exception as e: self._module.fail_json(msg="Failed to create item %s: %s" % (item_name, e)) - def update_item(self, item_name, item_id, key, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def update_item(self, item_name, item_id, key, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -195,6 +203,8 @@ def update_item(self, item_name, item_id, key, update_interval, interfaceid, url parameters["allow_traps"] = allow_traps if authtype is not None: parameters["authtype"] = authtype + if convert_json is not None: + parameters["output_format"] = convert_json if description is not None: parameters["description"] = description if follow_redirects is not None: @@ -266,7 +276,7 @@ def update_item(self, item_name, item_id, key, update_interval, interfaceid, url if tags is not None: parameters["tags"] = tags if preprocessing is not None: - parameters["preprocessing"] = preprocessing + parameters["preprocessing"] = preprocessing self._zapi.item.update(parameters) except Exception as e: self._module.fail_json(msg="Failed to update item %s: %s" % (item_name, e)) @@ -279,15 +289,8 @@ def delete_item(self, item_id, item_name): except Exception as e: self._module.fail_json(msg="Failed to delete item %s: %s" % (item_name, e)) - def get_hostid_by_host_name(self, host_name): - host_list = self._zapi.host.get({"output": "extend", "filter": {"host": [host_name]}}) - if len(host_list) < 1: - self._module.fail_json(msg="Host not found: %s" % host_name) - else: - return int(host_list[0]["hostid"]) - - def check_all_properties(self, item_id, key, host_id, host_name, update_interval, interfaceid, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): - exist_item = self._zapi.item.get({"output": "extend", "filter": {"itemid": item_id}})[0] + def check_all_properties(self, item_id, key, host_id, host_name, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + exist_item = self._zapi.item.get({"output": "extend", "selectPreprocessing": "extend", "selectTags": "extend", "filter": {"itemid": item_id}})[0] if host_id and host_id != int(exist_item["hostid"]): return True if key and key != exist_item["key_"]: @@ -302,6 +305,8 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if authtype and authtype != exist_item["authtype"]: return True + if convert_json and convert_json != exist_item["output_format"]: + return True if description and description != exist_item["description"]: return True if follow_redirects and follow_redirects != exist_item["follow_redirects"]: @@ -422,7 +427,7 @@ def main(): headers=dict(type="dict"), history=dict(type="str"), http_proxy=dict(type="str"), - inventory_link=dict(type="str"), + inventory_link=dict(type="str", choices=["type", "1", "type_full", "2", "name", "3", "alias", "4", "os", "5", "os_full", "6", "os_short", "7", "serialno_a", "8", "serialno_b", "9", "tag", "10", "asset_tag", "11", "macaddress_a", "12", "macaddress_b", "13", "hardware", "14", "hardware_full", "15", "software", "16", "software_full", "17", "software_app_a", "18", "software_app_b", "19", "software_app_c", "20", "software_app_d", "21", "software_app_e", "22", "contact", "23", "location", "24", "location_lat", "25", "location_lon", "26", "notes", "27", "chassis", "28", "model", "29", "hw_arch", "30", "vendor", "31", "contract_number", "32", "installer_name", "33", "deployment_status", "34", "url_a", "35", "url_b", "36", "url_c", "37", "host_networks", "38", "host_netmask", "39", "host_router", "40", "oob_ip", "41", "oob_netmask", "42", "oob_router", "43", "date_hw_purchase", "44", "date_hw_install", "45", "date_hw_expiry", "46", "date_hw_decomm", "47", "site_address_a", "48", "site_address_b", "49", "site_address_c", "50", "site_city", "51", "site_state", "52", "site_country", "53", "site_zip", "54", "site_rack", "55", "site_notes", "56", "poc_1_name", "57", "poc_1_email", "58", "poc_1_phone_a", "59", "poc_1_phone_b", "60", "poc_1_cell", "61", "poc_1_screen", "62", "poc_1_notes", "63", "poc_2_name", "64", "poc_2_email", "65", "poc_2_phone_a", "66", "poc_2_phone_b", "67", "poc_2_cell", "68", "poc_2_screen", "69", "poc_2_notes", "70"]), ipmi_sensor=dict(type="str", required_if=[ ["type", 12, ["ipmi"]], ]), @@ -431,7 +436,7 @@ def main(): master_item=dict(type="str", required_if=[ ["type", 18, ["dependent"]], ]), - output_format=dict(type="str", choices=["raw", "0", "json", "1"]), + convert_json=dict(type="bool"), parameters=dict(type="dict"), password=dict(type="str", no_log=True), body_type=dict(type="str", choices=["raw", "0", "json", "2", "xml", "3"]), @@ -562,7 +567,7 @@ def main(): jmx_endpoint = module.params["jmx_endpoint"] logtimefmt = module.params["logtimefmt"] master_item = module.params["master_item"] - output_format = module.params["output_format"] + convert_json = module.params["convert_json"] script = module.params["script"] db_query = module.params["db_query"] parameters = module.params["parameters"] @@ -624,23 +629,41 @@ def main(): if interface: interface = item.get_host_interfaceid_by_host(interface, host_id, host_name) + if inventory_link: + if value_type in list([0, 1, 3, 4]): + inventory = {"type":1,"type_full":2,"name":3,"alias":4,"os":5,"os_full":6,"os_short":7,"serialno_a":8,"serialno_b":9,"tag":10,"asset_tag":11,"macaddress_a":12,"macaddress_b":13,"hardware":14,"hardware_full":15,"software":16,"software_full":17,"software_app_a":18,"software_app_b":19,"software_app_c":20,"software_app_d":21,"software_app_e":22,"contact":23,"location":24,"location_lat":25,"location_lon":26,"notes":27,"chassis":28,"model":29,"hw_arch":30,"vendor":31,"contract_number":32,"installer_name":33,"deployment_status":34,"url_a":35,"url_b":36,"url_c":37,"host_networks":38,"host_netmask":39,"host_router":40,"oob_ip":41,"oob_netmask":42,"oob_router":43,"date_hw_purchase":44,"date_hw_install":45,"date_hw_expiry":46,"date_hw_decomm":47,"site_address_a":48,"site_address_b":49,"site_address_c":50,"site_city":51,"site_state":52,"site_country":53,"site_zip":54,"site_rack":55,"site_notes":56,"poc_1_name":57,"poc_1_email":58,"poc_1_phone_a":59,"poc_1_phone_b":60,"poc_1_cell":61,"poc_1_screen":62,"poc_1_notes":63,"poc_2_name":64,"poc_2_email":65,"poc_2_phone_a":66,"poc_2_phone_b":67,"poc_2_cell":68,"poc_2_screen":69,"poc_2_notes":70} + if inventory_link in list(inventory): + inventory_link = inventory[inventory_link] + else: + inventory_link = int(inventory_link) + else: + inventoryid = "0" + # convert bools/choices to integers if allow_traps: allow_traps = 1 if allow_traps == True else 0 - if authtype: - authtype_types = {"password": 0, "publickey": 1, "none": 0, "basic": 1, "ntlm": 2, "kerberos": 3} - if authtype in list(authtype_types.keys()): - authtype = authtype_types[authtype] + if type == 13: + if authtype: + authtype_types = {"password": 0, "publickey": 1} + if authtype in list(authtype_types.keys()): + authtype = authtype_types[authtype] + else: + authtype = int(authtype) + else: + authtype = 0 + if type == 19: + if authtype: + authtype_types = {"password": 0, "publickey": 1, "none": 0, "basic": 1, "ntlm": 2, "kerberos": 3} + if authtype in list(authtype_types.keys()): + authtype = authtype_types[authtype] + else: + authtype = int(authtype) else: - authtype = int(authtype) + authtype = 0 if follow_redirects: follow_redirects = 1 if follow_redirects == True else 0 - if output_format: - output_format_types = {"raw": 0, "json": 1} - if output_format in list(output_format_types.keys()): - output_format = output_format_types[output_format] - else: - output_format = int(output_format) + if convert_json: + convert_json = 1 if convert_json == True else 0 if body_type: body_type_types = {"raw": 0, "json": 2, "xml": 3} if body_type in list(body_type_types.keys()): @@ -683,14 +706,9 @@ def main(): # conditional parameter filtering if type in list([2, 17, 18]): update_interval = "0" - if type == 13 and authtype is None: - authtype = 0 - if type == 19 and authtype is None: - authtype = 0 if master_item: master_item = item.get_itemid_by_item_and_hostid(master_item, host_id)[0]["itemid"] - # check if item exist is_item_exist = item.is_item_exist(item_name, host_name) if is_item_exist: @@ -702,9 +720,9 @@ def main(): module.exit_json(changed=True, result="Successfully deleted item %s" % item_name) else: # update item - if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): # update the item - item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) + item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully updated item %s on host %s" % (item_name, host_name)) else: @@ -719,7 +737,7 @@ def main(): module.fail_json(msg="Specify a host when creating item '%s'" % item_name) # create item - item_id = item.add_item(item_name, key, host_id, type, value_type, update_interval, interface, url, allow_traps, authtype, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) + item_id = item.add_item(item_name, key, host_id, type, value_type, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully added item %s on host %s" % (item_name, host_name)) From 046ed956f7d4157b96c89ecf390330026ee66a9d Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Thu, 18 Apr 2024 13:21:24 +0000 Subject: [PATCH 10/21] Added documentation --- plugins/modules/zabbix_item.py | 479 ++++++++++++++++++++++++++++++++- 1 file changed, 478 insertions(+), 1 deletion(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 5fe138f40..9e3440b0b 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -7,9 +7,486 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type +DOCUMENTATION = r""" +module: zabbix_item +short_description: Create/update/delete Zabbix items on hosts +description: + - This module allows you to create, modify and delete Zabbix item entries associated on hosts. +author: + - "Cove (@cove)" + - Tony Minfei Ding (!UNKNOWN) + - Harrison Gu (@harrisongu) + - Werner Dijkerman (@dj-wasabi) + - Eike Frost (@eikef) + - Lars van der Hooft (@ljvdhooft) +requirements: + - "python >= 3.9" +options: + item_name: + description: + - Name of the item in Zabbix. + type: str + required: true + key: + description: + - Key of the item in Zabbix. + - Key must be unique from other items. + - Required if I(state="present") + type: str + description: + description: + - Description of the item in Zabbix. + type: str + host_name: + description: + - Name of the host associated to the item. + - Required if I(state="present") + type: str + state: + description: + - State of the item. + - On C(present), it will create if item does not exist or update the item if the associated data is different. + - On C(absent), it will remove an item if it exists. + choices: ["present", "absent"] + default: "present" + type: str + status: + description: + - Monitoring status of the item. + choices: ["enabled", "disabled"] + default: "enabled" + type: str + type: + description: + - Type of the check performed. + - Numerical values are also accepted for type. + - Required if I(state="present") + - 0 = zabbix_agent + - 2 = zabbix_trapper + - 3 = simple_check + - 5 = zabbix_internal + - 7 = zabbix_agent_active + - 9 = web_item + - 10 = external_check + - 11 = database_monitor + - 12 = ipmi + - 13 = ssh + - 14 = telnet + - 15 = calculated + - 16 = jmx + - 17 = snmp_trap + - 18 = dependent + - 19 = http + - 20 = snmp_agent + - 21 = script + choices: ["zabbix_agent", "0", "zabbix_trapper", "2", "simple_check", "3", "zabbix_internal", "5", "zabbix_agent_active", "7", "web_item", "9", "external_check", "10", "database_monitor", "11", "ipmi", "12", "ssh", "13", "telnet", "14", "calculated", "15", "jmx", "16", "snmp_trap", "17", "dependent", "18", "http", "19", "snmp_agent", "20", "script", "21"] + type: str + value_type: + description: + - Type of the data stored during the check. + - Required if I(state="present") + - Numerical values are also accepted for value_type. + - 0 = float + - 1 = character + - 2 = log + - 3 = unsigned + - 4 = text + choices: ["float", "0", "character", "1", "log", "2", "unsigned", "3", "text", "4"] + type: str + update_interval: + description: + - The interval at which the item should perform checks. + - Required if I(state="present") + type: str + interface: + description: + - The host's interface specified for checks. + - Formatted in [ip/dns]:[port] + - Required if I(type="zabbix_agent") + - Required if I(type="ipmi") + - Required if I(type="jmx") + - Required if I(type="snmp_trap") + - Required if I(type="snmp_agent") + type: str + url: + description: + - The URL to perform checks at. + - Required if I(type="http") + type: str + allow_traps: + description: + - Allow to populate value similarly to the trapper item. + type: bool + authtype: + description: + - Authentication method + - If I(type="ssh"): 0 = password (default) + - If I(type="ssh"): 1 = publickey + - If I(type="http"): 0 = none (default) + - If I(type="http"): 1 = basic + - If I(type="http"): 2 = ntlm + - If I(type="http"): 3 = kerberos + type: str + choices: ["password", "0", "publickey", "1", "none", "0", "basic", "1", "ntlm", "2", "kerberos", "3"] + follow_redirects: + description: + - Follow response redirects while polling http data. + type: bool + formula: + description: + - Formula for the calculated items when . + type: str + headers: + description: + - Headers used for a HTTP request. + - Headers must be formatted as a dict. + type: dict + history: + description: + - Defines the time that history data is stored. + type: str + http_proxy: + description: + - Proxy connection used in a HTTP request. + type: str + inventory_link: + description: + - Defines the property used to populate the inventory field with the check result + - Supported if I(value_type="float") + - Supported if I(value_type="character") + - Supported if I(value_type="unsigned") + - Supported if I(value_type="text") + - 1 = type + - 2 = type_full + - 3 = name + - 4 = alias + - 5 = os + - 6 = os_full + - 7 = os_short + - 8 = serialno_a + - 9 = serialno_b + - 10 = tag + - 11 = asset_tag + - 12 = macaddress_a + - 13 = macaddress_b + - 14 = hardware + - 15 = hardware_full + - 16 = software + - 17 = software_full + - 18 = software_app_a + - 19 = software_app_b + - 20 = software_app_c + - 21 = software_app_d + - 22 = software_app_e + - 23 = contact + - 24 = location + - 25 = location_lat + - 26 = location_lon + - 27 = notes + - 28 = chassis + - 29 = model + - 30 = hw_arch + - 31 = vendor + - 32 = contract_number + - 33 = installer_name + - 34 = deployment_status + - 35 = url_a + - 36 = url_b + - 37 = url_c + - 38 = host_networks + - 39 = host_netmask + - 40 = host_router + - 41 = oob_ip + - 42 = oob_netmask + - 43 = oob_router + - 44 = date_hw_purchase + - 45 = date_hw_install + - 46 = date_hw_expiry + - 47 = date_hw_decomm + - 48 = site_address_a + - 49 = site_address_b + - 50 = site_address_c + - 51 = site_city + - 52 = site_state + - 53 = site_country + - 54 = site_zip + - 55 = site_rack + - 56 = site_notes + - 57 = poc_1_name + - 58 = poc_1_email + - 59 = poc_1_phone_a + - 60 = poc_1_phone_b + - 61 = poc_1_cell + - 62 = poc_1_screen + - 63 = poc_1_notes + - 64 = poc_2_name + - 65 = poc_2_email + - 66 = poc_2_phone_a + - 67 = poc_2_phone_b + - 68 = poc_2_cell + - 69 = poc_2_screen + - 70 = poc_2_notes + choices: ["type", "1", "type_full", "2", "name", "3", "alias", "4", "os", "5", "os_full", "6", "os_short", "7", "serialno_a", "8", "serialno_b", "9", "tag", "10", "asset_tag", "11", "macaddress_a", "12", "macaddress_b", "13", "hardware", "14", "hardware_full", "15", "software", "16", "software_full", "17", "software_app_a", "18", "software_app_b", "19", "software_app_c", "20", "software_app_d", "21", "software_app_e", "22", "contact", "23", "location", "24", "location_lat", "25", "location_lon", "26", "notes", "27", "chassis", "28", "model", "29", "hw_arch", "30", "vendor", "31", "contract_number", "32", "installer_name", "33", "deployment_status", "34", "url_a", "35", "url_b", "36", "url_c", "37", "host_networks", "38", "host_netmask", "39", "host_router", "40", "oob_ip", "41", "oob_netmask", "42", "oob_router", "43", "date_hw_purchase", "44", "date_hw_install", "45", "date_hw_expiry", "46", "date_hw_decomm", "47", "site_address_a", "48", "site_address_b", "49", "site_address_c", "50", "site_city", "51", "site_state", "52", "site_country", "53", "site_zip", "54", "site_rack", "55", "site_notes", "56", "poc_1_name", "57", "poc_1_email", "58", "poc_1_phone_a", "59", "poc_1_phone_b", "60", "poc_1_cell", "61", "poc_1_screen", "62", "poc_1_notes", "63", "poc_2_name", "64", "poc_2_email", "65", "poc_2_phone_a", "66", "poc_2_phone_b", "67", "poc_2_cell", "68", "poc_2_screen", "69", "poc_2_notes", "70"] + type: str + ipmi_sensor: + description: + - Defines IPMI sensor. + type: str + jmx_endpoint: + description: + - Defines custom connection string for JMX agent. + type: str + logtimefmt: + description: + - Defines the format of the time in log entries. + type: str + master_item: + description: + - Defines the master item used in dependent checks. + - Required if I(type="dependent") + type: str + convert_json: + description: + - Defines if the response body should be converted to a JSON object. + type: bool + script: + description: + - The script used when I(type="script"), I(type="ssh") or I(type="telnet"). + type: str + parameters: + description: + - Additional parameters for script type. + type: str + password: + description: + - Password used when I(type="jmx"), I(type="simple_check"), I(type="ssh"), I(type="telnet"), I(type="database_monitor"), I(type="http"). + - Required if I(type="jmx") and username is set. + type: str + body_type: + description: + - Defines the body type of the HTTP request. + - 0 = raw + - 1 = json + - 2 = xml + choices: ["raw", "0", "json", "2", "xml", "3"] + type: str + body: + description: + - Defines the body used for the HTTP request. + type: str + privatekey: + description: + - Defines the path to the private key file used for the SSH agent when using public key authentication. + - Required if I(type="ssh") and I(authtype="publickey") + type: str + publickey: + description: + - Defines the path to the public key file used for the SSH agent when using public key authentication. + - Required if I(type="ssh") and I(authtype="publickey") + type: str + url_query: + description: + - Defines the query parameters used for the HTTP request. + - Query entries must be formatted in object form (dict). + type: dict + http_method: + description: + - Defines the HTTP method used for the request. + - 0 = GET + - 1 = POST + - 2 = PUT + - 3 = HEAD + choices: ["GET", "0", "POST", "1", "PUT", "2", "HEAD", "3"] + type: str + retrieve_mode: + description: + - Defines if either the body, headers or both are processed in response of the HTTP request. + - 0 = body (default) + - 1 = headers + - 2 = both + choices: ["body", "0", "headers", "1", "both", "2"] + type: str + snmp_oid: + description: + - Defines the OID filtered on with the SMTP agent. + - Required if I(type="snmp_agent") + type: str + db_query: + description: + - Defines the query used for the database_monitor check. + - Required if I(type="database_monitor") + type: str + ssl_cert_file: + description: + - Defines the path of the public SSL key file used with the HTTP check. + type: str + ssl_key_file: + description: + - Defines the path of the private SSL key file used with the HTTP check. + type: str + ssl_key_password: + description: + - Defines the password of the SSL key file used with the HTTP check. + type: str + status_codes: + description: + - Defines the response status codes filtered on with the HTTP check. + - Entries must be formatted in list + type: list + timeout: + description: + - Defines the timeout for item polling. + type: str + allowed_hosts: + description: + - Allowed hosts. + type: str + trends: + description: + - Defines the time of how long data should be stored. + type: str + units: + description: + - Defines the unit of the check's value. + type: str + username: + description: + - Username for check authentication. + - Required if I(type="ssh") + - Required if I(type="telnet") + - Required if I(type="jmx") + type: str + verify_host: + description: + - Defines an extra check if the host's name matches the certificate. + type: bool + verify_peer: + description: + - Defines an extra check if the host's certificate is authentic. + type: bool + tags: + description: + - Defines tags used by Zabbix. + - Entries must be formatted as a list with objects that contain 'tag' and 'value' + type: list + elements: dict + suboptions: + tag: + description: + - The name of the tag + type: str + value: + description: + - The value of the tag + type: str + preprocessing: + description: + - Defines the Zabbix preprocessing rules used for the item. + - Entries must be formatted as a list with objects that contain 'type', + type: list + elements: dict + suboptions: + type: + description: + - The type of Zabbix preprocessing used. + - 1 = custom_multiplier + - 2 = right_trim + - 3 = left_trim + - 4 = trim + - 5 = regex + - 6 = bool_to_dec + - 7 = oct_to_dec + - 8 = hex_to_dec + - 9 = simple_change + - 10 = change_per_sec + - 11 = xml_xpath + - 12 = jsonpath + - 13 = in_range + - 14 = regex_match + - 15 = regex_not_match + - 16 = json_error_check + - 17 = xml_error_check + - 18 = regex_error_check + - 19 = discard_unchanged + - 20 = discard_unchanged_with_heartbeat + - 21 = javascript + - 22 = prometheus_pattern + - 23 = prometheus_to_json + - 24 = csv_to_json + - 25 = replace + - 26 = check_unsupported + - 27 = xml_to_json + - 28 = snmp_walk_value + - 29 = snmp_walk_to_json + choices: ["custom_multiplier", "1", "right_trim", "2", "left_trim", "3", "trim", "4", "regex", "5", "bool_to_dec", "6", "oct_to_dec", "7", "hex_to_dec", "8", "simple_change", "9", "change_per_sec", "10", "xml_xpath", "11", "jsonpath", "12", "in_range", "13", "regex_match", "14", "regex_not_match", "15", "json_error_check", "16", "xml_error_check", "17", "regex_error_check", "18", "discard_unchanged", "19", "discard_unchanged_with_heartbeat", "20", "javascript", "21", "prometheus_pattern", "22", "prometheus_to_json", "23", "csv_to_json", "24", "replace", "25", "check_unsupported", "26", "xml_to_json", "27", "snmp_walk_value", "28", "snmp_walk_to_json", "29"] + type: str + params: + description: + - Additional parameters depending on the type of preprocessing. + - Required if I(type="custom_multiplier") + - Required if I(type="right_trim") + - Required if I(type="left_trim") + - Required if I(type="trim") + - Required if I(type="regex") + - Required if I(type="xml_xpath") + - Required if I(type="jsonpath") + - Required if I(type="in_range") + - Required if I(type="regex_match") + - Required if I(type="regex_not_match") + - Required if I(type="json_error_check") + - Required if I(type="xml_error_check") + - Required if I(type="regex_error_check") + - Required if I(type="discard_unchanged_with_heartbeat") + - Required if I(type="javascript") + - Required if I(type="prometheus_pattern") + - Required if I(type="prometheus_to_json") + - Required if I(type="csv_to_json") + - Required if I(type="replace") + - Required if I(type="snmp_walk_value") + - Required if I(type="snmp_walk_to_jso") + type: str + error_handling: + description: + - Defines the preprocessing error handling. + - 0 = zabbix + - 1 = discard + - 2 = custom_value + - 3 = custom_message + - Required if I(type="custom_multiplier") + - Required if I(type="regex") + - Required if I(type="bool_to_dec") + - Required if I(type="oct_to_dec") + - Required if I(type="hex_to_dec") + - Required if I(type="simple_change") + - Required if I(type="change_per_sec") + - Required if I(type="xml_xpath") + - Required if I(type="jsonpath") + - Required if I(type="in_range") + - Required if I(type="regex_match") + - Required if I(type="regex_not_match") + - Required if I(type="json_error_check") + - Required if I(type="xml_error_check") + - Required if I(type="regex_error_check") + - Required if I(type="prometheus_pattern") + - Required if I(type="prometheus_to_json") + - Required if I(type="csv_to_json") + - Required if I(type="check_unsupported") + - Required if I(type="xml_to_json") + - Required if I(type="snmp_walk_value") + - Required if I(type="snmp_walk_to_json) + choices: ["zabbix", "0", "discard", "1", "custom_value", "2", "custom_message", "3"] + type: str + error_handling_params: + description: + - The parameters used when 'error_handling' is set to 'custom_value' or 'custom_message' + - Required if I(error_handling="custom_value") + - Required if I(error_handling="custom_message") + type: str -import copy +""" + +import copy, re from ansible.module_utils.basic import AnsibleModule From 6f337de281a7f80533d4e6a918de4c356ee1e394 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Tue, 23 Apr 2024 07:01:46 +0000 Subject: [PATCH 11/21] bugfixing --- plugins/modules/zabbix_item.py | 94 ++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 38 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 9e3440b0b..878590136 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -31,7 +31,6 @@ description: - Key of the item in Zabbix. - Key must be unique from other items. - - Required if I(state="present") type: str description: description: @@ -486,7 +485,7 @@ """ -import copy, re +import copy, re, json from ansible.module_utils.basic import AnsibleModule @@ -539,29 +538,33 @@ def construct_preprocessing(self, preprocessing): for rule in preprocessing: if rule["type"] in list(preprocessing_type_types.keys()): - rule["type"] = preprocessing_type_types[rule["type"]] + rule["type"] = str(preprocessing_type_types[rule["type"]]) else: - rule["type"] = int(rule["type"]) + rule["type"] = str(int(rule["type"])) - if rule["type"] in list([1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 28, 29]): + if int(rule["type"]) in list([1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 28, 29]): if not rule["params"]: - self._module.fail_json(msg="Option 'params' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"]]) + self._module.fail_json(msg="Option 'params' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"] + 1]) + else: + rule["params"] = "" - if rule["type"] in list([1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,22,23,24,26,27,28,29]): + if int(rule["type"]) in list([1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,22,23,24,26,27,28,29]): if not rule["error_handler"]: - self._module.fail_json(msg="Option 'error_handler' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[rule["type"]]) + self._module.fail_json(msg="Option 'error_handler' required in combination with the preprocessing type %s" % list(preprocessing_type_types.keys())[int(rule["type"])]) else: if rule["error_handler"] in list(preprocessing_error_handler_types.keys()): - rule["error_handler"] = preprocessing_error_handler_types[rule["error_handler"]] + rule["error_handler"] = str(preprocessing_error_handler_types[rule["error_handler"]]) else: - rule["error_handler"] = int(rule["error_handler"]) + rule["error_handler"] = str(int(rule["error_handler"])) else: rule["error_handler"] = "0" rule["error_handler_params"] = "" - if rule["error_handler"] in list([2, 3]): + if int(rule["error_handler"]) in list([2, 3]): if not rule["error_handler_params"]: self._module.fail_json(msg="Option 'error_handler_params' required in combination with the preprocessing error handling type %s" % list(preprocessing_error_handler_types.keys())[rule["error_handler_type"]]) + else: + rule["error_handler_params"] = "" return preprocessing @@ -774,19 +777,19 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if update_interval and update_interval != exist_item["delay"]: return True - if interfaceid and interfaceid != exist_item["interfaceid"]: + if interfaceid and int(interfaceid) != int(exist_item["interfaceid"]): return True if url and url != exist_item["url"]: return True - if allow_traps and allow_traps != exist_item["allow_traps"]: + if allow_traps and int(allow_traps) != int(exist_item["allow_traps"]): return True - if authtype and authtype != exist_item["authtype"]: + if authtype and int(authtype) != int(exist_item["authtype"]): return True - if convert_json and convert_json != exist_item["output_format"]: + if convert_json and int(convert_json) != int(exist_item["output_format"]): return True if description and description != exist_item["description"]: return True - if follow_redirects and follow_redirects != exist_item["follow_redirects"]: + if follow_redirects and int(follow_redirects) != int(exist_item["follow_redirects"]): return True if formula and formula != exist_item["params"]: return True @@ -796,7 +799,7 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if http_proxy and http_proxy != exist_item["http_proxy"]: return True - if inventory_link and inventory_link != exist_item["inventory_link"]: + if inventory_link and int(inventory_link) != int(exist_item["inventory_link"]): return True if ipmi_sensor and ipmi_sensor != exist_item["ipmi_sensor"]: return True @@ -804,7 +807,7 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if logtimefmt and logtimefmt != exist_item["logtimefmt"]: return True - if master_itemid and master_itemid != exist_item["master_itemid"]: + if master_itemid and int(master_itemid) != int(exist_item["master_itemid"]): return True if script and script != exist_item["params"]: return True @@ -812,7 +815,7 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if password and password != exist_item["password"]: return True - if body_type and body_type != exist_item["post_type"]: + if body_type and int(body_type) != int(exist_item["post_type"]): return True if body and body != exist_item["posts"]: return True @@ -822,9 +825,9 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if url_query and url_query != exist_item["query_fields"]: return True - if http_method and http_method != exist_item["request_method"]: + if http_method and int(http_method) != int(exist_item["request_method"]): return True - if retrieve_mode and retrieve_mode != exist_item["retrieve_mode"]: + if retrieve_mode and int(retrieve_mode) != int(exist_item["retrieve_mode"]): return True if snmp_oid and snmp_oid != exist_item["snmp_oid"]: return True @@ -848,14 +851,14 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if username and username != exist_item["username"]: return True - if verify_host and verify_host != exist_item["verify_host"]: + if verify_host and int(verify_host) != int(exist_item["verify_host"]): return True - if verify_peer and verify_peer != exist_item["verify_peer"]: + if verify_peer and int(verify_peer) != int(exist_item["verify_peer"]): return True if tags and tags != exist_item["tags"]: return True if preprocessing and preprocessing != exist_item["preprocessing"]: - return True + return True return False @@ -1076,23 +1079,35 @@ def main(): item = Item(module) + # check if item exist + is_item_exist = item.is_item_exist(item_name, host_name) + preprocessing = item.construct_preprocessing(preprocessing) - type_types = {"zabbix_agent": 0, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 5, "zabbix_agent_active": 7, "web_item": 9, "external_check": 10, "database_monitor": 11, "ipmi": 12, "ssh": 13, "telnet": 14, "calculated": 15, "jmx": 16, "snmp_trap": 17, "dependent": 18, "http": 19, "snmp_agent": 20, "script": 21} - value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} if state == "present": - if type in list(type_types.keys()): - type = type_types[type] - else: - type = int(type) - - if value_type in list(value_type_types.keys()): - value_type = value_type_types[value_type] - else: - value_type = int(value_type) + if not is_item_exist: + # check mandatory parameters + if not item_name: + module.fail_json(msg="Item name must be set.") + if not host_name: + module.fail_json(msg="Host name must be set.") + if type is None: + module.fail_json(msg="Type cannot be empty.") + + type_types = {"zabbix_agent": 0, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 5, "zabbix_agent_active": 7, "web_item": 9, "external_check": 10, "database_monitor": 11, "ipmi": 12, "ssh": 13, "telnet": 14, "calculated": 15, "jmx": 16, "snmp_trap": 17, "dependent": 18, "http": 19, "snmp_agent": 20, "script": 21} + if type in list(type_types.keys()): + type = type_types[type] + else: + type = int(type) + value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} + if value_type in list(value_type_types.keys()): + value_type = value_type_types[value_type] + else: + value_type = int(value_type) + # find host id host_id = "" if host_name is not None: @@ -1114,7 +1129,7 @@ def main(): else: inventory_link = int(inventory_link) else: - inventoryid = "0" + inventory_link = "0" # convert bools/choices to integers if allow_traps: @@ -1186,8 +1201,10 @@ def main(): if master_item: master_item = item.get_itemid_by_item_and_hostid(master_item, host_id)[0]["itemid"] - # check if item exist - is_item_exist = item.is_item_exist(item_name, host_name) + + if body and body_type == 2: + body = body.replace("\'", "\"") + if is_item_exist: item_id = is_item_exist[0]["itemid"] @@ -1198,6 +1215,7 @@ def main(): else: # update item if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + print("Item worth updating") # update the item item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) From f10583e82282caeebf7810b2f691802ab794d7ed Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 24 Apr 2024 07:37:08 +0000 Subject: [PATCH 12/21] more bugfixing --- plugins/modules/zabbix_item.py | 89 ++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 30 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 878590136..fcfc9b10f 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -65,7 +65,6 @@ - 3 = simple_check - 5 = zabbix_internal - 7 = zabbix_agent_active - - 9 = web_item - 10 = external_check - 11 = database_monitor - 12 = ipmi @@ -568,13 +567,15 @@ def construct_preprocessing(self, preprocessing): return preprocessing - def add_item(self, item_name, key, host_id, type, value_type, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def add_item(self, item_name, key, host_id, type, status, value_type, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) else: parameters = {"name": item_name, "key_": key, "hostid": host_id, "type": type, "value_type": value_type, "delay": update_interval} #add more parameters #add conditional parameters + if status is not None: + parameters["status"] = status if interfaceid is not None: parameters["interfaceid"] = interfaceid if url is not None: @@ -663,7 +664,7 @@ def add_item(self, item_name, key, host_id, type, value_type, update_interval, i except Exception as e: self._module.fail_json(msg="Failed to create item %s: %s" % (item_name, e)) - def update_item(self, item_name, item_id, key, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def update_item(self, item_name, item_id, key, type, status, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, item_parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): try: if self._module.check_mode: self._module.exit_json(changed=True) @@ -673,6 +674,10 @@ def update_item(self, item_name, item_id, key, update_interval, interfaceid, url parameters["name"] = item_name if key is not None: parameters["key_"] = key + if type is not None: + parameters["type"] = type + if status is not None: + parameters["status"] = status if update_interval is not None: parameters["delay"] = update_interval if interfaceid is not None: @@ -769,12 +774,16 @@ def delete_item(self, item_id, item_name): except Exception as e: self._module.fail_json(msg="Failed to delete item %s: %s" % (item_name, e)) - def check_all_properties(self, item_id, key, host_id, host_name, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): + def check_all_properties(self, item_id, key, host_id, host_name, type, status, update_interval, interfaceid, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_itemid, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): exist_item = self._zapi.item.get({"output": "extend", "selectPreprocessing": "extend", "selectTags": "extend", "filter": {"itemid": item_id}})[0] if host_id and host_id != int(exist_item["hostid"]): return True if key and key != exist_item["key_"]: return True + if type and int(type) != int(exist_item["type"]): + return True + if status and int(status) != int(exist_item["status"]): + return True if update_interval and update_interval != exist_item["delay"]: return True if interfaceid and int(interfaceid) != int(exist_item["interfaceid"]): @@ -827,7 +836,9 @@ def check_all_properties(self, item_id, key, host_id, host_name, update_interval return True if http_method and int(http_method) != int(exist_item["request_method"]): return True + # raise Exception("%s - %s" % (retrieve_mode, exist_item["retrieve_mode"])) if retrieve_mode and int(retrieve_mode) != int(exist_item["retrieve_mode"]): + # raise Exception("retrieve_mode is different! ") return True if snmp_oid and snmp_oid != exist_item["snmp_oid"]: return True @@ -869,10 +880,10 @@ def main(): key=dict(type="str", required_if=[["state", 1, ["present"]]]), host_name=dict(type="str", required_if=[["state", 1, ["present"]]]), state=dict(type="str", default="present", choices=["present", "absent"]), - status=dict(type="str", default="enabled", choices=["enabled", "disabled"]), + status=dict(type="str", choices=["enabled", "disabled"]), type=dict(type="str", choices=["zabbix_agent", "0", "zabbix_trapper", "2", "simple_check", "3", "zabbix_internal", "5", "zabbix_agent_active", "7", "web_item", "9", "external_check", "10", "database_monitor", "11", "ipmi", "12", "ssh", "13", "telnet", "14", "calculated", "15", "jmx", "16", "snmp_trap", "17", "dependent", "18", "http", "19", "snmp_agent", "20", "script", "21"], required_if=[["state", 1, ["present"]]]), value_type=dict(type="str", choices=["float", "0", "character", "1", "log", "2", "unsigned", "3", "text", "4"], required_if=[["state", 1, ["present"]]]), - update_interval=dict(type="str", default="10s", required_if=[ + update_interval=dict(type="str", required_if=[ ["type", 3, ["simple_check"]], ["type", 5, ["zabbix_internal"]], ["type", 7, ["zabbix_agent_active"]], @@ -937,6 +948,7 @@ def main(): ["type", 20, ["snmp_agent"]], ]), script=dict(type="str", required_if=[ + ["type", 15, ["calculated"]], ["type", 21, ["script"]], ["type", 13, ["ssh"]], ["type", 14, ["telnet"]] @@ -1074,9 +1086,6 @@ def main(): tags = module.params["tags"] preprocessing = module.params["preprocessing"] - - status = 1 if status == "disabled" else 0 - item = Item(module) # check if item exist @@ -1084,7 +1093,25 @@ def main(): preprocessing = item.construct_preprocessing(preprocessing) - + if type: + type_types = {"zabbix_agent": 0, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 5, "zabbix_agent_active": 7, "web_item": 9, "external_check": 10, "database_monitor": 11, "ipmi": 12, "ssh": 13, "telnet": 14, "calculated": 15, "jmx": 16, "snmp_trap": 17, "dependent": 18, "http": 19, "snmp_agent": 20, "script": 21} + if type in list(type_types.keys()): + type = type_types[type] + else: + type = int(type) + else: + if not is_item_exist: + module.fail_json(msg='"type" required when creating an item') + if value_type: + value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} + if value_type in list(value_type_types.keys()): + value_type = value_type_types[value_type] + else: + value_type = int(value_type) + else: + if not is_item_exist: + module.fail_json(msg='"value_type" required when creating an item') + if state == "present": if not is_item_exist: # check mandatory parameters @@ -1095,19 +1122,16 @@ def main(): if type is None: module.fail_json(msg="Type cannot be empty.") - type_types = {"zabbix_agent": 0, "zabbix_trapper": 2, "simple_check": 3, "zabbix_internal": 5, "zabbix_agent_active": 7, "web_item": 9, "external_check": 10, "database_monitor": 11, "ipmi": 12, "ssh": 13, "telnet": 14, "calculated": 15, "jmx": 16, "snmp_trap": 17, "dependent": 18, "http": 19, "snmp_agent": 20, "script": 21} - if type in list(type_types.keys()): - type = type_types[type] + if status: + if status == "enabled": + status = 1 + elif status == "disabled": + status = 0 else: - type = int(type) - - value_type_types = {"float": 0, "character": 1, "log": 2, "unsigned": 3, "text": 4} - if value_type in list(value_type_types.keys()): - value_type = value_type_types[value_type] - else: - value_type = int(value_type) + module.fail_json(msg="Status must be enabled or disabled.") + else: + status = 1 - # find host id host_id = "" if host_name is not None: @@ -1143,15 +1167,18 @@ def main(): authtype = int(authtype) else: authtype = 0 - if type == 19: + elif type == 19: if authtype: - authtype_types = {"password": 0, "publickey": 1, "none": 0, "basic": 1, "ntlm": 2, "kerberos": 3} + authtype_types = {"none": 0, "basic": 1, "ntlm": 2, "kerberos": 3} if authtype in list(authtype_types.keys()): authtype = authtype_types[authtype] else: authtype = int(authtype) else: authtype = 0 + else: + authtype = 0 + if follow_redirects: follow_redirects = 1 if follow_redirects == True else 0 if convert_json: @@ -1197,13 +1224,16 @@ def main(): # conditional parameter filtering if type in list([2, 17, 18]): - update_interval = "0" + update_interval: "0" + else: + if not update_interval: + update_interval = "10s" if master_item: master_item = item.get_itemid_by_item_and_hostid(master_item, host_id)[0]["itemid"] - if body and body_type == 2: - body = body.replace("\'", "\"") + if body_type == 2: + body = body.replace("\'", '\"') if is_item_exist: item_id = is_item_exist[0]["itemid"] @@ -1214,10 +1244,9 @@ def main(): module.exit_json(changed=True, result="Successfully deleted item %s" % item_name) else: # update item - if item.check_all_properties(item_id, key, host_id, host_name, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): - print("Item worth updating") + if item.check_all_properties(item_id, key, host_id, host_name, type, status, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing): # update the item - item.update_item(item_name, item_id, key, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) + item.update_item(item_name, item_id, key, type, status, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully updated item %s on host %s" % (item_name, host_name)) else: @@ -1232,7 +1261,7 @@ def main(): module.fail_json(msg="Specify a host when creating item '%s'" % item_name) # create item - item_id = item.add_item(item_name, key, host_id, type, value_type, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) + item_id = item.add_item(item_name, key, host_id, type, status, value_type, update_interval, interface, url, allow_traps, authtype, convert_json, description, follow_redirects, formula, headers, history, http_proxy, inventory_link, ipmi_sensor, jmx_endpoint, logtimefmt, master_item, script, parameters, password, body_type, body, privatekey, publickey, url_query, http_method, retrieve_mode, snmp_oid, db_query, ssl_cert_file, ssl_key_file, ssl_key_password, status_codes, timeout, allowed_hosts, trends, units, username, verify_host, verify_peer, tags, preprocessing) module.exit_json(changed=True, result="Successfully added item %s on host %s" % (item_name, host_name)) From 333c06c8f0b6b7005382a52f58cc22df0c2dceb5 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 24 Apr 2024 07:37:38 +0000 Subject: [PATCH 13/21] added more tests --- .../tasks/zabbix_item_tests.yml | 1051 ++++++++++++++++- 1 file changed, 1047 insertions(+), 4 deletions(-) diff --git a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml index 98f635608..7966241a9 100644 --- a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml +++ b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml @@ -1,10 +1,1053 @@ --- -- name: "test: create item on host ExampleHostForHostInfoModule" +- name: "test: create item ExampleItem on host ExampleHostForItem with many options set" community.zabbix.zabbix_item: item_name: ExampleItem - host_name: ExampleHostForHostInfoModule + host_name: ExampleHostForItem key: ExampleItem - type: simple_check + type: http + url: localhost + convert_json: true + body_type: json + body: { + test: "yes" + } + http_method: GET + retrieve_mode: both + status_codes: + - 200 + - 401 + state: present + value_type: text + update_interval: 1m + preprocessing: [ + { + type: json_error_check, + params: "$.", + error_handler: custom_message, + error_handler_params: "An error occured..." + }, + { + type: trim, + params: "\"" + } + ] + tags: + - tag: ExampleItemTag + value: ExampleTagValue + - tag: ExampleItemTag2 + value: ExampleTagValue + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: try to create the same item with the same settings" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + key: ExampleItem + type: http + url: localhost + convert_json: true + body_type: json + body: { + test: "yes" + } + http_method: GET + retrieve_mode: both + status_codes: + - 200 + - 401 + state: present + value_type: text + update_interval: 1m + preprocessing: [ + { + type: json_error_check, + params: "$.", + error_handler: custom_message, + error_handler_params: "An error occured..." + }, + { + type: trim, + params: "\"" + } + ] + tags: + - tag: ExampleItemTag + value: ExampleTagValue + - tag: ExampleItemTag2 + value: ExampleTagValue + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: disable item" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + status: disabled + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: disable item (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + status: disabled + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: try to create the same item changing one parameter" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + key: ExampleItem + type: http + url: localhost + convert_json: true + body_type: json + body: { + "test": "yes" + } + retrieve_mode: both + status_codes: + - 200 + - 201 state: present value_type: text - delay: 1m \ No newline at end of file + update_interval: 1m + preprocessing: [ + { + type: bool_to_dec, + error_handler: custom_message, + error_handler_params: "An error occured..." + }, + { + type: trim, + params: "\"" + } + ] + register: zabbix_item1 + +- name: changing the value of the already existing parameter status_codes should work and mark task as changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change the key of the item" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + key: ExampleItemKey_changed + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change the key of the item (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + key: ExampleItemKey_changed + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change description" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + description: ExampleItem Description Test + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change description (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + description: ExampleItem Description Test + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change preprocessing (remove one rule)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + preprocessing: [ + { + type: trim, + params: "\"" + } + ] + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change preprocessing (add one rule)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + preprocessing: [ + { + type: trim, + params: "\"" + }, + { + type: jsonpath, + params: "$.", + error_handler: discard + } + ] + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type to zabbix_agent" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: zabbix_agent + interface: test-interface.zabbix.test:10050 + update_interval: 10m + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type zabbix_agent (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: zabbix_agent + interface: test-interface.zabbix.test:10050 + update_interval: 10m + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change interface" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + interface: 10.1.1.1:10055 + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change interface (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + interface: 10.1.1.1:10055 + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type zabbix_trapper" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: zabbix_trapper + allowed_hosts: localhost + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type zabbix_trapper (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: zabbix_trapper + allowed_hosts: localhost + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type simple_check" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: simple_check + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type simple_check (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: simple_check + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type zabbix_internal" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: zabbix_internal + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type zabbix_internal (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: zabbix_internal + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type zabbix_agent_active" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: zabbix_agent_active + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type zabbix_agent_active (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: zabbix_agent_active + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type external_check with dns specified interface" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: external_check + interface: test-interface.zabbix.test:10050 + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type external_check with dns specified interface (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: external_check + interface: test-interface.zabbix.test:10050 + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type database_monitor" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: database_monitor + db_query: SELECT * FROM test + username: test + password: test + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type database_monitor (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: database_monitor + db_query: SELECT * FROM test + username: test + password: test + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type ipmi" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: ipmi + ipmi_sensor: root + interface: 10.1.1.1:12346 + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type ipmi (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: ipmi + ipmi_sensor: root + interface: 10.1.1.1:12346 + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type ssh using password" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: ssh + update_interval: 10m + authtype: password + username: root + password: test + script: ls + interface: test-interface.zabbix.test:10050 + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type ssh using password (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: ssh + update_interval: 10m + authtype: password + username: root + password: test + script: ls + interface: test-interface.zabbix.test:10050 + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type ssh using publickey" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: ssh + update_interval: 10m + authtype: publickey + username: root + privatekey: ~/.ssh/id_rsa + publickey: ~/.ssh/id_rsa.pub + script: ls + interface: test-interface.zabbix.test:10050 + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type ssh using publickey (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: ssh + update_interval: 10m + authtype: publickey + username: root + privatekey: ~/.ssh/id_rsa + publickey: ~/.ssh/id_rsa.pub + script: ls + interface: test-interface.zabbix.test:10050 + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type telnet" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: telnet + update_interval: 10m + authtype: publickey + username: root + password: test + script: ls + interface: test-interface.zabbix.test:10050 + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type telnet (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: telnet + update_interval: 10m + authtype: publickey + username: root + password: test + script: ls + interface: test-interface.zabbix.test:10050 + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type calculated" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: calculated + update_interval: 10m + script: 1 + 1 + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type calculated (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: calculated + update_interval: 10m + script: 1 + 1 + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type jmx" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: jmx + update_interval: 10m + interface: 10.1.1.1:77 + jmx_endpoint: service:jmx + username: root + password: test + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type jmx (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: jmx + update_interval: 10m + interface: 10.1.1.1:77 + jmx_endpoint: service:jmx + username: root + password: test + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type snmp_trap" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: snmp_trap + interface: 10.1.1.1:12345 + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type snmp_trap (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: snmp_trap + interface: 10.1.1.1:12345 + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: Create master item for dependent check + community.zabbix.zabbix_item: + item_name: ExampleMasterItem + host_name: ExampleHostForItem + key: ExampleHostForItem.ExampleMasterItem + type: zabbix_internal + value_type: text + update_interval: 1m + register: zabbix_item1 + +- name: "test: change type dependent" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: dependent + master_item: ExampleMasterItem + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type dependent (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: dependent + master_item: ExampleMasterItem + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http no auth" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: http + update_interval: 1m + interface: 10.1.1.1:10050 + allow_traps: true + authtype: none + follow_redirects: true + headers: { + User-Agent: 'Zabbix' + } + http_proxy: 8.8.8.8 + convert_json: true + body_type: raw + body: "test123" + url_query: { + test: 'yes' + } + retrieve_mode: both + ssl_cert_file: /tmp/temp.cert + ssl_key_file: /tmp/key.kex + ssl_key_password: test + status_codes: + - 200 + - 400-405 + timeout: 30s + allowed_hosts: localhost + verify_host: true + verify_peer: true + url: google.com + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http no auth (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: http + update_interval: 1m + interface: 10.1.1.1:10050 + allow_traps: true + authtype: none + follow_redirects: true + headers: { + User-Agent: 'Zabbix' + } + http_proxy: 8.8.8.8 + convert_json: true + body_type: raw + body: "test123" + url_query: { + test: 'yes' + } + retrieve_mode: both + ssl_cert_file: /tmp/temp.cert + ssl_key_file: /tmp/key.kex + ssl_key_password: test + status_codes: + - 200 + - 400-405 + timeout: 30s + allowed_hosts: localhost + verify_host: true + verify_peer: true + url: google.com + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http basic auth" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + authtype: basic + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http no auth (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + authtype: basic + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http ntlm auth" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: http + authtype: ntlm + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http ntlm auth (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: http + authtype: ntlm + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http kerberos auth" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: http + authtype: kerberos + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http kerberos auth (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: http + authtype: kerberos + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http body_type json" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + body_type: json + body: { + test: "true" + } + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http body_type json (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + body_type: json + body: { + test: "true" + } + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http body_type xml" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + body_type: xml + body: "" + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http body_type xml (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + body_type: xml + body: "" + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http http_method POST" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + http_method: POST + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http http_method POST (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + http_method: POST + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http http_method PUT" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + http_method: PUT + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http http_method PUT (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + http_method: PUT + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type http http_method HEAD" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + http_method: HEAD + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type http http_method HEAD (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + http_method: HEAD + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type snmp_agent" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: snmp_agent + interface: 10.1.1.1:12345 + snmp_oid: .1 + update_interval: 10m + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type snmp_agent (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: snmp_agent + interface: 10.1.1.1:12345 + snmp_oid: .1 + update_interval: 10m + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + +- name: "test: change type script" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: script + update_interval: 10m + script: echo "test" + parameters: { + test: "yes", + test2: "no" + } + register: zabbix_item1 + +- name: expect to succeed and that things changed + ansible.builtin.assert: + that: + - "zabbix_item1 is changed" + +- name: "test: change type script (again)" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + type: script + update_interval: 10m + script: echo "test" + parameters: { + test: "yes", + test2: "no" + } + register: zabbix_item1 + +- name: updating with same values should be idempotent + ansible.builtin.assert: + that: + - "not zabbix_item1 is changed" + From d9817cc0094c03d6fa92ba8983ea9d6db1838b53 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 24 Apr 2024 07:38:19 +0000 Subject: [PATCH 14/21] added testing skeleton --- .../targets/test_zabbix_item/tasks/main.yml | 17 ++++- .../tasks/zabbix_item_setup.yml | 68 +++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 tests/integration/targets/test_zabbix_item/tasks/zabbix_item_setup.yml diff --git a/tests/integration/targets/test_zabbix_item/tasks/main.yml b/tests/integration/targets/test_zabbix_item/tasks/main.yml index 0463b4455..fcd82268e 100644 --- a/tests/integration/targets/test_zabbix_item/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_item/tasks/main.yml @@ -1,6 +1,6 @@ --- - block: - # - include_tasks: zabbix_item_setup.yml + - include_tasks: zabbix_item_setup.yml - include_tasks: zabbix_item_tests.yml @@ -8,5 +8,16 @@ # - include_tasks: zabbix_item_teardown.yml - # always: - # - name: "Cleanup if test failed" + always: + - name: "Cleanup item if test failed" + community.zabbix.zabbix_item: + item_name: ExampleItem + host_name: ExampleHostForItem + state: absent + ignore_errors: true + - name: "Cleanup host if test failed" + community.zabbix.zabbix_host: + host_name: ExampleHostForItem + state: absent + ignore_errors: true + diff --git a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_setup.yml b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_setup.yml new file mode 100644 index 000000000..14096ee44 --- /dev/null +++ b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_setup.yml @@ -0,0 +1,68 @@ +--- +# set up a zabbix host to test zabbix_item with + +- name: Create a new host + community.zabbix.zabbix_host: + host_name: ExampleHostForItem + visible_name: ExampleHostForItem + description: My ExampleHost Description + host_groups: + - Linux servers + - Zabbix servers + status: enabled + state: present + inventory_mode: manual + inventory_zabbix: + tag: test-tag + alias: test-alias + notes: "Special Informations: test-info" + location: test-location + site_rack: test-rack + os: test-os + hardware: test-hw + interfaces: + - type: 1 + main: 1 + useip: 1 + ip: 10.1.1.1 + dns: "test-interface.zabbix.test" + port: "10050" + - type: 1 + main: 0 + useip: 1 + ip: 10.1.1.1 + dns: "" + port: "10055" + - type: 2 + main: 1 + useip: 1 + ip: 10.1.1.1 + dns: "" + port: "12345" + details: { + community: "zabbix" + } + - type: 3 + main: 1 + useip: 1 + ip: 10.1.1.1 + dns: "" + port: "12346" + - type: 4 + main: 1 + useip: 1 + ip: 10.1.1.1 + dns: "" + port: "77" + + macros: + - macro: MACRO1 + value: test1 + - macro: "{$MACRO2}" + value: test2 + tags: + - tag: Tag1 + - tag: Tag2 + value: test2 + register: zabbix_host + From f4beb78485dae1309dd4eb2bbf4442618f8e4414 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 24 Apr 2024 07:56:09 +0000 Subject: [PATCH 15/21] added examples and removed unused imports --- plugins/modules/zabbix_item.py | 55 +++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index fcfc9b10f..e9c9332fd 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -484,7 +484,60 @@ """ -import copy, re, json +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 a new item or rewrite an existing item's info +# 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_item: + host_name: ExampleHost + item_name: ExampleItem + description: My ExampleItem Description + type: zabbix_internal + status: enabled + state: present + tags: + - tag: ExampleHostsTag + - tag: ExampleHostsTag2 + value: ExampleTagValue + +- name: Update an existing item's check type +# Set current task level 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 + ansible_host: zabbix-example-fqdn.org # you can use task level ansible_host or delegate_to like in previous example + become: false + community.zabbix.zabbix_host: + host_name: ExampleHost + item_name: ExampleItem + type: simple_check +""" + +import re from ansible.module_utils.basic import AnsibleModule From 23169f1c279d746c2ee8e7bb8f5e19a0472a41a6 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 24 Apr 2024 08:09:08 +0000 Subject: [PATCH 16/21] typos in examples --- plugins/modules/zabbix_item.py | 9 +- .../targets/test_zabbix_item/tasks/main.yml | 4 +- .../tasks/zabbix_item_doc.yml | 29 ++++ .../tasks/zabbix_item_tests.yml | 140 +++++++++--------- 4 files changed, 106 insertions(+), 76 deletions(-) create mode 100644 tests/integration/targets/test_zabbix_item/tasks/zabbix_item_doc.yml diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index e9c9332fd..38eb4af95 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -511,13 +511,16 @@ community.zabbix.zabbix_item: host_name: ExampleHost item_name: ExampleItem + key: ExampleItem description: My ExampleItem Description type: zabbix_internal + value_type: text status: enabled state: present tags: - - tag: ExampleHostsTag - - tag: ExampleHostsTag2 + - tag: ExampleItemTag + value: ExampleTagValue + - tag: ExampleItemTag2 value: ExampleTagValue - name: Update an existing item's check type @@ -531,7 +534,7 @@ ansible_zabbix_url_path: "zabbixeu" # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http:///zabbixeu ansible_host: zabbix-example-fqdn.org # you can use task level ansible_host or delegate_to like in previous example become: false - community.zabbix.zabbix_host: + community.zabbix.zabbix_item: host_name: ExampleHost item_name: ExampleItem type: simple_check diff --git a/tests/integration/targets/test_zabbix_item/tasks/main.yml b/tests/integration/targets/test_zabbix_item/tasks/main.yml index fcd82268e..ff8ea30a3 100644 --- a/tests/integration/targets/test_zabbix_item/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_item/tasks/main.yml @@ -4,9 +4,7 @@ - include_tasks: zabbix_item_tests.yml - # - include_tasks: zabbix_item_doc.yml - - # - include_tasks: zabbix_item_teardown.yml + - include_tasks: zabbix_item_doc.yml always: - name: "Cleanup item if test failed" diff --git a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_doc.yml b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_doc.yml new file mode 100644 index 000000000..cd2ded50b --- /dev/null +++ b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_doc.yml @@ -0,0 +1,29 @@ +--- +# These two tests are close to documentation example + +- name: Create a new item or rewrite an existing item's info + community.zabbix.zabbix_item: + host_name: ExampleHost + item_name: ExampleItem + key: ExampleItem + description: My ExampleItem Description + type: zabbix_internal + status: enabled + state: present + tags: + - tag: ExampleItemTag + value: ExampleTagValue + - tag: ExampleItemTag2 + value: ExampleTagValue + +- name: Update an existing item's check type + community.zabbix.zabbix_item: + host_name: ExampleHost + item_name: ExampleItem + type: simple_check + +- name: expect both to succeed + ansible.builtin.assert: + that: + - "zabbix_item_1 is changed" + - "zabbix_item_2 is changed" diff --git a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml index 7966241a9..22b247738 100644 --- a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml +++ b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml @@ -1,9 +1,9 @@ --- - name: "test: create item ExampleItem on host ExampleHostForItem with many options set" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem - key: ExampleItem + key: ExampleItem1 type: http url: localhost convert_json: true @@ -45,9 +45,9 @@ - name: "test: try to create the same item with the same settings" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem - key: ExampleItem + key: ExampleItem1 type: http url: localhost convert_json: true @@ -89,7 +89,7 @@ - name: "test: disable item" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem status: disabled register: zabbix_item1 @@ -101,7 +101,7 @@ - name: "test: disable item (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem status: disabled register: zabbix_item1 @@ -113,9 +113,9 @@ - name: "test: try to create the same item changing one parameter" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem - key: ExampleItem + key: ExampleItem1 type: http url: localhost convert_json: true @@ -150,9 +150,9 @@ - name: "test: change the key of the item" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem - key: ExampleItemKey_changed + key: ExampleItem1Key_changed register: zabbix_item1 - name: expect to succeed and that things changed @@ -162,9 +162,9 @@ - name: "test: change the key of the item (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem - key: ExampleItemKey_changed + key: ExampleItem1Key_changed register: zabbix_item1 - name: updating with same values should be idempotent @@ -174,7 +174,7 @@ - name: "test: change description" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem description: ExampleItem Description Test register: zabbix_item1 @@ -186,7 +186,7 @@ - name: "test: change description (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem description: ExampleItem Description Test register: zabbix_item1 @@ -198,7 +198,7 @@ - name: "test: change preprocessing (remove one rule)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem preprocessing: [ { @@ -215,7 +215,7 @@ - name: "test: change preprocessing (add one rule)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem preprocessing: [ { @@ -237,7 +237,7 @@ - name: "test: change type to zabbix_agent" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: zabbix_agent interface: test-interface.zabbix.test:10050 @@ -251,7 +251,7 @@ - name: "test: change type zabbix_agent (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: zabbix_agent interface: test-interface.zabbix.test:10050 @@ -265,7 +265,7 @@ - name: "test: change interface" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem interface: 10.1.1.1:10055 register: zabbix_item1 @@ -277,7 +277,7 @@ - name: "test: change interface (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem interface: 10.1.1.1:10055 register: zabbix_item1 @@ -289,7 +289,7 @@ - name: "test: change type zabbix_trapper" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: zabbix_trapper allowed_hosts: localhost @@ -302,7 +302,7 @@ - name: "test: change type zabbix_trapper (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: zabbix_trapper allowed_hosts: localhost @@ -315,7 +315,7 @@ - name: "test: change type simple_check" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: simple_check register: zabbix_item1 @@ -327,7 +327,7 @@ - name: "test: change type simple_check (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: simple_check register: zabbix_item1 @@ -339,7 +339,7 @@ - name: "test: change type zabbix_internal" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: zabbix_internal register: zabbix_item1 @@ -351,7 +351,7 @@ - name: "test: change type zabbix_internal (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: zabbix_internal register: zabbix_item1 @@ -363,7 +363,7 @@ - name: "test: change type zabbix_agent_active" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: zabbix_agent_active register: zabbix_item1 @@ -375,7 +375,7 @@ - name: "test: change type zabbix_agent_active (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: zabbix_agent_active register: zabbix_item1 @@ -387,7 +387,7 @@ - name: "test: change type external_check with dns specified interface" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: external_check interface: test-interface.zabbix.test:10050 @@ -400,7 +400,7 @@ - name: "test: change type external_check with dns specified interface (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: external_check interface: test-interface.zabbix.test:10050 @@ -413,7 +413,7 @@ - name: "test: change type database_monitor" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: database_monitor db_query: SELECT * FROM test @@ -428,7 +428,7 @@ - name: "test: change type database_monitor (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: database_monitor db_query: SELECT * FROM test @@ -443,7 +443,7 @@ - name: "test: change type ipmi" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: ipmi ipmi_sensor: root @@ -457,7 +457,7 @@ - name: "test: change type ipmi (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: ipmi ipmi_sensor: root @@ -471,7 +471,7 @@ - name: "test: change type ssh using password" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: ssh update_interval: 10m @@ -489,7 +489,7 @@ - name: "test: change type ssh using password (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: ssh update_interval: 10m @@ -507,7 +507,7 @@ - name: "test: change type ssh using publickey" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: ssh update_interval: 10m @@ -526,7 +526,7 @@ - name: "test: change type ssh using publickey (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: ssh update_interval: 10m @@ -545,7 +545,7 @@ - name: "test: change type telnet" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: telnet update_interval: 10m @@ -563,7 +563,7 @@ - name: "test: change type telnet (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: telnet update_interval: 10m @@ -581,7 +581,7 @@ - name: "test: change type calculated" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: calculated update_interval: 10m @@ -595,7 +595,7 @@ - name: "test: change type calculated (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: calculated update_interval: 10m @@ -609,7 +609,7 @@ - name: "test: change type jmx" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: jmx update_interval: 10m @@ -626,7 +626,7 @@ - name: "test: change type jmx (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: jmx update_interval: 10m @@ -643,7 +643,7 @@ - name: "test: change type snmp_trap" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: snmp_trap interface: 10.1.1.1:12345 @@ -656,7 +656,7 @@ - name: "test: change type snmp_trap (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: snmp_trap interface: 10.1.1.1:12345 @@ -679,7 +679,7 @@ - name: "test: change type dependent" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: dependent master_item: ExampleMasterItem @@ -692,7 +692,7 @@ - name: "test: change type dependent (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: dependent master_item: ExampleMasterItem @@ -705,7 +705,7 @@ - name: "test: change type http no auth" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: http update_interval: 1m @@ -744,7 +744,7 @@ - name: "test: change type http no auth (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: http update_interval: 1m @@ -783,7 +783,7 @@ - name: "test: change type http basic auth" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem authtype: basic register: zabbix_item1 @@ -795,7 +795,7 @@ - name: "test: change type http no auth (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem authtype: basic register: zabbix_item1 @@ -807,7 +807,7 @@ - name: "test: change type http ntlm auth" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: http authtype: ntlm @@ -820,7 +820,7 @@ - name: "test: change type http ntlm auth (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: http authtype: ntlm @@ -833,7 +833,7 @@ - name: "test: change type http kerberos auth" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: http authtype: kerberos @@ -846,7 +846,7 @@ - name: "test: change type http kerberos auth (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: http authtype: kerberos @@ -859,7 +859,7 @@ - name: "test: change type http body_type json" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem body_type: json body: { @@ -874,7 +874,7 @@ - name: "test: change type http body_type json (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem body_type: json body: { @@ -889,7 +889,7 @@ - name: "test: change type http body_type xml" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem body_type: xml body: "" @@ -902,7 +902,7 @@ - name: "test: change type http body_type xml (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem body_type: xml body: "" @@ -915,7 +915,7 @@ - name: "test: change type http http_method POST" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem http_method: POST register: zabbix_item1 @@ -927,7 +927,7 @@ - name: "test: change type http http_method POST (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem http_method: POST register: zabbix_item1 @@ -939,7 +939,7 @@ - name: "test: change type http http_method PUT" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem http_method: PUT register: zabbix_item1 @@ -951,7 +951,7 @@ - name: "test: change type http http_method PUT (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem http_method: PUT register: zabbix_item1 @@ -963,7 +963,7 @@ - name: "test: change type http http_method HEAD" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem http_method: HEAD register: zabbix_item1 @@ -975,7 +975,7 @@ - name: "test: change type http http_method HEAD (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem http_method: HEAD register: zabbix_item1 @@ -987,7 +987,7 @@ - name: "test: change type snmp_agent" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: snmp_agent interface: 10.1.1.1:12345 @@ -1002,7 +1002,7 @@ - name: "test: change type snmp_agent (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: snmp_agent interface: 10.1.1.1:12345 @@ -1017,7 +1017,7 @@ - name: "test: change type script" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: script update_interval: 10m @@ -1035,7 +1035,7 @@ - name: "test: change type script (again)" community.zabbix.zabbix_item: - item_name: ExampleItem + item_name: ExampleItem1 host_name: ExampleHostForItem type: script update_interval: 10m From bbcb661a9181936d5e5e2e5d5a3600d4249e0f2a Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 24 Apr 2024 08:09:40 +0000 Subject: [PATCH 17/21] added documentation tests --- tests/integration/targets/test_zabbix_item/tasks/main.yml | 2 +- .../targets/test_zabbix_item/tasks/zabbix_item_doc.yml | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/integration/targets/test_zabbix_item/tasks/main.yml b/tests/integration/targets/test_zabbix_item/tasks/main.yml index ff8ea30a3..108bd3194 100644 --- a/tests/integration/targets/test_zabbix_item/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_item/tasks/main.yml @@ -2,7 +2,7 @@ - block: - include_tasks: zabbix_item_setup.yml - - include_tasks: zabbix_item_tests.yml + # - include_tasks: zabbix_item_tests.yml - include_tasks: zabbix_item_doc.yml diff --git a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_doc.yml b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_doc.yml index cd2ded50b..69c176fe4 100644 --- a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_doc.yml +++ b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_doc.yml @@ -3,11 +3,12 @@ - name: Create a new item or rewrite an existing item's info community.zabbix.zabbix_item: - host_name: ExampleHost + host_name: ExampleHostForItem item_name: ExampleItem key: ExampleItem description: My ExampleItem Description type: zabbix_internal + value_type: text status: enabled state: present tags: @@ -15,12 +16,14 @@ value: ExampleTagValue - tag: ExampleItemTag2 value: ExampleTagValue + register: zabbix_item_1 - name: Update an existing item's check type community.zabbix.zabbix_item: - host_name: ExampleHost + host_name: ExampleHostForItem item_name: ExampleItem type: simple_check + register: zabbix_item_2 - name: expect both to succeed ansible.builtin.assert: From 9a033a69b0a13db54306350eab10218a100d722b Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Wed, 24 Apr 2024 08:17:03 +0000 Subject: [PATCH 18/21] re-enabled regular tests --- tests/integration/targets/test_zabbix_item/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/targets/test_zabbix_item/tasks/main.yml b/tests/integration/targets/test_zabbix_item/tasks/main.yml index 108bd3194..ff8ea30a3 100644 --- a/tests/integration/targets/test_zabbix_item/tasks/main.yml +++ b/tests/integration/targets/test_zabbix_item/tasks/main.yml @@ -2,7 +2,7 @@ - block: - include_tasks: zabbix_item_setup.yml - # - include_tasks: zabbix_item_tests.yml + - include_tasks: zabbix_item_tests.yml - include_tasks: zabbix_item_doc.yml From 9c6ead3859ffe92d6288a116bbf56737718f4566 Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Fri, 26 Apr 2024 07:18:52 +0000 Subject: [PATCH 19/21] inverted status bool --- plugins/modules/zabbix_item.py | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 38eb4af95..036333336 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -628,10 +628,8 @@ def add_item(self, item_name, key, host_id, type, status, value_type, update_int if self._module.check_mode: self._module.exit_json(changed=True) else: - parameters = {"name": item_name, "key_": key, "hostid": host_id, "type": type, "value_type": value_type, "delay": update_interval} #add more parameters + parameters = {"name": item_name, "key_": key, "hostid": host_id, "status": status, "type": type, "value_type": value_type, "delay": update_interval} #add more parameters #add conditional parameters - if status is not None: - parameters["status"] = status if interfaceid is not None: parameters["interfaceid"] = interfaceid if url is not None: @@ -725,15 +723,13 @@ def update_item(self, item_name, item_id, key, type, status, update_interval, in if self._module.check_mode: self._module.exit_json(changed=True) else: - parameters = {"itemid": item_id} + parameters = {"itemid": item_id, "status": status} if item_name is not None: parameters["name"] = item_name if key is not None: parameters["key_"] = key if type is not None: parameters["type"] = type - if status is not None: - parameters["status"] = status if update_interval is not None: parameters["delay"] = update_interval if interfaceid is not None: @@ -936,7 +932,7 @@ def main(): key=dict(type="str", required_if=[["state", 1, ["present"]]]), host_name=dict(type="str", required_if=[["state", 1, ["present"]]]), state=dict(type="str", default="present", choices=["present", "absent"]), - status=dict(type="str", choices=["enabled", "disabled"]), + status=dict(type="str", default="enabled", choices=["enabled", "disabled"]), type=dict(type="str", choices=["zabbix_agent", "0", "zabbix_trapper", "2", "simple_check", "3", "zabbix_internal", "5", "zabbix_agent_active", "7", "web_item", "9", "external_check", "10", "database_monitor", "11", "ipmi", "12", "ssh", "13", "telnet", "14", "calculated", "15", "jmx", "16", "snmp_trap", "17", "dependent", "18", "http", "19", "snmp_agent", "20", "script", "21"], required_if=[["state", 1, ["present"]]]), value_type=dict(type="str", choices=["float", "0", "character", "1", "log", "2", "unsigned", "3", "text", "4"], required_if=[["state", 1, ["present"]]]), update_interval=dict(type="str", required_if=[ @@ -1142,6 +1138,10 @@ def main(): tags = module.params["tags"] preprocessing = module.params["preprocessing"] + # convert enabled to 0; disabled to 1 + status = 1 if status == "disabled" else 0 + + item = Item(module) # check if item exist @@ -1178,16 +1178,6 @@ def main(): if type is None: module.fail_json(msg="Type cannot be empty.") - if status: - if status == "enabled": - status = 1 - elif status == "disabled": - status = 0 - else: - module.fail_json(msg="Status must be enabled or disabled.") - else: - status = 1 - # find host id host_id = "" if host_name is not None: From 9791833c4794f79eb70c82d987c9d29f2459b09b Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Fri, 26 Apr 2024 08:57:05 +0000 Subject: [PATCH 20/21] removed debugging --- plugins/modules/zabbix_item.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/modules/zabbix_item.py b/plugins/modules/zabbix_item.py index 036333336..ae5dfc28e 100644 --- a/plugins/modules/zabbix_item.py +++ b/plugins/modules/zabbix_item.py @@ -888,9 +888,7 @@ def check_all_properties(self, item_id, key, host_id, host_name, type, status, u return True if http_method and int(http_method) != int(exist_item["request_method"]): return True - # raise Exception("%s - %s" % (retrieve_mode, exist_item["retrieve_mode"])) if retrieve_mode and int(retrieve_mode) != int(exist_item["retrieve_mode"]): - # raise Exception("retrieve_mode is different! ") return True if snmp_oid and snmp_oid != exist_item["snmp_oid"]: return True From d4ded6ee6ed351eeb3465d59f148b9d8e45d812a Mon Sep 17 00:00:00 2001 From: Lars van der Hooft Date: Tue, 7 May 2024 22:51:09 +0000 Subject: [PATCH 21/21] Rebuilt tests, creating new item for each type --- .../tasks/zabbix_item_tests.yml | 253 ++++++++++++------ 1 file changed, 165 insertions(+), 88 deletions(-) diff --git a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml index 22b247738..333b2683b 100644 --- a/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml +++ b/tests/integration/targets/test_zabbix_item/tasks/zabbix_item_tests.yml @@ -3,6 +3,7 @@ community.zabbix.zabbix_item: item_name: ExampleItem1 host_name: ExampleHostForItem + status: enabled key: ExampleItem1 type: http url: localhost @@ -235,9 +236,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type to zabbix_agent" +- name: "test: create new item with type zabbix_agent" community.zabbix.zabbix_item: - item_name: ExampleItem1 + state: present + status: enabled + item_name: ExampleItemZabbixAgent + key: ExampleItemZabbixAgent + value_type: text host_name: ExampleHostForItem type: zabbix_agent interface: test-interface.zabbix.test:10050 @@ -249,9 +254,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type zabbix_agent (again)" +- name: "test: create new item with type zabbix_agent (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + state: present + status: enabled + item_name: ExampleItemZabbixAgent + key: ExampleItemZabbixAgent + value_type: text host_name: ExampleHostForItem type: zabbix_agent interface: test-interface.zabbix.test:10050 @@ -265,7 +274,7 @@ - name: "test: change interface" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItemZabbixAgent host_name: ExampleHostForItem interface: 10.1.1.1:10055 register: zabbix_item1 @@ -277,7 +286,7 @@ - name: "test: change interface (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItemZabbixAgent host_name: ExampleHostForItem interface: 10.1.1.1:10055 register: zabbix_item1 @@ -287,12 +296,15 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type zabbix_trapper" +- name: "test: create new item with type zabbix_trapper" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1ZabbixTrapper + key: ExampleItem1ZabbixTrapper host_name: ExampleHostForItem type: zabbix_trapper + value_type: text allowed_hosts: localhost + update_interval: 0 register: zabbix_item1 - name: expect to succeed and that things changed @@ -300,12 +312,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type zabbix_trapper (again)" +- name: "test: create new item with type zabbix_trapper (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1ZabbixTrapper host_name: ExampleHostForItem type: zabbix_trapper allowed_hosts: localhost + update_interval: 0 register: zabbix_item1 - name: updating with same values should be idempotent @@ -313,11 +326,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type simple_check" +- name: "test: create new item with type simple_check" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1SimpleCheck + key: ExampleItem1SimpleCheck host_name: ExampleHostForItem type: simple_check + value_type: text register: zabbix_item1 - name: expect to succeed and that things changed @@ -325,11 +340,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type simple_check (again)" +- name: "test: create new item with type simple_check (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1SimpleCheck + key: ExampleItem1SimpleCheck host_name: ExampleHostForItem type: simple_check + value_type: text register: zabbix_item1 - name: updating with same values should be idempotent @@ -337,11 +354,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type zabbix_internal" +- name: "test: create new item with type zabbix_internal" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1ZabbixInternal + key: ExampleItem1ZabbixInternal host_name: ExampleHostForItem type: zabbix_internal + value_type: text register: zabbix_item1 - name: expect to succeed and that things changed @@ -349,11 +368,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type zabbix_internal (again)" +- name: "test: create new item with type zabbix_internal" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1ZabbixInternal + key: ExampleItem1ZabbixInternal host_name: ExampleHostForItem type: zabbix_internal + value_type: text register: zabbix_item1 - name: updating with same values should be idempotent @@ -361,11 +382,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type zabbix_agent_active" +- name: "test: create new item with type zabbix_agent_active" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1ZabbixAgentActive + key: ExampleItem1ZabbixAgentActive host_name: ExampleHostForItem type: zabbix_agent_active + value_type: text register: zabbix_item1 - name: expect to succeed and that things changed @@ -373,11 +396,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type zabbix_agent_active (again)" +- name: "test: create new item with type zabbix_agent_active (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1ZabbixAgentActive + key: ExampleItem1ZabbixAgentActive host_name: ExampleHostForItem type: zabbix_agent_active + value_type: text register: zabbix_item1 - name: updating with same values should be idempotent @@ -385,11 +410,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type external_check with dns specified interface" +- name: "test: create new item with type external_check with dns specified interface" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1ExternalCheck + key: ExampleItem1ExternalCheck host_name: ExampleHostForItem type: external_check + value_type: text interface: test-interface.zabbix.test:10050 register: zabbix_item1 @@ -398,11 +425,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type external_check with dns specified interface (again)" +- name: "test: create new item with type external_check with dns specified interface (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1ExternalCheck + key: ExampleItem1ExternalCheck host_name: ExampleHostForItem type: external_check + value_type: text interface: test-interface.zabbix.test:10050 register: zabbix_item1 @@ -411,11 +440,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type database_monitor" +- name: "test: create new item with type database_monitor" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1DatabaseMonitor + key: ExampleItem1DatabaseMonitor host_name: ExampleHostForItem type: database_monitor + value_type: text db_query: SELECT * FROM test username: test password: test @@ -426,11 +457,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type database_monitor (again)" +- name: "test: create new item with type database_monitor (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1DatabaseMonitor + key: ExampleItem1DatabaseMonitor host_name: ExampleHostForItem type: database_monitor + value_type: text db_query: SELECT * FROM test username: test password: test @@ -441,11 +474,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type ipmi" +- name: "test: create new item with type ipmi" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Ipmi + key: ExampleItem1Ipmi host_name: ExampleHostForItem type: ipmi + value_type: text ipmi_sensor: root interface: 10.1.1.1:12346 register: zabbix_item1 @@ -455,11 +490,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type ipmi (again)" +- name: "test: create new item with type ipmi (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Ipmi + key: ExampleItem1Ipmi host_name: ExampleHostForItem type: ipmi + value_type: text ipmi_sensor: root interface: 10.1.1.1:12346 register: zabbix_item1 @@ -469,11 +506,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type ssh using password" +- name: "test: create new item with type ssh using password" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Ssh + key: ExampleItem1Ssh host_name: ExampleHostForItem type: ssh + value_type: text update_interval: 10m authtype: password username: root @@ -487,11 +526,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type ssh using password (again)" +- name: "test: create new item with type ssh using password (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Ssh + key: ExampleItem1Ssh host_name: ExampleHostForItem type: ssh + value_type: text update_interval: 10m authtype: password username: root @@ -507,7 +548,7 @@ - name: "test: change type ssh using publickey" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Ssh host_name: ExampleHostForItem type: ssh update_interval: 10m @@ -526,7 +567,7 @@ - name: "test: change type ssh using publickey (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Ssh host_name: ExampleHostForItem type: ssh update_interval: 10m @@ -543,11 +584,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type telnet" +- name: "test: create new item with type telnet" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Telnet + key: ExampleItem1Telnet host_name: ExampleHostForItem type: telnet + value_type: text update_interval: 10m authtype: publickey username: root @@ -561,11 +604,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type telnet (again)" +- name: "test: create new item with type telnet (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Telnet + key: ExampleItem1Telnet host_name: ExampleHostForItem type: telnet + value_type: text update_interval: 10m authtype: publickey username: root @@ -579,11 +624,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type calculated" +- name: "test: create new item with type calculated" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Calculated + key: ExampleItem1Calculated host_name: ExampleHostForItem type: calculated + value_type: text update_interval: 10m script: 1 + 1 register: zabbix_item1 @@ -593,11 +640,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type calculated (again)" +- name: "test: create new item with type calculated (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Calculated + key: ExampleItem1Calculated host_name: ExampleHostForItem type: calculated + value_type: text update_interval: 10m script: 1 + 1 register: zabbix_item1 @@ -607,11 +656,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type jmx" +- name: "test: create new item with type jmx" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Jmx + key: ExampleItem1Jmx host_name: ExampleHostForItem type: jmx + value_type: text update_interval: 10m interface: 10.1.1.1:77 jmx_endpoint: service:jmx @@ -624,11 +675,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type jmx (again)" +- name: "test: create new item with type jmx (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Jmx + key: ExampleItem1Jmx host_name: ExampleHostForItem type: jmx + value_type: text update_interval: 10m interface: 10.1.1.1:77 jmx_endpoint: service:jmx @@ -641,12 +694,15 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type snmp_trap" +- name: "test: create new item with type snmp_trap" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1SnmpTrap + key: ExampleItem1SnmpTrap host_name: ExampleHostForItem type: snmp_trap + value_type: text interface: 10.1.1.1:12345 + update_interval: 0 register: zabbix_item1 - name: expect to succeed and that things changed @@ -654,12 +710,15 @@ that: - "zabbix_item1 is changed" -- name: "test: change type snmp_trap (again)" +- name: "test: create new item with type snmp_trap (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1SnmpTrap + key: ExampleItem1SnmpTrap host_name: ExampleHostForItem type: snmp_trap + value_type: text interface: 10.1.1.1:12345 + update_interval: 0 register: zabbix_item1 - name: updating with same values should be idempotent @@ -677,12 +736,15 @@ update_interval: 1m register: zabbix_item1 -- name: "test: change type dependent" +- name: "test: create new item with type dependent" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Dependent + key: ExampleItem1Dependent host_name: ExampleHostForItem type: dependent + value_type: text master_item: ExampleMasterItem + update_interval: 0 register: zabbix_item1 - name: expect to succeed and that things changed @@ -690,12 +752,15 @@ that: - "zabbix_item1 is changed" -- name: "test: change type dependent (again)" +- name: "test: create new item with type dependent (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Dependent + key: ExampleItem1Dependent host_name: ExampleHostForItem type: dependent + value_type: text master_item: ExampleMasterItem + update_interval: 0 register: zabbix_item1 - name: updating with same values should be idempotent @@ -703,11 +768,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type http no auth" +- name: "test: create new item with type http no auth" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http + key: ExampleItem1Http host_name: ExampleHostForItem type: http + value_type: text update_interval: 1m interface: 10.1.1.1:10050 allow_traps: true @@ -742,11 +809,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type http no auth (again)" +- name: "test: create new item with type http no auth (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http + key: ExampleItem1Http host_name: ExampleHostForItem type: http + value_type: text update_interval: 1m interface: 10.1.1.1:10050 allow_traps: true @@ -783,7 +852,7 @@ - name: "test: change type http basic auth" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem authtype: basic register: zabbix_item1 @@ -795,7 +864,7 @@ - name: "test: change type http no auth (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem authtype: basic register: zabbix_item1 @@ -807,7 +876,7 @@ - name: "test: change type http ntlm auth" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem type: http authtype: ntlm @@ -820,7 +889,7 @@ - name: "test: change type http ntlm auth (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem type: http authtype: ntlm @@ -833,7 +902,7 @@ - name: "test: change type http kerberos auth" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem type: http authtype: kerberos @@ -846,7 +915,7 @@ - name: "test: change type http kerberos auth (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem type: http authtype: kerberos @@ -859,7 +928,7 @@ - name: "test: change type http body_type json" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem body_type: json body: { @@ -874,7 +943,7 @@ - name: "test: change type http body_type json (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem body_type: json body: { @@ -889,7 +958,7 @@ - name: "test: change type http body_type xml" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem body_type: xml body: "" @@ -902,7 +971,7 @@ - name: "test: change type http body_type xml (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem body_type: xml body: "" @@ -915,7 +984,7 @@ - name: "test: change type http http_method POST" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem http_method: POST register: zabbix_item1 @@ -927,7 +996,7 @@ - name: "test: change type http http_method POST (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem http_method: POST register: zabbix_item1 @@ -939,7 +1008,7 @@ - name: "test: change type http http_method PUT" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem http_method: PUT register: zabbix_item1 @@ -951,7 +1020,7 @@ - name: "test: change type http http_method PUT (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem http_method: PUT register: zabbix_item1 @@ -963,7 +1032,7 @@ - name: "test: change type http http_method HEAD" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem http_method: HEAD register: zabbix_item1 @@ -975,7 +1044,7 @@ - name: "test: change type http http_method HEAD (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Http host_name: ExampleHostForItem http_method: HEAD register: zabbix_item1 @@ -985,11 +1054,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type snmp_agent" +- name: "test: create new item with type snmp_agent" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1SnmpAgent + key: ExampleItem1SnmpAgent host_name: ExampleHostForItem type: snmp_agent + value_type: text interface: 10.1.1.1:12345 snmp_oid: .1 update_interval: 10m @@ -1000,11 +1071,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type snmp_agent (again)" +- name: "test: create new item with type snmp_agent (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1SnmpAgent + key: ExampleItem1SnmpAgent host_name: ExampleHostForItem type: snmp_agent + value_type: text interface: 10.1.1.1:12345 snmp_oid: .1 update_interval: 10m @@ -1015,11 +1088,13 @@ that: - "not zabbix_item1 is changed" -- name: "test: change type script" +- name: "test: create new item with type script" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Script + key: ExampleItem1Script host_name: ExampleHostForItem type: script + value_type: text update_interval: 10m script: echo "test" parameters: { @@ -1033,11 +1108,13 @@ that: - "zabbix_item1 is changed" -- name: "test: change type script (again)" +- name: "test: create new item with type script (again)" community.zabbix.zabbix_item: - item_name: ExampleItem1 + item_name: ExampleItem1Script + key: ExampleItem1Script host_name: ExampleHostForItem type: script + value_type: text update_interval: 10m script: echo "test" parameters: {