
    Vhr                         d dl mZmZmZ eZdZdZdZd dl	Z	d dl
Z
d dlZd dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmc mc mc mc mZ  G d de      Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functiona  
---
module: zabbix_template
short_description: Create/update/delete Zabbix template
description:
    - This module allows you to create, modify and delete 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 >= 3.9"
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) and I(template_yaml).
        required: false
        type: json
    template_xml:
        description:
            - XML dump of templates to import.
            - Multiple templates can be imported this way.
            - Mutually exclusive with I(template_name) and I(template_json) and I(template_yaml).
        required: false
        type: str
    template_yaml:
        description:
            - Context of exported templates file to import.
            - Multiple templates can be imported this way.
            - Mutually exclusive with I(template_name) and I(template_json) and I(template_xml).
        required: false
        type: str
    template_groups:
        description:
            - List of template groups to add template to when template is created.
            - Replaces the current template 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:
            macro:
                description:
                    - Name of the macro.
                    - Must be specified in {$NAME} format.
                type: str
                required: true
            value:
                description:
                    - Value of the macro.
                type: str
                required: true
    tags:
        description:
            - List of tags to assign to the template.
            - Providing I(tags=[]) with I(force=yes) will clean all of the tags from the template.
        required: false
        type: list
        elements: dict
        suboptions:
            tag:
                description:
                    - Name of the template tag.
                type: str
                required: true
            value:
                description:
                    - Value of the template tag.
                type: str
                default: ""
    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=absent) template will be deleted.
        required: false
        choices: [present, absent]
        default: "present"
        type: str

extends_documentation_fragment:
- community.zabbix.zabbix
a  
---
# If you want to use Username and Password to be authenticated by Zabbix Server
- name: Set credentials to access Zabbix Server API
  ansible.builtin.set_fact:
    ansible_user: Admin
    ansible_httpapi_pass: zabbix

# If you want to use API token to be authenticated by Zabbix Server
# https://www.zabbix.com/documentation/current/en/manual/web_interface/frontend_sections/administration/general#api-tokens
- name: Set API token
  ansible.builtin.set_fact:
    ansible_zabbix_auth_key: 8ec0d52432c15c91fcafe9888500cf9a607f44091ab554dbee860f6b44fac895

- name: Create a new Zabbix template linked to groups, macros and templates
  # set task level variables as we change ansible_connection plugin here
  vars:
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 443
    ansible_httpapi_use_ssl: true
    ansible_httpapi_validate_certs: false
    ansible_zabbix_url_path: "zabbixeu"  # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
    ansible_host: zabbix-example-fqdn.org
  community.zabbix.zabbix_template:
    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
  # set task level variables as we change ansible_connection plugin here
  vars:
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 443
    ansible_httpapi_use_ssl: true
    ansible_httpapi_validate_certs: false
    ansible_zabbix_url_path: "zabbixeu"  # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
    ansible_host: zabbix-example-fqdn.org
  community.zabbix.zabbix_template:
    template_name: ExampleHost
    clear_templates:
      - Example template3
      - Example template4
    state: present

- name: Import Zabbix templates from JSON
  # set task level variables as we change ansible_connection plugin here
  vars:
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 443
    ansible_httpapi_use_ssl: true
    ansible_httpapi_validate_certs: false
    ansible_zabbix_url_path: "zabbixeu"  # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
    ansible_host: zabbix-example-fqdn.org
  community.zabbix.zabbix_template:
    template_json: "{{ lookup('file', 'zabbix_apache2.json') }}"
    state: present

- name: Import Zabbix templates from XML
  # set task level variables as we change ansible_connection plugin here
  vars:
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 443
    ansible_httpapi_use_ssl: true
    ansible_httpapi_validate_certs: false
    ansible_zabbix_url_path: "zabbixeu"  # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
    ansible_host: zabbix-example-fqdn.org
  community.zabbix.zabbix_template:
    template_xml: "{{ lookup('file', 'zabbix_apache2.xml') }}"
    state: present

- name: Import Zabbix template from Ansible dict variable
  # set task level variables as we change ansible_connection plugin here
  vars:
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 443
    ansible_httpapi_use_ssl: true
    ansible_httpapi_validate_certs: false
    ansible_zabbix_url_path: "zabbixeu"  # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
    ansible_host: zabbix-example-fqdn.org
  community.zabbix.zabbix_template:
    template_json:
      zabbix_export:
        version: "3.2"
        templates:
          - name: Template for Testing
            description: "Testing template import"
            template: Test Template
            groups:
              - name: Templates
    state: present

- name: Configure macros on the existing Zabbix template
  # set task level variables as we change ansible_connection plugin here
  vars:
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 443
    ansible_httpapi_use_ssl: true
    ansible_httpapi_validate_certs: false
    ansible_zabbix_url_path: "zabbixeu"  # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
    ansible_host: zabbix-example-fqdn.org
  community.zabbix.zabbix_template:
    template_name: Template
    macros:
      - macro: "{$TEST_MACRO}"
        value: "Example"
    state: present

- name: Add tags to the existing Zabbix template
  # set task level variables as we change ansible_connection plugin here
  vars:
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 443
    ansible_httpapi_use_ssl: true
    ansible_httpapi_validate_certs: false
    ansible_zabbix_url_path: "zabbixeu"  # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
    ansible_host: zabbix-example-fqdn.org
  community.zabbix.zabbix_template:
    template_name: Template
    tags:
      - tag: class
        value: application
    state: present

- name: Delete Zabbix template
  # set task level variables as we change ansible_connection plugin here
  vars:
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 443
    ansible_httpapi_use_ssl: true
    ansible_httpapi_validate_certs: false
    ansible_zabbix_url_path: "zabbixeu"  # If Zabbix WebUI runs on non-default (zabbix) path ,e.g. http://<FQDN>/zabbixeu
    ansible_host: zabbix-example-fqdn.org
  community.zabbix.zabbix_template:
    template_name: Template
    state: absent
z
---
N)AnsibleModule)	to_native)PY2)
ZabbixBase)LooseVersionc                   L    e Zd Zd Zd Zd Zd Zd Zd Zd Z	ddZ
d	 Zdd
Zy)Templatec                 ~   g }|D ]  }t        | j                        t        d      k\  r,| j                  j                  j	                  dgd|id      }n+| j                  j
                  j	                  dgd|id      }|r|j                  d|d   d   i       | j                  j                  d|z          |S )N6.2groupidnameoutputfilterr   zTemplate group not found: %smsg)	r
   _zbx_api_version_zapitemplategroupget	hostgroupappend_module	fail_json)selfgroup_names	group_ids
group_namegroups        t/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/zabbix/plugins/modules/zabbix_template.pyget_group_ids_by_group_namesz%Template.get_group_ids_by_group_names4  s    	% 	XJD112l56II

0044X^`jWk5lm

,,00YKTZ\fSg1hi  )U1Xi-@!AB&&+IJ+V&W	X     c                     g }|t        |      dk(  r|S |D ]V  }| j                  j                  j                  dd|id      }t        |      dk  r<|d   d   }|j	                  d|i       X |S )Nr   extendhostr      
templateid)lenr   templater   r   )r   template_listtemplate_idsr,   template_ids        r#   get_template_idszTemplate.get_template_idsA  s     C$6!$;% 	AH JJ//33xTZ\dSe4fgM=!A%+A.|<##\;$?@	A r%   c                 @   | j                   j                  r| j                   j                  d       |||||d}||j                  dg i       ||j                  dg i       ||j                  dg i       | j                  j
                  j                  |       y )NTchanged)r(   groups	templatesmacrostagsr6   r7   r5   )r   
check_mode	exit_jsonupdater   r,   create)r   template_namer    link_template_idsr6   r7   new_templates          r#   add_templatezTemplate.add_templateN  s    <<""LL""4"0 -Qbnt  C  D>2/<-$b 12

""<0r%   c                 Z   d}|ddddddddddidddddddddddddiddidddddddddddd}	 d|d   d	<   |j                  d
      |d<   t        | j                        t        d      k  r+ddi|d<   |j                  dd       |j                  dd       |||d}| j                  j                  j                  |      }t        |      dk7  rd}|S y# t        $ rC}| j                  j                  dt        |      t        j                                Y d}~yd}~ww xY w)zitemplate_content has same structure as Zabbix uses (e.g. it was optimally exported via Zabbix GUI or API)FNTcreateMissingupdateExistingdeleteMissingrB   rB   rC   discoveryRulesgraphshost_groups	httptestsitemsr5   template_groupstemplateLinkagetemplateScreenstriggers	valueMapsrM   rD   rN   templateDashboardsr   r4   rI   rL   formatsourcerulesr   zUnable to compare templater   details	exception)popr
   r   r   configurationimportcomparer+   	Exceptionr   r   r   	traceback
format_exc)r   template_contenttemplate_typer3   update_rulesr[   compare_resultes           r#   import_comparezTemplate.import_compare\  s    ' &*&*%)# &*&*%) $T  &*&*%) &*&*%) &*&*
 $T$ $T$ &*&*%)$ &*&*%) &*&*Y0LdICG./@5A5E5EFW5X12   5 56e9LL.=t-DL* $$]D9 $$%6=+8DT_k l!%!9!9!G!G!V~&!+"GA (B  I&&+GQZ[\Q]1:1E1E1G ' I IIs   B$C 	D*'9D%%D*c                    d}| j                  |d      }|kt        | j                        t        d      k\  r|d   d   D 	cg c]  }	|	d   	 }
}	n|d   d   D 	cg c]  }	|	d   	 }
}	t        |      t        |
      k7  rd	}d
|d   d
   d   vrg |d   d
   d   d
<   |d   d
   d   d
   D cg c]  }|d   	 }}|t        |      t        |      k7  rd	}nt        g       t        |      k7  rd	}||D ]
  }||v sd	} n d|d   d
   d   vrg |d   d
   d   d<   ||d   d
   d   d   }||k7  rd	}d|d   d
   d   vrg |d   d
   d   d<   ||d   d
   d   d   }||k7  rd	}|S c c}	w c c}	w c c}w )zECompare template with user provided all parameters via module optionsFjson)r`   r   zabbix_exportrL   r   r4   Tr5   r   r6   r7   )dump_templater
   r   set)r   r.   rL   link_templatesclear_templatestemplate_macrostemplate_tagsr3   existing_templategexisting_groupstexist_child_templatesexisting_macrosexisting_tagss                  r#   check_template_changedzTemplate.check_template_changed  s-     ..|6.R&D112l56II6G6XYj6k"l1V9"l"l6G6XYa6b"c1V9"c"c?#s?';;/@MaPPNPo.{;A>{K 5Fo4VWb4cde4fgr4s tq6 t t%>"c*?&@@2w#344 &$ --"G
 ,_=kJ1MMKMo.{;A>xH&/@MaPQYZO/1*?;KHKKIKo.{;A>vF$-o>{KANvVM-S #m"c !us   E(E-.E2c                    i }||j                  d|i       ||j                  d|i       n|j                  dg i       ||j                  d|i       ||j                  d|i       n|j                  dg i       ||j                  d|i       n|j                  dg i       |r:|j                  |d          | j                  j                  j                  |       y y )Nr4   r5   templates_clearr6   r7   r   )r:   r   r,   )r   r.   r    r=   clear_template_idsrl   rm   template_changess           r#   update_templatezTemplate.update_template  s     ##Xy$9:(##[2C$DE##["$56)##%68J$KL&##X$?@##XrN3$##V]$;<##VRL1##LO4JJ&&'78 r%   c                     | j                   j                  r| j                   j                  d       |D cg c]  }|j                  d       }}| j                  j
                  j                  |       y c c}w )NTr2   r*   )r   r8   r9   r   r   r,   delete)r   templateidsrq   templateids_lists       r#   delete_templatezTemplate.delete_template  s`    <<""LL""4"09DEAAEE,/EE

""#34 Fs   A7c                 *   |D cg c]  }|j                  d       }}	 | j                  j                  j                  |d|id      }| j	                  |      S c c}w # t
        $ r)}| j                  j                  d|z         Y d }~y d }~ww xY w)Nr*   r5   )rS   optionszUnable to export template: %sr   )r   r   rZ   exportload_json_templater\   r   r   )r   r.   r`   rq   template_ids_listdumprc   s          r#   rh   zTemplate.dump_template  s    :FGQQUU<0GG	L::++22mYdfwXx3yzD**400 H
  	LLL""'F'J"KK	Ls   A:A   	B)BBc                     	 t        j                  |      }|S # t        $ rC}| j                  j	                  dt        |      t        j                                Y d }~y d }~ww xY w)NzInvalid JSON providedrV   )rf   loads
ValueErrorr   r   r   r]   r^   )r   template_jsonjsondocrc   s       r#   r   zTemplate.load_json_template  sY    	xjj/GN 	xLL""'>	RS`i`t`t`v"ww	xs    	A%9A  A%c                    | j                   j                  r| j                   j                  d       ddddddddddidddddddddddddiddidddddddddddd}	 d|d   d<   |j                  d	      |d
<   t	        | j
                        t	        d      k  r+ddi|d<   |j                  dd        |j                  dd        t        rt        j                  dd|      }|||d}| j                  j                  j                  |       y # t        $ rC}| j                   j                  dt        |      t        j                                 Y d }~y d }~ww xY w)NTr2   rA   rB   rE   rF   rM   rD   rN   rQ   r   r4   rI   rL   z\\\\u([0-9a-z]{,4})z\\u\1rR   zUnable to import templaterV   )r   r8   r9   rY   r
   r   r   resubr   rZ   import_r\   r   r   r]   r^   )r   r_   r`   ra   import_datarc   s         r#   import_templatezTemplate.import_template
  s   <<""LL""4"0
 "&"&!% "&"&!%   "&"&!% "&"&!% "&"&
       "&"&!%  "&"&!% "&"&Y0
d	E?CL*+O<1=1A1ABS1TL-. D112\%5HH*94)@X&  5  !2D9 #%66*@(L\#] %2>NYefKJJ$$,,[9 	ELL""'BIVWL-6-A-A-C # E E	Es   &B0D 	E# 9EE#N)rf   )__name__
__module____qualname__r$   r0   r?   rd   ru   rz   r   rh   r   r    r%   r#   r   r   2  s<    1GIR0d985LxLEr%   r   c                     t        j                         } | j                  t        t        dd      t        dd      t        dd      t        dd      t        ddd      t        ddd      t        ddd      t        ddt        t        dd      t        dd      	      
      t        ddt        t        dd      t        dd            
      t        ddddg      
             t	        | g dgg dgdddgggd      }|j
                  d   }|j
                  d   }|j
                  d   }|j
                  d   }|j
                  d   }|j
                  d   }|j
                  d   }|j
                  d   }	|j
                  d   }
|j
                  d   }t        |      }d\  }}}|d}|}n"|d}|}n|d }|}n|g}|j                  |      }|dk(  r@|s|j                  dd!|z  "       |j                  |       |j                  dd#|z  $       y |dk(  r|l|j                  ||      }|s|j                  |d%$       y |j                  r|j                  |&       |j                  ||       |j                  |d'$       y d }||j                  |      }d }||j                  |      }d }||j                  |      }|	|	D ]  }|D ]  }t        ||         ||<     |
|
D ]  }|D ]  }t        ||         ||<     |s@||j                  d()       |j!                  ||||	|
       |j                  dd*|z  $       y |j#                  |||||	|
      }|j                  r|j                  |&       |r+||j                  ||       n|j%                  |||||	|
       |j                  |d+$       y y ),NstrF)typerequiredrf   list)r   r   elementsdictT)macrovalue)r   r   r    )r   default)tagr   presentabsent)r   r   choices)
r<   r   template_xmltemplate_yamlrL   rj   rk   r6   r7   state)r<   r   r   r   r   r<   )argument_specrequired_one_ofmutually_exclusiverequired_ifsupports_check_moder   r   r   rL   rj   rk   r6   r7   )NNNxmlyamlz"Template not found. No changed: %s)r3   r   z Successfully deleted template %s)r3   resultzTemplate is up-to dater2   zTemplate import successfulz@template_groups are required when creating a new Zabbix templater   zSuccessfully added template: %szTemplate successfully updated)zabbix_utilszabbix_common_argument_specr:   r   r   paramsr   r0   r9   r   rd   r8   r   r$   r   r   r?   ru   rz   )r   moduler<   r   r   r   rL   rj   rk   rl   rm   r   r,   r_   r`   r.   template_namesr3   r    r=   rx   	macroitemkeytagitems                           r#   mainr   Y  sw    <<>M67uu56&55I%%H&55I55
 ed3r2
 y9h:OP1 4 #O
 P
 h 12
 !F MM/2MMM/2M==0LMM/2Mmm$56O]]#34Nmm$56OmmH-OMM&)MMM'"EH 5E1m\ (		!'		"( (00@U0TWd0de  ..PS`.`a	)	'--.>NG  9Q R$$$$W$5(()9=I  9U V I*$AA/R	 $)$,$=$=n$M!!%*%-%>%>%O"*!0 =I( =),Ys^)<	#== (, 9G& 9'*73<'899  $$$)k$l%%mY@QSbdqr  6WZg6g h #99,Ygix:I=Z $$$$W$5$0 001A=Q 00yJ[]o1@-Q   9X Ys 
r%   __main__) 
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNrf   r]   r   ansible.module_utils.basicr   ansible.module_utils._textr   ansible.module_utils.sixr   >ansible_collections.community.zabbix.plugins.module_utils.baser	   #ansible.module_utils.compat.versionr
   Aansible_collections.community.zabbix.plugins.module_utils.helpers	communityzabbixpluginsmodule_utilshelpersr   r   r   r   r   r%   r#   <module>r      s|    A @tn[z

   	 4 0 ( U < X X XdEz dEN	KZ\ zF r%   