diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/FixedSNMP.pm | 125 | ||||
-rwxr-xr-x | include/config.pm.dist | 136 | ||||
-rwxr-xr-x | include/nms.pm | 186 | ||||
-rw-r--r-- | include/nms/snmp.pm | 91 | ||||
-rw-r--r-- | include/nms/util.pm | 141 | ||||
-rwxr-xr-x | include/nms/web.pm | 112 |
6 files changed, 0 insertions, 791 deletions
diff --git a/include/FixedSNMP.pm b/include/FixedSNMP.pm deleted file mode 100644 index 1ea3089..0000000 --- a/include/FixedSNMP.pm +++ /dev/null @@ -1,125 +0,0 @@ -# A bugfix to the gettable functions of SNMP.pm, that deals properly -# with bulk responses being overridden. Original copyright: -# -# Copyright (c) 1995-2006 G. S. Marzot. All rights reserved. -# This program is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -# To use, just "use FixedSNMP;" and then use SNMP::Session as usual. - -use strict; -use warnings; -use SNMP; - -package FixedSNMP::Session; - -sub _gettable_do_it() { - my ($this, $vbl, $parse_indexes, $textnode, $state) = @_; - - my ($res); - - $vbl = $_[$#_] if ($state->{'options'}{'callback'}); - - my $num_vbls = scalar @$vbl; - my $num_stopconds = scalar @{$state->{'stopconds'}}; - - while ($num_vbls > 0 && !$this->{ErrorNum}) { - my @found_eof = (0) x $num_stopconds; - - for (my $i = 0; $i <= $#$vbl; $i++) { - my $row_oid = SNMP::translateObj($vbl->[$i][0]); - my $row_text = $vbl->[$i][0]; - my $row_index = $vbl->[$i][1]; - my $row_value = $vbl->[$i][2]; - my $row_type = $vbl->[$i][3]; - - my $stopcond_num = $i % $num_stopconds; - my $stopcond = $state->{'stopconds'}[$stopcond_num]; - if ($row_oid !~ /^\Q$stopcond\E/ || $row_value eq 'ENDOFMIBVIEW') { - $found_eof[$stopcond_num] = 1; - } else { - - if ($row_type eq "OBJECTID") { - - # If the value returned is an OID, translate this - # back in to a textual OID - - $row_value = SNMP::translateObj($row_value); - - } - - # continue past this next time - - $state->{'varbinds'}[$stopcond_num] = [ $row_text, $row_index ]; - - # Place the results in a hash - - $state->{'result_hash'}{$row_index}{$row_text} = $row_value; - } - } - - my @newstopconds = (); - my @newvarbinds = (); - for (my $i = 0; $i < $num_stopconds; ++$i) { - unless ($found_eof[$i]) { - push @newstopconds, $state->{'stopconds'}[$i]; - push @newvarbinds, $state->{'varbinds'}[$i]; - } - } - if ($#newstopconds == -1) { - last; - } - $state->{'varbinds'} = \@newvarbinds; - $state->{'stopconds'} = \@newstopconds; - $vbl = $state->{'varbinds'}; - $num_vbls = scalar @newvarbinds; - $num_stopconds = scalar @newstopconds; - - # - # if we've been configured with a callback, then call the - # sub-functions with a callback to our own "next" processing - # function (_gettable_do_it). or else call the blocking method and - # call the next processing function ourself. - # - if ($state->{'options'}{'callback'}) { - if ($this->{Version} ne '1' && !$state->{'options'}{'nogetbulk'}) { - $res = $this->getbulk(0, $state->{'repeatcount'}, $vbl, - [\&_gettable_do_it, $this, $vbl, - $parse_indexes, $textnode, $state]); - } else { - $res = $this->getnext($vbl, - [\&_gettable_do_it, $this, $vbl, - $parse_indexes, $textnode, $state]); - } - return; - } else { - if ($this->{Version} ne '1' && !$state->{'options'}{'nogetbulk'}) { - $res = $this->getbulk(0, $state->{'repeatcount'}, $vbl); - } else { - $res = $this->getnext($vbl); - } - } - } - - # finish up - _gettable_end_routine($state, $parse_indexes, $textnode); - - # return the hash if no callback was specified - if (!$state->{'options'}{'callback'}) { - return($state->{'result_hash'}); - } - - # - # if they provided a callback, call it - # (if an array pass the args as well) - # - if (ref($state->{'options'}{'callback'}) eq 'ARRAY') { - my $code = shift @{$state->{'options'}{'callback'}}; - $code->(@{$state->{'options'}{'callback'}}, $state->{'result_hash'}); - } else { - $state->{'options'}{'callback'}->($state->{'result_hash'}); - } -} - -*FixedSNMP::Session::_gettable_end_routine = *SNMP::Session::_gettable_end_routine; -*SNMP::Session::_gettable_do_it = *FixedSNMP::Session::_gettable_do_it; diff --git a/include/config.pm.dist b/include/config.pm.dist deleted file mode 100755 index cf1362a..0000000 --- a/include/config.pm.dist +++ /dev/null @@ -1,136 +0,0 @@ -#! /usr/bin/perl -use strict; -use warnings; -use DBI; -package nms::config; - -# DB -our $db_name = "nms"; -our $db_host = "bb-8.tg16.gathering.org"; -our $db_username = "nms"; -our $db_password = "<removed>"; # TODO: Remove before publishing "goodiebag" - -# Gondul -our $gondul_url = "http://foo.bar"; # TODO: Remove before publishing "goodiebag" -our $gondul_user = "secret"; # TODO: Remove before publishing "goodiebag" -our $gondul_pass = "<removed>"; # TODO: Remove before publishing "goodiebag" - -# NMS: What SNMP objects to fetch. -# Some basics -our @snmp_objects = [ -['ifIndex'], -['sysName'], -['sysDescr'], -['ifHighSpeed'], -['ifType'], -['ifName'], -['ifDescr'], -['ifAlias'], -['ifOperStatus'], -['ifAdminStatus'], -['ifLastChange'], -['ifHCInOctets'], -['ifHCOutOctets'], -['ifInDiscards'], -['ifOutDiscards'], -['ifInErrors'], -['ifOutErrors'], -['ifInUnknownProtos'], -['ifOutQLen'], -['sysUpTime'], -['jnxOperatingTemp'], -['jnxOperatingCPU'], -['jnxOperatingDescr'], -['jnxBoxSerialNo'] -]; -# Max SNMP polls to fire off at the same time. -our $snmp_max = 20; - -# DHCP-servers -our $dhcp_server1 = "185.110.149.2"; # primary -our $dhcp_server2 = "185.110.148.2"; # secondary - -# TACACS-login for NMS -our $tacacs_user = "<removed>"; # TODO: Remove before publishing "goodiebag" -our $tacacs_pass = "<removed>"; # TODO: Remove before publishing "goodiebag" - -# Telnet-timeout for smanagrun -our $telnet_timeout = 300; - -# IP/IPv6/DNS-info -our $tgname = "tg16"; -our $pri_hostname = "r2-d2"; -our $pri_v4 = "185.110.149.2"; -our $pri_v6 = "2a06:5841:149a::2"; -our $pri_net_v4 = "185.110.149.0/26"; -our $pri_net_v6 = "2a06:5841:149a::/64"; - -our $sec_hostname = "c-3po"; -our $sec_v4 = "185.110.148.2"; -our $sec_v6 = "2a06:5841:1337::2"; -our $sec_net_v4 = "185.110.148.0/26"; -our $sec_net_v6 = "2a06:5841:1337::/64"; - -# for RIPE to get reverse zones via DNS AXFR -# https://www.ripe.net/data-tools/dns/reverse-dns/how-to-set-up-reverse-delegation -our $ext_xfer = "193.0.0.0/22; 2001:610:240::/48; 2001:67c:2e8::/48"; - -# allow XFR from NOC -our $noc_net = "185.110.150.0/25; 2a06:5841:150a::1/64"; - -# To generate new dnssec-key for ddns: -# dnssec-keygen -a HMAC-MD5 -b 512 -n HOST DHCP_UPDATER -our $ddns_key = "<removed>"; # TODO: Remove before publishing "goodiebag" -our $ddns_to = "127.0.0.1"; # just use localhost - -# Base networks -our $base_ipv4net = "88.92.0.0/17"; -our $base_ipv6net = "2a06:5840::/29"; -our $ipv6zone = "0.4.8.5.6.0.a.2.ip6.arpa"; - -# extra networks that are outside the normal ranges -# that should have recursive DNS access -our @rec_net = ( - '185.110.148.0/22', -); - -# extra networks that are outside the normal ranges -# that should be added to DNS -our @extra_nets = ( - '185.110.148.0/24', - '185.110.149.0/24', - '185.110.150.0/24', - '185.110.151.0/24', -); - -# add WLC's -our $wlc1_v4 = "185.110.148.14"; -our $wlc1_v6 = "f00d::1"; - -# add VOIP-server -our $voip1_v4 = "<removed>"; # TODO: Remove before publishing "goodiebag" -our $voip1_v6 = "<removed>"; # TODO: Remove before publishing "goodiebag" - -# PXE-server (rest of bootstrap assumes $sec_v4/$sec_v6) -our $pxe_server_v4 = $sec_v4; -our $pxe_server_v6 = $sec_v6; - -# FAP-server (Gondul) -our $fap_server_v4 = "<removed>"; # TODO: Remove before publishing "goodiebag" -our $fap_server_v6 = "<removed>"; # TODO: Remove before publishing "goodiebag" -our @fap_networks = ( - '88.92.54.0/26', # distro0 - '88.92.54.64/26', # distro1 - '88.92.54.128/26', # distro2 - '88.92.54.192/26', # distro3 - '88.92.55.0/26', # distro4 - '88.92.55.64/26', # distro5 - '88.92.55.128/26', # distro6 - '88.92.55.192/26', # distro7 - '88.92.56.0/26', # distro8 - '88.92.56.64/26', # vc1.ring -); - - - -1; diff --git a/include/nms.pm b/include/nms.pm deleted file mode 100755 index 2ec922b..0000000 --- a/include/nms.pm +++ /dev/null @@ -1,186 +0,0 @@ -#! /usr/bin/perl -use strict; -use warnings; -use DBI; -use Net::OpenSSH; -use Net::Telnet; -use Data::Dumper; -use FileHandle; -use JSON; -package nms; - -use base 'Exporter'; -our @EXPORT = qw(switch_disconnect switch_connect_ssh switch_connect_dlink switch_exec switch_exec_json switch_timeout db_connect); - -BEGIN { - require "config.pm"; - eval { - require "config.local.pm"; - }; -} - - -sub db_connect { - my $connstr = "dbi:Pg:dbname=" . $nms::config::db_name; - $connstr .= ";host=" . $nms::config::db_host unless (!defined($nms::config::db_host)); - - my $dbh = DBI->connect($connstr, - $nms::config::db_username, - $nms::config::db_password, {AutoCommit => 0}) - or die "Couldn't connect to database"; - return $dbh; -} - -sub switch_connect_ssh($) { - my ($ip) = @_; - my $ssh = Net::OpenSSH->new($ip, - user => $nms::config::tacacs_user, - password => $nms::config::tacacs_pass, - master_opts => [ "-o", "StrictHostKeyChecking=no" ]); - my ($pty, $pid) = $ssh->open2pty({stderr_to_stdout => 1}) - or die "unable to start remote shell: " . $ssh->error; - - my $dumplog = FileHandle->new; - $dumplog->open(">>/tmp/dumplog-queue") or die "/tmp/dumplog-queue: $!"; - #$dumplog->print("\n\nConnecting to " . $ip . "\n\n"); - - my $inputlog = FileHandle->new; - $inputlog->open(">>/tmp/inputlog-queue") or die "/tmp/inputlog-queue: $!"; - #$inputlog->print("\n\nConnecting to " . $ip . "\n\n"); - - my $telnet = Net::Telnet->new(-fhopen => $pty, - -timeout => $nms::config::telnet_timeout, - -dump_log => $dumplog, - -input_log => $inputlog, - -prompt => '/.*\@[a-z0-9-]+[>#] /', - -telnetmode => 0, - -cmd_remove_mode => 1, - -output_record_separator => "\r"); - $telnet->waitfor(-match => $telnet->prompt, - -errmode => "return") - or die "login failed: " . $telnet->lastline; - - $telnet->cmd("set cli screen-length 0"); - - return { telnet => $telnet, ssh => $ssh, pid => $pid, pty => $pty }; -} - -sub switch_connect_dlink($) { - my ($ip) = @_; - - my $dumplog = FileHandle->new; - $dumplog->open(">>/tmp/dumplog-queue") or die "/tmp/dumplog-queue: $!"; - $dumplog->print("\n\nConnecting to " . $ip . "\n\n"); - - my $inputlog = FileHandle->new; - $inputlog->open(">>/tmp/inputlog-queue") or die "/tmp/inputlog-queue: $!"; - $inputlog->print("\n\nConnecting to " . $ip . "\n\n"); - - my $conn = new Net::Telnet( Timeout => $nms::config::telnet_timeout, - Dump_Log => $dumplog, - Input_Log => $inputlog, - Errmode => 'return', - Prompt => '/[\S\-\_]+[#>]/'); - my $ret = $conn->open( Host => $ip); - if (!$ret || $ret != 1) { - return (undef); - } - # Handle login with and without password - print "Logging in without password\n"; - $conn->waitfor('/User ?Name:/'); - $conn->print('admin'); - my (undef, $match) = $conn->waitfor('/DGS-3100#|Password:/'); - die 'Unexpected prompt after login attempt' if (not defined $match); - if ($match eq 'Password:') { - $conn->print('gurbagurba'); # Dette passordet skal feile - $conn->waitfor('/User ?Name:/'); - $conn->print($nms::config::tacacs_user); - my (undef, $match) = $conn->waitfor('/DGS-3100#|Password:/'); - if ($match eq 'Password:') { - $conn->cmd($nms::config::tacacs_pass); - } - } - return { telnet => $conn }; -} - -# Send a command to switch and return the data recvied from the switch -sub switch_exec { - my ($cmd, $conn, $print) = @_; - - sleep 1; # don't overload the D-Link - - # Send the command and get data from switch - my @data; - if (defined($print)) { - $conn->print($cmd); - return; - } else { - @data = $conn->cmd($cmd); - print "ERROR: " . $conn->errmsg . "\n" if $conn->errmsg; - } - return @data; -} - -sub switch_exec_json($$) { - my ($cmd, $conn) = @_; - my @json = switch_exec("$cmd | display json", $conn); - pop @json; # Remove the banner at the end of the output - return ::decode_json(join("", @json)); -} - -sub switch_timeout { - my ($timeout, $conn) = @_; - - $conn->timeout($timeout); - return ('Set timeout to ' . $timeout); -} - -sub switch_disconnect($) { - my ($struct) = @_; - my $conn = $struct->{telnet}; - $conn->close(); - if ($struct->{pid}) { - waitpid($struct->{pid}, 0); - } -} -# A few utilities to convert from SNMP binary address format to human-readable. - -sub convert_mac { - return join(':', map { sprintf "%02x", $_ } unpack('C*', shift)); -} - -sub convert_ipv4 { - return join('.', map { sprintf "%d", $_ } unpack('C*', shift)); -} - -sub convert_ipv6 { - return join(':', map { sprintf "%x", $_ } unpack('n*', shift)); -} - -sub convert_addr { - my ($data, $type) = @_; - if ($type == 1) { - return convert_ipv4($data); - } elsif ($type == 2) { - return convert_ipv6($data); - } else { - die "Unknown address type $type"; - } -} - -# Convert raw binary SNMP data to list of bits. -sub convert_bytelist { - return split //, unpack("B*", shift); -} - -sub convert_lldp_caps { - my ($caps_data, $data) = @_; - - my @caps = convert_bytelist($caps_data); - my @caps_names = qw(other repeater bridge ap router telephone docsis stationonly); - for (my $i = 0; $i < scalar @caps && $i < scalar @caps_names; ++$i) { - $data->{'cap_enabled_' . $caps_names[$i]} = $caps[$i]; - } -} - -1; diff --git a/include/nms/snmp.pm b/include/nms/snmp.pm deleted file mode 100644 index 26ada44..0000000 --- a/include/nms/snmp.pm +++ /dev/null @@ -1,91 +0,0 @@ -#! /usr/bin/perl -use strict; -use warnings; -use SNMP; -use nms; -package nms::snmp; - -use base 'Exporter'; -our @EXPORT = qw(); - -BEGIN { - # $SNMP::debugging = 1; - - # sudo mkdir /usr/share/mibs/site - # cd /usr/share/mibs/site - # wget -O- ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz | sudo tar --strip-components=3 -zxvvf - - SNMP::initMib(); - SNMP::addMibDirs("/srv/tgmanage/mibs/StandardMibs"); - SNMP::addMibDirs("/srv/tgmanage/mibs/JuniperMibs"); - - SNMP::loadModules('SNMPv2-MIB'); - SNMP::loadModules('ENTITY-MIB'); - SNMP::loadModules('IF-MIB'); - SNMP::loadModules('LLDP-MIB'); - SNMP::loadModules('IP-MIB'); - SNMP::loadModules('IP-FORWARD-MIB'); -} - -sub snmp_open_session { - my ($ip, $community, $async) = @_; - - $async //= 0; - - my %options = (UseEnums => 1); - if ($ip =~ /:/) { - $options{'DestHost'} = "udp6:$ip"; - } else { - $options{'DestHost'} = "udp:$ip"; - } - - if ($community =~ /^snmpv3:(.*)$/) { - my ($username, $authprotocol, $authpassword, $privprotocol, $privpassword) = split /\//, $1; - - $options{'SecName'} = $username; - $options{'SecLevel'} = 'authNoPriv'; - $options{'AuthProto'} = $authprotocol; - $options{'AuthPass'} = $authpassword; - - if (defined($privprotocol) && defined($privpassword)) { - $options{'SecLevel'} = 'authPriv'; - $options{'PrivProto'} = $privprotocol; - $options{'PrivPass'} = $privpassword; - } - - $options{'Version'} = 3; - } else { - $options{'Community'} = $community; - $options{'Version'} = 2; - } - - my $session = SNMP::Session->new(%options); - if (defined($session) && ($async || defined($session->getnext('sysDescr')))) { - return $session; - } else { - die 'Could not open SNMP session to ' . $ip; - } -} - -# Not currently in use; kept around for reference. -sub fetch_multi_snmp { - my ($session, @oids) = @_; - - my %results = (); - - # Do bulk reads of 40 and 40; seems to be about the right size for 1500-byte packets. - for (my $i = 0; $i < scalar @oids; $i += 40) { - my $end = $i + 39; - $end = $#oids if ($end > $#oids); - my @oid_slice = @oids[$i..$end]; - - my $localresults = $session->get_request(-varbindlist => \@oid_slice); - return undef if (!defined($localresults)); - - while (my ($key, $value) = each %$localresults) { - $results{$key} = $value; - } - } - - return \%results; -} - diff --git a/include/nms/util.pm b/include/nms/util.pm deleted file mode 100644 index 64637b8..0000000 --- a/include/nms/util.pm +++ /dev/null @@ -1,141 +0,0 @@ -#! /usr/bin/perl -use strict; -use warnings; -package nms::util; -use Data::Dumper; - -use base 'Exporter'; -our @EXPORT = qw(guess_placement parse_switches_txt parse_switches parse_switch); - -# Parse a single switches.txt-formatted switch -sub parse_switch { - my ($switch, $subnet4, $subnet6, $mgtmt4, $mgtmt6, $lolid, $distro) = split(/ /); - my %foo = guess_placement($switch); - my %ret = ( - 'sysname' => "$switch", - 'subnet4' => "$subnet4", - 'subnet6' => "$subnet6", - 'mgmt_v4_addr' => "$mgtmt4", - 'mgmt_v6_addr' => "$mgtmt6", - 'traffic_vlan' => "$lolid", - 'distro' => "$distro" - ); - %{$ret{'placement'}} = guess_placement($switch); - return %ret; -} - -# Parses a switches_txt given as a filehandle on $_[0] -# (e.g.: parse_switches_txt(*STDIN) or parse_switches_txt(whatever). -sub parse_switches_txt { - my $fh = $_[0]; - my @switches; - while(<$fh>) { - chomp; - my %switch = parse_switch($_); - push @switches, {%switch}; - } - return @switches; -} - -# Parses switches in switches.txt format given as $_[0]. -# E.g: parse_switches("e1-3 88.92.0.0/26 2a06:5840:0a::/64 88.92.54.2/26 2a06:5840:54a::2/64 1013 distro0") -sub parse_switches { - my @switches; - my $txt = $_[0]; - foreach (split("\n",$txt)) { - chomp; - my %switch = parse_switch($_); - push @switches, {%switch}; - } - return @switches; -} - -# Guesses placement from name to get a starting point -# Largely courtesy of Knuta -sub guess_placement { - my ($x, $y, $xx, $yy); - - my $name = $_[0]; - my $src = "unknown"; - if ($name =~ /^e\d+-\d+$/) { - $name =~ /e(\d+)-(\d+)/; - my ($e, $s) = ($1, $2); - $src = "main"; - - $x = int(292 + (($e-1)/2) * 31.1); - $y = undef; - - $x += 14 if ($e >= 13); - $x += 14 if ($e >= 25); - $x += 14 if ($e >= 41); - $x += 14 if ($e >= 59); - - if ($s > 2) { - $y = 405 - 120 * ($s-2); - } else { - $y = 689 - 120 * ($s); - } - - $xx = $x + 16; - $yy = $y + 120; - - # Justeringer - $y += 45 if $name eq "e1-4"; - $y += 20 if $name eq "e3-4"; - $y += 15 if $name eq "e5-4"; - $yy -= 25 if $name eq "e7-1"; - $y += 10 if $name eq "e5-2"; - $yy -= 25 if $name eq "e5-2"; - $y += 20 if ($e >= 81 and $s == 2); - $yy -= 20 if ($e >= 79 and $s == 1); - $yy -= 30 if ($e >= 81 and $s == 1); - - } elsif ($name =~ /^creativia(\d+)$/) { - my ($s) = ($1); - $src = "creativia"; - $x = 1535; - $y = int(160 + 32.2 * $s); - $yy = $y + 20; - if ($s == 1) { - $xx = $x + 70; - } elsif ($s == 2) { - $xx = $x + 90; - } elsif ($s == 3) { - $xx = $x + 102; - } else { - $xx = $x + 142; - } - - } elsif ($name =~ /^crew(\d+)-(\d+)$/) { - my ($s, $n) = ($1, $2); - $src = "crew"; - $x = 550 + 65 * $n; - $y = int(759 + 20.5 * $s); - $xx = $x + 65; - $yy = $y + 14; - } elsif ($name =~ /^distro(\d)/) { - my $d = ($1); - $src = "distro"; - $x = 292 + $d * 165; - $y = 415; - $xx = $x + 130; - $yy = $y + 20; - } else { - # Fallback to have _some_ position - $src = "random"; - $x = int(rand(500)); - $y = int(rand(500)); - $xx = $x + 20; - $yy = $y + 130; - }; - - - my %box = ( - 'src' => "$src", - 'x1' => $x, - 'y1' => $y, - 'xx' => $xx, - 'yy' => $yy - ); - return %box; -} diff --git a/include/nms/web.pm b/include/nms/web.pm deleted file mode 100755 index 7c9339e..0000000 --- a/include/nms/web.pm +++ /dev/null @@ -1,112 +0,0 @@ -#! /usr/bin/perl -# vim:ts=8:sw=8 -use strict; -use warnings; -use utf8; -use DBI; -use Data::Dumper; -use JSON; -use nms; -use Digest::SHA; -use FreezeThaw; -use URI::Escape; -package nms::web; - -use base 'Exporter'; -our %get_params; -our %json; -our @EXPORT = qw(finalize_output now json $dbh db_safe_quote %get_params get_input %json); -our $dbh; -our $now; -our $when; -our %cc; - -sub get_input { - my $in = ""; - while(<STDIN>) { $in .= $_; } - return $in; -} -# Print cache-control from %cc -sub printcc { - my $line = ""; - my $first = ""; - foreach my $tmp (keys(%cc)) { - $line .= $first . $tmp . "=" . $cc{$tmp}; - $first = ", "; - } - print 'Cache-Control: ' . $line . "\n"; -} - -sub db_safe_quote { - my $word = $_[0]; - my $term = $get_params{$word}; - if (!defined($term)) { - if(defined($_[1])) { - $term = $_[1]; - } else { - die "Missing CGI param $word"; - } - } - return $dbh->quote($term) || die; -} - -# returns a valid $when statement -# Also sets cache-control headers if time is overridden -# This can be called explicitly to override the window of time we evaluate. -# Normally up to 15 minutes old data will be returned, but for some API -# endpoints it is better to return no data than old data (e.g.: ping). -sub setwhen { - $now = "now()"; - my $window = '8m'; - my $offset = '0s'; - if (@_ > 0) { - $window = $_[0]; - } - if (@_ > 1) { - $offset = $_[1]; - } - if (defined($get_params{'now'})) { - $now = db_safe_quote('now') . "::timestamp with time zone "; - $cc{'max-age'} = "3600"; - } - $now = "(" . $now . " - '" . $offset . "'::interval)"; - $when = " time > " . $now . " - '".$window."'::interval and time < " . $now . " "; -} - -sub finalize_output { - my $query; - my $hash = Digest::SHA::sha512_base64(FreezeThaw::freeze(%json)); - $dbh->commit; - $query = $dbh->prepare('select extract(epoch from date_trunc(\'seconds\', ' . $now . ')) as time;'); - $query->execute(); - - $json{'time'} = int($query->fetchrow_hashref()->{'time'}); - $json{'hash'} = $hash; - - printcc; - - print "Etag: $hash\n"; - print "Access-Control-Allow-Origin: *\n"; - print "Access-Control-Allow-Methods: HEAD, GET\n"; - print "Content-Type: text/json; charset=utf-8\n\n"; - print JSON::XS::encode_json(\%json); - print "\n"; -} - -sub populate_params { - my $querystring = $ENV{'QUERY_STRING'} || ""; - foreach my $hdr (split("&",$querystring)) { - my ($key, $value) = split("=",$hdr,"2"); - $get_params{$key} = URI::Escape::uri_unescape($value); - } -} - -BEGIN { - $cc{'stale-while-revalidate'} = "3600"; - $cc{'max-age'} = "20"; - - $dbh = nms::db_connect(); - populate_params(); - setwhen(); -} -1; |