App-ClusterSSH
view release on metacpan or search on metacpan
lib/App/ClusterSSH/Host.pm view on Meta::CPAN
package App::ClusterSSH::Host;
use strict;
use warnings;
use version;
our $VERSION = version->new('0.03');
use Carp;
use Net::hostent;
use base qw/ App::ClusterSSH::Base /;
our %ssh_hostname_for;
our %ssh_configs_read;
sub new {
my ( $class, %args ) = @_;
if ( !$args{hostname} ) {
croak(
App::ClusterSSH::Exception->throw(
error => $class->loc('hostname is undefined')
)
);
}
# remove any keys undef values - must be a better way...
foreach my $remove (qw/ port username geometry /) {
if ( !$args{$remove} && grep {/^$remove$/} keys(%args) ) {
delete( $args{$remove} );
}
}
my $self
= $class->SUPER::new( ssh_config => "$ENV{HOME}/.ssh/config", %args );
# load in ssh hostname for later use
if ( !%ssh_hostname_for || !$ssh_configs_read{ $self->{ssh_config} } ) {
$self->read_ssh_file( $self->{ssh_config} );
$self->debug( 5, 'Have the following ssh hostnames' );
$self->debug( 5, ' "', $_, '"' )
foreach ( sort keys %ssh_hostname_for );
}
return $self;
}
sub read_ssh_file($$) {
my ($self) = shift;
my ($filename) = glob(shift);
$self->debug( 3, 'Reading SSH file: ', $filename );
$ssh_configs_read{$filename} = 1;
if ( open( my $ssh_config_fh, '<', $filename ) ) {
while ( my $line = <$ssh_config_fh> ) {
chomp $line;
if ( $line =~ /^\s*include\s+(.+)/i ) {
$self->read_ssh_file($1);
next;
}
next unless ( $line =~ m/^\s*host\s+(.*)/i );
# account for multiple declarations of hosts
$ssh_hostname_for{$_} = 1 foreach ( split( /\s+/, $1 ) );
}
close($ssh_config_fh);
}
else {
$self->debug( 3, 'Unable to read ', $filename, ': ', $!, $/ );
}
}
sub get_hostname {
my ($self) = @_;
return $self->{hostname};
}
lib/App/ClusterSSH/Host.pm view on Meta::CPAN
}
# Check for a '/nnnn' port definition
if ( $host_string =~ s!(?:/(\d+)$)!! ) {
$port = $1;
}
# use number of colons as a possible indicator
my $colon_count = $host_string =~ tr/://;
# if there are 7 colons assume its a full IPv6 address
# if its 8 then assumed full IPv6 address with a port
# also catch localhost address here
if ( $colon_count == 7 || $colon_count == 8 || $host_string eq '::1' ) {
if ( $colon_count == 8 ) {
$host_string =~ s/(?::(\d+?))$//;
$port = $1;
}
$self->debug(
5,
$self->loc(
'IPv6: u=[_1] h=[_2] p=[_3] g=[_4]',
$username, $host_string, $port, $geometry,
),
);
return __PACKAGE__->new(
parse_string => $parse_string,
username => $username,
hostname => $host_string,
port => $port,
geometry => $geometry,
type => 'ipv6',
);
}
if ( $colon_count > 1
&& $colon_count < 8 )
{
warn 'Ambiguous host string: "', $host_string, '"', $/;
warn 'Assuming you meant "[', $host_string, ']"?', $/;
$self->debug(
5,
$self->loc(
'Ambiguous IPv6 u=[_1] h=[_2] p=[_3] g=[_4]',
$username, $host_string, $port, $geometry,
)
);
return __PACKAGE__->new(
parse_string => $parse_string,
username => $username,
hostname => $host_string,
port => $port,
geometry => $geometry,
type => 'ipv6',
);
}
# if we got this far, we didnt parse the host_string properly
croak(
App::ClusterSSH::Exception->throw(
error => $self->loc(
'Unable to parse hostname from "[_1]"', $host_string
)
)
);
}
sub check_ssh_hostname {
my ( $self, ) = @_;
$self->debug( 4, 'Checking ssh hosts for hostname ',
$self->get_hostname );
if ( $ssh_hostname_for{ $self->get_hostname } ) {
$self->debug( 5, 'Found' );
return 1;
}
else {
$self->debug( 5, 'Not found' );
return 0;
}
}
use overload (
q{""} => sub {
my ($self) = @_;
return $self->{hostname};
},
fallback => 1,
);
1;
=pod
=head1 NAME
ClusterSSH::Host - Object representing a host.
=head1 SYNOPSIS
use ClusterSSH::Host;
my $host = ClusterSSH::Host->new({
hostname => 'hostname',
});
my $host = ClusterSSH::Host->parse_host_string('username@hostname:1234');
=head1 DESCRIPTION
Object representing a host. Include details to contact the host such as
hostname/ipaddress, username and port.
=head1 METHODS
=over 4
=item $host=ClusterSSH::Host->new ({ hostname => 'hostname' })
Create a new host object. 'hostname' is a required arg, 'username' and
( run in 0.670 second using v1.01-cache-2.11-cpan-39bf76dae61 )