File: 1.00.0a/server/bin/tester.php (View as Code)

1: 2: /* ------------------------------------------------------------- 3: This file is part of FreeNATS 4: 5: FreeNATS is (C) Copyright 2008 PurplePixie Systems 6: 7: FreeNATS is free software: you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation, either version 3 of the License, or 10: (at your option) any later version. 11: 12: FreeNATS is distributed in the hope that it will be useful, 13: but WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: GNU General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with FreeNATS. If not, see www.gnu.org/licenses 19: 20: For more information see www.purplepixie.org/freenats 21: -------------------------------------------------------------- */ 22: 23: if ((isset($argc))&&(isset($argv))) 24: { 25: if ($argc>1) 26: { 27: $nfilter=$argv[1]; 28: } 29: else $nfilter=""; 30: } 31: 32: require("include.php"); 33: 34: $dbt=""; 35: 36: function db($txt,$nl=true) 37: { 38: global $dbt; 39: echo $txt; 40: $dbt.=$txt; 41: if ($nl) 42: { 43: echo "\n"; 44: $dbt.="
\n";
45: } 46: } 47: 48: $NATS->Start(); 49: if ($nfilter!="") $st=": Node ".$nfilter; 50: else $st=""; 51: db("NATS Tester Script Starting".$st); 52: 53: $highalertlevel=-1; 54: $talertc=0; 55: 56: // check if already running 57: $cq="SELECT startx FROM fntestrun WHERE fnode=\"".ss($nfilter)."\" AND finishx=0 LIMIT 0,1"; 58: $cr=$NATS->DB->Query($cq); 59: if ($NATS->DB->Num_Rows($cr)>0) 60: { 61: $NATS->Event("Tester Already Running: Aborted",1,"Tester","Error"); 62: db("Tester Already Running: Aborted"); 63: $NATS->Stop(); 64: exit(); 65: } 66: $NATS->DB->Free($cr); 67: 68: $gq="INSERT INTO fntestrun(startx,fnode) VALUES(".time().",\"".ss($nfilter)."\")"; 69: $NATS->DB->Query($gq); 70: $trid=$NATS->DB->Insert_Id(); 71: db("Test ID: ".$trid." (Started at ".nicedt(time()).")"); 72: $NATS->Event("Tester ".$trid." Started",5,"Tester","Start"); 73: 74: db(" "); 75: 76: // Find node to test - must be enabled, have id if set, and be due to be tested (nextrunx) 77: 78: $q="SELECT * FROM fnnode WHERE nodeenabled=1"; 79: if ($nfilter!="") $q.=" AND nodeid=\"".ss($nfilter)."\""; 80: $q.=" AND nextrunx<=".time(); 81: 82: $r=$NATS->DB->Query($q); 83: 84: 85: while ($row=$NATS->DB->Fetch_Array($r)) 86: { 87: $dotests=true; 88: $alertlevel=0; 89: $alerts=array(); 90: $alertc=0; 91: db("NodeID: ".$row['nodeid']); 92: $NATS->Event("Tester ".$trid." Node ".$row['nodeid'],10,"Tester","Node"); 93: 94: // Scheduling Test In Here - sets dotests to false and alertlevel to -1 untested 95: if ($row['scheduleid']!=0) // has a schedule 96: { 97: db(" Has Schedule: Yes - Checking"); 98: $run=run_x_in_schedule(time(),$row['scheduleid']); 99: if (!$run) 100: { 101: db(" In Schedule: No - Skipping Tests"); 102: $NATS->Event("Tester ".$trid." Skipped by Schedule",5,"Tester","Node"); 103: $dotests=false; 104: $alertlevel=-1; 105: } 106: else db(" In Schedule: Yes"); 107: } 108: 109: 110: $ptr=0; 111: $pal=0; 112: 113: 114: // Update lastrun and nextrun regardless of dotests 115: $q="UPDATE fnnode SET lastrunx=".time().",nextrunx=".next_run_x($row['testinterval'])." WHERE nodeid=\"".ss($row['nodeid'])."\""; 116: $NATS->DB->Query($q); 117: 118: 119: if ($row['pingtest']&&$dotests) 120: { 121: db(" Ping Test: Yes"); 122: $NATS->Event("Tester ".$trid." Pinging Node ".$row['nodeid'],10,"Tester","Ping"); 123: $ptr=PingTest($row['hostname']); 124: $NATS->Event("Tester ".$trid." Ping Node ".$row['nodeid']." Returned ".$ptr,10,"Tester","Ping"); 125: db(" Ping Returned: ".$ptr); 126: if ( ($ptr<=0) && ($NATS->Cfg->Get("test.icmp.attempts","2")>1) ) 127: { 128: $att=$NATS->Cfg->Get("test.icmp.attempts","2"); 129: for ($a=2; $a<=$att; $a++) // starting on second attempt 130: { 131: // try again... 132: test_sleep(); 133: db(" Trying Ping Again - X".$a); 134: $NATS->Event("Tester ".$trid." Ping X".$a." Node ".$row['nodeid'],10,"Tester","Ping"); 135: $ptr=PingTest($row['hostname']); 136: $NATS->Event("Tester ".$trid." Ping Node ".$row['nodeid']." Returned ".$ptr,10,"Tester","Ping"); 137: db(" Ping Returned: ".$ptr); 138: if ($ptr>0) $a=$att+1; // break out of the loop 139: } 140: } 141: 142: if ($ptr<=0) 143: { 144: $alertlevel=2; 145: db(" Ping Test: Failed"); 146: $alerts[$alertc++]="ping failed"; 147: $pal=2; 148: } 149: else db(" Ping Test: Passed"); 150: 151: // pingtest output bodge 152: // is there a test entry for ICMP 153: $fq="SELECT localtestid FROM fnlocaltest WHERE nodeid=\"".$row['nodeid']."\" AND testtype=\"ICMP\""; 154: $fr=$NATS->DB->Query($fq); 155: $ltid_icmp=""; 156: if ($irow=$NATS->DB->Fetch_Array($fr)) 157: { // exists 158: $uq="UPDATE fnlocaltest SET alertlevel=".$pal.",lastrunx=".time().",lastvalue=".$ptr.",testrecord=1,testinterval=0 WHERE localtestid=".$irow['localtestid']; 159: $ltid_icmp=$irow['localtestid']; 160: //echo $uq; 161: $NATS->DB->Query($uq); 162: } 163: else 164: { // doesn't exist 165: $uq="INSERT INTO fnlocaltest(nodeid,testrecord,testinterval,testtype,alertlevel,lastrunx,lastvalue) VALUES(\"".$row['nodeid']."\",1,0,\"ICMP\",".$pal.",".time().",".$ptr.")"; 166: //echo $uq; 167: $NATS->DB->Query($uq); 168: $ltid_icmp=$NATS->DB->Insert_Id(); 169: } 170: $NATS->DB->Free($fr); 171: 172: // record the ICMP bodge-test here 173: $rq="INSERT INTO fnrecord(testid,recordx,testvalue,alertlevel,nodeid) VALUES(\"L".$ltid_icmp."\",".time().",".$ptr.",".$pal.",\"".$row['nodeid']."\")"; 174: $NATS->DB->Query($rq); 175: //echo $rq." ".$NATS->DB->Affected_Rows()."\n"; 176: 177: } 178: else 179: { // further ICMP bodge - update to -1 or do nothing if the test doesn't exist 180: $uq="UPDATE fnlocaltest SET alertlevel=-1,lastrunx=".time()." WHERE nodeid=\"".$row['nodeid']."\" AND testtype=\"ICMP\""; 181: $NATS->DB->Query($uq); 182: } 183: 184: if ($dotests&&($row['pingfatal'])&&($ptr<=0)) 185: { 186: db(" Ping Fatal: Yes - Not Continuing"); 187: $NATS->Event("Tester ".$trid." Ping Fatal for Node ".$row['nodeid'],10,"Tester","Ping"); 188: $dotests=false; 189: } 190: 191: // do the tests - only actually exec if dotests true 192: 193: $first_test=true; 194: 195: db("Doing Local Tests"); 196: $NATS->Event("Tester ".$trid." Testing Node ".$row['nodeid'],10,"Tester","Test"); 197: $q="SELECT * FROM fnlocaltest WHERE nodeid=\"".$row['nodeid']."\" AND testtype!=\"ICMP\" AND testenabled=1 ORDER BY localtestid ASC"; 198: $res=$NATS->DB->Query($q); 199: while ($lrow=$NATS->DB->Fetch_Array($res)) 200: { 201: if ($lrow['nextrunx']<=time()) $testdue=true; 202: else $testdue=false; 203: 204: if ($first_test) 205: { 206: $first_test=false; 207: if ($row['pingtest']==1) test_sleep(); // sleep if has done a ping 208: } 209: else test_sleep(); 210: 211: if ($testdue) 212: { 213: 214: db(" Test: ".$lrow['testtype']." (".$lrow['testparam'].")"); 215: 216: // Build parameter array 217: $params=array(); 218: $params[0]=$lrow['testparam']; // pass standard param in as 0 219: for ($a=1; $a<10; $a++) 220: { 221: $parstr="testparam".$a; 222: $params[$a]=$lrow[$parstr]; 223: } 224: 225: $NATS->Event("Tester ".$trid." Node ".$row['nodeid']." Doing ".$lrow['testtype']."(".$lrow['testparam'].")",10,"Tester","Test"); 226: if ($testdue) $result=DoTest($lrow['testtype'],$lrow['testparam'],$row['hostname'],$lrow['timeout'],$params,$row['nodeid']); 227: else $result=0; 228: $NATS->Event("Tester ".$trid." Node ".$row['nodeid']." Result ".$result." from ".$lrow['testtype']."(".$lrow['testparam'].")",10,"Tester","Test"); 229: db(" Result: ".$result); 230: 231: if ($dotests) 232: { 233: // evaluation 234: if ($lrow['simpleeval']==1) $lvl=SimpleEval($lrow['testtype'],$result); 235: else $lvl=nats_eval("L".$lrow['localtestid'],$result); 236: db(" Eval: ".$lvl); 237: 238: // put in the custom retries based on attempts here - we KNOW dotests is on so don't need to worry about untested status 239: $att=$lrow['attempts']; 240: if ( ($lvl!=0) && (is_numeric($att)) && ($att>1) ) 241: { 242: for ($a=2; $a<=$att; $a++) 243: { 244: test_sleep(); 245: db(" Test: ".$lrow['testtype']." (".$lrow['testparam'].") X".$a); 246: $NATS->Event("Tester ".$trid." Node ".$row['nodeid']." X".$a." Doing ".$lrow['testtype']."(".$lrow['testparam'].")",10,"Tester","Test"); 247: $result=DoTest($lrow['testtype'],$lrow['testparam'],$row['hostname'],$lrow['timeout'],$params,$row['nodeid']); 248: db(" Result: ".$result); 249: if ($lrow['simpleeval']==1) $lvl=SimpleEval($lrow['testtype'],$result); 250: else $lvl=nats_eval("L".$lrow['localtestid'],$result); 251: db(" Eval: ".$lvl); 252: if ($lvl==0) $a=$att+1; // test passed 253: } 254: } 255: 256: // $lvl is now the last lvl regardless of where it came from 257: 258: if ($lvl>$alertlevel) $alertlevel=$lvl; 259: if ($lvl>0) 260: { 261: if ($lrow['testname']=="") $s=$lrow['testtype']."/".substr($lrow['testparam'],0,5)." "; 262: else $s=$lrow['testname']." "; 263: if ($lvl>1) $s.="failed"; 264: else $s.="warning"; 265: $alerts[$alertc++]=$s; 266: } 267: } else $lvl=-1; 268: 269: // record it 270: if ($lrow['testrecord']==1) 271: { 272: $tid="L".$lrow['localtestid']; 273: $iq="INSERT INTO fnrecord(testid,nodeid,alertlevel,testvalue,recordx) VALUES("; 274: $iq.="\"".$tid."\",\"".$row['nodeid']."\",".$lvl.",".$result.",".time().")"; 275: $NATS->DB->Query($iq); 276: db(" Recording Test"); 277: } 278: if ((!isset($result))||(!is_numeric($result))) $result=0; // safety net 279: 280: // update localtest record 281: $uq="UPDATE fnlocaltest SET lastrunx=".time().",nextrunx=".next_run_x($lrow['testinterval']).",alertlevel=".$lvl.",lastvalue=".$result." WHERE localtestid=".$lrow['localtestid']; 282: $NATS->DB->Query($uq); 283: } 284: 285: else // test not due so take pre-existing level for it 286: { 287: $lvl=$lrow['alertlevel']; 288: if (($lvl>0)&&($lvl>$alertlevel)) $alertlevel=$lvl; 289: } 290: 291: 292: } 293: 294: // Node-side testy magic 295: db("Nodeside Testing"); 296: $freshdata=false; 297: if ( $dotests && ($row['nsenabled']==1) && ($row['nspullenabled']==1) ) // should be doing a pull 298: { 299: $pullalert=$row['nspullalert']; // what happened the last time we tried 300: 301: if ($row['nsnextx']<=time()) // the time is right 302: { 303: db(" Pulling Data"); 304: $pull_result=$NATS->Nodeside_Pull($row['nodeid']); 305: 306: if ($pull_result===false) // Pull Failed 307: { 308: db(" Pull Failed"); 309: $pullalert=1; // alert 310: $alerts[$alertc++]="pull failed"; 311: $alertlevel=2; 312: } 313: else // Pull Worked 314: { 315: $freshdata=true; 316: $pullalert=0; // ok 317: db(" Pull Succeeded"); 318: } 319: 320: 321: db(" Updating Pull nslast/nextx and nspullalert"); 322: $uq="UPDATE fnnode SET nsnextx=".next_run_x($row['nsinterval']).",nspullalert=".$pullalert.",nslastx=".time()." WHERE nodeid=\"".$row['nodeid']."\""; 323: $NATS->DB->Query($uq); 324: if ($NATS->DB->Affected_Rows()<=0) db(" - Failed"); 325: } 326: /* 327: // Process for alerts in here - whether pulled or not! 328: $tq="SELECT testtype,testname,alertlevel FROM fnnstest WHERE nodeid=\"".$row['nodeid']."\" AND testenabled=1 AND testalerts=1 AND alertlevel>0"; 329: $tr=$NATS->DB->Query($tq); 330: while ($trow=$NATS->DB->Fetch_Array($tr)) 331: { 332: if ($trow['testname']=="") $tname=$trow['testtype']; 333: else $tname=$trow['testname']; 334: if ($freshdata) $alerts[$alertc++]=$tname." ".oText($trow['alertlevel']); // only record text to log if fresh 335: if ($trow['alertlevel']>$alertlevel) $alertlevel=$trow['alertlevel']; 336: } 337: */ 338: 339: // and finally again use pullalert - this is either the new value if a pull was attempted or just remains the same as the old one 340: // if pull not scheduled yet 341: if ($pullalert>0) $alertlevel=2; // so mark a failure 342: 343: } 344: 345: if ( ($dotests && ($row['nsenabled']==1) && ($row['nspullenabled']==1)) || // pull and tests are on 346: (($row['nsenabled']==1)&&($row['nspushenabled']==1)) ) // or pushed 347: { 348: if ($row['nsfreshpush']==1) 349: { 350: $freshdata=true; 351: $uq="UPDATE fnnode SET nsfreshpush=0 WHERE nodeid=\"".$row['nodeid']."\""; 352: $NATS->DB->Query($uq); 353: } 354: // Process for alerts in here - whether pulled or not! 355: $tq="SELECT testtype,testname,alertlevel FROM fnnstest WHERE nodeid=\"".$row['nodeid']."\" AND testenabled=1 AND testalerts=1 AND alertlevel>0"; 356: $tr=$NATS->DB->Query($tq); 357: while ($trow=$NATS->DB->Fetch_Array($tr)) 358: { 359: if ($trow['testname']=="") $tname=$trow['testtype']; 360: else $tname=$trow['testname']; 361: if ($freshdata) $alerts[$alertc++]=$tname." ".oText($trow['alertlevel']); // only record text to log if fresh 362: if ($trow['alertlevel']>$alertlevel) $alertlevel=$trow['alertlevel']; 363: } 364: } 365: 366: $NATS->Event("Tester ".$trid." Finished Node ".$row['nodeid'],10,"Tester","Node"); 367: 368: 369: db("Highest Alert Level: ".$alertlevel); 370: db("Alert Count : ".$alertc); 371: $als=""; 372: foreach($alerts as $al) $als.=$al.", "; 373: db("Alerts: ".$als); 374: 375: $NATS->SetAlerts($row['nodeid'],$alertlevel,$alerts); 376: 377: db(" "); 378: 379: if ($alertlevel>$highalertlevel) $highalertlevel=$alertlevel; 380: $talertc+=$alertc; 381: 382: } 383: 384: 385: 386: db("Finished Tests... Finishing Off"); 387: db("Summary: Tester ".$trid." Highest Level ".$highalertlevel.", Alerts ".$talertc); 388: $uq="UPDATE fntestrun SET finishx=".time().",routput=\"".ss($dbt)."\" WHERE trid=".$trid; 389: $NATS->DB->Query($uq); 390: 391: 392: $NATS->Event("Tester ".$trid." Highest Level ".$highalertlevel.", Alerts ".$talertc,7,"Tester","Stat"); 393: $NATS->Event("Tester ".$trid." Finished",5,"Tester","Stop"); 394: 395: // in here for now... 396: $NATS->ActionFlush(); 397: 398: $NATS->Stop(); 399: db("NATS Stopped... Finished"); 400: ?> 401: 402: