API Ruby class
Ruby GEM
The API Ruby class(es) are now packaged together as a Ruby GEM. The latest GEM is available for download from the author's web site. The current version is 3.0.0 available here:
RDoc Documentation
The author's site also hosts Ruby RDoc documents for the classes implementing this API. The link is:
Examples
Several example scripts are included with the GEM or available for direct download from the author.
- tikcli.rb - A command-line-like interactive ruby script. You can type MikroTik API commands and arguments directly and have them executed.
- tikcommand.rb - A non-interactive command-line script to execute a single MikroTik API command and return the results to STDOUT.
- tikjson.rb - Another non-interactive command-line script that executes a single MikroTik API command and returns the results to STDOUT, however the results are encoded in JSON format. One could easily add CGI handling to this script, install it on a web server, and use it via a web browser. (The author in fact has done something like this for a JavaScript-based management web application that interacts with MikroTik devices via the API.)
- tikfetch.rb - This non-interactive command-line script lets one instruct a MikroTik device to download one or more files from the provided URL(s).
Here is are several example runs of the tikcli.rb script:
user@bsdhost:~$ ./tikcli.rb 10.20.30.1 admin wrongpassword <<< '/login' (6) <<< END-OF-SENTENCE >>> '!done' (5) >>> 'ret=bf41fd4286417870c5eb86674a3b8fe4' (36) >>> '.tag=0' (6) >>> END-OF SENTENCE <<< '/login' (6) <<< '=name=admin' (11) <<< '=response=0003a042937d84ca4bc4cf7da50aadd507' (44) <<< END-OF-SENTENCE >>> '!trap' (5) >>> 'message=cannot log in' (21) >>> '.tag=1' (6) >>> END-OF SENTENCE >>> '!done' (5) >>> '.tag=1' (6) >>> END-OF SENTENCE === LOGIN ERROR: Login failed: cannot log in user@bsdhost:~$
That run was deliberately with the wrong password. Here's the login with the correct password:
user@bsdhost:~$ ./tikcli.rb 10.20.30.1 admin correctpassword <<< '/login' (6) <<< END-OF-SENTENCE >>> '!done' (5) >>> 'ret=857e91c460620a02c3ca72ea7cf6c696' (36) >>> '.tag=0' (6) >>> END-OF SENTENCE <<< '/login' (6) <<< '=name=admin' (11) <<< '=response=001a77aec14077ec267c5297969ba1fa24' (44) <<< END-OF-SENTENCE >>> '!done' (5) >>> '.tag=1' (6) >>> END-OF SENTENCE Command (/quit to end):
At this point, the interactive client will accept MikroTik API commands in the format /command/name arg1 arg2 arg3
or also 12:/command/name arg1 arg2 arg3
where the 12: is a custom numeric prefix that tells the Ruby interactive client to auto-cancel the command in question after exactly 12 reply sentences are received, since otherwise a command with continuous output would hang the single-threaded interactive client in an endless reply-handling loop (until someone aborted it).
Arguments to API commands in this interactive client must ALREADY be in the API argument form. For example:
Command (/quit to end): /interface/getall ?name=ether1 === COMMAND: /interface/getall ?name=ether1 <<< '/interface/getall' (17) <<< '?name=ether1' (12) <<< END-OF-SENTENCE >>> '!re' (3) >>> '.id=*5' (6) >>> 'name=ether1' (11) >>> 'type=ether' (10) >>> 'mtu=1500' (8) >>> 'l2mtu=1500' (10) >>> 'bytes=26908361008/15001379552' (29) >>> 'packets=34880279/26382227' (25) >>> 'drops=0/0' (9) >>> 'errors=5/0' (10) >>> 'dynamic=false' (13) >>> 'running=true' (12) >>> 'disabled=false' (14) >>> 'comment=' (8) >>> '.tag=4' (6) >>> END-OF SENTENCE >>> '!done' (5) >>> '.tag=4' (6) >>> END-OF SENTENCE Command (/quit to end):
Did you see how the user properly prefixed the query parameter name
with the query character (question mark ?) and also paired it via = with the query value? With this example CLI, you must manually format all arguments as specified by the MikroTik API.
You may have noticed that this Ruby API implementation automatically adds a unique .tag
to every command. That means if you specify a tag value, the Ruby code will ignore it and use its own. It adds a tag so that replies can be correctly matched to the appropriate request.
Now here's the same query again, only add another parameter, =interval=1
so that the command will repeatedly send output each second. To avoid the command continuing forever, it will be prefixed with 6: (this CLI script strips the digit(s) and colon before sending the command to the device) to limit the number of response sentences to exactly six before the interactive client will automagically issue an appropriate /cancel =tag=XYZ
command to cancel it.
Command (/quit to end): 6:/interface/getall ?name=ether1=interval=1 === COMMAND: /interface/getall ?name=ether1=interval=1 <<< '/interface/getall' (17) <<< '?name=ether1' (12) <<< '=interval=1' (11) <<< END-OF-SENTENCE >>> '!re' (3) >>> '.id=*5' (6) >>> 'name=ether1' (11) >>> 'type=ether' (10) >>> 'mtu=1524' (8) >>> 'l2mtu=1524' (10) >>> 'bytes=26909135851/15002882324' (29) >>> 'packets=34886461/26387909' (25) >>> 'drops=0/0' (9) >>> 'errors=5/0' (10) >>> 'dynamic=false' (13) >>> 'running=true' (12) >>> 'disabled=false' (14) >>> 'comment=' (8) >>> '.tag=2' (6) >>> END-OF SENTENCE >>> '!re' (3) >>> '.id=*5' (6) >>> 'name=ether1' (11) >>> 'type=ether' (10) >>> 'mtu=1524' (8) >>> 'l2mtu=1524' (10) >>> 'bytes=26909140098/15002892177' (29) >>> 'packets=34886498/26387943' (25) >>> 'drops=0/0' (9) >>> 'errors=5/0' (10) >>> 'dynamic=false' (13) >>> 'running=true' (12) >>> 'disabled=false' (14) >>> 'comment=' (8) >>> '.tag=2' (6) >>> END-OF SENTENCE >>> '!re' (3) >>> '.id=*5' (6) >>> 'name=ether1' (11) >>> 'type=ether' (10) >>> 'mtu=1524' (8) >>> 'l2mtu=1524' (10) >>> 'bytes=26909141508/15002893670' (29) >>> 'packets=34886508/26387951' (25) >>> 'drops=0/0' (9) >>> 'errors=5/0' (10) >>> 'dynamic=false' (13) >>> 'running=true' (12) >>> 'disabled=false' (14) >>> 'comment=' (8) >>> '.tag=2' (6) >>> END-OF SENTENCE >>> '!re' (3) >>> '.id=*5' (6) >>> 'name=ether1' (11) >>> 'type=ether' (10) >>> 'mtu=1524' (8) >>> 'l2mtu=1524' (10) >>> 'bytes=26909143624/15002895110' (29) >>> 'packets=34886524/26387963' (25) >>> 'drops=0/0' (9) >>> 'errors=5/0' (10) >>> 'dynamic=false' (13) >>> 'running=true' (12) >>> 'disabled=false' (14) >>> 'comment=' (8) >>> '.tag=2' (6) >>> END-OF SENTENCE >>> '!re' (3) >>> '.id=*5' (6) >>> 'name=ether1' (11) >>> 'type=ether' (10) >>> 'mtu=1524' (8) >>> 'l2mtu=1524' (10) >>> 'bytes=26909144116/15002895406' (29) >>> 'packets=34886530/26387967' (25) >>> 'drops=0/0' (9) >>> 'errors=5/0' (10) >>> 'dynamic=false' (13) >>> 'running=true' (12) >>> 'disabled=false' (14) >>> 'comment=' (8) >>> '.tag=2' (6) >>> END-OF SENTENCE >>> '!re' (3) >>> '.id=*5' (6) >>> 'name=ether1' (11) >>> 'type=ether' (10) >>> 'mtu=1524' (8) >>> 'l2mtu=1524' (10) >>> 'bytes=26909144824/15002896659' (29) >>> 'packets=34886535/26387973' (25) >>> 'drops=0/0' (9) >>> 'errors=5/0' (10) >>> 'dynamic=false' (13) >>> 'running=true' (12) >>> 'disabled=false' (14) >>> 'comment=' (8) >>> '.tag=2' (6) >>> END-OF SENTENCE <<< '/cancel' (7) <<< '=tag=2' (6) <<< END-OF-SENTENCE >>> '!trap' (5) >>> 'category=2' (10) >>> 'message=interrupted' (19) >>> '.tag=2' (6) >>> END-OF SENTENCE === TRAP: 'interrupted' >>> '!done' (5) >>> '.tag=3' (6) >>> END-OF SENTENCE >>> '!done' (5) >>> '.tag=2' (6) >>> END-OF SENTENCE Command (/quit to end):
TO COME: Some non-interactive examples of using the Ruby API.
Notes
- This has only been testing using Ruby 1.9.1 and Ruby 1.8.7 on several FreeBSD hosts, though it should work identically on other Ruby installations.
- Encoding/decoding longer words has NOT be thoroughly tested.
- Connection timeouts and auto-reconnections are NOT implemented.
- The above code is single-threaded, but is probably be safe to use within a multi-threaded Ruby application (untested).
- The 3.0.0 GEM version uses an event/callback style to send commands and receive responses.
- The 3.0.0 GEM version DOES support multiple simultaneous commands, and supports commands that send back periodic continual responses, but you have to be careful to implement a main event loop for this functionality to work correctly.
See also
External links
- developers page: astounding hosted page
- forum discussion mikrotik forum and Other Mikrotik forum thread