File Coverage

blib/lib/Net/SSH/Perl/ProxiedIPC.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Net::SSH::Perl::ProxiedIPC;
2 1     1   938 use strict;
  1         3  
  1         44  
3 1     1   6 use warnings;
  1         2  
  1         41  
4 1     1   15 use vars qw($VERSION);
  1         2  
  1         70  
5              
6             $VERSION = '0.02';
7              
8             =head1 NAME
9              
10             Net::SSH::Perl::ProxiedIPC - Make long distance SSH commands
11              
12             =head1 SYNOPSIS
13              
14             my $ssh = Net::SSH::Perl->new( ... );
15              
16             my $pipc = Net::SSH::Perl::ProxiedIPC->new( ssh => $ssh );
17              
18             {
19             my ($cmd, $perlssh) = $pipc->open;
20              
21             $perlssh->eval( "use POSIX qw(uname)" );
22             my @uname = $perlssh->eval( "uname()" ); # Returns the host of $ssh
23             }
24              
25             {
26             # Go from this host through host1 to host2
27             my ($cmd, $perlssh) = $pipc->open( 'user1@host1', 'user2@host2' );
28              
29             $perlssh->eval( "use POSIX qw(uname)" );
30             my @uname = $perlssh->eval( "uname()" ); # Returns 'host2'
31             }
32              
33             =head1 DESCRIPTION
34              
35             This is a utility module that wraps around two SSH modules;
36             L and L. By leveraging PerlSSH against
37             the authenticated long-distance requests, you create a means to access
38             data that would otherwise be secured and unaccessible from the outside
39             world, such as if you were on site with a client. And it lets you call
40             Perl from the remote machine! Yay!
41              
42             =head1 METHODS
43              
44             =over 4
45              
46             =item new
47              
48             Create a new proxied object by passing the object you
49             create with C.
50              
51             =item open
52              
53             This is just a wrapper around C<_open_perlssh>, an internal function you
54             shouldn't have to worry about.
55              
56             =back
57              
58             =cut
59              
60 1     1   482 use IPC::PerlSSH;
  0            
  0            
61              
62             sub new {
63             my( $class ) = shift;
64             bless( { @_ }, $class );
65             }
66              
67             sub _ssh {
68             $_[0]->{ssh} ||= $_[0]->_build_ssh
69             }
70              
71             sub _build_ssh {
72             require Net::SSH::Perl;
73             Net::SSH::Perl->new();
74             }
75              
76             sub _ssh_env_vars {
77             if( defined $_[1] ) {
78             $_[0]->{ssh_env_vars} = $_[1];
79             } else {
80             $_[0]->{ssh_env_vars} ||= $_[0]->_build_ssh_env_vars;
81             }
82             }
83              
84             sub _build_ssh_env_vars {
85             return '';
86             # this needs work I think. First off, it won't work.
87             # +{ $_[0]->_firsthop_perlssh->eval(; 'chomp(my @env = `ssh-agent`); my %new_env; foreach (@env) { /^(.*?)=(.*)/; $ENV{$1} =$new_env{$1}=$2; } return %new_env;' ); }
88             }
89              
90             sub _open_perlssh {
91             my( $self, @hosts ) = @_;
92             my $ssh = $self->_ssh;
93              
94             my $env_str = $self->_ssh_env_vars;
95             my $command = join ' ',
96             (map "ssh -o StrictHostKeyChecking=no -A $_", @hosts),
97             "perl";
98             $command = "sh -c '$env_str$command'";
99             my( $read, $write ) = $ssh->open2($command);
100              
101             my $readfunc = sub { sysread( $read, $_[0], $_[1] ) };
102             my $writefunc = sub { syswrite( $write, $_[0] ) };
103              
104             ($command, IPC::PerlSSH->new( Readfunc => $readfunc, Writefunc => $writefunc ));
105             }
106              
107             # Provide a nice interface to _open_ssh()
108             sub open { shift->_open_perlssh( @_ ) }
109              
110             1;
111              
112             __END__