source: trunk/cgi-bin/consistency-check.pl@ 901

Last change on this file since 901 was 901, checked in by Kris Deugau, 7 years ago

/trunk

Major update to consistency-check.pl due to ongoing changes in back end

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author
File size: 4.6 KB
RevLine 
[6]1#!/usr/bin/perl
[8]2# ipdb/cgi-bin/consistency-check.pl
[6]3# Does full check to see if the data in the db is consistent and complete.
[901]4# Note this can't account for slightly squirrelly or pretzelly legacy data;
5# that has to be hand-verified when this script chokes on it and spits up
6# errors.
[8]7###
8# SVN revision info
9# $Date: 2017-02-10 17:01:25 +0000 (Fri, 10 Feb 2017) $
10# SVN revision $Rev: 901 $
11# Last update by $Author: kdeugau $
12###
[901]13# Copyright (C) 2004-2010,2014,2017 - Kris Deugau
[6]14
[901]15use strict;
16use warnings;
17
[6]18use DBI;
19use NetAddr::IP;
[635]20use Data::Dumper;
[6]21
[417]22# don't remove! required for GNU/FHS-ish install from tarball
23##uselib##
24
25use MyIPDB;
26
[901]27# Convenience for calling from admin tools
[214]28print "Content-type: text/plain\n\n";
29
[901]30my ($dbh,$errstr) = connectDB_My;
[402]31die $errstr if !$dbh;
[167]32# May as well. We need a number of globals.
33initIPDBGlobals($dbh);
[6]34
[901]35my %idlist;
36my $sth = $dbh->prepare("SELECT id FROM allocations WHERE type='mm' ORDER BY cidr");
37$sth->execute;
38while (my ($mid) = $sth->fetchrow_array) {
39 checkcontainer($mid, \%idlist, 0);
[635]40}
41
[901]42print "\nChecking that all allocations are referenced:\n";
43$sth = $dbh->prepare("SELECT id FROM allocations");
[6]44$sth->execute;
[901]45my $i = 0;
46while (my ($id) = $sth->fetchrow_array) {
47 delete $idlist{$id};
48 $i++;
[6]49}
[901]50print " $i allocations confirmed referenced\n";
51$i = 0;
52$sth = $dbh->prepare("SELECT id FROM freeblocks");
[6]53$sth->execute;
[901]54while (my ($id) = $sth->fetchrow_array) {
55 delete $idlist{'fb'.$id};
56 $i++;
57}
58print " $i freeblocks confirmed referenced\n";
59foreach (keys %idlist) {
60 if (/^fb/) {
61 print " Unreferenced free block ID $_, $idlist{$_}\n";
62 } else {
63 print " Unreferenced block ID $_, $idlist{$_}\n";
[6]64 }
65}
66
[901]67print "\nChecking for correctness on 'defined' CustIDs:\n";
68$sth = $dbh->prepare("SELECT cidr,type,custid FROM allocations WHERE NOT (type='cn' OR type LIKE '_r') ORDER BY cidr");
[6]69$sth->execute;
[901]70while (my($cidr,$type,$custid) = $sth->fetchrow_array) {
71 print "$cidr ($disp_alloctypes{$type}) has incorrect CustID $custid\n"
72 if $custid ne $def_custids{$type};
[6]73}
[901]74print "Done predefined CustID correctness check.\n\n";
[6]75
[901]76print "Checking for customer blocks with 'bad' CustIDs:\n";
77# Make sure cn-type ("customer netblock") blocks have "real" CustIDs.
78$sth = $dbh->prepare("SELECT cidr,custid,description FROM allocations WHERE type='cn' AND (custid='$IPDB::defcustid' OR custid='STAFF') ORDER BY cidr");
[62]79$sth->execute;
[901]80while (my ($cidr,$custid,$desc) = $sth->fetchrow_array) {
81 print "cn block $cidr ($desc) has incorrect CustID $custid\n";
[62]82}
[901]83print "Done checking customer blocks\n";
[62]84
[901]85exit;
[62]86
[190]87
[901]88# All we need to check on is "do the allocations and free blocks within a container completely make up the container?"
89sub checkcontainer {
90 my $cid = shift;
91 my $idlist = shift;
92 my $depth = shift;
[6]93
[901]94 # snarf the container's CIDR
95 my $sth = $dbh->prepare("SELECT cidr,type FROM allocations WHERE id = ?");
96 $sth->execute($cid);
97 my ($ccidr,$ctype) = $sth->fetchrow_array();
98 # note that we've "seen" the ID/CIDR
99 $idlist->{$cid} = $ccidr;
100 $ccidr = NetAddr::IP->new($ccidr);
[6]101
[901]102 $depth++;
103 print "error: gone too deep ($depth). breaking off\n" if $depth > 6;
104 my $indent = ' ' x $depth;
105 print $indent."Checking $disp_alloctypes{$ctype} $ccidr ($cid)\n";
[11]106
[901]107 $sth = $dbh->prepare(qq(
108 SELECT id, cidr, type, network(cidr) AS net, broadcast(cidr) AS bcast FROM allocations WHERE parent_id = ?
109 UNION
110 SELECT id, cidr, 'f' AS type, network(cidr) AS net, broadcast(cidr) AS bcast FROM freeblocks WHERE parent_id = ?
111 ORDER BY cidr
112 ));
113 $sth->execute($cid, $cid) or die $dbh->errstr;
114 my $prev = $ccidr;
115 while (my ($childid, $childcidr, $childtype, $childnet, $childbcast) = $sth->fetchrow_array) {
116 # note that we've "seen" the ID/CIDR, flagging freeblocks
117 $idlist->{$childid} = $childcidr if $childtype ne 'f';
118 $idlist->{'fb'.$childid} = $childcidr if $childtype eq 'f';
119 checkcontainer($childid, $idlist, $depth) if $childtype =~ /.[cm]/;
[635]120 my $prevn = $prev->broadcast->numeric + 1;
[901]121 my $cur = new NetAddr::IP $childnet;
[635]122 if ($cur->numeric == $prevn) {
123 $prev = $cur;
124 next;
125 }
[901]126 if ($ccidr->numeric == $prev->numeric) {
[11]127 # check if cur starts with master
128 if ($cur->numeric > $prev->numeric) {
[901]129 print $indent." Gap from start of parent $ccidr to first block $cur\n";
[11]130 } elsif ($cur->numeric < $prev->numeric) {
[901]131 print $indent." BIG problem! Current block $cur begins before parent $ccidr!\n";
[11]132 }
[6]133 } else {
[11]134 if ($cur->numeric < ($prev->numeric + 1)) {
[901]135 print $indent." Block ".$prev->network." overlaps block $cur\n";
[11]136 } elsif ($cur->numeric > ($prev->numeric + 1)) {
[901]137 print $indent." Gap between end of block ".$prev->network." and block $cur\n";
[11]138 }
[6]139 }
[11]140
141 $prev = $cur;
142 $prev--;
[6]143 }
144}
Note: See TracBrowser for help on using the repository browser.