]> git.sesse.net Git - nms/blob - clients/smanagrun.pl
Merge.
[nms] / clients / smanagrun.pl
1 #!/usr/bin/perl
2 #
3 #
4
5 use warnings;
6 use strict;
7 use Net::Telnet;
8 use DBI;
9 use POSIX;
10 use lib '../include';
11 use nms;
12
13 # Tweak and check
14 my $password = 'removed';
15 my $timeout = 15;
16 my $delaytime = 30;
17 my $poll_frequency = 60;
18
19 my $dbh = db_connect();
20 $dbh->{AutoCommit} = 0;
21
22 my $spoll = $dbh->prepare("
23 SELECT
24   addr,
25   sysname
26 FROM
27   squeue
28 WHERE
29   processed = 'f' AND
30   disabled = 'f' AND
31   (locked='f' OR now() - updated > '3 minutes'::interval) AND
32   (delay IS NULL OR delay - now() < 0)
33 ORDER BY
34   priority DESC,
35   added
36 LIMIT 1");
37 my $sgetallpoll = $dbh->prepare("
38 SELECT
39   id,
40   gid,
41   addr,
42   sysname,
43   cmd
44 FROM
45   squeue
46 WHERE
47   sysname = ? AND
48   disabled = 'f' AND
49   processed = 'f'
50 ORDER BY
51   priority DESC,
52   added");
53
54 my $slock = $dbh->prepare("UPDATE squeue SET locked = 't', updated=now() WHERE sysname = ?")
55         or die "Unable to prepare slock";
56 my $sunlock = $dbh->prepare("UPDATE squeue SET locked = 'f', updated=now() WHERE sysname = ?")
57         or die "Unable to prepare sunlock";
58 my $sresult = $dbh->prepare("UPDATE squeue SET updated = now(), result = ?,
59                             processed = 't' WHERE id = ?")
60         or die "Unable to prepare sresult";
61 my $sdelay = $dbh->prepare("UPDATE squeue SET delay = now() + delaytime, updated=now(), result = ? WHERE sysname = ?")
62         or die "Unable to prepae sdelay";
63
64 # Send a command to switch and return the data recvied from the switch
65 sub switch_exec($$) {
66         my ($cmd, $conn) = @_;
67
68         # Send the command and get data from switch
69         my @data = $conn->cmd($cmd);
70         my @lines = ();
71         foreach my $line (@data) {
72                 # Remove escape-7 sequence
73                 $line =~ s/\x1b\x37//g;
74                 push (@lines, $line);
75         }
76
77         return @data;
78 }
79
80 sub switch_connect($) {
81         my ($ip) = @_;
82
83         my $conn = new Net::Telnet(     Timeout => $timeout,
84                                         Dump_Log => '/tmp/dumplog-queue',
85                                         Errmode => 'return',
86                                         Prompt => '/es(\-)?3024|e\d+\-\dsw>/i');
87         my $ret = $conn->open(  Host => $ip);
88         if (!$ret || $ret != 1) {
89                 return (undef);
90         }
91         # XXX: Just send the password as text, I did not figure out how to
92         # handle authentication with only password through $conn->login().
93         #$conn->login(»·Prompt => '/password[: ]*$/i',
94         #               Name => $password,
95         #               Password => $password);
96         $conn->cmd($password);
97         # Get rid of banner
98         $conn->get;
99         return ($conn);
100 }
101
102 sub mylog {
103         my $msg = shift;
104         my $time = POSIX::ctime(time);
105         $time =~ s/\n.*$//;
106         printf STDERR "[%s] %s\n", $time, $msg;
107 }
108
109 while (1) {
110         $spoll->execute() or die "Could not execute spoll";
111         my $switch = $spoll->fetchrow_hashref();
112         if (!defined($switch)) {
113                 $dbh->commit;
114                 mylog("No available switches in pool, sleeping.");
115                 sleep 60;
116                 next;
117         }
118         $slock->execute($switch->{sysname});
119         $dbh->commit();
120
121         if ($switch->{'locked'}) {
122                 mylog("WARNING: Lock timed out on $switch->{'ip'}, breaking lock");
123         }
124
125         my $conn = switch_connect($switch->{addr});
126         if (!defined($conn)) {
127                 mylog("Could not connect to ".$switch->{sysname})."(".$switch->{addr}.")";
128                 $sdelay->execute("Could not connect to switch, delaying...", $switch->{sysname});
129                 $sunlock->execute($switch->{sysname});
130                 $dbh->commit();
131                 next;
132         }
133         my $error;
134         $error = $sgetallpoll->execute($switch->{sysname});
135         if (!$error) {
136                 print "Could not execute sgetallpoll\n".$dbh->errstr();
137                 $conn->close;
138                 next;
139         }
140         while (my $row = $sgetallpoll->fetchrow_hashref()) {
141                 print "sysname: ".$row->{sysname}." cmd: ".$row->{cmd}."\n";
142                 my @data = switch_exec($row->{cmd}, $conn);
143                 my $result = join("\n", @data);
144                 $sresult->execute($result, $row->{id});
145         }
146         $conn->close();
147         $sunlock->execute($switch->{sysname});
148 }
149