Firewall-Config-Connector

 view release on metacpan or  search on metacpan

lib/Firewall/Config/Connector.pm  view on Meta::CPAN

package Firewall::Config::Connector;

# ABSTRACT: turns baubles into trinkets

#------------------------------------------------------------------------------
# 加载系统模块
#------------------------------------------------------------------------------
use Moose;
use namespace::autoclean;
use POSIX;
use Time::HiRes;
use Data::Dumper;

#------------------------------------------------------------------------------
# 加载项目模块
#------------------------------------------------------------------------------
use Firewall::Config::Dao::Parser;
use Firewall::Config::Content::Static;
use Firewall::Utils::Date;

$Data::dumper::Sortkeys = 1;

has dbi => ( is => 'ro', does => 'Firewall::DBI::Role', );

sub update {
  my ( $self, %param ) = @_;
  my ( $fwType, @process, $conf, %processForFw, $numOfProcesses, $fwIds );
  my $fwInfo = $self->getFwInfo;
  if ( @{$param{fwIds}} ) {
    $fwIds = $param{fwIds};
  }
  else {
    $fwIds = [ keys %{$fwInfo} ];
  }
  $numOfProcesses
    = ( defined $param{numOfProcessesInput} and $param{numOfProcessesInput} > 0 ) ? $param{numOfProcessesInput} : 10;
  $numOfProcesses = ( @{$fwIds} > $numOfProcesses ) ? $numOfProcesses : scalar( @{$fwIds} );

  my $i = 0;
  foreach my $fwIdNum ( @{$fwIds} ) {
    push @{$process[ $i % $numOfProcesses ]}, $fwIdNum;
    $i++;
  }
  my $func = "getConfById";
  my %childPids;
  my $home = $ENV{firewall_manager_home};
  if ( not defined($home) or $home =~ /^\s*$/ ) {
    print("ERROR: 获取home目录失败: $@\n");
    exit();
  }
  my $logPath = $home . '/log/' . POSIX::strftime( "%Y%m%d", localtime() );
  mkdir( $logPath, 0755 ) or confess("ERROR: mkdir( $logPath, 0755 ) failed: $!") if not -d $logPath;
  for ( my $j = 0; $j < $numOfProcesses; $j++ ) {
    if ( my $pid = fork ) {
      $childPids{$pid}    = undef;
      $processForFw{$pid} = $process[$j];
    }
    else {
      foreach my $fwId ( @{$process[$j]} ) {
        my $logName = sprintf( '%04d', $fwId ) . '_' . $fwInfo->{$fwId}{fwName};
        if ( open( STDERR, q{>>}, "$logPath/$logName" ) ) {
          print STDERR '<'
            . Firewall::Utils::Date->new->getFormatedDate
            . "> $fwId:$fwInfo->{$fwId}{fwName} start in proc $$\n";

          $fwType = $fwInfo->{$fwId}->{fwType};
          eval { $conf = $self->getConfById( $fwInfo->{$fwId} ) };

          if ( !!$@ ) {
            open( my $failedList, q{>>}, "$logPath/failedList" )
              or confess("ERROR: open file $logPath/failedList failed: $!");
            print $failedList $fwId . ",";
            print STDERR $@;
          }
          else {
            eval { $self->saveconfig( {fwId => $fwId, type => $fwType, conf => $conf} ) };
            print STDERR $@ if !!$@;
            print STDERR '<' . Firewall::Utils::Date->new->getFormatedDate . "> $fwId:$fwInfo->{$fwId}{fwName} end\n";
          }
        }
        else {
          warn(qq{ERROR: open( STDERR, ">>$logPath/$logName" ) failed: $!});
        }
      } ## end foreach my $fwId ( @{$process...})
      exit;
    } ## end else [ if ( my $pid = fork ) ]
  } ## end for ( my $i = 0; $i < $numOfProcesses...)
  open( my $parentLog, q{>>}, "$logPath/parentLog" ) or confess("ERROR: open file $logPath/parentLog failed: $!");
  print $parentLog dumper( \%processForFw );
  close $parentLog;

  my $exitPid;
  while ( keys(%childPids) ) {
    while ( ( $exitPid = waitpid( -1, WNOHANG ) ) > 0 ) {
      delete( $childPids{$exitPid} );
      sleep(0.25);
    }
  }
} ## end sub update

sub saveconfig {
  my ( $self, $param ) = @_;
  my ( $fwId, $type, $conf ) = @{$param}{qw/fwId type conf/};
  my $sonDbi = $self->dbi->clone;
  my $predefinedService;
  eval
    "use Firewall::Config::Dao::PredefinedService::$type; \$predefinedService = Firewall::Config::Dao::PredefinedService::$type->new( dbi => \$sonDbi )";
  confess $@ if !!$@;

  $predefinedService = $predefinedService->load($fwId);
  use Firewall::Config::Dao::Config;
  my $daoConf         = Firewall::Config::Dao::Config->new( dbi => $sonDbi, conf => $conf );
  my $isConfigChanged = $daoConf->save;
  return unless $isConfigChanged or $ENV{firewall_manager_force_parse};
  my $daoLock;
  use Firewall::Config::Dao::Lock;
  $daoLock = Firewall::Config::Dao::Lock->new( dbi => $sonDbi, fwId => $fwId );
  $daoLock->lock;
  my $parser;
  eval
    "use Firewall::Config::Parser::$type; \$parser = Firewall::Config::Parser::$type->new(config => \$conf, preDefinedService => \$predefinedService);";
  confess $@ if !!$@;
  $parser->parse();
  my $dao = Firewall::Config::Dao::Parser->new( dbi => $sonDbi, parser => $parser );
  $dao->save;
  $daoLock->unLock;
} ## end sub saveconfig

sub getConfById {
  my ( $self, $fwInfoEachId ) = @_;
  my ( $fwId, $manageIp, $username, $passwd, $fwType, $connectionType, $fwName )
    = @{$fwInfoEachId}{qw/fwId manageIp username passwd fwType connectionType fwName/};
  my $className = "Firewall::Config::Connector::$fwType";
  my ( $config, $conn );
  eval "use $className;\$conn = \$className->new();";
  confess $@ if $@;
  my $configStr;
  my $num = 0;
  do {
    eval { $configStr = $conn->$connectionType( host => $manageIp, user => $username, password => $passwd ) };
    $num++;
    sleep 5;
  } while ( $num < 8 and $@ );
  confess $@ if $@;
  $config = [ split( /(?<=\n)/, $configStr ) ];
  my $conf
    = Firewall::Config::Content::Static->new( fwId => $fwId, fwName => $fwName, config => $config, fwType => $fwType );
  return $conf;
} ## end sub getConfById

sub getFwInfo {
  my $self   = shift;
  my $fwInfo = $self->dbi->execute(
    "select i.fw_id,i.fw_name,
        (select b.basekey_name from fw_basekey b where b.basekey_id = i.connection_type) as connection_type,
        (select b.basekey_name from fw_basekey b where b.basekey_id = i.fw_type) as fw_type,
        i.username,i.passwd,i.state,i.manage_ip,i.device_idfrom FW_INFO iwhere i.state = 1"
  )->all;
  $self->dbi->disconnect;



( run in 0.463 second using v1.01-cache-2.11-cpan-9581c071862 )