fortinet-ansible-dev / ansible-galaxy-fortimanager-collection

GNU General Public License v3.0
16 stars 15 forks source link

fmgr_firewall_address_dynamicmapping fails if _scope parameter is not added or is added as an empty list #75

Closed albertogd closed 7 months ago

albertogd commented 7 months ago

Using the module fmgr_firewall_address_dynamicmapping, if I don't add the parameter _scope (which is not mandatory), the module fails with the error TypeError: 'NoneType' object is not subscriptable.

I think there is an issue with the variable _scope not being properly initialized and managed in the code, as it should be possible to have an empty _scope.

  1. Running this playbook without _scope parameter:
    - name: Configure dynamic mappings of IPv4 address
      fortinet.fortimanager.fmgr_firewall_address_dynamicmapping:
        adom: "{{adomname}}"
        address: "{{addressname}}"
        firewall_address_dynamicmapping:
          allow-routing: disable
          cache-ttl: 0
          color: 0
          fabric-object: disable
          subnet: "{{subnet}}"
          uuid: "00000000-0000-0000-0000-000000000000"
        state: present

The result is TypeError: 'NoneType' object is not subscriptable error:

 File "/tmp/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload_s6xi86u0/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload.zip/ansible_collections/fortinet/fortimanager/plugins/modules/fmgr_firewall_address_dynamicmapping.py", line 3030, in <module>
  File "/tmp/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload_s6xi86u0/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload.zip/ansible_collections/fortinet/fortimanager/plugins/modules/fmgr_firewall_address_dynamicmapping.py", line 3023, in main
  File "/tmp/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload_s6xi86u0/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload.zip/ansible_collections/fortinet/fortimanager/plugins/module_utils/napi.py", line 1129, in process_curd
  File "<string>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable
  1. Adding an empty _scope to the playbook:
    - name: Configure dynamic mappings of IPv4 address
      fortinet.fortimanager.fmgr_firewall_address_dynamicmapping:
        adom: "{{adomname}}"
        address: "{{addressname}}"
        firewall_address_dynamicmapping:
          _scope: []
          allow-routing: disable
          cache-ttl: 0
          color: 0
          fabric-object: disable
          subnet: "{{subnet}}"
          uuid: "00000000-0000-0000-0000-000000000000"
        state: present

I get an IndexError: list index out of range error:

  File "/tmp/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload_9v65262a/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload.zip/ansible_collections/fortinet/fortimanager/plugins/modules/fmgr_firewall_address_dynamicmapping.py", line 3030, in <module>
  File "/tmp/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload_9v65262a/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload.zip/ansible_collections/fortinet/fortimanager/plugins/modules/fmgr_firewall_address_dynamicmapping.py", line 3023, in main
  File "/tmp/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload_9v65262a/ansible_fortinet.fortimanager.fmgr_firewall_address_dynamicmapping_payload.zip/ansible_collections/fortinet/fortimanager/plugins/module_utils/napi.py", line 1129, in process_curd
  File "<string>", line 1, in <module>
IndexError: list index out of range

The API request that is working is:

{
                "method": "add",
                "params":
                [
                    {
                        "data":
                        {
                            "allow-routing": 0,
                            "cache-ttl": 0,
                            "color": 0,
                            "dirty": 1,
                            "dynamic_mapping":
                            [],
                            "fabric-object": 0,
                            "interface": null,
                            "name": "{{addressname}}",
                            "node-ip-only": 0,
                            "obj-type": 9,
                            "sdn-addr-type": 0,
                            "sub-type": 0,
                            "subnet": "{{subnet}}",
                            "type": 0,
                            "uuid": "00000000-0000-0000-0000-000000000000",
                            "wildcard": "0.0.0.0/0.0.0.0"
                        },
                        "url": "pm/config/adom/{{adomname}}/obj/firewall/address"
                    }
                ],
            }
dux-fortinet commented 7 months ago

Hi Alberto,

Your API request example calls the API: pm/config/adom/{{adomname}}/obj/firewall/address (corresponding to fmgr_firewall_address in fortimanager ansible collection) However, fmgr_firewall_address_dynamicmapping calls the API /pm/config/adom/{adom}/obj/firewall/address/{address}/dynamic_mapping

Here is an example of the URL ends with dynamic_mapping:

{
    "method": "set",
    "params": [
        {
            "url": "/pm/config/adom/{{adom_name}}/obj/firewall/address/{{address_name}}/dynamic_mapping",
            "data": {
                "_scope": [
                    {
                        "name": "{{device_name}}",
                        "vdom": "{{device_vdom_name}}"
                    }
                ],
                "subnet": [
                    "0.0.0.0",
                    "0.0.0.0"
                ],
                "type": 0,
                "color": 0,
                "uuid": "xxxxxxxxxxxxxxxxxx",
                "allow-routing": 0,
                "clearpass-spt": 0,
                "obj-type": 9,
                "node-ip-only": 0,
                "fabric-object": 0,
                "macaddr": [],
                "dirty": 1,
                "unset attrs": [
                    "associated-interface"
                ]
            }
        }
    ],
    "session": "{{fortimanager_session}}",
    "id": 6,
    "verbose": 1
}

And this API requires you specify '_scope'. I think adding _scope is mandatory in dynamic_mapping:

 "_scope": [
    {
        "name": "{{device_name}}",
        "vdom": "{{device_vdom_name}}"
    }
],

If you don't, you will get error: "The data is invalid for selected url"

The example you provide works well because it uses URL "pm/config/adom/{{adomname}}/obj/firewall/address" and does not specify dynamic_mapping. Yet if you want to specify dynamic_mapping, you have to add _scope in dynamic_mapping.

The module fmgr_firewall_address_dynamicmapping in fortimanager ansible collection assumes you define ["_scope"][0]["name"] and ["_scope"][0]["vdom"]. And you get the error if you don't.

albertogd commented 7 months ago

Thank you very much. You're totally right: we had to use fmgr_firewall_address instead of fmgr_firewall_address_dynamicmapping. We used the module fmgr_firewall_address and it worked great.