Giter Site home page Giter Site logo

librouteros's Introduction

Documentation

Documentation resides over at readthedocs

librouteros's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar github-actions[bot] avatar hugovk avatar i-ky avatar luqasz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

librouteros's Issues

librouteros.exceptions.ConnectionError: [SSL: NO_CIPHERS_AVAILABLE] no ciphers available (_ssl.c:661)

OpenSSL 1.1.0f 25 May 2017

python -V
Python 2.7.13

import ssl
from librouteros import connect

def main(args):

    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    ctx.set_ciphers('ADH')
    api = connect(username='admin', password='password', host='host.domain', 
    ssl_wrapper=ctx.wrap_socket, port=8729)

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))
Traceback (most recent call last):
  File "test.py", line 38, in <module>
    sys.exit(main(sys.argv))
  File "test.py", line 34, in main
    api = connect(username='admin', password='password', host='host.domain', ssl_wrapper=ctx.wrap_socket, port=8729)
  File "/home/pi/.local/lib/python2.7/site-packages/librouteros/__init__.py", line 41, in connect
    transport = create_transport(host, **arguments)
  File "/home/pi/.local/lib/python2.7/site-packages/librouteros/__init__.py", line 69, in create_transport
    raise ConnectionError(error)
librouteros.exceptions.ConnectionError: [SSL: NO_CIPHERS_AVAILABLE] no ciphers available (_ssl.c:661)

with python3 works as expected

[SSL: NO_CIPHERS_AVAILABLE] Python 3.5.3

Proceding as wiki to make SSL connection to routerOS 6.42.6 :

Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> from librouteros import connect
>>> ctx = ssl.create_default_context()
>>> ctx.check_hostname = False
>>> ctx.verify_mode = ssl.CERT_NONE
>>> ctx.set_ciphers('ADH')
>>> api = connect(username='***************', password='************', host='10.228.5.50', ssl_wrapper=ctx.wrap_socket, port=8729)
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/librouteros/__init__.py", line 66, in create_transport
    sock = kwargs['ssl_wrapper'](sock)
  File "/usr/lib/python3.5/ssl.py", line 385, in wrap_socket
    _context=self)
  File "/usr/lib/python3.5/ssl.py", line 760, in __init__
    self.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 996, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 641, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: NO_CIPHERS_AVAILABLE] no ciphers available (_ssl.c:720)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/dist-packages/librouteros/__init__.py", line 41, in connect
    transport = create_transport(host, **arguments)
  File "/usr/local/lib/python3.5/dist-packages/librouteros/__init__.py", line 69, in create_transport
    raise ConnectionError(error)
librouteros.exceptions.ConnectionError: [SSL: NO_CIPHERS_AVAILABLE] no ciphers available (_ssl.c:720)

dummy_user fills error log

Hi,

The problem I want to discuss is that router log is filled with false positive messages about invalid logins. It looks like this

system, error, critical    login failure for user dummy_user from 10.1.2.3 via api
system, error, critical    login failure for user dummy_user from 10.1.2.3 via api
system, error, critical    login failure for user dummy_user from 10.1.2.3 via api
system, error, critical    login failure for user dummy_user from 10.1.2.3 via api
system, error, critical    login failure for user dummy_user from 10.1.2.3 via api
system, error, critical    login failure for user dummy_user from 10.1.2.3 via api
system, info, account      user real_user logged in from 10.1.2.3 via api
system, info, account      user real_user logged out from 10.1.2.3 via api

with error lines written in red. This makes router log less usable, as it is filled with a lot of noise. For instance I have router monitoring system which log in into router every minute and log is full with this error messages. I did not find any way to filter out errors for dummy_user in particular.

I think we need some "use_6_43_auth=None" parameter in connect method

def connect(host, username, password, use_6_43_auth=None, **kwargs):

and argument based choice on what to do, maybe like this

if use_6_43_auth is None:
    try:
        # First send dummy credentials to know if we get a =ret= back.
        # This way we know if it is a pre 6.43 auth method or not.
        sentence = api('/login', **{'name': 'dummy_user', 'password': 'dummy_password'})
        token = sentence[0]['ret']
    except (TrapError, MultiTrapError):
        # Login failed so use 6.43 auth method.
        api('/login', **{'name': username, 'password': password})
    except (ConnectionError, FatalError):
        transport.close()
        raise
    else:
        # We got =ret= so use pre 6.43 auth method.
        api('/login', **{'name': username, 'response': encode_password(token, password)})
elif use_6_43_auth:
    api('/login', **{'name': username, 'password': password})
else:
    api('/login', **{'name': username, 'response': encode_password(token, password)})

My proposal is that new parameter name is unique and can't be confused with anything. No existing code uses "use_6_43_auth". Google search by this name returns absolutely nothing right now. So you are safe adding this parameter. Also it has default value, so calling code requires no modifications.

Default value is None, not True or False. None corresponds to existing logic. So if calling code will not specify any value for use_6_43_auth parameter, then behavior will not change.

P.S. start of original discussion #29

Chinese symbols in DHCP lease

Hi.
Thank you for your library, it's really helpful.
Recently I stuck with a problem while I was picking up DHCP static bindings from Mikrotiks:
<--- '/ip/dhcp-server/lease/print'
<--- EOS
---> '!re'
---> '=.id=*4'
---> '=address=10.6.68.250'
---> '=mac-address=3C:D9:2B:A0:E3:B0'
---> '=address-lists='
---> '=server=dhcp1'
---> '=dhcp-option='
---> '=status=bound'
---> '=expires-after=23h28m14s'
---> '=last-seen=31m46s'
---> '=active-address=10.6.68.250'
---> '=active-mac-address=3C:D9:2B:A0:E3:B0'
---> '=active-server=dhcp1'
---> '=host-name=NPIA0E3B0'
---> '=radius=false'
---> '=dynamic=false'
---> '=blocked=false'
---> '=disabled=false'
---> EOS
---> '!re'
---> '=.id=*7DC'
---> '=address=10.6.68.234'
---> '=mac-address=70:54:D2:E3:B3:A7'
---> '=client-id=1:70:54:d2:e3:b3:a7'
---> '=address-lists='
---> '=server=dhcp1'
---> '=dhcp-option='
---> '=status=bound'
---> '=expires-after=23h9m9s'
---> '=last-seen=5m36s'
---> '=active-address=10.6.68.234'
---> '=active-mac-address=70:54:D2:E3:B3:A7'
---> '=active-client-id=1:70:54:d2:e3:b3:a7'
---> '=active-server=dhcp1'
---> '=host-name=wbf-342'
---> '=radius=false'
---> '=dynamic=true'
---> '=blocked=false'
---> '=disabled=false'
---> EOS
Traceback (most recent call last):
File "./apicli.py", line 75, in
main()
File "./apicli.py", line 65, in main
selectloop(api)
File "./apicli.py", line 42, in selectloop
proto.readSentence()
File "/usr/local/lib/python3.5/dist-packages/librouteros/connections.py", line 147, in readSentence
sentence = tuple(word for word in iter(self.readWord, b'\x00'))
File "/usr/local/lib/python3.5/dist-packages/librouteros/connections.py", line 147, in
sentence = tuple(word for word in iter(self.readWord, b'\x00'))
File "/usr/local/lib/python3.5/dist-packages/librouteros/connections.py", line 164, in readWord
return self.transport.read(length).decode(encoding=self.encoding, errors='strict')
UnicodeDecodeError: 'ascii' codec can't decode byte 0x8f in position 14: ordinal not in range(128)

The bad hostname in DHCP leases was (but i have many of them):
sk-\8F\8A

b'\x8f\x8a'.decode('utf-16')
'誏'
(that means, play upon words)

I tried to change encoding from ASCII to utf-16 but nothing changed (script timed out).
After that I made an attempt to get rid of this address:
<--- '/ip/dhcp-server/lease/print'
<--- '?=dynamic=false'
<--- EOS
---> '!re'
---> '=.id=*4'
---> '=address=10.6.68.250'
---> '=mac-address=3C:D9:2B:A0:E3:B0'
---> '=address-lists='
---> '=server=dhcp1'
---> '=dhcp-option='
---> '=status=bound'
---> '=expires-after=22h33m19s'
---> '=last-seen=1h26m41s'
---> '=active-address=10.6.68.250'
---> '=active-mac-address=3C:D9:2B:A0:E3:B0'
---> '=active-server=dhcp1'
---> '=host-name=NPIA0E3B0'
---> '=radius=false'
---> '=dynamic=false'
---> '=blocked=false'
---> '=disabled=false'
---> EOS
---> '!done'
---> EOS

from your apicli.py everything was working fine, but when I tried the same from a script:
dhcp_lease = '/ip/dhcp-server/lease/print'
dhcp_s = s(cmd=dhcp_lease, dynamic=False)

or
dhcp_lease = '/ip/dhcp-server/lease/print'
params = {'dynamic': False}
dhcp_s = s(cmd=dhcp_lease, **params)

I had that:
Traceback (most recent call last):
File "./net_crawler.py", line 183, in get_config
dhcp_s = s(cmd=dhcp_lease, dynamic=False)
File "/usr/local/lib/python3.5/dist-packages/librouteros/api.py", line 80, in call
return self._readResponse()
File "/usr/local/lib/python3.5/dist-packages/librouteros/api.py", line 106, in _readResponse
self._trapCheck(response)
File "/usr/local/lib/python3.5/dist-packages/librouteros/api.py", line 124, in _trapCheck
raise TrapError(message=trap['message'], category=trap.get('category'))
librouteros.exceptions.TrapError: unknown parameter

I have two questions hopefully you will be able to help me out with....
Is there any way to use unicode-16, or how to avoid this problem with unicode-16 symbols?
How can I pass the params like that {'dynamic': False} in any print?

Can Not Login Connection Reset By Peer

Hey,

I was using librouter os to connect my Mikrotik via API and it was working fine until today. My Mikrotik version is 6.43.8, and as you know login is changed for API versions of 6.43 and later. I saw that you already created a function for it called 'login_plain'. I tried to force it and used only login_plain function to login but it did not work as well. Creating the socket part is working fine but as far as I see there is something wrong with receiving the response data.

Thank you in the advance

Add tag support

API has support for .tag which as name suggests, tags each response when request is tagged. This enables async usage of API and other issues:

  • Does library need to track each request and return a response when it is ready ?
  • API allows to use same tags multiple times
  • API may return multiple !trap errors
  • API behaves differently on different routeros versions
  • When tag is passed as '1' (int as a string) API must return same type.

on version 5.25 with url which is malformed:

<--- /tool/fetch (11)
<--- =url=http://wp.pl/xxx (21)
<--- .tag=3 (6)
<--- EOS

---> !re (3)
---> =status=connecting (18)
---> .tag=3 (6)
---> EOS
---> !re (3)
---> =status=failed (14)
---> .tag=3 (6)
---> EOS
---> !re (3)
---> =status=failed (14)
---> .tag=3 (6)
---> EOS

<--- /cancel (7)
<--- =tag=3 (6)
<--- .tag=7 (6)
<--- EOS

---> !trap (5)
---> =category=2 (11)
---> =message=interrupted (20)
---> .tag=3 (6)
---> EOS
---> !done (5)
---> .tag=7 (6)
---> EOS
---> !trap (5)
---> =message=failure: 301 Moved Permanently (39)
---> .tag=3 (6)
---> EOS
---> !done (5)
---> .tag=3 (6)
---> EOS

on version 6.1 with url that exists:

<--- /tool/fetch
<--- =url=http://noc.gts.pl/1mb.gts
<--- .tag=1
<--- EOS

---> !re
---> =status=connecting
---> .tag=1
---> EOS
---> !re
---> =status=downloading
---> =downloaded=753
---> =total=1000
---> =duration=2d09:29:51
---> .tag=1
---> EOS
---> !re
---> =status=finished
---> .tag=1
---> EOS
---> !done
---> .tag=1
---> EOS

on version 6.1 with url which is malformed:

<--- /tool/fetch
<--- =url=http://noc.gts.pl/1mb.gtsss
<--- .tag=1
<--- EOS

---> !re
---> =status=connecting
---> .tag=1
---> EOS
---> !re
---> =status=failed
---> .tag=1
---> EOS
---> !trap
---> =message=failure: closing connection: <404 Not Found> 217.153.108.10:80 (4)
---> .tag=1
---> EOS
---> !done
---> .tag=1
---> EOS

Canceling a listen command returns !trap which is not actually any error at all:

<--- '/ip/address/listen'
<--- '.tag=10'
<--- EOS

---> '!re'
---> '.tag=10'
---> '=.id=*A'
---> '=address=1.1.1.1/32'
---> '=network=1.1.1.1'
---> '=interface=br-lan'
---> '=actual-interface=br-lan'
---> '=invalid=false'
---> '=dynamic=false'
---> '=disabled=false'
---> EOS
---> '!re'
---> '.tag=10'
---> '=.id=*A'
---> '=.dead=true'
---> EOS

<--- '/cancel'
<--- '=tag=10'
<--- '.tag=20'
<--- EOS

---> '!trap'
---> '.tag=10'
---> '=category=2'
---> '=message=interrupted'
---> EOS
---> '!done'
---> '.tag=20'
---> EOS
---> '!done'
---> '.tag=10'
---> EOS

Drop pre 3.6 python support

Python 2.7 will end support on end of 2020. Python 3.4 is already EOL 3.5 will be EOL in 3.5.8 final: September 23, 2019.

To do:

  • upgrade pytest
  • remove code that depends on python < 3.6
  • use yield from

Document how to connect without certificate installed on routeros

Documentation states that a certificate is required on routeros, however that is silly if you are just going to disable verification anyway.

Please document the proper configuration for connecting to routeros without an installed certificate.

import ssl
from librouteros import connect
from librouteros.login import login_plain

ctx = ssl.create_default_context()
ctx.set_ciphers('ADH:@SECLEVEL=0')
ctx.check_hostname = False

api = connect(
    username='...',
    password='...',
    host='...',
    port=8729,
    login_methods=(login_plain,),
    ssl_wrapper=ctx.wrap_socket)

ID Fields

For /ip/service/print, the .id returns *4 for SSH, which matches the ID in webfig.

When I go to change it with /ip/service/set though, it makes the change to ID *6 (www-ssl) .

def toggle_ssh(api, mode=False):
	services = api(cmd='/ip/service/print')
	ssh_port = 22
	ssh_id = 0
	for service in services:
		if service['name'] == 'ssh':
			ssh_port = service['port']
			ssh_id = service['.id']
			break
	params = {'disabled': (not mode), '.id': ssh_id}
	api(cmd='/ip/service/set', **params)
	return ssh_port

api(cmd='/ip/service/print')

params = {'disabled': False, '.id' :'4'}   <----
api(cmd='/ip/service/set', **params)

api(cmd='/ip/service/print')

params = {'disabled': True, '.id' :'4'}  <----
api(cmd='/ip/service/set', **params)

api(cmd='/ip/service/print')

The README is incorrect, you need to put the * in the ID field. Why, I don't know.

params = {'disabled': True, '.id' :'*4'}

Iteration problem

Hey, all.

Thank you @luqasz for great API.

I have a problem iterating in a for loop and removing userman profiles

A simple line as:

api('/tool/user-manager/user/clear-profiles', numbers="user1")
api('/tool/user-manager/user/clear-profiles', numbers="user2")

Could result in a error:

  File "/home/iap/Packages/Mikrotik_api/librouteros/api.py", line 80, in __call__
    return self._readResponse()
  File "/home/iap/Packages/Mikrotik_api/librouteros/api.py", line 106, in _readResponse
    self._trapCheck(response)
  File "/home/iap/Packages/Mikrotik_api/librouteros/api.py", line 124, in _trapCheck
    raise TrapError(message=trap['message'], category=trap.get('category'))
librouteros.exceptions.TrapError: failure: cannot remove purchase: 

What happens is that profiles are successfully removed from user1, but when i try to remove profiles from user2, the api command somehow still sends "user1" as a parameter, instead of expected "user2". That results in trying to remove profiles which were already removed... Trying to remove empty profiles - makes an error.

Could you help please?

How to use find

Throu terminal i use following command
/ip firewall connection remove [find src-address~"^192.168.0.15:.*\$"]

How am i going to use it in a path? following code gives me an error no such command prefix

command = ['/ip', 'firewall', 'connection', 'remove', '[find src-address~"^192.168.0.15:.*\\$"]']
api.path(*command)

Add query support

Things to considder:

  • =.proplist= must be passed as first word followed by any other query words
  • query only works with print commands
  • order of query words matters
  • python dict does not have any order
  • docs

Forum discussion.

Proposals:

API Python
?-ip NotHaving( row.ip, row.address )
?ip Having( row.ip, row.address )
?=ip=x row.ip == '1.1.1.1/32'
?=ip=1.1.1.1/32 ?#! row.ip != '1.1.1.1/32'
?<rx-byte=100 row.rx-byte < 100
?>rx-byte=100 row.rx-byte > 100
?#& And()
?#| Or()

Get all communities which names are in ('com', 'qwe', 'asd', 'zxc')
'?=name=asd', '?=name=zxc', '?=name=qwe', '?=name=com', '?#|||'
community.name.In('com', 'qwe', 'asd', 'zxc')

Implementing __iter__ will execute query.

Encrypted Connection Not Working

Hi,

I'm using Python 3.6.9 with librouteros 3.0.0. I'm getting the following error when I try to connect to a remote Mikrotik with encryption (I'm a Python novice so please excuse any rookie mistakes):

root@localhost:~# python3 ssl.py 
Traceback (most recent call last):
  File "ssl.py", line 3, in <module>
    import ssl
  File "/root/ssl.py", line 6, in <module>
    ctx = ssl.create_default_context()
AttributeError: module 'ssl' has no attribute 'create_default_context'

I'm using the code provided in the documentation:

import ssl
from librouteros import connect

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.set_ciphers('ADH:@SECLEVEL=0')
api = connect(
    username='admin',
    password='abc',
    host='some.address.com',
    ssl_wrapper=ctx.wrap_socket,
    port=8729
    )

Unencrypted connection works fine.

Drop python 3.1, 3.2, 3.3 support

Drop support for versions 3.0, 3.1 , 3.2 because:

  • no u'' which makes unicode handling difficult.
  • no 3.x versions of pytest.
  • pydocstyle 2.0.0 depends on snowballstreamer which throws SyntaxError on python 3.2
  • pytest does not have tmpdir_factory (disk_image fixture)

ValueError: not enough values to unpack (expected 3, got 1)

In some cases I'm getting stackTrace when do the call cmd='/interface/wireless/registration-table/getall':

  File "<stdin>", line 1, in <module>
  File "/opt/hass/lib/python3.5/site-packages/librouteros/api.py", line 81, in __call__
    return self._readResponse()
  File "/opt/hass/lib/python3.5/site-packages/librouteros/api.py", line 104, in _readResponse
    reply_word, words = self._readSentence()
  File "/opt/hass/lib/python3.5/site-packages/librouteros/api.py", line 90, in _readSentence
    words = dict(self.parseWord(word) for word in words)
  File "/opt/hass/lib/python3.5/site-packages/librouteros/api.py", line 90, in <genexpr>
    words = dict(self.parseWord(word) for word in words)
  File "/opt/hass/lib/python3.5/site-packages/librouteros/api.py", line 35, in parseWord
    _, key, value = word.split('=', 2)

I've dumped response from Mikrotik and looks like it returns broken data:
Normal response:

=signal-strength-ch0=-60
=signal-strength-ch1=-66
=strength-at-rates=-56@1Mbps 1m58s660ms,[email protected] 39m49s430ms,-54@11Mbps 39m55s900ms,-51@HT20-0 40m1s630ms,-51@HT20-1 40m1s630ms,-58@HT20-2 2m50s680ms,-57@HT20-3 4m38s360ms,-55@HT20-4 4m33s320ms,-57@HT20-5 31m17s460ms,-50@HT20-6 18m48s650ms,-51@HT20-7 3s530ms
=tx-ccq=93
=p-throughput=59398

Broken response:

=signal-strength-ch0=-60
=signal-strength-ch1=-66
54@11Mbps 40m5s560ms,-51@HT20-0 40m11s290ms,-

Probably we can catch an exception and do a retry?

rawCmd documentation

I am not sure if i am using it wrong or if it is broken. Below it is what i tried to do. Everything seems to run smoothly, but the backup is not generated.

api = connect( username='admin', password='my_password', host='my_ip', timeout=20, ) api.rawCmd('/system/backup/save')

So, if it is working properly, what is wrong?

Wrong Docs on adding element

  • so i started to try new docs after you change cause my last issue
  • and when i try the code from docs
data = {'interface':'ether1', 'address':'172.31.31.1/24'}
ID = api('/ip/address/add',data)
print(ID)
  • and error like this
Traceback (most recent call last):
  File "API.py", line 23, in <module>
    ID = api('/ip/address/add',data)
TypeError: __call__() takes 2 positional arguments but 3 were given
  • and i found something in your help built in function
__call__(self, cmd, **kwargs)
     |      Call Api with given command.
     |      
     |      :param cmd: Command word. eg. /ip/address/print
     |      :param kwargs: Dictionary with optional arguments.
  • and the result, you must change args to kwargs
data = {'interface':'ether4', 'address':'172.31.31.1/24'}
ID = api('/ip/address/add',**data)
print(ID) # ({'ret': '*7'},)

Question about socket connection

Do you know if it's possible to check if socket/connection is still active so I don't have to (re)connect hundreds of times per day for every command?

fix broken pipe error by reconnecting to the mikrotik

Hello, is it possible add the functionality to reconnect to the mikrotik in case it was restarted. i am using home assistant and i get a broken pipe error if the mikrotik is rebooted. it can only be solved by restarting home assistant afterwards.
File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 79, in __call__ self.protocol.writeSentence(cmd, *words) File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/connections.py", line 139, in writeSentence self.transport.write(encoded) File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/connections.py", line 185, in write raise ConnectionError('Failed to write to socket. ' + str(error)) librouteros.exceptions.ConnectionError: Failed to write to socket. [Errno 32] Broken pipe

My suggestion is to try to create a new socket connection if we get connection error exception and then try to send the code again.
Thanks

RouterOS hyphen keywords vs Python hyphen usage

I would like to push out a new syslog config but I came across the below issue.

The specific code I tried to push was:
result = api(cmd='/system/logging/action/add', name='testremove', target='remote', remote='172.16.0.4', bsd-syslog=True)
This returned:
SyntaxError: keyword can't be an expression

I believe this has to do with the way RouterOS uses hyphens in keywords and with how the hyphen is reserved for the subtraction operator in python. Is there anyway around this issue? I looked through the wiki and did not see any similar examples.

RoS 6.42.4 can't login

Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.

import librouteros
client = librouteros.connect(host='192.168.88.1', username='hass', password='hass')
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.5/dist-packages/librouteros/init.py", line 58, in connect
api('/login', **{'name': username, 'response': encode_password(token, password)})
File "/usr/local/lib/python3.5/dist-packages/librouteros/api.py", line 80, in call
return self._readResponse()
File "/usr/local/lib/python3.5/dist-packages/librouteros/api.py", line 106, in _readResponse
self._trapCheck(response)
File "/usr/local/lib/python3.5/dist-packages/librouteros/api.py", line 124, in _trapCheck
raise TrapError(message=trap['message'], category=trap.get('category'))
librouteros.exceptions.TrapError: cannot log in

librouteros version is 2.1.0
RoS log: 11:39:39 system,error,critical login failure for user hass from 192.168.88.151 via winbox

Update librouteros on PyPi

Hello there,

Just a heads up: librouteros' version on PyPi is still 1.0.4 so the usage instructions in the current README won't work.

Traceback (most recent call last):
  File "librouteros_demo.py", line 4, in <module>
    from librouteros import login
ImportError: cannot import name login

Cheers.

support for where

Hi, new in Mikroitk, how do i make this command 'where' e.g. /ip/hotspot/user/print where name='hello'. Because I got a reply of 'no such command'. And this command works fine in command line. Thanks

query

How should I express this command?

ip firewall address-list print where dynamic =yes

I try entering this command but I have an error

api(cmd='/ip/firewall/address-list/print', dynamic=true)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'true' is not defined

Add API call timoeout

Hello, could you consider adding timeout for api function call? Either in Api __init__ or __call__ method. Reasoning is as follows, there are some blocking calls, for instance interface lte info lte1 that must be called prior to using once option of that command, or, as I experimentally checked, the response will be always empty. Perhaps, mikrotik has option for changing that behaviour, but unfortunately, I'm not aware of it. Thank you.

Connect with valid SSL certificate

Hi,

I can't connect to ROS without ctx.check_hostname = False. I have trusted certificate authority signed SSL certificate installed.

from librouteros import connect
import ssl

ctx = ssl.create_default_context()
api = connect(
    username='admin',
    password='',
    host='example.com',
    ssl_wrapper=ctx.wrap_socket,
    port=8729,
)

I got error:

Traceback (most recent call last):
  File "~/mikrotik/libros.py", line 12, in <module>
    port=8729
  File "~/mikrotik/venv/lib/python3.7/site-packages/librouteros/__init__.py", line 46, in connect
    transport = create_transport(host, **arguments)
  File "~/mikrotik/venv/lib/python3.7/site-packages/librouteros/__init__.py", line 60, in create_transport
    sock = kwargs['ssl_wrapper'](sock)
  File "/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 423, in wrap_socket
    session=session
  File "/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 827, in _create
    raise ValueError("check_hostname requires server_hostname")
ValueError: check_hostname requires server_hostname

I am using macOS 10.15.4 with Python 3.7.7
Thanks.

Problem with encoded

When I try the command api(cmd='/ip/neighbor/print') return this error:

File "/home/HOME/.local/lib/python3.5/site-packages/librouteros/connections.py", line 164, in readWord
return self.transport.read(length).decode(encoding=self.encoding, errors='strict')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 33: ordinal not in range(128)

ValueError: not enough values to unpack (expected 3, got 2)

We are expecting this issue again:
RouterOS: 6.40

File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/device_tracker/mikrotik.py", line 137, in scan_devices
    self._update_info()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/device_tracker/mikrotik.py", line 159, in _update_info
    device_names = self.client(cmd='/ip/dhcp-server/lease/getall')
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 80, in __call__
    return self._readResponse()
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 103, in _readResponse
    reply_word, words = self._readSentence()
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 89, in _readSentence
    words = dict(self.parseWord(word) for word in words)
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 89, in <genexpr>
    words = dict(self.parseWord(word) for word in words)
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 34, in parseWord
    _, key, value = word.split('=', 2)
ValueError: not enough values to unpack (expected 3, got 2)

File creation over API returns existing file instead of nothing.

RouterOS doesn't allow direct file creation from the API or CLI instead you have to run something like /file print file=myFile
and it will create a new file with the name of myFile and nothing printed to the CLI

with the code

file = api.path('file')
tuple(file('print', **{'file':'"test10"'}))

I get a tuple of all the existing files, it still creates the new file but I'm not sure why it's returning a tuple of existing files.

tuple(file('set', **{'.id':'test10', 'contents':'testcontents'}))

works as expected and returns an empty tuple and sets the contents of the file correctly.

Unable to Install for Python 2.7

Trying to install on a server that only runs Python 2.7, fails with following output.

Collecting librouteros
Using cached librouteros-1.0.4.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-build-5YgwAy/librouteros/setup.py", line 62, in
'Topic :: Software Development :: Libraries'
File "/usr/lib64/python2.7/distutils/core.py", line 112, in setup
_setup_distribution = dist = klass(attrs)
File "/usr/lib/python2.7/site-packages/setuptools/dist.py", line 265, in init
self.fetch_build_eggs(attrs.pop('setup_requires'))
File "/usr/lib/python2.7/site-packages/setuptools/dist.py", line 289, in fetch_build_eggs
parse_requirements(requires), installer=self.fetch_build_egg
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 630, in resolve
raise VersionConflict(dist,req) # XXX put more info here
pkg_resources.VersionConflict: (setuptools 0.9.8 (/usr/lib/python2.7/site-packages), Requirement.parse('setuptools>=12.0.5'))

----------------------------------------

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-5YgwAy/librouteros/

librouteros.exceptions.ConnectionError: Failed to read from socket. [Errno 104] Connection reset by peer

After upgrading mirotik routerOS to version 6.41 we are expecting new issue:

File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/device_tracker/mikrotik.py", line 137, in scan_devices
    self._update_info()
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/components/device_tracker/mikrotik.py", line 159, in _update_info
    device_names = self.client(cmd='/ip/dhcp-server/lease/getall')
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 80, in __call__
    return self._readResponse()
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 103, in _readResponse
    reply_word, words = self._readSentence()
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/api.py", line 88, in _readSentence
    reply_word, words = self.protocol.readSentence()
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/connections.py", line 163, in readSentence
    sentence = tuple(word for word in iter(self.readWord, None))
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/connections.py", line 163, in <genexpr>
    sentence = tuple(word for word in iter(self.readWord, None))
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/connections.py", line 173, in readWord
    length = self.transport.read(1)
  File "/srv/homeassistant/lib/python3.5/site-packages/librouteros/connections.py", line 217, in read
    raise ConnectionError('Failed to read from socket. ' + str(error))
librouteros.exceptions.ConnectionError: Failed to read from socket. [Errno 104] Connection reset by peer

Api instance has no attribute 'run'

Hey guys,

I can't seem to "run" commands via this API.
Ultimately I want to be able to add to an address list (/ip/firewall/address-list), but I can't even get as far as pulling down information from the router.

import librouteros
api = librouteros.connect(username=USERNAME, password=PASSWORD, host=HOSTNAME)
addresses = api.run('/ip/address/print')
print addresses
api.close()

Results in:

Traceback (most recent call last):
    [....]
    addresses = api.run('/ip/address/print')
AttributeError: Api instance has no attribute 'run'

Running Python 2.7 and librouteros 2.1.0.

Any ideas? Thanks!

UnicodeDecode Error retriving leases from dhcp server

I 'm trying to get all dhcp leases from a MK with version 6.45.2
Actually 3234 items,

lease_list  = [f for f in api(cmd='/ip/dhcp-server/lease/print')]

returns

UnicodeDecodeError: 'ascii' codec can't decode byte 0xae in position 11: ordinal not in range(128)

[f for f in api(cmd='/ip/dhcp-server/lease/print')]

pseudo-works, returns something strange, only 2313 leases, and the first truncated

My knowledges don't permit to enter in more depth,

The same requests to a 6.45.1 and 113 leases works fine

Here the complete traceback

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 1, in <listcomp>
  File "/home/gil/PycharmProjects/testestest/venv/lib/python3.6/site-packages/librouteros/api.py", line 28, in __call__
    yield from self.readResponse()
  File "/home/gil/PycharmProjects/testestest/venv/lib/python3.6/site-packages/librouteros/api.py", line 60, in readResponse
    reply_word, words = self.readSentence()
  File "/home/gil/PycharmProjects/testestest/venv/lib/python3.6/site-packages/librouteros/api.py", line 46, in readSentence
    reply_word, words = self.protocol.readSentence()
  File "/home/gil/PycharmProjects/testestest/venv/lib/python3.6/site-packages/librouteros/protocol.py", line 189, in readSentence
    sentence = tuple(word for word in iter(self.readWord, ''))
  File "/home/gil/PycharmProjects/testestest/venv/lib/python3.6/site-packages/librouteros/protocol.py", line 189, in <genexpr>
    sentence = tuple(word for word in iter(self.readWord, ''))
  File "/home/gil/PycharmProjects/testestest/venv/lib/python3.6/site-packages/librouteros/protocol.py", line 206, in readWord
    return word.decode(encoding=self.encoding, errors='strict')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xae in position 11: ordinal not in range(128)

If I can contribute with more data, here I'm

Thank you!

Unable to specify '.id' attribute

If I try to specify a target item ID, this happens:

api(cmd='/ip/firewall/nat/print')
api(cmd='/ip/firewall/nat/set', .id=7)
File "", line 1
pi(cmd='/ip/firewall/nat/set', disabled='yes', .id=7)
SyntaxError: invalid syntax

That's because a keyword can't start with a period. However, when I try it without the period, this happens:

api(cmd='/ip/firewall/nat/set', disabled='yes', id='7')
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/librouteros/api.py", line 80, in call
print words
File "/usr/local/lib/python2.7/dist-packages/librouteros/api.py", line 106, in _readResponse
response.append((reply_word, words))
File "/usr/local/lib/python2.7/dist-packages/librouteros/api.py", line 124, in _trapCheck
elif len(traps) == 1:
librouteros.exceptions.TrapError: unknown parameter

Pisses me off that Mikrotik somehow reached the conclusion that starting ANY attribute with a period was a good idea, but I digress.

Am I doing something wrong?

no run methods

  • have followed the documentation, but still face errors with the method run of connect class
Traceback (most recent call last):
  File "API.py", line 23, in <module>
    ID = api.run('/ip/address/add', data)
AttributeError: 'Api' object has no attribute 'run'
  • and the code is same as in your documentation
import os
from librouteros import *

os.system("clear")
api = connect(username='admin', password='', host='192.168.1.200')
data = {'interface':'ether1', 'address':'172.31.31.1/24'}
ID = api.run('/ip/address/add', data)
  • info machine
Linux 4.15.0-38-generic #41 41-Ubuntu SMP 2018 x86_64 GNU/Linux
Python 3.6.6
librouteros              2.2.0 

Can't get any information from API

Hey, Łukasz. Thank you for sharing API.

(Please forgive me, i m quite newbie)
I am trying to use API now, but I am not getting anything out of requests.

I m using latest MikroTik v6.41.2 on wAP. I have created hotspot on 10.0.0.1, connected with my PC and i am trying just to start up with API. That's my code in test.py, which i have out to the same folder as librouteros:
` from librouteros import connect

api = connect(username='admin', password='eplmmlsw', host='10.0.0.1')

api(cmd='/interface/print')

api.close() And after running i m just getting blank output. No errors, no data.C:\Python34\python.exe E:/Development/mikrotik_api/test.py

Process finished with exit code 0
`
Could you please help me out?

Library has broken Python 2 support

On your project page, your PyPI badge indicates Python 2 support. However, trying to install it leads to a failure.

$ pip install librouteros
Collecting librouteros
  Downloading librouteros-1.0.1.tar.gz
    Complete output from command python setup.py egg_info:
    error in librouteros setup command: 'extras_require' must be a dictionary whose values are strings or lists of strings containing valid project/version requirement specifiers.

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-MbOonr/librouteros/

Environment information:

$ python -V
Python 2.7.9
$ pip --version
pip 9.0.1 from /home/user/.virtualenvs/ros/local/lib/python2.7/site-packages (python 2.7)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.