package Local::SSHTunnel; # adapted from: # Re: How do you use Net::OpenSSH to query mysql database via ssh tunnel # https://www.perlmonks.org/?node_id=11106237 use Types::Standard qw(Str); # HashRef ArrayRef Object use Data::Printer; use Net::OpenSSH; use Local::DB; # path in crontab PERL5LIB use Moo; my $LOCAL_PORT = 3307; my $DB_PORT = 3306; has remote_host => ( is => 'ro', required => 1 ); has db_name => ( is => 'ro', isa => Str ); # optional, for dbix() has dbix => ( is => 'lazy' ); has ssh => ( is => 'ro', builder => sub { my $ssh = Net::OpenSSH->new( shift->remote_host, master_opts => "-L127.0.0.1:$LOCAL_PORT:localhost:$DB_PORT" ); die "Couldn't establish SSH connection: ". $ssh->error if $ssh->error; return $ssh; } ); sub _build_dbix { my $self = shift; # check db_name var has been supplied: $self->db_name || die "db_name variable required if calling dbix()"; my %h = ( dbname => $self->db_name, port => $LOCAL_PORT ); my $dbix = Local::DB->dbix(\%h); # p $dbix; # my $img = $dbix->select('images', 'img_name', { id => 7255 })->value; p $img; return $dbix; #return { # alternative arrangement to keep $ssh in scope # dbix => $dbix, # ssh => $ssh, # need to keep this in scope for query to succeed #} } =begin my $REMOTE_HOST = 'hmds.org.uk'; my $DB_NAME = 'exif_data'; my $DB_USERNAME = '***'; my $DB_PASSWORD = '****'; sub new { my $class = shift; $class = ref $class || $class; my $ssh = Net::OpenSSH->new( $REMOTE_HOST, master_opts => "-L127.0.0.1:$LOCAL_PORT:localhost:$DB_PORT" ); die "Couldn't establish SSH connection: ". $ssh->error if $ssh->error; #my $dsn = "DBI:mysql:database=$DB_NAME;host=127.0.0.1;port=$LOCAL_PORT"; #my $dbh = DBI->connect($dsn, $DB_USERNAME, $DB_PASSWORD); my $self = { dbh => $dbix, ssh => $ssh, }; bless $self, $class; return $self; } #=begin # for DBI sub disconnect { my ($self) = @_; $self->{dbh}->disconnect; $self->{ssh}->system('exit'); } sub DESTROY { disconnect(); } #=begin sub AUTOLOAD { my $self= shift; return if $AUTOLOAD =~ /::DESTROY$/; $AUTOLOAD =~ s/^.*:://; $self->{dbh}->$AUTOLOAD(@_); } =cut 1;