Your IP : 3.16.29.71


Current Path : /opt/webdir/lib/
Upload File :
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;