diff options
author | Joachim Tingvold <joachim@tingvold.com> | 2014-04-06 03:11:04 +0200 |
---|---|---|
committer | Joachim Tingvold <joachim@tingvold.com> | 2014-04-06 03:11:04 +0200 |
commit | 2a0c0a3dbbdf7fa5040953c0b0d88ad6f62c011e (patch) | |
tree | 92c7cbf54272466b46f64e5dc8d1ddb429858836 /clients/smanagrun.pl | |
parent | fe0be5960aac1f9bb600dbf853d862a9f4e60de8 (diff) |
Initial commit. Source; TG13-goodiebag.
Diffstat (limited to 'clients/smanagrun.pl')
-rwxr-xr-x | clients/smanagrun.pl | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/clients/smanagrun.pl b/clients/smanagrun.pl new file mode 100755 index 0000000..4d03696 --- /dev/null +++ b/clients/smanagrun.pl @@ -0,0 +1,167 @@ +#!/usr/bin/perl +# +# + +use warnings; +use strict; +use Net::Telnet; +use DBI; +use POSIX; +use lib '../include'; +use nms; +use Data::Dumper::Simple; + +BEGIN { + require "../include/config.pm"; + eval { + require "../include/config.local.pm"; + }; +} +# Tweak and check +my $password = ''; +my $timeout = 15; +my $delaytime = 30; +my $poll_frequency = 60; + +my $dbh = db_connect(); +$dbh->{AutoCommit} = 0; + +my $spoll = $dbh->prepare(" +SELECT + addr, + sysname +FROM + squeue +WHERE + processed = 'f' AND + disabled = 'f' AND + (locked='f' OR now() - updated > '10 minutes'::interval) AND + (delay IS NULL OR delay < now()) +ORDER BY + priority DESC, + added +LIMIT 1"); +my $sgetallpoll = $dbh->prepare(" +SELECT + id, + gid, + addr, + sysname, + cmd +FROM + squeue +WHERE + sysname = ? AND + disabled = 'f' AND + processed = 'f' +ORDER BY + priority DESC, + added"); + +my $slock = $dbh->prepare("UPDATE squeue SET locked = 't', updated=now() WHERE sysname = ?") + or die "Unable to prepare slock"; +my $sunlock = $dbh->prepare("UPDATE squeue SET locked = 'f', updated=now() WHERE sysname = ?") + or die "Unable to prepare sunlock"; +my $sresult = $dbh->prepare("UPDATE squeue SET updated = now(), result = ?, + processed = 't' WHERE id = ?") + or die "Unable to prepare sresult"; +my $sdelay = $dbh->prepare("UPDATE squeue SET delay = now() + delaytime, updated=now(), result = ? WHERE sysname = ?") + or die "Unable to prepae sdelay"; + +## Send a command to switch and return the data recvied from the switch +#sub switch_exec($$) { +# my ($cmd, $conn) = @_; +# +# # Send the command and get data from switch +# my @data = $conn->cmd($cmd); +# my @lines = (); +# foreach my $line (@data) { +# # Remove escape-7 sequence +# $line =~ s/\x1b\x37//g; +# push (@lines, $line); +# } +# +# return @data; +#} +# +#sub switch_connect($) { +# my ($ip) = @_; +# +# my $conn = new Net::Telnet( Timeout => $timeout, +# Dump_Log => '/tmp/dumplog-queue', +# Errmode => 'return', +# Prompt => '/DGS-3100\#/i'); +# my $ret = $conn->open( Host => $ip); +# if (!$ret || $ret != 1) { +# return (undef); +# } +# # XXX: Just send the password as text, I did not figure out how to +# # handle authentication with only password through $conn->login(). +# #$conn->login(»·Prompt => '/password[: ]*$/i', +# # Name => $password, +# # Password => $password); +# $conn->cmd($password); +# # Get rid of banner +# $conn->get; +# return ($conn); +#} +# +sub mylog { + my $msg = shift; + my $time = POSIX::ctime(time); + $time =~ s/\n.*$//; + printf STDERR "[%s] %s\n", $time, $msg; +} + +while (1) { + $spoll->execute() or die "Could not execute spoll"; + my $switch = $spoll->fetchrow_hashref(); + if (!defined($switch)) { + $dbh->commit; + mylog("No available switches in pool, sleeping."); + sleep 10; + next; + } + $slock->execute($switch->{sysname}); + $dbh->commit(); + + if ($switch->{'locked'}) { + mylog("WARNING: Lock timed out on $switch->{'ip'}, breaking lock"); + } + + mylog("Connecting to $switch->{sysname} on $switch->{addr}"); + my $conn = switch_connect($switch->{addr}); + if (!defined($conn)) { + mylog("Could not connect to ".$switch->{sysname}."(".$switch->{addr}.")"); + $sdelay->execute("Could not connect to switch, delaying...", $switch->{sysname}); + $sunlock->execute($switch->{sysname}); + $dbh->commit(); + next; + } + my $error; + $error = $sgetallpoll->execute($switch->{sysname}); + if (!$error) { + print "Could not execute sgetallpoll\n".$dbh->errstr(); + $conn->close; + next; + } + while (my $row = $sgetallpoll->fetchrow_hashref()) { + print "sysname: ".$row->{sysname}." cmd: ".$row->{cmd}."\n"; + my @data; + my @commands = split(/[\r\n\000]+/, $row->{cmd}); + for my $cmd (@commands) { + next unless $cmd =~ /\S/; # ignorer linjer med kun whitespace + push @data, "# $cmd"; + if ($cmd =~ s/^!//) { + push @data, switch_exec($cmd, $conn, 1); + } else { + push @data, switch_exec($cmd, $conn); + } + } + my $result = join("\n", @data); + $sresult->execute($result, $row->{id}); + } + $conn->close(); + $sunlock->execute($switch->{sysname}); +} + |