Logic Machine Forum
MikroTik API Lua library - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: MikroTik API Lua library (/showthread.php?tid=2911)



MikroTik API Lua library - admin - 20.10.2020

Use attached code to create a user library named mikrotik.
Make sure that your router is running at least v6.43.
It is recommended to create a separate user for api access, possibly with limited read-only access if you don't need to change anything on the router remotely.

Example:
Code:
mt, err = require('user.mikrotik').new('192.168.1.1')

if mt then
  res, err = mt:login('api', '123456') -- user api, pass 123456

  if res then
    -- get wireless registration table
    res, err = mt:readlist('/interface/wireless/registration-table/print')
    log(res)
  else
    log('login failed', tostring(err))
  end

  mt:close()
else
  log('connect failed', tostring(err))
end



RE: MikroTik API Lua library - FatMax - 20.10.2020

Hijacking this thread for a quick question:

Has anyone done the same type of integration towards Ubiquiti Unify routers/controllers?


RE: MikroTik API Lua library - admin - 20.10.2020

Unify API is done via HTTP requests. You need to send one request for login, get a cookie value from it and pass this cookie to any other requests after that.
Here's an example that can be used as a starting point: https://forum.logicmachine.net/showthread.php?tid=2831&pid=18233#pid18233
The difference is that this example uses standard POST whereas Unify communicates via raw POST / JSON. Like this:
Code:
http = require('socket.http')
json = require('json')

login_url = 'https://IP:8443/api/login'
data = json.encode({
  username = user,
  password = pass,
})

res, err, hdrs = http.request(login_url, data)
log(res, err, hdrs)



RE: MikroTik API Lua library - gjniewenhuijse - 20.10.2020

(20.10.2020, 06:57)admin Wrote: Use attached code to create a user library named mikrotik.
Make sure that your router is running at least v6.43.
It is recommended to create a separate user for api access, possibly with limited read-only access if you don't need to change anything on the router remotely.

Example:
Code:
mt, err = require('user.mikrotik').new('192.168.1.1')

if mt then
  res, err = mt:login('api', '123456') -- user api, pass 123456

  if res then
    -- get wireless registration table
    res, err = mt:readlist('/interface/wireless/registration-table/print')
    log(res)
  else
    log('login failed', tostring(err))
  end

  mt:close()
else
  log('connect failed', tostring(err))
end
-- get wireless registration table if you use capsman Smile
/caps-man/registration-table/print


RE: MikroTik API Lua library - DGrandes - 03.12.2020

Hi,

I have a question about writing in Mikrotik using API.
For example add an interface:

/ip address add address=192.168.88.1/24 interface=ether3 disabled=no

I´ve tried with this code but i doesn´t know how to add an IP address:
res, err = mtConfusedend('/ip/address/add/address=192.168.88.1/24')


RE: MikroTik API Lua library - admin - 04.12.2020

Each parameter must be specified as a separate string in =param=value format.
Code:
res, err = mt:send('/ip/address/add', '=interface=ether2-master', '=address=192.168.0.1/24', '=disabled=no')
if res then
  res, err = mt:read()
  log(res, err)
else
  log('send failed', tostring(err))
end



RE: MikroTik API Lua library - DGrandes - 07.12.2020

Thanks so much!! It works

I have another problem with api:

I´ve created an script in Mikrotik that works when I execute it directly from Mikrotik but if I execute it from LM Api, it runs but only the first line:


Code:
{

/tool fetch url="http://remote:AAaa1111@192.168.2.205/scada-remote" http-data="m=json&r=grp&fn=write&alias=38/6/100&value=true" http-method=post as-value output=user;

:delay 5

/tool fetch url="http://remote:AAaa1111@192.168.2.205/scada-remote" http-data="m=json&r=grp&fn=write&alias=38/6/100&value=false" http-method=post as-value output=user;

:delay 5


/tool fetch url="http://remote:AAaa1111@192.168.2.205/scada-remote" http-data="m=json&r=grp&fn=write&alias=38/6/100&value=true" http-method=post as-value output=user;

}



RE: MikroTik API Lua library - admin - 07.12.2020

The default timeout is 5 seconds, you can try increasing it by editing the library code. Why do you need this script on Mikrotik? LM can run the same HTTP queries.


RE: MikroTik API Lua library - DGrandes - 07.12.2020

Because I´m trying doing bandwith test and get the result from LM but when I send this comand from LM: "/tool bandwidth-test 38.104.52.187 duration=10s direction=both protocol=tcp user=btest pass=btest" give me the result in the moment, not final result.

Because of this, i´m trying doing the same with an script. I run Bandwidth test script from LM and this script response me with Bandwidth results. But doesn´t work neither.


RE: MikroTik API Lua library - admin - 09.12.2020

For bandwidth test you need to use readlist because MT will report test result every second (this also means that the timeout value should not be changed). The last element of res table will contain the final result.
Code:
res, err = mt:readlist('/tool/bandwidth-test', '=address=38.104.52.187', '=duration=10s', '=direction=both', '=protocol=tcp', '=user=btest', '=password=btest')
testresults = res[ #res ]
log(testresults, err)



RE: MikroTik API Lua library - DGrandes - 09.12.2020

(09.12.2020, 07:19)admin Wrote: For bandwidth test you need to use readlist because MT will report test result every second (this also means that the timeout value should not be changed). The last element of res table will contain the final result.
Code:
res, err = mt:readlist('/tool/bandwidth-test', '=address=38.104.52.187', '=duration=10s', '=direction=both', '=protocol=tcp', '=user=btest', '=password=btest')
testresults = res[ #res ]
log(testresults, err)

Perfect! 

Thanks!!


RE: MikroTik API Lua library - FatMax - 07.01.2021

(20.10.2020, 12:13)admin Wrote: Unify API is done via HTTP requests. You need to send one request for login, get a cookie value from it and pass this cookie to any other requests after that.
Here's an example that can be used as a starting point: https://forum.logicmachine.net/showthread.php?tid=2831&pid=18233#pid18233
The difference is that this example uses standard POST whereas Unify communicates via raw POST / JSON. Like this:
Code:
http = require('socket.http')
json = require('json')

login_url = 'https://IP:8443/api/login'
data = json.encode({
  username = user,
  password = pass,
})

res, err, hdrs = http.request(login_url, data)
log(res, err, hdrs)

Finally got around to get credentials and actually test this out. With the help from your example I managed to fetch a list over active clients. Thank you very much!


RE: MikroTik API Lua library - Igori - 10.01.2021

Hello!
I'm trying this method of connecting to a Mikrotik, I did everything according to the instructions. But I get the following error in the examle script:

"Resident script:1: attempt to index a boolean value
stack traceback:"

What's wrong?


RE: MikroTik API Lua library - admin - 11.01.2021

Post your full script and check that user.mikrotik library has correct contents.


RE: MikroTik API Lua library - Igori - 11.01.2021

I am sorry. Copied the original library again and it worked.
Thanks!


RE: MikroTik API Lua library - edgars - 26.08.2021

Example: how to disable list of Mikrotik access points (managed by capsman) with the comment "ap"

Code:
mt, err = require('user.mikrotik').new('192.168.0.11') -- capsman manager IP 192.168.0.11

if mt then
  res, err = mt:login('api', 'Password123') -- user api, password Password123

  if res then
   list, err = mt:readlist('/caps-man/interface/print')

    for _, item in ipairs(list) do
      id = item['.id']
     
      if id and item.comment == 'ap' then
        r1, e1 = mt:send('/caps-man/interface/disable', '=.id=' .. id)
        r2, e2 = mt:read()
        -- log(id, r1, e1, r2, e2)
      end
   end
  else
    log('login failed', tostring(err))
  end
  mt:close()
else
  log('connect failed', tostring(err))
end