UNPKG

mikronode-ng

Version:

Mikrotik API implemented in Node

479 lines (332 loc) 22.4 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Index</title> <meta property="og:title" content=""/> <meta property="og:type" content="website"/> <meta property="og:image" content=""/> <meta property="og:url" content=""/> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <script src="scripts/jquery.min.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css"> <link type="text/css" rel="stylesheet" href="styles/jaguar.css"> <script> var config = {"monospaceLinks":true,"cleverLinks":true,"default":{"outputSourceFiles":true},"applicationName":"MikroNode","disqus":"","googleAnalytics":"","openGraph":{"title":"","type":"website","image":"","site_name":"","url":""},"meta":{"title":"","description":"","keyword":""},"linenums":false}; </script> </head> <body> <div id="wrap" class="clearfix"> <div class="navigation"> <h3 class="applicationName"><a href="index.html">MikroNode</a></h3> <div class="search"> <input id="search" type="text" class="form-control input-sm" placeholder="Search Documentations"> </div> <ul class="list"> <li class="item" data-name="mikronode-ng"> <span class="title"> <a href="mikronode-ng.html">mikronode-ng</a> <span class="static">static</span> </span> <ul class="members itemMembers"> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="methods itemMembers"> <span class="subtitle">Methods</span> <li data-name="mikronode-ng.getConnection"><a href="mikronode-ng.html#.getConnection">getConnection</a></li> <li data-name="mikronode-ng.parseItems"><a href="mikronode-ng.html#.parseItems">parseItems</a></li> </ul> <ul class="events itemMembers"> </ul> </li> <li class="item" data-name="mikronode-ng.Channel"> <span class="title"> <a href="mikronode-ng.Channel.html">mikronode-ng.Channel</a> </span> <ul class="members itemMembers"> <span class="subtitle">Members</span> <li data-name="mikronode-ng.Channel#clearEvents"><a href="mikronode-ng.Channel.html#clearEvents">clearEvents</a></li> <li data-name="mikronode-ng.Channel#closed"><a href="mikronode-ng.Channel.html#closed">closed</a></li> <li data-name="mikronode-ng.Channel#closeOnDone"><a href="mikronode-ng.Channel.html#closeOnDone">closeOnDone</a></li> <li data-name="mikronode-ng.Channel#closing"><a href="mikronode-ng.Channel.html#closing">closing</a></li> <li data-name="mikronode-ng.Channel#id"><a href="mikronode-ng.Channel.html#id">id</a></li> <li data-name="mikronode-ng.Channel#lastCommand"><a href="mikronode-ng.Channel.html#lastCommand">lastCommand</a></li> <li data-name="mikronode-ng.Channel#running"><a href="mikronode-ng.Channel.html#running">running</a></li> <li data-name="mikronode-ng.Channel#saveBuffer"><a href="mikronode-ng.Channel.html#saveBuffer">saveBuffer</a></li> </ul> <ul class="typedefs itemMembers"> <span class="subtitle">Typedefs</span> <li data-name="mikronode-ng.Channel.writeCallback"><a href="mikronode-ng.Channel.html#.writeCallback">writeCallback</a></li> </ul> <ul class="methods itemMembers"> <span class="subtitle">Methods</span> <li data-name="mikronode-ng.Channel#close"><a href="mikronode-ng.Channel.html#close">close</a></li> <li data-name="mikronode-ng.Channel#finalize"><a href="mikronode-ng.Channel.html#finalize">finalize</a></li> <li data-name="mikronode-ng.Channel#write"><a href="mikronode-ng.Channel.html#write">write</a></li> </ul> <ul class="events itemMembers"> <span class="subtitle">Events</span> <li data-name="mikronode-ng.Channel#event:close"><a href="mikronode-ng.Channel.html#event:event:close">event:close</a></li> <li data-name="mikronode-ng.Channel#event:done"><a href="mikronode-ng.Channel.html#event:event:done">event:done</a></li> <li data-name="mikronode-ng.Channel#event:error"><a href="mikronode-ng.Channel.html#event:event:error">event:error</a></li> <li data-name="mikronode-ng.Channel#event:timeout"><a href="mikronode-ng.Channel.html#event:event:timeout">event:timeout</a></li> <li data-name="mikronode-ng.Channel#event:trap"><a href="mikronode-ng.Channel.html#event:event:trap">event:trap</a></li> </ul> </li> <li class="item" data-name="mikronode-ng.Connection"> <span class="title"> <a href="mikronode-ng.Connection.html">mikronode-ng.Connection</a> </span> <ul class="members itemMembers"> <span class="subtitle">Members</span> <li data-name="mikronode-ng.Connection#channels"><a href="mikronode-ng.Connection.html#channels">channels</a></li> <li data-name="mikronode-ng.Connection#closeOnDone"><a href="mikronode-ng.Connection.html#closeOnDone">closeOnDone</a></li> <li data-name="mikronode-ng.Connection#host"><a href="mikronode-ng.Connection.html#host">host</a></li> <li data-name="mikronode-ng.Connection#password"><a href="mikronode-ng.Connection.html#password">password</a></li> <li data-name="mikronode-ng.Connection#port"><a href="mikronode-ng.Connection.html#port">port</a></li> <li data-name="mikronode-ng.Connection#status"><a href="mikronode-ng.Connection.html#status">status</a></li> <li data-name="mikronode-ng.Connection#timeout"><a href="mikronode-ng.Connection.html#timeout">timeout</a></li> <li data-name="mikronode-ng.Connection#tls"><a href="mikronode-ng.Connection.html#tls">tls</a></li> <li data-name="mikronode-ng.Connection#user"><a href="mikronode-ng.Connection.html#user">user</a></li> </ul> <ul class="typedefs itemMembers"> <span class="subtitle">Typedefs</span> <li data-name="mikronode-ng.Connection.connectCallback"><a href="mikronode-ng.Connection.html#.connectCallback">connectCallback</a></li> </ul> <ul class="methods itemMembers"> <span class="subtitle">Methods</span> <li data-name="mikronode-ng.Connection.parseItems"><a href="mikronode-ng.Connection.html#.parseItems">parseItems</a></li> <li data-name="mikronode-ng.Connection#closeChannel"><a href="mikronode-ng.Connection.html#closeChannel">closeChannel</a></li> <li data-name="mikronode-ng.Connection#connect"><a href="mikronode-ng.Connection.html#connect">connect</a></li> <li data-name="mikronode-ng.Connection#getChannel"><a href="mikronode-ng.Connection.html#getChannel">getChannel</a></li> <li data-name="mikronode-ng.Connection#getCommandPromise"><a href="mikronode-ng.Connection.html#getCommandPromise">getCommandPromise</a></li> <li data-name="mikronode-ng.Connection#getConnectPromise"><a href="mikronode-ng.Connection.html#getConnectPromise">getConnectPromise</a></li> <li data-name="mikronode-ng.Connection#openChannel"><a href="mikronode-ng.Connection.html#openChannel">openChannel</a></li> </ul> <ul class="events itemMembers"> <span class="subtitle">Events</span> <li data-name="mikronode-ng.Connection#event:close"><a href="mikronode-ng.Connection.html#event:event:close">event:close</a></li> <li data-name="mikronode-ng.Connection#event:error"><a href="mikronode-ng.Connection.html#event:event:error">event:error</a></li> <li data-name="mikronode-ng.Connection#event:timeout"><a href="mikronode-ng.Connection.html#event:event:timeout">event:timeout</a></li> <li data-name="mikronode-ng.Connection#event:trap"><a href="mikronode-ng.Connection.html#event:event:trap">event:trap</a></li> </ul> </li> <li class="item" data-name="mikronode-ng.Trap"> <span class="title"> <a href="mikronode-ng.Trap.html">mikronode-ng.Trap</a> </span> <ul class="members itemMembers"> <span class="subtitle">Members</span> <li data-name="mikronode-ng.Trap#channel"><a href="mikronode-ng.Trap.html#channel">channel</a></li> <li data-name="mikronode-ng.Trap#channelId"><a href="mikronode-ng.Trap.html#channelId">channelId</a></li> <li data-name="mikronode-ng.Trap#errors"><a href="mikronode-ng.Trap.html#errors">errors</a></li> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="methods itemMembers"> </ul> <ul class="events itemMembers"> </ul> </li> <li class="item" data-name="mikronode-ng.TrapError"> <span class="title"> <a href="mikronode-ng.TrapError.html">mikronode-ng.TrapError</a> </span> <ul class="members itemMembers"> <span class="subtitle">Members</span> <li data-name="mikronode-ng.TrapError#category"><a href="mikronode-ng.TrapError.html#category">category</a></li> <li data-name="mikronode-ng.TrapError#message"><a href="mikronode-ng.TrapError.html#message">message</a></li> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="methods itemMembers"> </ul> <ul class="events itemMembers"> </ul> </li> </ul> </div> <div class="main"> <h1 class="page-title" data-filename="index.html">Index</h1> <h3> </h3> <section> <article class="readme"><h1>MikroNode</h1><p> Full-Featured asynchronous Mikrotik API interface for <a href="http://nodejs.org">NodeJS</a>.</p> <pre class="prettyprint source"><code> var MikroNode = require('mikronode-ng'); var connection = MikroNode.getConnection(process.argv[2], process.argv[3], process.argv[4]); connection.connect(function(conn) { var chan = conn.openChannel(); conn.closeOnDone = true; chan.write('/ip/address/print', function() { chan.closeOnDone = true; chan.on('done', function(data) { var parsed = MikroNode.parseItems(data); parsed.forEach(function(item) { console.log('Interface/IP: ' + item.interface + &quot;/&quot; + item.address); }); }); chan.once('trap', function(trap, chan) { console.log('Command failed: ' + trap); }); chan.once('error', function(err, chan) { console.log('Oops: ' + err); }); }); }); /* Now let's do this with Promises */ var connection = MikroNode.getConnection(process.argv[2], process.argv[3], process.argv[4], { closeOnDone : true }); connection.getConnectPromise().then(function(conn) { conn.getCommandPromise('/ip/address/print').then(function resolved(values) { console.log('Addreses: ' + JSON.stringify(values)); }, function rejected(reason) { console.log('Oops: ' + JSON.stringify(reason)); }); });</code></pre><h2>Installation</h2><p> Clone this repository into your node_modules directory.</p> <ul> <li>or -<br> $ npm install mikronode-ng</li> </ul> <h2>Features</h2><ul> <li>Channel based communication</li> <li>Multiple Connections can be used in parallel in the same Node process</li> <li>Multiple Channels can be used in parallel on the same Connection</li> <li>Synchronous execution of commands issued on the same channel</li> <li>Asynchrounous execution of commands issued on different channels</li> <li>Focus on high performance</li> <li>ES6 Promise support for Connection and Channel</li> <li>TLS Support</li> </ul> <h2>Upgrading from versions &lt; 1.0.0</h2><p>There are 2 changes that will need to be made...</p> <pre class="prettyprint source"><code>var MikroNode = require('mikronode-ng'); // From var connection = new MikroNode(...) // To var connection = MikroNode.getConnection(...) // or var connection = new MikroNode.Connection(...) // From connection.closeOnDone(true); channel.closeOnDone(true); // To connection.closeOnDone = true; channel.closeOnDone = true;</code></pre><p>Everything else should work as expected.</p> <h2>TODO</h2><ul> <li>???</li> </ul> <h2>API</h2><p>See the <a href="http://trakkasure.github.io/mikronode">API JSDocs</a> in the doc directory.</p> <h2>Notes for Node &lt; 4.0.0</h2><p>MikroNode requires 2 ES6 features that appeared in Node 4.0.0: Promises and WeakMaps. If<br>you're running an earlier version of Node and MikroNode can't find those symbols, it will<br>attempt to load them from the 'es6-promise' and 'weakmap' packages respectively. If you wish<br>to use other packages to supply those symbols, require them before requiring mikronode and<br>set the global symbols.</p> <pre class="prettyprint source"><code>global.WeakMap = require('some-weakmap-polyfill').WeakMap; global.Promise = require('some-promise-polyfill').Promise; var MikroNode = require('mikronode-ng');</code></pre><h2>Tests</h2><p>The <a href="test/">test</a> directory contains a test that exercises all functionality including<br>Promises and listens/cancels.</p> <h2>Examples</h2><p><a href="examples/">Examples (including Promise examples)</a></p> <h3>Connect to a Mikrotik, and add an address to ether1</h3><pre class="prettyprint source"><code>var MikroNode = require('mikronode-ng'); var connection = MikroNode.getConnection('192.168.88.1','admin','password'); connection.closeOnDone = true; connection.connect(function(conn) { var chan=conn.openChannel(); chan.closeOnDone = true; chan.write(['/ip/address/add','=interface=ether1','=address=192.168.1.1'], function(c) { c.on('trap',function(data) { console.log('Error setting IP: '+data); }); c.on('done',function(data) { console.log('IP Set.'); }); }); });</code></pre><h3>Writing the program for the example API conversation on the <a href="http://wiki.mikrotik.com/wiki/API#.2Fcancel.2C_simultaneous_commands">Mikrotik Wiki</a></h3><p>DON'T RUN THIS IF YOU'RE CONNECTED VIA ether1! :)</p> <pre class="prettyprint source"><code> var MikroNode = require('mikronode-ng'); var connection = MikroNode.getConnection('192.168.88.1','admin','password'); connection.connect(function(conn) { conn.closeOnDone = true; var chan2=conn.openChannel(2); chan2.write('/interface/listen',function(chan) { chan.on('read',function(data) { packet=MikroNode.parseItems(data); console.log('Interface change: '+JSON.stringify(packet)); }); }); var chan3=conn.openChannel(3); chan3.closeOnDone = true chan3.write(['/interface/set','=disabled=yes','=.id=ether1'],function(chan) { chan.on('done',function(d,chan) { // We do this here, 'cause we want channel 4 to write after channel 3 is done. var chan4=conn.openChannel(4); // We'll use this later. chan4.closeOnDone = true; chan4.write(['/interface/set','=disabled=no','=.id=ether1'],function() { var chan5=conn.openChannel(5); chan5.closeOnDone = true; chan5.write('/interface/getall',function(chan) { chan.on('done',function(data) { packets=MikroNode.parseItems(data); packets.forEach(function(packet) { console.log('Interface: '+JSON.stringify(packet)); }); chan2.close(); // This should call the /cancel command to stop the listen. }); }); }) }); }); });</code></pre><h3>Simplifying the above by reducing the number of channels.</h3><p>DON'T RUN THIS IF YOU'RE CONNECTED VIA ether1! :)<br> Notice how the callback embedding is not needed using the syncronous capability.</p> <pre class="prettyprint source"><code> var MikroNode = require('mikronode-ng'); var connection = MikroNode.getConnection('192.168.88.1','admin','password'); connection.connect(function(conn) { conn.closeOnDone = true; // All channels need to complete before the connection will close. var listenChannel=conn.openChannel(); listenChannel.write('/interface/listen',function(chan) { chan.on('read',function(data) { packet=MikroNode.parseItems(data); console.log('Interface change: '+JSON.stringify(packet)); }); }); var actionChannel=conn.openChannel(); // These will run synchronsously actionChannel.write(['/interface/set','=disabled=yes','=.id=ether1']); // don't care to do anything after it's done. actionChannel.write(['/interface/set','=disabled=no','=.id=ether1']); // don't care to do anything after it's done. actionChannel.write('/interface/getall',function(chan) { chan.on('done',function(data) { packets=MikroNode.parseItems(data); packets.forEach(function(packet) { console.log('Interface: '+JSON.stringify(packet)); }); listenChannel.close(); // This should call the /cancel command to stop the listen. }); }); actionChannel.close(); // The above commands will complete before this is closed. });</code></pre><h3>A simple Promise scenario</h3><pre class="prettyprint source"><code>// If your nodejs installation doesn't have Promise support, uncomment // the following line //require('es6-promise').polyfill(); // or globally export Promise from your favorite ES6 compatable Promise library. var MikroNode = require('mikronode-ng'); var connection = MikroNode.getConnection(process.argv[2], process.argv[3], process.argv[4], { closeOnDone : true }); connection.getConnectPromise().then(function(conn) { conn.getCommandPromise('/ip/address/print').then(function resolved(values) { console.log('Addreses: ' + JSON.stringify(values)); }, function rejected(reason) { console.log('Oops: ' + JSON.stringify(reason)); }); });</code></pre><p> The methods <em>decodeLength</em> and <em>encodeString</em> were written based on code <a href="http://wiki.mikrotik.com/wiki/API_PHP_class#Class">here on the Mikrotik Wiki</a>.</p> <h2>License</h2><p>(The MIT License)</p> <p>Copyright (c) 2011-2015 Brandon Myers <a href="&#109;&#x61;&#x69;&#x6c;&#x74;&#x6f;&#x3a;&#x74;&#114;&#97;&#107;&#x6b;&#97;&#x73;&#117;&#x72;&#x65;&#x40;&#103;&#109;&#97;&#105;&#108;&#46;&#x63;&#111;&#x6d;">&#x74;&#114;&#97;&#107;&#x6b;&#97;&#x73;&#117;&#x72;&#x65;&#x40;&#103;&#109;&#97;&#105;&#108;&#46;&#x63;&#111;&#x6d;</a><br>Copyright (c) 2015 George Joseph <a href="&#x6d;&#x61;&#105;&#108;&#x74;&#111;&#58;&#103;&#x65;&#x6f;&#114;&#x67;&#x65;&#46;&#106;&#x6f;&#x73;&#x65;&#112;&#104;&#64;&#x66;&#97;&#105;&#114;&#x76;&#x69;&#x65;&#x77;&#53;&#46;&#99;&#x6f;&#x6d;">&#103;&#x65;&#x6f;&#114;&#x67;&#x65;&#46;&#106;&#x6f;&#x73;&#x65;&#112;&#104;&#64;&#x66;&#97;&#105;&#114;&#x76;&#x69;&#x65;&#x77;&#53;&#46;&#99;&#x6f;&#x6d;</a></p> <p>Permission is hereby granted, free of charge, to any person obtaining<br>a copy of this software and associated documentation files (the<br>'Software'), to deal in the Software without restriction, including<br>without limitation the rights to use, copy, modify, merge, publish,<br>distribute, sublicense, and/or sell copies of the Software, and to<br>permit persons to whom the Software is furnished to do so, subject to<br>the following conditions:</p> <p>The above copyright notice and this permission notice shall be<br>included in all copies or substantial portions of the Software.</p> <p>THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,<br>EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF<br>MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.<br>IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY<br>CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,<br>TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE<br>SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p></article> </section> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Wed Jul 06 2016 06:45:18 GMT-0600 (MDT) </footer> </div> </div> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> <script src="scripts/main.js"></script> </body> </html>