aboutsummaryrefslogtreecommitdiffstats
path: root/clients/smanagrun.pl
blob: 0546901006843ba9fbd575c32245cd3c30cf6895 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/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 $delaytime = 30;

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";

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});
}