r1724 + generateAutoPorts(): welcome new ophandler
[racktables] / inc / database.php
index 1027607f3ecaa5739db3e48f4c960008a67acbec..4f2fba50782b7e608418801d3e9c7df13b19d2f7 100644 (file)
@@ -5,10 +5,15 @@
 *
 */
 
-function escapeString ($value)
+function escapeString ($value, $do_db_escape = TRUE)
 {
-       global $dbxlink;
-       return substr ($dbxlink->quote (htmlentities ($value)), 1, -1);
+       $ret = htmlentities ($value, ENT_QUOTES);
+       if ($do_db_escape)
+       {
+               global $dbxlink;
+               $ret = substr ($dbxlink->quote ($ret), 1, -1);
+       }
+       return $ret;
 }
 
 // This function returns detailed information about either all or one
@@ -371,6 +376,8 @@ function commitAddObject ($new_name, $new_label, $new_barcode, $new_type_id, $ne
        $row = $result2->fetch (PDO::FETCH_NUM);
        $last_insert_id = $row[0];
        $result2->closeCursor();
+       // Do AutoPorts magic
+       executeAutoPorts ($last_insert_id, $new_type_id);
        return recordHistory ('RackObject', "id = ${last_insert_id}");
 }
 
@@ -597,7 +604,7 @@ function recordHistory ($tableName, $whereClause)
        $result = $dbxlink->query ($query);
        if ($result == NULL or $result->rowCount() != 1)
        {
-               showError ("SQL query failed for table ${tableName}", __FUNCTION__);
+               showError ("SQL query '${query}' failed for table ${tableName}", __FUNCTION__);
                return FALSE;
        }
        return TRUE;
@@ -668,11 +675,14 @@ function getResidentRacksData ($object_id = 0, $fetch_rackdata = TRUE)
        }
        $rows = $result->fetchAll (PDO::FETCH_NUM);
        $result->closeCursor();
-       if (!$fetch_rackdata)
-               return $rows[0];
        $ret = array();
        foreach ($rows as $row)
        {
+               if (!$fetch_rackdata)
+               {
+                       $ret[$row[0]] = $row[0];
+                       continue;
+               }
                $rackData = getRackData ($row[0]);
                if ($rackData == NULL)
                {
@@ -1357,17 +1367,17 @@ function addPortCompat ($type1 = 0, $type2 = 0)
 function getDict ()
 {
        global $dbxlink;
-       $query =
+       $query1 =
                "select chapter_name, Chapter.chapter_no, dict_key, dict_value, sticky from " .
                "Chapter natural left join Dictionary order by chapter_name, dict_value";
-       $result = $dbxlink->query ($query);
-       if ($result == NULL)
+       $result1 = $dbxlink->query ($query1);
+       if ($result1 == NULL)
        {
-               showError ('SQL query failed', __FUNCTION__);
+               showError ('SQL query #1 failed', __FUNCTION__);
                return NULL;
        }
        $dict = array();
-       while ($row = $result->fetch (PDO::FETCH_ASSOC))
+       while ($row = $result1->fetch (PDO::FETCH_ASSOC))
        {
                $chapter_no = $row['chapter_no'];
                if (!isset ($dict[$chapter_no]))
@@ -1378,15 +1388,37 @@ function getDict ()
                        $dict[$chapter_no]['word'] = array();
                }
                if ($row['dict_key'] != NULL)
+               {
                        $dict[$chapter_no]['word'][$row['dict_key']] = $row['dict_value'];
+                       $dict[$chapter_no]['refcnt'][$row['dict_key']] = 0;
+               }
        }
-       $result->closeCursor();
+       $result1->closeCursor();
+// Find the list of all assigned values of dictionary-addressed attributes, each with
+// chapter/word keyed reference counters. Use the structure to adjust reference counters
+// of the returned disctionary words.
+       $query2 = "select a.attr_id, am.chapter_no, uint_value, count(object_id) as refcnt " .
+               "from Attribute as a inner join AttributeMap as am on a.attr_id = am.attr_id " .
+               "inner join AttributeValue as av on a.attr_id = av.attr_id " .
+               "inner join Dictionary as d on am.chapter_no = d.chapter_no and av.uint_value = d.dict_key " .
+               "where attr_type = 'dict' group by a.attr_id, am.chapter_no, uint_value " .
+               "order by a.attr_id, am.chapter_no, uint_value";
+       $result2 = $dbxlink->query ($query2);
+       if ($result2 == NULL)
+       {
+               showError ('SQL query #2 failed', __FUNCTION__);
+               return NULL;
+       }
+       $refcnt = array();
+       while ($row = $result2->fetch (PDO::FETCH_ASSOC))
+               $dict[$row['chapter_no']]['refcnt'][$row['uint_value']] = $row['refcnt'];
+       $result2->closeCursor();
        return $dict;
 }
 
 function getDictStats ()
 {
-       $stock_chapters = array (1, 2, 3, 11, 12, 13, 14, 16, 17, 18, 19, 20);
+       $stock_chapters = array (1, 2, 3, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23);
        global $dbxlink;
        $query =
                "select Chapter.chapter_no, chapter_name, count(dict_key) as wc from " .
@@ -1438,6 +1470,62 @@ function getDictStats ()
        return $ret;
 }
 
+function getIPv4Stats()
+{
+       global $dbxlink;
+       $ret = array();
+       $subject = array();
+       $subject[] = array ('q' => 'select count(id) from IPRanges', 'txt' => 'Networks');
+       $subject[] = array ('q' => 'select count(ip) from IPAddress', 'txt' => 'Addresses commented/reserved');
+       $subject[] = array ('q' => 'select count(ip) from IPBonds', 'txt' => 'Addresses allocated');
+       $subject[] = array ('q' => 'select count(*) from PortForwarding', 'txt' => 'NAT rules');
+       $subject[] = array ('q' => 'select count(id) from IPVirtualService', 'txt' => 'Virtual services');
+       $subject[] = array ('q' => 'select count(id) from IPRSPool', 'txt' => 'Real server pools');
+       $subject[] = array ('q' => 'select count(id) from IPRealServer', 'txt' => 'Real servers');
+       $subject[] = array ('q' => 'select count(distinct object_id) from IPLoadBalancer', 'txt' => 'Load balancers');
+
+       foreach ($subject as $item)
+       {
+               $result = $dbxlink->query ($item['q']);
+               if ($result == NULL)
+               {
+                       showError ("SQL query '${item['q']}' failed", __FUNCTION__);
+                       return NULL;
+               }
+               $row = $result->fetch (PDO::FETCH_NUM);
+               $ret[$item['txt']] = $row[0];
+               $result->closeCursor();
+               unset ($result);
+       }
+       return $ret;
+}
+
+function getRackspaceStats()
+{
+       global $dbxlink;
+       $ret = array();
+       $subject = array();
+       $subject[] = array ('q' => 'select count(*) from Dictionary where chapter_no = 3', 'txt' => 'Rack rows');
+       $subject[] = array ('q' => 'select count(*) from Rack', 'txt' => 'Racks');
+       $subject[] = array ('q' => 'select avg(height) from Rack', 'txt' => 'Average rack height');
+       $subject[] = array ('q' => 'select sum(height) from Rack', 'txt' => 'Total rack units in field');
+
+       foreach ($subject as $item)
+       {
+               $result = $dbxlink->query ($item['q']);
+               if ($result == NULL)
+               {
+                       showError ("SQL query '${item['q']}' failed", __FUNCTION__);
+                       return NULL;
+               }
+               $row = $result->fetch (PDO::FETCH_NUM);
+               $ret[$item['txt']] = empty ($row[0]) ? 0 : $row[0];
+               $result->closeCursor();
+               unset ($result);
+       }
+       return $ret;
+}
+
 function commitUpdateDictionary ($chapter_no = 0, $dict_key = 0, $dict_value = '')
 {
        if ($chapter_no <= 0 or $dict_key <= 0 or empty ($dict_value))
@@ -1979,12 +2067,12 @@ function getDatabaseVersion ()
 function getSLBSummary ()
 {
        global $dbxlink;
-       $query = 'select vs.id as vsid, inet_ntoa(vip) as vip, vport, proto, ' .
-               'vs.name, rsp.id as pool_id, rsp.name as pool_name, object_id, count(rs.id) as rscount from ' .
-               'IPVirtualService as vs inner join IPRSPool as rsp on vs.id = rsp.vs_id ' .
-               'inner join IPRealServer as rs on rs.rspool_id = rsp.id ' .
-               'inner join IPLoadBalancer as lb on rsp.id = lb.rspool_id ' .
-               'group by rsp.id, object_id order by vip, object_id';
+       $query = 'select vs.id as vsid, inet_ntoa(vip) as vip, vport, proto, vs.name, object_id, ' .
+               'lb.rspool_id, pool.name as pool_name, count(rs.id) as rscount ' .
+               'from IPVirtualService as vs inner join IPLoadBalancer as lb on vs.id = lb.vs_id ' .
+               'inner join IPRSPool as pool on lb.rspool_id = pool.id ' .
+               'left join IPRealServer as rs on rs.rspool_id = lb.rspool_id ' .
+               'group by vs.id, object_id order by vs.vip, object_id';
        $result = $dbxlink->query ($query);
        if ($result == NULL)
        {
@@ -2004,7 +2092,13 @@ function getSLBSummary ()
                                $ret[$vsid][$cname] = $row[$cname];
                        $ret[$vsid]['lblist'] = array();
                }
-               $ret[$vsid]['lblist'][$row['object_id']][$row['pool_id']] = array ('size' => $row['rscount'], 'name' => $row['pool_name']);
+               // There's only one assigned RS pool possible for each LB-VS combination.
+               $ret[$vsid]['lblist'][$row['object_id']] = array
+               (
+                       'id' => $row['rspool_id'],
+                       'size' => $row['rscount'],
+                       'name' => $row['pool_name']
+               );
        }
        $result->closeCursor();
        return $ret;
@@ -2066,13 +2160,13 @@ function getVServiceInfo ($vsid = 0)
 // Collect and return the following info about the given real server pool:
 // basic information
 // parent virtual service information
-// load balancers list
+// load balancers list (each with a list of VSes)
 // real servers list
 
 function getRSPoolInfo ($id = 0)
 {
        global $dbxlink;
-       $query1 = "select ${id} as id, vs_id, name, vsconfig, rsconfig from " .
+       $query1 = "select id, name, vsconfig, rsconfig from " .
                "IPRSPool where id = ${id}";
        $result1 = $dbxlink->query ($query1);
        if ($result1 == NULL)
@@ -2084,12 +2178,12 @@ function getRSPoolInfo ($id = 0)
        $row = $result1->fetch (PDO::FETCH_ASSOC);
        if (!$row)
                return NULL;
-       foreach (array ('id', 'name', 'vsconfig', 'rsconfig', 'vs_id') as $c)
+       foreach (array ('id', 'name', 'vsconfig', 'rsconfig') as $c)
                $ret[$c] = $row[$c];
        $result1->closeCursor();
        $ret['lblist'] = array();
        $ret['rslist'] = array();
-       $query2 = "select object_id, vsconfig, rsconfig from IPLoadBalancer where rspool_id = ${id} order by object_id";
+       $query2 = "select object_id, vs_id, vsconfig, rsconfig from IPLoadBalancer where rspool_id = ${id} order by object_id";
        $result2 = $dbxlink->query ($query2);
        if ($result2 == NULL)
        {
@@ -2098,9 +2192,10 @@ function getRSPoolInfo ($id = 0)
        }
        while ($row = $result2->fetch (PDO::FETCH_ASSOC))
                foreach (array ('vsconfig', 'rsconfig') as $c)
-                       $ret['lblist'][$row['object_id']][$c] = $row[$c];
+                       $ret['lblist'][$row['object_id']][$row['vs_id']][$c] = $row[$c];
        $result2->closeCursor();
-       $query3 = "select id, inet_ntoa(rsip) as rsip, rsport, rsconfig from IPRealServer where rspool_id = ${id} order by rsip, rsport";
+       $query3 = "select id, inservice, inet_ntoa(rsip) as rsip, rsport, rsconfig from " .
+               "IPRealServer where rspool_id = ${id} order by IPRealServer.rsip, rsport";
        $result3 = $dbxlink->query ($query3);
        if ($result3 == NULL)
        {
@@ -2108,13 +2203,13 @@ function getRSPoolInfo ($id = 0)
                return NULL;
        }
        while ($row = $result3->fetch (PDO::FETCH_ASSOC))
-               foreach (array ('rsip', 'rsport', 'rsconfig') as $c)
+               foreach (array ('inservice', 'rsip', 'rsport', 'rsconfig') as $c)
                        $ret['rslist'][$row['id']][$c] = $row[$c];
        $result3->closeCursor();
        return $ret;
 }
 
-function addRStoRSPool ($pool_id = 0, $rsip = '', $rsport = 0, $rsconfig = '')
+function addRStoRSPool ($pool_id = 0, $rsip = '', $rsport = 0, $inservice = 'no', $rsconfig = '')
 {
        if ($pool_id <= 0 or $rsport <= 0)
        {
@@ -2129,6 +2224,7 @@ function addRStoRSPool ($pool_id = 0, $rsip = '', $rsport = 0, $rsconfig = '')
                        'rsip' => "inet_aton('${rsip}')",
                        'rsport' => $rsport,
                        'rspool_id' => $pool_id,
+                       'inservice' => ($inservice == 'yes' ? "'yes'" : "'no'"),
                        'rsconfig' => (empty ($rsconfig) ? 'NULL' : "'${rsconfig}'")
                )
        );
@@ -2156,9 +2252,9 @@ function commitCreateVS ($vip = '', $vport = 0, $proto = '', $name = '', $vsconf
        );
 }
 
-function addLBtoRSPool ($pool_id = 0, $object_id = 0, $vsconfig = '', $rsconfig = '')
+function addLBtoRSPool ($pool_id = 0, $object_id = 0, $vs_id = 0, $vsconfig = '', $rsconfig = '')
 {
-       if ($pool_id <= 0 or $object_id <= 0)
+       if ($pool_id <= 0 or $object_id <= 0 or $vs_id <= 0)
        {
                showError ('Invalid arguments', __FUNCTION__);
                die;
@@ -2170,6 +2266,7 @@ function addLBtoRSPool ($pool_id = 0, $object_id = 0, $vsconfig = '', $rsconfig
                (
                        'object_id' => $object_id,
                        'rspool_id' => $pool_id,
+                       'vs_id' => $vs_id,
                        'vsconfig' => (empty ($vsconfig) ? 'NULL' : "'${vsconfig}'"),
                        'rsconfig' => (empty ($rsconfig) ? 'NULL' : "'${rsconfig}'")
                )
@@ -2190,12 +2287,13 @@ function commitDeleteVS ($id = 0)
        return useDeleteBlade ('IPVirtualService', 'id', $id);
 }
 
-function commitDeleteLB ($object_id = 0, $pool_id = 0)
+function commitDeleteLB ($object_id = 0, $pool_id = 0, $vs_id = 0)
 {
        global $dbxlink;
-       if ($object_id <= 0 or $pool_id <= 0)
+       if ($object_id <= 0 or $pool_id <= 0 or $vs_id <= 0)
                return FALSE;
-       $query = "delete from IPLoadBalancer where object_id = ${object_id} and rspool_id = ${pool_id} limit 1";
+       $query = "delete from IPLoadBalancer where object_id = ${object_id} and " .
+               "rspool_id = ${pool_id} and vs_id = ${vs_id} limit 1";
        $result = $dbxlink->exec ($query);
        if ($result === NULL)
                return FALSE;
@@ -2231,9 +2329,9 @@ function commitUpdateRS ($rsid = 0, $rsip = '', $rsport = 0, $rsconfig = '')
        return TRUE;
 }
 
-function commitUpdateLB ($object_id = 0, $pool_id = 0, $vsconfig = '', $rsconfig = '')
+function commitUpdateLB ($object_id = 0, $pool_id = 0, $vs_id = 0, $vsconfig = '', $rsconfig = '')
 {
-       if ($object_id <= 0 or $pool_id <= 0)
+       if ($object_id <= 0 or $pool_id <= 0 or $vs_id <= 0)
        {
                showError ('Invalid args', __FUNCTION__);
                die;
@@ -2244,12 +2342,11 @@ function commitUpdateLB ($object_id = 0, $pool_id = 0, $vsconfig = '', $rsconfig
                (empty ($vsconfig) ? 'NULL' : "'${vsconfig}'") .
                ', rsconfig = ' .
                (empty ($rsconfig) ? 'NULL' : "'${rsconfig}'") .
-               " where object_id = ${object_id} and rspool_id = ${pool_id} limit 1";
+               " where object_id = ${object_id} and rspool_id = ${pool_id} " .
+               "and vs_id = ${vs_id} limit 1";
        $result = $dbxlink->exec ($query);
        if ($result === NULL)
                return FALSE;
-       elseif ($result != 1)
-               return FALSE;
        else
                return TRUE;
 }
@@ -2273,18 +2370,17 @@ function commitUpdateVS ($vsid = 0, $vip = '', $vport = 0, $proto = '', $name =
        $result = $dbxlink->exec ($query);
        if ($result === NULL)
                return FALSE;
-       elseif ($result != 1)
-               return FALSE;
        else
                return TRUE;
 }
 
 // Return the list of virtual services, indexed by vs_id.
+// Each record will be shown with its basic info plus RS pools counter.
 function getVSList ()
 {
        global $dbxlink;
-       $query = "select vs.id, inet_ntoa(vip) as vip, vport, proto, vs.name, vs.vsconfig, vs.rsconfig, count(pool.id) as poolcount " .
-               "from IPVirtualService as vs left join IPRSPool as pool on pool.vs_id = vs.id " .
+       $query = "select vs.id, inet_ntoa(vip) as vip, vport, proto, vs.name, vs.vsconfig, vs.rsconfig, count(rspool_id) as poolcount " .
+               "from IPVirtualService as vs left join IPLoadBalancer as lb on vs.id = lb.vs_id " .
                "group by vs.id order by vs.vip, proto, vport";
        $result = $dbxlink->query ($query);
        if ($result == NULL)
@@ -2292,33 +2388,33 @@ function getVSList ()
                showError ('SQL query failed', __FUNCTION__);
                return NULL;
        }
-       $vslist = array ();
+       $ret = array ();
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
                foreach (array ('vip', 'vport', 'proto', 'name', 'vsconfig', 'rsconfig', 'poolcount') as $cname)
-                       $vslist[$row['id']][$cname] = $row[$cname];
+                       $ret[$row['id']][$cname] = $row[$cname];
        $result->closeCursor();
-       return $vslist;
+       return $ret;
 }
 
 // Return the list of RS pool, indexed by pool id.
 function getRSPoolList ()
 {
        global $dbxlink;
-       $query = "select pool.id, vs_id, pool.name, count(rs.id) as rscount, pool.vsconfig, pool.rsconfig " .
-               "from IPRSPool as pool left join IPRealServer as rs on pool.id = rs.rspool_id " .
-               "group by pool.id order by vs_id, name";
+       $query = "select pool.id, pool.name, count(rspool_id) as refcnt, pool.vsconfig, pool.rsconfig " .
+               "from IPRSPool as pool left join IPLoadBalancer as lb on pool.id = lb.rspool_id " .
+               "group by pool.id order by pool.id, name";
        $result = $dbxlink->query ($query);
        if ($result == NULL)
        {
                showError ('SQL query failed', __FUNCTION__);
                return NULL;
        }
-       $pool_list = array ();
+       $ret = array ();
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
-               foreach (array ('vs_id', 'name', 'rscount', 'vsconfig', 'rsconfig') as $cname)
-                       $pool_list[$row['id']][$cname] = $row[$cname];
+               foreach (array ('name', 'refcnt', 'vsconfig', 'rsconfig') as $cname)
+                       $ret[$row['id']][$cname] = $row[$cname];
        $result->closeCursor();
-       return $pool_list;
+       return $ret;
 }
 
 function loadThumbCache ($rack_id = 0)
@@ -2364,9 +2460,10 @@ function resetThumbCache ($rack_id = 0)
        $result = $dbxlink->exec ($query);
 }
 
-// Return a tactical overview of RS pools configured with enough info to render
-// links to pages with detailed info. We might decide exposing more detailed tree
-// at some latter point.
+// Return the list of attached RS pools for the given object. As long as we have
+// the LB-VS UNIQUE in IPLoadBalancer table, it is Ok to key returned records
+// by vs_id, because there will be only one RS pool listed for each VS of the
+// current object.
 function getRSPoolsForObject ($object_id = 0)
 {
        if ($object_id <= 0)
@@ -2375,40 +2472,34 @@ function getRSPoolsForObject ($object_id = 0)
                return NULL;
        }
        global $dbxlink;
-       $query = "select pool.id, pool.name, vs_id, vs.name as vs_name, count(rsip) as rscount, " .
-               "inet_ntoa(vs.vip) as vip, vs.vport, vs.proto from " .
-               "IPLoadBalancer as lb inner join IPRSPool as pool on lb.rspool_id = pool.id " .
-               "inner join IPVirtualService as vs on pool.vs_id = vs.id " .
-               "left join IPRealServer as rs on pool.id = rs.rspool_id " .
-               "where lb.object_id = ${object_id} group by pool.id " .
-               "order by vip, vport, proto, name";
+       $query = 'select vs_id, inet_ntoa(vip) as vip, vport, proto, vs.name, pool.id as pool_id, ' .
+               'pool.name as pool_name, count(rsip) as rscount, lb.vsconfig, lb.rsconfig from ' .
+               'IPLoadBalancer as lb inner join IPRSPool as pool on lb.rspool_id = pool.id ' .
+               'inner join IPVirtualService as vs on lb.vs_id = vs.id ' .
+               'left join IPRealServer as rs on lb.rspool_id = rs.rspool_id ' .
+               "where lb.object_id = ${object_id} " .
+               'group by lb.rspool_id, lb.vs_id order by vs.vip, vport, proto, pool.name';
        $result = $dbxlink->query ($query);
        if ($result == NULL)
        {
                showError ('SQL query failed', __FUNCTION__);
                return NULL;
        }
-       $pool_list = array ();
+       $ret = array ();
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
-               foreach (array ('name', 'vs_id', 'vs_name', 'rscount', 'vip', 'vport', 'proto') as $cname)
-                       $pool_list[$row['id']][$cname] = $row[$cname];
+               foreach (array ('vip', 'vport', 'proto', 'name', 'pool_id', 'pool_name', 'rscount', 'vsconfig', 'rsconfig') as $cname)
+                       $ret[$row['vs_id']][$cname] = $row[$cname];
        $result->closeCursor();
-       return $pool_list;
+       return $ret;
 }
 
-function commitCreateRSPool ($vs_id = 0, $name = '', $vsconfig, $rsconfig)
+function commitCreateRSPool ($name = '', $vsconfig = '', $rsconfig = '')
 {
-       if ($vs_id <= 0)
-       {
-               showError ('Invalid argument', __FUNCTION__);
-               die;
-       }
        return useInsertBlade
        (
                'IPRSPool',
                array
                (
-                       'vs_id' => $vs_id,
                        'name' => (empty ($name) ? 'NULL' : "'${name}'"),
                        'vsconfig' => (empty ($vsconfig) ? 'NULL' : "'${vsconfig}'"),
                        'rsconfig' => (empty ($rsconfig) ? 'NULL' : "'${rsconfig}'")
@@ -2456,7 +2547,7 @@ function commitUpdateRSPool ($pool_id = 0, $name = '', $vsconfig = '', $rsconfig
 function getRSList ()
 {
        global $dbxlink;
-       $query = "select id, inet_ntoa(rsip) as rsip, rsport, rspool_id, rsconfig " .
+       $query = "select id, inservice, inet_ntoa(rsip) as rsip, rsport, rspool_id, rsconfig " .
                "from IPRealServer order by rspool_id, IPRealServer.rsip, rsport";
        $result = $dbxlink->query ($query);
        if ($result == NULL)
@@ -2464,12 +2555,107 @@ function getRSList ()
                showError ('SQL query failed', __FUNCTION__);
                return NULL;
        }
-       $rslist = array ();
+       $ret = array ();
        while ($row = $result->fetch (PDO::FETCH_ASSOC))
-               foreach (array ('rsip', 'rsport', 'rspool_id', 'rsconfig') as $cname)
-                       $rslist[$row['id']][$cname] = $row[$cname];
+               foreach (array ('inservice', 'rsip', 'rsport', 'rspool_id', 'rsconfig') as $cname)
+                       $ret[$row['id']][$cname] = $row[$cname];
        $result->closeCursor();
-       return $rslist;
+       return $ret;
+}
+
+// Return the list of all currently configured load balancers with their pool count.
+function getLBList ()
+{
+       global $dbxlink;
+       $query = "select object_id, count(rspool_id) as poolcount " .
+               "from IPLoadBalancer group by object_id order by object_id";
+       $result = $dbxlink->query ($query);
+       if ($result == NULL)
+       {
+               showError ('SQL query failed', __FUNCTION__);
+               return NULL;
+       }
+       $ret = array ();
+       while ($row = $result->fetch (PDO::FETCH_ASSOC))
+               $ret[$row['object_id']] = $row['poolcount'];
+       $result->closeCursor();
+       return $ret;
+}
+
+// For the given object return: it vsconfig/rsconfig; the list of RS pools
+// attached (each with vsconfig/rsconfig in turn), each with the list of
+// virtual services terminating the pool. Each pool also lists all real
+// servers with rsconfig.
+function buildLBConfig ($object_id)
+{
+       if ($object_id <= 0)
+       {
+               showError ('Invalid arg', __FUNCTION__);
+               return NULL;
+       }
+       global $dbxlink;
+       $ret = array();
+       $query = 'select vs_id, inet_ntoa(vip) as vip, vport, proto, vs.name as vs_name, ' .
+               'vs.vsconfig as vs_vsconfig, vs.rsconfig as vs_rsconfig, ' .
+               'lb.vsconfig as lb_vsconfig, lb.rsconfig as lb_rsconfig, pool.id as pool_id, pool.name as pool_name, ' .
+               'pool.vsconfig as pool_vsconfig, pool.rsconfig as pool_rsconfig, ' .
+               'rs.id as rs_id, inet_ntoa(rsip) as rsip, rsport, rs.rsconfig as rs_rsconfig from ' .
+               'IPLoadBalancer as lb inner join IPRSPool as pool on lb.rspool_id = pool.id ' .
+               'inner join IPVirtualService as vs on lb.vs_id = vs.id ' .
+               'inner join IPRealServer as rs on lb.rspool_id = rs.rspool_id ' .
+               "where lb.object_id = ${object_id} and rs.inservice = 'yes' " .
+               "order by vs.vip, vport, proto, pool.name, rs.rsip, rs.rsport";
+       $result = $dbxlink->query ($query);
+       if ($result == NULL)
+       {
+               showError ('SQL query failed', __FUNCTION__);
+               return NULL;
+       }
+       while ($row = $result->fetch (PDO::FETCH_ASSOC))
+       {
+               $vs_id = $row['vs_id'];
+               if (!isset ($ret[$vs_id]))
+               {
+                       foreach (array ('vip', 'vport', 'proto', 'vs_name', 'vs_vsconfig', 'vs_rsconfig', 'lb_vsconfig', 'lb_rsconfig', 'pool_vsconfig', 'pool_rsconfig', 'pool_id', 'pool_name') as $c)
+                               $ret[$vs_id][$c] = $row[$c];
+                       $ret[$vs_id]['rslist'] = array();
+               }
+               foreach (array ('rsip', 'rsport', 'rs_rsconfig') as $c)
+                       $ret[$vs_id]['rslist'][$row['rs_id']][$c] = $row[$c];
+       }
+       $result->closeCursor();
+       return $ret;
+}
+
+function commitSetInService ($rs_id = 0, $inservice = '')
+{
+       if ($rs_id <= 0 or empty ($inservice))
+       {
+               showError ('Invalid args', __FUNCTION__);
+               return NULL;
+       }
+       global $dbxlink;
+       $query = "update IPRealServer set inservice = '${inservice}' where id = ${rs_id} limit 1";
+       $result = $dbxlink->exec ($query);
+       if ($result === NULL)
+               return FALSE;
+       elseif ($result != 1)
+               return FALSE;
+       else
+               return TRUE;
+}
+
+function executeAutoPorts ($object_id = 0, $type_id = 0)
+{
+       if ($object_id == 0 or $type_id == 0)
+       {
+               showError ('Invalid arguments', __FUNCTION__);
+               die;
+       }
+       $ret = TRUE;
+       foreach (getAutoPorts ($type_id) as $autoport)
+               $ret = $ret and '' == commitAddPort ($object_id, $autoport['name'], $autoport['type'], '', '');
+       return $ret;
 }
 
 ?>