Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't change value of nat using api_find_and_modify #169

Open
ZamanOof opened this issue May 18, 2023 · 8 comments
Open

can't change value of nat using api_find_and_modify #169

ZamanOof opened this issue May 18, 2023 · 8 comments

Comments

@ZamanOof
Copy link

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

@felixfontein
Copy link
Collaborator

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.

@ZamanOof
Copy link
Author

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

@felixfontein
Copy link
Collaborator

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.

@ZamanOof
Copy link
Author

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'

@felixfontein
Copy link
Collaborator

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 }}"

?

@ZamanOof
Copy link
Author

ZamanOof commented May 20, 2023

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
Copy link
Author

ZamanOof commented May 21, 2023

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

@Tualua
Copy link

Tualua commented Jan 19, 2024

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})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants