Reworked zabbix_template to support XML import/export + updated documentation (#59040)
This commit is contained in:
parent
d0dac80e41
commit
31bfcd4745
2 changed files with 336 additions and 168 deletions
|
@ -0,0 +1,8 @@
|
|||
minor_changes:
|
||||
- zabbix_template - new parameter `template_xml` adds support for importing templates from XML documents
|
||||
- zabbix_template - new parameter `dump_format` allows user to specify in which format (JSON or XML) should a template be exported from Zabbix
|
||||
- zabbix_template - it is no longer accepted to provide parameters `template_name` and `template_groups` when using `template_json`
|
||||
- zabbix_template - parameters `template_name`, `template_json` and `template_xml` are now mutually exclusive
|
||||
- zabbix_template - parameter `template_groups` is now required when passing `template_name` and template is being created for the fisrt time. Not required when template is being updated.
|
||||
- zabbix_template - now allows import of multiple templates at once when using `template_json` or `template_xml` parameters
|
||||
- zabbix_template - template can now be updated with just a `clear_templates` parameter without requiring any additional parameters to be passed (see examples of the module)
|
|
@ -16,13 +16,15 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|||
DOCUMENTATION = '''
|
||||
---
|
||||
module: zabbix_template
|
||||
short_description: Create/delete/dump Zabbix template
|
||||
short_description: Create/update/delete/dump Zabbix template
|
||||
description:
|
||||
- Create/delete/dump Zabbix template.
|
||||
- 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.
|
||||
version_added: "2.5"
|
||||
author:
|
||||
- "sookido (@sookido)"
|
||||
- "Logan Vig (@logan2211)"
|
||||
- "Dusan Matejka (@D3DeFi)"
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "zabbix-api >= 0.5.3"
|
||||
|
@ -30,33 +32,75 @@ options:
|
|||
template_name:
|
||||
description:
|
||||
- Name of Zabbix template.
|
||||
- Required when I(template_json) is not used.
|
||||
- Required when I(template_json) or I(template_xml) are not used.
|
||||
- Mutually exclusive with I(template_json) and I(template_xml).
|
||||
required: false
|
||||
template_json:
|
||||
description:
|
||||
- JSON dump of template to import.
|
||||
- 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
|
||||
version_added: '2.9'
|
||||
template_groups:
|
||||
description:
|
||||
- List of template groups to create or delete.
|
||||
- Required when I(template_name) is used and C(state=present).
|
||||
- List of host groups to add template to when template is createad.
|
||||
- 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
|
||||
link_templates:
|
||||
description:
|
||||
- List of templates linked to the template.
|
||||
- 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
|
||||
clear_templates:
|
||||
description:
|
||||
- List of templates cleared from the template.
|
||||
- See templates_clear in https://www.zabbix.com/documentation/3.0/manual/api/reference/template/update
|
||||
- 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
|
||||
macros:
|
||||
description:
|
||||
- List of template macros.
|
||||
- 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
|
||||
suboptions:
|
||||
name:
|
||||
description:
|
||||
- Name of the macro.
|
||||
- Must be specified in {$NAME} format.
|
||||
value:
|
||||
description:
|
||||
- Value of the macro.
|
||||
dump_format:
|
||||
description:
|
||||
- Format to use when dumping template with C(state=dump).
|
||||
required: false
|
||||
choices: [json, xml]
|
||||
default: "json"
|
||||
version_added: '2.9'
|
||||
state:
|
||||
description:
|
||||
- 'State: present - create/update template; absent - delete template'
|
||||
- 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.
|
||||
required: false
|
||||
choices: [present, absent, dump]
|
||||
default: "present"
|
||||
|
@ -67,24 +111,19 @@ extends_documentation_fragment:
|
|||
|
||||
EXAMPLES = '''
|
||||
---
|
||||
# Creates a new Zabbix template from linked template
|
||||
- name: Create Zabbix template using linked template
|
||||
- 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_json: "{'zabbix_export': {}}"
|
||||
template_groups:
|
||||
- Role
|
||||
- Role2
|
||||
link_templates:
|
||||
- Example template1
|
||||
- Example template2
|
||||
clear_templates:
|
||||
- Example template3
|
||||
- Example template4
|
||||
macros:
|
||||
- macro: '{$EXAMPLE_MACRO1}'
|
||||
value: 30000
|
||||
|
@ -94,26 +133,41 @@ EXAMPLES = '''
|
|||
value: 'Example'
|
||||
state: present
|
||||
|
||||
# Create a new template from a JSON config definition
|
||||
- name: Import Zabbix JSON template configuration
|
||||
- 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: Apache2
|
||||
template_json: "{{ lookup('file', 'zabbix_apache2.json') }}"
|
||||
template_groups:
|
||||
- Webservers
|
||||
template_name: ExampleHost
|
||||
clear_templates:
|
||||
- Example template3
|
||||
- Example template4
|
||||
state: present
|
||||
|
||||
# Import a template from Ansible variable dict
|
||||
- name: Import Zabbix template
|
||||
- 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_name: Test Template
|
||||
template_json:
|
||||
zabbix_export:
|
||||
version: '3.2'
|
||||
|
@ -125,11 +179,9 @@ EXAMPLES = '''
|
|||
- name: Templates
|
||||
applications:
|
||||
- name: Test Application
|
||||
template_groups: Templates
|
||||
state: present
|
||||
|
||||
# Add a macro to a template
|
||||
- name: Set a macro on the Zabbix template
|
||||
- name: Configure macros on the existing Zabbix template
|
||||
local_action:
|
||||
module: zabbix_template
|
||||
server_url: http://127.0.0.1
|
||||
|
@ -141,7 +193,6 @@ EXAMPLES = '''
|
|||
value: 'Example'
|
||||
state: present
|
||||
|
||||
# Remove a template
|
||||
- name: Delete Zabbix template
|
||||
local_action:
|
||||
module: zabbix_template
|
||||
|
@ -151,8 +202,7 @@ EXAMPLES = '''
|
|||
template_name: Template
|
||||
state: absent
|
||||
|
||||
# Export template JSON definition
|
||||
- name: Dump Zabbix template
|
||||
- name: Dump Zabbix template as JSON
|
||||
local_action:
|
||||
module: zabbix_template
|
||||
server_url: http://127.0.0.1
|
||||
|
@ -161,6 +211,17 @@ EXAMPLES = '''
|
|||
template_name: Template
|
||||
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
|
||||
state: dump
|
||||
register: template_dump
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
|
@ -191,15 +252,53 @@ template_json:
|
|||
}]
|
||||
}
|
||||
}
|
||||
|
||||
template_xml:
|
||||
description: dump of the template in XML representation
|
||||
returned: when state is dump and dump_format is xml
|
||||
type: str
|
||||
sample: |-
|
||||
<?xml version="1.0" ?>
|
||||
<zabbix_export>
|
||||
<version>4.2</version>
|
||||
<date>2019-07-12T13:37:26Z</date>
|
||||
<groups>
|
||||
<group>
|
||||
<name>Templates</name>
|
||||
</group>
|
||||
</groups>
|
||||
<templates>
|
||||
<template>
|
||||
<template>test</template>
|
||||
<name>Test Template</name>
|
||||
<description/>
|
||||
<groups>
|
||||
<group>
|
||||
<name>Templates</name>
|
||||
</group>
|
||||
</groups>
|
||||
<applications/>
|
||||
<items/>
|
||||
<discovery_rules/>
|
||||
<httptests/>
|
||||
<macros/>
|
||||
<templates/>
|
||||
<screens/>
|
||||
<tags/>
|
||||
</template>
|
||||
</templates>
|
||||
</zabbix_export>
|
||||
'''
|
||||
|
||||
|
||||
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
|
||||
import atexit
|
||||
import json
|
||||
import traceback
|
||||
|
||||
|
||||
try:
|
||||
from zabbix_api import ZabbixAPI, ZabbixAPIException
|
||||
|
@ -253,58 +352,87 @@ class Template(object):
|
|||
template_ids.append(template_id)
|
||||
return template_ids
|
||||
|
||||
def add_template(self, template_name, template_json, group_ids,
|
||||
child_template_ids, macros):
|
||||
def add_template(self, template_name, group_ids, link_template_ids, macros):
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=True)
|
||||
|
||||
if template_json:
|
||||
self.import_template(template_json, template_name)
|
||||
else:
|
||||
self._zapi.template.create({'host': template_name,
|
||||
'groups': group_ids,
|
||||
'templates': child_template_ids,
|
||||
'macros': macros})
|
||||
self._zapi.template.create({'host': template_name, 'groups': group_ids, 'templates': link_template_ids,
|
||||
'macros': macros})
|
||||
|
||||
def update_template(self, templateids, template_json,
|
||||
group_ids, child_template_ids,
|
||||
clear_template_ids, macros,
|
||||
existing_template_json=None):
|
||||
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 dictonaries,
|
||||
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 dictonaries
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
# 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 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})
|
||||
changed = True
|
||||
if child_template_ids is not None:
|
||||
template_changes.update({'templates': child_template_ids})
|
||||
changed = True
|
||||
if macros is not None:
|
||||
template_changes.update({'macros': macros})
|
||||
changed = True
|
||||
do_import = False
|
||||
if template_json:
|
||||
parsed_template_json = self.load_json_template(template_json)
|
||||
if self.diff_template(parsed_template_json,
|
||||
existing_template_json):
|
||||
do_import = True
|
||||
changed = True
|
||||
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=changed)
|
||||
if link_template_ids is not None:
|
||||
template_changes.update({'templates': link_template_ids})
|
||||
|
||||
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:
|
||||
template_changes.update({
|
||||
'templateid': templateids,
|
||||
'templates_clear': clear_template_ids
|
||||
})
|
||||
# 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)
|
||||
|
||||
if do_import:
|
||||
self.import_template(template_json,
|
||||
existing_template_json['zabbix_export']['templates'][0]['template'])
|
||||
|
||||
return changed
|
||||
|
||||
def delete_template(self, templateids):
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=True)
|
||||
|
@ -319,15 +447,17 @@ class Template(object):
|
|||
else:
|
||||
return obj
|
||||
|
||||
def dump_template(self, template_ids):
|
||||
def dump_template(self, template_ids, template_type='json'):
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=True)
|
||||
|
||||
try:
|
||||
dump = self._zapi.configuration.export({
|
||||
'format': 'json',
|
||||
'options': {'templates': template_ids}
|
||||
})
|
||||
return self.load_json_template(dump)
|
||||
dump = self._zapi.configuration.export({'format': template_type, 'options': {'templates': template_ids}})
|
||||
if template_type == 'xml':
|
||||
return str(ET.tostring(ET.fromstring(dump.encode('utf-8')), encoding='utf-8'))
|
||||
else:
|
||||
return self.load_json_template(dump)
|
||||
|
||||
except ZabbixAPIException as e:
|
||||
self._module.fail_json(msg='Unable to export template: %s' % e)
|
||||
|
||||
|
@ -359,21 +489,43 @@ class Template(object):
|
|||
|
||||
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 identation
|
||||
xml_root_text = list(line.strip() for line in ET.tostring(parsed_xml_root).split('\n'))
|
||||
return ''.join(xml_root_text)
|
||||
|
||||
def load_json_template(self, template_json):
|
||||
try:
|
||||
return json.loads(template_json)
|
||||
except ValueError as e:
|
||||
self._module.fail_json(
|
||||
msg='Invalid JSON provided',
|
||||
details=to_native(e),
|
||||
exception=traceback.format_exc()
|
||||
)
|
||||
self._module.fail_json(msg='Invalid JSON provided', details=to_native(e), exception=traceback.format_exc())
|
||||
|
||||
def import_template(self, template_json, template_name=None):
|
||||
parsed_template_json = self.load_json_template(template_json)
|
||||
if template_name != parsed_template_json['zabbix_export']['templates'][0]['template']:
|
||||
self._module.fail_json(msg='JSON template name does not match presented name')
|
||||
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': {
|
||||
|
@ -427,21 +579,14 @@ class Template(object):
|
|||
# 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:
|
||||
if LooseVersion(api_version).version[:2] <= LooseVersion('3.2').version:
|
||||
update_rules['applications']['updateExisting'] = True
|
||||
|
||||
self._zapi.configuration.import_({
|
||||
'format': 'json',
|
||||
'source': template_json,
|
||||
'rules': update_rules
|
||||
})
|
||||
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 JSON template',
|
||||
details=to_native(e),
|
||||
exception=traceback.format_exc()
|
||||
)
|
||||
self._module.fail_json(msg='Unable to import template', details=to_native(e),
|
||||
exception=traceback.format_exc())
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -451,20 +596,29 @@ def main():
|
|||
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),
|
||||
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),
|
||||
state=dict(default="present", choices=['present', 'absent',
|
||||
'dump']),
|
||||
dump_format=dict(type='str', required=False, default='json', choices=['json', 'xml']),
|
||||
state=dict(default="present", choices=['present', 'absent', 'dump']),
|
||||
timeout=dict(type='int', default=10)
|
||||
),
|
||||
required_one_of=[['template_name', 'template_json']],
|
||||
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
|
||||
)
|
||||
|
||||
|
@ -479,104 +633,110 @@ def main():
|
|||
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']
|
||||
dump_format = module.params['dump_format']
|
||||
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 = 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)
|
||||
if template_json and not template_name:
|
||||
# Ensure template_name is not empty for safety check in import_template
|
||||
template_loaded = template.load_json_template(template_json)
|
||||
template_name = template_loaded['zabbix_export']['templates'][0]['template']
|
||||
elif template_name and not template_groups and state == 'present':
|
||||
module.fail_json(msg="Option template_groups is required when template_json is not used")
|
||||
|
||||
template_ids = template.get_template_ids([template_name])
|
||||
existing_template_json = None
|
||||
if template_ids:
|
||||
existing_template_json = template.dump_template(template_ids)
|
||||
# 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)
|
||||
|
||||
# delete template
|
||||
if state == "absent":
|
||||
# if template not found. no change, no fail
|
||||
if not template_ids:
|
||||
module.exit_json(changed=False,
|
||||
msg="Template not found. " +
|
||||
"No changed: %s" % template_name)
|
||||
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 delete template %s" %
|
||||
template_name)
|
||||
module.exit_json(changed=True, result="Successfully deleted template %s" % template_name)
|
||||
|
||||
elif state == "dump":
|
||||
if not template_ids:
|
||||
module.fail_json(msg='Template not found: %s' % template_name)
|
||||
module.exit_json(changed=False, template_json=existing_template_json)
|
||||
|
||||
if dump_format == 'json':
|
||||
module.exit_json(changed=False, template_json=template.dump_template(template_ids, template_type='json'))
|
||||
elif dump_format == 'xml':
|
||||
module.exit_json(changed=False, template_xml=template.dump_template(template_ids, template_type='xml'))
|
||||
|
||||
elif state == "present":
|
||||
child_template_ids = None
|
||||
if link_templates is not None:
|
||||
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)
|
||||
# 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)
|
||||
|
||||
clear_template_ids = []
|
||||
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)
|
||||
|
||||
group_ids = None
|
||||
if template_groups is not None:
|
||||
# If the template exists, compare the already set groups
|
||||
existing_groups = None
|
||||
if existing_template_json:
|
||||
existing_groups = set(list(group['name'] for group in existing_template_json['zabbix_export']['groups']))
|
||||
if not existing_groups or set(template_groups) != existing_groups:
|
||||
group_ids = template.get_group_ids_by_group_names(template_groups)
|
||||
|
||||
macros = None
|
||||
if template_macros is not None:
|
||||
existing_macros = None
|
||||
# zabbix configuration.export does not differentiate python types (numbers are returned as strings)
|
||||
# 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 = existing_template_json['zabbix_export']['templates'][0]['macros']
|
||||
if not existing_macros or template_macros != existing_macros:
|
||||
macros = template_macros
|
||||
|
||||
if not template_ids:
|
||||
template.add_template(template_name, template_json, group_ids,
|
||||
child_template_ids, macros)
|
||||
module.exit_json(changed=True,
|
||||
result="Successfully added template: %s" %
|
||||
template_name)
|
||||
# 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.update_template(template_ids[0], template_json,
|
||||
group_ids, child_template_ids,
|
||||
clear_template_ids, macros,
|
||||
existing_template_json)
|
||||
module.exit_json(changed=changed,
|
||||
result="Successfully updated template: %s" %
|
||||
template_name)
|
||||
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__':
|
||||
|
|
Loading…
Reference in a new issue