1<?php 2 3# This file is a part of RackTables, a datacenter and server room management 4# framework. See accompanying file "COPYING" for the full copyright and 5# licensing information. 6 7$vs_proto = array ( 8 'TCP' => 'TCP', 9 'UDP' => 'UDP', 10 'MARK' => 'MARK', 11); 12 13// ********************* Config-generating functions ********************* 14 15// you may override the class name to make using your own triplet class 16$triplet_class = 'SLBTriplet'; 17$parser_class = 'MacroParser'; 18 19class SLBTriplet 20{ 21 public $lb; 22 public $vs; 23 public $rs; 24 public $slb; 25 public $display_cells; 26 27 public function __construct ($lb_id, $vs_id, $rs_id, $db_row = NULL) 28 { 29 $this->lb = spotEntity ('object', $lb_id); 30 $this->vs = spotEntity ('ipv4vs', $vs_id); 31 $this->rs = spotEntity ('ipv4rspool', $rs_id); 32 $this->display_cells = array ('lb', 'vs', 'rs'); 33 if (isset ($db_row)) 34 $this->slb = $db_row; 35 else 36 { 37 $result = usePreparedSelectBlade 38 ( 39 "SELECT prio, vsconfig, rsconfig FROM IPv4LB WHERE object_id = ? AND vs_id = ? AND rspool_id = ?", 40 array ($lb_id, $vs_id, $rs_id) 41 ); 42 if ($row = $result->fetch (PDO::FETCH_ASSOC)) 43 $this->slb = $row; 44 else 45 throw new RackTablesError ("SLB triplet not found in the DB"); 46 } 47 } 48 49 static public function getTriplets ($cell) 50 { 51 if (isset ($cell['ip_bin']) && isset ($cell['vslist'])) 52 // cell is IPAddress 53 return self::getTripletsByIP ($cell['ip_bin']); 54 $ret = array(); 55 switch ($cell['realm']) 56 { 57 case 'object': 58 $db_field = 'object_id'; 59 $order_fields = 'vs_id'; 60 $display_cells = array('vs', 'rs'); 61 break; 62 case 'ipv4vs': 63 $db_field = 'vs_id'; 64 $order_fields = 'rspool_id'; 65 $display_cells = array('rs', 'lb'); 66 break; 67 case 'ipv4rspool': 68 $db_field = 'rspool_id'; 69 $order_fields = 'vs_id'; 70 $display_cells = array('vs', 'lb'); 71 break; 72 default: 73 throw new InvalidArgException ('realm', $cell['realm']); 74 } 75 $result = usePreparedSelectBlade 76 ( 77 'SELECT object_id, rspool_id, vs_id, prio, vsconfig, rsconfig FROM IPv4LB ' . 78 "WHERE `$db_field` = ? ORDER BY $order_fields", 79 array ($cell['id']) 80 ); 81 $rows = $result->fetchAll (PDO::FETCH_ASSOC); 82 unset ($result); 83 global $triplet_class; 84 foreach ($rows as $row) 85 { 86 $row['vsconfig'] = dos2unix ($row['vsconfig']); 87 $row['rsconfig'] = dos2unix ($row['rsconfig']); 88 $triplet = new $triplet_class ($row['object_id'], $row['vs_id'], $row['rspool_id'], $row); 89 $triplet->display_cells = $display_cells; 90 $ret[] = $triplet; 91 } 92 return $ret; 93 } 94 95 static public function getTripletsByIP ($ip_bin) 96 { 97 $ret = array(); 98 $result = usePreparedSelectBlade (" 99SELECT DISTINCT IPv4LB.object_id, IPv4LB.rspool_id, IPv4LB.vs_id, IPv4LB.prio, IPv4LB.vsconfig, IPv4LB.rsconfig 100FROM 101 IPv4LB INNER JOIN IPv4VS ON IPv4VS.id = IPv4LB.vs_id 102 LEFT JOIN IPv4RS USING (rspool_id) 103WHERE 104 rsip = ? OR vip = ? 105ORDER BY 106 vs_id 107 ", array ($ip_bin, $ip_bin) 108 ); 109 $rows = $result->fetchAll (PDO::FETCH_ASSOC); 110 unset ($result); 111 global $triplet_class; 112 foreach ($rows as $row) 113 { 114 $triplet = new $triplet_class ($row['object_id'], $row['vs_id'], $row['rspool_id'], $row); 115 $triplet->display_cells = array ('vs', 'lb', 'rs'); 116 $ret[] = $triplet; 117 } 118 return $ret; 119 } 120} 121 122function generateSLBConfig ($triplet_list) 123{ 124 $ret = ''; 125 126 global $parser_class; 127 $gl_parser = new $parser_class; 128 $defaults = getSLBDefaults (TRUE); 129 $gl_parser->addMacro ('GLOBAL_VS_CONF', dos2unix ($defaults['vsconfig'])); 130 $gl_parser->addMacro ('GLOBAL_RS_CONF', dos2unix ($defaults['rsconfig'])); 131 $gl_parser->addMacro ('RSPORT', '%VPORT%'); 132 $gl_parser->addMacro ('VS_PREPEND', 133"# LB (id == %LB_ID%): %LB_NAME% 134# VS (id == %VS_ID%): %VS_NAME% 135# RS (id == %RSP_ID%): %RSP_NAME%"); 136 137 // group triplets by object_id, vs_id 138 $grouped = array(); 139 foreach ($triplet_list as $triplet) 140 $grouped[$triplet->lb['id']][$triplet->vs['id']][] = $triplet; 141 142 foreach ($grouped as $object_id => $subarr) 143 { 144 $lb = array_first (array_first ($subarr))->lb; 145 $lb_parser = clone $gl_parser; 146 $lb_parser->addMacro ('LB_ID', $lb['id']); 147 $lb_parser->addMacro ('LB_NAME', $lb['name']); 148 foreach ($subarr as $vs_id => $triplets) 149 { 150 $vs = array_first ($triplets)->vs; 151 $vs_parser = clone $lb_parser; 152 $vs_parser->addMacro ('VS_ID', $vs['id']); 153 $vs_parser->addMacro ('VS_NAME', $vs['name']); 154 $vs_parser->addMacro ('VIP', $vs['vip']); 155 $vs_parser->addMacro ('VPORT', $vs['vport']); 156 $vs_parser->addMacro ('IP_VER', (strlen ($vs['vip_bin']) == 16) ? 6 : 4); 157 if ($vs['proto'] == 'MARK') 158 { 159 $vs_parser->addMacro ('PROTO', 'TCP'); 160 $mark = implode ('', unpack ('N', substr ($vs['vip_bin'], 0, 4))); 161 $vs_parser->addMacro ('MARK', $mark); 162 $vs_parser->addMacro ('VS_HEADER', "fwmark $mark"); 163 } 164 else 165 { 166 $vs_parser->addMacro ('VS_HEADER', $vs['vip'] . ' ' . $vs['vport']); 167 $vs_parser->addMacro ('PROTO', $vs['proto']); 168 } 169 $vs_parser->addMacro ('VS_RS_CONF', dos2unix ($vs['rsconfig'])); 170 171 $vip_bin = ip_checkparse ($vs_parser->expandMacro ('VIP')); 172 if ($vip_bin === FALSE) 173 $family_length = 4; 174 else 175 $family_length = strlen ($vip_bin); 176 177 foreach ($triplets as $triplet) 178 { 179 $rsp = $triplet->rs; 180 $rs_parser = clone $vs_parser; 181 $rs_parser->addMacro ('RSP_ID', $rsp['id']); 182 $rs_parser->addMacro ('RSP_NAME', $rsp['name']); 183 $rs_parser->addMacro ('RSP_VS_CONF', dos2unix ($rsp['vsconfig'])); 184 $rs_parser->addMacro ('RSP_RS_CONF', dos2unix ($rsp['rsconfig'])); 185 $rs_parser->addMacro ('VS_VS_CONF', dos2unix ($vs['vsconfig'])); // VS-driven vsconfig has higher priority than RSP-driven 186 187 $rs_parser->addMacro ('PRIO', $triplet->slb['prio']); 188 $rs_parser->addMacro ('SLB_VS_CONF', dos2unix ($triplet->slb['vsconfig'])); 189 $rs_parser->addMacro ('SLB_RS_CONF', dos2unix ($triplet->slb['rsconfig'])); 190 191 $ret .= $rs_parser->expand (" 192%VS_PREPEND% 193virtual_server %VS_HEADER% { 194 protocol %PROTO% 195 %GLOBAL_VS_CONF% 196 %RSP_VS_CONF% 197 %VS_VS_CONF% 198 %SLB_VS_CONF% 199"); 200 201 foreach ($rs_parser->getRSList() as $rs_row) 202 { 203 if ($rs_row['inservice'] != 'yes') 204 continue; 205 $parser = clone $rs_parser; 206 $parser->addMacro ('RS_HEADER', ($parser->expandMacro ('PROTO') == 'MARK' ? '%RSIP%' : '%RSIP% %RSPORT%')); 207 $parser->addMacro ('RSIP', $rs_row['rsip']); 208 if (isset ($rs_row['rsport'])) 209 $parser->addMacro ('RSPORT', $rs_row['rsport']); 210 $parser->addMacro ('RS_COMMENT', $rs_row['comment']); 211 $parser->addMacro ('RS_RS_CONF', dos2unix ($rs_row['rsconfig'])); 212 213 // do not add v6 reals into v4 service and vice versa 214 $rsip_bin = ip_checkparse ($parser->expandMacro ('RSIP')); 215 if ($rsip_bin !== FALSE && strlen ($rsip_bin) == $family_length) 216 foreach (explode (',', $parser->expandMacro ('RSPORT')) as $rsp_token) 217 { 218 $port_range = explode ('-', $rsp_token); 219 if (count ($port_range) < 1) 220 throw new InvalidArgException ('RSPORT', $rsp_token, "invalid RS port range"); 221 if (count ($port_range) < 2) 222 $port_range[] = $port_range[0]; 223 if ($port_range[0] > $port_range[1]) 224 throw new InvalidArgException ('RSPORT', $rsp_token, "invalid RS port range"); 225 226 for ($rsport = $port_range[0]; $rsport <= $port_range[1]; $rsport++) 227 { 228 $r_parser = clone $parser; 229 $r_parser->addMacro ('RSPORT', $rsport); 230 $ret .= $r_parser->expand (" 231 %RS_PREPEND% 232 real_server %RS_HEADER% { 233 %GLOBAL_RS_CONF% 234 %VS_RS_CONF% 235 %RSP_RS_CONF% 236 %SLB_RS_CONF% 237 %RS_RS_CONF% 238 } 239"); 240 } 241 } 242 } 243 $ret .= "}\n"; 244 } 245 } 246 } 247 return $ret; 248} 249 250class MacroParser 251{ 252 protected $macros; // current macro context 253 protected $trace; // recursive macro expansion path 254 255 public function __construct() 256 { 257 $this->macros = array(); 258 $this->trace = array(); 259 } 260 261 // cuts the subsequent defines from $value and stores the $name-$value define 262 // if $value is unset, returns immediately 263 public function addMacro ($name, $value) 264 { 265 if (! isset ($value)) 266 return; 267 $new_value = ''; // value without defines 268 $macro_deep = 0; 269 foreach (explode ("\n", $value) as $line) 270 { 271 if (! $macro_deep) 272 { 273 if (preg_match ('/^([A-Za-z_0-9]+)([\?:]?=)(.*)/', $line, $m)) 274 { 275 // found macro definition 276 $mname = $m[1]; 277 $op = $m[2]; 278 $mvalue = ltrim ($m[3]); 279 if (substr ($mvalue, 0, 1) == '`') // quoted define value 280 { 281 $line = substr ($mvalue, 1); 282 $mvalue = ''; 283 $macro_deep++; 284 } 285 else 286 { 287 $mvalue = rtrim ($mvalue); 288 if ($op === ':=') 289 $this->macros[$mname] = $this->expand ($mvalue); 290 elseif ($op === '?=' && '' === $this->expandMacro ($mname)) 291 $this->macros[$mname] = $mvalue; 292 else 293 $this->macros[$mname] = $mvalue; 294 } 295 } 296 else 297 $new_value .= $line . "\n"; 298 } 299 300 if ($macro_deep) 301 { 302 for ($i = 0; $i < strlen ($line); $i++) 303 { 304 $c = $line[$i]; 305 if ($c == "'" && 0 == --$macro_deep) 306 { 307 if ($op === ':=') 308 $this->macros[$mname] = $this->expand ($mvalue); 309 elseif ($op === '?=' && '' === $this->expandMacro ($mname)) 310 $this->macros[$mname] = $mvalue; 311 else 312 $this->macros[$mname] = $mvalue; 313 $rest = substr ($line, $i + 1); 314 if (preg_match ('/\S/', $rest)) 315 $new_value .= $rest . "\n"; 316 break; 317 } 318 elseif ($c == "`") 319 $macro_deep++; 320 $mvalue .= $c; 321 } 322 if ($macro_deep) 323 $mvalue .= "\n"; 324 } 325 } 326 $this->macros[$name] = substr ($new_value, 0, -1); // trim last \n 327 } 328 329 // replaces all macro expansions (like %THIS%) by the results of expandMacro calls 330 // Has some formatting logic: 331 // * indent each line of expansion if the expanding line contains only the macro reference 332 // * do not add empty line to the output if the expanding line contains only the macro reference and expands to empty string 333 // * trim last newline of expansion if there already is newline in source string after the macro reference 334 public function expand ($text) 335 { 336 $ret = ''; 337 $len = strlen ($text); 338 $pos = 0; 339 $state = 0; 340 $lazy = 0; 341 while ($pos < $len || $pos == $len && $state == 100) 342 switch ($state) 343 { 344 case 99: // expansion failed, cat it untouched into $ret 345 $ret .= '%'; 346 $pos = $exp_start + 1; 347 $state = 0; 348 break; 349 case 100: // expand from $exp_start to $pos with $e_value 350 $pre_blank = TRUE; 351 $indent = ''; 352 $line_start = 0; 353 for ($i = $exp_start - 1; $i >= 0; $i--) 354 if ($text[$i] == "\n") 355 { 356 $line_start = $i + 1; 357 break; 358 } 359 elseif ($text[$i] != ' ' && $text[$i] != "\t") 360 { 361 $pre_blank = FALSE; 362 break; 363 } 364 if ($pre_blank) 365 $indent = substr ($text, $line_start, $exp_start - $line_start); 366 367 $after_blank = TRUE; 368 $line_end = $len; 369 for ($i = $pos; $i < $len; $i++) 370 if ($text[$i] == "\n") 371 { 372 $line_end = $i; 373 break; 374 } 375 elseif ($text[$i] != ' ' && $text[$i] != "\t") 376 { 377 $after_blank = FALSE; 378 break; 379 } 380 // do actual expansion 381 if ($e_value == '') 382 { 383 // skip entire line if empty expansion was lazy 384 if ($lazy) 385 { 386 $ret = preg_replace ('/.*$/', '', $ret, 1); 387 $pos = $line_end + 1; 388 } 389 // skip newline if expansion is empty and alone 390 elseif ($pre_blank && $after_blank) 391 { 392 $ret = rtrim ($ret, " \t"); 393 $pos = $line_end + 1; 394 } 395 } 396 else 397 { 398 // trim last newline of expansion 399 if ($after_blank && $e_value != '' && $e_value[strlen ($e_value) - 1] == "\n") 400 $e_value = substr ($e_value, 0, -1); 401 // indent each line of $e_value 402 if ($indent != '') 403 $e_value = preg_replace ('/\n(?!$)/', "\n$indent", $e_value); 404 $ret .= $e_value; 405 } 406 $lazy = 0; 407 $state = 0; 408 break; 409 case 0: // initial state, search for % 410 if (FALSE === ($exp_start = strpos ($text, '%', $pos))) 411 { 412 $ret .= substr ($text, $pos); 413 $pos = $len; 414 } 415 else 416 { 417 $ret .= substr ($text, $pos, $exp_start - $pos); 418 $pos = $exp_start + 1; 419 $state = 1; 420 if ($pos < $len) 421 { 422 if ($text[$pos] == '{') 423 { 424 $state = 2; 425 $pos++; 426 } 427 elseif ($text[$pos] == '?') 428 { 429 $lazy = 1; 430 $pos++; 431 } 432 } 433 $mname_begin = $pos; 434 } 435 break; 436 case 1: // simple expansion (%ABC%) ending 437 if (preg_match ('/[%\n]/s', $text, $m, PREG_OFFSET_CAPTURE, $pos) && $m[0][0] != "\n") 438 { 439 $i = $m[0][1]; 440 $macro_name = substr ($text, $mname_begin, $i - $mname_begin); 441 if (preg_match('/^[A-Za-z_0-9]+$/', $macro_name)) 442 { 443 $pos = $i + 1; // skip '%'' 444 $e_value = $this->expandMacro ($macro_name); 445 $state = 100; 446 break; 447 } 448 } 449 $state = 99; // rollback expansion 450 break; 451 case 2: // enhanced expansion (%{ABC}% or %{ABC:[+-]smthng}%) stage 1 452 if (preg_match ('/[}:\n]/s', $text, $m, PREG_OFFSET_CAPTURE, $pos) && $m[0][0] != "\n") 453 { 454 $i = $m[0][1]; 455 $macro_name = substr ($text, $mname_begin, $i - $mname_begin); 456 if (preg_match('/^[A-Za-z_0-9]+$/', $macro_name)) 457 { 458 if ($text[$i] == '}' && $i + 1 < $len && $text[$i + 1] == '%') 459 { 460 $e_value = $this->expandMacro ($macro_name); 461 $pos = $i + 2; // skip '}%' 462 $state = 100; 463 break; 464 } 465 elseif ($text[$i] == ':') 466 { 467 $i++; 468 if ($i < $len && ($text[$i] == '+' || $text[$i] == '-')) 469 { 470 $condition_type = $text[$i]; 471 $deep = 1; 472 $pos = $i + 1; 473 $cond_start = $pos; 474 $state = 3; 475 break; 476 } 477 } 478 } 479 } 480 $state = 99; // rollback expansion 481 break; 482 case 3: // conditional expansion (%{ABC:[+-]smthng}%) ending 483 if (! preg_match ('/[{}]/', $text, $m, PREG_OFFSET_CAPTURE, $pos)) 484 $state = 99; 485 else 486 { 487 $i = $m[0][1]; 488 $pos = $i + 1; 489 if ($text[$i] == '{' && $i > 0 && $text[$i - 1] == '%') 490 { 491 $deep++; 492 $pos++; // skip '%{' 493 } 494 elseif ($text[$i] == '}' && $i + 1 < $len && $text[$i + 1] == '%') 495 { 496 $deep--; 497 $pos++; 498 if ($deep == 0) 499 { 500 $exp = substr ($text, $cond_start, $i - $cond_start); 501 $m_value = $this->expandMacro ($macro_name); 502 if ($condition_type == '+') 503 $e_value = ($m_value == '') ? '' : $this->expand ($exp); 504 elseif ($condition_type == '-') 505 $e_value = ($m_value != '') ? $m_value : $this->expand ($exp); 506 $state = 100; 507 } 508 } 509 } 510 break; 511 default: 512 throw new RackTablesError ("Unexpected state $state in " . __CLASS__ . '::' . __METHOD__ . " FSM", RackTablesError::INTERNAL); 513 } 514 515 if ($state != 0) 516 $ret .= substr ($text, $exp_start); 517 return $ret; 518 } 519 520 // returns the result of expanding the named define, or '' if unset 521 public function expandMacro ($name) 522 { 523 array_push ($this->trace, $name); 524 if (isset ($this->macros[$name])) 525 $ret = $this->expand ($this->macros[$name]); 526 else 527 $ret = ''; 528 array_pop ($this->trace); 529 return $ret; 530 } 531 532 // you can inherit the parser class and override this method to fill RS list dynamically 533 public function getRSList() 534 { 535 if (isset ($this->macros['RSP_ID'])) 536 return getRSListInPool ($this->macros['RSP_ID']); 537 return array(); 538 } 539} 540 541function buildEntityLVSConfig ($cell) 542{ 543 $ret = "#\n#\n# This configuration has been generated automatically by RackTables\n#\n#\n"; 544 // slbv2 545 if ($cell['realm'] != 'ipv4vs') 546 $ret .= generateSLBConfig2 (getTriplets ($cell)); 547 // slbv1 548 if ($cell['realm'] != 'ipvs') 549 $ret .= generateSLBConfig (SLBTriplet::getTriplets ($cell)); 550 return $ret; 551} 552 553function buildLVSConfig ($object_id) 554{ 555 return callHook ('buildEntityLVSConfig', spotEntity ('object', $object_id)); 556} 557 558// ********************* Database functions ********************* 559 560function addRStoRSPool ($pool_id, $rsip_bin, $rsport = 0, $inservice = 'no', $rsconfig = '', $comment = '') 561{ 562 $ret = usePreparedInsertBlade 563 ( 564 'IPv4RS', 565 array 566 ( 567 'rspool_id' => $pool_id, 568 'rsip' => $rsip_bin, 569 'rsport' => ($rsport == '' || $rsport === 0) ? NULL : $rsport, 570 'inservice' => $inservice == 'yes' ? 'yes' : 'no', 571 'rsconfig' => nullIfEmptyStr ($rsconfig), 572 'comment' => nullIfEmptyStr ($comment), 573 ) 574 ); 575 lastCreated ('iprs', lastInsertID()); 576 return $ret; 577} 578 579function addLBtoRSPool ($pool_id = 0, $object_id = 0, $vs_id = 0, $vsconfig = '', $rsconfig = '', $prio = '') 580{ 581 usePreparedInsertBlade 582 ( 583 'IPv4LB', 584 array 585 ( 586 'object_id' => $object_id, 587 'rspool_id' => $pool_id, 588 'vs_id' => $vs_id, 589 'vsconfig' => nullIfEmptyStr ($vsconfig), 590 'rsconfig' => nullIfEmptyStr ($rsconfig), 591 'prio' => nullIfEmptyStr ($prio), 592 ) 593 ); 594} 595 596function commitDeleteVS ($id = 0) 597{ 598 releaseFiles ('ipv4vs', $id); 599 destroyTagsForEntity ('ipv4vs', $id); 600 usePreparedDeleteBlade ('IPv4VS', array ('id' => $id)); 601} 602 603function commitUpdateRS ($rsid, $rsip_bin, $rsport = 0, $inservice = 'yes', $rsconfig = '', $comment = '') 604{ 605 usePreparedExecuteBlade 606 ( 607 'UPDATE IPv4RS SET rsip=?, rsport=?, inservice=?, rsconfig=?, comment=? WHERE id=?', 608 array 609 ( 610 $rsip_bin, 611 ($rsport == '' || $rsport === 0) ? NULL : $rsport, 612 $inservice, 613 nullIfEmptyStr ($rsconfig), 614 nullIfEmptyStr ($comment), 615 $rsid, 616 ) 617 ); 618} 619 620// $vport is ignored if $proto == 'MARK' 621function commitUpdateVS ($vsid, $vip_bin, $vport = 0, $proto = '', $name = '', $vsconfig = '', $rsconfig = '') 622{ 623 if ($proto != 'MARK' && $vport <= 0) 624 throw new InvalidArgException ('vport', $vport); 625 if ($proto == '') 626 throw new InvalidArgException ('proto', $proto); 627 return usePreparedUpdateBlade 628 ( 629 'IPv4VS', 630 array 631 ( 632 'vip' => $vip_bin, 633 'vport' => ($proto == 'MARK' ? NULL : $vport), 634 'proto' => $proto, 635 'name' => nullIfEmptyStr ($name), 636 'vsconfig' => nullIfEmptyStr ($vsconfig), 637 'rsconfig' => nullIfEmptyStr ($rsconfig), 638 ), 639 array ('id' => $vsid) 640 ); 641} 642 643function commitCreateRSPool ($name = '', $vsconfig = '', $rsconfig = '', $tagidlist = array()) 644{ 645 usePreparedInsertBlade 646 ( 647 'IPv4RSPool', 648 array 649 ( 650 'name' => nullIfEmptyStr ($name), 651 'vsconfig' => nullIfEmptyStr ($vsconfig), 652 'rsconfig' => nullIfEmptyStr ($rsconfig), 653 ) 654 ); 655 $new_pool_id = lastInsertID(); 656 lastCreated ('ipv4rspool', $new_pool_id); 657 produceTagsForNewRecord ('ipv4rspool', $tagidlist, $new_pool_id); 658 return $new_pool_id; 659} 660 661function commitDeleteRSPool ($pool_id = 0) 662{ 663 releaseFiles ('ipv4rspool', $pool_id); 664 destroyTagsForEntity ('ipv4rspool', $pool_id); 665 usePreparedDeleteBlade ('IPv4RSPool', array ('id' => $pool_id)); 666} 667 668function commitUpdateSLBDefConf ($data) 669{ 670 saveScript('DefaultVSConfig', $data['vs']); 671 saveScript('DefaultRSConfig', $data['rs']); 672} 673 674function getSLBDefaults ($do_cache_result = FALSE) 675{ 676 static $ret = array(); 677 678 if (! $do_cache_result) 679 $ret = array(); 680 elseif (count ($ret)) 681 return $ret; 682 683 $ret['vsconfig'] = loadScript ('DefaultVSConfig'); 684 $ret['rsconfig'] = loadScript ('DefaultRSConfig'); 685 return $ret; 686} 687 688// Return the list of all currently configured load balancers with their pool count. 689function getLBList () 690{ 691 $result = usePreparedSelectBlade 692 ( 693 "select object_id, count(rspool_id) as poolcount " . 694 "from IPv4LB group by object_id order by object_id" 695 ); 696 $ret = array (); 697 while ($row = $result->fetch (PDO::FETCH_ASSOC)) 698 $ret[$row['object_id']] = $row['poolcount']; 699 return $ret; 700} 701 702function getRSList () 703{ 704 $result = usePreparedSelectBlade 705 ( 706 "select id, inservice, rsip as rsip_bin, rsport, rspool_id, rsconfig " . 707 "from IPv4RS order by rspool_id, IPv4RS.rsip, rsport" 708 ); 709 $ret = array (); 710 while ($row = $result->fetch (PDO::FETCH_ASSOC)) 711 { 712 $row['rsip'] = ip_format ($row['rsip_bin']); 713 $row['rsconfig'] = dos2unix ($row['rsconfig']); 714 foreach (array ('inservice', 'rsip_bin', 'rsip', 'rsport', 'rspool_id', 'rsconfig') as $cname) 715 $ret[$row['id']][$cname] = $row[$cname]; 716 } 717 return $ret; 718} 719 720function getRSListInPool ($rspool_id) 721{ 722 $ret = array(); 723 $query = "select id, inservice, rsip as rsip_bin, rsport, rsconfig, comment from " . 724 "IPv4RS where rspool_id = ? order by IPv4RS.rsip, rsport"; 725 $result = usePreparedSelectBlade ($query, array ($rspool_id)); 726 while ($row = $result->fetch (PDO::FETCH_ASSOC)) 727 { 728 $row['rsip'] = ip_format ($row['rsip_bin']); 729 $ret[$row['id']] = $row; 730 } 731 return $ret; 732} 733