]> git.sesse.net Git - nms/blob - web/tempfetch.pl
initial import
[nms] / web / tempfetch.pl
1 #! /usr/bin/perl
2 #use BER;
3 use Data::Dumper;
4 use DBI;
5 use Net::Telnet;
6 use POSIX;
7 use Time::HiRes;
8 use strict;
9 use warnings;
10 #require 'SNMP_Session.pm';
11
12 # Tweak timeouit og sjekk med :support||:net hva passord vil bli
13 my $password = 'removed';
14 my $timeout = 25;
15 my $location = 'skipet';
16
17 my $dbh = DBI->connect("dbi:Pg:dbname=snmpfetch;host=violet.tg05.gathering.org", "snmpfetch", "removed")
18         or die "Couldn't connect to database";
19 $dbh->{AutoCommit} = 0;
20
21 my $qswitch = $dbh->prepare(<<"EOF")
22 SELECT 
23   *
24 FROM
25   switches
26   NATURAL LEFT JOIN switchtypes
27 WHERE
28   (locked='f' OR now() - last_updated > '15 minutes'::interval)
29 LIMIT 1
30 FOR UPDATE OF switches
31 EOF
32         or die "Couldn't prepare qswitch";
33 my $qlock = $dbh->prepare("UPDATE switches SET locked='t', last_updated=now() WHERE switch=?")
34         or die "Couldn't prepare qlock";
35 my $qunlock = $dbh->prepare("UPDATE switches SET locked='f', last_updated=now() WHERE switch=?")
36         or die "Couldn't prepare qunlock";
37 my $qpoll = $dbh->prepare("INSERT INTO temppoll (time, switch, temp) VALUES (timeofday()::timestamp,?::text::int,?::text::float)")
38         or die "Couldn't prepare qpoll";
39
40 while (1) {
41         # Find a switch to grab
42         $qswitch->execute()
43                 or die "Couldn't get switch";
44         my $switch = $qswitch->fetchrow_hashref();
45
46         if (!defined($switch)) {
47                 $dbh->commit;
48                 mylog("No available switches in pool, sleeping.");
49                 sleep 60;
50                 next;
51         }
52
53         $qlock->execute($switch->{'switch'})
54                 or die "Couldn't lock switch";
55         $dbh->commit;
56
57         if ($switch->{'locked'}) {
58                 mylog("WARNING: Lock timed out on $switch->{'ip'}, breaking lock");
59         }
60
61         my $msg;
62         if (defined($switch->{'overdue'})) {
63                 $msg = sprintf "Polling temp on %s (%s), %s overdue.",
64                         $switch->{'ip'}, $switch->{'sysname'}, $switch->{'overdue'};
65         } else {
66                 $msg = sprintf "Polling temp on %s (%s), never polled before.",
67                         $switch->{'ip'}, $switch->{'sysname'};
68         }
69         mylog($msg);
70
71         my $ip = $switch->{'ip'};
72         my $start = [Time::HiRes::gettimeofday];
73         eval {
74                 my $conn = switch_connect($ip);
75                 if (!defined($conn)) {
76                         print "Could not connect to switch ".$switch->{'switch'}."\n";
77                 }
78                 my @data = switch_exec('sys monitor status', $conn);
79                 my @fields = split(/\s+/, $data[2]);
80                 # The temp fields are 6, 7, 8
81                 my $avgtemp = ($fields[6] + $fields[7] + $fields[8]) / 3;
82                 print $avgtemp." avgtemp\n";
83                 $qpoll->execute($switch->{'switch'},
84                                 $avgtemp) or die "Could not exec qpoll";
85         };
86         my $elapsed = Time::HiRes::tv_interval($start);
87         $msg = sprintf "Polled $switch->{'ip'} in %5.3f seconds.", $elapsed;
88         mylog($msg);
89
90         $qunlock->execute($switch->{'switch'})
91                 or die "Couldn't unlock switch";
92         sleep 1;
93         $dbh->commit;
94 }
95
96 sub switch_exec {
97         my ($cmd, $conn) = @_;
98
99         # Send the command and get data from switch
100         my @data = $conn->cmd($cmd);
101         my @lines = ();
102         foreach my $line (@data) {
103                 # Remove escape-7 sequence
104                 $line =~ s/\x1b\x37//g;
105                 push (@lines, $line);
106                 }
107
108         return @lines;
109 }
110
111 sub switch_connect {
112         my ($ip) = @_;
113
114         my $conn = new Net::Telnet(     Timeout => $timeout,
115                                         Dump_Log => '/tmp/dumplog',
116                                         Errmode => 'return',
117                                         Prompt => '/(es3024|e\d+\-\dsw)>/i');
118         my $ret = $conn->open(  Host => $ip);
119         if (!$ret || $ret != 1) {
120                 return (0);
121         }
122         # XXX: Just send the password as text, I did not figure out how to
123         # handle authentication with only password through $conn->login().
124         #$conn->login(  Prompt => '/password[: ]*$/i',
125         #               Name => $password,
126         #               Password => $password);
127         my @data = $conn->cmd($password);
128         # Get rid of banner
129         $conn->get;
130         return ($conn);
131 }
132
133
134 sub mylog {
135         my $msg = shift;
136         my $time = POSIX::ctime(time);
137         $time =~ s/\n.*$//;
138         printf STDERR "[%s] %s\n", $time, $msg;
139 }