This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

MikroTik API Lua library
#1
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

Attached Files
.lua   mikrotik.lua (Size: 3.85 KB / Downloads: 46)
Reply
#2
Hijacking this thread for a quick question:

Has anyone done the same type of integration towards Ubiquiti Unify routers/controllers?
Reply
#3
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/showthrea...3#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)
Reply
#4
(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
Reply
#5
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')
Reply
#6
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
Reply
#7
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;

}
Reply
#8
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.
Reply
#9
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.
Reply
#10
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)
Reply
#11
(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!!
Reply
#12
(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/showthrea...3#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!
Reply
#13
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?
Reply
#14
Post your full script and check that user.mikrotik library has correct contents.
Reply
#15
I am sorry. Copied the original library again and it worked.
Thanks!
Reply
#16
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
Reply


Forum Jump: