From a9aa1053a89ccd317d36ac5cede2854742ea7cd2 Mon Sep 17 00:00:00 2001 From: Dusan Matejka Date: Thu, 29 Nov 2018 20:38:32 +0100 Subject: [PATCH] zabbix_template: fixed idempotency issues (#49188) --- .../48730-zabbix_hostmacro-fixes.yaml | 4 ++ ...49188-zabbix_template-fix-idempotency.yaml | 3 ++ .../monitoring/zabbix/zabbix_template.py | 51 +++++++++++-------- 3 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 changelogs/fragments/48730-zabbix_hostmacro-fixes.yaml create mode 100644 changelogs/fragments/49188-zabbix_template-fix-idempotency.yaml diff --git a/changelogs/fragments/48730-zabbix_hostmacro-fixes.yaml b/changelogs/fragments/48730-zabbix_hostmacro-fixes.yaml new file mode 100644 index 00000000000..a4816301670 --- /dev/null +++ b/changelogs/fragments/48730-zabbix_hostmacro-fixes.yaml @@ -0,0 +1,4 @@ +--- +bugfixes: + - zabbix_hostmacro - Added missing validate_certs logic for running module against Zabbix servers with untrused SSL certificates (https://github.com/ansible/ansible/issues/47611) + - zabbix_hostmacro - Fixed support for user macros with context (https://github.com/ansible/ansible/issues/46953) diff --git a/changelogs/fragments/49188-zabbix_template-fix-idempotency.yaml b/changelogs/fragments/49188-zabbix_template-fix-idempotency.yaml new file mode 100644 index 00000000000..0b2a06ce481 --- /dev/null +++ b/changelogs/fragments/49188-zabbix_template-fix-idempotency.yaml @@ -0,0 +1,3 @@ +--- +bugfixes: + - zabbix_template - Fixed idempotency of the module when using ``link_templates``, ``macros`` or ``template_json`` options (https://github.com/ansible/ansible/issues/48337) diff --git a/lib/ansible/modules/monitoring/zabbix/zabbix_template.py b/lib/ansible/modules/monitoring/zabbix/zabbix_template.py index 7b1dd499032..67a2b8b0e89 100644 --- a/lib/ansible/modules/monitoring/zabbix/zabbix_template.py +++ b/lib/ansible/modules/monitoring/zabbix/zabbix_template.py @@ -1,21 +1,9 @@ #!/usr/bin/python # -*- coding: utf-8 -*- + # (c) 2017, sookido -# -# 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 . +# 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 @@ -26,7 +14,7 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', DOCUMENTATION = ''' - +--- module: zabbix_template short_description: create/delete/dump zabbix template description: @@ -174,6 +162,7 @@ EXAMPLES = ''' ''' RETURN = ''' +--- template_json: description: The JSON dump of the template returned: when state is dump @@ -350,6 +339,18 @@ class Template(object): 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 template.keys(): + if not template[key] or (key == 'description' and desc_not_supported): + template.pop(key) + return template_json def load_json_template(self, template_json): @@ -516,7 +517,12 @@ def main(): elif state == "present": child_template_ids = None if link_templates is not None: - child_template_ids = template.get_template_ids(link_templates) + existing_child_templates = None + if existing_template_json: + existing_child_templates = set(list( + tmpl['name'] for tmpl in existing_template_json['zabbix_export']['templates'][0]['templates'])) + if not existing_template_json or set(link_templates) != existing_child_templates: + child_template_ids = template.get_template_ids(link_templates) clear_template_ids = [] if clear_templates is not None: @@ -534,9 +540,14 @@ def main(): macros = None if template_macros is not None: existing_macros = 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 existing_template_json: - existing_macros = set(existing_template_json['zabbix_export']['templates'][0]['macros']) - if not existing_macros or set(template_macros) != existing_macros: + existing_macros = existing_template_json['zabbix_export']['templates'][0]['macros'] + if not existing_macros or template_macros != existing_macros: macros = template_macros if not template_ids: @@ -551,7 +562,7 @@ def main(): clear_template_ids, macros, existing_template_json) module.exit_json(changed=changed, - result="Successfully updateed template: %s" % + result="Successfully updated template: %s" % template_name)