rename CLI Transport to SSH
This commit is contained in:
115
lib/App/Netdisco/Transport/SSH.pm
Normal file
115
lib/App/Netdisco/Transport/SSH.pm
Normal file
@@ -0,0 +1,115 @@
|
||||
package App::Netdisco::Transport::SSH;
|
||||
|
||||
use Dancer qw/:syntax :script/;
|
||||
|
||||
use App::Netdisco::Util::Device 'get_device';
|
||||
use Module::Load ();
|
||||
use Net::OpenSSH;
|
||||
use Try::Tiny;
|
||||
|
||||
use base 'Dancer::Object::Singleton';
|
||||
|
||||
=head1 NAME
|
||||
|
||||
App::Netdisco::Transport::SSH
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Returns an object which has an active SSH connection which can be used
|
||||
for some actions such as arpnip.
|
||||
|
||||
my $cli = App::Netdisco::Transport::SSH->session_for( ... );
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->attributes(qw/ sessions /);
|
||||
|
||||
sub init {
|
||||
my ( $class, $self ) = @_;
|
||||
$self->sessions( {} );
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head1 session_for( $ip )
|
||||
|
||||
Given an IP address, returns an object instance configured for and connected
|
||||
to that device.
|
||||
|
||||
Returns C<undef> if the connection fails.
|
||||
|
||||
=cut
|
||||
|
||||
{
|
||||
package MySession;
|
||||
use Moo;
|
||||
|
||||
has 'ssh' => ( is => 'rw' );
|
||||
has 'auth' => ( is => 'rw' );
|
||||
has 'host' => ( is => 'rw' );
|
||||
has 'platform' => ( is => 'rw' );
|
||||
|
||||
sub arpnip {
|
||||
my $self = shift;
|
||||
$self->platform->arpnip(@_, $self->host, $self->ssh, $self->auth);
|
||||
}
|
||||
}
|
||||
|
||||
sub session_for {
|
||||
my ($class, $ip) = @_;
|
||||
|
||||
my $device = get_device($ip) or return undef;
|
||||
my $sessions = $class->instance->sessions or return undef;
|
||||
|
||||
return $sessions->{$device->ip} if exists $sessions->{$device->ip};
|
||||
debug sprintf 'cli session cache warm: [%s]', $device->ip;
|
||||
|
||||
my $auth = (setting('device_auth') || []);
|
||||
if (1 != scalar @$auth) {
|
||||
error sprintf " [%s] require only one matching auth stanza", $device->ip;
|
||||
return undef;
|
||||
}
|
||||
$auth = $auth->[0];
|
||||
|
||||
my @master_opts = qw(-o BatchMode=no);
|
||||
push(@master_opts, @{$auth->{ssh_master_opts}})
|
||||
if $auth->{ssh_master_opts};
|
||||
|
||||
$Net::OpenSSH::debug = $ENV{SSH_TRACE};
|
||||
my $ssh = Net::OpenSSH->new(
|
||||
$device->ip,
|
||||
user => $auth->{username},
|
||||
password => $auth->{password},
|
||||
timeout => 30,
|
||||
async => 0,
|
||||
default_stderr_file => '/dev/null',
|
||||
master_opts => \@master_opts
|
||||
);
|
||||
|
||||
if ($ssh->error) {
|
||||
error sprintf " [%s] ssh connection error [%s]", $device->ip, $ssh->error;
|
||||
return undef;
|
||||
}
|
||||
elsif (! $ssh) {
|
||||
error sprintf " [%s] Net::OpenSSH instantiation error", $device->ip;
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $platform = "App::Netdisco::SSHCollector::Platform::" . $auth->{platform};
|
||||
my $happy = false;
|
||||
try {
|
||||
Module::Load::load $platform;
|
||||
$happy = true;
|
||||
} catch { error $_ };
|
||||
return unless $happy;
|
||||
|
||||
my $sess = MySession->new(
|
||||
ssh => $ssh,
|
||||
auth => $auth,
|
||||
host => $device->ip,
|
||||
platform => $platform->new(),
|
||||
);
|
||||
|
||||
return ($sessions->{$device->ip} = $sess);
|
||||
}
|
||||
|
||||
true;
|
||||
Reference in New Issue
Block a user