Closed HonzaKoren closed 1 year ago
I cannot reproduce. What version of Zabbix?
When playbook task contains a space or - in its value, the task end up with error "connection error occurred: string indices must be integers". Other variable values work as expected.
Can you please clarify what you mean by "value of playbook task" here? What code works?
I suspect that this behavior is not tight to the _templatename attribute. I'm using the _templatexml attribute with a jinja lookup like so:
template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}"
Which worked fine until i switched to the new httpapi-plugin. After switching to the new plugin i could no longer import any template with a xml file extension. Resulting in the following error:
failed: [host] (item=templates/template/rabbit_mq_node_by_zabbix_agent2.xml) => {"ansible_loop_var": "item", "changed": false, "item": "templates/template/rabbit_mq_node_by_zabbix_agent2.xml", "msg": "connection error occurred: string indices must be integers"}
So this works with the newest version:
- name: Import templates
local_action:
module: community.zabbix.zabbix_template
server_url: "https://{{ zabbix_host_url }}"
login_user: "{{ zabbix_admin_user }}"
login_password: "{{ zabbix_admin_user_password }}"
template_groups:
- Zabbix servers
template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}"
state: present
loop: "{{ result_list }}"
This does not work (for lookup == file):
- name: Init connection parameters
ansible.builtin.set_fact:
ansible_become: false
ansible_network_os: community.zabbix.zabbix
ansible_connection: httpapi
ansible_httpapi_port: 443
ansible_httpapi_use_ssl: true
ansible_httpapi_validate_certs: true
ansible_user: "{{ zabbix_admin_user }}"
ansible_host: "{{ zabbix_host_url }}"
ansible_httpapi_pass: "{{ zabbix_admin_user_password }}"
- name: Import templates
community.zabbix.zabbix_template:
template_groups:
- Zabbix servers
template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}"
state: present
loop: "{{ result_list }}"
Unfortunately I cloud not determine the root cause for this behavior. 😢 I switched this task back to local_action and the old way (server_url, login_user, login_password) which worked fine for now.
I cannot reproduce. What version of Zabbix?
6.0 LTS
When playbook task contains a space or - in its value, the task end up with error "connection error occurred: string indices must be integers". Other variable values work as expected.
Can you please clarify what you mean by "value of playbook task" here? What code works?
- name: Update templates to provide required tags
community.zabbix.zabbix_template:
# template_name: '{{item.name}}'
# tags: '{{item.tags}}'
template_name: 'Template-RHEL_Base'
tags:
- tag: class
value: Linux
state: present
If I use another template name, it passes.
---
- name: Update templates to provide required tags
community.zabbix.zabbix_template:
# template_name: '{{item.name}}'
# tags: '{{item.tags}}'
template_name: 'Template_RHEL_Base'
tags:
- tag: class
value: Linux
state: present
I suspect that this behavior is not tight to the _templatename attribute. I'm using the _templatexml attribute with a jinja lookup like so:
template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}"
Which worked fine until i switched to the new httpapi-plugin. After switching to the new plugin i could no longer import any template with a xml file extension. Resulting in the following error:
failed: [host] (item=templates/template/rabbit_mq_node_by_zabbix_agent2.xml) => {"ansible_loop_var": "item", "changed": false, "item": "templates/template/rabbit_mq_node_by_zabbix_agent2.xml", "msg": "connection error occurred: string indices must be integers"}
So this works with the newest version:
- name: Import templates local_action: module: community.zabbix.zabbix_template server_url: "https://{{ zabbix_host_url }}" login_user: "{{ zabbix_admin_user }}" login_password: "{{ zabbix_admin_user_password }}" template_groups: - Zabbix servers template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}" state: present loop: "{{ result_list }}"
This does not work (for lookup == file):
- name: Init connection parameters ansible.builtin.set_fact: ansible_become: false ansible_network_os: community.zabbix.zabbix ansible_connection: httpapi ansible_httpapi_port: 443 ansible_httpapi_use_ssl: true ansible_httpapi_validate_certs: true ansible_user: "{{ zabbix_admin_user }}" ansible_host: "{{ zabbix_host_url }}" ansible_httpapi_pass: "{{ zabbix_admin_user_password }}" - name: Import templates community.zabbix.zabbix_template: template_groups: - Zabbix servers template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}" state: present loop: "{{ result_list }}"
Unfortunately I cloud not determine the root cause for this behavior. cry I switched this task back to local_action and the old way (server_url, login_user, login_password) which worked fine for now.
Interesting hint, thank you. I'll try to play with httpapi versions.
I am confused, when did you get this problem?
1) When template_name
had space or - in it
2) When template_xml
performs 'file' type lookup?
Anyway I tried with .xml and still works without problems:
tasks:
- name: Update templates to provide required tags
community.zabbix.zabbix_template:
#template_name: 'Template-RHEL_Base'
template_groups:
- Templates
tags:
- tag: class
value: Linux
template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}"
state: present
loop:
- zbx_export_templates.xml
I had difficult times with this generic/cryptic error message. Here is how I am able to reproduce it:
- zabbix_template_info:
template_name: "Windows by Zabbix agent active"
format: json
omit_date: yes
Note that Windows by Zabbix agent active
is a default template.
Results:
TASK [zabbix_template_info] ******************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "connection error occurred: string indices must be integers"}
This seems related to Windows by Zabbix agent active > Discovery rules > Network interfaces discovery
I was able to "make it work" by:
Network interfaces discovery
.Interface {#IFNAME}({#IFALIAS}): Speed
errors
by something else in Interface {#IFNAME}({#IFALIAS}): Inbound packets with errors
and Interface {#IFNAME}({#IFALIAS}): Outbound packets with errors
(in Name, Key, Description)I'd say there are multiple possible causes but at least the keyword errors
crashes the connection.
I use Zabbix 6.2.6 & ansible-core 2.14.3 installed from pip3 on Debian.
I've experiencing same behaviour (zabbix 6.0.17 LTS, community.zabbix is 56f94d151da34b71a1a09af0b4eca6c7ddee319b) on one of our templates (others imported OK).
Template link: https://nextcloud.managed-it.a1.by/s/3WbDkfBHfRtqFLw
error is failed: [
- name: Create zabbix templates task
community.zabbix.zabbix_template:
template_xml: "{{ lookup('file',item) }}"
loop:
- files/zabbix/template_juniper-optical-interface.xml
- files/zabbix/template_multi_icmp_ping.xml
- files/zabbix/template_net_mtr.xml
- files/zabbix/template_multi_web_perf.xml
- files/zabbix/template_juniper_bgp.xml # This one causes error
this error related to configuration.export api calling.
zabbix_template module call configuration.export api. but this call dont care returning xml string so this error was happen.
condition of this bug happening is
I feel it seems to this bug not related to including hyphen or space.
Running into the same issue: template import works fine via legacy interface, but fails with the httpapi interface. Included the culprit attached. zbx_export_templates.json.txt
Hello,
I think the problem is only with the discovery rules. If you try to import one more time "Linux by Zabbix agent active" (for example), you have the same error message:
TASK [zabbix_6 : Import templates] *********************************************************************************************************************************************************************************************************
failed: [inf-adm-zabbix-web-1] (item=/home/pulsar895/git/ansible/playbooks/deploy_zabbix/files/zbx_export_templates-linux.json) => {"ansible_loop_var": "item", "changed": false, "item": "/home/pulsar895/git/ansible/playbooks/deploy_zabbix/files/zbx_export_templates-linux.json", "msg": "connection error occurred: string indices must be integers"}
If you remove discovery rules, it's ok:
TASK [zabbix_6 : Import templates] *********************************************************************************************************************************************************************************************************
ok: [inf-adm-zabbix-web-1] => (item=/home/pulsar895/git/ansible/playbooks/deploy_zabbix/files/zbx_export_templates-linux.json)
I hope my comment helps devteam to solve this problem.
Running into the same issue: template import works fine via legacy interface, but fails with the httpapi interface. Included the culprit attached. zbx_export_templates.json.txt
Just tested with Zabbix 6.4 - no problems importing this templates file.
See my comment in https://github.com/ansible-collections/community.zabbix/pull/1006 I'd love to have a file to import that would cause this issue.
So running into the same issue, tested on both zabbix latest LTS version 6.0 and 6.4.
Versions:
6.0.19
and 6.4.4
2.13.2
2.1.0
5.1.1
1.4.0
5.4.0
Problem description: Able to import the template on the 1st Ansible run, however on subsequent Ansible runs, import task fails with:
"msg": "connection error occurred: string indices must be integers, not 'str'"
1st Ansible run on import task (verbose output):
changed: [zabbix_host] => {
"changed": true,
"invocation": {
"module_args": {
"clear_templates": null,
"http_login_password": null,
"http_login_user": null,
"link_templates": null,
"macros": null,
"state": "present",
"tags": null,
"template_groups": null,
"template_json": null,
"template_name": null,
"template_xml": "<zabbix_export>\n <version>6.0</version>\n <groups>\n <group>\n <uuid>52a9bce1d9ac4ea7880a0b618c011577</uuid>\n <name>Storage</name>\n </group>\n </groups>\n <templates>\n <template>\n <uuid>cf82f065616a4a0392477a2a2d7e1393</uuid>\n <template>Storage1</template>\n <name>Storage1</name>\n <groups>\n <group>\n <name>Storage</name>\n </group>\n </groups>\n <items>\n <item>\n <uuid>f4495906698f45f1866c7494e7a01913</uuid>\n <name>storage_quotas</name>\n <key>storage_user_quota</key>\n <trends>0</trends>\n <value_type>CHAR</value_type>\n <preprocessing>\n <step>\n <type>CSV_TO_JSON</type>\n <parameters>\n <parameter>,</parameter>\n <parameter>"</parameter>\n <parameter>1</parameter>\n </parameters>\n <error_handler>CUSTOM_ERROR</error_handler>\n <error_handler_params>Failed to populate user quotas</error_handler_params>\n </step>\n </preprocessing>\n </item>\n </items>\n </template>\n </templates>\n</zabbix_export>"
}
},
"result": "Template import successful"
}
Subsequent Ansible run on import task (verbose output):
The full traceback is:
File "/var/folders/fc/s3k1pmdn42v_p669fm12mjvw0000gn/T/ansible_community.zabbix.zabbix_template_payload_bvy93set/ansible_community.zabbix.zabbix_template_payload.zip/ansible_collections/community/zabbix/plugins/module_utils/api_request.py", line 29, in _httpapi_error_handle
code, response = self.connection.send_request(data=payload)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/folders/fc/s3k1pmdn42v_p669fm12mjvw0000gn/T/ansible_community.zabbix.zabbix_template_payload_bvy93set/ansible_community.zabbix.zabbix_template_payload.zip/ansible/module_utils/connection.py", line 200, in __rpc__
raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
fatal: [zabbix_host]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"clear_templates": null,
"http_login_password": null,
"http_login_user": null,
"link_templates": null,
"macros": null,
"state": "present",
"tags": null,
"template_groups": null,
"template_json": null,
"template_name": null,
"template_xml": "<zabbix_export>\n <version>6.0</version>\n <groups>\n <group>\n <uuid>52a9bce1d9ac4ea7880a0b618c011577</uuid>\n <name>Storage</name>\n </group>\n </groups>\n <templates>\n <template>\n <uuid>cf82f065616a4a0392477a2a2d7e1393</uuid>\n <template>Storage1</template>\n <name>Storage1</name>\n <groups>\n <group>\n <name>Storage</name>\n </group>\n </groups>\n <items>\n <item>\n <uuid>f4495906698f45f1866c7494e7a01913</uuid>\n <name>storage_quotas</name>\n <key>storage_user_quota</key>\n <trends>0</trends>\n <value_type>CHAR</value_type>\n <preprocessing>\n <step>\n <type>CSV_TO_JSON</type>\n <parameters>\n <parameter>,</parameter>\n <parameter>"</parameter>\n <parameter>1</parameter>\n </parameters>\n <error_handler>CUSTOM_ERROR</error_handler>\n <error_handler_params>Failed to populate user quotas</error_handler_params>\n </step>\n </preprocessing>\n </item>\n </items>\n </template>\n </templates>\n</zabbix_export>"
}
},
"msg": "connection error occurred: string indices must be integers, not 'str'"
}
XML template used for testing: zabbix_import_failure_template.xml.txt
I don't think it's related to spaces or hyphens, as I have tested on the template with spaces and hyphens in the names, etc and was able to do multiple Ansible runs.
One thing that was interesting to me is that when commenting out these 2 lines in the template, I am able to perform multiple Ansible runs without issues also adding the word error
in the template / item name causes the import failure:
<error_handler>CUSTOM_ERROR</error_handler>
<error_handler_params>Failed to populate user quotas</error_handler_params>
Is it failing due to the keyword error
being present in the template?
Hope this helps!
For me, unsetting the "custom on fail" in the discovery's preprocessing leads to having no "error"-like lines in my template and after that, it successfully imports. Not sure if it's due to the keyword "error", but that's the main thing that has changed in my template.
More specifically, it removed these two lines:
error_handler: CUSTOM_ERROR
error_handler_params: 'Endpoint healthcheck contains no checks'
Zabbix 6.2.9 and Ansible core 2.15.1 using the community 2.1.0 release version
After checking a few more templates, it's not specifically tied to the error_handler, but rather to something more. Other templates that don't have error_handler but do have "error" as text in them, also fail.
This seems to also happen when used to set a macro for a template:
- name: Configure macro of network interfaces by Zabbix agent active template
community.zabbix.zabbix_template:
template_name: "Linux network interfaces by Zabbix agent active"
state: present
macros:
- macro: 'TEST'
value: 'value'
Output:
TASK [zabbix-server-config : Configure macro of network interfaces by Zabbix agent active template] *************************
fatal: [ops_zabbix_1]: FAILED! => {"changed": false, "msg": "connection error occurred: string indices must be integers"}
I suspect that this behavior is not tight to the _templatename attribute. I'm using the _templatexml attribute with a jinja lookup like so:
template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}"
Which worked fine until i switched to the new httpapi-plugin. After switching to the new plugin i could no longer import any template with a xml file extension. Resulting in the following error:
failed: [host] (item=templates/template/rabbit_mq_node_by_zabbix_agent2.xml) => {"ansible_loop_var": "item", "changed": false, "item": "templates/template/rabbit_mq_node_by_zabbix_agent2.xml", "msg": "connection error occurred: string indices must be integers"}
So this works with the newest version:
- name: Import templates local_action: module: community.zabbix.zabbix_template server_url: "https://{{ zabbix_host_url }}" login_user: "{{ zabbix_admin_user }}" login_password: "{{ zabbix_admin_user_password }}" template_groups: - Zabbix servers template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}" state: present loop: "{{ result_list }}"
This does not work (for lookup == file):
- name: Init connection parameters ansible.builtin.set_fact: ansible_become: false ansible_network_os: community.zabbix.zabbix ansible_connection: httpapi ansible_httpapi_port: 443 ansible_httpapi_use_ssl: true ansible_httpapi_validate_certs: true ansible_user: "{{ zabbix_admin_user }}" ansible_host: "{{ zabbix_host_url }}" ansible_httpapi_pass: "{{ zabbix_admin_user_password }}" - name: Import templates community.zabbix.zabbix_template: template_groups: - Zabbix servers template_xml: "{{ lookup('template', '{{ item }}') if 'j2' in item else lookup('file', '{{ item }}') }}" state: present loop: "{{ result_list }}"
Unfortunately I cloud not determine the root cause for this behavior. 😢 I switched this task back to local_action and the old way (server_url, login_user, login_password) which worked fine for now.
I just tried the ansible plugin way again with community.zabbix version 2.1.0. I still get the same error:
failed: [ops_zabbix_1] (item=templates/template/template1.xml) => {"ansible_loop_var": "item", "changed": false, "item": "templates/template/template1.xml", "msg": "connection error occurred: string indices must be integers"}
failed: [ops_zabbix_1] (item=templates/template/template2.xml.j2) => {"ansible_loop_var": "item", "changed": false, "item": "templates/template/template2.xml.j2", "msg": "connection error occurred: string indices must be integers"}
failed: [ops_zabbix_1] (item=templates/template/template3.xml.j2) => {"ansible_loop_var": "item", "changed": false, "item": "templates/template/template3.xml.j2", "msg": "connection error occurred: string indices must be integers"}
failed: [ops_zabbix_1] (item=templates/template/template4.xml) => {"ansible_loop_var": "item", "changed": false, "item": "templates/template/template4.xml", "msg": "connection error occurred: string indices must be integers"}
I just tried the ansible plugin way again with community.zabbix version 2.1.0. I still get the same error: It is fixed in main branch, 2.1.0 does not have this fix. You either need to wait for 2.2.0 or get your collection to use main branch of this repository.
SUMMARY
When playbook task contains a space or - in its value, the task end up with error "connection error occurred: string indices must be integers". Other variable values work as expected.
ISSUE TYPE
COMPONENT NAME
community.zabbix.zabbix_template
ANSIBLE VERSION
CONFIGURATION
OS / ENVIRONMENT / Zabbix Version
Linux, Ubuntu Focal Python3 virtual environment Python 3.10.6 ansible==7.1.0 ansible-core==2.14.2 certifi==2022.12.7 cffi==1.15.1 charset-normalizer==2.1.1 cryptography==39.0.0 flake8==6.0.0 idna==3.4 Jinja2==3.1.2 MarkupSafe==2.1.2 mccabe==0.7.0 packaging==23.0 pycodestyle==2.10.0 pycparser==2.21 pyflakes==3.0.1 PyYAML==6.0 pyzabbix==1.2.1 requests==2.28.1 resolvelib==0.8.1 urllib3==1.26.14
/home/honza/.virtualenvs/cez_loader/lib/python3.10/site-packages/ansible_collections
Collection Version
amazon.aws 5.1.0
ansible.netcommon 4.1.0
ansible.posix 1.4.0
ansible.utils 2.8.0
ansible.windows 1.12.0 arista.eos 6.0.0
awx.awx 21.10.0 azure.azcollection 1.14.0 check_point.mgmt 4.0.0
chocolatey.chocolatey 1.3.1
cisco.aci 2.3.0
cisco.asa 4.0.0
cisco.dnac 6.6.1
cisco.intersight 1.0.22 cisco.ios 4.0.0
cisco.iosxr 4.0.3
cisco.ise 2.5.9
cisco.meraki 2.13.0 cisco.mso 2.1.0
cisco.nso 1.0.3
cisco.nxos 4.0.1
cisco.ucs 1.8.0
cloud.common 2.1.2
cloudscale_ch.cloud 2.2.3
community.aws 5.0.0
community.azure 2.0.0
community.ciscosmb 1.0.5
community.crypto 2.9.0
community.digitalocean 1.22.0 community.dns 2.4.2
community.docker 3.3.1
community.fortios 1.0.0
community.general 6.1.0
community.google 1.0.0
community.grafana 1.5.3
community.hashi_vault 4.0.0
community.hrobot 1.6.0
community.libvirt 1.2.0
community.mongodb 1.4.2
community.mysql 3.5.1
community.network 5.0.0
community.okd 2.2.0
community.postgresql 2.3.1
community.proxysql 1.4.0
community.rabbitmq 1.2.3
community.routeros 2.5.0
community.sap 1.0.0
community.sap_libs 1.4.0
community.skydive 1.0.0
community.sops 1.5.0
community.vmware 3.2.0
community.windows 1.11.1 community.zabbix 1.9.0
containers.podman 1.10.1 cyberark.conjur 1.2.0
cyberark.pas 1.0.14 dellemc.enterprise_sonic 2.0.0
dellemc.openmanage 6.3.0
dellemc.os10 1.1.1
dellemc.os6 1.0.7
dellemc.os9 1.0.4
f5networks.f5_modules 1.21.0 fortinet.fortimanager 2.1.7
fortinet.fortios 2.2.1
frr.frr 2.0.0
gluster.gluster 1.0.2
google.cloud 1.0.2
grafana.grafana 1.1.0
hetzner.hcloud 1.9.0
hpe.nimble 1.1.4
ibm.qradar 2.1.0
ibm.spectrum_virtualize 1.10.0 infinidat.infinibox 1.3.12 infoblox.nios_modules 1.4.1
inspur.ispim 1.2.0
inspur.sm 2.3.0
junipernetworks.junos 4.1.0
kubernetes.core 2.3.2
lowlydba.sqlserver 1.2.1
mellanox.onyx 1.0.0
netapp.aws 21.7.0 netapp.azure 21.10.0 netapp.cloudmanager 21.21.0 netapp.elementsw 21.7.0 netapp.ontap 22.0.1 netapp.storagegrid 21.11.1 netapp.um_info 21.8.0 netapp_eseries.santricity 1.3.1
netbox.netbox 3.9.0
ngine_io.cloudstack 2.3.0
ngine_io.exoscale 1.0.0
ngine_io.vultr 1.1.2
openstack.cloud 1.10.0 openvswitch.openvswitch 2.1.0
ovirt.ovirt 2.4.1
purestorage.flasharray 1.15.0 purestorage.flashblade 1.10.0 purestorage.fusion 1.2.0
sensu.sensu_go 1.13.1 splunk.es 2.1.0
t_systems_mms.icinga_director 1.31.4 theforeman.foreman 3.7.0
vmware.vmware_rest 2.2.0
vultr.cloud 1.3.1
vyos.vyos 4.0.0
wti.remote 1.0.4
/home/honza/.ansible/collections/ansible_collections
Collection Version
ansible.netcommon 4.1.0
ansible.posix 1.5.1
ansible.utils 2.9.0
ansible.windows 1.13.0 community.general 6.3.0
community.mysql 3.5.1
community.postgresql 2.3.2
community.zabbix 1.9.1
STEPS TO REPRODUCE
Simple playbook to tag existing template (template of such name must exists).
EXPECTED RESULTS
Template modification - template is tagged as requested.
ACTUAL RESULTS
The full traceback is: File "/tmp/ansible_community.zabbix.zabbix_template_payload_t9r5agev/ansible_community.zabbix.zabbix_template_payload.zip/ansible_collections/community/zabbix/plugins/module_utils/api_request.py", line 29, in _httpapi_error_handle code, response = self.connection.send_request(data=payload) File "/tmp/ansible_community.zabbix.zabbix_template_payload_t9r5agev/ansible_community.zabbix.zabbix_template_payload.zip/ansible/module_utils/connection.py", line 200, in rpc raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code) fatal: [ca00253]: FAILED! => { "changed": false, "invocation": { "module_args": { "clear_templates": null, "dump_format": "json", "http_login_password": null, "http_login_user": null, "link_templates": null, "login_password": null, "login_user": null, "macros": null, "omit_date": false, "server_url": null, "state": "present", "tags": [ { "tag": "class", "value": "Linux" } ], "template_groups": null, "template_json": null, "template_name": "Template-RHEL_Base", "template_xml": null, "timeout": null, "validate_certs": null } }, "msg": "connection error occurred: string indices must be integers" }