#!/usr/bin/perl my $config; my $configs; my $host; my @hosts; my $ssh_opt; my $user; my $pass; my $remain; my $count=1; # Expect Befehl vom System ermitteln my $expect="/usr/bin/expect"; # Datumsstring yyyymmdd_hhmmss my $date=`date +"%Y%m%d_%H%M%S"`; chomp $date; # zu konfigurierende hosts aus configs.txt auslesen open CONFIGS, ") { # Kommentarzeilen überspringen # Auskommentierte hosts überpringen next if ($l =~ /^#/); ($host)=$l=~ /^(.*) >>>>$/; # host in @hosts aufnehmen push @hosts, $host if $host ne ""; } close CONFIGS; # komplette configs.txt einlesen open CONFIGS, "; close CONFIGS; # komplette configs in eine variable für multiline matche foreach (@configs) { next if /^#/; $configs=$configs . $_; } # für alle zu konfigurierende hosts die konfig ermitteln foreach $host (@hosts) { # Logfilename erstellen # log_yyyymmdd_hhmmss_Nummer.txt # Nummer wird für jeden host hochgezählt, also neues logfile für jeden Konfigabschnitt $logfile="log_".$date."_$count".".txt"; #$logfile="log"; $count++; # Initialisierung $ssh_opt=""; $user=""; $pass=""; $config=""; $remain=""; # Aus gesamtem Konfigfile den Teil für host selektieren (nach $config) # Der Rest geht nach $remain ($config,$remain) = $configs =~ /$host >>>>\n(.*?)<<<<(.*)/s; # Der Rest ist dann die neue gesamte Konfiguration $configs=$remain; # die parameter für verbindungen zum host aus devices.txt lesen open DEVICES, ") { # steht am Anfang der Zeile (Kommentarzeile) ein # wird übersprungen next if /^#/; chomp; # Zeile holen in der Verbindungsparameter für host stehen if (/^$host/) { # Parameter splitten ($host,$ssh_opt,$user,$pass) = split /\|/; $pwtxt="from config"; # Wenn als Passwort ENV:SSHPASS angegeben ist, if ($pass eq "ENV:SSHPASS") { # Inhalt der Umgebungsvariablen SSHPASS als PW nutzen $pass = $ENV{'SSHPASS'}; $pwtxt="from ENV:SSHPASS"; } # vorhandene ssh Parameter werden angenommen # ist Zeichenkette leer: keine Paramter my $o=1; $o=0 if $ssh_opt eq ""; # das expect skript dazu bauen # host, dessen konfig und Schalter ob ssh Parameter verwendet werden write_exp ($host, $config, $o); } } close DEVICES; # wenn keine Zeile in devices für host gefunden wurde oder es wurde # kein User und/oder Passwort angegeben: Fehler und Tschüss if ($user eq "" or $pass eq "") { die "\n\nno user or password for host $host\n\n"; } # Logfile erstellen wird expect weiter gefüllt open LOG, ">$logfile"; printf LOG "!\n! Let's have a look at host $host\n!\n\n"; # alles soweit korrekt dann konfig durchführen ($o1,$o2)=split/ /, $ssh_opt; print "Start expect with parameters\n\tscript run.exp\n\tlogfile $logfile\n\thost $host\n\tuser $user\n\tpassword *hidden* $pwtxt\n\nssh Options used\n\t-oStrictHostKeyChecking=no\n\t-oUserKnownHostsFile=/dev/null\n\t$o1\n\t$o2\n\n"; printf LOG "Start expect with parameters\n\tscript run.exp\n\tlogfile $logfile\n\thost $host\n\tuser $user\n\tpassword *hidden* $pwtxt\n\nssh Options used\n\t-oStrictHostKeyChecking=no\n\t-oUserKnownHostsFile=/dev/null\n\t$o1\n\t$o2\n\n"; close LOG; `$expect run.exp $logfile $host $user $pass $ssh_opt`; } unlink "run.exp"; # Funktion zum erstellen der run.exp sub write_exp { my ($host,$config,$options)=@_; open FILE, ">run.exp"; # Neue run.exp printf FILE <<'EOFILE1'; # run.exp füllen #!/usr/bin/expect -f set timeout 20 log_file [lindex $argv 0] set host [lindex $argv 1] set user [lindex $argv 2] set pass [lindex $argv 3] set ssh1 [lindex $argv 4] set ssh2 [lindex $argv 5] set ssh3 [lindex $argv 6] EOFILE1 close FILE; # Datei schließen open FILE, ">>run.exp"; # an run.exp anhängen # ssh optionen vorhanden, daher ssh Aufruf mit diesen Parametern in run.exp schreiben if ($options == 1) { printf FILE 'spawn ssh $host -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -l $user $ssh1 $ssh2 $ssh3' . "\n"; } # ssh optionen nicht vorhanden, daher ssh ohne Parameter in run.exp schreiben if ($options == 0) { printf FILE 'spawn ssh $host -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -l $user' . "\n"; } close FILE; # Datei schließen my @conf=split /\n/, $config; foreach (@conf) { chomp; s/\/\/.*//; # Kommentare entfernen s/\s*$//g; # Leerzeichen am Zeilenende entfernen ($semi) = $_ =~ /(;*)$/; # Semikolons ausschneiden my $count=length($semi); # Anzahl Semikolons s/;*$//; # Semikolons entfernen for ($i=1; $i<=$count; $i++) { # und durch Anzahl $_=$_ .'\n'; # mal \n ersetzen; wichtig! ' verwenden } s/^s (.*)/send "$1\\n"/; # s durch send ersetzen und " hinzufügen s/^e (.*)/expect "$1"/; # e durch expect ersetzen und " hinzufügen $_=$_ . "\n"; # Zeilenumbruch anhängen; wichtig! " verwenden } open FILE, ">>run.exp"; # Expect Befehle in run.exp schreiben foreach (@conf) { printf FILE $_; } printf FILE "expect eof\nexit\n"; # Expect abschließen close FILE; # run.exp schließen }