Your IP : 3.16.29.71
Current Path : /opt/webdir/lib/ |
|
Current File : //opt/webdir/lib/bxNetwork.pm |
package bxNetwork;
use Moose;
use File::Basename qw( dirname basename );
use File::Spec::Functions;
use Data::Dumper;
use Sys::Hostname;
use Net::DNS;
use Output;
use JSON;
use Pool;
# short hostname, defualt bxserverID
has 'host' => (
is => 'rw',
isa => 'Str',
lazy => 1,
builder => 'get_host_by_netaddr',
predicate => 'has_host',
);
# ip address or fqdn
has 'netaddr' => (
is => 'rw',
isa => 'Str',
lazy => 1,
builder => 'get_netaddr_by_host',
predicate => 'has_netaddr',
);
has 'interface' => (
is => 'ro',
isa => 'Str',
);
has 'debug' => (
is => 'ro',
isa => 'Int',
default => 0,
);
has 'logfile' => (
is => 'ro',
isa => 'Str',
default => '/opt/webdir/logs/pool_network.debug',
);
# bulid
sub BUILD {
my $self = shift;
die "Need to specify at least one of 'netaddr', 'host'!"
unless $self->has_netaddr || $self->has_host;
}
# create default bxserverID name
sub create_default_name {
my $self = shift;
my $standart_name = "server";
my $last_id = 0;
my $pool = Pool->new();
my $get_servers = $pool->get_ansible_data();
# pool is created
if ($get_servers->is_error == 0){
my $data_servers = $get_servers->get_data->[1];
foreach my $srv_name (keys %$data_servers){
if ($srv_name =~ /^$standart_name(\d+)$/){
my $id = $1;
if ($last_id < $id){ $last_id = $id; }
}
}
}
$last_id = $last_id+1;
return $standart_name.$last_id;
}
# dnsname to ip address
sub a_lookup {
my $self = shift;
my $dnsname = shift;
my $res = Net::DNS::Resolver->new(recurse => 0, debug => $self->debug);
$res->udp_timeout(10);
$res->force_v4(1);
my $query = $res->search($dnsname, 'A');
my $ip = '';
# found
if ($query){
foreach my $rr ($query->answer) {
next unless $rr->type eq "A";
$ip = $rr->address;
}
}
return $ip;
}
# BUILDER
# ip address to dnsname
sub ptr_lookup {
my $self = shift;
my $ip = shift;
my $res = Net::DNS::Resolver->new(recurse => 0, debug => $self->debug);
$res->udp_timeout(10);
$res->force_v4(1);
my $query = $res->search($ip,'PTR');
my $dnsname = '';
# found
if ($query){
foreach my $rr ($query->answer) {
next unless $rr->type eq "PTR";
if ( $rr->ptrdname =~ /^[\w\d\-\_\.]+\.(com|ru|de|org|ua|private|test|bx|lan)$/i ){
if($self->debug){
printf "%-15s: %s\n",("Found PTR", $rr->ptrdname);
}
$dnsname = $rr->ptrdname;
}
}
}
return $dnsname;
}
# BUILDER
# get netaddr by hostname
sub get_netaddr_by_host {
my $self = shift;
my $host = $self->host;
my $debug = $self->debug;
my $logOutput = Output->new(error => 0, logfile => $self->logfile);
my $netaddr = $self->a_lookup($host);
if ($debug) { $logOutput->log_data($netaddr); }
return $netaddr;
}
sub get_host_by_netaddr {
my $self = shift;
my $netaddr = $self->netaddr;
my $host = '';
# ip
if ( $netaddr =~ /^[0-9\.]+$/ ){
$host = $self->ptr_lookup($netaddr);
if ( $host =~ /^$/ ){
$host = $self->create_default_name;
}
}else{
# first part of DNS name
$host = $netaddr;
$host =~ s/^([^\.]+)\..+$/$1/;
}
return $host;
}
# create network info for localhost
sub create_localhost {
my $self = shift;
my $message_p = (caller(0))[3];
# return values
my %h_info = (
'host' => '',
'netaddr' => '',
'type' => 'ip',
'interface' => '',
);
# get localhost network options
$h_info{'host'} = hostname;
if ($self->debug){ printf "%-15s: %s\n",($message_p, "Hostname: ".$h_info{'host'}); }
my @interfaces = IO::Interface::Simple->interfaces;
# if user defined interface that used in the pool
if (defined $self->interface){
@interfaces = grep /^$self->interface$/, @interfaces;
}
my $running_int = '';
foreach my $int (sort @interfaces){
if ($running_int =~ /^$/ && $int->is_running && $int !~ /^lo/ ){
if ($int->address !~ /^127\.0\.0\.1$/){
$running_int = $int;
$h_info{'netaddr'} = $int->address;
$h_info{'interface'} = $int;
if ($self->debug){
printf "%-15s: %s\n",($message_p, "Interface: $int, Address: ". $h_info{'netaddr'});
}
}
}
}
# exclude next names, creating default values
my $lregexp = '^(localhost|localhost\.localdomain|127\.0\.0\.1|)$';
# if we create hostname localy, use it ip address
if ($h_info{'host'} =~ /$lregexp/){
$h_info{'host'} = $self->create_default_name;
if ($self->debug){
printf "%-15s: %s\n",($message_p, "Generate hostname: ". $h_info{'host'});
}
# if hostname was set
}else{
# check if ip address fits to hostname
my $ipaddres_by_dns = $self->a_lookup($h_info{'host'});
if ($self->debug){
printf "%-15s: %s\n",($message_p, "Nslookup: ". $ipaddres_by_dns);
}
# if hostname is resolved, ip_address is not empty
if ($ipaddres_by_dns !~ /^$/){
# address the same, use hostname like netaddr
if ($h_info{'netaddr'} =~ /^$ipaddres_by_dns$/){
$h_info{'type'} = 'fqdn';
$h_info{'netaddr'} = $h_info{'host'};
$h_info{'host'} =~ s/^([^\.]+)\..+$/$1/;
if ($self->debug){
printf "%-15s: %s\n",($message_p, "Name correct use it: ". $h_info{'host'});
}
}
}
}
# creat short name
$h_info{'host'} =~ s/^([^\.]+)\..+$/$1/;
#print Dumper(\%h_info);
return \%h_info;
}
# hostinfo
# test netaddr and host attributtes
sub network_info {
my $self = shift;
my $message_p = (caller(0))[3];
my $message_t = __PACKAGE__;
# return values
my %h_info = (
'host' => $self->host,
'netaddr' => $self->netaddr,
'type' => 'fqdn',
);
if ($self->debug){
printf "%-15s: %s\n",($message_p, "Host: ". $h_info{'host'});
printf "%-15s: %s\n",($message_p, "IP: ". $h_info{'netaddr'});
}
# own method for localhost
my $lregexp = '^(localhost|localhost\.localdomain|127\.0\.0\.1)$';
if ( $h_info{'host'} =~ /$lregexp/ || $h_info{'netaddr'} =~ /$lregexp/ ){
if ($self->debug){
printf "%-15s: %s\n",($message_p, "Detected $lregexp for ". $h_info{'host'});
}
my $create_localhost_info = $self->create_localhost;
%h_info = %{$create_localhost_info};
}else{
# get ip add by hostname ( from saved file )
if ( $h_info{'netaddr'} =~ /^$/ ){
return Output->new(
error => 1,
message => "Cannot defined ip address for hostname ".$h_info{'host'},
);
}
# this is impossible, but all things are possible
if ( $h_info{'host'} =~ /^$/ ){
return Output->new(
error => 1,
message => "Cannot defined hostname for network addrress ".$h_info{'netaddr'},
);
}
# if defined ip and cannot define name for host (generate it)
if ( $h_info{'netaddr'} =~ /^[0-9\.]+$/ ){
# if short name is ip address create new one
if ( $h_info{'host'} =~ /^$h_info{'netaddr'}$/ ){
$h_info{'host'} = $self->create_default_name;
# test host info and ip
}else{
# test if A record is the same with hostname
my $test_ip = $self->a_lookup($h_info{'host'});
if ( $test_ip =~ $h_info{'netaddr'} ){
$h_info{'netaddr'} = $h_info{'host'};
$h_info{'type'} = 'fqdn';
}else{
$h_info{'type'} = 'ip';
}
}
}else{
if ( $h_info{'host'} =~ /^$h_info{'netaddr'}$/ ){
my $test_ip = $self->a_lookup($h_info{'host'});
# test if we can get ip by netaddres
if ( $test_ip !~ /^$/ ){
$h_info{'type'} = 'fqdn';
}else{
return Output->new(
error => 1,
message => "Cannot get IP for network addrress ".$h_info{'netaddr'},
);
}
}else{
my $host_ip = $self->a_lookup($h_info{'host'});
my $netaddr_ip = $self->a_lookup($h_info{'netaddr'});
if ($netaddr_ip =~ /^$/){
return Output->new(
error => 1,
message => "Cannot get IP for network addrress ".$h_info{'netaddr'},
);
}
if ($host_ip =~ /^$/){
$h_info{'host'} = $h_info{'netaddr'};
$h_info{'type'} = 'fqdn';
}else{
if ( $host_ip =~ /^$netaddr_ip$/ ){
$h_info{'host'} = $h_info{'netaddr'};
$h_info{'type'} = 'fqdn';
}else{
return Output->new(
error => 1,
message => "IP address for ".$h_info{'host'}." doesn't match ip network name ".$h_info{'netaddr'},
);
}
}
}
}
}
# define type from netaddr
if ( $h_info{'netaddr'} =~ /^[0-9\.]+$/ ){
$h_info{'type'} = 'ip';
}
$h_info{'host'} =~ s/^([^\.]+)\..+$/$1/;
return Output->new(
error => 0,
data => ['host_network', \%h_info],
);
};
1;