From 24405289fe16e4a703928ae5022f6b348fb695ad Mon Sep 17 00:00:00 2001 From: Dusan Matejka Date: Mon, 16 Mar 2020 11:55:34 +0100 Subject: [PATCH] removing zabbix modules and their references due to migration to a dedicated collection (#11) --- .github/BOTMETA.yml | 66 - meta/routing.yml | 8 - plugins/doc_fragments/zabbix.py | 50 - .../monitoring/zabbix/zabbix_action.py | 2113 ----------------- .../modules/monitoring/zabbix/zabbix_group.py | 208 -- .../monitoring/zabbix/zabbix_group_facts.py | 1 - .../monitoring/zabbix/zabbix_group_info.py | 132 - .../modules/monitoring/zabbix/zabbix_host.py | 1058 --------- .../zabbix/zabbix_host_events_info.py | 336 --- .../monitoring/zabbix/zabbix_host_facts.py | 1 - .../monitoring/zabbix/zabbix_host_info.py | 252 -- .../monitoring/zabbix/zabbix_hostmacro.py | 264 -- .../monitoring/zabbix/zabbix_maintenance.py | 402 ---- .../modules/monitoring/zabbix/zabbix_map.py | 829 ------- .../monitoring/zabbix/zabbix_mediatype.py | 705 ------ .../modules/monitoring/zabbix/zabbix_proxy.py | 471 ---- .../monitoring/zabbix/zabbix_screen.py | 471 ---- .../monitoring/zabbix/zabbix_service.py | 291 --- .../monitoring/zabbix/zabbix_template.py | 795 ------- .../monitoring/zabbix/zabbix_template_info.py | 273 --- .../modules/monitoring/zabbix/zabbix_user.py | 663 ------ .../monitoring/zabbix/zabbix_user_info.py | 175 -- .../monitoring/zabbix/zabbix_valuemap.py | 339 --- scripts/inventory/zabbix.ini | 20 - scripts/inventory/zabbix.py | 196 -- .../integration/targets/setup_zabbix/aliases | 5 - .../targets/setup_zabbix/defaults/main.yml | 13 - .../targets/setup_zabbix/handlers/main.yml | 15 - .../targets/setup_zabbix/meta/main.yml | 2 - .../targets/setup_zabbix/tasks/main.yml | 3 - .../targets/setup_zabbix/tasks/setup.yml | 75 - .../setup_zabbix/templates/zabbix.conf.php.j2 | 20 - .../templates/zabbix_server.conf.j2 | 7 - tests/integration/targets/zabbix_host/aliases | 6 - .../targets/zabbix_host/defaults/main.yml | 5 - .../targets/zabbix_host/meta/main.yml | 2 - .../targets/zabbix_host/tasks/main.yml | 16 - .../zabbix_host/tasks/zabbix_host_doc.yml | 83 - .../zabbix_host/tasks/zabbix_host_setup.yml | 20 - .../tasks/zabbix_host_teardown.yml | 10 - .../zabbix_host/tasks/zabbix_host_tests.yml | 1169 --------- .../targets/zabbix_template/aliases | 6 - .../targets/zabbix_template/defaults/main.yml | 5 - .../targets/zabbix_template/meta/main.yml | 2 - .../targets/zabbix_template/tasks/main.yml | 159 -- tests/integration/targets/zabbix_user/aliases | 6 - .../targets/zabbix_user/defaults/main.yml | 5 - .../targets/zabbix_user/meta/main.yml | 2 - .../targets/zabbix_user/tasks/main.yml | 912 ------- tests/sanity/ignore-2.10.txt | 32 +- tests/sanity/ignore-2.9.txt | 32 +- 51 files changed, 2 insertions(+), 12729 deletions(-) delete mode 100644 plugins/doc_fragments/zabbix.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_action.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_group.py delete mode 120000 plugins/modules/monitoring/zabbix/zabbix_group_facts.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_group_info.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_host.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_host_events_info.py delete mode 120000 plugins/modules/monitoring/zabbix/zabbix_host_facts.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_host_info.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_hostmacro.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_maintenance.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_map.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_mediatype.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_proxy.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_screen.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_service.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_template.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_template_info.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_user.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_user_info.py delete mode 100644 plugins/modules/monitoring/zabbix/zabbix_valuemap.py delete mode 100644 scripts/inventory/zabbix.ini delete mode 100644 scripts/inventory/zabbix.py delete mode 100644 tests/integration/targets/setup_zabbix/aliases delete mode 100644 tests/integration/targets/setup_zabbix/defaults/main.yml delete mode 100644 tests/integration/targets/setup_zabbix/handlers/main.yml delete mode 100644 tests/integration/targets/setup_zabbix/meta/main.yml delete mode 100644 tests/integration/targets/setup_zabbix/tasks/main.yml delete mode 100644 tests/integration/targets/setup_zabbix/tasks/setup.yml delete mode 100644 tests/integration/targets/setup_zabbix/templates/zabbix.conf.php.j2 delete mode 100644 tests/integration/targets/setup_zabbix/templates/zabbix_server.conf.j2 delete mode 100644 tests/integration/targets/zabbix_host/aliases delete mode 100644 tests/integration/targets/zabbix_host/defaults/main.yml delete mode 100644 tests/integration/targets/zabbix_host/meta/main.yml delete mode 100644 tests/integration/targets/zabbix_host/tasks/main.yml delete mode 100644 tests/integration/targets/zabbix_host/tasks/zabbix_host_doc.yml delete mode 100644 tests/integration/targets/zabbix_host/tasks/zabbix_host_setup.yml delete mode 100644 tests/integration/targets/zabbix_host/tasks/zabbix_host_teardown.yml delete mode 100644 tests/integration/targets/zabbix_host/tasks/zabbix_host_tests.yml delete mode 100644 tests/integration/targets/zabbix_template/aliases delete mode 100644 tests/integration/targets/zabbix_template/defaults/main.yml delete mode 100644 tests/integration/targets/zabbix_template/meta/main.yml delete mode 100644 tests/integration/targets/zabbix_template/tasks/main.yml delete mode 100644 tests/integration/targets/zabbix_user/aliases delete mode 100644 tests/integration/targets/zabbix_user/defaults/main.yml delete mode 100644 tests/integration/targets/zabbix_user/meta/main.yml delete mode 100644 tests/integration/targets/zabbix_user/tasks/main.yml diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index eae63a78bd..65d98acf01 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -160,7 +160,6 @@ files: $doc_fragments/xenserver.py: maintainers: bvitnik labels: xenserver - $doc_fragments/zabbix.py: $filters/gcp_kms_filters.py: $filters/json_query.py: $filters/random_mac.py: @@ -1181,70 +1180,6 @@ files: authors: bhcopeland $modules/monitoring/uptimerobot.py: authors: nate-kingsley - $modules/monitoring/zabbix/: - authors: sky-joker - maintainers: D3DeFi rubentsirunyan - ignore: ryansb - $modules/monitoring/zabbix/zabbix_action.py: - authors: K-DOT rubentsirunyan - maintainers: D3DeFi sky-joker - ignore: ryansb - $modules/monitoring/zabbix/zabbix_group.py: - authors: cove harrisongu - maintainers: $team_zabbix - ignore: cove - $modules/monitoring/zabbix/zabbix_group_info.py: - authors: RedWhiteMiko - maintainers: $team_zabbix - ignore: ryansb - $modules/monitoring/zabbix/zabbix_host.py: - authors: cove dj-wasabi eikef harrisongu - maintainers: $team_zabbix - ignore: cove - $modules/monitoring/zabbix/zabbix_host_events_info.py: - authors: stravassac - maintainers: $team_zabbix - ignore: ryansb - $modules/monitoring/zabbix/zabbix_host_info.py: - authors: RedWhiteMiko - maintainers: $team_zabbix - ignore: ryansb - $modules/monitoring/zabbix/zabbix_hostmacro.py: - authors: cove - maintainers: $team_zabbix - ignore: cove - $modules/monitoring/zabbix/zabbix_maintenance.py: - authors: abulimov - maintainers: $team_zabbix - ignore: ryansb - $modules/monitoring/zabbix/zabbix_map.py: - authors: Akint - maintainers: $team_zabbix - ignore: ryansb - $modules/monitoring/zabbix/zabbix_mediatype.py: - authors: rubentsirunyan - maintainers: D3DeFi sky-joker - ignore: ryansb - $modules/monitoring/zabbix/zabbix_proxy.py: - authors: akomic - maintainers: $team_zabbix - ignore: ryansb - $modules/monitoring/zabbix/zabbix_screen.py: - authors: cove harrisongu - maintainers: $team_zabbix - ignore: cove - $modules/monitoring/zabbix/zabbix_service.py: - authors: emriver - maintainers: $team_zabbix - ignore: ryansb - $modules/monitoring/zabbix/zabbix_template.py: - authors: D3DeFi logan2211 sookido - maintainers: rubentsirunyan sky-joker - ignore: ryansb - $modules/monitoring/zabbix/zabbix_valuemap.py: - authors: rubentsirunyan - maintainers: D3DeFi sky-joker - ignore: ryansb $modules/net_tools/cloudflare_dns.py: authors: mgruener maintainers: andreaso @@ -2302,4 +2237,3 @@ macros: team_suse: commel dcermak evrardjp lrupp toabctl team_virt: joshainglis karmab team_vultr: Spredzy resmo - team_zabbix: D3DeFi rubentsirunyan sky-joker diff --git a/meta/routing.yml b/meta/routing.yml index 29dcf22093..109b8a8b7d 100644 --- a/meta/routing.yml +++ b/meta/routing.yml @@ -608,14 +608,6 @@ plugin_routing: deprecation: removal_date: TBD warning_text: see plugin documentation for details - zabbix_group_facts: - deprecation: - removal_date: TBD - warning_text: see plugin documentation for details - zabbix_host_facts: - deprecation: - removal_date: TBD - warning_text: see plugin documentation for details ldap_attr: deprecation: removal_date: TBD diff --git a/plugins/doc_fragments/zabbix.py b/plugins/doc_fragments/zabbix.py deleted file mode 100644 index 83f5c18efc..0000000000 --- a/plugins/doc_fragments/zabbix.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright: (c) 2017, Ansible, Inc -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - - -class ModuleDocFragment(object): - - # Standard documentation fragment - DOCUMENTATION = r''' -options: - server_url: - description: - - URL of Zabbix server, with protocol (http or https). - C(url) is an alias for C(server_url). - required: true - type: str - aliases: [ url ] - login_user: - description: - - Zabbix user name. - type: str - required: true - login_password: - description: - - Zabbix user password. - type: str - required: true - http_login_user: - description: - - Basic Auth login - type: str - http_login_password: - description: - - Basic Auth password - type: str - timeout: - description: - - The timeout of API request (seconds). - type: int - default: 10 - validate_certs: - description: - - If set to False, SSL certificates will not be validated. This should only be used on personally controlled sites using self-signed certificates. - type: bool - default: yes -notes: - - If you use I(login_password=zabbix), the word "zabbix" is replaced by "********" in all module output, because I(login_password) uses C(no_log). - See L(this FAQ,https://docs.ansible.com/ansible/latest/network/user_guide/faq.html#why-is-my-output-sometimes-replaced-with) for more information. -''' diff --git a/plugins/modules/monitoring/zabbix/zabbix_action.py b/plugins/modules/monitoring/zabbix/zabbix_action.py deleted file mode 100644 index af0743ef35..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_action.py +++ /dev/null @@ -1,2113 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# 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 - - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community' -} - -DOCUMENTATION = ''' ---- -module: zabbix_action - -short_description: Create/Delete/Update Zabbix actions - - -description: - - This module allows you to create, modify and delete Zabbix actions. - -author: - - Ruben Tsirunyan (@rubentsirunyan) - - Ruben Harutyunov (@K-DOT) - -requirements: - - "zabbix-api >= 0.5.4" - -options: - name: - description: - - Name of the action - required: true - event_source: - description: - - Type of events that the action will handle. - - Required when C(state=present). - required: false - choices: ['trigger', 'discovery', 'auto_registration', 'internal'] - state: - description: - - State of the action. - - On C(present), it will create an action if it does not exist or update the action if the associated data is different. - - On C(absent), it will remove the action if it exists. - choices: ['present', 'absent'] - default: 'present' - status: - description: - - Status of the action. - choices: ['enabled', 'disabled'] - default: 'enabled' - pause_in_maintenance: - description: - - Whether to pause escalation during maintenance periods or not. - - Can be used when I(event_source=trigger). - type: 'bool' - default: true - esc_period: - description: - - Default operation step duration. Must be greater than 60 seconds. - - Accepts only seconds in int for <= Zabbix 3.2 - - Accepts seconds, time unit with suffix and user macro since => Zabbix 3.4 - - Required when C(state=present). - required: false - conditions: - type: list - description: - - List of dictionaries of conditions to evaluate. - - For more information about suboptions of this option please - check out Zabbix API documentation U(https://www.zabbix.com/documentation/4.0/manual/api/reference/action/object#action_filter_condition) - suboptions: - type: - description: - - Type (label) of the condition. - - 'Possible values when I(event_source=trigger):' - - ' - C(host_group)' - - ' - C(host)' - - ' - C(trigger)' - - ' - C(trigger_name)' - - ' - C(trigger_severity)' - - ' - C(time_period)' - - ' - C(host_template)' - - ' - C(application)' - - ' - C(maintenance_status)' - - ' - C(event_tag)' - - ' - C(event_tag_value)' - - 'Possible values when I(event_source=discovery):' - - ' - C(host_IP)' - - ' - C(discovered_service_type)' - - ' - C(discovered_service_port)' - - ' - C(discovery_status)' - - ' - C(uptime_or_downtime_duration)' - - ' - C(received_value)' - - ' - C(discovery_rule)' - - ' - C(discovery_check)' - - ' - C(proxy)' - - ' - C(discovery_object)' - - 'Possible values when I(event_source=auto_registration):' - - ' - C(proxy)' - - ' - C(host_name)' - - ' - C(host_metadata)' - - 'Possible values when I(event_source=internal):' - - ' - C(host_group)' - - ' - C(host)' - - ' - C(host_template)' - - ' - C(application)' - - ' - C(event_type)' - value: - description: - - Value to compare with. - - 'When I(type=discovery_status), the choices are:' - - ' - C(up)' - - ' - C(down)' - - ' - C(discovered)' - - ' - C(lost)' - - 'When I(type=discovery_object), the choices are:' - - ' - C(host)' - - ' - C(service)' - - 'When I(type=event_type), the choices are:' - - ' - C(item in not supported state)' - - ' - C(item in normal state)' - - ' - C(LLD rule in not supported state)' - - ' - C(LLD rule in normal state)' - - ' - C(trigger in unknown state)' - - ' - C(trigger in normal state)' - - 'When I(type=trigger_severity), the choices are (case-insensitive):' - - ' - C(not classified)' - - ' - C(information)' - - ' - C(warning)' - - ' - C(average)' - - ' - C(high)' - - ' - C(disaster)' - - Irrespective of user-visible names being changed in Zabbix. Defaults to C(not classified) if omitted. - - Besides the above options, this is usually either the name - of the object or a string to compare with. - operator: - description: - - Condition operator. - - When I(type) is set to C(time_period), the choices are C(in), C(not in). - - C(matches), C(does not match), C(Yes) and C(No) condition operators work only with >= Zabbix 4.0 - choices: - - '=' - - '<>' - - 'like' - - 'not like' - - 'in' - - '>=' - - '<=' - - 'not in' - - 'matches' - - 'does not match' - - 'Yes' - - 'No' - formulaid: - description: - - Arbitrary unique ID that is used to reference the condition from a custom expression. - - Can only contain upper-case letters. - - Required for custom expression filters. - eval_type: - description: - - Filter condition evaluation method. - - Defaults to C(andor) if conditions are less then 2 or if - I(formula) is not specified. - - Defaults to C(custom_expression) when formula is specified. - choices: - - 'andor' - - 'and' - - 'or' - - 'custom_expression' - formula: - description: - - User-defined expression to be used for evaluating conditions of filters with a custom expression. - - The expression must contain IDs that reference specific filter conditions by its formulaid. - - The IDs used in the expression must exactly match the ones - defined in the filter conditions. No condition can remain unused or omitted. - - Required for custom expression filters. - - Use sequential IDs that start at "A". If non-sequential IDs are used, Zabbix re-indexes them. - This makes each module run notice the difference in IDs and update the action. - default_message: - description: - - Problem message default text. - default_subject: - description: - - Problem message default subject. - recovery_default_message: - description: - - Recovery message text. - - Works only with >= Zabbix 3.2 - recovery_default_subject: - description: - - Recovery message subject. - - Works only with >= Zabbix 3.2 - acknowledge_default_message: - description: - - Update operation (known as "Acknowledge operation" before Zabbix 4.0) message text. - - Works only with >= Zabbix 3.4 - acknowledge_default_subject: - description: - - Update operation (known as "Acknowledge operation" before Zabbix 4.0) message subject. - - Works only with >= Zabbix 3.4 - operations: - type: list - description: - - List of action operations - suboptions: - type: - description: - - Type of operation. - choices: - - send_message - - remote_command - - add_host - - remove_host - - add_to_host_group - - remove_from_host_group - - link_to_template - - unlink_from_template - - enable_host - - disable_host - - set_host_inventory_mode - esc_period: - description: - - Duration of an escalation step in seconds. - - Must be greater than 60 seconds. - - Accepts only seconds in int for <= Zabbix 3.2 - - Accepts seconds, time unit with suffix and user macro since => Zabbix 3.4 - - If set to 0 or 0s, the default action escalation period will be used. - default: 0s - esc_step_from: - description: - - Step to start escalation from. - default: 1 - esc_step_to: - description: - - Step to end escalation at. - default: 1 - send_to_groups: - type: list - description: - - User groups to send messages to. - send_to_users: - type: list - description: - - Users (usernames or aliases) to send messages to. - message: - description: - - Operation message text. - - Will check the 'default message' and use the text from I(default_message) if this and I(default_subject) are not specified - subject: - description: - - Operation message subject. - - Will check the 'default message' and use the text from I(default_subject) if this and I(default_subject) are not specified - media_type: - description: - - Media type that will be used to send the message. - - Set to C(all) for all media types - default: 'all' - operation_condition: - type: 'str' - description: - - The action operation condition object defines a condition that must be met to perform the current operation. - choices: - - acknowledged - - not_acknowledged - host_groups: - type: list - description: - - List of host groups host should be added to. - - Required when I(type=add_to_host_group) or I(type=remove_from_host_group). - templates: - type: list - description: - - List of templates host should be linked to. - - Required when I(type=link_to_template) or I(type=unlink_from_template). - inventory: - description: - - Host inventory mode. - - Required when I(type=set_host_inventory_mode). - command_type: - description: - - Type of operation command. - - Required when I(type=remote_command). - choices: - - custom_script - - ipmi - - ssh - - telnet - - global_script - command: - description: - - Command to run. - - Required when I(type=remote_command) and I(command_type!=global_script). - execute_on: - description: - - Target on which the custom script operation command will be executed. - - Required when I(type=remote_command) and I(command_type=custom_script). - choices: - - agent - - server - - proxy - run_on_groups: - description: - - Host groups to run remote commands on. - - Required when I(type=remote_command) if I(run_on_hosts) is not set. - run_on_hosts: - description: - - Hosts to run remote commands on. - - Required when I(type=remote_command) if I(run_on_groups) is not set. - - If set to 0 the command will be run on the current host. - ssh_auth_type: - description: - - Authentication method used for SSH commands. - - Required when I(type=remote_command) and I(command_type=ssh). - choices: - - password - - public_key - ssh_privatekey_file: - description: - - Name of the private key file used for SSH commands with public key authentication. - - Required when I(type=remote_command) and I(command_type=ssh). - ssh_publickey_file: - description: - - Name of the public key file used for SSH commands with public key authentication. - - Required when I(type=remote_command) and I(command_type=ssh). - username: - description: - - User name used for authentication. - - Required when I(type=remote_command) and I(command_type in [ssh, telnet]). - password: - description: - - Password used for authentication. - - Required when I(type=remote_command) and I(command_type in [ssh, telnet]). - port: - description: - - Port number used for authentication. - - Required when I(type=remote_command) and I(command_type in [ssh, telnet]). - script_name: - description: - - The name of script used for global script commands. - - Required when I(type=remote_command) and I(command_type=global_script). - recovery_operations: - type: list - description: - - List of recovery operations. - - C(Suboptions) are the same as for I(operations). - - Works only with >= Zabbix 3.2 - acknowledge_operations: - type: list - description: - - List of acknowledge operations. - - C(Suboptions) are the same as for I(operations). - - Works only with >= Zabbix 3.4 - -notes: - - Only Zabbix >= 3.0 is supported. - - -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = ''' -# Trigger action with only one condition -- name: Deploy trigger action - zabbix_action: - server_url: "http://zabbix.example.com/zabbix/" - login_user: Admin - login_password: secret - name: "Send alerts to Admin" - event_source: 'trigger' - state: present - status: enabled - esc_period: 60 - conditions: - - type: 'trigger_severity' - operator: '>=' - value: 'Information' - operations: - - type: send_message - subject: "Something bad is happening" - message: "Come on, guys do something" - media_type: 'Email' - send_to_users: - - 'Admin' - -# Trigger action with multiple conditions and operations -- name: Deploy trigger action - zabbix_action: - server_url: "http://zabbix.example.com/zabbix/" - login_user: Admin - login_password: secret - name: "Send alerts to Admin" - event_source: 'trigger' - state: present - status: enabled - esc_period: 1m - conditions: - - type: 'trigger_name' - operator: 'like' - value: 'Zabbix agent is unreachable' - formulaid: A - - type: 'trigger_severity' - operator: '>=' - value: 'disaster' - formulaid: B - formula: A or B - operations: - - type: send_message - media_type: 'Email' - send_to_users: - - 'Admin' - - type: remote_command - command: 'systemctl restart zabbix-agent' - command_type: custom_script - execute_on: server - run_on_hosts: - - 0 - -# Trigger action with recovery and acknowledge operations -- name: Deploy trigger action - zabbix_action: - server_url: "http://zabbix.example.com/zabbix/" - login_user: Admin - login_password: secret - name: "Send alerts to Admin" - event_source: 'trigger' - state: present - status: enabled - esc_period: 1h - conditions: - - type: 'trigger_severity' - operator: '>=' - value: 'Information' - operations: - - type: send_message - subject: "Something bad is happening" - message: "Come on, guys do something" - media_type: 'Email' - send_to_users: - - 'Admin' - recovery_operations: - - type: send_message - subject: "Host is down" - message: "Come on, guys do something" - media_type: 'Email' - send_to_users: - - 'Admin' - acknowledge_operations: - - type: send_message - media_type: 'Email' - send_to_users: - - 'Admin' -''' - -RETURN = ''' -msg: - description: The result of the operation - returned: success - type: str - sample: 'Action Deleted: Register webservers, ID: 0001' -''' - - -import atexit -import traceback - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -class Zapi(object): - """ - A simple wrapper over the Zabbix API - """ - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - def check_if_action_exists(self, name): - """Check if action exists. - - Args: - name: Name of the action. - - Returns: - The return value. True for success, False otherwise. - - """ - try: - _action = self._zapi.action.get({ - "selectOperations": "extend", - "selectRecoveryOperations": "extend", - "selectAcknowledgeOperations": "extend", - "selectFilter": "extend", - 'selectInventory': 'extend', - 'filter': {'name': [name]} - }) - if len(_action) > 0: - _action[0]['recovery_operations'] = _action[0].pop('recoveryOperations', []) - _action[0]['acknowledge_operations'] = _action[0].pop('acknowledgeOperations', []) - return _action - except Exception as e: - self._module.fail_json(msg="Failed to check if action '%s' exists: %s" % (name, e)) - - def get_action_by_name(self, name): - """Get action by name - - Args: - name: Name of the action. - - Returns: - dict: Zabbix action - - """ - try: - action_list = self._zapi.action.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'name': [name]} - }) - if len(action_list) < 1: - self._module.fail_json(msg="Action not found: " % name) - else: - return action_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get ID of '%s': %s" % (name, e)) - - def get_host_by_host_name(self, host_name): - """Get host by host name - - Args: - host_name: host name. - - Returns: - host matching host name - - """ - try: - host_list = self._zapi.host.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'host': [host_name]} - }) - if len(host_list) < 1: - self._module.fail_json(msg="Host not found: %s" % host_name) - else: - return host_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get host '%s': %s" % (host_name, e)) - - def get_hostgroup_by_hostgroup_name(self, hostgroup_name): - """Get host group by host group name - - Args: - hostgroup_name: host group name. - - Returns: - host group matching host group name - - """ - try: - hostgroup_list = self._zapi.hostgroup.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'name': [hostgroup_name]} - }) - if len(hostgroup_list) < 1: - self._module.fail_json(msg="Host group not found: %s" % hostgroup_name) - else: - return hostgroup_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get host group '%s': %s" % (hostgroup_name, e)) - - def get_template_by_template_name(self, template_name): - """Get template by template name - - Args: - template_name: template name. - - Returns: - template matching template name - - """ - try: - template_list = self._zapi.template.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'host': [template_name]} - }) - if len(template_list) < 1: - self._module.fail_json(msg="Template not found: %s" % template_name) - else: - return template_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get template '%s': %s" % (template_name, e)) - - def get_trigger_by_trigger_name(self, trigger_name): - """Get trigger by trigger name - - Args: - trigger_name: trigger name. - - Returns: - trigger matching trigger name - - """ - try: - trigger_list = self._zapi.trigger.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'description': [trigger_name]} - }) - if len(trigger_list) < 1: - self._module.fail_json(msg="Trigger not found: %s" % trigger_name) - else: - return trigger_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get trigger '%s': %s" % (trigger_name, e)) - - def get_discovery_rule_by_discovery_rule_name(self, discovery_rule_name): - """Get discovery rule by discovery rule name - - Args: - discovery_rule_name: discovery rule name. - - Returns: - discovery rule matching discovery rule name - - """ - try: - discovery_rule_list = self._zapi.drule.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'name': [discovery_rule_name]} - }) - if len(discovery_rule_list) < 1: - self._module.fail_json(msg="Discovery rule not found: %s" % discovery_rule_name) - else: - return discovery_rule_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get discovery rule '%s': %s" % (discovery_rule_name, e)) - - def get_discovery_check_by_discovery_check_name(self, discovery_check_name): - """Get discovery check by discovery check name - - Args: - discovery_check_name: discovery check name. - - Returns: - discovery check matching discovery check name - - """ - try: - discovery_check_list = self._zapi.dcheck.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'name': [discovery_check_name]} - }) - if len(discovery_check_list) < 1: - self._module.fail_json(msg="Discovery check not found: %s" % discovery_check_name) - else: - return discovery_check_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get discovery check '%s': %s" % (discovery_check_name, e)) - - def get_proxy_by_proxy_name(self, proxy_name): - """Get proxy by proxy name - - Args: - proxy_name: proxy name. - - Returns: - proxy matching proxy name - - """ - try: - proxy_list = self._zapi.proxy.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'host': [proxy_name]} - }) - if len(proxy_list) < 1: - self._module.fail_json(msg="Proxy not found: %s" % proxy_name) - else: - return proxy_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get proxy '%s': %s" % (proxy_name, e)) - - def get_mediatype_by_mediatype_name(self, mediatype_name): - """Get mediatype by mediatype name - - Args: - mediatype_name: mediatype name - - Returns: - mediatype matching mediatype name - - """ - try: - if str(mediatype_name).lower() == 'all': - return '0' - mediatype_list = self._zapi.mediatype.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'description': [mediatype_name]} - }) - if len(mediatype_list) < 1: - self._module.fail_json(msg="Media type not found: %s" % mediatype_name) - else: - return mediatype_list[0]['mediatypeid'] - except Exception as e: - self._module.fail_json(msg="Failed to get mediatype '%s': %s" % (mediatype_name, e)) - - def get_user_by_user_name(self, user_name): - """Get user by user name - - Args: - user_name: user name - - Returns: - user matching user name - - """ - try: - user_list = self._zapi.user.get({ - 'output': 'extend', - 'selectInventory': - 'extend', 'filter': {'alias': [user_name]} - }) - if len(user_list) < 1: - self._module.fail_json(msg="User not found: %s" % user_name) - else: - return user_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get user '%s': %s" % (user_name, e)) - - def get_usergroup_by_usergroup_name(self, usergroup_name): - """Get usergroup by usergroup name - - Args: - usergroup_name: usergroup name - - Returns: - usergroup matching usergroup name - - """ - try: - usergroup_list = self._zapi.usergroup.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'name': [usergroup_name]} - }) - if len(usergroup_list) < 1: - self._module.fail_json(msg="User group not found: %s" % usergroup_name) - else: - return usergroup_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get user group '%s': %s" % (usergroup_name, e)) - - # get script by script name - def get_script_by_script_name(self, script_name): - """Get script by script name - - Args: - script_name: script name - - Returns: - script matching script name - - """ - try: - if script_name is None: - return {} - script_list = self._zapi.script.get({ - 'output': 'extend', - 'selectInventory': 'extend', - 'filter': {'name': [script_name]} - }) - if len(script_list) < 1: - self._module.fail_json(msg="Script not found: %s" % script_name) - else: - return script_list[0] - except Exception as e: - self._module.fail_json(msg="Failed to get script '%s': %s" % (script_name, e)) - - -class Action(object): - """ - Restructures the user defined action data to fit the Zabbix API requirements - """ - def __init__(self, module, zbx, zapi_wrapper): - self._module = module - self._zapi = zbx - self._zapi_wrapper = zapi_wrapper - - def _construct_parameters(self, **kwargs): - """Construct parameters. - - Args: - **kwargs: Arbitrary keyword parameters. - - Returns: - dict: dictionary of specified parameters - """ - - _params = { - 'name': kwargs['name'], - 'eventsource': to_numeric_value([ - 'trigger', - 'discovery', - 'auto_registration', - 'internal'], kwargs['event_source']), - 'esc_period': kwargs.get('esc_period'), - 'filter': kwargs['conditions'], - 'def_longdata': kwargs['default_message'], - 'def_shortdata': kwargs['default_subject'], - 'r_longdata': kwargs['recovery_default_message'], - 'r_shortdata': kwargs['recovery_default_subject'], - 'ack_longdata': kwargs['acknowledge_default_message'], - 'ack_shortdata': kwargs['acknowledge_default_subject'], - 'operations': kwargs['operations'], - 'recovery_operations': kwargs.get('recovery_operations'), - 'acknowledge_operations': kwargs.get('acknowledge_operations'), - 'status': to_numeric_value([ - 'enabled', - 'disabled'], kwargs['status']) - } - if kwargs['event_source'] == 'trigger': - if float(self._zapi.api_version().rsplit('.', 1)[0]) >= 4.0: - _params['pause_suppressed'] = '1' if kwargs['pause_in_maintenance'] else '0' - else: - _params['maintenance_mode'] = '1' if kwargs['pause_in_maintenance'] else '0' - - return _params - - def check_difference(self, **kwargs): - """Check difference between action and user specified parameters. - - Args: - **kwargs: Arbitrary keyword parameters. - - Returns: - dict: dictionary of differences - """ - existing_action = convert_unicode_to_str(self._zapi_wrapper.check_if_action_exists(kwargs['name'])[0]) - parameters = convert_unicode_to_str(self._construct_parameters(**kwargs)) - change_parameters = {} - _diff = cleanup_data(compare_dictionaries(parameters, existing_action, change_parameters)) - return _diff - - def update_action(self, **kwargs): - """Update action. - - Args: - **kwargs: Arbitrary keyword parameters. - - Returns: - action: updated action - """ - try: - if self._module.check_mode: - self._module.exit_json(msg="Action would be updated if check mode was not specified: %s" % kwargs, changed=True) - kwargs['actionid'] = kwargs.pop('action_id') - return self._zapi.action.update(kwargs) - except Exception as e: - self._module.fail_json(msg="Failed to update action '%s': %s" % (kwargs['actionid'], e)) - - def add_action(self, **kwargs): - """Add action. - - Args: - **kwargs: Arbitrary keyword parameters. - - Returns: - action: added action - """ - try: - if self._module.check_mode: - self._module.exit_json(msg="Action would be added if check mode was not specified", changed=True) - parameters = self._construct_parameters(**kwargs) - action_list = self._zapi.action.create(parameters) - return action_list['actionids'][0] - except Exception as e: - self._module.fail_json(msg="Failed to create action '%s': %s" % (kwargs['name'], e)) - - def delete_action(self, action_id): - """Delete action. - - Args: - action_id: Action id - - Returns: - action: deleted action - """ - try: - if self._module.check_mode: - self._module.exit_json(msg="Action would be deleted if check mode was not specified", changed=True) - return self._zapi.action.delete([action_id]) - except Exception as e: - self._module.fail_json(msg="Failed to delete action '%s': %s" % (action_id, e)) - - -class Operations(object): - """ - Restructures the user defined operation data to fit the Zabbix API requirements - """ - def __init__(self, module, zbx, zapi_wrapper): - self._module = module - # self._zapi = zbx - self._zapi_wrapper = zapi_wrapper - - def _construct_operationtype(self, operation): - """Construct operation type. - - Args: - operation: operation to construct - - Returns: - str: constructed operation - """ - try: - return to_numeric_value([ - "send_message", - "remote_command", - "add_host", - "remove_host", - "add_to_host_group", - "remove_from_host_group", - "link_to_template", - "unlink_from_template", - "enable_host", - "disable_host", - "set_host_inventory_mode"], operation['type'] - ) - except Exception as e: - self._module.fail_json(msg="Unsupported value '%s' for operation type." % operation['type']) - - def _construct_opmessage(self, operation): - """Construct operation message. - - Args: - operation: operation to construct the message - - Returns: - dict: constructed operation message - """ - try: - return { - 'default_msg': '0' if operation.get('message') is not None or operation.get('subject')is not None else '1', - 'mediatypeid': self._zapi_wrapper.get_mediatype_by_mediatype_name( - operation.get('media_type') - ) if operation.get('media_type') is not None else '0', - 'message': operation.get('message'), - 'subject': operation.get('subject'), - } - except Exception as e: - self._module.fail_json(msg="Failed to construct operation message. The error was: %s" % e) - - def _construct_opmessage_usr(self, operation): - """Construct operation message user. - - Args: - operation: operation to construct the message user - - Returns: - list: constructed operation message user or None if operation not found - """ - if operation.get('send_to_users') is None: - return None - return [{ - 'userid': self._zapi_wrapper.get_user_by_user_name(_user)['userid'] - } for _user in operation.get('send_to_users')] - - def _construct_opmessage_grp(self, operation): - """Construct operation message group. - - Args: - operation: operation to construct the message group - - Returns: - list: constructed operation message group or None if operation not found - """ - if operation.get('send_to_groups') is None: - return None - return [{ - 'usrgrpid': self._zapi_wrapper.get_usergroup_by_usergroup_name(_group)['usrgrpid'] - } for _group in operation.get('send_to_groups')] - - def _construct_opcommand(self, operation): - """Construct operation command. - - Args: - operation: operation to construct command - - Returns: - list: constructed operation command - """ - try: - return { - 'type': to_numeric_value([ - 'custom_script', - 'ipmi', - 'ssh', - 'telnet', - 'global_script'], operation.get('command_type', 'custom_script')), - 'command': operation.get('command'), - 'execute_on': to_numeric_value([ - 'agent', - 'server', - 'proxy'], operation.get('execute_on', 'server')), - 'scriptid': self._zapi_wrapper.get_script_by_script_name( - operation.get('script_name') - ).get('scriptid'), - 'authtype': to_numeric_value([ - 'password', - 'private_key' - ], operation.get('ssh_auth_type', 'password')), - 'privatekey': operation.get('ssh_privatekey_file'), - 'publickey': operation.get('ssh_publickey_file'), - 'username': operation.get('username'), - 'password': operation.get('password'), - 'port': operation.get('port') - } - except Exception as e: - self._module.fail_json(msg="Failed to construct operation command. The error was: %s" % e) - - def _construct_opcommand_hst(self, operation): - """Construct operation command host. - - Args: - operation: operation to construct command host - - Returns: - list: constructed operation command host - """ - if operation.get('run_on_hosts') is None: - return None - return [{ - 'hostid': self._zapi_wrapper.get_host_by_host_name(_host)['hostid'] - } if str(_host) != '0' else {'hostid': '0'} for _host in operation.get('run_on_hosts')] - - def _construct_opcommand_grp(self, operation): - """Construct operation command group. - - Args: - operation: operation to construct command group - - Returns: - list: constructed operation command group - """ - if operation.get('run_on_groups') is None: - return None - return [{ - 'groupid': self._zapi_wrapper.get_hostgroup_by_hostgroup_name(_group)['hostid'] - } for _group in operation.get('run_on_groups')] - - def _construct_opgroup(self, operation): - """Construct operation group. - - Args: - operation: operation to construct group - - Returns: - list: constructed operation group - """ - return [{ - 'groupid': self._zapi_wrapper.get_hostgroup_by_hostgroup_name(_group)['groupid'] - } for _group in operation.get('host_groups', [])] - - def _construct_optemplate(self, operation): - """Construct operation template. - - Args: - operation: operation to construct template - - Returns: - list: constructed operation template - """ - return [{ - 'templateid': self._zapi_wrapper.get_template_by_template_name(_template)['templateid'] - } for _template in operation.get('templates', [])] - - def _construct_opinventory(self, operation): - """Construct operation inventory. - - Args: - operation: operation to construct inventory - - Returns: - dict: constructed operation inventory - """ - return {'inventory_mode': operation.get('inventory')} - - def _construct_opconditions(self, operation): - """Construct operation conditions. - - Args: - operation: operation to construct the conditions - - Returns: - list: constructed operation conditions - """ - _opcond = operation.get('operation_condition') - if _opcond is not None: - if _opcond == 'acknowledged': - _value = '1' - elif _opcond == 'not_acknowledged': - _value = '0' - return [{ - 'conditiontype': '14', - 'operator': '0', - 'value': _value - }] - return [] - - def construct_the_data(self, operations): - """Construct the operation data using helper methods. - - Args: - operation: operation to construct - - Returns: - list: constructed operation data - """ - constructed_data = [] - for op in operations: - operation_type = self._construct_operationtype(op) - constructed_operation = { - 'operationtype': operation_type, - 'esc_period': op.get('esc_period'), - 'esc_step_from': op.get('esc_step_from'), - 'esc_step_to': op.get('esc_step_to') - } - # Send Message type - if constructed_operation['operationtype'] == '0': - constructed_operation['opmessage'] = self._construct_opmessage(op) - constructed_operation['opmessage_usr'] = self._construct_opmessage_usr(op) - constructed_operation['opmessage_grp'] = self._construct_opmessage_grp(op) - constructed_operation['opconditions'] = self._construct_opconditions(op) - - # Send Command type - if constructed_operation['operationtype'] == '1': - constructed_operation['opcommand'] = self._construct_opcommand(op) - constructed_operation['opcommand_hst'] = self._construct_opcommand_hst(op) - constructed_operation['opcommand_grp'] = self._construct_opcommand_grp(op) - constructed_operation['opconditions'] = self._construct_opconditions(op) - - # Add to/Remove from host group - if constructed_operation['operationtype'] in ('4', '5'): - constructed_operation['opgroup'] = self._construct_opgroup(op) - - # Link/Unlink template - if constructed_operation['operationtype'] in ('6', '7'): - constructed_operation['optemplate'] = self._construct_optemplate(op) - - # Set inventory mode - if constructed_operation['operationtype'] == '10': - constructed_operation['opinventory'] = self._construct_opinventory(op) - - constructed_data.append(constructed_operation) - - return cleanup_data(constructed_data) - - -class RecoveryOperations(Operations): - """ - Restructures the user defined recovery operations data to fit the Zabbix API requirements - """ - def _construct_operationtype(self, operation): - """Construct operation type. - - Args: - operation: operation to construct type - - Returns: - str: constructed operation type - """ - try: - return to_numeric_value([ - "send_message", - "remote_command", - None, - None, - None, - None, - None, - None, - None, - None, - None, - "notify_all_involved"], operation['type'] - ) - except Exception as e: - self._module.fail_json(msg="Unsupported value '%s' for recovery operation type." % operation['type']) - - def construct_the_data(self, operations): - """Construct the recovery operations data using helper methods. - - Args: - operation: operation to construct - - Returns: - list: constructed recovery operations data - """ - constructed_data = [] - for op in operations: - operation_type = self._construct_operationtype(op) - constructed_operation = { - 'operationtype': operation_type, - } - - # Send Message type - if constructed_operation['operationtype'] in ('0', '11'): - constructed_operation['opmessage'] = self._construct_opmessage(op) - constructed_operation['opmessage_usr'] = self._construct_opmessage_usr(op) - constructed_operation['opmessage_grp'] = self._construct_opmessage_grp(op) - - # Send Command type - if constructed_operation['operationtype'] == '1': - constructed_operation['opcommand'] = self._construct_opcommand(op) - constructed_operation['opcommand_hst'] = self._construct_opcommand_hst(op) - constructed_operation['opcommand_grp'] = self._construct_opcommand_grp(op) - - constructed_data.append(constructed_operation) - - return cleanup_data(constructed_data) - - -class AcknowledgeOperations(Operations): - """ - Restructures the user defined acknowledge operations data to fit the Zabbix API requirements - """ - def _construct_operationtype(self, operation): - """Construct operation type. - - Args: - operation: operation to construct type - - Returns: - str: constructed operation type - """ - try: - return to_numeric_value([ - "send_message", - "remote_command", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "notify_all_involved"], operation['type'] - ) - except Exception as e: - self._module.fail_json(msg="Unsupported value '%s' for acknowledge operation type." % operation['type']) - - def construct_the_data(self, operations): - """Construct the acknowledge operations data using helper methods. - - Args: - operation: operation to construct - - Returns: - list: constructed acknowledge operations data - """ - constructed_data = [] - for op in operations: - operation_type = self._construct_operationtype(op) - constructed_operation = { - 'operationtype': operation_type, - } - - # Send Message type - if constructed_operation['operationtype'] in ('0', '11'): - constructed_operation['opmessage'] = self._construct_opmessage(op) - constructed_operation['opmessage_usr'] = self._construct_opmessage_usr(op) - constructed_operation['opmessage_grp'] = self._construct_opmessage_grp(op) - - # Send Command type - if constructed_operation['operationtype'] == '1': - constructed_operation['opcommand'] = self._construct_opcommand(op) - constructed_operation['opcommand_hst'] = self._construct_opcommand_hst(op) - constructed_operation['opcommand_grp'] = self._construct_opcommand_grp(op) - - constructed_data.append(constructed_operation) - - return cleanup_data(constructed_data) - - -class Filter(object): - """ - Restructures the user defined filter conditions to fit the Zabbix API requirements - """ - def __init__(self, module, zbx, zapi_wrapper): - self._module = module - self._zapi = zbx - self._zapi_wrapper = zapi_wrapper - - def _construct_evaltype(self, _eval_type, _formula, _conditions): - """Construct the eval type - - Args: - _formula: zabbix condition evaluation formula - _conditions: list of conditions to check - - Returns: - dict: constructed acknowledge operations data - """ - if len(_conditions) <= 1: - return { - 'evaltype': '0', - 'formula': None - } - if _eval_type == 'andor': - return { - 'evaltype': '0', - 'formula': None - } - if _eval_type == 'and': - return { - 'evaltype': '1', - 'formula': None - } - if _eval_type == 'or': - return { - 'evaltype': '2', - 'formula': None - } - if _eval_type == 'custom_expression': - if _formula is not None: - return { - 'evaltype': '3', - 'formula': _formula - } - else: - self._module.fail_json(msg="'formula' is required when 'eval_type' is set to 'custom_expression'") - if _formula is not None: - return { - 'evaltype': '3', - 'formula': _formula - } - return { - 'evaltype': '0', - 'formula': None - } - - def _construct_conditiontype(self, _condition): - """Construct the condition type - - Args: - _condition: condition to check - - Returns: - str: constructed condition type data - """ - try: - return to_numeric_value([ - "host_group", - "host", - "trigger", - "trigger_name", - "trigger_severity", - "trigger_value", - "time_period", - "host_ip", - "discovered_service_type", - "discovered_service_port", - "discovery_status", - "uptime_or_downtime_duration", - "received_value", - "host_template", - None, - "application", - "maintenance_status", - None, - "discovery_rule", - "discovery_check", - "proxy", - "discovery_object", - "host_name", - "event_type", - "host_metadata", - "event_tag", - "event_tag_value"], _condition['type'] - ) - except Exception as e: - self._module.fail_json(msg="Unsupported value '%s' for condition type." % _condition['type']) - - def _construct_operator(self, _condition): - """Construct operator - - Args: - _condition: condition to construct - - Returns: - str: constructed operator - """ - try: - return to_numeric_value([ - "=", - "<>", - "like", - "not like", - "in", - ">=", - "<=", - "not in", - "matches", - "does not match", - "Yes", - "No"], _condition['operator'] - ) - except Exception as e: - self._module.fail_json(msg="Unsupported value '%s' for operator." % _condition['operator']) - - def _construct_value(self, conditiontype, value): - """Construct operator - - Args: - conditiontype: type of condition to construct - value: value to construct - - Returns: - str: constructed value - """ - try: - # Host group - if conditiontype == '0': - return self._zapi_wrapper.get_hostgroup_by_hostgroup_name(value)['groupid'] - # Host - if conditiontype == '1': - return self._zapi_wrapper.get_host_by_host_name(value)['hostid'] - # Trigger - if conditiontype == '2': - return self._zapi_wrapper.get_trigger_by_trigger_name(value)['triggerid'] - # Trigger name: return as is - # Trigger severity - if conditiontype == '4': - return to_numeric_value([ - "not classified", - "information", - "warning", - "average", - "high", - "disaster"], value or "not classified" - ) - - # Trigger value - if conditiontype == '5': - return to_numeric_value([ - "ok", - "problem"], value or "ok" - ) - # Time period: return as is - # Host IP: return as is - # Discovered service type - if conditiontype == '8': - return to_numeric_value([ - "SSH", - "LDAP", - "SMTP", - "FTP", - "HTTP", - "POP", - "NNTP", - "IMAP", - "TCP", - "Zabbix agent", - "SNMPv1 agent", - "SNMPv2 agent", - "ICMP ping", - "SNMPv3 agent", - "HTTPS", - "Telnet"], value - ) - # Discovered service port: return as is - # Discovery status - if conditiontype == '10': - return to_numeric_value([ - "up", - "down", - "discovered", - "lost"], value - ) - if conditiontype == '13': - return self._zapi_wrapper.get_template_by_template_name(value)['templateid'] - if conditiontype == '18': - return self._zapi_wrapper.get_discovery_rule_by_discovery_rule_name(value)['druleid'] - if conditiontype == '19': - return self._zapi_wrapper.get_discovery_check_by_discovery_check_name(value)['dcheckid'] - if conditiontype == '20': - return self._zapi_wrapper.get_proxy_by_proxy_name(value)['proxyid'] - if conditiontype == '21': - return to_numeric_value([ - "pchldrfor0", - "host", - "service"], value - ) - if conditiontype == '23': - return to_numeric_value([ - "item in not supported state", - "item in normal state", - "LLD rule in not supported state", - "LLD rule in normal state", - "trigger in unknown state", - "trigger in normal state"], value - ) - return value - except Exception as e: - self._module.fail_json( - msg="""Unsupported value '%s' for specified condition type. - Check out Zabbix API documentation for supported values for - condition type '%s' at - https://www.zabbix.com/documentation/3.4/manual/api/reference/action/object#action_filter_condition""" % (value, conditiontype) - ) - - def construct_the_data(self, _eval_type, _formula, _conditions): - """Construct the user defined filter conditions to fit the Zabbix API - requirements operations data using helper methods. - - Args: - _formula: zabbix condition evaluation formula - _conditions: conditions to construct - - Returns: - dict: user defined filter conditions - """ - if _conditions is None: - return None - constructed_data = {} - constructed_data['conditions'] = [] - for cond in _conditions: - condition_type = self._construct_conditiontype(cond) - constructed_data['conditions'].append({ - "conditiontype": condition_type, - "value": self._construct_value(condition_type, cond.get("value")), - "value2": cond.get("value2"), - "formulaid": cond.get("formulaid"), - "operator": self._construct_operator(cond) - }) - _constructed_evaltype = self._construct_evaltype( - _eval_type, - _formula, - constructed_data['conditions'] - ) - constructed_data['evaltype'] = _constructed_evaltype['evaltype'] - constructed_data['formula'] = _constructed_evaltype['formula'] - return cleanup_data(constructed_data) - - -def convert_unicode_to_str(data): - """Converts unicode objects to strings in dictionary - args: - data: unicode object - - Returns: - dict: strings in dictionary - """ - if isinstance(data, dict): - return dict(map(convert_unicode_to_str, data.items())) - elif isinstance(data, (list, tuple, set)): - return type(data)(map(convert_unicode_to_str, data)) - elif data is None: - return data - else: - return str(data) - - -def to_numeric_value(strs, value): - """Converts string values to integers - Args: - value: string value - - Returns: - int: converted integer - """ - strs = [s.lower() if isinstance(s, str) else s for s in strs] - value = value.lower() - tmp_dict = dict(zip(strs, list(range(len(strs))))) - return str(tmp_dict[value]) - - -def compare_lists(l1, l2, diff_dict): - """ - Compares l1 and l2 lists and adds the items that are different - to the diff_dict dictionary. - Used in recursion with compare_dictionaries() function. - Args: - l1: first list to compare - l2: second list to compare - diff_dict: dictionary to store the difference - - Returns: - dict: items that are different - """ - if len(l1) != len(l2): - diff_dict.append(l1) - return diff_dict - for i, item in enumerate(l1): - if isinstance(item, dict): - diff_dict.insert(i, {}) - diff_dict[i] = compare_dictionaries(item, l2[i], diff_dict[i]) - else: - if item != l2[i]: - diff_dict.append(item) - while {} in diff_dict: - diff_dict.remove({}) - return diff_dict - - -def compare_dictionaries(d1, d2, diff_dict): - """ - Compares d1 and d2 dictionaries and adds the items that are different - to the diff_dict dictionary. - Used in recursion with compare_lists() function. - Args: - d1: first dictionary to compare - d2: second dictionary to compare - diff_dict: dictionary to store the difference - - Returns: - dict: items that are different - """ - for k, v in d1.items(): - if k not in d2: - diff_dict[k] = v - continue - if isinstance(v, dict): - diff_dict[k] = {} - compare_dictionaries(v, d2[k], diff_dict[k]) - if diff_dict[k] == {}: - del diff_dict[k] - else: - diff_dict[k] = v - elif isinstance(v, list): - diff_dict[k] = [] - compare_lists(v, d2[k], diff_dict[k]) - if diff_dict[k] == []: - del diff_dict[k] - else: - diff_dict[k] = v - else: - if v != d2[k]: - diff_dict[k] = v - return diff_dict - - -def cleanup_data(obj): - """Removes the None values from the object and returns the object - Args: - obj: object to cleanup - - Returns: - object: cleaned object - """ - if isinstance(obj, (list, tuple, set)): - return type(obj)(cleanup_data(x) for x in obj if x is not None) - elif isinstance(obj, dict): - return type(obj)((cleanup_data(k), cleanup_data(v)) - for k, v in obj.items() if k is not None and v is not None) - else: - return obj - - -def main(): - """Main ansible module function - """ - - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - esc_period=dict(type='str', required=False), - timeout=dict(type='int', default=10), - name=dict(type='str', required=True), - event_source=dict(type='str', required=False, choices=['trigger', 'discovery', 'auto_registration', 'internal']), - state=dict(type='str', required=False, default='present', choices=['present', 'absent']), - status=dict(type='str', required=False, default='enabled', choices=['enabled', 'disabled']), - pause_in_maintenance=dict(type='bool', required=False, default=True), - default_message=dict(type='str', required=False, default=''), - default_subject=dict(type='str', required=False, default=''), - recovery_default_message=dict(type='str', required=False, default=''), - recovery_default_subject=dict(type='str', required=False, default=''), - acknowledge_default_message=dict(type='str', required=False, default=''), - acknowledge_default_subject=dict(type='str', required=False, default=''), - conditions=dict( - type='list', - required=False, - default=[], - elements='dict', - options=dict( - formulaid=dict(type='str', required=False), - operator=dict(type='str', required=True), - type=dict(type='str', required=True), - value=dict(type='str', required=True), - value2=dict(type='str', required=False) - ) - ), - formula=dict(type='str', required=False, default=None), - eval_type=dict(type='str', required=False, default=None, choices=['andor', 'and', 'or', 'custom_expression']), - operations=dict( - type='list', - required=False, - default=[], - elements='dict', - options=dict( - type=dict( - type='str', - required=True, - choices=[ - 'send_message', - 'remote_command', - 'add_host', - 'remove_host', - 'add_to_host_group', - 'remove_from_host_group', - 'link_to_template', - 'unlink_from_template', - 'enable_host', - 'disable_host', - 'set_host_inventory_mode', - ] - ), - esc_period=dict(type='str', required=False), - esc_step_from=dict(type='int', required=False, default=1), - esc_step_to=dict(type='int', required=False, default=1), - operation_condition=dict( - type='str', - required=False, - default=None, - choices=['acknowledged', 'not_acknowledged'] - ), - # when type is remote_command - command_type=dict( - type='str', - required=False, - choices=[ - 'custom_script', - 'ipmi', - 'ssh', - 'telnet', - 'global_script' - ] - ), - command=dict(type='str', required=False), - execute_on=dict( - type='str', - required=False, - choices=['agent', 'server', 'proxy'] - ), - password=dict(type='str', required=False), - port=dict(type='int', required=False), - run_on_groups=dict(type='list', required=False), - run_on_hosts=dict(type='list', required=False), - script_name=dict(type='str', required=False), - ssh_auth_type=dict( - type='str', - required=False, - default='password', - choices=['password', 'public_key'] - ), - ssh_privatekey_file=dict(type='str', required=False), - ssh_publickey_file=dict(type='str', required=False), - username=dict(type='str', required=False), - # when type is send_message - media_type=dict(type='str', required=False), - subject=dict(type='str', required=False), - message=dict(type='str', required=False), - send_to_groups=dict(type='list', required=False), - send_to_users=dict(type='list', required=False), - # when type is add_to_host_group or remove_from_host_group - host_groups=dict(type='list', required=False), - # when type is set_host_inventory_mode - inventory=dict(type='str', required=False), - # when type is link_to_template or unlink_from_template - templates=dict(type='list', required=False) - ), - required_if=[ - ['type', 'remote_command', ['command_type']], - ['type', 'remote_command', ['run_on_groups', 'run_on_hosts'], True], - ['command_type', 'custom_script', [ - 'command', - 'execute_on' - ]], - ['command_type', 'ipmi', ['command']], - ['command_type', 'ssh', [ - 'command', - 'password', - 'username', - 'port', - 'ssh_auth_type', - 'ssh_privatekey_file', - 'ssh_publickey_file' - ]], - ['command_type', 'telnet', [ - 'command', - 'password', - 'username', - 'port' - ]], - ['command_type', 'global_script', ['script_name']], - ['type', 'add_to_host_group', ['host_groups']], - ['type', 'remove_from_host_group', ['host_groups']], - ['type', 'link_to_template', ['templates']], - ['type', 'unlink_from_template', ['templates']], - ['type', 'set_host_inventory_mode', ['inventory']], - ['type', 'send_message', ['send_to_users', 'send_to_groups'], True] - ] - ), - recovery_operations=dict( - type='list', - required=False, - default=[], - elements='dict', - options=dict( - type=dict( - type='str', - required=True, - choices=[ - 'send_message', - 'remote_command', - 'notify_all_involved' - ] - ), - # when type is remote_command - command_type=dict( - type='str', - required=False, - choices=[ - 'custom_script', - 'ipmi', - 'ssh', - 'telnet', - 'global_script' - ] - ), - command=dict(type='str', required=False), - execute_on=dict( - type='str', - required=False, - choices=['agent', 'server', 'proxy'] - ), - password=dict(type='str', required=False), - port=dict(type='int', required=False), - run_on_groups=dict(type='list', required=False), - run_on_hosts=dict(type='list', required=False), - script_name=dict(type='str', required=False), - ssh_auth_type=dict( - type='str', - required=False, - default='password', - choices=['password', 'public_key'] - ), - ssh_privatekey_file=dict(type='str', required=False), - ssh_publickey_file=dict(type='str', required=False), - username=dict(type='str', required=False), - # when type is send_message - media_type=dict(type='str', required=False), - subject=dict(type='str', required=False), - message=dict(type='str', required=False), - send_to_groups=dict(type='list', required=False), - send_to_users=dict(type='list', required=False), - ), - required_if=[ - ['type', 'remote_command', ['command_type']], - ['type', 'remote_command', [ - 'run_on_groups', - 'run_on_hosts' - ], True], - ['command_type', 'custom_script', [ - 'command', - 'execute_on' - ]], - ['command_type', 'ipmi', ['command']], - ['command_type', 'ssh', [ - 'command', - 'password', - 'username', - 'port', - 'ssh_auth_type', - 'ssh_privatekey_file', - 'ssh_publickey_file' - ]], - ['command_type', 'telnet', [ - 'command', - 'password', - 'username', - 'port' - ]], - ['command_type', 'global_script', ['script_name']], - ['type', 'send_message', ['send_to_users', 'send_to_groups'], True] - ] - ), - acknowledge_operations=dict( - type='list', - required=False, - default=[], - elements='dict', - options=dict( - type=dict( - type='str', - required=True, - choices=[ - 'send_message', - 'remote_command', - 'notify_all_involved' - ] - ), - # when type is remote_command - command_type=dict( - type='str', - required=False, - choices=[ - 'custom_script', - 'ipmi', - 'ssh', - 'telnet', - 'global_script' - ] - ), - command=dict(type='str', required=False), - execute_on=dict( - type='str', - required=False, - choices=['agent', 'server', 'proxy'] - ), - password=dict(type='str', required=False), - port=dict(type='int', required=False), - run_on_groups=dict(type='list', required=False), - run_on_hosts=dict(type='list', required=False), - script_name=dict(type='str', required=False), - ssh_auth_type=dict( - type='str', - required=False, - default='password', - choices=['password', 'public_key'] - ), - ssh_privatekey_file=dict(type='str', required=False), - ssh_publickey_file=dict(type='str', required=False), - username=dict(type='str', required=False), - # when type is send_message - media_type=dict(type='str', required=False), - subject=dict(type='str', required=False), - message=dict(type='str', required=False), - send_to_groups=dict(type='list', required=False), - send_to_users=dict(type='list', required=False), - ), - required_if=[ - ['type', 'remote_command', ['command_type']], - ['type', 'remote_command', [ - 'run_on_groups', - 'run_on_hosts' - ], True], - ['command_type', 'custom_script', [ - 'command', - 'execute_on' - ]], - ['command_type', 'ipmi', ['command']], - ['command_type', 'ssh', [ - 'command', - 'password', - 'username', - 'port', - 'ssh_auth_type', - 'ssh_privatekey_file', - 'ssh_publickey_file' - ]], - ['command_type', 'telnet', [ - 'command', - 'password', - 'username', - 'port' - ]], - ['command_type', 'global_script', ['script_name']], - ['type', 'send_message', ['send_to_users', 'send_to_groups'], True] - ] - ) - ), - required_if=[ - ['state', 'present', [ - 'esc_period', - 'event_source' - ]] - ], - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - timeout = module.params['timeout'] - name = module.params['name'] - esc_period = module.params['esc_period'] - event_source = module.params['event_source'] - state = module.params['state'] - status = module.params['status'] - pause_in_maintenance = module.params['pause_in_maintenance'] - default_message = module.params['default_message'] - default_subject = module.params['default_subject'] - recovery_default_message = module.params['recovery_default_message'] - recovery_default_subject = module.params['recovery_default_subject'] - acknowledge_default_message = module.params['acknowledge_default_message'] - acknowledge_default_subject = module.params['acknowledge_default_subject'] - conditions = module.params['conditions'] - formula = module.params['formula'] - eval_type = module.params['eval_type'] - operations = module.params['operations'] - recovery_operations = module.params['recovery_operations'] - acknowledge_operations = module.params['acknowledge_operations'] - - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, - passwd=http_login_password, validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - zapi_wrapper = Zapi(module, zbx) - - action = Action(module, zbx, zapi_wrapper) - - action_exists = zapi_wrapper.check_if_action_exists(name) - ops = Operations(module, zbx, zapi_wrapper) - recovery_ops = RecoveryOperations(module, zbx, zapi_wrapper) - acknowledge_ops = AcknowledgeOperations(module, zbx, zapi_wrapper) - fltr = Filter(module, zbx, zapi_wrapper) - - if action_exists: - action_id = zapi_wrapper.get_action_by_name(name)['actionid'] - if state == "absent": - result = action.delete_action(action_id) - module.exit_json(changed=True, msg="Action Deleted: %s, ID: %s" % (name, result)) - else: - difference = action.check_difference( - action_id=action_id, - name=name, - event_source=event_source, - esc_period=esc_period, - status=status, - pause_in_maintenance=pause_in_maintenance, - default_message=default_message, - default_subject=default_subject, - recovery_default_message=recovery_default_message, - recovery_default_subject=recovery_default_subject, - acknowledge_default_message=acknowledge_default_message, - acknowledge_default_subject=acknowledge_default_subject, - operations=ops.construct_the_data(operations), - recovery_operations=recovery_ops.construct_the_data(recovery_operations), - acknowledge_operations=acknowledge_ops.construct_the_data(acknowledge_operations), - conditions=fltr.construct_the_data(eval_type, formula, conditions) - ) - - if difference == {}: - module.exit_json(changed=False, msg="Action is up to date: %s" % (name)) - else: - result = action.update_action( - action_id=action_id, - **difference - ) - module.exit_json(changed=True, msg="Action Updated: %s, ID: %s" % (name, result)) - else: - if state == "absent": - module.exit_json(changed=False) - else: - action_id = action.add_action( - name=name, - event_source=event_source, - esc_period=esc_period, - status=status, - pause_in_maintenance=pause_in_maintenance, - default_message=default_message, - default_subject=default_subject, - recovery_default_message=recovery_default_message, - recovery_default_subject=recovery_default_subject, - acknowledge_default_message=acknowledge_default_message, - acknowledge_default_subject=acknowledge_default_subject, - operations=ops.construct_the_data(operations), - recovery_operations=recovery_ops.construct_the_data(recovery_operations), - acknowledge_operations=acknowledge_ops.construct_the_data(acknowledge_operations), - conditions=fltr.construct_the_data(eval_type, formula, conditions) - ) - module.exit_json(changed=True, msg="Action created: %s, ID: %s" % (name, action_id)) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_group.py b/plugins/modules/monitoring/zabbix/zabbix_group.py deleted file mode 100644 index 9f984e6ec7..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_group.py +++ /dev/null @@ -1,208 +0,0 @@ -#!/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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: zabbix_group -short_description: Create/delete Zabbix host groups -description: - - Create host groups if they do not exist. - - Delete existing host groups if they exist. -author: - - "Cove (@cove)" - - "Tony Minfei Ding (!UNKNOWN)" - - "Harrison Gu (@harrisongu)" -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - state: - description: - - Create or delete host group. - required: false - type: str - default: "present" - choices: [ "present", "absent" ] - host_groups: - description: - - List of host groups to create or delete. - required: true - type: list - elements: str - aliases: [ "host_group" ] - -extends_documentation_fragment: -- community.general.zabbix - - -notes: - - Too many concurrent updates to the same group may cause Zabbix to return errors, see examples for a workaround if needed. -''' - -EXAMPLES = r''' -# Base create host groups example -- name: Create host groups - local_action: - module: zabbix_group - server_url: http://monitor.example.com - login_user: username - login_password: password - state: present - host_groups: - - Example group1 - - Example group2 - -# Limit the Zabbix group creations to one host since Zabbix can return an error when doing concurrent updates -- name: Create host groups - local_action: - module: zabbix_group - server_url: http://monitor.example.com - login_user: username - login_password: password - state: present - host_groups: - - Example group1 - - Example group2 - when: inventory_hostname==groups['group_name'][0] -''' - - -import atexit -import traceback - -try: - from zabbix_api import ZabbixAPI - from zabbix_api import Already_Exists - - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -class HostGroup(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - # create host group(s) if not exists - def create_host_group(self, group_names): - try: - group_add_list = [] - for group_name in group_names: - result = self._zapi.hostgroup.get({'filter': {'name': group_name}}) - if not result: - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.hostgroup.create({'name': group_name}) - group_add_list.append(group_name) - except Already_Exists: - return group_add_list - return group_add_list - except Exception as e: - self._module.fail_json(msg="Failed to create host group(s): %s" % e) - - # delete host group(s) - def delete_host_group(self, group_ids): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.hostgroup.delete(group_ids) - except Exception as e: - self._module.fail_json(msg="Failed to delete host group(s), Exception: %s" % e) - - # get group ids by name - def get_group_ids(self, host_groups): - group_ids = [] - - group_list = self._zapi.hostgroup.get({'output': 'extend', 'filter': {'name': host_groups}}) - for group in group_list: - group_id = group['groupid'] - group_ids.append(group_id) - return group_ids, group_list - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - host_groups=dict(type='list', required=True, aliases=['host_group']), - state=dict(type='str', default="present", choices=['present', 'absent']), - timeout=dict(type='int', default=10) - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - host_groups = module.params['host_groups'] - state = module.params['state'] - timeout = module.params['timeout'] - - zbx = None - - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - hostGroup = HostGroup(module, zbx) - - group_ids = [] - group_list = [] - if host_groups: - group_ids, group_list = hostGroup.get_group_ids(host_groups) - - if state == "absent": - # delete host groups - if group_ids: - delete_group_names = [] - hostGroup.delete_host_group(group_ids) - for group in group_list: - delete_group_names.append(group['name']) - module.exit_json(changed=True, - result="Successfully deleted host group(s): %s." % ",".join(delete_group_names)) - else: - module.exit_json(changed=False, result="No host group(s) to delete.") - else: - # create host groups - group_add_list = hostGroup.create_host_group(host_groups) - if len(group_add_list) > 0: - module.exit_json(changed=True, result="Successfully created host group(s): %s" % group_add_list) - else: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_group_facts.py b/plugins/modules/monitoring/zabbix/zabbix_group_facts.py deleted file mode 120000 index 20451bef68..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_group_facts.py +++ /dev/null @@ -1 +0,0 @@ -zabbix_group_info.py \ No newline at end of file diff --git a/plugins/modules/monitoring/zabbix/zabbix_group_info.py b/plugins/modules/monitoring/zabbix/zabbix_group_info.py deleted file mode 100644 index 6da08d5103..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_group_info.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) me@mimiko.me -# 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -RETURN = r''' ---- -host_groups: - description: List of Zabbix groups. - returned: success - type: dict - sample: [ { "flags": "0", "groupid": "33", "internal": "0", "name": "Hostgruup A" } ] -''' - -DOCUMENTATION = r''' ---- -module: zabbix_group_info -short_description: Gather information about Zabbix hostgroup -description: - - This module allows you to search for Zabbix hostgroup entries. - - This module was called C(zabbix_group_facts) before Ansible 2.9. The usage did not change. -author: - - "Michael Miko (@RedWhiteMiko)" -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - hostgroup_name: - description: - - Name of the hostgroup in Zabbix. - - hostgroup is the unique identifier used and cannot be updated using this module. - required: true - type: list - elements: str -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = r''' -- name: Get hostgroup info - local_action: - module: zabbix_group_info - server_url: http://monitor.example.com - login_user: username - login_password: password - hostgroup_name: - - ExampleHostgroup - timeout: 10 -''' - - -import atexit -import traceback - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - - -class Host(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - def get_group_ids_by_group_names(self, group_names): - group_list = self._zapi.hostgroup.get({'output': 'extend', 'filter': {'name': group_names}}) - if len(group_list) < 1: - self._module.fail_json(msg="Hostgroup not found: %s" % group_names) - return group_list - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - hostgroup_name=dict(type='list', required=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - timeout=dict(type='int', default=10) - ), - supports_check_mode=True - ) - if module._name == 'zabbix_group_facts': - module.deprecate("The 'zabbix_group_facts' module has been renamed to 'zabbix_group_info'", version='2.13') - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - hostgroup_name = module.params['hostgroup_name'] - timeout = module.params['timeout'] - - zbx = None - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - host = Host(module, zbx) - host_groups = host.get_group_ids_by_group_names(hostgroup_name) - module.exit_json(host_groups=host_groups) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_host.py b/plugins/modules/monitoring/zabbix/zabbix_host.py deleted file mode 100644 index a6743d9998..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_host.py +++ /dev/null @@ -1,1058 +0,0 @@ -#!/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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: zabbix_host -short_description: Create/update/delete Zabbix hosts -description: - - This module allows you to create, modify and delete Zabbix host entries and associated group and template data. -author: - - "Cove (@cove)" - - Tony Minfei Ding (!UNKNOWN) - - Harrison Gu (@harrisongu) - - Werner Dijkerman (@dj-wasabi) - - Eike Frost (@eikef) -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - host_name: - description: - - Name of the host in Zabbix. - - I(host_name) is the unique identifier used and cannot be updated using this module. - required: true - type: str - visible_name: - description: - - Visible name of the host in Zabbix. - type: str - description: - description: - - Description of the host in Zabbix. - type: str - host_groups: - description: - - List of host groups the host is part of. - type: list - elements: str - link_templates: - description: - - List of templates linked to the host. - type: list - elements: str - inventory_mode: - description: - - Configure the inventory mode. - choices: ['automatic', 'manual', 'disabled'] - type: str - inventory_zabbix: - description: - - Add Facts for a zabbix inventory (e.g. Tag) (see example below). - - Please review the interface documentation for more information on the supported properties - - U(https://www.zabbix.com/documentation/3.2/manual/api/reference/host/object#host_inventory) - type: dict - status: - description: - - Monitoring status of the host. - choices: ['enabled', 'disabled'] - default: 'enabled' - type: str - state: - description: - - State of the host. - - On C(present), it will create if host does not exist or update the host if the associated data is different. - - On C(absent) will remove a host if it exists. - choices: ['present', 'absent'] - default: 'present' - type: str - proxy: - description: - - The name of the Zabbix proxy to be used. - type: str - interfaces: - type: list - elements: dict - description: - - List of interfaces to be created for the host (see example below). - - For more information, review host interface documentation at - - U(https://www.zabbix.com/documentation/4.0/manual/api/reference/hostinterface/object) - suboptions: - type: - description: - - Interface type to add - - Numerical values are also accepted for interface type - - 1 = agent - - 2 = snmp - - 3 = ipmi - - 4 = jmx - choices: ['agent', 'snmp', 'ipmi', 'jmx'] - required: true - main: - type: int - description: - - Whether the interface is used as default. - - If multiple interfaces with the same type are provided, only one can be default. - - 0 (not default), 1 (default) - default: 0 - choices: [0, 1] - useip: - type: int - description: - - Connect to host interface with IP address instead of DNS name. - - 0 (don't use ip), 1 (use ip) - default: 0 - choices: [0, 1] - ip: - type: str - description: - - IP address used by host interface. - - Required if I(useip=1). - default: '' - dns: - type: str - description: - - DNS name of the host interface. - - Required if I(useip=0). - default: '' - port: - type: str - description: - - Port used by host interface. - - If not specified, default port for each type of interface is used - - 10050 if I(type='agent') - - 161 if I(type='snmp') - - 623 if I(type='ipmi') - - 12345 if I(type='jmx') - bulk: - type: int - description: - - Whether to use bulk SNMP requests. - - 0 (don't use bulk requests), 1 (use bulk requests) - choices: [0, 1] - default: 1 - default: [] - tls_connect: - description: - - Specifies what encryption to use for outgoing connections. - - Possible values, 1 (no encryption), 2 (PSK), 4 (certificate). - - Works only with >= Zabbix 3.0 - default: 1 - type: int - tls_accept: - description: - - Specifies what types of connections are allowed for incoming connections. - - The tls_accept parameter accepts values of 1 to 7 - - Possible values, 1 (no encryption), 2 (PSK), 4 (certificate). - - Values can be combined. - - Works only with >= Zabbix 3.0 - default: 1 - type: int - tls_psk_identity: - description: - - It is a unique name by which this specific PSK is referred to by Zabbix components - - Do not put sensitive information in the PSK identity string, it is transmitted over the network unencrypted. - - Works only with >= Zabbix 3.0 - type: str - tls_psk: - description: - - PSK value is a hard to guess string of hexadecimal digits. - - The preshared key, at least 32 hex digits. Required if either I(tls_connect) or I(tls_accept) has PSK enabled. - - Works only with >= Zabbix 3.0 - type: str - ca_cert: - description: - - Required certificate issuer. - - Works only with >= Zabbix 3.0 - aliases: [ tls_issuer ] - type: str - tls_subject: - description: - - Required certificate subject. - - Works only with >= Zabbix 3.0 - type: str - ipmi_authtype: - description: - - IPMI authentication algorithm. - - Please review the Host object documentation for more information on the supported properties - - 'https://www.zabbix.com/documentation/3.4/manual/api/reference/host/object' - - Possible values are, C(0) (none), C(1) (MD2), C(2) (MD5), C(4) (straight), C(5) (OEM), C(6) (RMCP+), - with -1 being the API default. - - Please note that the Zabbix API will treat absent settings as default when updating - any of the I(ipmi_)-options; this means that if you attempt to set any of the four - options individually, the rest will be reset to default values. - type: int - ipmi_privilege: - description: - - IPMI privilege level. - - Please review the Host object documentation for more information on the supported properties - - 'https://www.zabbix.com/documentation/3.4/manual/api/reference/host/object' - - Possible values are C(1) (callback), C(2) (user), C(3) (operator), C(4) (admin), C(5) (OEM), with C(2) - being the API default. - - also see the last note in the I(ipmi_authtype) documentation - type: int - ipmi_username: - description: - - IPMI username. - - also see the last note in the I(ipmi_authtype) documentation - type: str - ipmi_password: - description: - - IPMI password. - - also see the last note in the I(ipmi_authtype) documentation - type: str - force: - description: - - Overwrite the host configuration, even if already present. - type: bool - default: 'yes' - macros: - description: - - List of user macros to assign to the zabbix host. - - Providing I(macros=[]) with I(force=yes) will clean all of the existing user macros from the host. - type: list - elements: dict - suboptions: - macro: - description: - - Name of the user macro. - - Can be in zabbix native format "{$MACRO}" or short format "MACRO". - type: str - required: true - value: - description: - - Value of the user macro. - type: str - required: true - description: - description: - - Description of the user macro. - - Works only with >= Zabbix 4.4. - type: str - required: false - default: '' - aliases: [ user_macros ] - tags: - description: - - List of host tags to assign to the zabbix host. - - Works only with >= Zabbix 4.2. - - Providing I(tags=[]) with I(force=yes) will clean all of the tags from the host. - type: list - elements: dict - suboptions: - tag: - description: - - Name of the host tag. - type: str - required: true - value: - description: - - Value of the host tag. - type: str - default: '' - aliases: [ host_tags ] - -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = r''' -- name: Create a new host or update an existing host's info - local_action: - module: zabbix_host - server_url: http://monitor.example.com - login_user: username - login_password: password - host_name: ExampleHost - visible_name: ExampleName - description: My ExampleHost Description - host_groups: - - Example group1 - - Example group2 - link_templates: - - Example template1 - - Example template2 - status: enabled - state: present - inventory_mode: manual - inventory_zabbix: - tag: "{{ your_tag }}" - alias: "{{ your_alias }}" - notes: "Special Informations: {{ your_informations | default('None') }}" - location: "{{ your_location }}" - site_rack: "{{ your_site_rack }}" - os: "{{ your_os }}" - hardware: "{{ your_hardware }}" - ipmi_authtype: 2 - ipmi_privilege: 4 - ipmi_username: username - ipmi_password: password - interfaces: - - type: 1 - main: 1 - useip: 1 - ip: 10.xx.xx.xx - dns: "" - port: "10050" - - type: 4 - main: 1 - useip: 1 - ip: 10.xx.xx.xx - dns: "" - port: "12345" - proxy: a.zabbix.proxy - macros: - - macro: '{$EXAMPLEMACRO}' - value: ExampleMacroValue - - macro: EXAMPLEMACRO2 - value: ExampleMacroValue2 - description: Example desc that work only with Zabbix 4.4 and higher - tags: - - tag: ExampleHostsTag - - tag: ExampleHostsTag2 - value: ExampleTagValue - -- name: Update an existing host's TLS settings - local_action: - module: zabbix_host - server_url: http://monitor.example.com - login_user: username - login_password: password - host_name: ExampleHost - visible_name: ExampleName - host_groups: - - Example group1 - tls_psk_identity: test - tls_connect: 2 - tls_psk: 123456789abcdef123456789abcdef12 -''' - - -import atexit -import copy -import traceback - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from distutils.version import LooseVersion -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -class Host(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - self._zbx_api_version = zbx.api_version()[:5] - - # exist host - def is_host_exist(self, host_name): - result = self._zapi.host.get({'filter': {'host': host_name}}) - return result - - # check if host group exists - def check_host_group_exist(self, group_names): - for group_name in group_names: - result = self._zapi.hostgroup.get({'filter': {'name': group_name}}) - if not result: - self._module.fail_json(msg="Hostgroup not found: %s" % group_name) - return True - - def get_template_ids(self, template_list): - template_ids = [] - if template_list is None or len(template_list) == 0: - return template_ids - for template in template_list: - template_list = self._zapi.template.get({'output': 'extend', 'filter': {'host': template}}) - if len(template_list) < 1: - self._module.fail_json(msg="Template not found: %s" % template) - else: - template_id = template_list[0]['templateid'] - template_ids.append(template_id) - return template_ids - - def add_host(self, host_name, group_ids, status, interfaces, proxy_id, visible_name, description, tls_connect, - tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject, ipmi_authtype, ipmi_privilege, - ipmi_username, ipmi_password, macros, tags): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - parameters = {'host': host_name, 'interfaces': interfaces, 'groups': group_ids, 'status': status, - 'tls_connect': tls_connect, 'tls_accept': tls_accept} - if proxy_id: - parameters['proxy_hostid'] = proxy_id - if visible_name: - parameters['name'] = visible_name - if tls_psk_identity is not None: - parameters['tls_psk_identity'] = tls_psk_identity - if tls_psk is not None: - parameters['tls_psk'] = tls_psk - if tls_issuer is not None: - parameters['tls_issuer'] = tls_issuer - if tls_subject is not None: - parameters['tls_subject'] = tls_subject - if description: - parameters['description'] = description - if ipmi_authtype is not None: - parameters['ipmi_authtype'] = ipmi_authtype - if ipmi_privilege is not None: - parameters['ipmi_privilege'] = ipmi_privilege - if ipmi_username is not None: - parameters['ipmi_username'] = ipmi_username - if ipmi_password is not None: - parameters['ipmi_password'] = ipmi_password - if macros is not None: - parameters['macros'] = macros - if tags is not None: - parameters['tags'] = tags - - host_list = self._zapi.host.create(parameters) - if len(host_list) >= 1: - return host_list['hostids'][0] - except Exception as e: - self._module.fail_json(msg="Failed to create host %s: %s" % (host_name, e)) - - def update_host(self, host_name, group_ids, status, host_id, interfaces, exist_interface_list, proxy_id, - visible_name, description, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, - tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - parameters = {'hostid': host_id, 'groups': group_ids, 'status': status, 'tls_connect': tls_connect, - 'tls_accept': tls_accept} - if proxy_id >= 0: - parameters['proxy_hostid'] = proxy_id - if visible_name: - parameters['name'] = visible_name - if tls_psk_identity: - parameters['tls_psk_identity'] = tls_psk_identity - if tls_psk: - parameters['tls_psk'] = tls_psk - if tls_issuer: - parameters['tls_issuer'] = tls_issuer - if tls_subject: - parameters['tls_subject'] = tls_subject - if description: - parameters['description'] = description - if ipmi_authtype: - parameters['ipmi_authtype'] = ipmi_authtype - if ipmi_privilege: - parameters['ipmi_privilege'] = ipmi_privilege - if ipmi_username: - parameters['ipmi_username'] = ipmi_username - if ipmi_password: - parameters['ipmi_password'] = ipmi_password - if macros is not None: - parameters['macros'] = macros - if tags is not None: - parameters['tags'] = tags - - self._zapi.host.update(parameters) - interface_list_copy = exist_interface_list - if interfaces: - for interface in interfaces: - flag = False - interface_str = interface - for exist_interface in exist_interface_list: - interface_type = int(interface['type']) - exist_interface_type = int(exist_interface['type']) - if interface_type == exist_interface_type: - # update - interface_str['interfaceid'] = exist_interface['interfaceid'] - self._zapi.hostinterface.update(interface_str) - flag = True - interface_list_copy.remove(exist_interface) - break - if not flag: - # add - interface_str['hostid'] = host_id - self._zapi.hostinterface.create(interface_str) - # remove - remove_interface_ids = [] - for remove_interface in interface_list_copy: - interface_id = remove_interface['interfaceid'] - remove_interface_ids.append(interface_id) - if len(remove_interface_ids) > 0: - self._zapi.hostinterface.delete(remove_interface_ids) - except Exception as e: - self._module.fail_json(msg="Failed to update host %s: %s" % (host_name, e)) - - def delete_host(self, host_id, host_name): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.host.delete([host_id]) - except Exception as e: - self._module.fail_json(msg="Failed to delete host %s: %s" % (host_name, e)) - - # get host by host name - def get_host_by_host_name(self, host_name): - params = { - 'output': 'extend', - 'selectInventory': 'extend', - 'selectMacros': 'extend', - 'filter': { - 'host': [host_name] - } - } - - if LooseVersion(self._zbx_api_version) >= LooseVersion('4.2.0'): - params.update({'selectTags': 'extend'}) - - host_list = self._zapi.host.get(params) - if len(host_list) < 1: - self._module.fail_json(msg="Host not found: %s" % host_name) - else: - return host_list[0] - - # get proxyid by proxy name - def get_proxyid_by_proxy_name(self, proxy_name): - proxy_list = self._zapi.proxy.get({'output': 'extend', 'filter': {'host': [proxy_name]}}) - if len(proxy_list) < 1: - self._module.fail_json(msg="Proxy not found: %s" % proxy_name) - else: - return int(proxy_list[0]['proxyid']) - - # get group ids by group names - def get_group_ids_by_group_names(self, group_names): - if self.check_host_group_exist(group_names): - return self._zapi.hostgroup.get({'output': 'groupid', 'filter': {'name': group_names}}) - - # get host groups ids by host id - def get_group_ids_by_host_id(self, host_id): - return self._zapi.hostgroup.get({'output': 'groupid', 'hostids': host_id}) - - # get host templates by host id - def get_host_templates_by_host_id(self, host_id): - template_ids = [] - template_list = self._zapi.template.get({'output': 'extend', 'hostids': host_id}) - for template in template_list: - template_ids.append(template['templateid']) - return template_ids - - # check the exist_interfaces whether it equals the interfaces or not - def check_interface_properties(self, exist_interface_list, interfaces): - interfaces_port_list = [] - - if interfaces is not None: - if len(interfaces) >= 1: - for interface in interfaces: - interfaces_port_list.append(str(interface['port'])) - - exist_interface_ports = [] - if len(exist_interface_list) >= 1: - for exist_interface in exist_interface_list: - exist_interface_ports.append(str(exist_interface['port'])) - - if set(interfaces_port_list) != set(exist_interface_ports): - return True - - for exist_interface in exist_interface_list: - exit_interface_port = str(exist_interface['port']) - for interface in interfaces: - interface_port = str(interface['port']) - if interface_port == exit_interface_port: - for key in interface.keys(): - if str(exist_interface[key]) != str(interface[key]): - return True - - return False - - # get the status of host by host - def get_host_status_by_host(self, host): - return host['status'] - - # check all the properties before link or clear template - def check_all_properties(self, host_id, group_ids, status, interfaces, template_ids, - exist_interfaces, host, proxy_id, visible_name, description, host_name, - inventory_mode, inventory_zabbix, tls_accept, tls_psk_identity, tls_psk, - tls_issuer, tls_subject, tls_connect, ipmi_authtype, ipmi_privilege, - ipmi_username, ipmi_password, macros, tags): - # get the existing host's groups - exist_host_groups = sorted(self.get_group_ids_by_host_id(host_id), key=lambda k: k['groupid']) - if sorted(group_ids, key=lambda k: k['groupid']) != exist_host_groups: - return True - - # get the existing status - exist_status = self.get_host_status_by_host(host) - if int(status) != int(exist_status): - return True - - # check the exist_interfaces whether it equals the interfaces or not - if self.check_interface_properties(exist_interfaces, interfaces): - return True - - # get the existing templates - exist_template_ids = self.get_host_templates_by_host_id(host_id) - if set(list(template_ids)) != set(exist_template_ids): - return True - - if int(host['proxy_hostid']) != int(proxy_id): - return True - - # Check whether the visible_name has changed; Zabbix defaults to the technical hostname if not set. - if visible_name: - if host['name'] != visible_name: - return True - - # Only compare description if it is given as a module parameter - if description: - if host['description'] != description: - return True - - if inventory_mode: - if LooseVersion(self._zbx_api_version) <= LooseVersion('4.4.0'): - if host['inventory']: - if int(host['inventory']['inventory_mode']) != self.inventory_mode_numeric(inventory_mode): - return True - elif inventory_mode != 'disabled': - return True - else: - if int(host['inventory_mode']) != self.inventory_mode_numeric(inventory_mode): - return True - - if inventory_zabbix: - proposed_inventory = copy.deepcopy(host['inventory']) - proposed_inventory.update(inventory_zabbix) - if proposed_inventory != host['inventory']: - return True - - if tls_accept is not None and 'tls_accept' in host: - if int(host['tls_accept']) != tls_accept: - return True - - if tls_psk_identity is not None and 'tls_psk_identity' in host: - if host['tls_psk_identity'] != tls_psk_identity: - return True - - if tls_psk is not None and 'tls_psk' in host: - if host['tls_psk'] != tls_psk: - return True - - if tls_issuer is not None and 'tls_issuer' in host: - if host['tls_issuer'] != tls_issuer: - return True - - if tls_subject is not None and 'tls_subject' in host: - if host['tls_subject'] != tls_subject: - return True - - if tls_connect is not None and 'tls_connect' in host: - if int(host['tls_connect']) != tls_connect: - return True - if ipmi_authtype is not None: - if int(host['ipmi_authtype']) != ipmi_authtype: - return True - if ipmi_privilege is not None: - if int(host['ipmi_privilege']) != ipmi_privilege: - return True - if ipmi_username is not None: - if host['ipmi_username'] != ipmi_username: - return True - if ipmi_password is not None: - if host['ipmi_password'] != ipmi_password: - return True - - # hostmacroid and hostid are present in every item of host['macros'] and need to be removed - if macros is not None and 'macros' in host: - existing_macros = sorted(host['macros'], key=lambda k: k['macro']) - for macro in existing_macros: - macro.pop('hostid', False) - macro.pop('hostmacroid', False) - - if sorted(macros, key=lambda k: k['macro']) != existing_macros: - return True - - if tags is not None and 'tags' in host: - if sorted(tags, key=lambda k: k['tag']) != sorted(host['tags'], key=lambda k: k['tag']): - return True - - return False - - # link or clear template of the host - def link_or_clear_template(self, host_id, template_id_list, tls_connect, tls_accept, tls_psk_identity, tls_psk, - tls_issuer, tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password): - # get host's exist template ids - exist_template_id_list = self.get_host_templates_by_host_id(host_id) - - exist_template_ids = set(exist_template_id_list) - template_ids = set(template_id_list) - template_id_list = list(template_ids) - - # get unlink and clear templates - templates_clear = exist_template_ids.difference(template_ids) - templates_clear_list = list(templates_clear) - request_str = {'hostid': host_id, 'templates': template_id_list, 'templates_clear': templates_clear_list, - 'tls_connect': tls_connect, 'tls_accept': tls_accept, 'ipmi_authtype': ipmi_authtype, - 'ipmi_privilege': ipmi_privilege, 'ipmi_username': ipmi_username, 'ipmi_password': ipmi_password} - if tls_psk_identity is not None: - request_str['tls_psk_identity'] = tls_psk_identity - if tls_psk is not None: - request_str['tls_psk'] = tls_psk - if tls_issuer is not None: - request_str['tls_issuer'] = tls_issuer - if tls_subject is not None: - request_str['tls_subject'] = tls_subject - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.host.update(request_str) - except Exception as e: - self._module.fail_json(msg="Failed to link template to host: %s" % e) - - def inventory_mode_numeric(self, inventory_mode): - if inventory_mode == "automatic": - return int(1) - elif inventory_mode == "manual": - return int(0) - elif inventory_mode == "disabled": - return int(-1) - return inventory_mode - - # Update the host inventory_mode - def update_inventory_mode(self, host_id, inventory_mode): - - # nothing was set, do nothing - if not inventory_mode: - return - - inventory_mode = self.inventory_mode_numeric(inventory_mode) - - # watch for - https://support.zabbix.com/browse/ZBX-6033 - request_str = {'hostid': host_id, 'inventory_mode': inventory_mode} - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.host.update(request_str) - except Exception as e: - self._module.fail_json(msg="Failed to set inventory_mode to host: %s" % e) - - def update_inventory_zabbix(self, host_id, inventory): - - if not inventory: - return - - request_str = {'hostid': host_id, 'inventory': inventory} - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.host.update(request_str) - except Exception as e: - self._module.fail_json(msg="Failed to set inventory to host: %s" % e) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - host_name=dict(type='str', required=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - host_groups=dict(type='list', required=False), - link_templates=dict(type='list', required=False), - status=dict(type='str', default="enabled", choices=['enabled', 'disabled']), - state=dict(type='str', default="present", choices=['present', 'absent']), - inventory_mode=dict(type='str', required=False, choices=['automatic', 'manual', 'disabled']), - ipmi_authtype=dict(type='int', default=None), - ipmi_privilege=dict(type='int', default=None), - ipmi_username=dict(type='str', required=False, default=None), - ipmi_password=dict(type='str', required=False, default=None, no_log=True), - tls_connect=dict(type='int', default=1), - tls_accept=dict(type='int', default=1), - tls_psk_identity=dict(type='str', required=False), - tls_psk=dict(type='str', required=False), - ca_cert=dict(type='str', required=False, aliases=['tls_issuer']), - tls_subject=dict(type='str', required=False), - inventory_zabbix=dict(type='dict', required=False), - timeout=dict(type='int', default=10), - interfaces=dict(type='list', required=False), - force=dict(type='bool', default=True), - proxy=dict(type='str', required=False), - visible_name=dict(type='str', required=False), - description=dict(type='str', required=False), - macros=dict( - type='list', - elements='dict', - aliases=['user_macros'], - options=dict( - macro=dict(type='str', required=True), - value=dict(type='str', required=True), - description=dict(type='str', required=False, default='') - ) - ), - tags=dict( - type='list', - elements='dict', - aliases=['host_tags'], - options=dict( - tag=dict(type='str', required=True), - value=dict(type='str', default='') - ) - ) - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - host_name = module.params['host_name'] - visible_name = module.params['visible_name'] - description = module.params['description'] - host_groups = module.params['host_groups'] - link_templates = module.params['link_templates'] - inventory_mode = module.params['inventory_mode'] - ipmi_authtype = module.params['ipmi_authtype'] - ipmi_privilege = module.params['ipmi_privilege'] - ipmi_username = module.params['ipmi_username'] - ipmi_password = module.params['ipmi_password'] - tls_connect = module.params['tls_connect'] - tls_accept = module.params['tls_accept'] - tls_psk_identity = module.params['tls_psk_identity'] - tls_psk = module.params['tls_psk'] - tls_issuer = module.params['ca_cert'] - tls_subject = module.params['tls_subject'] - inventory_zabbix = module.params['inventory_zabbix'] - status = module.params['status'] - state = module.params['state'] - timeout = module.params['timeout'] - interfaces = module.params['interfaces'] - force = module.params['force'] - proxy = module.params['proxy'] - macros = module.params['macros'] - tags = module.params['tags'] - - # convert enabled to 0; disabled to 1 - status = 1 if status == "disabled" else 0 - - zbx = None - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - host = Host(module, zbx) - - template_ids = [] - if link_templates: - template_ids = host.get_template_ids(link_templates) - - group_ids = [] - - if host_groups: - group_ids = host.get_group_ids_by_group_names(host_groups) - - ip = "" - if interfaces: - # ensure interfaces are well-formed - for interface in interfaces: - if 'type' not in interface: - module.fail_json(msg="(interface) type needs to be specified for interface '%s'." % interface) - interfacetypes = {'agent': 1, 'snmp': 2, 'ipmi': 3, 'jmx': 4} - if interface['type'] in interfacetypes.keys(): - interface['type'] = interfacetypes[interface['type']] - if interface['type'] < 1 or interface['type'] > 4: - module.fail_json(msg="Interface type can only be 1-4 for interface '%s'." % interface) - if 'useip' not in interface: - interface['useip'] = 0 - if 'dns' not in interface: - if interface['useip'] == 0: - module.fail_json(msg="dns needs to be set if useip is 0 on interface '%s'." % interface) - interface['dns'] = '' - if 'ip' not in interface: - if interface['useip'] == 1: - module.fail_json(msg="ip needs to be set if useip is 1 on interface '%s'." % interface) - interface['ip'] = '' - if 'main' not in interface: - interface['main'] = 0 - if 'port' in interface and not isinstance(interface['port'], str): - try: - interface['port'] = str(interface['port']) - except ValueError: - module.fail_json(msg="port should be convertable to string on interface '%s'." % interface) - if 'port' not in interface: - if interface['type'] == 1: - interface['port'] = "10050" - elif interface['type'] == 2: - interface['port'] = "161" - elif interface['type'] == 3: - interface['port'] = "623" - elif interface['type'] == 4: - interface['port'] = "12345" - - if interface['type'] == 1: - ip = interface['ip'] - - if macros: - # convert macros to zabbix native format - {$MACRO} - for macro in macros: - macro['macro'] = macro['macro'].upper() - if not macro['macro'].startswith('{$'): - macro['macro'] = '{$' + macro['macro'] - if not macro['macro'].endswith('}'): - macro['macro'] = macro['macro'] + '}' - if LooseVersion(zbx.api_version()[:5]) <= LooseVersion('4.4.0'): - if 'description' in macro: - macro.pop('description', False) - - # Use proxy specified, or set to 0 - if proxy: - proxy_id = host.get_proxyid_by_proxy_name(proxy) - else: - proxy_id = 0 - - # check if host exist - is_host_exist = host.is_host_exist(host_name) - - if is_host_exist: - # get host id by host name - zabbix_host_obj = host.get_host_by_host_name(host_name) - host_id = zabbix_host_obj['hostid'] - - # If proxy is not specified as a module parameter, use the existing setting - if proxy is None: - proxy_id = int(zabbix_host_obj['proxy_hostid']) - - if state == "absent": - # remove host - host.delete_host(host_id, host_name) - module.exit_json(changed=True, result="Successfully delete host %s" % host_name) - else: - if not host_groups: - # if host_groups have not been specified when updating an existing host, just - # get the group_ids from the existing host without updating them. - group_ids = host.get_group_ids_by_host_id(host_id) - - # get existing host's interfaces - exist_interfaces = host._zapi.hostinterface.get({'output': 'extend', 'hostids': host_id}) - - # if no interfaces were specified with the module, start with an empty list - if not interfaces: - interfaces = [] - - # When force=no is specified, append existing interfaces to interfaces to update. When - # no interfaces have been specified, copy existing interfaces as specified from the API. - # Do the same with templates and host groups. - if not force or not interfaces: - for interface in copy.deepcopy(exist_interfaces): - # remove values not used during hostinterface.add/update calls - for key in tuple(interface.keys()): - if key in ['interfaceid', 'hostid', 'bulk']: - interface.pop(key, None) - - for index in interface.keys(): - if index in ['useip', 'main', 'type']: - interface[index] = int(interface[index]) - - if interface not in interfaces: - interfaces.append(interface) - - if not force or link_templates is None: - template_ids = list(set(template_ids + host.get_host_templates_by_host_id(host_id))) - - if not force: - for group_id in host.get_group_ids_by_host_id(host_id): - if group_id not in group_ids: - group_ids.append(group_id) - - # Macros not present in host.update will be removed if we dont copy them when force=no - if macros is not None and 'macros' in zabbix_host_obj.keys(): - provided_macros = [m['macro'] for m in macros] - existing_macros = zabbix_host_obj['macros'] - for macro in existing_macros: - if macro['macro'] not in provided_macros: - macros.append(macro) - - # Tags not present in host.update will be removed if we dont copy them when force=no - if tags is not None and 'tags' in zabbix_host_obj.keys(): - provided_tags = [t['tag'] for t in tags] - existing_tags = zabbix_host_obj['tags'] - for tag in existing_tags: - if tag['tag'] not in provided_tags: - tags.append(tag) - - # update host - if host.check_all_properties( - host_id, group_ids, status, interfaces, template_ids, exist_interfaces, zabbix_host_obj, proxy_id, - visible_name, description, host_name, inventory_mode, inventory_zabbix, tls_accept, - tls_psk_identity, tls_psk, tls_issuer, tls_subject, tls_connect, ipmi_authtype, ipmi_privilege, - ipmi_username, ipmi_password, macros, tags): - - host.update_host( - host_name, group_ids, status, host_id, interfaces, exist_interfaces, proxy_id, visible_name, - description, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject, - ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password, macros, tags) - - host.link_or_clear_template( - host_id, template_ids, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, - tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password) - - host.update_inventory_mode(host_id, inventory_mode) - host.update_inventory_zabbix(host_id, inventory_zabbix) - - module.exit_json(changed=True, - result="Successfully update host %s (%s) and linked with template '%s'" - % (host_name, ip, link_templates)) - else: - module.exit_json(changed=False) - - else: - if state == "absent": - # the host is already deleted. - module.exit_json(changed=False) - - if not group_ids: - module.fail_json(msg="Specify at least one group for creating host '%s'." % host_name) - - if not interfaces or (interfaces and len(interfaces) == 0): - module.fail_json(msg="Specify at least one interface for creating host '%s'." % host_name) - - # create host - host_id = host.add_host( - host_name, group_ids, status, interfaces, proxy_id, visible_name, description, tls_connect, tls_accept, - tls_psk_identity, tls_psk, tls_issuer, tls_subject, ipmi_authtype, ipmi_privilege, ipmi_username, - ipmi_password, macros, tags) - - host.link_or_clear_template( - host_id, template_ids, tls_connect, tls_accept, tls_psk_identity, tls_psk, tls_issuer, tls_subject, - ipmi_authtype, ipmi_privilege, ipmi_username, ipmi_password) - - host.update_inventory_mode(host_id, inventory_mode) - host.update_inventory_zabbix(host_id, inventory_zabbix) - - module.exit_json(changed=True, result="Successfully added host %s (%s) and linked with template '%s'" % ( - host_name, ip, link_templates)) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_host_events_info.py b/plugins/modules/monitoring/zabbix/zabbix_host_events_info.py deleted file mode 100644 index 74d297337a..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_host_events_info.py +++ /dev/null @@ -1,336 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) stephane.travassac@fr.clara.net -# 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 - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -RETURN = ''' ---- -triggers_ok: - description: Host Zabbix Triggers in OK state - returned: On success - type: complex - contains: - comments: - description: Additional description of the trigger - type: str - description: - description: Name of the trigger - type: str - error: - description: Error text if there have been any problems when updating the state of the trigger - type: str - expression: - description: Reduced trigger expression - type: str - flags: - description: Origin of the trigger - type: int - lastchange: - description: Time when the trigger last changed its state (timestamp) - type: int - priority: - description: Severity of the trigger - type: int - state: - description: State of the trigger - type: int - status: - description: Whether the trigger is enabled or disabled - type: int - templateid: - description: ID of the parent template trigger - type: int - triggerid: - description: ID of the trigger - type: int - type: - description: Whether the trigger can generate multiple problem events - type: int - url: - description: URL associated with the trigger - type: str - value: - description: Whether the trigger is in OK or problem state - type: int -triggers_problem: - description: Host Zabbix Triggers in problem state. See trigger and event objects in API documentation of your zabbix version for more - returned: On success - type: complex - contains: - comments: - description: Additional description of the trigger - type: str - description: - description: Name of the trigger - type: str - error: - description: Error text if there have been any problems when updating the state of the trigger - type: str - expression: - description: Reduced trigger expression - type: str - flags: - description: Origin of the trigger - type: int - last_event: - description: last event informations - type: complex - contains: - acknowledged: - description: If set to true return only acknowledged events - type: int - acknowledges: - description: acknowledges informations - type: complex - contains: - alias: - description: Account who acknowledge - type: str - clock: - description: Time when the event was created (timestamp) - type: int - message: - description: Text of the acknowledgement message - type: str - clock: - description: Time when the event was created (timestamp) - type: int - eventid: - description: ID of the event - type: int - value: - description: State of the related object - type: int - lastchange: - description: Time when the trigger last changed its state (timestamp) - type: int - priority: - description: Severity of the trigger - type: int - state: - description: State of the trigger - type: int - status: - description: Whether the trigger is enabled or disabled - type: int - templateid: - description: ID of the parent template trigger - type: int - triggerid: - description: ID of the trigger - type: int - type: - description: Whether the trigger can generate multiple problem events - type: int - url: - description: URL associated with the trigger - type: str - value: - description: Whether the trigger is in OK or problem state - type: int -''' - -DOCUMENTATION = ''' ---- -module: zabbix_host_events_info -short_description: Get all triggers about a Zabbix host -description: - - This module allows you to see if a Zabbix host have no active alert to make actions on it. - For this case use module Ansible 'fail' to exclude host in trouble. - - Length of "triggers_ok" allow if template's triggers exist for Zabbix Host -author: - - "Stéphane Travassac (@stravassac)" -requirements: - - "python >= 2.7" - - "zabbix-api >= 0.5.3" -options: - host_identifier: - description: - - Identifier of Zabbix Host - required: true - type: str - host_id_type: - description: - - Type of host_identifier - choices: - - hostname - - visible_name - - hostid - required: false - default: hostname - type: str - trigger_severity: - description: - - Zabbix severity for search filter - default: average - required: false - choices: - - not_classified - - information - - warning - - average - - high - - disaster - type: str -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = ''' -- name: exclude machine if alert active on it - zabbix_host_events_info: - server_url: "{{ zabbix_url }}" - login_user: "{{ lookup('env','ZABBIX_USER') }}" - login_password: "{{ lookup('env','ZABBIX_PASSWORD') }}" - host_identifier: "{{inventory_hostname}}" - host_id_type: "hostname" - timeout: 120 - register: zbx_host - delegate_to: localhost -- fail: - msg: "machine alert in zabbix" - when: zbx_host['triggers_problem']|length > 0 -''' - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -import atexit -import traceback - -try: - from zabbix_api import ZabbixAPI - - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - - -class Host(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - def get_host(self, host_identifier, host_inventory, search_key): - """ Get host by hostname|visible_name|hostid """ - host = self._zapi.host.get( - {'output': 'extend', 'selectParentTemplates': ['name'], 'filter': {search_key: host_identifier}, - 'selectInventory': host_inventory}) - if len(host) < 1: - self._module.fail_json(msg="Host not found: %s" % host_identifier) - else: - return host[0] - - def get_triggers_by_host_id_in_problem_state(self, host_id, trigger_severity): - """ Get triggers in problem state from a hostid""" - # https://www.zabbix.com/documentation/3.4/manual/api/reference/trigger/get - output = 'extend' - triggers_list = self._zapi.trigger.get({'output': output, 'hostids': host_id, - 'min_severity': trigger_severity}) - return triggers_list - - def get_last_event_by_trigger_id(self, triggers_id): - """ Get the last event from triggerid""" - output = ['eventid', 'clock', 'acknowledged', 'value'] - select_acknowledges = ['clock', 'alias', 'message'] - event = self._zapi.event.get({'output': output, 'objectids': triggers_id, - 'select_acknowledges': select_acknowledges, "limit": 1, "sortfield": "clock", - "sortorder": "DESC"}) - return event[0] - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - host_identifier=dict(type='str', required=True), - host_id_type=dict( - default='hostname', - type='str', - choices=['hostname', 'visible_name', 'hostid']), - trigger_severity=dict( - type='str', - required=False, - default='average', - choices=['not_classified', 'information', 'warning', 'average', 'high', 'disaster']), - validate_certs=dict(type='bool', required=False, default=True), - timeout=dict(type='int', default=10), - - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), - exception=ZBX_IMP_ERR) - - trigger_severity_map = {'not_classified': 0, 'information': 1, 'warning': 2, 'average': 3, 'high': 4, 'disaster': 5} - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - host_id = module.params['host_identifier'] - host_id_type = module.params['host_id_type'] - trigger_severity = trigger_severity_map[module.params['trigger_severity']] - timeout = module.params['timeout'] - - host_inventory = 'hostid' - zbx = None - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - host = Host(module, zbx) - - if host_id_type == 'hostname': - zabbix_host = host.get_host(host_id, host_inventory, 'host') - host_id = zabbix_host['hostid'] - - elif host_id_type == 'visible_name': - zabbix_host = host.get_host(host_id, host_inventory, 'name') - host_id = zabbix_host['hostid'] - - elif host_id_type == 'hostid': - ''' check hostid exist''' - zabbix_host = host.get_host(host_id, host_inventory, 'hostid') - - triggers = host.get_triggers_by_host_id_in_problem_state(host_id, trigger_severity) - - triggers_ok = [] - triggers_problem = [] - for trigger in triggers: - # tGet last event for trigger with problem value = 1 - # https://www.zabbix.com/documentation/3.4/manual/api/reference/trigger/object - if int(trigger['value']) == 1: - event = host.get_last_event_by_trigger_id(trigger['triggerid']) - trigger['last_event'] = event - triggers_problem.append(trigger) - else: - triggers_ok.append(trigger) - - module.exit_json(ok=True, triggers_ok=triggers_ok, triggers_problem=triggers_problem) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_host_facts.py b/plugins/modules/monitoring/zabbix/zabbix_host_facts.py deleted file mode 120000 index c6d22f6237..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_host_facts.py +++ /dev/null @@ -1 +0,0 @@ -zabbix_host_info.py \ No newline at end of file diff --git a/plugins/modules/monitoring/zabbix/zabbix_host_info.py b/plugins/modules/monitoring/zabbix/zabbix_host_info.py deleted file mode 100644 index 3c10d7a6bd..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_host_info.py +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) me@mimiko.me -# 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -RETURN = r''' ---- -hosts: - description: List of Zabbix hosts. See https://www.zabbix.com/documentation/4.0/manual/api/reference/host/get for list of host values. - returned: success - type: dict - sample: [ { "available": "1", "description": "", "disable_until": "0", "error": "", "flags": "0", "groups": ["1"], "host": "Host A", ... } ] -''' - -DOCUMENTATION = r''' ---- -module: zabbix_host_info -short_description: Gather information about Zabbix host -description: - - This module allows you to search for Zabbix host entries. - - This module was called C(zabbix_host_facts) before Ansible 2.9. The usage did not change. -author: - - "Michael Miko (@RedWhiteMiko)" -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - host_name: - description: - - Name of the host in Zabbix. - - host_name is the unique identifier used and cannot be updated using this module. - - Required when I(host_ip) is not used. - required: false - type: str - host_ip: - description: - - Host interface IP of the host in Zabbix. - - Required when I(host_name) is not used. - required: false - type: list - elements: str - exact_match: - description: - - Find the exact match - type: bool - default: no - remove_duplicate: - description: - - Remove duplicate host from host result - type: bool - default: yes - host_inventory: - description: - - List of host inventory keys to display in result. - - Whole host inventory is retrieved if keys are not specified. - type: list - elements: str - required: false -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = r''' -- name: Get host info - local_action: - module: zabbix_host_info - server_url: http://monitor.example.com - login_user: username - login_password: password - host_name: ExampleHost - host_ip: 127.0.0.1 - timeout: 10 - exact_match: no - remove_duplicate: yes - -- name: Reduce host inventory information to provided keys - local_action: - module: zabbix_host_info - server_url: http://monitor.example.com - login_user: username - login_password: password - host_name: ExampleHost - host_inventory: - - os - - tag - host_ip: 127.0.0.1 - timeout: 10 - exact_match: no - remove_duplicate: yes -''' - - -import atexit -import traceback - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - - -class Host(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - def get_hosts_by_host_name(self, host_name, exact_match, host_inventory): - """ Get host by host name """ - search_key = 'search' - if exact_match: - search_key = 'filter' - host_list = self._zapi.host.get({ - 'output': 'extend', - 'selectParentTemplates': ['name'], - search_key: {'host': [host_name]}, - 'selectInventory': host_inventory, - 'selectGroups': 'extend', - 'selectTags': 'extend', - 'selectMacros': 'extend' - }) - if len(host_list) < 1: - self._module.fail_json(msg="Host not found: %s" % host_name) - else: - return host_list - - def get_hosts_by_ip(self, host_ips, host_inventory): - """ Get host by host ip(s) """ - hostinterfaces = self._zapi.hostinterface.get({ - 'output': 'extend', - 'filter': { - 'ip': host_ips - } - }) - if len(hostinterfaces) < 1: - self._module.fail_json(msg="Host not found: %s" % host_ips) - host_list = [] - for hostinterface in hostinterfaces: - host = self._zapi.host.get({ - 'output': 'extend', - 'selectGroups': 'extend', - 'selectParentTemplates': ['name'], - 'hostids': hostinterface['hostid'], - 'selectInventory': host_inventory, - 'selectTags': 'extend', - 'selectMacros': 'extend' - }) - host[0]['hostinterfaces'] = hostinterface - host_list.append(host[0]) - return host_list - - def delete_duplicate_hosts(self, hosts): - """ Delete duplicated hosts """ - unique_hosts = [] - listed_hostnames = [] - for zabbix_host in hosts: - if zabbix_host['name'] in listed_hostnames: - continue - unique_hosts.append(zabbix_host) - listed_hostnames.append(zabbix_host['name']) - return unique_hosts - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - host_name=dict(type='str', default='', required=False), - host_ip=dict(type='list', default=[], required=False), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - timeout=dict(type='int', default=10), - exact_match=dict(type='bool', required=False, default=False), - remove_duplicate=dict(type='bool', required=False, default=True), - host_inventory=dict(type='list', default=[], required=False) - ), - supports_check_mode=True - ) - if module._name == 'zabbix_host_facts': - module.deprecate("The 'zabbix_host_facts' module has been renamed to 'zabbix_host_info'", version='2.13') - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - host_name = module.params['host_name'] - host_ips = module.params['host_ip'] - timeout = module.params['timeout'] - exact_match = module.params['exact_match'] - is_remove_duplicate = module.params['remove_duplicate'] - host_inventory = module.params['host_inventory'] - - if not host_inventory: - host_inventory = 'extend' - - zbx = None - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - host = Host(module, zbx) - - if host_name: - hosts = host.get_hosts_by_host_name(host_name, exact_match, host_inventory) - if is_remove_duplicate: - hosts = host.delete_duplicate_hosts(hosts) - extended_hosts = [] - for zabbix_host in hosts: - zabbix_host['hostinterfaces'] = host._zapi.hostinterface.get({ - 'output': 'extend', 'hostids': zabbix_host['hostid'] - }) - extended_hosts.append(zabbix_host) - module.exit_json(ok=True, hosts=extended_hosts) - - elif host_ips: - extended_hosts = host.get_hosts_by_ip(host_ips, host_inventory) - if is_remove_duplicate: - hosts = host.delete_duplicate_hosts(extended_hosts) - module.exit_json(ok=True, hosts=extended_hosts) - else: - module.exit_json(ok=False, hosts=[], result="No Host present") - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_hostmacro.py b/plugins/modules/monitoring/zabbix/zabbix_hostmacro.py deleted file mode 100644 index bf29841ad0..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_hostmacro.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: zabbix_hostmacro -short_description: Create/update/delete Zabbix host macros -description: - - manages Zabbix host macros, it can create, update or delete them. -author: - - "Cove (@cove)" - - Dean Hailin Song (!UNKNOWN) -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - host_name: - description: - - Name of the host. - required: true - type: str - macro_name: - description: - - Name of the host macro in zabbix native format C({$MACRO}) or simple format C(MACRO). - required: true - type: str - macro_value: - description: - - Value of the host macro. - - Required if I(state=present). - type: str - state: - description: - - State of the macro. - - On C(present), it will create if macro does not exist or update the macro if the associated data is different. - - On C(absent) will remove a macro if it exists. - required: false - choices: ['present', 'absent'] - type: str - default: "present" - force: - description: - - Only updates an existing macro if set to C(yes). - default: 'yes' - type: bool - -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = r''' -- name: Create new host macro or update an existing macro's value - local_action: - module: zabbix_hostmacro - server_url: http://monitor.example.com - login_user: username - login_password: password - host_name: ExampleHost - macro_name: EXAMPLE.MACRO - macro_value: Example value - state: present - -# Values with curly brackets need to be quoted otherwise they will be interpreted as a dictionary -- name: Create new host macro in Zabbix native format - local_action: - module: zabbix_hostmacro - server_url: http://monitor.example.com - login_user: username - login_password: password - host_name: ExampleHost - macro_name: "{$EXAMPLE.MACRO}" - macro_value: Example value - state: present - -- name: Delete existing host macro - local_action: - module: zabbix_hostmacro - server_url: http://monitor.example.com - login_user: username - login_password: password - host_name: ExampleHost - macro_name: "{$EXAMPLE.MACRO}" - state: absent -''' - - -import atexit -import traceback - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -class HostMacro(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - # get host id by host name - def get_host_id(self, host_name): - try: - 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: - host_id = host_list[0]['hostid'] - return host_id - except Exception as e: - self._module.fail_json(msg="Failed to get the host %s id: %s." % (host_name, e)) - - # get host macro - def get_host_macro(self, macro_name, host_id): - try: - host_macro_list = self._zapi.usermacro.get( - {"output": "extend", "selectSteps": "extend", 'hostids': [host_id], 'filter': {'macro': macro_name}}) - if len(host_macro_list) > 0: - return host_macro_list[0] - return None - except Exception as e: - self._module.fail_json(msg="Failed to get host macro %s: %s" % (macro_name, e)) - - # create host macro - def create_host_macro(self, macro_name, macro_value, host_id): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.usermacro.create({'hostid': host_id, 'macro': macro_name, 'value': macro_value}) - self._module.exit_json(changed=True, result="Successfully added host macro %s" % macro_name) - except Exception as e: - self._module.fail_json(msg="Failed to create host macro %s: %s" % (macro_name, e)) - - # update host macro - def update_host_macro(self, host_macro_obj, macro_name, macro_value): - host_macro_id = host_macro_obj['hostmacroid'] - if host_macro_obj['macro'] == macro_name and host_macro_obj['value'] == macro_value: - self._module.exit_json(changed=False, result="Host macro %s already up to date" % macro_name) - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.usermacro.update({'hostmacroid': host_macro_id, 'value': macro_value}) - self._module.exit_json(changed=True, result="Successfully updated host macro %s" % macro_name) - except Exception as e: - self._module.fail_json(msg="Failed to update host macro %s: %s" % (macro_name, e)) - - # delete host macro - def delete_host_macro(self, host_macro_obj, macro_name): - host_macro_id = host_macro_obj['hostmacroid'] - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.usermacro.delete([host_macro_id]) - self._module.exit_json(changed=True, result="Successfully deleted host macro %s" % macro_name) - except Exception as e: - self._module.fail_json(msg="Failed to delete host macro %s: %s" % (macro_name, e)) - - -def normalize_macro_name(macro_name): - # Zabbix handles macro names in upper case characters - if ':' in macro_name: - macro_name = ':'.join([macro_name.split(':')[0].upper(), ':'.join(macro_name.split(':')[1:])]) - else: - macro_name = macro_name.upper() - - # Valid format for macro is {$MACRO} - if not macro_name.startswith('{$'): - macro_name = '{$' + macro_name - if not macro_name.endswith('}'): - macro_name = macro_name + '}' - - return macro_name - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - host_name=dict(type='str', required=True), - macro_name=dict(type='str', required=True), - macro_value=dict(type='str', required=False), - state=dict(type='str', default='present', choices=['present', 'absent']), - timeout=dict(type='int', default=10), - force=dict(type='bool', default=True) - ), - required_if=[ - ['state', 'present', ['macro_value']] - ], - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - host_name = module.params['host_name'] - macro_name = normalize_macro_name(module.params['macro_name']) - macro_value = module.params['macro_value'] - state = module.params['state'] - timeout = module.params['timeout'] - force = module.params['force'] - - zbx = None - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - host_macro_class_obj = HostMacro(module, zbx) - - if host_name: - host_id = host_macro_class_obj.get_host_id(host_name) - host_macro_obj = host_macro_class_obj.get_host_macro(macro_name, host_id) - - if state == 'absent': - if not host_macro_obj: - module.exit_json(changed=False, msg="Host Macro %s does not exist" % macro_name) - else: - # delete a macro - host_macro_class_obj.delete_host_macro(host_macro_obj, macro_name) - else: - if not host_macro_obj: - # create host macro - host_macro_class_obj.create_host_macro(macro_name, macro_value, host_id) - elif force: - # update host macro - host_macro_class_obj.update_host_macro(host_macro_obj, macro_name, macro_value) - else: - module.exit_json(changed=False, result="Host macro %s already exists and force is set to no" % macro_name) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_maintenance.py b/plugins/modules/monitoring/zabbix/zabbix_maintenance.py deleted file mode 100644 index 954fc20333..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_maintenance.py +++ /dev/null @@ -1,402 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2013, Alexander Bulimov -# 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' - -module: zabbix_maintenance -short_description: Create Zabbix maintenance windows -description: - - This module will let you create Zabbix maintenance windows. -author: "Alexander Bulimov (@abulimov)" -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - state: - description: - - Create or remove a maintenance window. Maintenance window to remove is identified by name. - default: present - choices: [ "present", "absent" ] - type: str - host_names: - description: - - Hosts to manage maintenance window for. - - B(Required) option when I(state=present) and I(host_groups) is not used. - aliases: [ "host_name" ] - type: list - elements: str - host_groups: - description: - - Host groups to manage maintenance window for. - - B(Required) option when I(state=present) and I(host_names) is not used. - aliases: [ "host_group" ] - type: list - elements: str - minutes: - description: - - Length of maintenance window in minutes. - default: 10 - type: int - name: - description: - - Unique name of maintenance window. - required: true - type: str - desc: - description: - - Short description of maintenance window. - default: Created by Ansible - type: str - collect_data: - description: - - Type of maintenance. With data collection, or without. - type: bool - default: 'yes' - -extends_documentation_fragment: -- community.general.zabbix - - -notes: - - Useful for setting hosts in maintenance mode before big update, - and removing maintenance window after update. - - Module creates maintenance window from now() to now() + minutes, - so if Zabbix server's time and host's time are not synchronized, - you will get strange results. - - Install required module with 'pip install zabbix-api' command. -''' - -EXAMPLES = r''' -- name: Create a named maintenance window for host www1 for 90 minutes - zabbix_maintenance: - name: Update of www1 - host_name: www1.example.com - state: present - minutes: 90 - server_url: https://monitoring.example.com - login_user: ansible - login_password: pAsSwOrD - -- name: Create a named maintenance window for host www1 and host groups Office and Dev - zabbix_maintenance: - name: Update of www1 - host_name: www1.example.com - host_groups: - - Office - - Dev - state: present - server_url: https://monitoring.example.com - login_user: ansible - login_password: pAsSwOrD - -- name: Create a named maintenance window for hosts www1 and db1, without data collection. - zabbix_maintenance: - name: update - host_names: - - www1.example.com - - db1.example.com - state: present - collect_data: False - server_url: https://monitoring.example.com - login_user: ansible - login_password: pAsSwOrD - -- name: Remove maintenance window by name - zabbix_maintenance: - name: Test1 - state: absent - server_url: https://monitoring.example.com - login_user: ansible - login_password: pAsSwOrD -''' - - -import atexit -import datetime -import time -import traceback - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -def create_maintenance(zbx, group_ids, host_ids, start_time, maintenance_type, period, name, desc): - end_time = start_time + period - try: - zbx.maintenance.create( - { - "groupids": group_ids, - "hostids": host_ids, - "name": name, - "maintenance_type": maintenance_type, - "active_since": str(start_time), - "active_till": str(end_time), - "description": desc, - "timeperiods": [{ - "timeperiod_type": "0", - "start_date": str(start_time), - "period": str(period), - }] - } - ) - # zabbix_api can call sys.exit() so we need to catch SystemExit here - except (Exception, SystemExit) as e: - return 1, None, str(e) - return 0, None, None - - -def update_maintenance(zbx, maintenance_id, group_ids, host_ids, start_time, maintenance_type, period, desc): - end_time = start_time + period - try: - zbx.maintenance.update( - { - "maintenanceid": maintenance_id, - "groupids": group_ids, - "hostids": host_ids, - "maintenance_type": maintenance_type, - "active_since": str(start_time), - "active_till": str(end_time), - "description": desc, - "timeperiods": [{ - "timeperiod_type": "0", - "start_date": str(start_time), - "period": str(period), - }] - } - ) - # zabbix_api can call sys.exit() so we need to catch SystemExit here - except (Exception, SystemExit) as e: - return 1, None, str(e) - return 0, None, None - - -def get_maintenance(zbx, name): - try: - maintenances = zbx.maintenance.get( - { - "filter": - { - "name": name, - }, - "selectGroups": "extend", - "selectHosts": "extend" - } - ) - # zabbix_api can call sys.exit() so we need to catch SystemExit here - except (Exception, SystemExit) as e: - return 1, None, str(e) - - for maintenance in maintenances: - maintenance["groupids"] = [group["groupid"] for group in maintenance["groups"]] if "groups" in maintenance else [] - maintenance["hostids"] = [host["hostid"] for host in maintenance["hosts"]] if "hosts" in maintenance else [] - return 0, maintenance, None - - return 0, None, None - - -def delete_maintenance(zbx, maintenance_id): - try: - zbx.maintenance.delete([maintenance_id]) - # zabbix_api can call sys.exit() so we need to catch SystemExit here - except (Exception, SystemExit) as e: - return 1, None, str(e) - return 0, None, None - - -def get_group_ids(zbx, host_groups): - group_ids = [] - for group in host_groups: - try: - result = zbx.hostgroup.get( - { - "output": "extend", - "filter": - { - "name": group - } - } - ) - # zabbix_api can call sys.exit() so we need to catch SystemExit here - except (Exception, SystemExit) as e: - return 1, None, str(e) - - if not result: - return 1, None, "Group id for group %s not found" % group - - group_ids.append(result[0]["groupid"]) - - return 0, group_ids, None - - -def get_host_ids(zbx, host_names): - host_ids = [] - for host in host_names: - try: - result = zbx.host.get( - { - "output": "extend", - "filter": - { - "name": host - } - } - ) - # zabbix_api can call sys.exit() so we need to catch SystemExit here - except (Exception, SystemExit) as e: - return 1, None, str(e) - - if not result: - return 1, None, "Host id for host %s not found" % host - - host_ids.append(result[0]["hostid"]) - - return 0, host_ids, None - - -def main(): - module = AnsibleModule( - argument_spec=dict( - state=dict(type='str', required=False, default='present', choices=['present', 'absent']), - server_url=dict(type='str', required=True, aliases=['url']), - host_names=dict(type='list', required=False, default=None, aliases=['host_name']), - minutes=dict(type='int', required=False, default=10), - host_groups=dict(type='list', required=False, default=None, aliases=['host_group']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - name=dict(type='str', required=True), - desc=dict(type='str', required=False, default="Created by Ansible"), - collect_data=dict(type='bool', required=False, default=True), - timeout=dict(type='int', default=10), - ), - supports_check_mode=True, - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - host_names = module.params['host_names'] - host_groups = module.params['host_groups'] - state = module.params['state'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - minutes = module.params['minutes'] - name = module.params['name'] - desc = module.params['desc'] - server_url = module.params['server_url'] - collect_data = module.params['collect_data'] - timeout = module.params['timeout'] - - if collect_data: - maintenance_type = 0 - else: - maintenance_type = 1 - - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - # zabbix_api can call sys.exit() so we need to catch SystemExit here - except (Exception, SystemExit) as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - changed = False - - if state == "present": - - if not host_names and not host_groups: - module.fail_json(msg="At least one host_name or host_group must be defined for each created maintenance.") - - now = datetime.datetime.now().replace(second=0) - start_time = time.mktime(now.timetuple()) - period = 60 * int(minutes) # N * 60 seconds - - if host_groups: - (rc, group_ids, error) = get_group_ids(zbx, host_groups) - if rc != 0: - module.fail_json(msg="Failed to get group_ids: %s" % error) - else: - group_ids = [] - - if host_names: - (rc, host_ids, error) = get_host_ids(zbx, host_names) - if rc != 0: - module.fail_json(msg="Failed to get host_ids: %s" % error) - else: - host_ids = [] - - (rc, maintenance, error) = get_maintenance(zbx, name) - if rc != 0: - module.fail_json(msg="Failed to check maintenance %s existence: %s" % (name, error)) - - if maintenance and ( - sorted(group_ids) != sorted(maintenance["groupids"]) or - sorted(host_ids) != sorted(maintenance["hostids"]) or - str(maintenance_type) != maintenance["maintenance_type"] or - str(int(start_time)) != maintenance["active_since"] or - str(int(start_time + period)) != maintenance["active_till"] - ): - if module.check_mode: - changed = True - else: - (rc, data, error) = update_maintenance(zbx, maintenance["maintenanceid"], group_ids, host_ids, start_time, maintenance_type, period, desc) - if rc == 0: - changed = True - else: - module.fail_json(msg="Failed to update maintenance: %s" % error) - - if not maintenance: - if module.check_mode: - changed = True - else: - (rc, data, error) = create_maintenance(zbx, group_ids, host_ids, start_time, maintenance_type, period, name, desc) - if rc == 0: - changed = True - else: - module.fail_json(msg="Failed to create maintenance: %s" % error) - - if state == "absent": - - (rc, maintenance, error) = get_maintenance(zbx, name) - if rc != 0: - module.fail_json(msg="Failed to check maintenance %s existence: %s" % (name, error)) - - if maintenance: - if module.check_mode: - changed = True - else: - (rc, data, error) = delete_maintenance(zbx, maintenance["maintenanceid"]) - if rc == 0: - changed = True - else: - module.fail_json(msg="Failed to remove maintenance: %s" % error) - - module.exit_json(changed=changed) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_map.py b/plugins/modules/monitoring/zabbix/zabbix_map.py deleted file mode 100644 index 5b15c87181..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_map.py +++ /dev/null @@ -1,829 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017-2018, Antony Alekseyev -# 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 - -DOCUMENTATION = r''' ---- -module: zabbix_map -author: - - "Antony Alekseyev (@Akint)" -short_description: Create/update/delete Zabbix maps -description: - - "This module allows you to create, modify and delete Zabbix map entries, - using Graphviz binaries and text description written in DOT language. - Nodes of the graph will become map elements and edges will become links between map elements. - See U(https://en.wikipedia.org/wiki/DOT_(graph_description_language)) and U(https://www.graphviz.org/) for details. - Inspired by U(http://blog.zabbix.com/maps-for-the-lazy/)." - - "The following extra node attributes are supported: - C(zbx_host) contains name of the host in Zabbix. Use this if desired type of map element is C(host). - C(zbx_group) contains name of the host group in Zabbix. Use this if desired type of map element is C(host group). - C(zbx_map) contains name of the map in Zabbix. Use this if desired type of map element is C(map). - C(zbx_label) contains label of map element. - C(zbx_image) contains name of the image used to display the element in default state. - C(zbx_image_disabled) contains name of the image used to display disabled map element. - C(zbx_image_maintenance) contains name of the image used to display map element in maintenance. - C(zbx_image_problem) contains name of the image used to display map element with problems. - C(zbx_url) contains map element URL in C(name:url) format. - More than one URL could be specified by adding a postfix (e.g., C(zbx_url1), C(zbx_url2))." - - "The following extra link attributes are supported: - C(zbx_draw_style) contains link line draw style. Possible values: C(line), C(bold), C(dotted), C(dashed). - C(zbx_trigger) contains name of the trigger used as a link indicator in C(host_name:trigger_name) format. - More than one trigger could be specified by adding a postfix (e.g., C(zbx_trigger1), C(zbx_trigger2)). - C(zbx_trigger_color) contains indicator color specified either as CSS3 name or as a hexadecimal code starting with C(#). - C(zbx_trigger_draw_style) contains indicator draw style. Possible values are the same as for C(zbx_draw_style)." -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" - - pydotplus - - webcolors - - Pillow - - Graphviz -options: - name: - description: - - Name of the map. - required: true - aliases: [ "map_name" ] - type: str - data: - description: - - Graph written in DOT language. - required: false - aliases: [ "dot_data" ] - type: str - state: - description: - - State of the map. - - On C(present), it will create if map does not exist or update the map if the associated data is different. - - On C(absent) will remove the map if it exists. - required: false - choices: ['present', 'absent'] - default: "present" - type: str - width: - description: - - Width of the map. - required: false - default: 800 - type: int - height: - description: - - Height of the map. - required: false - default: 600 - type: int - margin: - description: - - Size of white space between map's borders and its elements. - required: false - default: 40 - type: int - expand_problem: - description: - - Whether the problem trigger will be displayed for elements with a single problem. - required: false - type: bool - default: true - highlight: - description: - - Whether icon highlighting is enabled. - required: false - type: bool - default: true - label_type: - description: - - Map element label type. - required: false - choices: ['label', 'ip', 'name', 'status', 'nothing', 'custom'] - default: "name" - type: str - default_image: - description: - - Name of the Zabbix image used to display the element if this element doesn't have the C(zbx_image) attribute defined. - required: false - aliases: [ "image" ] - type: str - -extends_documentation_fragment: -- community.general.zabbix - -''' - -RETURN = r''' # ''' - -EXAMPLES = r''' -### -### Example inventory: -# [web] -# web[01:03].example.com ansible_host=127.0.0.1 -# [db] -# db.example.com ansible_host=127.0.0.1 -# [backup] -# backup.example.com ansible_host=127.0.0.1 -### -### Each inventory host is present in Zabbix with a matching name. -### -### Contents of 'map.j2': -# digraph G { -# graph [layout=dot splines=false overlap=scale] -# INTERNET [zbx_url="Google:https://google.com" zbx_image="Cloud_(96)"] -# {% for web_host in groups.web %} -# {% set web_loop = loop %} -# web{{ '%03d' % web_loop.index }} [zbx_host="{{ web_host }}"] -# INTERNET -> web{{ '%03d' % web_loop.index }} [zbx_trigger="{{ web_host }}:Zabbix agent on {HOST.NAME} is unreachable for 5 minutes"] -# {% for db_host in groups.db %} -# {% set db_loop = loop %} -# web{{ '%03d' % web_loop.index }} -> db{{ '%03d' % db_loop.index }} -# {% endfor %} -# {% endfor %} -# { rank=same -# {% for db_host in groups.db %} -# {% set db_loop = loop %} -# db{{ '%03d' % db_loop.index }} [zbx_host="{{ db_host }}"] -# {% for backup_host in groups.backup %} -# {% set backup_loop = loop %} -# db{{ '%03d' % db_loop.index }} -> backup{{ '%03d' % backup_loop.index }} [color="blue"] -# {% endfor %} -# {% endfor %} -# {% for backup_host in groups.backup %} -# {% set backup_loop = loop %} -# backup{{ '%03d' % backup_loop.index }} [zbx_host="{{ backup_host }}"] -# {% endfor %} -# } -# } -### -### Create Zabbix map "Demo Map" made of template 'map.j2' -- name: Create Zabbix map - zabbix_map: - server_url: http://zabbix.example.com - login_user: username - login_password: password - name: Demo map - state: present - data: "{{ lookup('template', 'map.j2') }}" - default_image: Server_(64) - expand_problem: no - highlight: no - label_type: label - delegate_to: localhost - run_once: yes -''' - -ANSIBLE_METADATA = { - 'metadata_version': '1.1', - 'supported_by': 'community', - 'status': ['preview'] -} - - -import atexit -import base64 -import traceback - -from io import BytesIO -from operator import itemgetter -from distutils.version import StrictVersion -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - -try: - import pydotplus - HAS_PYDOTPLUS = True -except ImportError: - PYDOT_IMP_ERR = traceback.format_exc() - HAS_PYDOTPLUS = False - -try: - import webcolors - HAS_WEBCOLORS = True -except ImportError: - WEBCOLORS_IMP_ERR = traceback.format_exc() - HAS_WEBCOLORS = False - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -try: - from PIL import Image - HAS_PIL = True -except ImportError: - PIL_IMP_ERR = traceback.format_exc() - HAS_PIL = False - - -class Map(): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - self.map_name = module.params['name'] - self.dot_data = module.params['data'] - self.width = module.params['width'] - self.height = module.params['height'] - self.state = module.params['state'] - self.default_image = module.params['default_image'] - self.map_id = self._get_sysmap_id(self.map_name) - self.margin = module.params['margin'] - self.expand_problem = module.params['expand_problem'] - self.highlight = module.params['highlight'] - self.label_type = module.params['label_type'] - self.api_version = self._zapi.api_version() - self.selements_sort_keys = self._get_selements_sort_keys() - - def _build_graph(self): - try: - graph_without_positions = pydotplus.graph_from_dot_data(self.dot_data) - dot_data_with_positions = graph_without_positions.create_dot() - graph_with_positions = pydotplus.graph_from_dot_data(dot_data_with_positions) - if graph_with_positions: - return graph_with_positions - except Exception as e: - self._module.fail_json(msg="Failed to build graph from DOT data: %s" % e) - - def get_map_config(self): - if not self.dot_data: - self._module.fail_json(msg="'data' is mandatory with state 'present'") - graph = self._build_graph() - nodes = self._get_graph_nodes(graph) - edges = self._get_graph_edges(graph) - icon_ids = self._get_icon_ids() - map_config = { - 'name': self.map_name, - 'label_type': self._get_label_type_id(self.label_type), - 'expandproblem': int(self.expand_problem), - 'highlight': int(self.highlight), - 'width': self.width, - 'height': self.height, - 'selements': self._get_selements(graph, nodes, icon_ids), - 'links': self._get_links(nodes, edges), - } - return map_config - - def _get_label_type_id(self, label_type): - label_type_ids = { - 'label': 0, - 'ip': 1, - 'name': 2, - 'status': 3, - 'nothing': 4, - 'custom': 5, - } - try: - label_type_id = label_type_ids[label_type] - except Exception as e: - self._module.fail_json(msg="Failed to find id for label type '%s': %s" % (label_type, e)) - return label_type_id - - def _get_images_info(self, data, icon_ids): - images = [ - { - 'dot_tag': 'zbx_image', - 'zbx_property': 'iconid_off', - 'mandatory': True - }, - { - 'dot_tag': 'zbx_image_disabled', - 'zbx_property': 'iconid_disabled', - 'mandatory': False - }, - { - 'dot_tag': 'zbx_image_maintenance', - 'zbx_property': 'iconid_maintenance', - 'mandatory': False - }, - { - 'dot_tag': 'zbx_image_problem', - 'zbx_property': 'iconid_on', - 'mandatory': False - } - ] - images_info = {} - default_image = self.default_image if self.default_image else sorted(icon_ids.items())[0][0] - for image in images: - image_name = data.get(image['dot_tag'], None) - if not image_name: - if image['mandatory']: - image_name = default_image - else: - continue - image_name = remove_quotes(image_name) - if image_name in icon_ids: - images_info[image['zbx_property']] = icon_ids[image_name] - if not image['mandatory']: - images_info['use_iconmap'] = 0 - else: - self._module.fail_json(msg="Failed to find id for image '%s'" % image_name) - return images_info - - def _get_element_type(self, data): - types = { - 'host': 0, - 'sysmap': 1, - 'trigger': 2, - 'group': 3, - 'image': 4 - } - element_type = { - 'elementtype': types['image'], - } - if StrictVersion(self.api_version) < StrictVersion('3.4'): - element_type.update({ - 'elementid': "0", - }) - for type_name, type_id in sorted(types.items()): - field_name = 'zbx_' + type_name - if field_name in data: - method_name = '_get_' + type_name + '_id' - element_name = remove_quotes(data[field_name]) - get_element_id = getattr(self, method_name, None) - if get_element_id: - elementid = get_element_id(element_name) - if elementid and int(elementid) > 0: - element_type.update({ - 'elementtype': type_id, - 'label': element_name - }) - if StrictVersion(self.api_version) < StrictVersion('3.4'): - element_type.update({ - 'elementid': elementid, - }) - else: - element_type.update({ - 'elements': [{ - type_name + 'id': elementid, - }], - }) - break - else: - self._module.fail_json(msg="Failed to find id for %s '%s'" % (type_name, element_name)) - return element_type - - # get list of map elements (nodes) - def _get_selements(self, graph, nodes, icon_ids): - selements = [] - icon_sizes = {} - scales = self._get_scales(graph) - for selementid, (node, data) in enumerate(nodes.items(), start=1): - selement = { - 'selementid': selementid - } - data['selementid'] = selementid - - images_info = self._get_images_info(data, icon_ids) - selement.update(images_info) - image_id = images_info['iconid_off'] - if image_id not in icon_sizes: - icon_sizes[image_id] = self._get_icon_size(image_id) - - pos = self._convert_coordinates(data['pos'], scales, icon_sizes[image_id]) - selement.update(pos) - - selement['label'] = remove_quotes(node) - element_type = self._get_element_type(data) - selement.update(element_type) - - label = self._get_label(data) - if label: - selement['label'] = label - - urls = self._get_urls(data) - if urls: - selement['urls'] = urls - - selements.append(selement) - return selements - - def _get_links(self, nodes, edges): - links = {} - for edge in edges: - link_id = tuple(sorted(edge.obj_dict['points'])) - node1, node2 = link_id - data = edge.obj_dict['attributes'] - - if "style" in data and data['style'] == "invis": - continue - - if link_id not in links: - links[link_id] = { - 'selementid1': min(nodes[node1]['selementid'], nodes[node2]['selementid']), - 'selementid2': max(nodes[node1]['selementid'], nodes[node2]['selementid']), - } - link = links[link_id] - - if "color" not in link: - link['color'] = self._get_color_hex(remove_quotes(data.get('color', 'green'))) - - if "zbx_draw_style" not in link: - link['drawtype'] = self._get_link_draw_style_id(remove_quotes(data.get('zbx_draw_style', 'line'))) - - label = self._get_label(data) - if label and "label" not in link: - link['label'] = label - - triggers = self._get_triggers(data) - if triggers: - if "linktriggers" not in link: - link['linktriggers'] = [] - link['linktriggers'] += triggers - - return list(links.values()) - - def _get_urls(self, data): - urls = [] - for url_raw in [remove_quotes(value) for key, value in data.items() if key.startswith("zbx_url")]: - try: - name, url = url_raw.split(':', 1) - except Exception as e: - self._module.fail_json(msg="Failed to parse zbx_url='%s': %s" % (url_raw, e)) - urls.append({ - 'name': name, - 'url': url, - }) - return urls - - def _get_triggers(self, data): - triggers = [] - for trigger_definition in [remove_quotes(value) for key, value in data.items() if key.startswith("zbx_trigger")]: - triggerid = self._get_trigger_id(trigger_definition) - if triggerid: - triggers.append({ - 'triggerid': triggerid, - 'color': self._get_color_hex(remove_quotes(data.get('zbx_trigger_color', 'red'))), - 'drawtype': self._get_link_draw_style_id(remove_quotes(data.get('zbx_trigger_draw_style', 'bold'))), - }) - else: - self._module.fail_json(msg="Failed to find trigger '%s'" % (trigger_definition)) - return triggers - - @staticmethod - def _get_label(data, default=None): - if "zbx_label" in data: - label = remove_quotes(data['zbx_label']).replace('\\n', '\n') - elif "label" in data: - label = remove_quotes(data['label']) - else: - label = default - return label - - def _get_sysmap_id(self, map_name): - exist_map = self._zapi.map.get({'filter': {'name': map_name}}) - if exist_map: - return exist_map[0]['sysmapid'] - return None - - def _get_group_id(self, group_name): - exist_group = self._zapi.hostgroup.get({'filter': {'name': group_name}}) - if exist_group: - return exist_group[0]['groupid'] - return None - - def map_exists(self): - return bool(self.map_id) - - def create_map(self, map_config): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - result = self._zapi.map.create(map_config) - if result: - return result - except Exception as e: - self._module.fail_json(msg="Failed to create map: %s" % e) - - def update_map(self, map_config): - if not self.map_id: - self._module.fail_json(msg="Failed to update map: map_id is unknown. Try to create_map instead.") - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - map_config['sysmapid'] = self.map_id - result = self._zapi.map.update(map_config) - if result: - return result - except Exception as e: - self._module.fail_json(msg="Failed to update map: %s" % e) - - def delete_map(self): - if not self.map_id: - self._module.fail_json(msg="Failed to delete map: map_id is unknown.") - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.map.delete([self.map_id]) - except Exception as e: - self._module.fail_json(msg="Failed to delete map, Exception: %s" % e) - - def is_exist_map_correct(self, generated_map_config): - exist_map_configs = self._zapi.map.get({ - 'sysmapids': self.map_id, - 'selectLinks': 'extend', - 'selectSelements': 'extend' - }) - exist_map_config = exist_map_configs[0] - if not self._is_dicts_equal(generated_map_config, exist_map_config): - return False - if not self._is_selements_equal(generated_map_config['selements'], exist_map_config['selements']): - return False - self._update_ids(generated_map_config, exist_map_config) - if not self._is_links_equal(generated_map_config['links'], exist_map_config['links']): - return False - return True - - def _get_selements_sort_keys(self): - keys_to_sort = ['label'] - if StrictVersion(self.api_version) < StrictVersion('3.4'): - keys_to_sort.insert(0, 'elementid') - return keys_to_sort - - def _is_selements_equal(self, generated_selements, exist_selements): - if len(generated_selements) != len(exist_selements): - return False - generated_selements_sorted = sorted(generated_selements, key=itemgetter(*self.selements_sort_keys)) - exist_selements_sorted = sorted(exist_selements, key=itemgetter(*self.selements_sort_keys)) - for (generated_selement, exist_selement) in zip(generated_selements_sorted, exist_selements_sorted): - if StrictVersion(self.api_version) >= StrictVersion("3.4"): - if not self._is_elements_equal(generated_selement.get('elements', []), exist_selement.get('elements', [])): - return False - if not self._is_dicts_equal(generated_selement, exist_selement, ['selementid']): - return False - if not self._is_urls_equal(generated_selement.get('urls', []), exist_selement.get('urls', [])): - return False - return True - - def _is_urls_equal(self, generated_urls, exist_urls): - if len(generated_urls) != len(exist_urls): - return False - generated_urls_sorted = sorted(generated_urls, key=itemgetter('name', 'url')) - exist_urls_sorted = sorted(exist_urls, key=itemgetter('name', 'url')) - for (generated_url, exist_url) in zip(generated_urls_sorted, exist_urls_sorted): - if not self._is_dicts_equal(generated_url, exist_url, ['selementid']): - return False - return True - - def _is_elements_equal(self, generated_elements, exist_elements): - if len(generated_elements) != len(exist_elements): - return False - generated_elements_sorted = sorted(generated_elements, key=lambda k: k.values()[0]) - exist_elements_sorted = sorted(exist_elements, key=lambda k: k.values()[0]) - for (generated_element, exist_element) in zip(generated_elements_sorted, exist_elements_sorted): - if not self._is_dicts_equal(generated_element, exist_element, ['selementid']): - return False - return True - - # since generated IDs differ from real Zabbix ones, make real IDs match generated ones - def _update_ids(self, generated_map_config, exist_map_config): - generated_selements_sorted = sorted(generated_map_config['selements'], key=itemgetter(*self.selements_sort_keys)) - exist_selements_sorted = sorted(exist_map_config['selements'], key=itemgetter(*self.selements_sort_keys)) - id_mapping = {} - for (generated_selement, exist_selement) in zip(generated_selements_sorted, exist_selements_sorted): - id_mapping[exist_selement['selementid']] = generated_selement['selementid'] - for link in exist_map_config['links']: - link['selementid1'] = id_mapping[link['selementid1']] - link['selementid2'] = id_mapping[link['selementid2']] - if link['selementid2'] < link['selementid1']: - link['selementid1'], link['selementid2'] = link['selementid2'], link['selementid1'] - - def _is_links_equal(self, generated_links, exist_links): - if len(generated_links) != len(exist_links): - return False - generated_links_sorted = sorted(generated_links, key=itemgetter('selementid1', 'selementid2', 'color', 'drawtype')) - exist_links_sorted = sorted(exist_links, key=itemgetter('selementid1', 'selementid2', 'color', 'drawtype')) - for (generated_link, exist_link) in zip(generated_links_sorted, exist_links_sorted): - if not self._is_dicts_equal(generated_link, exist_link, ['selementid1', 'selementid2']): - return False - if not self._is_triggers_equal(generated_link.get('linktriggers', []), exist_link.get('linktriggers', [])): - return False - return True - - def _is_triggers_equal(self, generated_triggers, exist_triggers): - if len(generated_triggers) != len(exist_triggers): - return False - generated_triggers_sorted = sorted(generated_triggers, key=itemgetter('triggerid')) - exist_triggers_sorted = sorted(exist_triggers, key=itemgetter('triggerid')) - for (generated_trigger, exist_trigger) in zip(generated_triggers_sorted, exist_triggers_sorted): - if not self._is_dicts_equal(generated_trigger, exist_trigger): - return False - return True - - @staticmethod - def _is_dicts_equal(d1, d2, exclude_keys=None): - if exclude_keys is None: - exclude_keys = [] - for key in d1.keys(): - if isinstance(d1[key], dict) or isinstance(d1[key], list): - continue - if key in exclude_keys: - continue - # compare as strings since Zabbix API returns everything as strings - if key not in d2 or str(d2[key]) != str(d1[key]): - return False - return True - - def _get_host_id(self, hostname): - hostid = self._zapi.host.get({'filter': {'host': hostname}}) - if hostid: - return str(hostid[0]['hostid']) - - def _get_trigger_id(self, trigger_definition): - try: - host, trigger = trigger_definition.split(':', 1) - except Exception as e: - self._module.fail_json(msg="Failed to parse zbx_trigger='%s': %s" % (trigger_definition, e)) - triggerid = self._zapi.trigger.get({ - 'host': host, - 'filter': { - 'description': trigger - } - }) - if triggerid: - return str(triggerid[0]['triggerid']) - - def _get_icon_ids(self): - icons_list = self._zapi.image.get({}) - icon_ids = {} - for icon in icons_list: - icon_ids[icon['name']] = icon['imageid'] - return icon_ids - - def _get_icon_size(self, icon_id): - icons_list = self._zapi.image.get({ - 'imageids': [ - icon_id - ], - 'select_image': True - }) - if len(icons_list) > 0: - icon_base64 = icons_list[0]['image'] - else: - self._module.fail_json(msg="Failed to find image with id %s" % icon_id) - image = Image.open(BytesIO(base64.b64decode(icon_base64))) - icon_width, icon_height = image.size - return icon_width, icon_height - - @staticmethod - def _get_node_attributes(node): - attr = {} - if "attributes" in node.obj_dict: - attr.update(node.obj_dict['attributes']) - pos = node.get_pos() - if pos is not None: - pos = remove_quotes(pos) - xx, yy = pos.split(",") - attr['pos'] = (float(xx), float(yy)) - return attr - - def _get_graph_nodes(self, parent): - nodes = {} - for node in parent.get_nodes(): - node_name = node.get_name() - if node_name in ('node', 'graph', 'edge'): - continue - nodes[node_name] = self._get_node_attributes(node) - for subgraph in parent.get_subgraphs(): - nodes.update(self._get_graph_nodes(subgraph)) - return nodes - - def _get_graph_edges(self, parent): - edges = [] - for edge in parent.get_edges(): - edges.append(edge) - for subgraph in parent.get_subgraphs(): - edges += self._get_graph_edges(subgraph) - return edges - - def _get_scales(self, graph): - bb = remove_quotes(graph.get_bb()) - min_x, min_y, max_x, max_y = bb.split(",") - scale_x = (self.width - self.margin * 2) / (float(max_x) - float(min_x)) if float(max_x) != float(min_x) else 0 - scale_y = (self.height - self.margin * 2) / (float(max_y) - float(min_y)) if float(max_y) != float(min_y) else 0 - return { - 'min_x': float(min_x), - 'min_y': float(min_y), - 'max_x': float(max_x), - 'max_y': float(max_y), - 'scale_x': float(scale_x), - 'scale_y': float(scale_y), - } - - # transform Graphviz coordinates to Zabbix's ones - def _convert_coordinates(self, pos, scales, icon_size): - return { - 'x': int((pos[0] - scales['min_x']) * scales['scale_x'] - icon_size[0] / 2 + self.margin), - 'y': int((scales['max_y'] - pos[1] + scales['min_y']) * scales['scale_y'] - icon_size[1] / 2 + self.margin), - } - - def _get_color_hex(self, color_name): - if color_name.startswith('#'): - color_hex = color_name - else: - try: - color_hex = webcolors.name_to_hex(color_name) - except Exception as e: - self._module.fail_json(msg="Failed to get RGB hex for color '%s': %s" % (color_name, e)) - color_hex = color_hex.strip('#').upper() - return color_hex - - def _get_link_draw_style_id(self, draw_style): - draw_style_ids = { - 'line': 0, - 'bold': 2, - 'dotted': 3, - 'dashed': 4 - } - try: - draw_style_id = draw_style_ids[draw_style] - except Exception as e: - self._module.fail_json(msg="Failed to find id for draw type '%s': %s" % (draw_style, e)) - return draw_style_id - - -# If a string has single or double quotes around it, remove them. -def remove_quotes(s): - if (s[0] == s[-1]) and s.startswith(("'", '"')): - s = s[1:-1] - return s - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - timeout=dict(type='int', default=10), - validate_certs=dict(type='bool', required=False, default=True), - name=dict(type='str', required=True, aliases=['map_name']), - data=dict(type='str', required=False, aliases=['dot_data']), - width=dict(type='int', default=800), - height=dict(type='int', default=600), - state=dict(type='str', default="present", choices=['present', 'absent']), - default_image=dict(type='str', required=False, aliases=['image']), - margin=dict(type='int', default=40), - expand_problem=dict(type='bool', default=True), - highlight=dict(type='bool', default=True), - label_type=dict(type='str', default='name', choices=['label', 'ip', 'name', 'status', 'nothing', 'custom']), - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - if not HAS_PYDOTPLUS: - module.fail_json(msg=missing_required_lib('pydotplus', url='https://pypi.org/project/pydotplus/'), exception=PYDOT_IMP_ERR) - if not HAS_WEBCOLORS: - module.fail_json(msg=missing_required_lib('webcolors', url='https://pypi.org/project/webcolors/'), exception=WEBCOLORS_IMP_ERR) - if not HAS_PIL: - module.fail_json(msg=missing_required_lib('Pillow', url='https://pypi.org/project/Pillow/'), exception=PIL_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - timeout = module.params['timeout'] - validate_certs = module.params['validate_certs'] - - zbx = None - - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - sysmap = Map(module, zbx) - - if sysmap.state == "absent": - if sysmap.map_exists(): - sysmap.delete_map() - module.exit_json(changed=True, result="Successfully deleted map: %s" % sysmap.map_name) - else: - module.exit_json(changed=False) - else: - map_config = sysmap.get_map_config() - if sysmap.map_exists(): - if sysmap.is_exist_map_correct(map_config): - module.exit_json(changed=False) - else: - sysmap.update_map(map_config) - module.exit_json(changed=True, result="Successfully updated map: %s" % sysmap.map_name) - else: - sysmap.create_map(map_config) - module.exit_json(changed=True, result="Successfully created map: %s" % sysmap.map_name) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_mediatype.py b/plugins/modules/monitoring/zabbix/zabbix_mediatype.py deleted file mode 100644 index 62ea174757..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_mediatype.py +++ /dev/null @@ -1,705 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: zabbix_mediatype -short_description: Create/Update/Delete Zabbix media types -description: - - This module allows you to create, modify and delete Zabbix media types. -author: - - Ruben Tsirunyan (@rubentsirunyan) -requirements: - - "zabbix-api >= 0.5.4" - -options: - name: - type: 'str' - description: - - Name of the media type. - required: true - state: - type: 'str' - description: - - Desired state of the mediatype. - - On C(present), it will create a mediatype if it does not exist or update the mediatype if the associated data is different. - - On C(absent), it will remove the mediatype if it exists. - choices: - - present - - absent - default: 'present' - type: - type: 'str' - description: - - Type of the media type. - - Media types I(jabber) and I(ez_texting) workable only with Zabbix 4.2 or less. - choices: - - email - - script - - sms - - jabber - - ez_texting - required: true - status: - type: 'str' - description: - - Whether the media type is enabled or no. - choices: - - enabled - - disabled - default: 'enabled' - max_sessions: - type: 'int' - description: - - The maximum number of alerts that can be processed in parallel. - - Possible value is 1 when I(type=sms) and 0-100 otherwise. - default: 1 - max_attempts: - type: 'int' - description: - - The maximum number of attempts to send an alert. - - Possible range is 0-10 - default: 3 - attempt_interval: - type: 'int' - description: - - The interval between retry attempts. - - Possible range is 0-60 - default: 10 - script_name: - type: 'str' - description: - - The name of the executed script. - - Required when I(type=script). - script_params: - type: 'list' - elements: str - description: - - List of script parameters. - - Required when I(type=script). - gsm_modem: - type: 'str' - description: - - Serial device name of the gsm modem. - - Required when I(type=sms). - username: - type: 'str' - description: - - Username or Jabber identifier. - - Required when I(type=jabber) or I(type=ez_texting). - - Required when I(type=email) and I(smtp_authentication=true). - password: - type: 'str' - description: - - Authentication password. - - Required when I(type=jabber) or I(type=ez_texting). - - Required when I(type=email) and I(smtp_authentication=true). - smtp_server: - type: 'str' - description: - - SMTP server host. - - Required when I(type=email). - default: 'localhost' - smtp_server_port: - type: 'int' - description: - - SMTP server port. - - Required when I(type=email). - default: 25 - smtp_helo: - type: 'str' - description: - - SMTP HELO. - - Required when I(type=email). - default: 'localhost' - smtp_email: - type: 'str' - description: - - Email address from which notifications will be sent. - - Required when I(type=email). - smtp_authentication: - type: 'bool' - description: - - Whether SMTP authentication with username and password should be enabled or not. - - If set to C(true), C(username) and C(password) should be specified. - default: false - smtp_security: - type: 'str' - description: - - SMTP connection security level to use. - choices: - - None - - STARTTLS - - SSL/TLS - smtp_verify_host: - type: 'bool' - description: - - SSL verify host for SMTP. - - Can be specified when I(smtp_security=STARTTLS) or I(smtp_security=SSL/TLS) - default: false - smtp_verify_peer: - type: 'bool' - description: - - SSL verify peer for SMTP. - - Can be specified when I(smtp_security=STARTTLS) or I(smtp_security=SSL/TLS) - default: false - message_text_limit: - type: 'str' - description: - - The message text limit. - - Required when I(type=ez_texting). - - 160 characters for USA and 136 characters for Canada. - choices: - - USA - - Canada -extends_documentation_fragment: -- community.general.zabbix - - -''' - -RETURN = r''' # ''' - -EXAMPLES = r''' -- name: 'Create an email mediatype with SMTP authentication' - zabbix_mediatype: - name: "Ops email" - server_url: "http://example.com/zabbix/" - login_user: Admin - login_password: "zabbix" - type: 'email' - smtp_server: 'example.com' - smtp_server_port: 2000 - smtp_email: 'ops@example.com' - smtp_authentication: true - username: 'smtp_user' - password: 'smtp_pass' - -- name: 'Create a script mediatype' - zabbix_mediatype: - name: "my script" - server_url: "http://example.com/zabbix/" - login_user: Admin - login_password: "zabbix" - type: 'script' - script_name: 'my_script.py' - script_params: - - 'arg1' - - 'arg2' - -- name: 'Create a jabber mediatype' - zabbix_mediatype: - name: "My jabber" - server_url: "http://example.com/zabbix/" - login_user: Admin - login_password: "zabbix" - type: 'jabber' - username: 'jabber_id' - password: 'jabber_pass' - -- name: 'Create an SMS mediatype' - zabbix_mediatype: - name: "My SMS Mediatype" - server_url: "http://example.com/zabbix/" - login_user: Admin - login_password: "zabbix" - type: 'sms' - gsm_modem: '/dev/ttyS0' -''' - - -import atexit -import traceback - - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -from distutils.version import LooseVersion - - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - - -def to_numeric_value(value, strs): - return strs.get(value) - - -def validate_params(module, params): - """Validates arguments that are required together. - - Fails the module with the message that shows the missing - requirements if there are some. - - Args: - module: AnsibleModule object. - params (list): Each element of this list - is a list like - ['argument_key', 'argument_value', ['required_arg_1', - 'required_arg_2']]. - Format is the same as `required_if` parameter of AnsibleModule. - """ - for param in params: - if module.params[param[0]] == param[1]: - if None in [module.params[i] for i in param[2]]: - module.fail_json( - msg="Following arguments are required when {key} is {value}: {arguments}".format( - key=param[0], - value=param[1], - arguments=', '.join(param[2]) - ) - ) - - -def construct_parameters(**kwargs): - """Translates data to a format suitable for Zabbix API and filters - the ones that are related to the specified mediatype type. - - Args: - **kwargs: Arguments passed to the module. - - Returns: - A dictionary of arguments that are related to kwargs['transport_type'], - and are in a format that is understandable by Zabbix API. - """ - if kwargs['transport_type'] == 'email': - return dict( - description=kwargs['name'], - status=to_numeric_value(kwargs['status'], - {'enabled': '0', - 'disabled': '1'}), - type=to_numeric_value(kwargs['transport_type'], - {'email': '0', - 'script': '1', - 'sms': '2', - 'jabber': '3', - 'ez_texting': '100'}), - maxsessions=str(kwargs['max_sessions']), - maxattempts=str(kwargs['max_attempts']), - attempt_interval=str(kwargs['attempt_interval']), - smtp_server=kwargs['smtp_server'], - smtp_port=str(kwargs['smtp_server_port']), - smtp_helo=kwargs['smtp_helo'], - smtp_email=kwargs['smtp_email'], - smtp_security=to_numeric_value(str(kwargs['smtp_security']), - {'None': '0', - 'STARTTLS': '1', - 'SSL/TLS': '2'}), - smtp_authentication=to_numeric_value(str(kwargs['smtp_authentication']), - {'False': '0', - 'True': '1'}), - smtp_verify_host=to_numeric_value(str(kwargs['smtp_verify_host']), - {'False': '0', - 'True': '1'}), - smtp_verify_peer=to_numeric_value(str(kwargs['smtp_verify_peer']), - {'False': '0', - 'True': '1'}), - username=kwargs['username'], - passwd=kwargs['password'] - ) - - elif kwargs['transport_type'] == 'script': - if kwargs['script_params'] is None: - _script_params = '' # ZBX-15706 - else: - _script_params = '\n'.join(str(i) for i in kwargs['script_params']) + '\n' - return dict( - description=kwargs['name'], - status=to_numeric_value(kwargs['status'], - {'enabled': '0', - 'disabled': '1'}), - type=to_numeric_value(kwargs['transport_type'], - {'email': '0', - 'script': '1', - 'sms': '2', - 'jabber': '3', - 'ez_texting': '100'}), - maxsessions=str(kwargs['max_sessions']), - maxattempts=str(kwargs['max_attempts']), - attempt_interval=str(kwargs['attempt_interval']), - exec_path=kwargs['script_name'], - exec_params=_script_params - ) - elif kwargs['transport_type'] == 'sms': - return dict( - description=kwargs['name'], - status=to_numeric_value(kwargs['status'], - {'enabled': '0', - 'disabled': '1'}), - type=to_numeric_value(kwargs['transport_type'], - {'email': '0', - 'script': '1', - 'sms': '2', - 'jabber': '3', - 'ez_texting': '100'}), - maxsessions=str(kwargs['max_sessions']), - maxattempts=str(kwargs['max_attempts']), - attempt_interval=str(kwargs['attempt_interval']), - gsm_modem=kwargs['gsm_modem'] - ) - elif kwargs['transport_type'] == 'jabber' and LooseVersion(kwargs['zbx_api_version']) <= LooseVersion('4.2'): - return dict( - description=kwargs['name'], - status=to_numeric_value(kwargs['status'], - {'enabled': '0', - 'disabled': '1'}), - type=to_numeric_value(kwargs['transport_type'], - {'email': '0', - 'script': '1', - 'sms': '2', - 'jabber': '3', - 'ez_texting': '100'}), - maxsessions=str(kwargs['max_sessions']), - maxattempts=str(kwargs['max_attempts']), - attempt_interval=str(kwargs['attempt_interval']), - username=kwargs['username'], - passwd=kwargs['password'] - ) - elif kwargs['transport_type'] == 'ez_texting' and LooseVersion(kwargs['zbx_api_version']) <= LooseVersion('4.2'): - return dict( - description=kwargs['name'], - status=to_numeric_value(kwargs['status'], - {'enabled': '0', - 'disabled': '1'}), - type=to_numeric_value(kwargs['transport_type'], - {'email': '0', - 'script': '1', - 'sms': '2', - 'jabber': '3', - 'ez_texting': '100'}), - maxsessions=str(kwargs['max_sessions']), - maxattempts=str(kwargs['max_attempts']), - attempt_interval=str(kwargs['attempt_interval']), - username=kwargs['username'], - passwd=kwargs['password'], - exec_path=to_numeric_value(kwargs['message_text_limit'], - {'USA': '0', - 'Canada': '1'}), - ) - - return {'unsupported_parameter': kwargs['transport_type'], 'zbx_api_version': kwargs['zbx_api_version']} - - -def check_if_mediatype_exists(module, zbx, name, zbx_api_version): - """Checks if mediatype exists. - - Args: - module: AnsibleModule object - zbx: ZabbixAPI object - name: Zabbix mediatype name - - Returns: - Tuple of (True, `id of the mediatype`) if mediatype exists, (False, None) otherwise - """ - filter_key_name = 'description' - if LooseVersion(zbx_api_version) >= LooseVersion('4.4'): - # description key changed to name key from zabbix 4.4 - filter_key_name = 'name' - - try: - mediatype_list = zbx.mediatype.get({ - 'output': 'extend', - 'filter': {filter_key_name: [name]} - }) - if len(mediatype_list) < 1: - return False, None - else: - return True, mediatype_list[0]['mediatypeid'] - except Exception as e: - module.fail_json(msg="Failed to get ID of the mediatype '{name}': {e}".format(name=name, e=e)) - - -def diff(existing, new): - """Constructs the diff for Ansible's --diff option. - - Args: - existing (dict): Existing mediatype data. - new (dict): New mediatype data. - - Returns: - A dictionary like {'before': existing, 'after': new} - with filtered empty values. - """ - before = {} - after = {} - for key in new: - before[key] = existing[key] - if new[key] is None: - after[key] = '' - else: - after[key] = new[key] - return {'before': before, 'after': after} - - -def get_update_params(module, zbx, mediatype_id, **kwargs): - """Filters only the parameters that are different and need to be updated. - - Args: - module: AnsibleModule object. - zbx: ZabbixAPI object. - mediatype_id (int): ID of the mediatype to be updated. - **kwargs: Parameters for the new mediatype. - - Returns: - A tuple where the first element is a dictionary of parameters - that need to be updated and the second one is a dictionary - returned by diff() function with - existing mediatype data and new params passed to it. - """ - existing_mediatype = zbx.mediatype.get({ - 'output': 'extend', - 'mediatypeids': [mediatype_id] - })[0] - - if existing_mediatype['type'] != kwargs['type']: - return kwargs, diff(existing_mediatype, kwargs) - else: - params_to_update = {} - for key in kwargs: - if (not (kwargs[key] is None and existing_mediatype[key] == '')) and kwargs[key] != existing_mediatype[key]: - params_to_update[key] = kwargs[key] - return params_to_update, diff(existing_mediatype, kwargs) - - -def delete_mediatype(module, zbx, mediatype_id): - try: - return zbx.mediatype.delete([mediatype_id]) - except Exception as e: - module.fail_json(msg="Failed to delete mediatype '{_id}': {e}".format(_id=mediatype_id, e=e)) - - -def update_mediatype(module, zbx, **kwargs): - try: - mediatype_id = zbx.mediatype.update(kwargs) - except Exception as e: - module.fail_json(msg="Failed to update mediatype '{_id}': {e}".format(_id=kwargs['mediatypeid'], e=e)) - - -def create_mediatype(module, zbx, **kwargs): - try: - mediatype_id = zbx.mediatype.create(kwargs) - except Exception as e: - module.fail_json(msg="Failed to create mediatype '{name}': {e}".format(name=kwargs['description'], e=e)) - - -def main(): - argument_spec = dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), timeout=dict(type='int', default=10), - name=dict(type='str', required=True), - state=dict(type='str', default='present', choices=['present', 'absent']), - type=dict(type='str', choices=['email', 'script', 'sms', 'jabber', 'ez_texting'], required=True), - status=dict(type='str', default='enabled', choices=['enabled', 'disabled'], required=False), - max_sessions=dict(type='int', default=1, required=False), - max_attempts=dict(type='int', default=3, required=False), - attempt_interval=dict(type='int', default=10, required=False), - # Script - script_name=dict(type='str', required=False), - script_params=dict(type='list', required=False), - # SMS - gsm_modem=dict(type='str', required=False), - # Jabber - username=dict(type='str', required=False), - password=dict(type='str', required=False, no_log=True), - # Email - smtp_server=dict(type='str', default='localhost', required=False), - smtp_server_port=dict(type='int', default=25, required=False), - smtp_helo=dict(type='str', default='localhost', required=False), - smtp_email=dict(type='str', required=False), - smtp_security=dict(type='str', required=False, choices=['None', 'STARTTLS', 'SSL/TLS']), - smtp_authentication=dict(type='bool', default=False, required=False), - smtp_verify_host=dict(type='bool', default=False, required=False), - smtp_verify_peer=dict(type='bool', default=False, required=False), - # EZ Text - message_text_limit=dict(type='str', required=False, choices=['USA', 'Canada']) - ) - - required_params = [ - ['type', 'email', ['smtp_email']], - ['type', 'script', ['script_name']], - ['type', 'sms', ['gsm_modem']], - ['type', 'jabber', ['username', 'password']], - ['type', 'ez_texting', ['username', 'password', 'message_text_limit']], - ['smtp_authentication', True, ['username', 'password']] - ] - - module = AnsibleModule( - argument_spec=argument_spec, - supports_check_mode=True - ) - - if module.params['state'] == 'present': - validate_params(module, required_params) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - state = module.params['state'] - timeout = module.params['timeout'] - name = module.params['name'] - transport_type = module.params['type'] - status = module.params['status'] - max_sessions = module.params['max_sessions'] - max_attempts = module.params['max_attempts'] - attempt_interval = module.params['attempt_interval'] - # Script - script_name = module.params['script_name'] - script_params = module.params['script_params'] - # SMS - gsm_modem = module.params['gsm_modem'] - # Jabber - username = module.params['username'] - password = module.params['password'] - # Email - smtp_server = module.params['smtp_server'] - smtp_server_port = module.params['smtp_server_port'] - smtp_helo = module.params['smtp_helo'] - smtp_email = module.params['smtp_email'] - smtp_security = module.params['smtp_security'] - smtp_authentication = module.params['smtp_authentication'] - smtp_verify_host = module.params['smtp_verify_host'] - smtp_verify_peer = module.params['smtp_verify_peer'] - # EZ Text - message_text_limit = module.params['message_text_limit'] - - zbx = None - - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - zbx_api_version = zbx.api_version()[:3] - mediatype_exists, mediatype_id = check_if_mediatype_exists(module, zbx, name, zbx_api_version) - - parameters = construct_parameters( - name=name, - transport_type=transport_type, - status=status, - max_sessions=max_sessions, - max_attempts=max_attempts, - attempt_interval=attempt_interval, - script_name=script_name, - script_params=script_params, - gsm_modem=gsm_modem, - username=username, - password=password, - smtp_server=smtp_server, - smtp_server_port=smtp_server_port, - smtp_helo=smtp_helo, - smtp_email=smtp_email, - smtp_security=smtp_security, - smtp_authentication=smtp_authentication, - smtp_verify_host=smtp_verify_host, - smtp_verify_peer=smtp_verify_peer, - message_text_limit=message_text_limit, - zbx_api_version=zbx_api_version - ) - - if 'unsupported_parameter' in parameters: - module.fail_json(msg="%s is unsupported for Zabbix version %s" % (parameters['unsupported_parameter'], parameters['zbx_api_version'])) - - if LooseVersion(zbx_api_version) >= LooseVersion('4.4'): - # description key changed to name key from zabbix 4.4 - parameters['name'] = parameters.pop('description') - - if mediatype_exists: - if state == 'absent': - if module.check_mode: - module.exit_json( - changed=True, - msg="Mediatype would have been deleted. Name: {name}, ID: {_id}".format( - name=name, - _id=mediatype_id - ) - ) - mediatype_id = delete_mediatype(module, zbx, mediatype_id) - module.exit_json( - changed=True, - msg="Mediatype deleted. Name: {name}, ID: {_id}".format( - name=name, - _id=mediatype_id - ) - ) - else: - params_to_update, diff = get_update_params(module, zbx, mediatype_id, **parameters) - if params_to_update == {}: - module.exit_json( - changed=False, - msg="Mediatype is up to date: {name}".format(name=name) - ) - else: - if module.check_mode: - module.exit_json( - changed=True, - diff=diff, - msg="Mediatype would have been updated. Name: {name}, ID: {_id}".format( - name=name, - _id=mediatype_id - ) - ) - mediatype_id = update_mediatype( - module, zbx, - mediatypeid=mediatype_id, - **params_to_update - ) - module.exit_json( - changed=True, - diff=diff, - msg="Mediatype updated. Name: {name}, ID: {_id}".format( - name=name, - _id=mediatype_id - ) - ) - else: - if state == "absent": - module.exit_json(changed=False) - else: - if module.check_mode: - module.exit_json( - changed=True, - msg="Mediatype would have been created. Name: {name}, ID: {_id}".format( - name=name, - _id=mediatype_id - ) - ) - mediatype_id = create_mediatype(module, zbx, **parameters) - module.exit_json( - changed=True, - msg="Mediatype created: {name}, ID: {_id}".format( - name=name, - _id=mediatype_id - ) - ) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_proxy.py b/plugins/modules/monitoring/zabbix/zabbix_proxy.py deleted file mode 100644 index a4f2e70083..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_proxy.py +++ /dev/null @@ -1,471 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# (c) 2017, Alen Komic -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . -# -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: zabbix_proxy -short_description: Create/delete/get/update Zabbix proxies -description: - - This module allows you to create, modify, get and delete Zabbix proxy entries. -author: - - "Alen Komic (@akomic)" -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - proxy_name: - description: - - Name of the proxy in Zabbix. - required: true - type: str - proxy_address: - description: - - Comma-delimited list of IP/CIDR addresses or DNS names to accept active proxy requests from. - - Requires I(status=active). - - Works only with >= Zabbix 4.0. ( remove option for <= 4.0 ) - required: false - type: str - description: - description: - - Description of the proxy. - required: false - type: str - status: - description: - - Type of proxy. (4 - active, 5 - passive) - required: false - choices: ['active', 'passive'] - default: "active" - type: str - tls_connect: - description: - - Connections to proxy. - required: false - choices: ['no_encryption','PSK','certificate'] - default: 'no_encryption' - type: str - tls_accept: - description: - - Connections from proxy. - required: false - choices: ['no_encryption','PSK','certificate'] - default: 'no_encryption' - type: str - ca_cert: - description: - - Certificate issuer. - required: false - aliases: [ tls_issuer ] - type: str - tls_subject: - description: - - Certificate subject. - required: false - type: str - tls_psk_identity: - description: - - PSK identity. Required if either I(tls_connect) or I(tls_accept) has PSK enabled. - required: false - type: str - tls_psk: - description: - - The preshared key, at least 32 hex digits. Required if either I(tls_connect) or I(tls_accept) has PSK enabled. - required: false - type: str - state: - description: - - State of the proxy. - - On C(present), it will create if proxy does not exist or update the proxy if the associated data is different. - - On C(absent) will remove a proxy if it exists. - required: false - choices: ['present', 'absent'] - default: "present" - type: str - interface: - description: - - Dictionary with params for the interface when proxy is in passive mode. - - For more information, review proxy interface documentation at - - U(https://www.zabbix.com/documentation/4.0/manual/api/reference/proxy/object#proxy_interface). - required: false - suboptions: - useip: - type: int - description: - - Connect to proxy interface with IP address instead of DNS name. - - 0 (don't use ip), 1 (use ip). - default: 0 - choices: [0, 1] - ip: - type: str - description: - - IP address used by proxy interface. - - Required if I(useip=1). - default: '' - dns: - type: str - description: - - DNS name of the proxy interface. - - Required if I(useip=0). - default: '' - port: - type: str - description: - - Port used by proxy interface. - default: '10051' - type: - type: int - description: - - Interface type to add. - - This suboption is currently ignored for Zabbix proxy. - - This suboption is deprecated since Ansible 2.10 and will eventually be removed in 2.14. - required: false - default: 0 - main: - type: int - description: - - Whether the interface is used as default. - - This suboption is currently ignored for Zabbix proxy. - - This suboption is deprecated since Ansible 2.10 and will eventually be removed in 2.14. - required: false - default: 0 - default: {} - type: dict - -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = r''' -- name: Create or update a proxy with proxy type active - local_action: - module: zabbix_proxy - server_url: http://monitor.example.com - login_user: username - login_password: password - proxy_name: ExampleProxy - description: ExampleProxy - status: active - state: present - proxy_address: ExampleProxy.local - -- name: Create a new passive proxy using only it's IP - local_action: - module: zabbix_proxy - server_url: http://monitor.example.com - login_user: username - login_password: password - proxy_name: ExampleProxy - description: ExampleProxy - status: passive - state: present - interface: - useip: 1 - ip: 10.1.1.2 - port: 10051 - -- name: Create a new passive proxy using only it's DNS - local_action: - module: zabbix_proxy - server_url: http://monitor.example.com - login_user: username - login_password: password - proxy_name: ExampleProxy - description: ExampleProxy - status: passive - state: present - interface: - dns: proxy.example.com - port: 10051 -''' - -RETURN = r''' # ''' - - -import traceback -import atexit - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -try: - from zabbix_api import ZabbixAPI - - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - - -class Proxy(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - self.existing_data = None - - def proxy_exists(self, proxy_name): - result = self._zapi.proxy.get({ - 'output': 'extend', 'selectInterface': 'extend', - 'filter': {'host': proxy_name}}) - - if len(result) > 0 and 'proxyid' in result[0]: - self.existing_data = result[0] - return result[0]['proxyid'] - else: - return result - - def add_proxy(self, data): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - - parameters = {} - for item in data: - if data[item]: - parameters[item] = data[item] - - if 'proxy_address' in data and data['status'] != '5': - parameters.pop('proxy_address', False) - - if 'interface' in data and data['status'] != '6': - parameters.pop('interface', False) - - proxy_ids_list = self._zapi.proxy.create(parameters) - self._module.exit_json(changed=True, - result="Successfully added proxy %s (%s)" % - (data['host'], data['status'])) - if len(proxy_ids_list) >= 1: - return proxy_ids_list['proxyids'][0] - except Exception as e: - self._module.fail_json(msg="Failed to create proxy %s: %s" % - (data['host'], e)) - - def delete_proxy(self, proxy_id, proxy_name): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.proxy.delete([proxy_id]) - self._module.exit_json(changed=True, - result="Successfully deleted" - + " proxy %s" % proxy_name) - except Exception as e: - self._module.fail_json(msg="Failed to delete proxy %s: %s" % - (proxy_name, str(e))) - - def compile_interface_params(self, new_interface): - old_interface = {} - if 'interface' in self.existing_data and \ - len(self.existing_data['interface']) > 0: - old_interface = self.existing_data['interface'] - - for item in ['type', 'main']: - new_interface.pop(item, False) - - final_interface = old_interface.copy() - final_interface.update(new_interface) - final_interface = dict((k, str(v)) for k, v in final_interface.items()) - - if final_interface != old_interface: - return final_interface - else: - return {} - - def update_proxy(self, proxy_id, data): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - parameters = {'proxyid': proxy_id} - - for item in data: - if data[item] and item in self.existing_data and \ - self.existing_data[item] != data[item]: - parameters[item] = data[item] - - if 'interface' in parameters: - parameters.pop('interface') - - if 'proxy_address' in data and data['status'] != '5': - parameters.pop('proxy_address', False) - - if 'interface' in data and data['status'] != '6': - parameters.pop('interface', False) - - if 'interface' in data and data['status'] == '6': - new_interface = self.compile_interface_params(data['interface']) - if len(new_interface) > 0: - parameters['interface'] = new_interface - - if len(parameters) > 1: - self._zapi.proxy.update(parameters) - self._module.exit_json( - changed=True, - result="Successfully updated proxy %s (%s)" % - (data['host'], proxy_id) - ) - else: - self._module.exit_json(changed=False) - except Exception as e: - self._module.fail_json(msg="Failed to update proxy %s: %s" % - (data['host'], e)) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - proxy_name=dict(type='str', required=True), - proxy_address=dict(type='str', required=False), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, - default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - status=dict(type='str', default="active", choices=['active', 'passive']), - state=dict(type='str', default="present", choices=['present', 'absent']), - description=dict(type='str', required=False), - tls_connect=dict(type='str', default='no_encryption', - choices=['no_encryption', 'PSK', 'certificate']), - tls_accept=dict(type='str', default='no_encryption', - choices=['no_encryption', 'PSK', 'certificate']), - ca_cert=dict(type='str', required=False, default=None, aliases=['tls_issuer']), - tls_subject=dict(type='str', required=False, default=None), - tls_psk_identity=dict(type='str', required=False, default=None), - tls_psk=dict(type='str', required=False, default=None), - timeout=dict(type='int', default=10), - interface=dict( - type='dict', - required=False, - default={}, - options=dict( - useip=dict(type='int', choices=[0, 1], default=0), - ip=dict(type='str', default=''), - dns=dict(type='str', default=''), - port=dict(type='str', default='10051'), - type=dict(type='int', default=0, removed_in_version='2.14'), - main=dict(type='int', default=0, removed_in_version='2.14') - ), - ) - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - proxy_name = module.params['proxy_name'] - proxy_address = module.params['proxy_address'] - description = module.params['description'] - status = module.params['status'] - tls_connect = module.params['tls_connect'] - tls_accept = module.params['tls_accept'] - tls_issuer = module.params['ca_cert'] - tls_subject = module.params['tls_subject'] - tls_psk_identity = module.params['tls_psk_identity'] - tls_psk = module.params['tls_psk'] - state = module.params['state'] - timeout = module.params['timeout'] - interface = module.params['interface'] - - # convert enabled to 0; disabled to 1 - status = 6 if status == "passive" else 5 - - if tls_connect == 'certificate': - tls_connect = 4 - elif tls_connect == 'PSK': - tls_connect = 2 - else: - tls_connect = 1 - - if tls_accept == 'certificate': - tls_accept = 4 - elif tls_accept == 'PSK': - tls_accept = 2 - else: - tls_accept = 1 - - zbx = None - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, - user=http_login_user, - passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - proxy = Proxy(module, zbx) - - # check if proxy already exists - proxy_id = proxy.proxy_exists(proxy_name) - - if proxy_id: - if state == "absent": - # remove proxy - proxy.delete_proxy(proxy_id, proxy_name) - else: - proxy.update_proxy(proxy_id, { - 'host': proxy_name, - 'description': description, - 'status': str(status), - 'tls_connect': str(tls_connect), - 'tls_accept': str(tls_accept), - 'tls_issuer': tls_issuer, - 'tls_subject': tls_subject, - 'tls_psk_identity': tls_psk_identity, - 'tls_psk': tls_psk, - 'interface': interface, - 'proxy_address': proxy_address - }) - else: - if state == "absent": - # the proxy is already deleted. - module.exit_json(changed=False) - - proxy_id = proxy.add_proxy(data={ - 'host': proxy_name, - 'description': description, - 'status': str(status), - 'tls_connect': str(tls_connect), - 'tls_accept': str(tls_accept), - 'tls_issuer': tls_issuer, - 'tls_subject': tls_subject, - 'tls_psk_identity': tls_psk_identity, - 'tls_psk': tls_psk, - 'interface': interface, - 'proxy_address': proxy_address - }) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_screen.py b/plugins/modules/monitoring/zabbix/zabbix_screen.py deleted file mode 100644 index c82a8a0d9c..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_screen.py +++ /dev/null @@ -1,471 +0,0 @@ -#!/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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: zabbix_screen -short_description: Create/update/delete Zabbix screens -description: - - This module allows you to create, modify and delete Zabbix screens and associated graph data. -author: - - "Cove (@cove)" - - "Tony Minfei Ding (!UNKNOWN)" - - "Harrison Gu (@harrisongu)" -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - screens: - description: - - List of screens to be created/updated/deleted (see example). - type: list - elements: dict - required: true - suboptions: - screen_name: - description: - - Screen name will be used. - - If a screen has already been added, the screen name won't be updated. - type: str - required: true - host_group: - description: - - Host group will be used for searching hosts. - - Required if I(state=present). - type: str - state: - description: - - I(present) - Create a screen if it doesn't exist. If the screen already exists, the screen will be updated as needed. - - I(absent) - If a screen exists, the screen will be deleted. - type: str - default: present - choices: - - absent - - present - graph_names: - description: - - Graph names will be added to a screen. Case insensitive. - - Required if I(state=present). - type: list - elements: str - graph_width: - description: - - Graph width will be set in graph settings. - type: int - graph_height: - description: - - Graph height will be set in graph settings. - type: int - graphs_in_row: - description: - - Limit columns of a screen and make multiple rows. - type: int - default: 3 - sort: - description: - - Sort hosts alphabetically. - - If there are numbers in hostnames, leading zero should be used. - type: bool - default: no - -extends_documentation_fragment: -- community.general.zabbix - - -notes: - - Too many concurrent updates to the same screen may cause Zabbix to return errors, see examples for a workaround if needed. -''' - -EXAMPLES = r''' -# Create/update a screen. -- name: Create a new screen or update an existing screen's items 5 in a row - local_action: - module: zabbix_screen - server_url: http://monitor.example.com - login_user: username - login_password: password - screens: - - screen_name: ExampleScreen1 - host_group: Example group1 - state: present - graph_names: - - Example graph1 - - Example graph2 - graph_width: 200 - graph_height: 100 - graphs_in_row: 5 - -# Create/update multi-screen -- name: Create two of new screens or update the existing screens' items - local_action: - module: zabbix_screen - server_url: http://monitor.example.com - login_user: username - login_password: password - screens: - - screen_name: ExampleScreen1 - host_group: Example group1 - state: present - graph_names: - - Example graph1 - - Example graph2 - graph_width: 200 - graph_height: 100 - - screen_name: ExampleScreen2 - host_group: Example group2 - state: present - graph_names: - - Example graph1 - - Example graph2 - graph_width: 200 - graph_height: 100 - -# Limit the Zabbix screen creations to one host since Zabbix can return an error when doing concurrent updates -- name: Create a new screen or update an existing screen's items - local_action: - module: zabbix_screen - server_url: http://monitor.example.com - login_user: username - login_password: password - state: present - screens: - - screen_name: ExampleScreen - host_group: Example group - state: present - graph_names: - - Example graph1 - - Example graph2 - graph_width: 200 - graph_height: 100 - when: inventory_hostname==groups['group_name'][0] -''' - - -import atexit -import traceback - -try: - from zabbix_api import ZabbixAPI - from zabbix_api import ZabbixAPIException - from zabbix_api import Already_Exists - - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -class Screen(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - # get group id by group name - def get_host_group_id(self, group_name): - if group_name == "": - self._module.fail_json(msg="group_name is required") - hostGroup_list = self._zapi.hostgroup.get({'output': 'extend', 'filter': {'name': group_name}}) - if len(hostGroup_list) < 1: - self._module.fail_json(msg="Host group not found: %s" % group_name) - else: - hostGroup_id = hostGroup_list[0]['groupid'] - return hostGroup_id - - # get monitored host_id by host_group_id - def get_host_ids_by_group_id(self, group_id, sort): - host_list = self._zapi.host.get({'output': 'extend', 'groupids': group_id, 'monitored_hosts': 1}) - if len(host_list) < 1: - self._module.fail_json(msg="No host in the group.") - else: - if sort: - host_list = sorted(host_list, key=lambda name: name['name']) - host_ids = [] - for i in host_list: - host_id = i['hostid'] - host_ids.append(host_id) - return host_ids - - # get screen - def get_screen_id(self, screen_name): - if screen_name == "": - self._module.fail_json(msg="screen_name is required") - try: - screen_id_list = self._zapi.screen.get({'output': 'extend', 'search': {"name": screen_name}}) - if len(screen_id_list) >= 1: - screen_id = screen_id_list[0]['screenid'] - return screen_id - return None - except Exception as e: - self._module.fail_json(msg="Failed to get screen %s from Zabbix: %s" % (screen_name, e)) - - # create screen - def create_screen(self, screen_name, h_size, v_size): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - screen = self._zapi.screen.create({'name': screen_name, 'hsize': h_size, 'vsize': v_size}) - return screen['screenids'][0] - except Exception as e: - self._module.fail_json(msg="Failed to create screen %s: %s" % (screen_name, e)) - - # update screen - def update_screen(self, screen_id, screen_name, h_size, v_size): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.screen.update({'screenid': screen_id, 'hsize': h_size, 'vsize': v_size}) - except Exception as e: - self._module.fail_json(msg="Failed to update screen %s: %s" % (screen_name, e)) - - # delete screen - def delete_screen(self, screen_id, screen_name): - try: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.screen.delete([screen_id]) - except Exception as e: - self._module.fail_json(msg="Failed to delete screen %s: %s" % (screen_name, e)) - - # get graph ids - def get_graph_ids(self, hosts, graph_name_list): - graph_id_lists = [] - vsize = 1 - for host in hosts: - graph_id_list = self.get_graphs_by_host_id(graph_name_list, host) - size = len(graph_id_list) - if size > 0: - graph_id_lists.extend(graph_id_list) - if vsize < size: - vsize = size - return graph_id_lists, vsize - - # getGraphs - def get_graphs_by_host_id(self, graph_name_list, host_id): - graph_ids = [] - for graph_name in graph_name_list: - graphs_list = self._zapi.graph.get({'output': 'extend', 'search': {'name': graph_name}, 'hostids': host_id}) - graph_id_list = [] - if len(graphs_list) > 0: - for graph in graphs_list: - graph_id = graph['graphid'] - graph_id_list.append(graph_id) - if len(graph_id_list) > 0: - graph_ids.extend(graph_id_list) - return graph_ids - - # get screen items - def get_screen_items(self, screen_id): - screen_item_list = self._zapi.screenitem.get({'output': 'extend', 'screenids': screen_id}) - return screen_item_list - - # delete screen items - def delete_screen_items(self, screen_id, screen_item_id_list): - try: - if len(screen_item_id_list) == 0: - return True - screen_item_list = self.get_screen_items(screen_id) - if len(screen_item_list) > 0: - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.screenitem.delete(screen_item_id_list) - return True - return False - except ZabbixAPIException: - pass - - # get screen's hsize and vsize - def get_hsize_vsize(self, hosts, v_size, graphs_in_row): - h_size = len(hosts) - # when there is only one host, put all graphs in a row - if h_size == 1: - if v_size <= graphs_in_row: - h_size = v_size - else: - h_size = graphs_in_row - v_size = (v_size - 1) // h_size + 1 - # when len(hosts) is more then graphs_in_row - elif len(hosts) > graphs_in_row: - h_size = graphs_in_row - v_size = (len(hosts) // graphs_in_row + 1) * v_size - - return h_size, v_size - - # create screen_items - def create_screen_items(self, screen_id, hosts, graph_name_list, width, height, h_size, graphs_in_row): - if len(hosts) < 4: - if width is None or width < 0: - width = 500 - else: - if width is None or width < 0: - width = 200 - if height is None or height < 0: - height = 100 - - try: - # when there're only one host, only one row is not good. - if len(hosts) == 1: - graph_id_list = self.get_graphs_by_host_id(graph_name_list, hosts[0]) - for i, graph_id in enumerate(graph_id_list): - if graph_id is not None: - self._zapi.screenitem.create({'screenid': screen_id, 'resourcetype': 0, 'resourceid': graph_id, - 'width': width, 'height': height, - 'x': i % h_size, 'y': i // h_size, 'colspan': 1, 'rowspan': 1, - 'elements': 0, 'valign': 0, 'halign': 0, - 'style': 0, 'dynamic': 0, 'sort_triggers': 0}) - else: - for i, host in enumerate(hosts): - graph_id_list = self.get_graphs_by_host_id(graph_name_list, host) - for j, graph_id in enumerate(graph_id_list): - if graph_id is not None: - self._zapi.screenitem.create({'screenid': screen_id, 'resourcetype': 0, 'resourceid': graph_id, - 'width': width, 'height': height, - 'x': i % graphs_in_row, 'y': len(graph_id_list) * (i // graphs_in_row) + j, - 'colspan': 1, 'rowspan': 1, - 'elements': 0, 'valign': 0, 'halign': 0, - 'style': 0, 'dynamic': 0, 'sort_triggers': 0}) - except Already_Exists: - pass - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - timeout=dict(type='int', default=10), - screens=dict( - type='list', - elements='dict', - required=True, - options=dict( - screen_name=dict(type='str', required=True), - host_group=dict(type='str'), - state=dict(type='str', default='present', choices=['absent', 'present']), - graph_names=dict(type='list', elements='str'), - graph_width=dict(type='int', default=None), - graph_height=dict(type='int', default=None), - graphs_in_row=dict(type='int', default=3), - sort=dict(default=False, type='bool'), - ), - required_if=[ - ['state', 'present', ['host_group']] - ] - ) - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - timeout = module.params['timeout'] - screens = module.params['screens'] - - zbx = None - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - screen = Screen(module, zbx) - created_screens = [] - changed_screens = [] - deleted_screens = [] - - for zabbix_screen in screens: - screen_name = zabbix_screen['screen_name'] - screen_id = screen.get_screen_id(screen_name) - state = zabbix_screen['state'] - sort = zabbix_screen['sort'] - - if state == "absent": - if screen_id: - screen_item_list = screen.get_screen_items(screen_id) - screen_item_id_list = [] - for screen_item in screen_item_list: - screen_item_id = screen_item['screenitemid'] - screen_item_id_list.append(screen_item_id) - screen.delete_screen_items(screen_id, screen_item_id_list) - screen.delete_screen(screen_id, screen_name) - - deleted_screens.append(screen_name) - else: - host_group = zabbix_screen['host_group'] - graph_names = zabbix_screen['graph_names'] - graphs_in_row = zabbix_screen['graphs_in_row'] - graph_width = zabbix_screen['graph_width'] - graph_height = zabbix_screen['graph_height'] - host_group_id = screen.get_host_group_id(host_group) - hosts = screen.get_host_ids_by_group_id(host_group_id, sort) - - screen_item_id_list = [] - resource_id_list = [] - - graph_ids, v_size = screen.get_graph_ids(hosts, graph_names) - h_size, v_size = screen.get_hsize_vsize(hosts, v_size, graphs_in_row) - - if not screen_id: - # create screen - screen_id = screen.create_screen(screen_name, h_size, v_size) - screen.create_screen_items(screen_id, hosts, graph_names, graph_width, graph_height, h_size, graphs_in_row) - created_screens.append(screen_name) - else: - screen_item_list = screen.get_screen_items(screen_id) - - for screen_item in screen_item_list: - screen_item_id = screen_item['screenitemid'] - resource_id = screen_item['resourceid'] - screen_item_id_list.append(screen_item_id) - resource_id_list.append(resource_id) - - # when the screen items changed, then update - if graph_ids != resource_id_list: - deleted = screen.delete_screen_items(screen_id, screen_item_id_list) - if deleted: - screen.update_screen(screen_id, screen_name, h_size, v_size) - screen.create_screen_items(screen_id, hosts, graph_names, graph_width, graph_height, h_size, graphs_in_row) - changed_screens.append(screen_name) - - if created_screens and changed_screens: - module.exit_json(changed=True, result="Successfully created screen(s): %s, and updated screen(s): %s" % (",".join(created_screens), - ",".join(changed_screens))) - elif created_screens: - module.exit_json(changed=True, result="Successfully created screen(s): %s" % ",".join(created_screens)) - elif changed_screens: - module.exit_json(changed=True, result="Successfully updated screen(s): %s" % ",".join(changed_screens)) - elif deleted_screens: - module.exit_json(changed=True, result="Successfully deleted screen(s): %s" % ",".join(deleted_screens)) - else: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_service.py b/plugins/modules/monitoring/zabbix/zabbix_service.py deleted file mode 100644 index f28dd958fd..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_service.py +++ /dev/null @@ -1,291 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2019, OVH SAS -# 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: zabbix_service -short_description: Create/update/delete Zabbix service -description: - - Create/update/delete Zabbix service. -author: - - "Emmanuel Riviere (@emriver)" -requirements: - - "python >= 2.7" - - "zabbix-api >= 0.5.4" -options: - name: - description: - - Name of Zabbix service - required: true - type: str - parent: - description: - - Name of Zabbix service parent - required: false - type: str - sla: - description: - - Sla value (i.e 99.99), goodsla in Zabbix API - required: false - type: float - calculate_sla: - description: - - If yes, calculate the SLA value for this service, showsla in Zabbix API - required: false - type: bool - algorithm: - description: - - Algorithm used to calculate the sla - - C(no), sla is not calculated - - C(one_child), problem if at least one child has a problem - - C(all_children), problem if all children have problems - required: false - type: str - choices: ["no", "one_child", "all_children"] - default: one_child - trigger_name: - description: - - Name of trigger linked to the service - required: false - type: str - trigger_host: - description: - - Name of host linked to the service - required: false - type: str - state: - description: - - 'State: present - create/update service; absent - delete service' - required: false - choices: [present, absent] - default: "present" - type: str - -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = ''' ---- -# Creates a new Zabbix service -- name: Manage services - local_action: - module: zabbix_service - server_url: "https://192.168.1.1" - login_user: username - login_password: password - name: apache2 service - sla: 99.99 - calculate_sla: yes - algorithm: one_child - trigger_name: apache2 service status - trigger_host: webserver01 - state: present -''' - -RETURN = ''' ---- -''' - -import atexit -import traceback - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -try: - from zabbix_api import ZabbixAPI, ZabbixAPIException - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - - -class Service(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - def get_service_ids(self, service_name): - service_ids = [] - services = self._zapi.service.get({'filter': {'name': service_name}}) - for service in services: - service_ids.append(service['serviceid']) - return service_ids - - def delete_service(self, service_ids): - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.service.delete(service_ids) - - def dump_services(self, service_ids): - services = self._zapi.service.get({'output': 'extend', 'filter': {'serviceid': service_ids}, 'selectParent': '1'}) - return services - - def generate_service_config(self, name, parent, sla, calculate_sla, trigger_name, trigger_host, algorithm): - algorithms = {'no': '0', 'one_child': '1', 'all_children': '2'} - algorithm = algorithms[algorithm] - - if calculate_sla: - calculate_sla = 1 - else: - calculate_sla = 0 - - # Zabbix api return when no trigger - trigger_id = 0 - if trigger_host and trigger_name: - # Retrieving the host to get the trigger - hosts = self._zapi.host.get({'filter': {'host': trigger_host}}) - if not hosts: - self._module.fail_json(msg="Target host %s not found" % trigger_host) - host_id = hosts[0]['hostid'] - - triggers = self._zapi.trigger.get({'filter': {'description': trigger_name}, 'hostids': [host_id]}) - if not triggers: - self._module.fail_json(msg="Trigger %s not found on host %s" % (trigger_name, trigger_host)) - trigger_id = triggers[0]['triggerid'] - - request = { - 'name': name, - 'algorithm': algorithm, - 'showsla': calculate_sla, - 'sortorder': 1, - 'goodsla': format(sla, '.4f'), # Sla has 4 decimals - 'triggerid': trigger_id - } - - if parent: - parent_ids = self.get_service_ids(parent) - if not parent_ids: - self._module.fail_json(msg="Parent %s not found" % parent) - request['parentid'] = parent_ids[0] - return request - - def create_service(self, name, parent, sla, calculate_sla, trigger_name, trigger_host, algorithm): - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.service.create(self.generate_service_config(name, parent, sla, calculate_sla, trigger_name, trigger_host, algorithm)) - - def update_service(self, service_id, name, parent, sla, calculate_sla, trigger_name, trigger_host, algorithm): - generated_config = self.generate_service_config(name, parent, sla, calculate_sla, trigger_name, trigger_host, algorithm) - live_config = self.dump_services(service_id)[0] - - item_to_check = ['name', 'showsla', 'algorithm', 'triggerid', 'sortorder', 'goodsla'] - change = False - for item in item_to_check: - if str(generated_config[item]) != str(live_config[item]): - change = True - - # In Zabbix 4.0 - # No parent returns : "parent": [] - # A parent returns : "parent": { "serviceid": 12 } - if 'parentid' in generated_config: - if 'serviceid' in live_config['parent']: - if generated_config['parentid'] != live_config['parent']['serviceid']: - change = True - else: - change = True - elif 'serviceid' in live_config['parent']: - change = True - - if not change: - self._module.exit_json(changed=False, msg="Service %s up to date" % name) - - if self._module.check_mode: - self._module.exit_json(changed=True) - generated_config['serviceid'] = service_id - self._zapi.service.update(generated_config) - self._module.exit_json(changed=True, msg="Service %s updated" % name) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - name=dict(type='str', required=True), - parent=dict(type='str', required=False), - sla=dict(type='float', required=False), - calculate_sla=dict(type='bool', required=False, default=False), - algorithm=dict(default='one_child', required=False, choices=['no', 'one_child', 'all_children']), - trigger_name=dict(type='str', required=False), - trigger_host=dict(type='str', required=False), - state=dict(default="present", choices=['present', 'absent']), - timeout=dict(type='int', default=10) - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - name = module.params['name'] - parent = module.params['parent'] - sla = module.params['sla'] - calculate_sla = module.params['calculate_sla'] - algorithm = module.params['algorithm'] - trigger_name = module.params['trigger_name'] - trigger_host = module.params['trigger_host'] - state = module.params['state'] - timeout = module.params['timeout'] - - zbx = None - - # Login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except ZabbixAPIException as error: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % error) - - # Load service module - service = Service(module, zbx) - service_ids = service.get_service_ids(name) - if service_ids: - service_json = service.dump_services(service_ids) - - # Delete service - if state == "absent": - if not service_ids: - module.exit_json(changed=False, msg="Service not found, no change: %s" % name) - service.delete_service(service_ids) - module.exit_json(changed=True, result="Successfully deleted service(s) %s" % name) - - elif state == "present": - if (trigger_name and not trigger_host) or (trigger_host and not trigger_name): - module.fail_json(msg="Specify either both trigger_host and trigger_name or none to create or update a service") - # Does not exists going to create it - if not service_ids: - service.create_service(name, parent, sla, calculate_sla, trigger_name, trigger_host, algorithm) - module.exit_json(changed=True, msg="Service %s created" % name) - # Else we update it if needed - else: - service.update_service(service_ids[0], name, parent, sla, calculate_sla, trigger_name, trigger_host, algorithm) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_template.py b/plugins/modules/monitoring/zabbix/zabbix_template.py deleted file mode 100644 index 86fb659f88..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_template.py +++ /dev/null @@ -1,795 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, sookido -# 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: zabbix_template -short_description: Create/update/delete/dump Zabbix template -description: - - This module allows you to create, modify, delete and dump Zabbix templates. - - Multiple templates can be created or modified at once if passing JSON or XML to module. -author: - - "sookido (@sookido)" - - "Logan Vig (@logan2211)" - - "Dusan Matejka (@D3DeFi)" -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - template_name: - description: - - Name of Zabbix template. - - Required when I(template_json) or I(template_xml) are not used. - - Mutually exclusive with I(template_json) and I(template_xml). - required: false - type: str - template_json: - description: - - JSON dump of templates to import. - - Multiple templates can be imported this way. - - Mutually exclusive with I(template_name) and I(template_xml). - required: false - type: json - template_xml: - description: - - XML dump of templates to import. - - Multiple templates can be imported this way. - - You are advised to pass XML structure matching the structure used by your version of Zabbix server. - - Custom XML structure can be imported as long as it is valid, but may not yield consistent idempotent - results on subsequent runs. - - Mutually exclusive with I(template_name) and I(template_json). - required: false - type: str - template_groups: - description: - - List of host groups to add template to when template is created. - - Replaces the current host groups the template belongs to if the template is already present. - - Required when creating a new template with C(state=present) and I(template_name) is used. - Not required when updating an existing template. - required: false - type: list - elements: str - link_templates: - description: - - List of template names to be linked to the template. - - Templates that are not specified and are linked to the existing template will be only unlinked and not - cleared from the template. - required: false - type: list - elements: str - clear_templates: - description: - - List of template names to be unlinked and cleared from the template. - - This option is ignored if template is being created for the first time. - required: false - type: list - elements: str - macros: - description: - - List of user macros to create for the template. - - Macros that are not specified and are present on the existing template will be replaced. - - See examples on how to pass macros. - required: false - type: list - elements: dict - suboptions: - name: - description: - - Name of the macro. - - Must be specified in {$NAME} format. - type: str - value: - description: - - Value of the macro. - type: str - dump_format: - description: - - Format to use when dumping template with C(state=dump). - - This option is deprecated and will eventually be removed in 2.14. - required: false - choices: [json, xml] - default: "json" - type: str - omit_date: - description: - - Removes the date field for the exported/dumped template - - Requires C(state=dump) - required: false - type: bool - default: false - state: - description: - - Required state of the template. - - On C(state=present) template will be created/imported or updated depending if it is already present. - - On C(state=dump) template content will get dumped into required format specified in I(dump_format). - - On C(state=absent) template will be deleted. - - The C(state=dump) is deprecated and will eventually be removed in 2.14. The M(zabbix_template_info) module should be used instead. - required: false - choices: [present, absent, dump] - default: "present" - type: str - -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = r''' ---- -- name: Create a new Zabbix template linked to groups, macros and templates - local_action: - module: zabbix_template - server_url: http://127.0.0.1 - login_user: username - login_password: password - template_name: ExampleHost - template_groups: - - Role - - Role2 - link_templates: - - Example template1 - - Example template2 - macros: - - macro: '{$EXAMPLE_MACRO1}' - value: 30000 - - macro: '{$EXAMPLE_MACRO2}' - value: 3 - - macro: '{$EXAMPLE_MACRO3}' - value: 'Example' - state: present - -- name: Unlink and clear templates from the existing Zabbix template - local_action: - module: zabbix_template - server_url: http://127.0.0.1 - login_user: username - login_password: password - template_name: ExampleHost - clear_templates: - - Example template3 - - Example template4 - state: present - -- name: Import Zabbix templates from JSON - local_action: - module: zabbix_template - server_url: http://127.0.0.1 - login_user: username - login_password: password - template_json: "{{ lookup('file', 'zabbix_apache2.json') }}" - state: present - -- name: Import Zabbix templates from XML - local_action: - module: zabbix_template - server_url: http://127.0.0.1 - login_user: username - login_password: password - template_xml: "{{ lookup('file', 'zabbix_apache2.json') }}" - state: present - -- name: Import Zabbix template from Ansible dict variable - zabbix_template: - login_user: username - login_password: password - server_url: http://127.0.0.1 - template_json: - zabbix_export: - version: '3.2' - templates: - - name: Template for Testing - description: 'Testing template import' - template: Test Template - groups: - - name: Templates - applications: - - name: Test Application - state: present - -- name: Configure macros on the existing Zabbix template - local_action: - module: zabbix_template - server_url: http://127.0.0.1 - login_user: username - login_password: password - template_name: Template - macros: - - macro: '{$TEST_MACRO}' - value: 'Example' - state: present - -- name: Delete Zabbix template - local_action: - module: zabbix_template - server_url: http://127.0.0.1 - login_user: username - login_password: password - template_name: Template - state: absent - -- name: Dump Zabbix template as JSON - local_action: - module: zabbix_template - server_url: http://127.0.0.1 - login_user: username - login_password: password - template_name: Template - omit_date: yes - state: dump - register: template_dump - -- name: Dump Zabbix template as XML - local_action: - module: zabbix_template - server_url: http://127.0.0.1 - login_user: username - login_password: password - template_name: Template - dump_format: xml - omit_date: false - state: dump - register: template_dump -''' - -RETURN = r''' ---- -template_json: - description: The JSON dump of the template - returned: when state is dump and omit_date is no - type: str - sample: { - "zabbix_export":{ - "date":"2017-11-29T16:37:24Z", - "templates":[{ - "templates":[], - "description":"", - "httptests":[], - "screens":[], - "applications":[], - "discovery_rules":[], - "groups":[{"name":"Templates"}], - "name":"Test Template", - "items":[], - "macros":[], - "template":"test" - }], - "version":"3.2", - "groups":[{ - "name":"Templates" - }] - } - } - -template_xml: - description: dump of the template in XML representation - returned: when state is dump, dump_format is xml and omit_date is yes - type: str - sample: |- - - - 4.2 - - - Templates - - - - - - -''' - - -import atexit -import json -import traceback -import xml.etree.ElementTree as ET - -from distutils.version import LooseVersion -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -from ansible.module_utils._text import to_native - -try: - from zabbix_api import ZabbixAPI, ZabbixAPIException - - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - - -class Template(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - # check if host group exists - def check_host_group_exist(self, group_names): - for group_name in group_names: - result = self._zapi.hostgroup.get({'filter': {'name': group_name}}) - if not result: - self._module.fail_json(msg="Hostgroup not found: %s" % - group_name) - return True - - # get group ids by group names - def get_group_ids_by_group_names(self, group_names): - group_ids = [] - if group_names is None or len(group_names) == 0: - return group_ids - if self.check_host_group_exist(group_names): - group_list = self._zapi.hostgroup.get( - {'output': 'extend', - 'filter': {'name': group_names}}) - for group in group_list: - group_id = group['groupid'] - group_ids.append({'groupid': group_id}) - return group_ids - - def get_template_ids(self, template_list): - template_ids = [] - if template_list is None or len(template_list) == 0: - return template_ids - for template in template_list: - template_list = self._zapi.template.get( - {'output': 'extend', - 'filter': {'host': template}}) - if len(template_list) < 1: - continue - else: - template_id = template_list[0]['templateid'] - template_ids.append(template_id) - return template_ids - - def add_template(self, template_name, group_ids, link_template_ids, macros): - if self._module.check_mode: - self._module.exit_json(changed=True) - - self._zapi.template.create({'host': template_name, 'groups': group_ids, 'templates': link_template_ids, - 'macros': macros}) - - def check_template_changed(self, template_ids, template_groups, link_templates, clear_templates, - template_macros, template_content, template_type): - """Compares template parameters to already existing values if any are found. - - template_json - JSON structures are compared as deep sorted dictionaries, - template_xml - XML structures are compared as strings, but filtered and formatted first, - If none above is used, all the other arguments are compared to their existing counterparts - retrieved from Zabbix API.""" - changed = False - # Compare filtered and formatted XMLs strings for any changes. It is expected that provided - # XML has same structure as Zabbix uses (e.g. it was optimally exported via Zabbix GUI or API) - if template_content is not None and template_type == 'xml': - existing_template = self.dump_template(template_ids, template_type='xml') - - if self.filter_xml_template(template_content) != self.filter_xml_template(existing_template): - changed = True - - return changed - - existing_template = self.dump_template(template_ids, template_type='json') - # Compare JSON objects as deep sorted python dictionaries - if template_content is not None and template_type == 'json': - parsed_template_json = self.load_json_template(template_content) - if self.diff_template(parsed_template_json, existing_template): - changed = True - - return changed - - # If neither template_json or template_xml were used, user provided all parameters via module options - if template_groups is not None: - existing_groups = [g['name'] for g in existing_template['zabbix_export']['groups']] - - if set(template_groups) != set(existing_groups): - changed = True - - if 'templates' not in existing_template['zabbix_export']['templates'][0]: - existing_template['zabbix_export']['templates'][0]['templates'] = [] - - # Check if any new templates would be linked or any existing would be unlinked - exist_child_templates = [t['name'] for t in existing_template['zabbix_export']['templates'][0]['templates']] - if link_templates is not None: - if set(link_templates) != set(exist_child_templates): - changed = True - else: - if set([]) != set(exist_child_templates): - changed = True - - # Mark that there will be changes when at least one existing template will be unlinked - if clear_templates is not None: - for t in clear_templates: - if t in exist_child_templates: - changed = True - break - - if 'macros' not in existing_template['zabbix_export']['templates'][0]: - existing_template['zabbix_export']['templates'][0]['macros'] = [] - - if template_macros is not None: - existing_macros = existing_template['zabbix_export']['templates'][0]['macros'] - if template_macros != existing_macros: - changed = True - - return changed - - def update_template(self, template_ids, group_ids, link_template_ids, clear_template_ids, template_macros): - template_changes = {} - if group_ids is not None: - template_changes.update({'groups': group_ids}) - - if link_template_ids is not None: - template_changes.update({'templates': link_template_ids}) - else: - template_changes.update({'templates': []}) - - if clear_template_ids is not None: - template_changes.update({'templates_clear': clear_template_ids}) - - if template_macros is not None: - template_changes.update({'macros': template_macros}) - - if template_changes: - # If we got here we know that only one template was provided via template_name - template_changes.update({'templateid': template_ids[0]}) - self._zapi.template.update(template_changes) - - def delete_template(self, templateids): - if self._module.check_mode: - self._module.exit_json(changed=True) - self._zapi.template.delete(templateids) - - def ordered_json(self, obj): - # Deep sort json dicts for comparison - if isinstance(obj, dict): - return sorted((k, self.ordered_json(v)) for k, v in obj.items()) - if isinstance(obj, list): - return sorted(self.ordered_json(x) for x in obj) - else: - return obj - - def dump_template(self, template_ids, template_type='json', omit_date=False): - if self._module.check_mode: - self._module.exit_json(changed=True) - - try: - dump = self._zapi.configuration.export({'format': template_type, 'options': {'templates': template_ids}}) - if template_type == 'xml': - xmlroot = ET.fromstring(dump.encode('utf-8')) - # remove date field if requested - if omit_date: - date = xmlroot.find(".date") - if date is not None: - xmlroot.remove(date) - return str(ET.tostring(xmlroot, encoding='utf-8').decode('utf-8')) - else: - return self.load_json_template(dump, omit_date=omit_date) - - except ZabbixAPIException as e: - self._module.fail_json(msg='Unable to export template: %s' % e) - - def diff_template(self, template_json_a, template_json_b): - # Compare 2 zabbix templates and return True if they differ. - template_json_a = self.filter_template(template_json_a) - template_json_b = self.filter_template(template_json_b) - if self.ordered_json(template_json_a) == self.ordered_json(template_json_b): - return False - return True - - def filter_template(self, template_json): - # Filter the template json to contain only the keys we will update - keep_keys = set(['graphs', 'templates', 'triggers', 'value_maps']) - unwanted_keys = set(template_json['zabbix_export']) - keep_keys - for unwanted_key in unwanted_keys: - del template_json['zabbix_export'][unwanted_key] - - # Versions older than 2.4 do not support description field within template - desc_not_supported = False - if LooseVersion(self._zapi.api_version()).version[:2] < LooseVersion('2.4').version: - desc_not_supported = True - - # Filter empty attributes from template object to allow accurate comparison - for template in template_json['zabbix_export']['templates']: - for key in list(template.keys()): - if not template[key] or (key == 'description' and desc_not_supported): - template.pop(key) - - return template_json - - def filter_xml_template(self, template_xml): - """Filters out keys from XML template that may wary between exports (e.g date or version) and - keys that are not imported via this module. - - It is advised that provided XML template exactly matches XML structure used by Zabbix""" - # Strip last new line and convert string to ElementTree - parsed_xml_root = self.load_xml_template(template_xml.strip()) - keep_keys = ['graphs', 'templates', 'triggers', 'value_maps'] - - # Remove unwanted XML nodes - for node in list(parsed_xml_root): - if node.tag not in keep_keys: - parsed_xml_root.remove(node) - - # Filter empty attributes from template objects to allow accurate comparison - for template in list(parsed_xml_root.find('templates')): - for element in list(template): - if element.text is None and len(list(element)) == 0: - template.remove(element) - - # Filter new lines and indentation - xml_root_text = list(line.strip() for line in ET.tostring(parsed_xml_root, encoding='utf8', method='xml').decode().split('\n')) - return ''.join(xml_root_text) - - def load_json_template(self, template_json, omit_date=False): - try: - jsondoc = json.loads(template_json) - if omit_date and 'date' in jsondoc['zabbix_export']: - del jsondoc['zabbix_export']['date'] - return jsondoc - except ValueError as e: - self._module.fail_json(msg='Invalid JSON provided', details=to_native(e), exception=traceback.format_exc()) - - def load_xml_template(self, template_xml): - try: - return ET.fromstring(template_xml) - except ET.ParseError as e: - self._module.fail_json(msg='Invalid XML provided', details=to_native(e), exception=traceback.format_exc()) - - def import_template(self, template_content, template_type='json'): - # rules schema latest version - update_rules = { - 'applications': { - 'createMissing': True, - 'deleteMissing': True - }, - 'discoveryRules': { - 'createMissing': True, - 'updateExisting': True, - 'deleteMissing': True - }, - 'graphs': { - 'createMissing': True, - 'updateExisting': True, - 'deleteMissing': True - }, - 'groups': { - 'createMissing': True - }, - 'httptests': { - 'createMissing': True, - 'updateExisting': True, - 'deleteMissing': True - }, - 'items': { - 'createMissing': True, - 'updateExisting': True, - 'deleteMissing': True - }, - 'templates': { - 'createMissing': True, - 'updateExisting': True - }, - 'templateLinkage': { - 'createMissing': True - }, - 'templateScreens': { - 'createMissing': True, - 'updateExisting': True, - 'deleteMissing': True - }, - 'triggers': { - 'createMissing': True, - 'updateExisting': True, - 'deleteMissing': True - }, - 'valueMaps': { - 'createMissing': True, - 'updateExisting': True - } - } - - try: - # old api version support here - api_version = self._zapi.api_version() - # updateExisting for application removed from zabbix api after 3.2 - if LooseVersion(api_version).version[:2] <= LooseVersion('3.2').version: - update_rules['applications']['updateExisting'] = True - - # templateLinkage.deleteMissing only available in 4.0 branch higher .16 and higher 4.4.4 - # it's not available in 4.2 branches or lower 4.0.16 - if LooseVersion(api_version).version[:2] == LooseVersion('4.0').version and \ - LooseVersion(api_version).version[:3] >= LooseVersion('4.0.16').version: - update_rules['templateLinkage']['deleteMissing'] = True - if LooseVersion(api_version).version[:3] >= LooseVersion('4.4.4').version: - update_rules['templateLinkage']['deleteMissing'] = True - - import_data = {'format': template_type, 'source': template_content, 'rules': update_rules} - self._zapi.configuration.import_(import_data) - except ZabbixAPIException as e: - self._module.fail_json(msg='Unable to import template', details=to_native(e), - exception=traceback.format_exc()) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - template_name=dict(type='str', required=False), - template_json=dict(type='json', required=False), - template_xml=dict(type='str', required=False), - template_groups=dict(type='list', required=False), - link_templates=dict(type='list', required=False), - clear_templates=dict(type='list', required=False), - macros=dict(type='list', required=False), - omit_date=dict(type='bool', required=False, default=False), - dump_format=dict(type='str', required=False, default='json', choices=['json', 'xml']), - state=dict(type='str', default="present", choices=['present', 'absent', 'dump']), - timeout=dict(type='int', default=10) - ), - required_one_of=[ - ['template_name', 'template_json', 'template_xml'] - ], - mutually_exclusive=[ - ['template_name', 'template_json', 'template_xml'] - ], - required_if=[ - ['state', 'absent', ['template_name']], - ['state', 'dump', ['template_name']] - ], - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - template_name = module.params['template_name'] - template_json = module.params['template_json'] - template_xml = module.params['template_xml'] - template_groups = module.params['template_groups'] - link_templates = module.params['link_templates'] - clear_templates = module.params['clear_templates'] - template_macros = module.params['macros'] - omit_date = module.params['omit_date'] - dump_format = module.params['dump_format'] - state = module.params['state'] - timeout = module.params['timeout'] - - zbx = None - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except ZabbixAPIException as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - template = Template(module, zbx) - - # Identify template names for IDs retrieval - # Template names are expected to reside in ['zabbix_export']['templates'][*]['template'] for both data types - template_content, template_type = None, None - if template_json is not None: - template_type = 'json' - template_content = template_json - json_parsed = template.load_json_template(template_content) - template_names = list(t['template'] for t in json_parsed['zabbix_export']['templates']) - - elif template_xml is not None: - template_type = 'xml' - template_content = template_xml - xml_parsed = template.load_xml_template(template_content) - template_names = list(t.find('template').text for t in list(xml_parsed.find('templates'))) - - else: - template_names = [template_name] - - template_ids = template.get_template_ids(template_names) - - if state == "absent": - if not template_ids: - module.exit_json(changed=False, msg="Template not found. No changed: %s" % template_name) - - template.delete_template(template_ids) - module.exit_json(changed=True, result="Successfully deleted template %s" % template_name) - - elif state == "dump": - module.deprecate("The 'dump' state has been deprecated and will be removed, use 'zabbix_template_info' module instead.", version='2.14') - if not template_ids: - module.fail_json(msg='Template not found: %s' % template_name) - - if dump_format == 'json': - module.exit_json(changed=False, template_json=template.dump_template(template_ids, template_type='json', omit_date=omit_date)) - elif dump_format == 'xml': - module.exit_json(changed=False, template_xml=template.dump_template(template_ids, template_type='xml', omit_date=omit_date)) - - elif state == "present": - # Load all subelements for template that were provided by user - group_ids = None - if template_groups is not None: - group_ids = template.get_group_ids_by_group_names(template_groups) - - link_template_ids = None - if link_templates is not None: - link_template_ids = template.get_template_ids(link_templates) - - clear_template_ids = None - if clear_templates is not None: - clear_template_ids = template.get_template_ids(clear_templates) - - if template_macros is not None: - # Zabbix configuration.export does not differentiate python types (numbers are returned as strings) - for macroitem in template_macros: - for key in macroitem: - macroitem[key] = str(macroitem[key]) - - if not template_ids: - # Assume new templates are being added when no ID's were found - if template_content is not None: - template.import_template(template_content, template_type) - module.exit_json(changed=True, result="Template import successful") - - else: - if group_ids is None: - module.fail_json(msg='template_groups are required when creating a new Zabbix template') - - template.add_template(template_name, group_ids, link_template_ids, template_macros) - module.exit_json(changed=True, result="Successfully added template: %s" % template_name) - - else: - changed = template.check_template_changed(template_ids, template_groups, link_templates, clear_templates, - template_macros, template_content, template_type) - - if module.check_mode: - module.exit_json(changed=changed) - - if changed: - if template_type is not None: - template.import_template(template_content, template_type) - else: - template.update_template(template_ids, group_ids, link_template_ids, clear_template_ids, - template_macros) - - module.exit_json(changed=changed, result="Template successfully updated") - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_template_info.py b/plugins/modules/monitoring/zabbix/zabbix_template_info.py deleted file mode 100644 index cdc5d573da..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_template_info.py +++ /dev/null @@ -1,273 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, sky-joker -# 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 - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = ''' -module: zabbix_template_info -short_description: Gather information about Zabbix template -author: - - sky-joker (@sky-joker) -description: - - This module allows you to search for Zabbix template. -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - template_name: - description: - - Name of the template in Zabbix. - required: true - type: str - format: - description: - - Format to use when dumping template. - choices: ['json', 'xml'] - default: json - type: str - omit_date: - description: - - Removes the date field for the dumped template - required: false - type: bool - default: false -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = ''' -- name: Get Zabbix template as JSON - zabbix_template_info: - server_url: "http://zabbix.example.com/zabbix/" - login_user: admin - login_password: secret - template_name: Template - format: json - omit_date: yes - register: template_json - -- name: Get Zabbix template as XML - zabbix_template_info: - server_url: "http://zabbix.example.com/zabbix/" - login_user: admin - login_password: secret - template_name: Template - format: xml - omit_date: no - register: template_json -''' - -RETURN = ''' ---- -template_json: - description: The JSON of the template - returned: when format is json and omit_date is true - type: str - sample: { - "zabbix_export": { - "version": "4.0", - "groups": [ - { - "name": "Templates" - } - ], - "templates": [ - { - "template": "Test Template", - "name": "Template for Testing", - "description": "Testing template import", - "groups": [ - { - "name": "Templates" - } - ], - "applications": [ - { - "name": "Test Application" - } - ], - "items": [], - "discovery_rules": [], - "httptests": [], - "macros": [], - "templates": [], - "screens": [] - } - ] - } - } - -template_xml: - description: The XML of the template - returned: when format is xml and omit_date is false - type: str - sample: >- - - 4.0 - 2019-10-27T14:49:57Z - - - Templates - - - - - - -''' - -import atexit -import traceback -import json -import xml.etree.ElementTree as ET - -try: - from zabbix_api import ZabbixAPI - from zabbix_api import Already_Exists - from zabbix_api import ZabbixAPIException - - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -from ansible.module_utils._text import to_native - - -class TemplateInfo(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - def get_template_id(self, template_name): - template_id = [] - try: - template_list = self._zapi.template.get( - { - 'output': 'extend', - 'filter': { - 'host': template_name - } - } - ) - except ZabbixAPIException as e: - self._module.fail_json(msg='Failed to get template: %s' % e) - - if template_list: - template_id.append(template_list[0]['templateid']) - - return template_id - - def load_json_template(self, template_json, omit_date=False): - try: - jsondoc = json.loads(template_json) - # remove date field if requested - if omit_date and 'date' in jsondoc['zabbix_export']: - del jsondoc['zabbix_export']['date'] - return jsondoc - except ValueError as e: - self._module.fail_json(msg='Invalid JSON provided', details=to_native(e), exception=traceback.format_exc()) - - def dump_template(self, template_id, template_type='json', omit_date=False): - try: - dump = self._zapi.configuration.export({'format': template_type, 'options': {'templates': template_id}}) - if template_type == 'xml': - xmlroot = ET.fromstring(dump.encode('utf-8')) - # remove date field if requested - if omit_date: - date = xmlroot.find(".date") - if date is not None: - xmlroot.remove(date) - return str(ET.tostring(xmlroot, encoding='utf-8').decode('utf-8')) - else: - return self.load_json_template(dump, omit_date) - - except ZabbixAPIException as e: - self._module.fail_json(msg='Unable to export template: %s' % e) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - timeout=dict(type='int', default=10), - template_name=dict(type='str', required=True), - omit_date=dict(type='bool', required=False, default=False), - format=dict(type='str', choices=['json', 'xml'], default='json') - ), - supports_check_mode=False - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), - exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - timeout = module.params['timeout'] - template_name = module.params['template_name'] - omit_date = module.params['omit_date'] - format = module.params['format'] - - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - template_info = TemplateInfo(module, zbx) - - template_id = template_info.get_template_id(template_name) - - if not template_id: - module.fail_json(msg='Template not found: %s' % template_name) - - if format == 'json': - module.exit_json(changed=False, template_json=template_info.dump_template(template_id, template_type='json', omit_date=omit_date)) - elif format == 'xml': - module.exit_json(changed=False, template_xml=template_info.dump_template(template_id, template_type='xml', omit_date=omit_date)) - - -if __name__ == "__main__": - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_user.py b/plugins/modules/monitoring/zabbix/zabbix_user.py deleted file mode 100644 index d68e384b32..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_user.py +++ /dev/null @@ -1,663 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, sky-joker -# 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 - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' -module: zabbix_user -short_description: Create/update/delete Zabbix users -author: - - sky-joker (@sky-joker) -description: - - This module allows you to create, modify and delete Zabbix users. -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - alias: - description: - - Name of the user alias in Zabbix. - - alias is the unique identifier used and cannot be updated using this module. - required: true - type: str - name: - description: - - Name of the user. - default: '' - type: str - surname: - description: - - Surname of the user. - default: '' - type: str - usrgrps: - description: - - User groups to add the user to. - required: true - type: list - elements: str - passwd: - description: - - User's password. - required: true - type: str - override_passwd: - description: - - Override password. - default: no - type: bool - lang: - description: - - Language code of the user's language. - default: 'en_GB' - choices: - - 'en_GB' - - 'en_US' - - 'zh_CN' - - 'cs_CZ' - - 'fr_FR' - - 'he_IL' - - 'it_IT' - - 'ko_KR' - - 'ja_JP' - - 'nb_NO' - - 'pl_PL' - - 'pt_BR' - - 'pt_PT' - - 'ru_RU' - - 'sk_SK' - - 'tr_TR' - - 'uk_UA' - type: str - theme: - description: - - User's theme. - default: 'default' - choices: - - 'default' - - 'blue-theme' - - 'dark-theme' - type: str - autologin: - description: - - Whether to enable auto-login. - - If enable autologin, cannot enable autologout. - default: false - type: bool - autologout: - description: - - User session life time in seconds. If set to 0, the session will never expire. - - If enable autologout, cannot enable autologin. - default: '0' - type: str - refresh: - description: - - Automatic refresh period in seconds. - default: '30' - type: str - rows_per_page: - description: - - Amount of object rows to show per page. - default: '50' - type: str - after_login_url: - description: - - URL of the page to redirect the user to after logging in. - default: '' - type: str - user_medias: - description: - - Set the user's media. - default: [] - suboptions: - mediatype: - description: - - Media type name to set. - default: 'Email' - type: str - sendto: - description: - - Address, user name or other identifier of the recipient. - required: true - type: str - period: - description: - - Time when the notifications can be sent as a time period or user macros separated by a semicolon. - - Please review the documentation for more information on the supported time period. - - https://www.zabbix.com/documentation/4.0/manual/appendix/time_period - default: '1-7,00:00-24:00' - type: str - severity: - description: - - Trigger severities to send notifications about. - suboptions: - not_classified: - description: - - severity not_classified enable/disable. - default: True - type: bool - information: - description: - - severity information enable/disable. - default: True - type: bool - warning: - description: - - severity warning enable/disable. - default: True - type: bool - average: - description: - - severity average enable/disable. - default: True - type: bool - high: - description: - - severity high enable/disable. - default: True - type: bool - disaster: - description: - - severity disaster enable/disable. - default: True - type: bool - default: - not_classified: True - information: True - warning: True - average: True - high: True - disaster: True - type: dict - active: - description: - - Whether the media is enabled. - default: true - type: bool - type: list - elements: dict - type: - description: - - Type of the user. - default: 'Zabbix user' - choices: - - 'Zabbix user' - - 'Zabbix admin' - - 'Zabbix super admin' - type: str - state: - description: - - State of the user. - - On C(present), it will create if user does not exist or update the user if the associated data is different. - - On C(absent) will remove a user if it exists. - default: 'present' - choices: ['present', 'absent'] - type: str -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = r''' -- name: create of zabbix user. - zabbix_user: - server_url: "http://zabbix.example.com/zabbix/" - login_user: Admin - login_password: secret - alias: example - name: user name - surname: user surname - usrgrps: - - Guests - - Disabled - passwd: password - lang: en_GB - theme: blue-theme - autologin: no - autologout: '0' - refresh: '30' - rows_per_page: '200' - after_login_url: '' - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: no - type: Zabbix super admin - state: present - -- name: delete of zabbix user. - zabbix_user: - server_url: "http://zabbix.example.com/zabbix/" - login_user: admin - login_password: secret - alias: example - usrgrps: - - Guests - passwd: password - user_medias: - - sendto: example@example.com - state: absent -''' - -RETURN = r''' -user_ids: - description: User id created or changed - returned: success - type: dict - sample: { "userids": [ "5" ] } -''' - -import atexit -import traceback - -try: - from zabbix_api import ZabbixAPI - from zabbix_api import Already_Exists - - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from distutils.version import LooseVersion -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -import copy - - -class User(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - self._zbx_api_version = zbx.api_version()[:3] - - def get_usergroupid_by_user_group_name(self, usrgrps): - user_group_ids = [] - for user_group_name in usrgrps: - user_group = self._zapi.usergroup.get({'output': 'extend', 'filter': {'name': user_group_name}}) - if user_group: - user_group_ids.append({'usrgrpid': user_group[0]['usrgrpid']}) - else: - self._module.fail_json(msg="User group not found: %s" % user_group_name) - return user_group_ids - - def check_user_exist(self, alias): - zbx_user = self._zapi.user.get({'output': 'extend', 'filter': {'alias': alias}, - 'getAccess': True, 'selectMedias': 'extend', - 'selectUsrgrps': 'extend'}) - - return zbx_user - - def convert_user_medias_parameter_types(self, user_medias): - copy_user_medias = copy.deepcopy(user_medias) - for user_media in copy_user_medias: - media_types = self._zapi.mediatype.get({'output': 'extend'}) - for media_type in media_types: - if LooseVersion(self._zbx_api_version) < LooseVersion('4.4'): - if media_type['description'] == user_media['mediatype']: - user_media['mediatypeid'] = media_type['mediatypeid'] - break - else: - if media_type['name'] == user_media['mediatype']: - user_media['mediatypeid'] = media_type['mediatypeid'] - break - - if 'mediatypeid' not in user_media: - self._module.fail_json(msg="Media type not found: %s" % user_media['mediatype']) - else: - del user_media['mediatype'] - - severity_binary_number = '' - for severity_key in 'disaster', 'high', 'average', 'warning', 'information', 'not_classified': - if user_media['severity'][severity_key]: - severity_binary_number = severity_binary_number + '1' - else: - severity_binary_number = severity_binary_number + '0' - user_media['severity'] = str(int(severity_binary_number, 2)) - - if user_media['active']: - user_media['active'] = '0' - else: - user_media['active'] = '1' - - return copy_user_medias - - def user_parameter_difference_check(self, zbx_user, alias, name, surname, user_group_ids, passwd, lang, theme, - autologin, autologout, refresh, rows_per_page, url, user_medias, user_type, - override_passwd): - - user_medias = self.convert_user_medias_parameter_types(user_medias) - - # existing data - existing_data = copy.deepcopy(zbx_user[0]) - usrgrpids = [] - for usrgrp in existing_data['usrgrps']: - usrgrpids.append({'usrgrpid': usrgrp['usrgrpid']}) - - existing_data['usrgrps'] = sorted(usrgrpids, key=lambda x: x['usrgrpid']) - - # Processing for zabbix 4.0 and above. - # In zabbix 4.0 and above, Email sendto is of type list. - # This module, one media supports only one Email sendto. - # Therefore following processing extract one Email from list. - if LooseVersion(self._zbx_api_version) >= LooseVersion('4.0'): - for media in existing_data['medias']: - if isinstance(media['sendto'], list): - media['sendto'] = media['sendto'][0] - - existing_data['user_medias'] = sorted(existing_data['medias'], key=lambda x: x['sendto']) - for del_key in ['medias', 'attempt_clock', 'attempt_failed', 'attempt_ip', 'debug_mode', 'users_status', - 'gui_access']: - del existing_data[del_key] - - for user_media in existing_data['user_medias']: - for del_key in ['mediaid', 'userid']: - del user_media[del_key] - - # request data - request_data = { - 'userid': zbx_user[0]['userid'], - 'alias': alias, - 'name': name, - 'surname': surname, - 'usrgrps': sorted(user_group_ids, key=lambda x: x['usrgrpid']), - 'lang': lang, - 'theme': theme, - 'autologin': autologin, - 'autologout': autologout, - 'refresh': refresh, - 'rows_per_page': rows_per_page, - 'url': url, - 'user_medias': sorted(user_medias, key=lambda x: x['sendto']), - 'type': user_type - } - - if override_passwd: - request_data['passwd'] = passwd - - user_parameter_difference_check_result = True - if existing_data == request_data: - user_parameter_difference_check_result = False - - diff_params = { - "before": existing_data, - "after": request_data - } - - return user_parameter_difference_check_result, diff_params - - def add_user(self, alias, name, surname, user_group_ids, passwd, lang, theme, autologin, autologout, refresh, - rows_per_page, url, user_medias, user_type): - - user_medias = self.convert_user_medias_parameter_types(user_medias) - - user_ids = {} - - request_data = { - 'alias': alias, - 'name': name, - 'surname': surname, - 'usrgrps': user_group_ids, - 'passwd': passwd, - 'lang': lang, - 'theme': theme, - 'autologin': autologin, - 'autologout': autologout, - 'refresh': refresh, - 'rows_per_page': rows_per_page, - 'url': url, - 'user_medias': user_medias, - 'type': user_type - } - - diff_params = {} - if not self._module.check_mode: - try: - user_ids = self._zapi.user.create(request_data) - except Exception as e: - self._module.fail_json(msg="Failed to create user %s: %s" % (alias, e)) - else: - diff_params = { - "before": "", - "after": request_data - } - - return user_ids, diff_params - - def update_user(self, zbx_user, alias, name, surname, user_group_ids, passwd, lang, theme, autologin, autologout, - refresh, rows_per_page, url, user_medias, user_type, override_passwd): - - user_medias = self.convert_user_medias_parameter_types(user_medias) - - user_ids = {} - - request_data = { - 'userid': zbx_user[0]['userid'], - 'alias': alias, - 'name': name, - 'surname': surname, - 'usrgrps': user_group_ids, - 'lang': lang, - 'theme': theme, - 'autologin': autologin, - 'autologout': autologout, - 'refresh': refresh, - 'rows_per_page': rows_per_page, - 'url': url, - 'type': user_type - } - - if override_passwd: - request_data['passwd'] = passwd - - # In the case of zabbix 3.2 or less, it is necessary to use updatemedia method to update media. - if LooseVersion(self._zbx_api_version) <= LooseVersion('3.2'): - try: - user_ids = self._zapi.user.update(request_data) - except Exception as e: - self._module.fail_json(msg="Failed to update user %s: %s" % (alias, e)) - - try: - user_ids = self._zapi.user.updatemedia({ - 'users': [{'userid': zbx_user[0]['userid']}], - 'medias': user_medias - }) - except Exception as e: - self._module.fail_json(msg="Failed to update user medias %s: %s" % (alias, e)) - - if LooseVersion(self._zbx_api_version) >= LooseVersion('3.4'): - try: - request_data['user_medias'] = user_medias - user_ids = self._zapi.user.update(request_data) - except Exception as e: - self._module.fail_json(msg="Failed to update user %s: %s" % (alias, e)) - - return user_ids - - def delete_user(self, zbx_user, alias): - user_ids = {} - diff_params = {} - - if not self._module.check_mode: - try: - user_ids = self._zapi.user.delete([zbx_user[0]['userid']]) - except Exception as e: - self._module.fail_json(msg="Failed to delete user %s: %s" % (alias, e)) - else: - diff_params = { - "before": zbx_user[0], - "after": "" - } - - return user_ids, diff_params - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - alias=dict(type='str', required=True), - name=dict(type='str', default=''), - surname=dict(type='str', default=''), - usrgrps=dict(type='list', required=True), - passwd=dict(type='str', required=True, no_log=True), - override_passwd=dict(type='bool', required=False, default=False), - lang=dict(type='str', default='en_GB', choices=['en_GB', 'en_US', 'zh_CN', 'cs_CZ', 'fr_FR', - 'he_IL', 'it_IT', 'ko_KR', 'ja_JP', 'nb_NO', - 'pl_PL', 'pt_BR', 'pt_PT', 'ru_RU', 'sk_SK', - 'tr_TR', 'uk_UA']), - theme=dict(type='str', default='default', choices=['default', 'blue-theme', 'dark-theme']), - autologin=dict(type='bool', default=False), - autologout=dict(type='str', default='0'), - refresh=dict(type='str', default='30'), - rows_per_page=dict(type='str', default='50'), - after_login_url=dict(type='str', default=''), - user_medias=dict(type='list', default=[], - elements='dict', - options=dict( - mediatype=dict(type='str', default='Email'), - sendto=dict(type='str', required=True), - period=dict(type='str', default='1-7,00:00-24:00'), - severity=dict(type='dict', - options=dict( - not_classified=dict(type='bool', default=True), - information=dict(type='bool', default=True), - warning=dict(type='bool', default=True), - average=dict(type='bool', default=True), - high=dict(type='bool', default=True), - disaster=dict(type='bool', default=True)), - default=dict( - not_classified=True, - information=True, - warning=True, - average=True, - high=True, - disaster=True - )), - active=dict(type='bool', default=True) - )), - type=dict(type='str', default='Zabbix user', choices=['Zabbix user', 'Zabbix admin', 'Zabbix super admin']), - state=dict(type='str', default="present", choices=['present', 'absent']), - timeout=dict(type='int', default=10) - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), - exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - alias = module.params['alias'] - name = module.params['name'] - surname = module.params['surname'] - usrgrps = module.params['usrgrps'] - passwd = module.params['passwd'] - override_passwd = module.params['override_passwd'] - lang = module.params['lang'] - theme = module.params['theme'] - autologin = module.params['autologin'] - autologout = module.params['autologout'] - refresh = module.params['refresh'] - rows_per_page = module.params['rows_per_page'] - after_login_url = module.params['after_login_url'] - user_medias = module.params['user_medias'] - user_type = module.params['type'] - state = module.params['state'] - timeout = module.params['timeout'] - - if autologin: - autologin = '1' - else: - autologin = '0' - - user_type_dict = { - 'Zabbix user': '1', - 'Zabbix admin': '2', - 'Zabbix super admin': '3' - } - user_type = user_type_dict[user_type] - - zbx = None - - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - user = User(module, zbx) - - user_ids = {} - zbx_user = user.check_user_exist(alias) - if state == 'present': - user_group_ids = user.get_usergroupid_by_user_group_name(usrgrps) - if zbx_user: - diff_check_result, diff_params = user.user_parameter_difference_check(zbx_user, alias, name, surname, - user_group_ids, passwd, lang, theme, - autologin, autologout, refresh, - rows_per_page, after_login_url, - user_medias, user_type, - override_passwd) - - if not module.check_mode and diff_check_result: - user_ids = user.update_user(zbx_user, alias, name, surname, user_group_ids, passwd, lang, - theme, autologin, autologout, refresh, rows_per_page, after_login_url, - user_medias, user_type, override_passwd) - else: - diff_check_result = True - user_ids, diff_params = user.add_user(alias, name, surname, user_group_ids, passwd, lang, theme, autologin, - autologout, refresh, rows_per_page, after_login_url, user_medias, - user_type) - - if state == 'absent': - if zbx_user: - diff_check_result = True - user_ids, diff_params = user.delete_user(zbx_user, alias) - else: - diff_check_result = False - diff_params = {} - - if not module.check_mode: - if user_ids: - module.exit_json(changed=True, user_ids=user_ids) - else: - module.exit_json(changed=False) - else: - if diff_check_result: - module.exit_json(changed=True, diff=diff_params) - else: - module.exit_json(changed=False, diff=diff_params) - - -if __name__ == "__main__": - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_user_info.py b/plugins/modules/monitoring/zabbix/zabbix_user_info.py deleted file mode 100644 index c5f753fd60..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_user_info.py +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2019, sky-joker -# 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 - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = ''' -module: zabbix_user_info -short_description: Gather information about Zabbix user -author: - - sky-joker (@sky-joker) -description: - - This module allows you to search for Zabbix user entries. -requirements: - - "python >= 2.6" - - "zabbix-api >= 0.5.4" -options: - alias: - description: - - Name of the user alias in Zabbix. - required: true - type: str -extends_documentation_fragment: -- community.general.zabbix - -''' - -EXAMPLES = ''' -- name: Get zabbix user info - zabbix_user_info: - server_url: "http://zabbix.example.com/zabbix/" - login_user: admin - login_password: secret - alias: example -''' - -RETURN = ''' -zabbix_user: - description: example - returned: always - type: dict - sample: { - "alias": "example", - "attempt_clock": "0", - "attempt_failed": "0", - "attempt_ip": "", - "autologin": "0", - "autologout": "0", - "debug_mode": "0", - "gui_access": "0", - "lang": "en_GB", - "medias": [ - { - "active": "0", - "mediaid": "668", - "mediatypeid": "1", - "period": "1-7,00:00-24:00", - "sendto": "example@example.com", - "severity": "63", - "userid": "660" - } - ], - "name": "user", - "refresh": "30s", - "rows_per_page": "50", - "surname": "example", - "theme": "default", - "type": "1", - "url": "", - "userid": "660", - "users_status": "0", - "usrgrps": [ - { - "debug_mode": "0", - "gui_access": "0", - "name": "Guests", - "users_status": "0", - "usrgrpid": "8" - } - ] - } -''' - -import atexit -import traceback - -try: - from zabbix_api import ZabbixAPI - - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -class User(object): - def __init__(self, module, zbx): - self._module = module - self._zapi = zbx - - def get_user_by_user_alias(self, alias): - zabbix_user = "" - try: - zabbix_user = self._zapi.user.get({'output': 'extend', 'filter': {'alias': alias}, - 'getAccess': True, 'selectMedias': 'extend', - 'selectUsrgrps': 'extend'}) - except Exception as e: - self._zapi.logout() - self._module.fail_json(msg="Failed to get user information: %s" % e) - - if not zabbix_user: - zabbix_user = {} - else: - zabbix_user = zabbix_user[0] - - return zabbix_user - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - alias=dict(type='str', required=True), - timeout=dict(type='int', default=10) - ), - supports_check_mode=True - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), - exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - alias = module.params['alias'] - timeout = module.params['timeout'] - - zbx = None - - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - user = User(module, zbx) - zabbix_user = user.get_user_by_user_alias(alias) - zbx.logout() - module.exit_json(changed=False, zabbix_user=zabbix_user) - - -if __name__ == "__main__": - main() diff --git a/plugins/modules/monitoring/zabbix/zabbix_valuemap.py b/plugins/modules/monitoring/zabbix/zabbix_valuemap.py deleted file mode 100644 index adf093b666..0000000000 --- a/plugins/modules/monitoring/zabbix/zabbix_valuemap.py +++ /dev/null @@ -1,339 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2019, Ruben Tsirunyan -# 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 - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = r''' ---- -module: zabbix_valuemap -short_description: Create/update/delete Zabbix value maps -description: - - This module allows you to create, modify and delete Zabbix value maps. -author: - - "Ruben Tsirunyan (@rubentsirunyan)" -requirements: - - "zabbix-api >= 0.5.4" -options: - name: - type: 'str' - description: - - Name of the value map. - required: true - state: - type: 'str' - description: - - State of the value map. - - On C(present), it will create a value map if it does not exist or update the value map if the associated data is different. - - On C(absent), it will remove the value map if it exists. - choices: ['present', 'absent'] - default: 'present' - mappings: - type: 'list' - elements: dict - description: - - List of value mappings for the value map. - - Required when I(state=present). - suboptions: - value: - type: 'str' - description: Original value. - required: true - map_to: - type: 'str' - description: Value to which the original value is mapped to. - required: true - -extends_documentation_fragment: -- community.general.zabbix - -''' - -RETURN = r''' -''' - -EXAMPLES = r''' -- name: Create a value map - local_action: - module: zabbix_valuemap - server_url: http://zabbix.example.com - login_user: username - login_password: password - name: Numbers - mappings: - - value: 1 - map_to: one - - value: 2 - map_to: two - state: present -''' - - -import atexit -import traceback - -try: - from zabbix_api import ZabbixAPI - HAS_ZABBIX_API = True -except ImportError: - ZBX_IMP_ERR = traceback.format_exc() - HAS_ZABBIX_API = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib - - -def construct_parameters(**kwargs): - """Translates data to a format suitable for Zabbix API - - Args: - **kwargs: Arguments passed to the module. - - Returns: - A dictionary of arguments in a format that is understandable by Zabbix API. - """ - if kwargs['mappings'] is None: - return dict( - name=kwargs['name'] - ) - return dict( - name=kwargs['name'], - mappings=[ - dict( - value=mapping['value'], - newvalue=mapping['map_to'] - ) for mapping in kwargs['mappings'] - ] - ) - - -def check_if_valuemap_exists(module, zbx, name): - """Checks if value map exists. - - Args: - module: AnsibleModule object - zbx: ZabbixAPI object - name: Zabbix valuemap name - - Returns: - tuple: First element is True if valuemap exists and False otherwise. - Second element is a dictionary of valuemap object if it exists. - """ - try: - valuemap_list = zbx.valuemap.get({ - 'output': 'extend', - 'selectMappings': 'extend', - 'filter': {'name': [name]} - }) - if len(valuemap_list) < 1: - return False, None - else: - return True, valuemap_list[0] - except Exception as e: - module.fail_json(msg="Failed to get ID of the valuemap '{name}': {e}".format(name=name, e=e)) - - -def diff(existing, new): - """Constructs the diff for Ansible's --diff option. - - Args: - existing (dict): Existing valuemap data. - new (dict): New valuemap data. - - Returns: - A dictionary like {'before': existing, 'after': new} - with filtered empty values. - """ - before = {} - after = {} - for key in new: - before[key] = existing[key] - if new[key] is None: - after[key] = '' - else: - after[key] = new[key] - return {'before': before, 'after': after} - - -def get_update_params(module, zbx, existing_valuemap, **kwargs): - """Filters only the parameters that are different and need to be updated. - - Args: - module: AnsibleModule object. - zbx: ZabbixAPI object. - existing_valuemap (dict): Existing valuemap. - **kwargs: Parameters for the new valuemap. - - Returns: - A tuple where the first element is a dictionary of parameters - that need to be updated and the second one is a dictionary - returned by diff() function with - existing valuemap data and new params passed to it. - """ - - params_to_update = {} - if sorted(existing_valuemap['mappings'], key=lambda k: k['value']) != sorted(kwargs['mappings'], key=lambda k: k['value']): - params_to_update['mappings'] = kwargs['mappings'] - return params_to_update, diff(existing_valuemap, kwargs) - - -def delete_valuemap(module, zbx, valuemap_id): - try: - return zbx.valuemap.delete([valuemap_id]) - except Exception as e: - module.fail_json(msg="Failed to delete valuemap '{_id}': {e}".format(_id=valuemap_id, e=e)) - - -def update_valuemap(module, zbx, **kwargs): - try: - valuemap_id = zbx.valuemap.update(kwargs) - except Exception as e: - module.fail_json(msg="Failed to update valuemap '{_id}': {e}".format(_id=kwargs['valuemapid'], e=e)) - - -def create_valuemap(module, zbx, **kwargs): - try: - valuemap_id = zbx.valuemap.create(kwargs) - except Exception as e: - module.fail_json(msg="Failed to create valuemap '{name}': {e}".format(name=kwargs['description'], e=e)) - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True, aliases=['url']), - login_user=dict(type='str', required=True), - login_password=dict(type='str', required=True, no_log=True), - http_login_user=dict(type='str', required=False, default=None), - http_login_password=dict(type='str', required=False, default=None, no_log=True), - validate_certs=dict(type='bool', required=False, default=True), - name=dict(type='str', required=True), - state=dict(type='str', default='present', choices=['present', 'absent']), - mappings=dict( - type='list', - elements='dict', - options=dict( - value=dict(type='str', required=True), - map_to=dict(type='str', required=True) - ) - ), - timeout=dict(type='int', default=10) - ), - supports_check_mode=True, - required_if=[ - ['state', 'present', ['mappings']], - ] - ) - - if not HAS_ZABBIX_API: - module.fail_json(msg=missing_required_lib('zabbix-api', url='https://pypi.org/project/zabbix-api/'), exception=ZBX_IMP_ERR) - - server_url = module.params['server_url'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - http_login_user = module.params['http_login_user'] - http_login_password = module.params['http_login_password'] - validate_certs = module.params['validate_certs'] - name = module.params['name'] - state = module.params['state'] - mappings = module.params['mappings'] - timeout = module.params['timeout'] - - zbx = None - # login to zabbix - try: - zbx = ZabbixAPI(server_url, timeout=timeout, user=http_login_user, passwd=http_login_password, - validate_certs=validate_certs) - zbx.login(login_user, login_password) - atexit.register(zbx.logout) - except Exception as e: - module.fail_json(msg="Failed to connect to Zabbix server: %s" % e) - - valuemap_exists, valuemap_object = check_if_valuemap_exists(module, zbx, name) - - parameters = construct_parameters( - name=name, - mappings=mappings - ) - - if valuemap_exists: - valuemap_id = valuemap_object['valuemapid'] - if state == 'absent': - if module.check_mode: - module.exit_json( - changed=True, - msg="Value map would have been deleted. Name: {name}, ID: {_id}".format( - name=name, - _id=valuemap_id - ) - ) - valuemap_id = delete_valuemap(module, zbx, valuemap_id) - module.exit_json( - changed=True, - msg="Value map deleted. Name: {name}, ID: {_id}".format( - name=name, - _id=valuemap_id - ) - ) - else: - params_to_update, diff = get_update_params(module, zbx, valuemap_object, **parameters) - if params_to_update == {}: - module.exit_json( - changed=False, - msg="Value map is up to date: {name}".format(name=name) - ) - else: - if module.check_mode: - module.exit_json( - changed=True, - diff=diff, - msg="Value map would have been updated. Name: {name}, ID: {_id}".format( - name=name, - _id=valuemap_id - ) - ) - valuemap_id = update_valuemap( - module, zbx, - valuemapid=valuemap_id, - **params_to_update - ) - module.exit_json( - changed=True, - diff=diff, - msg="Value map updated. Name: {name}, ID: {_id}".format( - name=name, - _id=valuemap_id - ) - ) - else: - if state == "absent": - module.exit_json(changed=False) - else: - if module.check_mode: - module.exit_json( - changed=True, - msg="Value map would have been created. Name: {name}, ID: {_id}".format( - name=name, - _id=valuemap_id - ) - ) - valuemap_id = create_valuemap(module, zbx, **parameters) - module.exit_json( - changed=True, - msg="Value map created: {name}, ID: {_id}".format( - name=name, - _id=valuemap_id - ) - ) - - -if __name__ == '__main__': - main() diff --git a/scripts/inventory/zabbix.ini b/scripts/inventory/zabbix.ini deleted file mode 100644 index ead19b62d5..0000000000 --- a/scripts/inventory/zabbix.ini +++ /dev/null @@ -1,20 +0,0 @@ -# Ansible Zabbix external inventory script settings -# - -[zabbix] - -# Server location -server = http://zabbix.example.com/zabbix - -# Login -username = admin -password = zabbix - -# Verify the server's SSL certificate -validate_certs = True - -# Read zabbix inventory per host -read_host_inventory = True - -# Set ansible_ssh_host based on first interface settings -use_host_interface = True \ No newline at end of file diff --git a/scripts/inventory/zabbix.py b/scripts/inventory/zabbix.py deleted file mode 100644 index acdf38e704..0000000000 --- a/scripts/inventory/zabbix.py +++ /dev/null @@ -1,196 +0,0 @@ -#!/usr/bin/env python - -# (c) 2013, Greg Buehler -# (c) 2018, Filippo Ferrazini -# -# This file is part of Ansible, -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -###################################################################### - -""" -Zabbix Server external inventory script. -======================================== - -Returns hosts and hostgroups from Zabbix Server. -If you want to run with --limit against a host group with space in the -name, use asterisk. For example --limit="Linux*servers". - -Configuration is read from `zabbix.ini`. - -Tested with Zabbix Server 2.0.6, 3.2.3 and 3.4. -""" - -from __future__ import print_function - -import os -import sys -import argparse -from ansible.module_utils.six.moves import configparser - -try: - from zabbix_api import ZabbixAPI -except Exception: - print("Error: Zabbix API library must be installed: pip install zabbix-api.", - file=sys.stderr) - sys.exit(1) - -import json - - -class ZabbixInventory(object): - - def read_settings(self): - config = configparser.SafeConfigParser() - conf_path = './zabbix.ini' - if not os.path.exists(conf_path): - conf_path = os.path.dirname(os.path.realpath(__file__)) + '/zabbix.ini' - if os.path.exists(conf_path): - config.read(conf_path) - # server - if config.has_option('zabbix', 'server'): - self.zabbix_server = config.get('zabbix', 'server') - - # login - if config.has_option('zabbix', 'username'): - self.zabbix_username = config.get('zabbix', 'username') - if config.has_option('zabbix', 'password'): - self.zabbix_password = config.get('zabbix', 'password') - # ssl certs - if config.has_option('zabbix', 'validate_certs'): - if config.get('zabbix', 'validate_certs') in ['false', 'False', False]: - self.validate_certs = False - # host inventory - if config.has_option('zabbix', 'read_host_inventory'): - if config.get('zabbix', 'read_host_inventory') in ['true', 'True', True]: - self.read_host_inventory = True - # host interface - if config.has_option('zabbix', 'use_host_interface'): - if config.get('zabbix', 'use_host_interface') in ['false', 'False', False]: - self.use_host_interface = False - - def read_cli(self): - parser = argparse.ArgumentParser() - parser.add_argument('--host') - parser.add_argument('--list', action='store_true') - self.options = parser.parse_args() - - def hoststub(self): - return { - 'hosts': [] - } - - def get_host(self, api, name): - api_query = {'output': 'extend', 'selectGroups': 'extend', "filter": {"host": [name]}} - if self.use_host_interface: - api_query['selectInterfaces'] = ['useip', 'ip', 'dns'] - if self.read_host_inventory: - api_query['selectInventory'] = "extend" - - data = {'ansible_ssh_host': name} - if self.use_host_interface or self.read_host_inventory: - try: - hosts_data = api.host.get(api_query)[0] - if 'interfaces' in hosts_data: - # use first interface only - if hosts_data['interfaces'][0]['useip'] == 0: - data['ansible_ssh_host'] = hosts_data['interfaces'][0]['dns'] - else: - data['ansible_ssh_host'] = hosts_data['interfaces'][0]['ip'] - if ('inventory' in hosts_data) and (hosts_data['inventory']): - data.update(hosts_data['inventory']) - except IndexError: - # Host not found in zabbix - pass - return data - - def get_list(self, api): - api_query = {'output': 'extend', 'selectGroups': 'extend'} - if self.use_host_interface: - api_query['selectInterfaces'] = ['useip', 'ip', 'dns'] - if self.read_host_inventory: - api_query['selectInventory'] = "extend" - - hosts_data = api.host.get(api_query) - data = {'_meta': {'hostvars': {}}} - - data[self.defaultgroup] = self.hoststub() - for host in hosts_data: - hostname = host['name'] - hostvars = dict() - data[self.defaultgroup]['hosts'].append(hostname) - - for group in host['groups']: - groupname = group['name'] - - if groupname not in data: - data[groupname] = self.hoststub() - - data[groupname]['hosts'].append(hostname) - if 'interfaces' in host: - # use first interface only - if host['interfaces'][0]['useip'] == 0: - hostvars['ansible_ssh_host'] = host['interfaces'][0]['dns'] - else: - hostvars['ansible_ssh_host'] = host['interfaces'][0]['ip'] - if ('inventory' in host) and (host['inventory']): - hostvars.update(host['inventory']) - data['_meta']['hostvars'][hostname] = hostvars - - return data - - def __init__(self): - - self.defaultgroup = 'group_all' - self.zabbix_server = None - self.zabbix_username = None - self.zabbix_password = None - self.validate_certs = True - self.read_host_inventory = False - self.use_host_interface = True - - self.meta = {} - - self.read_settings() - self.read_cli() - - if self.zabbix_server and self.zabbix_username: - try: - api = ZabbixAPI(server=self.zabbix_server, validate_certs=self.validate_certs) - api.login(user=self.zabbix_username, password=self.zabbix_password) - # zabbix_api tries to exit if it cannot parse what the zabbix server returned - # so we have to use SystemExit here - except (Exception, SystemExit) as e: - print("Error: Could not login to Zabbix server. Check your zabbix.ini.", file=sys.stderr) - sys.exit(1) - - if self.options.host: - data = self.get_host(api, self.options.host) - print(json.dumps(data, indent=2)) - - elif self.options.list: - data = self.get_list(api) - print(json.dumps(data, indent=2)) - - else: - print("usage: --list ..OR.. --host ", file=sys.stderr) - sys.exit(1) - - else: - print("Error: Configuration of server and credentials are required. See zabbix.ini.", file=sys.stderr) - sys.exit(1) - - -ZabbixInventory() diff --git a/tests/integration/targets/setup_zabbix/aliases b/tests/integration/targets/setup_zabbix/aliases deleted file mode 100644 index 3d0091e7a9..0000000000 --- a/tests/integration/targets/setup_zabbix/aliases +++ /dev/null @@ -1,5 +0,0 @@ -destructive -shippable/posix/group1 -skip/osx -skip/freebsd -skip/rhel diff --git a/tests/integration/targets/setup_zabbix/defaults/main.yml b/tests/integration/targets/setup_zabbix/defaults/main.yml deleted file mode 100644 index d6437a7568..0000000000 --- a/tests/integration/targets/setup_zabbix/defaults/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -db_name: 'zabbix' -db_user: 'zabbix' -db_password: 'fLhijUs3PgekNhwJ' - -zabbix_version: 4.4 -zabbix_apt_repository: 'deb http://repo.zabbix.com/zabbix/{{ zabbix_version }}/{{ ansible_distribution.lower() }}/ {{ ansible_distribution_release }} main' -zabbix_apt_repository_key: 'http://repo.zabbix.com/zabbix-official-repo.key' - -zabbix_packages: - - zabbix-server-mysql - - zabbix-frontend-php - - zabbix-apache-conf diff --git a/tests/integration/targets/setup_zabbix/handlers/main.yml b/tests/integration/targets/setup_zabbix/handlers/main.yml deleted file mode 100644 index a39556215a..0000000000 --- a/tests/integration/targets/setup_zabbix/handlers/main.yml +++ /dev/null @@ -1,15 +0,0 @@ -- name: remove zabbix repository - apt_repository: - repo: "{{ zabbix_apt_repository }}" - filename: zabbix - state: absent - -- name: remove zabbix packages - apt: - name: "{{ zabbix_packages }}" - state: absent - -- name: remove zabbix pip packages - pip: - name: zabbix-api - state: absent diff --git a/tests/integration/targets/setup_zabbix/meta/main.yml b/tests/integration/targets/setup_zabbix/meta/main.yml deleted file mode 100644 index 4aa170dc06..0000000000 --- a/tests/integration/targets/setup_zabbix/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - setup_mysql_db diff --git a/tests/integration/targets/setup_zabbix/tasks/main.yml b/tests/integration/targets/setup_zabbix/tasks/main.yml deleted file mode 100644 index 6d082fff21..0000000000 --- a/tests/integration/targets/setup_zabbix/tasks/main.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- include: setup.yml - when: ansible_os_family == 'Debian' diff --git a/tests/integration/targets/setup_zabbix/tasks/setup.yml b/tests/integration/targets/setup_zabbix/tasks/setup.yml deleted file mode 100644 index 2acf891424..0000000000 --- a/tests/integration/targets/setup_zabbix/tasks/setup.yml +++ /dev/null @@ -1,75 +0,0 @@ -- name: install zabbix repository key - apt_key: - url: '{{ zabbix_apt_repository_key }}' - state: present -- name: install zabbix repository - apt_repository: - repo: '{{ zabbix_apt_repository }}' - filename: zabbix - state: present - notify: remove zabbix repository -- name: check if dpkg is set to exclude specific destinations - stat: - path: /etc/dpkg/dpkg.cfg.d/excludes - register: dpkg_excludes -- name: ensure documentation installations are allowed for zabbix - lineinfile: - path: /etc/dpkg/dpkg.cfg.d/excludes - regexp: ^path-include=/usr/share/doc/zabbix*$ - line: path-include=/usr/share/doc/zabbix* - state: present - when: dpkg_excludes.stat.exists -- name: install zabbix apt dependencies - apt: - name: '{{ zabbix_packages }}' - state: latest - update_cache: true - notify: remove zabbix packages -- name: install zabbix-api python package - pip: - name: zabbix-api - state: latest - notify: remove zabbix pip packages -- name: create mysql user {{ db_user }} - mysql_user: - name: '{{ db_user }}' - password: '{{ db_password }}' - state: present - priv: '{{ db_name }}.*:ALL' - login_unix_socket: '{{ mysql_socket }}' -- name: import initial zabbix database - mysql_db: - name: '{{ db_name }}' - login_user: '{{ db_user }}' - login_password: '{{ db_password }}' - state: import - target: /usr/share/doc/zabbix-server-mysql/create.sql.gz -- name: deploy zabbix-server configuration - template: - src: zabbix_server.conf.j2 - dest: /etc/zabbix/zabbix_server.conf - owner: root - group: zabbix - mode: '0640' -- name: deploy zabbix web frontend configuration - template: - src: zabbix.conf.php.j2 - dest: /etc/zabbix/web/zabbix.conf.php - mode: '0644' -- name: Create proper run directory for zabbix-server - file: - path: /var/run/zabbix - state: directory - owner: zabbix - group: zabbix - mode: '0775' -- name: restart zabbix-server - service: - name: zabbix-server - state: restarted - enabled: true -- name: restart apache2 - service: - name: apache2 - state: restarted - enabled: true diff --git a/tests/integration/targets/setup_zabbix/templates/zabbix.conf.php.j2 b/tests/integration/targets/setup_zabbix/templates/zabbix.conf.php.j2 deleted file mode 100644 index ad0a8328d2..0000000000 --- a/tests/integration/targets/setup_zabbix/templates/zabbix.conf.php.j2 +++ /dev/null @@ -1,20 +0,0 @@ - diff --git a/tests/integration/targets/setup_zabbix/templates/zabbix_server.conf.j2 b/tests/integration/targets/setup_zabbix/templates/zabbix_server.conf.j2 deleted file mode 100644 index f4c201af59..0000000000 --- a/tests/integration/targets/setup_zabbix/templates/zabbix_server.conf.j2 +++ /dev/null @@ -1,7 +0,0 @@ -PidFile=/var/run/zabbix/zabbix_server.pid -LogFile=/tmp/zabbix_server.log -DBName={{ db_name }} -DBUser={{ db_user }} -DBPassword={{ db_password }} -Timeout=4 -LogSlowQueries=3000 diff --git a/tests/integration/targets/zabbix_host/aliases b/tests/integration/targets/zabbix_host/aliases deleted file mode 100644 index f37e6c6fb0..0000000000 --- a/tests/integration/targets/zabbix_host/aliases +++ /dev/null @@ -1,6 +0,0 @@ -destructive -shippable/posix/group1 -skip/aix -skip/osx -skip/freebsd -skip/rhel diff --git a/tests/integration/targets/zabbix_host/defaults/main.yml b/tests/integration/targets/zabbix_host/defaults/main.yml deleted file mode 100644 index 5482107368..0000000000 --- a/tests/integration/targets/zabbix_host/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -zabbix_server_url: http://127.0.0.1/zabbix/ -zabbix_login_user: Admin -zabbix_login_password: zabbix diff --git a/tests/integration/targets/zabbix_host/meta/main.yml b/tests/integration/targets/zabbix_host/meta/main.yml deleted file mode 100644 index d30074784c..0000000000 --- a/tests/integration/targets/zabbix_host/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - setup_zabbix diff --git a/tests/integration/targets/zabbix_host/tasks/main.yml b/tests/integration/targets/zabbix_host/tasks/main.yml deleted file mode 100644 index 914c1e5fcf..0000000000 --- a/tests/integration/targets/zabbix_host/tasks/main.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -# setup stuff not testing zabbix_host -- block: - - include: zabbix_host_setup.yml - - # zabbix_host module tests - - include: zabbix_host_tests.yml - - # documentation example tests - - include: zabbix_host_doc.yml - - # tear down stuff set up earlier - - include: zabbix_host_teardown.yml - - when: - - ansible_distribution == 'Ubuntu' diff --git a/tests/integration/targets/zabbix_host/tasks/zabbix_host_doc.yml b/tests/integration/targets/zabbix_host/tasks/zabbix_host_doc.yml deleted file mode 100644 index 40f702bb45..0000000000 --- a/tests/integration/targets/zabbix_host/tasks/zabbix_host_doc.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -# These two tests are close to documentation example - -- name: Create a new host or update an existing host's info - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost1 - visible_name: ExampleName - description: My ExampleHost Description - host_groups: - - Linux servers - - Zabbix servers - link_templates: - - Template App IMAP Service - - Template App NTP Service - 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 - ipmi_authtype: 2 - ipmi_privilege: 4 - ipmi_username: username - ipmi_password: password - interfaces: - - type: 1 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "10050" - - type: 4 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "12345" - macros: - - macro: '{$EXAMPLEMACRO}' - value: ExampleMacroValue - - macro: EXAMPLEMACRO2 - value: ExampleMacroValue2 - description: Example desc that work only with Zabbix 4.4 and higher - tags: - - tag: ExampleHostsTag - - tag: ExampleHostsTag2 - value: ExampleTagValue - register: zabbix_host1 - -- name: Update an existing host's tls settings - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost2 - visible_name: ExampleName2 - interfaces: - - type: 1 - main: 1 - useip: 1 - ip: 10.1.1.2 - dns: "" - port: "10050" - host_groups: - - Linux servers - tls_psk_identity: test - tls_connect: 2 - tls_psk: 123456789abcdef123456789abcdef12 - register: zabbix_host2 - -- name: expect both to succeed - assert: - that: - - "zabbix_host1 is changed" - - "zabbix_host2 is changed" diff --git a/tests/integration/targets/zabbix_host/tasks/zabbix_host_setup.yml b/tests/integration/targets/zabbix_host/tasks/zabbix_host_setup.yml deleted file mode 100644 index 498a725f29..0000000000 --- a/tests/integration/targets/zabbix_host/tasks/zabbix_host_setup.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -# set up a zabbix proxy to test zabbix_host with - -- name: Create a new proxy - zabbix_proxy: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - proxy_name: ExampleProxy - description: ExampleProxy - status: active - state: present - interface: - type: 0 - main: 1 - useip: 1 - ip: 10.5.6.7 - dns: "" - port: 10050 - register: zabbix_proxy diff --git a/tests/integration/targets/zabbix_host/tasks/zabbix_host_teardown.yml b/tests/integration/targets/zabbix_host/tasks/zabbix_host_teardown.yml deleted file mode 100644 index 1d76c516c7..0000000000 --- a/tests/integration/targets/zabbix_host/tasks/zabbix_host_teardown.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -# remove zabbix_proxy (hopefully) created earlier - -- name: remove proxy - zabbix_proxy: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - proxy_name: ExampleProxy - state: absent diff --git a/tests/integration/targets/zabbix_host/tasks/zabbix_host_tests.yml b/tests/integration/targets/zabbix_host/tasks/zabbix_host_tests.yml deleted file mode 100644 index 63be018988..0000000000 --- a/tests/integration/targets/zabbix_host/tasks/zabbix_host_tests.yml +++ /dev/null @@ -1,1169 +0,0 @@ ---- - -- name: "test: create host with many options set" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - visible_name: ExampleName - description: My ExampleHost Description - host_groups: - - Linux servers - - Zabbix servers - link_templates: - - Template App IMAP Service - - Template App NTP Service - 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: "" - port: "10050" - - type: 1 - main: 0 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "{$MACRO}" - - type: 4 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "12345" - proxy: ExampleProxy - tls_psk_identity: test - tls_connect: 2 - tls_psk: 123456789abcdef123456789abcdef12 - macros: - - macro: MACRO1 - value: test1 - - macro: '{$MACRO2}' - value: test2 - tags: - - tag: Tag1 - - tag: Tag2 - value: test2 - register: zabbix_host1 - -- name: expect to succeed and that things changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: try to create the same host with the same settings" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - visible_name: ExampleName - description: My ExampleHost Description - host_groups: - - Linux servers - - Zabbix servers - link_templates: - - Template App IMAP Service - - Template App NTP Service - 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: "" - port: "10050" - - type: 1 - main: 0 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "{$MACRO}" - - type: 4 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "12345" - proxy: ExampleProxy - tls_psk_identity: test - tls_connect: 2 - tls_psk: 123456789abcdef123456789abcdef12 - macros: - - macro: MACRO1 - value: test1 - - macro: '{$MACRO2}' - value: test2 - tags: - - tag: Tag1 - - tag: Tag2 - value: test2 - register: zabbix_host1 - -- name: updating with same values should be idempotent - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: try to create the same host with the same settings and force false" - zabbix_host: - force: false - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - visible_name: ExampleName - description: My ExampleHost Description - host_groups: - - Linux servers - - Zabbix servers - link_templates: - - Template App IMAP Service - - Template App NTP Service - 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: "" - port: "10050" - - type: 1 - main: 0 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "{$MACRO}" - - type: 4 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "12345" - proxy: ExampleProxy - tls_psk_identity: test - tls_connect: 2 - tls_psk: 123456789abcdef123456789abcdef12 - register: zabbix_host1 - -- name: updating with same values and force false should be idempotent - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: try to create the same host changing one parameter in the inventory with force false" - zabbix_host: - force: false - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - visible_name: ExampleName - description: My ExampleHost Description - host_groups: - - Linux servers - - Zabbix servers - link_templates: - - Template App IMAP Service - - Template App NTP Service - 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-modified - interfaces: - - type: 1 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "10050" - - type: 1 - main: 0 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "{$MACRO}" - - type: 4 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "12345" - proxy: ExampleProxy - tls_psk_identity: test - tls_connect: 2 - tls_psk: 123456789abcdef123456789abcdef12 - register: zabbix_host1 - -- name: changing the value of an already defined inventory should work and mark task as changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change visible_name" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - visible_name: "ExampleName Changed" - register: zabbix_host1 - -- name: expect to succeed and that things changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change visible_name (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - visible_name: "ExampleName Changed" - register: zabbix_host1 - -- name: updating with same values should be idempotent - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change description" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - description: "My ExampleHost Description Changed" - register: zabbix_host1 - -- name: expect to succeed and that things changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change description (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - description: "My ExampleHost Description Changed" - register: zabbix_host1 - -- name: updating with same values should be idempotent - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change host groups (adding one group)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - host_groups: - - Linux servers - - Zabbix servers - - Virtual machines - register: zabbix_host1 - -- name: expect to succeed and that things changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host groups (remove one group)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - host_groups: - - Linux servers - - Zabbix servers - register: zabbix_host1 - -- name: expect to succeed and that things changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host groups (add one group using force=no)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - host_groups: - - Virtual machines - force: no - register: zabbix_host1 - -- name: expect to succeed and that things changed - assert: - that: - - "zabbix_host1 is changed" - - -- name: "test: change host groups (check whether we are at three groups)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - host_groups: - - Linux servers - - Zabbix servers - - Virtual machines - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change host groups (attempt to remove all host groups)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - host_groups: - - - register: zabbix_host1 - ignore_errors: yes - -- name: expect to fail - assert: - that: - - "zabbix_host1 is failed" - -- name: "test: change host linked templates (same as before)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - link_templates: - - Template App IMAP Service - - Template App NTP Service - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change host linked templates (add one template)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - link_templates: - - Template App IMAP Service - - Template App NTP Service - - Template App HTTP Service - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host linked templates (add one template, using force=no)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - link_templates: - - Template App LDAP Service - force: no - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host linked templates (make sure we are at 4 templates)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - link_templates: - - Template App IMAP Service - - Template App NTP Service - - Template App HTTP Service - - Template App LDAP Service - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change host linked templates (remove all templates)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - link_templates: - - - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host linked templates (check we have no templates left)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - link_templates: - - - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change host status" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - status: disabled - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host status (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - status: disabled - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change host inventory mode" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - inventory_mode: automatic - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host inventory mode" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - inventory_mode: automatic - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change host inventory data (one field)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - inventory_zabbix: - tag: test-tag-two - alias: test-alias - notes: "Special Informations: test-info" - location: test-location - site_rack: test-rack - os: test-os - hardware: test-hw - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host inventory data (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - inventory_zabbix: - tag: test-tag-two - alias: test-alias - notes: "Special Informations: test-info" - location: test-location - site_rack: test-rack - os: test-os - hardware: test-hw - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: remove host proxy" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - proxy: '' - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add host proxy" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - proxy: ExampleProxy - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add host proxy (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - proxy: ExampleProxy - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change tls settings" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - tls_psk_identity: test2 - tls_connect: 4 - tls_accept: 7 - tls_psk: 123456789abcdef123456789abcdef13 - tls_issuer: AcmeCorp - tls_subject: AcmeCorpServer - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change tls settings (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - tls_psk_identity: test2 - tls_connect: 4 - tls_accept: 7 - tls_psk: 123456789abcdef123456789abcdef13 - tls_issuer: AcmeCorp - tls_subject: AcmeCorpServer - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change interface settings (remove one)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - interfaces: - - type: 1 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "10050" - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change interface settings (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - interfaces: - - type: 1 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "10050" - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: change interface settings (add one interface using force=no)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - interfaces: - - type: 4 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "12345" - force: no - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change interface settings (verify that we are at two interfaces)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - interfaces: - - type: 1 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "10050" - - type: 4 - main: 1 - useip: 1 - ip: 10.1.1.1 - dns: "" - port: "12345" - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "not zabbix_host1 is changed" - -- name: "test: add IPMI settings" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - ipmi_authtype: 2 - ipmi_privilege: 4 - ipmi_username: username - ipmi_password: password - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add IPMI settings again" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - ipmi_authtype: 2 - ipmi_privilege: 4 - ipmi_username: username - ipmi_password: password - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: verify that an empty change is idempotent" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: IPMI set default values" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - ipmi_authtype: -1 - ipmi_privilege: 2 - ipmi_username: "" - ipmi_password: "" - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: IPMI set default values (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - ipmi_authtype: -1 - ipmi_privilege: 2 - ipmi_username: "" - ipmi_password: "" - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: change host inventory mode to disabled" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - inventory_mode: disabled - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: change host inventory mode to manual" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - inventory_mode: manual - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add new set of user macros to the host" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: - - macro: '{$NEWMACRO1}' - value: test123 - - macro: NEWMACRO2 - value: abc - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add new set of user macros to the host (again - lowercase)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: - - macro: '{$newmacro1}' - value: test123 - - macro: newmacro2 - value: abc - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: update one of the user macros present on the host" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: - - macro: '{$NEWMACRO1}' - value: test1234 - - macro: NEWMACRO2 - value: abc - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: update one of the user macros with description" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: - - macro: '{$NEWMACRO1}' - value: test1234 - description: Example Description - - macro: NEWMACRO2 - value: abc - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: update one of the user macros with description (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: - - macro: '{$NEWMACRO1}' - value: test1234 - description: Example Description - - macro: NEWMACRO2 - value: abc - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: update one of the user macros by removing description" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: - - macro: '{$NEWMACRO1}' - value: test1234 - - macro: NEWMACRO2 - value: abc - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add user macro while keeping previous ones with force=no" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - force: no - macros: - - macro: '{$NEWMACRO3}' - value: testing - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add the same user macros (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: - - macro: '{$NEWMACRO1}' - value: test1234 - - macro: NEWMACRO2 - value: abc - - macro: '{$NEWMACRO3}' - value: testing - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: wipe out all of the user macros" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: [] - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: wipe out all of the user macros (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - macros: [] - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: add new set of tags to the host" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - tags: - - tag: NEWTAG1 - - tag: NewTag2 - value: abc - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add new set of tags to the host (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - tags: - - tag: NEWTAG1 - - tag: NewTag2 - value: abc - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: update one of the tags present on the host" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - tags: - - tag: NEWTAG1 - - tag: NewTag2 - value: abcd - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add tag while keeping previous ones with force=no" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - force: no - tags: - - tag: newtag3 - value: testing - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: add the same tags (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - tags: - - tag: NEWTAG1 - - tag: NewTag2 - value: abcd - - tag: newtag3 - value: testing - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: wipe out all of the tags" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - tags: [] - register: zabbix_host1 - -- name: expect to succeed and that things have changed - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: wipe out all of the tags (again)" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - tags: [] - register: zabbix_host1 - -- name: expect to succeed and that things have not changed - assert: - that: - - "zabbix_host1 is not changed" - -- name: "test: attempt to delete host created earlier" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - state: absent - register: zabbix_host1 - -- name: deleting a host is a change, right? - assert: - that: - - "zabbix_host1 is changed" - -- name: "test: attempt deleting a non-existant host" - zabbix_host: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - host_name: ExampleHost - state: absent - register: zabbix_host1 - -- name: deleting a non-existant host is not a change, right? - assert: - that: - - "not zabbix_host1 is changed" diff --git a/tests/integration/targets/zabbix_template/aliases b/tests/integration/targets/zabbix_template/aliases deleted file mode 100644 index f37e6c6fb0..0000000000 --- a/tests/integration/targets/zabbix_template/aliases +++ /dev/null @@ -1,6 +0,0 @@ -destructive -shippable/posix/group1 -skip/aix -skip/osx -skip/freebsd -skip/rhel diff --git a/tests/integration/targets/zabbix_template/defaults/main.yml b/tests/integration/targets/zabbix_template/defaults/main.yml deleted file mode 100644 index 5482107368..0000000000 --- a/tests/integration/targets/zabbix_template/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -zabbix_server_url: http://127.0.0.1/zabbix/ -zabbix_login_user: Admin -zabbix_login_password: zabbix diff --git a/tests/integration/targets/zabbix_template/meta/main.yml b/tests/integration/targets/zabbix_template/meta/main.yml deleted file mode 100644 index d30074784c..0000000000 --- a/tests/integration/targets/zabbix_template/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - setup_zabbix diff --git a/tests/integration/targets/zabbix_template/tasks/main.yml b/tests/integration/targets/zabbix_template/tasks/main.yml deleted file mode 100644 index ccabc31d9a..0000000000 --- a/tests/integration/targets/zabbix_template/tasks/main.yml +++ /dev/null @@ -1,159 +0,0 @@ ---- -- when: - - ansible_distribution == 'Ubuntu' - block: - - name: Create a new Zabbix template. - zabbix_template: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - template_groups: - - 'Linux servers' - - 'Templates' - state: present - register: create_zabbix_template_result - - - assert: - that: - - create_zabbix_template_result.changed is sameas true - - - name: Gather Zabbix template infomation. - zabbix_template_info: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - format: json - register: gather_template_result - - - assert: - that: - - gather_template_result.template_json.zabbix_export.groups.0.name == 'Linux servers' - - gather_template_result.template_json.zabbix_export.groups.1.name == 'Templates' - - - name: Add link_templates to Zabbix template. - zabbix_template: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - template_groups: - - 'Linux servers' - - 'Templates' - link_templates: - - 'Template App Zabbix Proxy' - - 'Template Module Zabbix agent' - state: present - register: update_zabbix_template_result - - - assert: - that: - - create_zabbix_template_result.changed is sameas true - - - name: Gather Zabbix template infomation. - zabbix_template_info: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - format: json - register: gather_template_result - - - assert: - that: - - gather_template_result.template_json.zabbix_export.groups.0.name == 'Linux servers' - - gather_template_result.template_json.zabbix_export.groups.1.name == 'Templates' - - gather_template_result.template_json.zabbix_export.templates.0.templates.0.name == 'Template App Zabbix Proxy' - - gather_template_result.template_json.zabbix_export.templates.0.templates.1.name == 'Template Module Zabbix agent' - - - name: Add macros to Zabbix template. - zabbix_template: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - template_groups: - - 'Linux servers' - - 'Templates' - link_templates: - - 'Template App Zabbix Proxy' - - 'Template Module Zabbix agent' - macros: - - macro: '{$EXAMPLE_MACRO1}' - value: 1000 - - macro: '{$EXAMPLE_MACRO2}' - value: 'text' - state: present - register: update_zabbix_template_result - - - assert: - that: - - create_zabbix_template_result.changed is sameas true - - - name: Gather Zabbix template infomation. - zabbix_template_info: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - format: json - register: gather_template_result - - - assert: - that: - - gather_template_result.template_json.zabbix_export.groups.0.name == 'Linux servers' - - gather_template_result.template_json.zabbix_export.groups.1.name == 'Templates' - - gather_template_result.template_json.zabbix_export.templates.0.templates.0.name == 'Template App Zabbix Proxy' - - gather_template_result.template_json.zabbix_export.templates.0.templates.1.name == 'Template Module Zabbix agent' - - gather_template_result.template_json.zabbix_export.templates.0.macros.0.macro == '{$EXAMPLE_MACRO1}' - - gather_template_result.template_json.zabbix_export.templates.0.macros.0.value == '1000' - - gather_template_result.template_json.zabbix_export.templates.0.macros.1.macro == '{$EXAMPLE_MACRO2}' - - gather_template_result.template_json.zabbix_export.templates.0.macros.1.value == 'text' - - - name: Dump Zabbix template to XML format. - zabbix_template: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - dump_format: xml - state: dump - register: template_dump_result - - - debug: var=template_dump_result - - - assert: - that: - - template_dump_result.deprecations is defined - - template_dump_result.deprecations.0.version == '2.14' - - - name: Dump Zabbix template to JSON format. - zabbix_template: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - dump_format: json - state: dump - register: template_dump_result - - - debug: var=template_dump_result - - - assert: - that: - - template_dump_result.deprecations is defined - - template_dump_result.deprecations.0.version == '2.14' - - - name: Delete Zabbix template. - zabbix_template: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - template_name: ExampleHost - state: absent - register: delete_zabbix_template_result - - - assert: - that: - - delete_zabbix_template_result.changed is sameas true diff --git a/tests/integration/targets/zabbix_user/aliases b/tests/integration/targets/zabbix_user/aliases deleted file mode 100644 index cc949990c8..0000000000 --- a/tests/integration/targets/zabbix_user/aliases +++ /dev/null @@ -1,6 +0,0 @@ -destructive -shippable/posix/group1 -skip/osx -skip/freebsd -skip/rhel -skip/aix diff --git a/tests/integration/targets/zabbix_user/defaults/main.yml b/tests/integration/targets/zabbix_user/defaults/main.yml deleted file mode 100644 index 5482107368..0000000000 --- a/tests/integration/targets/zabbix_user/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -zabbix_server_url: http://127.0.0.1/zabbix/ -zabbix_login_user: Admin -zabbix_login_password: zabbix diff --git a/tests/integration/targets/zabbix_user/meta/main.yml b/tests/integration/targets/zabbix_user/meta/main.yml deleted file mode 100644 index d30074784c..0000000000 --- a/tests/integration/targets/zabbix_user/meta/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -dependencies: - - setup_zabbix diff --git a/tests/integration/targets/zabbix_user/tasks/main.yml b/tests/integration/targets/zabbix_user/tasks/main.yml deleted file mode 100644 index b72337bc87..0000000000 --- a/tests/integration/targets/zabbix_user/tasks/main.yml +++ /dev/null @@ -1,912 +0,0 @@ ---- -- when: - - ansible_distribution == 'Ubuntu' - block: - # New user create test from here - - name: test - Create a new Zabbix user with check_mode and diff - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - passwd: password - check_mode: yes - diff: yes - register: create_zabbix_user_result - - - assert: - that: - - create_zabbix_user_result.changed is sameas true - - - name: test - Create a new Zabbix user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - passwd: password - register: create_zabbix_user_result - - - assert: - that: - - create_zabbix_user_result.changed is sameas true - - - name: test - Create a new Zabbix user(again) - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - passwd: password - register: create_zabbix_user_result - - - assert: - that: - - not create_zabbix_user_result.changed is sameas true - - # Parameter add test from here to existing user - - name: test - Add user group to existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: password - register: add_usergroup_to_existing_user_result - - - assert: - that: - - add_usergroup_to_existing_user_result.changed is sameas true - - - name: test - Add user medias(Email) to existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: password - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - register: add_user_medias_to_existing_user_result - - - assert: - that: - - add_user_medias_to_existing_user_result.changed is sameas true - - - name: test - Add multiple user medias(Email and SMS) to existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: password - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: add_user_medias_to_existing_user_result - - - assert: - that: - - add_user_medias_to_existing_user_result.changed is sameas true - - # Existing parameter updates test from here - - name: test - Update password parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - override_passwd: yes - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_password_parameter_existing_user_result - - - assert: - that: - - update_password_parameter_existing_user_result.changed is sameas true - - - name: test - Update autologin parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologin: yes - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_autologin_parameter_existing_user_result - - - assert: - that: - - update_autologin_parameter_existing_user_result.changed is sameas true - - - name: test - Update autologout parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_autologout_parameter_existing_user_result - - - assert: - that: - - update_autologout_parameter_existing_user_result.changed is sameas true - - - name: test - Update refresh parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_refresh_parameter_existing_user_result - - - assert: - that: - - update_refresh_parameter_existing_user_result.changed is sameas true - - - name: test - Update rows_per_page parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_rows_per_page_parameter_existing_user_result - - - assert: - that: - - update_rows_per_page_parameter_existing_user_result.changed is sameas true - - - name: test - Update after_login_url parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_after_login_url_parameter_existing_user_result - - - assert: - that: - - update_after_login_url_parameter_existing_user_result.changed is sameas true - - - name: test - Update theme parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: "{{ item }}" - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - loop: - - blue-theme - - dark-theme - register: update_theme_parameter_existing_user_result - - - assert: - that: - - item.changed is sameas true - loop: "{{ update_theme_parameter_existing_user_result.results }}" - - - name: test - Update type parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: "{{ item }}" - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - loop: - - Zabbix admin - - Zabbix super admin - register: update_type_parameter_existing_user_result - - - assert: - that: - - item.changed is sameas true - loop: "{{ update_type_parameter_existing_user_result.results }}" - - - name: test - Update lang parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example - surname: test - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: Zabbix super admin - lang: en_US - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_lang_parameter_existing_user_result - - - assert: - that: - - update_lang_parameter_existing_user_result.changed is sameas true - - - name: test - Update name and surname parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example2 - surname: test2 - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: Zabbix super admin - lang: en_US - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_name_and_surname_parameter_existing_user_result - - - assert: - that: - - update_name_and_surname_parameter_existing_user_result.changed is sameas true - - - name: test - Update lang parameter for existing user with check_mode and diff - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example2 - surname: test2 - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: Zabbix super admin - lang: en_GB - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - check_mode: yes - diff: yes - register: update_lang_parameter_existing_user_with_check_mode_diff_result - - - assert: - that: - - update_lang_parameter_existing_user_with_check_mode_diff_result.changed is sameas true - - - name: test - Update lang parameter for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example2 - surname: test2 - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: Zabbix super admin - lang: en_GB - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_lang_parameter_existing_user_result - - - assert: - that: - - update_lang_parameter_existing_user_result.changed is sameas true - - - name: test - Update lang parameter for existing user(again) - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example2 - surname: test2 - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: Zabbix super admin - lang: en_GB - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - - mediatype: SMS - sendto: example@example.com - period: 1-5,01:00-23:00 - severity: - not_classified: no - information: yes - warning: yes - average: no - high: yes - disaster: yes - active: yes - register: update_lang_parameter_existing_user_result - - - assert: - that: - - not update_lang_parameter_existing_user_result.changed is sameas true - - # Parameter delete test from here from existing user - - name: test - Delete user medias(SNS) for existing user with check_mode and diff - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example2 - surname: test2 - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: Zabbix super admin - lang: en_GB - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - check_mode: yes - diff: yes - register: delete_user_medias_existing_user_result - - - assert: - that: - - delete_user_medias_existing_user_result.changed is sameas true - - - name: test - Delete user medias(SNS) for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example2 - surname: test2 - usrgrps: - - Guests - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: Zabbix super admin - lang: en_GB - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - register: delete_user_medias_existing_user_result - - - assert: - that: - - delete_user_medias_existing_user_result.changed is sameas true - - - name: test - Delete user group for existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - name: example2 - surname: test2 - usrgrps: - - Zabbix administrators - passwd: update_password - autologout: 500 - refresh: 60 - rows_per_page: 300 - after_login_url: http://example.com - theme: dark-theme - type: Zabbix super admin - lang: en_GB - user_medias: - - mediatype: Email - sendto: example@example.com - period: 1-7,00:00-24:00 - severity: - not_classified: no - information: yes - warning: yes - average: yes - high: yes - disaster: yes - active: yes - register: delete_user_group_existing_user_result - - - assert: - that: - - delete_user_group_existing_user_result.changed is sameas true - - - name: test - Delete existing user with check_mode and diff - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - usrgrps: - - Zabbix administrators - passwd: update_password - state: absent - check_mode: yes - diff: yes - register: delete_existing_user_result - - - assert: - that: - - delete_existing_user_result.changed is sameas true - - - name: test - Delete existing user - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - usrgrps: - - Zabbix administrators - passwd: update_password - state: absent - register: delete_existing_user_result - - - assert: - that: - - delete_existing_user_result.changed is sameas true - - - name: test - Delete existing user(again) - zabbix_user: - server_url: "{{ zabbix_server_url }}" - login_user: "{{ zabbix_login_user }}" - login_password: "{{ zabbix_login_password }}" - alias: example1 - usrgrps: - - Zabbix administrators - passwd: update_password - state: absent - register: delete_existing_user_result - - - assert: - that: - - not delete_existing_user_result.changed is sameas true diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index c1c888333f..a08dbbf928 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -85,8 +85,6 @@ scripts/inventory/vagrant.py future-import-boilerplate scripts/inventory/vagrant.py metaclass-boilerplate scripts/inventory/vbox.py future-import-boilerplate scripts/inventory/vbox.py metaclass-boilerplate -scripts/inventory/zabbix.py future-import-boilerplate -scripts/inventory/zabbix.py metaclass-boilerplate scripts/inventory/zone.py future-import-boilerplate scripts/inventory/zone.py metaclass-boilerplate scripts/vault/azure_vault.py future-import-boilerplate @@ -1106,32 +1104,6 @@ plugins/modules/monitoring/statusio_maintenance.py validate-modules:doc-missing- plugins/modules/monitoring/statusio_maintenance.py validate-modules:parameter-list-no-elements plugins/modules/monitoring/statusio_maintenance.py validate-modules:parameter-type-not-in-doc plugins/modules/monitoring/uptimerobot.py validate-modules:doc-missing-type -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:doc-choices-do-not-match-spec -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:doc-default-does-not-match-spec -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:doc-required-mismatch -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:invalid-argument-name -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:missing-suboption-docs -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:nonexistent-parameter-documented -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:parameter-type-not-in-doc -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:undocumented-parameter -plugins/modules/monitoring/zabbix/zabbix_group.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_group.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_group_info.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_group_info.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_host.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_host.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_host_info.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_host_info.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_maintenance.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_maintenance.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_mediatype.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_mediatype.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_template.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_template.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_user.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_user.py validate-modules:parameter-list-no-elements plugins/modules/net_tools/cloudflare_dns.py validate-modules:parameter-type-not-in-doc plugins/modules/net_tools/dnsimple.py validate-modules:parameter-list-no-elements plugins/modules/net_tools/dnsmadeeasy.py validate-modules:doc-missing-type @@ -3543,8 +3515,6 @@ plugins/doc_fragments/vultr.py future-import-boilerplate plugins/doc_fragments/vultr.py metaclass-boilerplate plugins/doc_fragments/xenserver.py future-import-boilerplate plugins/doc_fragments/xenserver.py metaclass-boilerplate -plugins/doc_fragments/zabbix.py future-import-boilerplate -plugins/doc_fragments/zabbix.py metaclass-boilerplate tests/integration/targets/inventory_kubevirt/inventory_diff.py future-import-boilerplate tests/integration/targets/inventory_kubevirt/inventory_diff.py metaclass-boilerplate tests/integration/targets/inventory_kubevirt/server.py future-import-boilerplate @@ -3814,4 +3784,4 @@ tests/unit/modules/web_infrastructure/test_apache2_module.py metaclass-boilerpla tests/unit/modules/web_infrastructure/test_jenkins_plugin.py future-import-boilerplate tests/unit/modules/web_infrastructure/test_jenkins_plugin.py metaclass-boilerplate tests/unit/plugins/httpapi/test_ftd.py future-import-boilerplate -tests/unit/plugins/httpapi/test_ftd.py metaclass-boilerplate \ No newline at end of file +tests/unit/plugins/httpapi/test_ftd.py metaclass-boilerplate diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index c1c888333f..a08dbbf928 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -85,8 +85,6 @@ scripts/inventory/vagrant.py future-import-boilerplate scripts/inventory/vagrant.py metaclass-boilerplate scripts/inventory/vbox.py future-import-boilerplate scripts/inventory/vbox.py metaclass-boilerplate -scripts/inventory/zabbix.py future-import-boilerplate -scripts/inventory/zabbix.py metaclass-boilerplate scripts/inventory/zone.py future-import-boilerplate scripts/inventory/zone.py metaclass-boilerplate scripts/vault/azure_vault.py future-import-boilerplate @@ -1106,32 +1104,6 @@ plugins/modules/monitoring/statusio_maintenance.py validate-modules:doc-missing- plugins/modules/monitoring/statusio_maintenance.py validate-modules:parameter-list-no-elements plugins/modules/monitoring/statusio_maintenance.py validate-modules:parameter-type-not-in-doc plugins/modules/monitoring/uptimerobot.py validate-modules:doc-missing-type -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:doc-choices-do-not-match-spec -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:doc-default-does-not-match-spec -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:doc-required-mismatch -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:invalid-argument-name -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:missing-suboption-docs -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:nonexistent-parameter-documented -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:parameter-type-not-in-doc -plugins/modules/monitoring/zabbix/zabbix_action.py validate-modules:undocumented-parameter -plugins/modules/monitoring/zabbix/zabbix_group.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_group.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_group_info.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_group_info.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_host.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_host.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_host_info.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_host_info.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_maintenance.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_maintenance.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_mediatype.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_mediatype.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_template.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_template.py validate-modules:parameter-list-no-elements -plugins/modules/monitoring/zabbix/zabbix_user.py validate-modules:doc-elements-mismatch -plugins/modules/monitoring/zabbix/zabbix_user.py validate-modules:parameter-list-no-elements plugins/modules/net_tools/cloudflare_dns.py validate-modules:parameter-type-not-in-doc plugins/modules/net_tools/dnsimple.py validate-modules:parameter-list-no-elements plugins/modules/net_tools/dnsmadeeasy.py validate-modules:doc-missing-type @@ -3543,8 +3515,6 @@ plugins/doc_fragments/vultr.py future-import-boilerplate plugins/doc_fragments/vultr.py metaclass-boilerplate plugins/doc_fragments/xenserver.py future-import-boilerplate plugins/doc_fragments/xenserver.py metaclass-boilerplate -plugins/doc_fragments/zabbix.py future-import-boilerplate -plugins/doc_fragments/zabbix.py metaclass-boilerplate tests/integration/targets/inventory_kubevirt/inventory_diff.py future-import-boilerplate tests/integration/targets/inventory_kubevirt/inventory_diff.py metaclass-boilerplate tests/integration/targets/inventory_kubevirt/server.py future-import-boilerplate @@ -3814,4 +3784,4 @@ tests/unit/modules/web_infrastructure/test_apache2_module.py metaclass-boilerpla tests/unit/modules/web_infrastructure/test_jenkins_plugin.py future-import-boilerplate tests/unit/modules/web_infrastructure/test_jenkins_plugin.py metaclass-boilerplate tests/unit/plugins/httpapi/test_ftd.py future-import-boilerplate -tests/unit/plugins/httpapi/test_ftd.py metaclass-boilerplate \ No newline at end of file +tests/unit/plugins/httpapi/test_ftd.py metaclass-boilerplate