Skip to content

Template module panos_template is not idempotent #613

Open
@mhca99

Description

@mhca99

Describe the bug

We are trying to create zone resource in a template , at first run ansible successfully creates the zone , however, on second run it gives error as follows:

$ ansible-playbook template_test_for_github.yml -i inventory.yml

PLAY [Palo Alto test] *********************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************
[WARNING]: Platform linux on host myhost is using the discovered Python interpreter at
/home/auser/panos_venv/bin/python3.12, but future installation of another Python interpreter could change the
meaning of that path. See https://docs.ansible.com/ansible-core/2.18/reference_appendices/interpreter_discovery.html for more
information.
ok: [myhost]

TASK [Create Parent template] *************************************************************************************************
ok: [myhost]

TASK [Create Child template] **************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 309
fatal: [myhost]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n  File \"/home/auser/.ansible/tmp/ansible-tmp-1744497282.3592024-7990-211525943990714/AnsiballZ_panos_template.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/home/auser/.ansible/tmp/ansible-tmp-1744497282.3592024-7990-211525943990714/AnsiballZ_panos_template.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/auser/.ansible/tmp/ansible-tmp-1744497282.3592024-7990-211525943990714/AnsiballZ_panos_template.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.paloaltonetworks.panos.plugins.modules.panos_template', init_globals=dict(_module_fqn='ansible_collections.paloaltonetworks.panos.plugins.modules.panos_template', _modlib_path=modlib_path),\n  File \"<frozen runpy>\", line 226, in run_module\n  File \"<frozen runpy>\", line 98, in _run_module_code\n  File \"<frozen runpy>\", line 88, in _run_code\n  File \"/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/modules/panos_template.py\", line 146, in <module>\n  File \"/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/modules/panos_template.py\", line 142, in main\n  File \"/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/module_utils/panos.py\", line 516, in process\n  File \"/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/module_utils/panos.py\", line 702, in apply_state\n  File \"/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/module_utils/panos.py\", line 79, in eltostr\n  File \"/home/auser/panos_venv/lib/python3.12/site-packages/panos/base.py\", line 532, in element_str\n    parsed = minidom.parseString(raw)\n             ^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.12/xml/dom/minidom.py\", line 2000, in parseString\n    return expatbuilder.parseString(string)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.12/xml/dom/expatbuilder.py\", line 922, in parseString\n    return builder.parseString(string)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.12/xml/dom/expatbuilder.py\", line 220, in parseString\n    parser.Parse(string, True)\nxml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 309\n", "module_stdout": "", "msg": "MODULE FAILURE: No start of json char found\nSee stdout/stderr for the exact error", "rc": 1}

PLAY RECAP ********************************************************************************************************************
myhost              : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

Error:
fatal: [myhost]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n File "/home/auser/.ansible/tmp/ansible-tmp-1744497282.3592024-7990-211525943990714/AnsiballZ_panos_template.py", line 107, in \n _ansiballz_main()\n File "/home/auser/.ansible/tmp/ansible-tmp-1744497282.3592024-7990-211525943990714/AnsiballZ_panos_template.py", line 99, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File "/home/auser/.ansible/tmp/ansible-tmp-1744497282.3592024-7990-211525943990714/AnsiballZ_panos_template.py", line 47, in invoke_module\n runpy.run_module(mod_name='ansible_collections.paloaltonetworks.panos.plugins.modules.panos_template', init_globals=dict(_module_fqn='ansible_collections.paloaltonetworks.panos.plugins.modules.panos_template', _modlib_path=modlib_path),\n File "", line 226, in run_module\n File "", line 98, in _run_module_code\n File "", line 88, in _run_code\n File "/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/modules/panos_template.py", line 146, in \n File "/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/modules/panos_template.py", line 142, in main\n File "/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/module_utils/panos.py", line 516, in process\n File "/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/module_utils/panos.py", line 702, in apply_state\n File "/tmp/ansible_paloaltonetworks.panos.panos_template_payload_5ame9mqe/ansible_paloaltonetworks.panos.panos_template_payload.zip/ansible_collections/paloaltonetworks/panos/plugins/module_utils/panos.py", line 79, in eltostr\n File "/home/auser/panos_venv/lib/python3.12/site-packages/panos/base.py", line 532, in element_str\n parsed = minidom.parseString(raw)\n ^^^^^^^^^^^^^^^^^^^^^^^^\n File "/usr/lib/python3.12/xml/dom/minidom.py", line 2000, in parseString\n return expatbuilder.parseString(string)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File "/usr/lib/python3.12/xml/dom/expatbuilder.py", line 922, in parseString\n return builder.parseString(string)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File "/usr/lib/python3.12/xml/dom/expatbuilder.py", line 220, in parseString\n parser.Parse(string, True)\nxml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 309\n", "module_stdout": "", "msg": "MODULE FAILURE: No start of json char found\nSee stdout/stderr for the exact error", "rc": 1}

Expected behavior

Ansible should have run the same code without any change as there is no change has been done.

Current behavior

It giving error as mentioned above.

Possible solution

Not sure , seems like its producing the config payload that may not be compatible for xml parser.

Steps to reproduce

  1. create a sample playbook as follows which will create the parent , child template and then add a test zone in the child template.
- name: Palo Alto test
  hosts: panorama_dev
  connection: local

  collections:
    - paloaltonetworks.panos
  vars:
    panos_admin: admin
    panos_password: youradminpass
    
    provider:
      ip_address: "{{ansible_host}}"
      username: "{{panos_admin}}"
      password: "{{panos_password}}"

  tasks: 

    - name: Create Parent template
      paloaltonetworks.panos.panos_template:
        provider: '{{ provider }}'
        name: "parent_template"

    - name: Create Child template
      paloaltonetworks.panos.panos_template:
        provider: '{{ provider }}'
        name: "child_template"

    - name: Create template stack
      paloaltonetworks.panos.panos_template_stack:
        provider: '{{ provider }}'
        name: "test_template_stack"
        templates: ["parent_template" , "child_template"]

    - name: Create firewall zone
      paloaltonetworks.panos.panos_zone:
        provider: "{{ provider }}"
        zone: "external"
        mode: "layer3"
        template: "child_template"
            
    - name: commit candidate configs on panorama
      paloaltonetworks.panos.panos_commit_panorama:
        provider: '{{ provider }}'
      ignore_errors: true
  1. run the playbook e.g ansible-playbook template_test_for_github.yml -i inventory.yml

  2. First run should be successful and it creates required resources , on second run it fails with the error mentioned in the description.

Screenshots

Context

We are tying to create the resources that would be available to firewall via designated template stack.

Your Environment

  • Collection: paloaltonetworks.panos 2.21.4
  • Python: 3.12.3
  • Ansible: core 2.18.4]
  • PAN-OS Python Library & version (e.g. pandevice 0.14.0, pan-os-python 1.0.2):
  • pan-os-python 1.12.1
  • pan-python 0.17.0
  • pandevice 0.14.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions