MikroTik-API
view release on metacpan or search on metacpan
lib/MikroTik/API.pm view on Meta::CPAN
package MikroTik::API;
use 5.006;
use strict;
use warnings FATAL => 'all';
=head1 NAME
MikroTik::API - Client to MikroTik RouterOS API
=head1 VERSION
Version 2.0.1
B<CAUTION:> Dependencies change with version 2.0.0. MikroTik::API now relies on Moo instead of Moose. Please be sure, dependencies are met before upgrading.
=cut
our $VERSION = '2.0.1';
=head1 SYNOPSIS
use MikroTik::API;
my $api = MikroTik::API->new({
host => 'mikrotik.example.org',
username => 'whoami',
password => 'SECRET',
use_ssl => 1,
});
my ( $ret_get_identity, @aoh_identity ) = $api->query( '/system/identity/print', {}, {} );
print "Name of router: $aoh_identity[0]->{name}\n";
$api->logout();
=head1 DESCRIPTION
=cut
use Carp qw(croak);
use Digest::MD5;
use IO::Socket::IP;
use IO::Socket::SSL;
use Moo;
use MooX::Types::MooseLike::Base qw(Bool CodeRef Int Str);
use Time::Out qw{ timeout };
use Try::Tiny;
use Type::Tiny;
use namespace::autoclean;
=head1 PUBLIC METHODS
=head2 new( \%config )
my $api = MikroTik::API->new({
host => 'mikrotik.example.org',
username => 'whoami',
password => 'SECRET',
autoconnect => 1, # optional (set to 0 if you do not want to connect during construction, default: 1)
use_ssl => 1, # optional (0 for non ssl / 1 for ssl)
port => 8729, # optonal (needed if you use another port then 8728 for non-ssl or 8729 for ssl)
debug => 0, # optional (set beween 0 (none) and 5 (most) for debug messages)
timeout => 3, # optional (timeout after 3 seconds during connect)
probe_before_talk => 3, # optional (probe connection before each actual command)
reconnect_after_failed_probe => 1, # optional (reconnect if probe failed)
});
=cut
sub BUILD {
my ($self) = @_;
if ( $self->get_autoconnect() && $self->get_host() ) {
$self->connect();
if ( $self->get_username() && defined( $self->get_password() ) ) {
$self->login();
}
}
return $self;
}
=head2 $api->connect()
Connect happens on construction if you provide host address
my $api = MikroTik::API->new();
$api->set_host('mikrotik.example.org');
$api->set_port(1234);
$api->set_use_ssl(1);
$api->connect();
=cut
sub connect {
my ( $self ) = @_;
if ( ! $self->get_host() ) {
croak 'host must be set before connect()'
}
if ( $self->get_use_ssl ) {
my $socket
= try {
IO::Socket::SSL->new(
PeerHost => $self->get_host,
PeerPort => $self->get_port,
Proto => 'tcp',
SSL_cipher_list => 'HIGH',
SSL_verify_mode => $self->get_ssl_verify(),
Timeout => $self->get_timeout,
);
}
catch {
croak sprintf
'failed connect %s:%s or ssl handshake (%s: %s)',
$self->get_host,
$self->get_port,
$_,
IO::Socket::SSL::errstr();
};
# obsolete?
$socket
or croak sprintf
'failed connect %s:%s or ssl handshake (%s: %s)',
$self->get_host,
$self->get_port,
$!,
IO::Socket::SSL::errstr();
$self->set_socket($socket);
}
else {
$self->set_socket(
IO::Socket::IP->new(
PeerHost => $self->get_host,
PeerPort => $self->get_port,
Proto => 'tcp',
Timeout => $self->get_timeout,
)
or croak sprintf
'failed connect %s:%s (%s)',
$self->get_host,
$self->get_port,
$@,
);
}
if ( ! $self->get_socket ) {
croak "socket creation failed ($!)";
}
$self->get_socket()->sockopt(SO_KEEPALIVE,1);
$self->get_socket()->sockopt(SO_RCVTIMEO,$self->get_timeout());
$self->get_socket()->sockopt(SO_SNDTIMEO,$self->get_timeout());
return $self;
}
=head2 $api->login()
Connect happens on construction if you provide host address, username and password
my $api = MikroTik::API->new({ host => 'mikrotik.example.org' });
$api->set_username('whoami');
$api->set_password('SECRET');
$api->login();
=cut
sub login {
my ( $self ) = @_;
if ( ! $self->get_username() && defined( $self->get_password() ) ) {
croak 'username and password must be set before connect()';
}
if ( ! $self->get_socket() ) {
$self->connect();
}
# RouterOS post v6.43 has new authentication method, thus pushing login/pass in the very first request.
my @command = ('/login');
push( @command, '=name=' . $self->get_username() );
push( @command, '=password=' . $self->get_password() );
my ( $retval, @results ) = $self->talk( \@command );
croak 'disconnected while logging in' if !defined $retval;
if ( $retval > 1 ) {
croak 'error during establishing login: ' . $results[0]{'message'};
}
# if we got "=ret=" in response - then assuming this is old style AUTH
( run in 1.466 second using v1.01-cache-2.11-cpan-39bf76dae61 )