saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Get access to the Salt software package repository here:
https://repo.saltproject.io/
Apache License 2.0
14.17k stars 5.48k forks source link

[BUG] zabbix.py: module.run does not import source for configuration correctly #60563

Closed misch42 closed 3 years ago

misch42 commented 3 years ago

Description I want to use zabbix.run_query for a template import to zabbix, but the module does not read the source file somehow.

Setup state:

zabbix.run_query:
  module.run:
    - method: configuration.import
    - params:
        format: xml
        source: salt://zabbix/templates/testtempl.xml
        rules:
          templates:
            createMissing: true

with my templates/testtempl.xml:

<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>5.2</version>
    <date>2021-07-17T14:05:58Z</date>
    <groups>
        <group>
            <name>Templates</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>Testtemplate</template>
            <name>Testtemplate</name>
            <groups>
                <group>
                    <name>Templates</name>
                </group>
            </groups>
        </template>
    </templates>
</zabbix_export>

Steps to Reproduce the behavior Setup state and apply.

Expected behavior New template appears in Zabbix.

Screenshots Instead, salt answers:

          ID: zabbix.run_query
    Function: module.run
      Result: False
     Comment: Module function zabbix.run_query threw an exception. Exception: Zabbix API: Application error. (Cannot read XML: (4) Start tag expected, '<' not found [Line: 1 | Column: 1].)
     Started: 16:39:14.332092

Versions Report

salt --versions-report (Provided by running salt --versions-report. Please also mention any differences in master/minion versions.) ``` Salt Version: Salt: 3001.6 Dependency Versions: cffi: 1.14.0 cherrypy: Not Installed dateutil: 2.8.1 docker-py: Not Installed gitdb: 4.0.5 gitpython: 3.1.8 Jinja2: 2.11.2 libgit2: 1.0.1 M2Crypto: 0.36.0 Mako: Not Installed msgpack-pure: Not Installed msgpack-python: 1.0.0 mysql-python: Not Installed pycparser: 2.20 pycrypto: 3.9.8 pycryptodome: 3.9.8 pygit2: 1.3.0 Python: 3.7.9 (default, Nov 3 2020, 12:10:17) python-gnupg: 0.4.6 PyYAML: 5.3.1 PyZMQ: 19.0.1 smmap: 3.0.4 timelib: Not Installed Tornado: 4.5.3 ZMQ: 4.3.3 System Versions: dist: gentoo 2.7 locale: UTF-8 machine: x86_64 release: 4.9.74-grsecurity system: Linux version: Gentoo 2.7 ```

Additional context Add any other context about the problem here.

piterpunk commented 3 years ago

Hi @misch42 ,

This is the expected behaviour, all zabbix.run_query's params are passed directly to Zabbix API without any special handling, so your state definition will send the string salt://zabbix/templates/testtempl.xml, not the file contents:

data: {"jsonrpc": "2.0", "id": 0, "method": "configuration.import", "params": {"format": "xml", "source": "salt://zabbix/templates/testtempl.xml", "rules": {"templates": {"createMissing": true}}}, "auth": "4b42ef6b510a3f2c608d65972576d0f0"}

As the string salt://zabbix/templates/testtempl.xml isn't a valid XML the Zabbix API returns an error:

{'jsonrpc': '2.0', 'error': {'code': -32500, 'message': 'Application error.', 'data': "Cannot read XML: (4) Start tag expected, '<' not found [Line: 1 | Column: 1]."}, 'id': 0}

To achieve your objective to import the XML file as a configuration, you need to read the file and send its contents in source. This state definition does that:

{% set template_source = salt.cp.get_file_str('salt://zabbix/templates/testtempl.xml') %}
zabbix.run_query:
  module.run:
    - method: configuration.import
    - params:
        format: xml
        source: |
          {{ template_source | indent(10) }}
        rules:
          templates:
            createMissing: true

Please, pay special attention to the {{ template_source | indent(10) }} line. It need to start at 10th column or to change the indent number to the correct value.

With this state the following query will be sent:

data: {"jsonrpc": "2.0", "id": 0, "method": "configuration.import", "params": {"format": "xml", "source": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<zabbix_export>\n    <version>5.0</version>\n    <date>2021-07-17T14:05:58Z</date>\n    <groups>\n        <group>\n            <name>Templates</name>\n        </group>\n    </groups>\n    <templates>\n        <template>\n            <template>Testtemplate</template>\n            <name>Testtemplate</name>\n            <groups>\n                <group>\n                    <name>Templates</name>\n                </group>\n            </groups>\n        </template>\n    </templates>\n</zabbix_export>\n", "rules": {"templates": {"createMissing": true}}}, "auth": "4948e855cc9cb301bb6666d7015509b0"}

The response from Zabbix API to this query is:

{'jsonrpc': '2.0', 'result': True, 'id': 0}

Which results as a success to Salt execution:

local:
----------
          ID: zabbix.run_query
    Function: module.run
      Result: True
     Comment: Module function zabbix.run_query executed
     Started: 01:39:02.947866
    Duration: 563.199 ms
     Changes:   
              ----------
              ret:
                  True

Summary for local
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time: 563.199 ms
misch42 commented 3 years ago

Yes. That was the point. thanks.