#!/usr/bin/perl -w

use strict ;
use Fcntl;
use Socket;
####################################################
# This collects a list of nodes from pbsnodes
# and ssh-keyscans them adding them to a known hosts file
# if they are new.


my $configfile = '/etc/edg-pbs-knownhosts.conf' ;

my $specified ;  # Nodes that have specified manually.
my $pbsbin ;     # Location of pbs's pbsnodes.
my $types ;      # Types of ssh keys to collect(-t)
my $knownhosts ; # The path of known_hosts file.
####################################################
# Read the configuration file.
open(CONFIG,"<$configfile") || die "Could not open $configfile: $!\n" ;
while(<CONFIG>) {
  $specified  = $1  if (/^NODES\s*=\s*(.*)/)  ;
  $pbsbin     = $1  if (/^PBSBIN\s*=\s*(.*)/)  ;
  $types      = $1  if (/^KEYTYPES\s*=\s*(.*)/) ;
  $knownhosts = $1  if (/^KNOWNHOSTS\s*=\s*(.*)/) ;
}
close(CONFIG) ;

####################################################
# Create an array of nodes.
my $pbsn = $pbsbin.'/pbsnodes -a' ;
open(PBSNODES,"$pbsn|") || die "Could note open $pbsn pipe: $!\n" ;
my @nodes ;
while(<PBSNODES>) {
   push(@nodes,$1) if (/^(\S+)\s*$/)
}
close(PBSNODES) ;
foreach (split(/\s+/,$specified)) {
  push(@nodes,$_) ;
}


###################################################
# Parse the current known host files and build a hash.
my %known ;
if ( -f $knownhosts ) {
  open(KNOWN,"<$knownhosts") || die "Could not open $knownhosts\n" ;
  while(<KNOWN>) {
      chomp;
      $known{$1} = "true" if(/^([^,\s]+)[,\s]/)  ;
  }
  close(KNOWN) ;
}
##################################################
# Now work through each of the nodes that have
# been requested and see if any are new.
my @new ;
foreach ( @nodes ) {
  push(@new,$_) unless ( $known{$_} )  ;
}
#################################################
# Now add all the new nodes to the known hosts
# file.
sysopen(KNOWN, $knownhosts, O_WRONLY|O_CREAT|O_APPEND) ||die  $!;
foreach(@new) {
  my $packedaddress = inet_aton($_) ;
  if ($packedaddress) {
    my $ip =   inet_ntoa($packedaddress) ;
    my $cmd = "/usr/bin/ssh-keyscan -t $types $_ $ip 2>/dev/null" ;
    open(SCAN,"$cmd|") || die $! ;
    while(<SCAN>) {
      print KNOWN $_ ;
    }
    close(SCAN) ;
  }
}
close(KNOWN) ;
