colin
September 25, 2024, 10:47am
1
Hi All:
I want to query some nat rules via restful api,for some simple queries it has been implemented.
But i don’t know how to query like this:
(chain=chain1 or chain=chain2) and (action=netmap or action=log) and src-address=fd00:0:0:3::/64
Can anyone give some help? Thank you.
Amm0
September 25, 2024, 11:18am
2
You have to use a POST method, and use the “.query” parameter to specify the filter to apply. But the syntax for .query is stack-based is a bit complex. There are some examples here; http://forum.mikrotik.com/t/how-using-query-stack-in-rest-api/173298/1
The other approach is to do a GET (or POST …/print) to get the full list, and in your code/script process the results. For example, using a linux/mac/WSL shell with curl, you can use jq to do the filtering AFTER it comes back from Mikrotik.
Amm0
September 25, 2024, 11:19am
3
colin
September 25, 2024, 11:49am
4
Yes, with your help i can do simple queries. Thank you again.
But for the example:(chain=chain1 or chain=chain2) and (action=netmap or action=log) and src-address=fd00:0:0:3::/64,
i still don’t know how to write the query operations.
Tried the following code, not work:
{
".query": [
"chain=chain2",
"chain=chain1",
"action=netmap",
"action=log",
"src-address=fd00:0:0:3::/64",
"#&|&|"
],
".proplist": ".id,chain,action,to-addresses,out-interface"
}
Amm0
September 26, 2024, 4:25am
5
You can have multiple “#operators ” to resolve the stack as you go.
{
".query": [
"chain=chain2",
"chain=chain1",
"#|",
"action=netmap",
"action=log",
"#|&"
"src-address=fd00:0:0:3::/64",
"#&"
],
".proplist": ".id,chain,action,to-addresses,out-interface"
}
I test this using “raw” rules & fetch to localhost:
/ip firewall raw
add action=passthrough chain=chain1 comment=show
add action=passthrough chain=chain2
add action=log chain=chain2 comment=show
add action=log chain=chain1
:global auth {"user"="XXXX"; "password"="XXXXX"}
:global bodyarray {".proplist"="chain,action,comment" ; ".query"={ "chain=chain1"; "chain=chain2"; "#|"; "action=log"; "action=passthrough"; "#|&"; "comment=show"}}
/tool fetch http-method=post user=($auth->"user") password=($auth->"password") \
http-header-field="Content-Type: application/json" \
url=http://localhost/rest/ip/firewall/raw/print \
http-data=[:serialize to=json $bodyarray] \
output=user
status: finished
downloaded: 0KiBC-z pause]
total: 0KiB
duration: 1s
data: [{“action”:“passthrough”,“chain”:“chain1”,“comment”:“show”},{“action”:“log”,“chain”:“chain2”,“comment”:“show”}]
colin
September 26, 2024, 8:17am
6
Oh my god, i thought there could only be one line of operators. Thank you.
Amm0
September 26, 2024, 12:26pm
7
If you have haven’t used an old RPN-based HP calculator, you’d think Mikrotik was crazy for how this works. You can have multiple operators in one line, but you can ALSO have multiple “#operators ” in the string array passed to REST POST too.
And, the docs leave you hanging on the whole “.query” topic and REST API and POST. REST API docs mention .query exists with a passing reference elsewhere that POST follows the native API scheme, and the API docs link to a forum post with more examples (in API context) of “.query stacks”: http://forum.mikrotik.com/t/api-queries-complex-queries-please-explain/65851/1
colin
September 27, 2024, 4:37am
8
If you have haven’t used an old RPN-based HP calculator, you’d think Mikrotik was crazy for how this works. You can have multiple operators in one line, but you can ALSO have multiple “#operators ” in the string array passed to REST POST too.
And, the docs leave you hanging on the whole “.query” topic and REST API and POST. REST API docs mention .query exists with a passing reference elsewhere that POST follows the native API scheme, and the API docs link to a forum post with more examples (in API context) of “.query stacks”: http://forum.mikrotik.com/t/api-queries-complex-queries-please-explain/65851/1
Yes, with your example, I understand how the operator works, and thus understand how the underlying layer is implemented.