# -*- coding: UTF-8 -*- import typing from socket import create_connection from collections import ChainMap from librouteros.exceptions import ( ConnectionClosed, FatalError, ) from librouteros.connections import SocketTransport from librouteros.protocol import ApiProtocol from librouteros.login import ( plain, token, ) from librouteros.api import Api DEFAULTS = { 'timeout': 10, 'port': 8728, 'saddr': '', 'subclass': Api, 'encoding': 'ASCII', 'ssl_wrapper': lambda sock: sock, 'login_method': plain, } def connect(host: str, username: str, password: str, **kwargs) -> typing.Type[Api]: """ Connect and login to routeros device. Upon success return a Api class. :param host: Hostname to connecto to. May be ipv4,ipv6,FQDN. :param username: Username to login with. :param password: Password to login with. Only ASCII characters allowed. :param timeout: Socket timeout. Defaults to 10. :param port: Destination port to be used. Defaults to 8728. :param saddr: Source address to bind to. :param subclass: Subclass of Api class. Defaults to Api class from library. :param ssl_wrapper: Callable (e.g. ssl.SSLContext instance) to wrap socket with. :param login_method: Callable with login method. """ arguments = ChainMap(kwargs, DEFAULTS) transport = create_transport(host, **arguments) protocol = ApiProtocol(transport=transport, encoding=arguments['encoding']) api = arguments['subclass'](protocol=protocol) try: arguments['login_method'](api=api, username=username, password=password) return api except (ConnectionClosed, FatalError): transport.close() raise def create_transport(host: str, **kwargs) -> SocketTransport: sock = create_connection((host, kwargs['port']), kwargs['timeout'], (kwargs['saddr'], 0)) sock = kwargs['ssl_wrapper'](sock) return SocketTransport(sock=sock)