community.routeros icon indicating copy to clipboard operation
community.routeros copied to clipboard

can't change value of nat using api_find_and_modify

Open ZamanOof opened this issue 1 year ago • 8 comments

SUMMARY

when try to use api_find_and_modify can't get what i want by find based on input then change the value and i get the result ok (success) when remove require_matches_min: 1 but there is no change of values: so try to change it to get what i want but no luck

failed: [any -> localhost] (item=[443, 'hello.com']) => {
    "ansible_loop_var": "item",
    "changed": false,
    "invocation": {
        "module_args": {
            "allow_no_matches": false,
            "ca_path": "keys/trust.test.ca.crt",
            "encoding": "ASCII",
            "find": {
                "action": "masquerade",
                "chain": "srcnat",
                "disabled": "yes",
                "dst-address-list": "hello.com",
                "dst-port": "443",
                "protocol": "tcp",
                "src-address": "192.168.14.16"
            },
            "force_no_cert": false,
            "hostname": "gpsm.test",
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "path": "ip firewall nat",
            "port": null,
            "require_matches_max": null,
            "require_matches_min": 1,
            "timeout": 10,
            "tls": false,
            "username": "admin",
            "validate_cert_hostname": false,
            "validate_certs": true,
            "values": {
                "disabled": "no"
            }
        }
    },
    "item": [
        443,
        "hello.com"
    ],
    "msg": "Found no entries, but allow_no_matches=false"
}
failed: [any -> localhost] (item=[80, 'hello.com']) => {
    "ansible_loop_var": "item",
    "changed": false,
    "invocation": {
        "module_args": {
            "allow_no_matches": false,
            "ca_path": "keys/trust.test.ca.crt",
            "encoding": "ASCII",
            "find": {
                "action": "masquerade",
                "chain": "srcnat",
                "disabled": "yes",
                "dst-address-list": "hello.com",
                "dst-port": "80",
                "protocol": "tcp",
                "src-address": "192.168.14.16"
            },
            "force_no_cert": false,
            "hostname": "gpsm.test",
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "path": "ip firewall nat",
            "port": null,
            "require_matches_max": null,
            "require_matches_min": 1,
            "timeout": 10,
            "tls": false,
            "username": "admin",
            "validate_cert_hostname": false,
            "validate_certs": true,
            "values": {
                "disabled": "no"
            }
        }
    },
    "item": [
        80,
        "hello.com"
    ],
    "msg": "Found no entries, but allow_no_matches=false"
}
failed: [any -> localhost] (item=[80, 'google.com']) => {
    "ansible_loop_var": "item",
    "changed": false,
    "invocation": {
        "module_args": {
            "allow_no_matches": false,
            "ca_path": "keys/trust.test.ca.crt",
            "encoding": "ASCII",
            "find": {
                "action": "masquerade",
                "chain": "srcnat",
                "disabled": "yes",
                "dst-address-list": "google.com",
                "dst-port": "80",
                "protocol": "tcp",
                "src-address": "192.168.14.16"
            },
            "force_no_cert": false,
            "hostname": "gpsm.test",
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "path": "ip firewall nat",
            "port": null,
            "require_matches_max": null,
            "require_matches_min": 1,
            "timeout": 10,
            "tls": false,
            "username": "admin",
            "validate_cert_hostname": false,
            "validate_certs": true,
            "values": {
                "disabled": "no"
            }
        }
    },
    "item": [
        80,
        "google.com"
    ],
    "msg": "Found no entries, but allow_no_matches=false"
}
failed: [any -> localhost] (item=[443, 'google.com']) => {
    "ansible_loop_var": "item",
    "changed": false,
    "invocation": {
        "module_args": {
            "allow_no_matches": false,
            "ca_path": "keys/trust.test.ca.crt",
            "encoding": "ASCII",
            "find": {
                "action": "masquerade",
                "chain": "srcnat",
                "disabled": "yes",
                "dst-address-list": "google.com",
                "dst-port": "443",
                "protocol": "tcp",
                "src-address": "192.168.14.16"
            },
            "force_no_cert": false,
            "hostname": "gpsm.test",
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "path": "ip firewall nat",
            "port": null,
            "require_matches_max": null,
            "require_matches_min": 1,
            "timeout": 10,
            "tls": false,
            "username": "admin",
            "validate_cert_hostname": false,
            "validate_certs": true,
            "values": {
                "disabled": "no"
            }
        }
    },
    "item": [
        443,
        "google.com"
    ],
    "msg": "Found no entries, but allow_no_matches=false"
}

Sure

ISSUE TYPE
  • Your Report not sure if it's bug or need more info
COMPONENT NAME
montip: 192.168.14.16
montport: [443,80] #443/80
montproto: tcp #tcp/udp
user: root
websites: ['hello.com','google.com']
- name: Adjust NAT
community.routeros.api_find_and_modify:
  hostname: "{{ hostname }}"
  password: "{{ password }}"
  username: "{{ username }}"
  ca_path: "{{ ca_path }}"
  path: ip firewall nat
  find: >-
   src-address={{ montip }}
   protocol={{ montproto }}
   dst-address-list={{ item.1 }}
   dst-port={{ item.0 }}
   chain={{ natchain }}
   action={{ nataction }}
   out-interface-list={{ interfacelist }}
   disabled={{ natstatus }}
  values: 
    disabled: "no"
  require_matches_min: 1
  # allow_no_matches=true
  # require_matches_max: 1
delegate_to: localhost
register:   QueryNatOut
with_nested:  
  - "{{ montport }}"
  - "{{ websites }}"
ANSIBLE VERSION
ansible [core 2.13.3]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/user/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.16 (main, Dec 21 2022, 10:57:18) [GCC 8.5.0 20210514 (Red Hat 8.5.0-17)]
  jinja version = 3.1.2
  libyaml = True

Thanks

ZamanOof avatar May 18 '23 18:05 ZamanOof

Note that you are passing the string "yes" to disabled (for the find option), which won't match since disabled is a boolean. You should pass the boolean value true.

felixfontein avatar May 18 '23 19:05 felixfontein

Note that you are passing the string "yes" to disabled (for the find option), which won't match since disabled is a boolean. You should pass the boolean value true.

are you mean on find should use boolean? strange bcs when create nat details with string 'yes' and mikrotik as i know support yes,no for like disabled so how i know to use boolean or yes,no ? thanks

ZamanOof avatar May 19 '23 11:05 ZamanOof

MikroTik converts yes/no strings to boolean. But the module does not, it compares what you pass in with what the router sends back. So if you provide a string yes and the router says true, these are not equal.

felixfontein avatar May 19 '23 15:05 felixfontein

MikroTik converts yes/no strings to boolean. But the module does not, it compares what you pass in with what the router sends back. So if you provide a string yes and the router says true, these are not equal.

still the same, try string and boolean show "msg": "Found no entries, but allow_no_matches=false and the boolean on ansible show as true but mikrotik support 'yes' 'no'

ZamanOof avatar May 20 '23 11:05 ZamanOof

How does your task look like?

Also, is there a reason you are not using a YAML dictionary for find, like

...
  find:
   src-address: "{{ montip }}"
   protocol: "{{ montproto }}"
   dst-address-list: "{{ item.1 }}"
   dst-port: "{{ item.0 }}"
   chain: "{{ natchain }}"
   action: "{{ nataction }}"
   out-interface-list: "{{ interfacelist }}"
   disabled: "{{ natstatus }}"

?

felixfontein avatar May 20 '23 13:05 felixfontein

How does your task look like?

Also, is there a reason you are not using a YAML dictionary for find, like

...
  find:
   src-address: "{{ montip }}"
   protocol: "{{ montproto }}"
   dst-address-list: "{{ item.1 }}"
   dst-port: "{{ item.0 }}"
   chain: "{{ natchain }}"
   action: "{{ nataction }}"
   out-interface-list: "{{ interfacelist }}"
   disabled: "{{ natstatus }}"

?

i tried this before as u see (this copy/past from executed .yml file)

        find: 
          dst-port: "{{ item.0 }}"
          chain: "{{ natchain }}"
          src-address: "{{ montip }}"
          protocol: "{{ montproto }}"
          dst-address-list: "{{ item.1 }}"
          action: "{{ nataction }}"
          out-interface-list: "{{ interfacelist }}"
          disabled: "{{ natstatus }}"

ZamanOof avatar May 20 '23 18:05 ZamanOof

Hello, i try the same values in mikrotik directly but no success look like there is limitation or requirement when using it the command

set [find ...] disabled=no 

more check forum.mikrotik.com forum.mikrotik.com

ZamanOof avatar May 21 '23 13:05 ZamanOof

Got the same problem.

I think I've found the root of the problem, but I can't figure any workaround.

I believe it is integer vs string.

find:
          dst-port: “16800”

does not work

(item={'comment': 'vm28.hv10 TCP 14000', 'dst_port': 16800, 'protocol': 'tcp', 'to_addresses': '192.168.201.128', 'to_ports': 16800}) => {"ansible_loop_var": "item", "changed": false, "item": {"comment": "vm28.hv10 TCP 14000", "dst_port": 16800, "protocol": "tcp", "to_addresses": "192.168.201.128", "to_ports": 16800}, "msg": "Found no entries, but allow_no_matches=false"}

find:
          dst-port: 16800

this one works

changed: [hv10 -> localhost] => (item={'comment': 'vm28.hv10 TCP 14000', 'dst_port': 16800, 'protocol': 'tcp', 'to_addresses': '192.168.201.128', 'to_ports': 16800})

Tualua avatar Jan 19 '24 07:01 Tualua